diff --git a/src/cf/game.cpp b/src/cf/game.cpp index 248b647..7c44d2f 100644 --- a/src/cf/game.cpp +++ b/src/cf/game.cpp @@ -36,6 +36,10 @@ #include "strutil.h" #include "msgs.h" +#ifdef __EMSCRIPTEN__ +extern "C" void fredygames_save( void ); +#endif + extern Options CFOptions; // button identifiers used by the game hook function dispatcher @@ -1730,6 +1734,9 @@ GUI_Status Game::ShowDebriefing( Player &player, bool restart ) { view->CloseWindow( note ); CFOptions.Unlock( next_map ); +#ifdef __EMSCRIPTEN__ + fredygames_save(); +#endif int err = SwitchMap( next_map ); if ( err == -1 ) { note = new NoteWindow( MSG(MSG_ERROR), MSG(MSG_ERR_MAP_NOT_FOUND), 0, view ); diff --git a/src/cf/main.cpp b/src/cf/main.cpp index e8772db..5bc4aad 100644 --- a/src/cf/main.cpp +++ b/src/cf/main.cpp @@ -33,6 +33,10 @@ #include "SDL.h" +#ifdef __EMSCRIPTEN__ +# include +#endif + #include "view.h" #include "game.h" #include "misc.h" @@ -68,6 +72,15 @@ static void set_icon( const Surface &s, const Rect &icon ); static GUI_Status event_filter( SDL_Event &event, Window *window ); static void do_exit( void ); +#ifdef __EMSCRIPTEN__ +// fredygames.com: the game only writes its settings (and the campaign maps +// unlocked so far) when it quits. The page calls this when the tab is hidden +// or closed, and the game when it unlocks a map. +extern "C" EMSCRIPTEN_KEEPALIVE void fredygames_save( void ) { + if ( display ) save_settings( display ); +} +#endif + // Start of program functions ////////////////////////////////////////// #ifdef _MSC_VER diff --git a/src/common/SDL_zlib.c b/src/common/SDL_zlib.c index e1f7f8b..b080dd3 100644 --- a/src/common/SDL_zlib.c +++ b/src/common/SDL_zlib.c @@ -35,6 +35,44 @@ /* Functions to read/write gzip files */ +#if SDL_VERSION_ATLEAST(2,0,0) +/* SDL2 RWops: 64-bit offsets, sizes in size_t, read/write count whole objects */ +static Sint64 gzip_size(SDL_RWops *context) { + return -1; +} + +static Sint64 gzip_seek(SDL_RWops *context, Sint64 offset, int whence) { + z_off_t pos; + + pos = gzseek((gzFile)context->hidden.unknown.data1, (z_off_t)offset, whence); + if (pos == -1) SDL_Error(SDL_EFSEEK); + return pos; +} + +static size_t gzip_read(SDL_RWops *context, void *ptr, size_t size, size_t maxnum) { + int nread; + + if (size == 0) return 0; + nread = gzread((gzFile)context->hidden.unknown.data1, ptr, (unsigned)(size * maxnum)); + if (nread < 0) { + SDL_Error(SDL_EFREAD); + return 0; + } + return (size_t)nread / size; +} + +static size_t gzip_write(SDL_RWops *context, const void *ptr, size_t size, size_t num) { + int nwrote; + + if (size == 0) return 0; + nwrote = gzwrite((gzFile)context->hidden.unknown.data1, ptr, (unsigned)(size * num)); + if (nwrote <= 0) { + SDL_Error(SDL_EFWRITE); + return 0; + } + return (size_t)nwrote / size; +} +#else static int gzip_seek(SDL_RWops *context, int offset, int whence) { int pos; @@ -58,6 +96,7 @@ static int gzip_write(SDL_RWops *context, const void *ptr, int size, int num) { if (nwrote == 0) SDL_Error(SDL_EFWRITE); return nwrote; } +#endif static int gzip_close(SDL_RWops *context) { int rc = 0; @@ -136,6 +175,9 @@ SDL_RWops *SDL_RWFromGzip(const char *file, const char *mode) { if (gzfp != NULL) { rwops->hidden.unknown.data1 = gzfp; +#if SDL_VERSION_ATLEAST(2,0,0) + rwops->size = gzip_size; +#endif rwops->seek = gzip_seek; rwops->read = gzip_read; rwops->write = gzip_write; diff --git a/src/common/surface.cpp b/src/common/surface.cpp index b6c4fdf..0cdbe6f 100644 --- a/src/common/surface.cpp +++ b/src/common/surface.cpp @@ -74,7 +74,13 @@ int Surface::SetColorKey( const Color &col ) { Color Surface::GetColorKey( void ) const { Uint8 r, g, b; +#if SDL_VERSION_ATLEAST(2,0,0) + Uint32 key = 0; + SDL_GetColorKey( s_surface, &key ); + SDL_GetRGB( key, s_surface->format, &r, &g, &b ); +#else SDL_GetRGB( s_surface->format->colorkey, s_surface->format, &r, &g, &b ); +#endif return Color( r, g, b ); } diff --git a/src/common/textbox.cpp b/src/common/textbox.cpp index fba5d81..62c06b3 100644 --- a/src/common/textbox.cpp +++ b/src/common/textbox.cpp @@ -497,7 +497,12 @@ GUI_Status StringWidget::InputLoop( void ) { (event.key.keysym.sym == SDLK_TAB))) ) { quit = true; } else if ( event.type == SDL_KEYDOWN ) { +#if SDL_VERSION_ATLEAST(2,0,0) + // the SDL 1.2 layer (cfsdl12.c) keeps the typed character here + CharInput( event.key.keysym.sym, event.key.keysym.unused ); +#else CharInput( event.key.keysym.sym, event.key.keysym.unicode ); +#endif } } } while ( !quit ); diff --git a/src/common/view.cpp b/src/common/view.cpp index e3f8b28..5727ce4 100644 --- a/src/common/view.cpp +++ b/src/common/view.cpp @@ -289,7 +289,11 @@ GUI_Status View::FetchEvent( SDL_Event &event ) { Uint32 start = SDL_GetTicks(); do { +#if SDL_VERSION_ATLEAST(2,0,0) + int got = SDL_PeepEvents( &next, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION ); +#else int got = SDL_PeepEvents( &next, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK ); +#endif if ( got > 0 ) { event.motion.x = next.motion.x;