diff --git a/.gitattributes b/.gitattributes index 4f038520f1f..3e5b654e3d5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8626,6 +8626,7 @@ src/osd/sdl/sdlptty_unix.c svneol=native#text/plain src/osd/sdl/sdlptty_win32.c svneol=native#text/plain src/osd/sdl/sdlsocket.c svneol=native#text/plain src/osd/sdl/sdlsync.h svneol=native#text/plain +src/osd/sdl/sdlsync_mini.c svneol=native#text/plain src/osd/sdl/sdlsync_ntc.c svneol=native#text/plain src/osd/sdl/sdlsync_os2.c svneol=native#text/plain src/osd/sdl/sdlsync_sdl.c svneol=native#text/plain diff --git a/src/emu/machine.c b/src/emu/machine.c index 9b4fb482a13..787e4618d35 100644 --- a/src/emu/machine.c +++ b/src/emu/machine.c @@ -95,6 +95,28 @@ static char giant_string_buffer[65536] = { 0 }; +//************************************************************************** +// JAVASCRIPT PORT-SPECIFIC +//************************************************************************** + +#ifdef SDLMAME_EMSCRIPTEN +#include + +static device_scheduler * scheduler; + +void js_main_loop() { + attotime stoptime = scheduler->time() + attotime(0,HZ_TO_ATTOSECONDS(60)); + while (scheduler->time() < stoptime) { + scheduler->timeslice(); + } +} + +void js_set_main_loop(device_scheduler &sched) { + scheduler = &sched; + emscripten_set_main_loop(&js_main_loop, 0, 1); +} +#endif + //************************************************************************** // RUNNING MACHINE //************************************************************************** @@ -381,6 +403,11 @@ int running_machine::run(bool firstrun) { g_profiler.start(PROFILER_EXTRA); + #ifdef SDLMAME_EMSCRIPTEN + //break out to our async javascript loop and halt + js_set_main_loop(m_scheduler); + #endif + // execute CPUs if not paused if (!m_paused) m_scheduler.timeslice(); diff --git a/src/osd/sdl/drawogl.c b/src/osd/sdl/drawogl.c index 50e921435ba..b3856943ee9 100644 --- a/src/osd/sdl/drawogl.c +++ b/src/osd/sdl/drawogl.c @@ -594,7 +594,7 @@ static int drawogl_window_create(sdl_window_info *window, int width, int height) sdl->extra_flags |= SDL_OPENGL | SDL_DOUBLEBUF; SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); - #if (SDL_VERSION_ATLEAST(1,2,10)) + #if (SDL_VERSION_ATLEAST(1,2,10)) && (!defined(SDLMAME_EMSCRIPTEN)) SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, video_config.waitvsync ? 1 : 0); #endif diff --git a/src/osd/sdl/input.c b/src/osd/sdl/input.c index 3d3a96e94f0..7efa2f198e6 100644 --- a/src/osd/sdl/input.c +++ b/src/osd/sdl/input.c @@ -41,6 +41,12 @@ #undef DELETE #endif +// Emscripten requires the SDL2 API for keyboard inputs, but nothing else +#ifdef SDLMAME_EMSCRIPTEN +#undef SDLMAME_SDL2 +#define SDLMAME_SDL2 1 +#endif + //============================================================ // PARAMETERS //============================================================ @@ -496,6 +502,13 @@ static kt_table sdl_key_trans_table[] = }; #endif +#if defined(SDLMAME_EMSCRIPTEN) +#undef GET_WINDOW +#undef GET_FOCUS_WINDOW +#define GET_WINDOW(ev) sdl_window_list +#define GET_FOCUS_WINDOW(ev) sdl_window_list +#endif + struct key_lookup_table { int code; @@ -722,7 +735,7 @@ static void sdlinput_register_joysticks(running_machine &machine) { char *joy_name; -#if (SDLMAME_SDL2) +#if (SDLMAME_SDL2) && (!defined(SDLMAME_EMSCRIPTEN)) joy = SDL_JoystickOpen(physical_stick); joy_name = remove_spaces(machine, SDL_JoystickName(joy)); SDL_JoystickClose(joy); @@ -1533,7 +1546,7 @@ INT32 normalize_absolute_axis(INT32 raw, INT32 rawmin, INT32 rawmax) // sdlinput_poll //============================================================ -#if (SDLMAME_SDL2) +#if (SDLMAME_SDL2) && (!defined(SDLMAME_EMSCRIPTEN)) INLINE sdl_window_info * window_from_id(Uint32 windowID) { sdl_window_info *w; @@ -1923,7 +1936,7 @@ void sdlinput_poll(running_machine &machine) devinfo->joystick.balls[event.jball.ball * 2] = event.jball.xrel * INPUT_RELATIVE_PER_PIXEL; devinfo->joystick.balls[event.jball.ball * 2 + 1] = event.jball.yrel * INPUT_RELATIVE_PER_PIXEL; break; -#if (!SDLMAME_SDL2) +#if (!SDLMAME_SDL2) || defined(SDLMAME_EMSCRIPTEN) case SDL_APPMOUSEFOCUS: app_has_mouse_focus = event.active.gain; if (!event.active.gain) @@ -2000,7 +2013,7 @@ void sdlinput_poll(running_machine &machine) #endif } } -#if (SDLMAME_SDL2) +#if (SDLMAME_SDL2) && (!defined(SDLMAME_EMSCRIPTEN)) resize_all_windows(); #endif } diff --git a/src/osd/sdl/sdl.mak b/src/osd/sdl/sdl.mak index 34a9af9714a..77939f6738d 100644 --- a/src/osd/sdl/sdl.mak +++ b/src/osd/sdl/sdl.mak @@ -337,6 +337,12 @@ NO_USE_QTDEBUG = 1 NO_OPENGL = 1 endif +ifeq ($(TARGETOS),emscripten) +DEFS += -DSDLMAME_EMSCRIPTEN +BASE_TARGETOS = unix +SYNC_IMPLEMENTATION = mini +endif + #------------------------------------------------- # Sanity checks #------------------------------------------------- @@ -409,9 +415,12 @@ INCPATH += -Isrc/debug MOCINCPATH := $(INCPATH) # add the prefix file +# Don't pull in the system includes if we are compiling for Emscripten, which has its own headers +ifneq ($(TARGETOS),emscripten) INCPATH += -include $(SDLSRC)/sdlprefix.h INCPATH += -I/work/src/m/sdl MOCINCPATH += -I/work/src/m/sdl +endif #------------------------------------------------- @@ -530,7 +539,9 @@ ifeq ($(NO_X11),1) NO_DEBUGGER = 1 endif +ifneq ($(TARGETOS),emscripten) INCPATH += `$(SDL_CONFIG) --cflags | sed -e 's:/SDL[2]*::' -e 's:\(-D[^ ]*\)::g'` +endif CCOMFLAGS += `$(SDL_CONFIG) --cflags | sed -e 's:/SDL[2]*::' -e 's:\(-I[^ ]*\)::g'` LIBS += `$(SDL_CONFIG) --libs` @@ -542,7 +553,9 @@ INCPATH += -I$(SDL_INSTALL_ROOT)/include/directfb endif endif +ifneq ($(TARGETOS),emscripten) INCPATH += `pkg-config --cflags fontconfig` +endif LIBS += `pkg-config --libs fontconfig` ifeq ($(SDL_LIBVER),sdl2) @@ -597,7 +610,9 @@ ifeq ($(BASE_TARGETOS),win32) OSDCOREOBJS += $(SDLMAIN) ifdef SDL_INSTALL_ROOT +ifneq ($(TARGETOS),emscripten) INCPATH += -I$(SDL_INSTALL_ROOT)/include +endif LIBS += -L$(SDL_INSTALL_ROOT)/lib #-Wl,-rpath,$(SDL_INSTALL_ROOT)/lib endif @@ -714,6 +729,11 @@ LIBS += -L/usr/X11/lib -L/usr/X11R6/lib -L/usr/openwin/lib INCPATH += -I/usr/X11/include -I/usr/X11R6/include -I/usr/openwin/include endif # NO_X11 +# can't use native libs with emscripten +ifeq ($(TARGETOS),emscripten) +LIBS = +endif + #------------------------------------------------- # XInput #------------------------------------------------- diff --git a/src/osd/sdl/sdldir.c b/src/osd/sdl/sdldir.c index 5df2e0cd22d..82e9dce49a6 100644 --- a/src/osd/sdl/sdldir.c +++ b/src/osd/sdl/sdldir.c @@ -43,7 +43,7 @@ #define INVPATHSEPCH '\\' #endif -#if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_OS2) || defined(SDLMAME_HAIKU) +#if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_OS2) || defined(SDLMAME_HAIKU) || defined(SDLMAME_EMSCRIPTEN) typedef struct dirent sdl_dirent; typedef struct stat sdl_stat; #define sdl_readdir readdir diff --git a/src/osd/sdl/sdlfile.c b/src/osd/sdl/sdlfile.c index cb46900cf08..8c0bf364ddb 100644 --- a/src/osd/sdl/sdlfile.c +++ b/src/osd/sdl/sdlfile.c @@ -103,7 +103,7 @@ file_error osd_open(const char *path, UINT32 openflags, osd_file **file, UINT64 UINT32 access; const char *src; char *dst; - #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_OS2) || defined(SDLMAME_HAIKU) + #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_OS2) || defined(SDLMAME_HAIKU) || defined(SDLMAME_EMSCRIPTEN) struct stat st; #else struct stat64 st; @@ -203,7 +203,7 @@ file_error osd_open(const char *path, UINT32 openflags, osd_file **file, UINT64 #endif // attempt to open the file - #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_OS2) || defined(SDLMAME_HAIKU) + #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_OS2) || defined(SDLMAME_HAIKU) || defined(SDLMAME_EMSCRIPTEN) (*file)->handle = open(tmpstr, access, 0666); #else (*file)->handle = open64(tmpstr, access, 0666); @@ -226,7 +226,7 @@ file_error osd_open(const char *path, UINT32 openflags, osd_file **file, UINT64 // attempt to reopen the file if (error == NO_ERROR) { - #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_OS2) || defined(SDLMAME_HAIKU) + #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_OS2) || defined(SDLMAME_HAIKU) || defined(SDLMAME_EMSCRIPTEN) (*file)->handle = open(tmpstr, access, 0666); #else (*file)->handle = open64(tmpstr, access, 0666); @@ -246,6 +246,21 @@ file_error osd_open(const char *path, UINT32 openflags, osd_file **file, UINT64 } // get the file size + #ifdef SDLMAME_EMSCRIPTEN + //the fstat approach does not work on emscripten, work around for now + FILE *fileptr; + fileptr = fdopen((*file)->handle,"rb"); + if (fileptr == NULL) + { + *filesize = 0; + } + else + { + fseek(fileptr, 0, SEEK_END); + *filesize = ftell(fileptr); + fseek(fileptr, 0, SEEK_SET); + } + #else #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_OS2) || defined(SDLMAME_HAIKU) fstat((*file)->handle, &st); #else @@ -253,6 +268,7 @@ file_error osd_open(const char *path, UINT32 openflags, osd_file **file, UINT64 #endif *filesize = (UINT64)st.st_size; + #endif error: @@ -279,7 +295,7 @@ file_error osd_read(osd_file *file, void *buffer, UINT64 offset, UINT32 count, U switch (file->type) { case SDLFILE_FILE: -#if defined(SDLMAME_DARWIN) || defined(SDLMAME_BSD) +#if defined(SDLMAME_DARWIN) || defined(SDLMAME_BSD) || defined(SDLMAME_EMSCRIPTEN) result = pread(file->handle, buffer, count, offset); if (result < 0) #elif defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_OS2) @@ -325,7 +341,7 @@ file_error osd_write(osd_file *file, const void *buffer, UINT64 offset, UINT32 c switch (file->type) { case SDLFILE_FILE: -#if defined(SDLMAME_DARWIN) || defined(SDLMAME_BSD) +#if defined(SDLMAME_DARWIN) || defined(SDLMAME_BSD) || defined(SDLMAME_EMSCRIPTEN) result = pwrite(file->handle, buffer, count, offset); if (!result) #elif defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_OS2) diff --git a/src/osd/sdl/sdlmain.c b/src/osd/sdl/sdlmain.c index ede6291c0a7..b8e00ba1179 100644 --- a/src/osd/sdl/sdlmain.c +++ b/src/osd/sdl/sdlmain.c @@ -11,7 +11,7 @@ #ifdef SDLMAME_UNIX -#ifndef SDLMAME_MACOSX +#if (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_EMSCRIPTEN)) #if (SDLMAME_SDL2) //#include #else @@ -337,7 +337,7 @@ int main(int argc, char *argv[]) #ifdef SDLMAME_UNIX sdl_entered_debugger = 0; - #if (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_HAIKU)) + #if (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_HAIKU)) && (!defined(SDLMAME_EMSCRIPTEN)) #if !(SDLMAME_SDL2) if (TTF_Init() == -1) { @@ -391,7 +391,7 @@ int main(int argc, char *argv[]) //SDL_Quit(); #ifdef SDLMAME_UNIX - #if (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_HAIKU)) + #if (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_HAIKU)) && (!defined(SDLMAME_EMSCRIPTEN)) #if !(SDLMAME_SDL2) TTF_Quit(); #endif @@ -720,7 +720,7 @@ void sdl_osd_interface::init(running_machine &machine) #endif } -#ifdef SDLMAME_UNIX +#if defined(SDLMAME_UNIX) && (!defined(SDLMAME_EMSCRIPTEN)) #define POINT_SIZE 144.0 #ifdef SDLMAME_MACOSX diff --git a/src/osd/sdl/sdlprefix.h b/src/osd/sdl/sdlprefix.h index c578d4f8d84..c747863f957 100644 --- a/src/osd/sdl/sdlprefix.h +++ b/src/osd/sdl/sdlprefix.h @@ -64,6 +64,10 @@ #define SDLMAME_NO64BITIO 1 #endif +#if defined(EMSCRIPTEN) +#define SDLMAME_NO64BITIO 1 +#endif + // fix for Ubuntu 8.10 #ifdef _FORTIFY_SOURCE #undef _FORTIFY_SOURCE diff --git a/src/osd/sdl/sdlptty_unix.c b/src/osd/sdl/sdlptty_unix.c index 79b8f6695b0..92eb15e0261 100644 --- a/src/osd/sdl/sdlptty_unix.c +++ b/src/osd/sdl/sdlptty_unix.c @@ -22,7 +22,7 @@ #elif defined(SDLMAME_OPENBSD) # include # include -#elif defined(SDLMAME_LINUX) +#elif defined(SDLMAME_LINUX) || defined(SDLMAME_EMSCRIPTEN) # include #elif defined(SDLMAME_HAIKU) # include diff --git a/src/osd/sdl/sdlsocket.c b/src/osd/sdl/sdlsocket.c index e7e294a92c5..7de5f2e81a3 100644 --- a/src/osd/sdl/sdlsocket.c +++ b/src/osd/sdl/sdlsocket.c @@ -109,7 +109,7 @@ file_error sdl_open_socket(const char *path, UINT32 openflags, osd_file **file, file_error sdl_read_socket(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual) { -#ifndef SDLMAME_WIN32 +#if (!defined(SDLMAME_WIN32)) && (!defined(SDLMAME_EMSCRIPTEN)) ssize_t result; char line[80]; struct timeval timeout; diff --git a/src/osd/sdl/sdlsync_mini.c b/src/osd/sdl/sdlsync_mini.c new file mode 100644 index 00000000000..c6d22bbec8f --- /dev/null +++ b/src/osd/sdl/sdlsync_mini.c @@ -0,0 +1,173 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +//============================================================ +// +// sdlsync_mini.c - Minimal core synchronization functions +// +//============================================================ + +#include "osdcore.h" +#include "sdlsync.h" + +#define USE_SCALABLE_LOCKS (0) + +struct _osd_event +{ + void * ptr; +}; + +struct _osd_thread { + void * ptr; +}; + + +//============================================================ +// osd_lock_alloc +//============================================================ + +osd_lock *osd_lock_alloc(void) +{ + // the minimal implementation does not support threading + // just return a dummy value here + return (osd_lock *)1; +} + + +//============================================================ +// osd_lock_acquire +//============================================================ + +void osd_lock_acquire(osd_lock *lock) +{ + // the minimal implementation does not support threading + // the acquire always "succeeds" +} + + +//============================================================ +// osd_lock_try +//============================================================ + +int osd_lock_try(osd_lock *lock) +{ + // the minimal implementation does not support threading + // the acquire always "succeeds" + return TRUE; +} + + +//============================================================ +// osd_lock_release +//============================================================ + +void osd_lock_release(osd_lock *lock) +{ + // the minimal implementation does not support threading + // do nothing here +} + + +//============================================================ +// osd_lock_free +//============================================================ + +void osd_lock_free(osd_lock *lock) +{ + // the minimal implementation does not support threading + // do nothing here +} + + +//============================================================ +// osd_event_alloc +//============================================================ + +osd_event *osd_event_alloc(int manualreset, int initialstate) +{ + return NULL; +} + + +//============================================================ +// osd_event_free +//============================================================ + +void osd_event_free(osd_event *event) +{ +} + + +//============================================================ +// osd_event_set +//============================================================ + +void osd_event_set(osd_event *event) +{ +} + + +//============================================================ +// osd_event_reset +//============================================================ + +void osd_event_reset(osd_event *event) +{ +} + + +//============================================================ +// osd_event_wait +//============================================================ + +int osd_event_wait(osd_event *event, osd_ticks_t timeout) +{ + return TRUE; +} + + +//============================================================ +// osd_thread_create +//============================================================ + +osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam) +{ + return NULL; +} + + +//============================================================ +// osd_thread_adjust_priority +//============================================================ + +int osd_thread_adjust_priority(osd_thread *thread, int adjust) +{ + return FALSE; +} + + +//============================================================ +// osd_thread_cpu_affinity +//============================================================ + +int osd_thread_cpu_affinity(osd_thread *thread, UINT32 mask) +{ + return TRUE; +} + + +//============================================================ +// osd_thread_wait_free +//============================================================ + +void osd_thread_wait_free(osd_thread *thread) +{ +} + + +//============================================================ +// osd_process_kill +//============================================================ + +void osd_process_kill(void) +{ +} diff --git a/src/osd/sdl/window.c b/src/osd/sdl/window.c index 387daa96d44..e050237ffab 100644 --- a/src/osd/sdl/window.c +++ b/src/osd/sdl/window.c @@ -88,7 +88,7 @@ static sdl_window_info **last_window_ptr; static int multithreading_enabled; static osd_work_queue *work_queue; -#if !(SDLMAME_SDL2) +#if !(SDLMAME_SDL2) && (!defined(SDLMAME_EMSCRIPTEN)) typedef int SDL_threadID; #endif