make loading screen and title screen work with emterpreter async
authorTaylor Richards <taylor@icculus.org>
Sun, 14 Jan 2018 20:21:59 +0000 (15:21 -0500)
committerTaylor Richards <taylor@icculus.org>
Sat, 17 Mar 2018 15:23:54 +0000 (11:23 -0400)
14 files changed:
CMakeLists.txt
include/bmpman.h
include/freespace.h
include/gamesequence.h
include/gamesnd.h
include/levelpaging.h
include/pstypes.h
src/bmpman/bmpman.cpp
src/freespace2/freespace.cpp
src/freespace2/levelpaging.cpp
src/freespace2/main.cpp
src/gamesequence/gamesequence.cpp
src/gamesnd/gamesnd.cpp
src/globalincs/systemvars.cpp

index 7be6276..5f7d3ac 100644 (file)
@@ -194,59 +194,60 @@ target_link_libraries(
 )
 
 if(EMSCRIPTEN)
-  set(em_SYNC_WHITELIST
-    # for loading screen
+  set(ASYNC_FUNCTIONS
+       # common
     main
     game_main
     game_init
-    #game_loop_caller
-    #gameseq_process_events
-    #game_process_event
-    #gameseq_set_state
-    #game_enter_state
-    #game_start_mission
-    #freespace_mission_load_stuff
-    #game_busy_callback
-    #game_loading_callback
-    #game_loading_callback_close
-    #level_page_in
-    #bm_page_in_stop
-    #gamesnd_preload_common_sounds
-    #game_busy
     # fs2 title screen
     display_title_screen
+    # loading screen
+    game_loop_caller
+    gameseq_process_events
+    game_process_event
+    gameseq_set_state
+    game_enter_state
+    game_start_mission
+    freespace_mission_load_stuff
+    game_busy_callback
+    game_loading_callback
+    game_loading_callback_close
+    level_page_in
+    bm_page_in_stop
+    gamesnd_preload_common_sounds
+    game_busy
   )
 
-  list(GET em_SYNC_WHITELIST -1 LastOne)
+  list(GET ASYNC_FUNCTIONS -1 LastOne)
 
-  set(EMTERPRETIFY_WHITELIST "'[")
+  set(EMTERPRETIFY_WHITELIST "[")
 
-  foreach(func ${em_SYNC_WHITELIST})
+  foreach(func ${ASYNC_FUNCTIONS})
     if (${func} STREQUAL ${LastOne})
-      set(EMTERPRETIFY_WHITELIST "${EMTERPRETIFY_WHITELIST}\"_${func}\"]'")
+      set(EMTERPRETIFY_WHITELIST "${EMTERPRETIFY_WHITELIST}\"_${func}\"]")
     else()
       set(EMTERPRETIFY_WHITELIST "${EMTERPRETIFY_WHITELIST}\"_${func}\",")
     endif()
   endforeach()
 
-  set(em_LINK_FLAGS
+  set(LINK_FLAGS
     "-s USE_SDL=2"
     "-s FULL_ES2=1"
-       #"-s WASM=1"
+  "-s WASM=1"
     "-s TOTAL_MEMORY=184549376"
     "--shell-file ${CMAKE_SOURCE_DIR}/dist/fs_shell.html"
     "--preload-file game@/"
     "-s SAFE_HEAP=1"
     "-s DEMANGLE_SUPPORT=1"
-    "-s ASSERTIONS=1"
+    "-s ASSERTIONS=2"
     "--profiling-funcs"
     "-s EMTERPRETIFY=1"
     "-s EMTERPRETIFY_ASYNC=1"
-       #"-s EMTERPRETIFY_FILE=\"${FS_BINARY}.binary\""
-    "-s EMTERPRETIFY_WHITELIST=${EMTERPRETIFY_WHITELIST}"
+    "-s 'EMTERPRETIFY_FILE=\"${FS_BINARY}.binary\"'"
+    "-s 'EMTERPRETIFY_WHITELIST=${EMTERPRETIFY_WHITELIST}'"
   )
 
-  foreach(Flag ${em_LINK_FLAGS})
+  foreach(Flag ${LINK_FLAGS})
     set_property(TARGET ${FS_BINARY} APPEND_STRING PROPERTY LINK_FLAGS " ${Flag}")
   endforeach()
 endif(EMSCRIPTEN)
index 8e82b84..bb03f56 100644 (file)
@@ -294,7 +294,7 @@ void bm_get_frame_usage(int *ntotal, int *nnew);
 //============================================================================
 
 void bm_page_in_start();
-void bm_page_in_stop();
+extern "C" void bm_page_in_stop();
 
 // Paging code in a library should call these functions
 // in its page in function.
index ee4cce3..042b32a 100644 (file)
@@ -228,7 +228,7 @@ typedef struct fs_builtin_mission {
 // mission management -------------------------------------------------
 
 // loads in the currently selected mission
-int game_start_mission();              
+extern "C" int game_start_mission();
 
 // shutdown a mission
 void game_level_close();
index 169544e..6dec9ef 100644 (file)
@@ -477,12 +477,12 @@ extern const char *GS_state_text[];               // text description for the GS_STATE_* #def
 // function prototypes
 //
 void gameseq_init();
-int gameseq_process_events( void );            // returns current game state
+extern "C" int gameseq_process_events( void );         // returns current game state
 int gameseq_get_state( int depth = 0 );
 void gameseq_post_event( int event );
 int gameseq_get_event( void );
 
-void gameseq_set_state(int new_state, int override = 0);
+extern "C" void gameseq_set_state(int new_state, int override = 0);
 void gameseq_push_state( int new_state );
 void gameseq_pop_state( void );
 int gameseq_get_pushed_state();
@@ -491,9 +491,9 @@ void gameseq_pop_and_discard_state(void);
 
 
 // Called by the sequencing code when things happen.
-void game_process_event(int current_state, int event);
+extern "C" void game_process_event(int current_state, int event);
 void game_leave_state(int old_state,int new_state);
-void game_enter_state(int old_state,int new_state);
+extern "C" void game_enter_state(int old_state,int new_state);
 void game_do_state(int current_state);
 
 #endif /* __GAMESEQUENCE_H__ */
index 233b4c6..4a1be72 100644 (file)
@@ -328,7 +328,7 @@ void gamesnd_load_gameplay_sounds();
 void gamesnd_unload_gameplay_sounds();
 void gamesnd_load_interface_sounds();
 void gamesnd_unload_interface_sounds();
-void gamesnd_preload_common_sounds();
+extern "C" void gamesnd_preload_common_sounds();
 void gamesnd_play_iface(int n);
 
 void gamesnd_play_error_beep();
index aa26c1f..f8db5f6 100644 (file)
@@ -36,7 +36,7 @@
 #define _LEVELPAGING_H
 
 // Call this and it calls the page in code for all the subsystems
-void level_page_in();
+extern "C" void level_page_in();
 
 #endif //_LEVELPAGING_H
 
index 2d55ac0..98da92c 100644 (file)
@@ -562,10 +562,10 @@ int myrand();
 // If delta_step is above 0, then it will also make sure it 
 // calls the callback each time count steps 'delta_step' even
 // if 1/10th of a second hasn't elapsed.
-extern int game_busy_callback( void (*callback)(int count), int delta_step = -1 );
+extern "C" int game_busy_callback( void (*callback)(int count), int delta_step = -1 );
 
 // Call whenever loading to display cursor
-extern void game_busy();
+extern "C" void game_busy();
 
 
 //=========================================================
index babe672..35f9661 100644 (file)
@@ -2118,6 +2118,7 @@ void bm_page_in_start()
 
 }
 
+extern "C"
 void bm_page_in_stop()
 {      
        int i;  
index 05bfd4b..f3745be 100644 (file)
@@ -1224,7 +1224,9 @@ void game_start_subspace_ambient_sound();
 void game_stop_subspace_ambient_sound();
 void verify_ships_tbl();
 void verify_weapons_tbl();
-void display_title_screen();
+#if defined(FS2_DEMO) || defined(OEM_BUILD)
+extern "C" void display_title_screen();
+#endif
 
 // loading background filenames
 static const char *Game_loading_bground_fname[GR_NUM_RESOLUTIONS] = {
@@ -1849,6 +1851,7 @@ int Game_loading_background = -1;
 anim * Game_loading_ani = NULL;
 anim_instance  *Game_loading_ani_instance;
 int Game_loading_frame=-1;
+int Game_loading_ani_bitmap = -1;
 
 static int Game_loading_ani_coords[GR_NUM_RESOLUTIONS][2] = {
        {
@@ -1868,6 +1871,7 @@ static int Game_loading_ani_coords[GR_NUM_RESOLUTIONS][2] = {
 // This gets called 10x per second and count is the number of times 
 // game_busy() has been called since the current callback function
 // was set.
+extern "C"
 void game_loading_callback(int count)
 {      
        game_do_networking();
@@ -1888,21 +1892,32 @@ void game_loading_callback(int count)
                cbitmap = anim_get_next_frame(Game_loading_ani_instance);
        }
 
-
-       if ( cbitmap > -1 )     {
-               if ( Game_loading_background > -1 )     {
-                       gr_set_bitmap( Game_loading_background, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
-                       gr_bitmap(0,0);
+       if (cbitmap > -1) {
+               if (Game_loading_ani_bitmap > -1) {
+                       bm_release(Game_loading_ani_bitmap);
                }
 
                //mprintf(( "Showing frame %d/%d [ Bitmap=%d ]\n", Game_loading_frame ,  Game_loading_ani->total_frames, cbitmap ));
-               gr_set_bitmap( cbitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
-               gr_bitmap(Game_loading_ani_coords[gr_screen.res][0],Game_loading_ani_coords[gr_screen.res][1]);
+               Game_loading_ani_bitmap = cbitmap;
+       }
 
-               bm_release(cbitmap);
-       
-               gr_flip();
+       if (Game_loading_background > -1) {
+               gr_set_bitmap(Game_loading_background, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
+               gr_bitmap(0, 0);
+       } else {
+               gr_clear();
+       }
+
+       if (Game_loading_ani_bitmap > -1) {
+               gr_set_bitmap(Game_loading_ani_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
+               gr_bitmap(Game_loading_ani_coords[gr_screen.res][0], Game_loading_ani_coords[gr_screen.res][1]);
        }
+
+       gr_flip();
+
+#ifdef __EMSCRIPTEN__
+       emscripten_sleep(10);
+#endif
 }
 
 void game_loading_callback_init()
@@ -1920,6 +1935,7 @@ void game_loading_callback_init()
        Game_loading_ani_instance = init_anim_instance(Game_loading_ani, 16);
        SDL_assert( Game_loading_ani_instance != NULL );
        Game_loading_frame = -1;
+       Game_loading_ani_bitmap = -1;
 
        Game_loading_callback_inited = 1;
        Mouse_hidden = 1;
@@ -1928,6 +1944,7 @@ void game_loading_callback_init()
 
 }
 
+extern "C"
 void game_loading_callback_close()
 {
        SDL_assert( Game_loading_callback_inited==1 );
@@ -1954,9 +1971,18 @@ void game_loading_callback_close()
        anim_free(Game_loading_ani);
        Game_loading_ani = NULL;
 
-       bm_release( Game_loading_background );
+       if (Game_loading_ani_bitmap > -1) {
+               bm_release(Game_loading_ani_bitmap);
+               Game_loading_ani_bitmap = -1;
+       }
+
+       if (Game_loading_background > -1) {
+               bm_release(Game_loading_background);
+               Game_loading_background = -1;
+       }
+
        common_free_interface_palette();                // restore game palette
-       Game_loading_background = -1;
+
 
        gr_set_font( FONT1 );
 }
@@ -1998,6 +2024,7 @@ void game_assign_sound_environment()
 // function which gets called before actually entering the mission.  It is broken down into a funciton
 // since it will get called in one place from a single player game and from another place for
 // a multiplayer game
+extern "C"
 void freespace_mission_load_stuff()
 {
        // called if we're not on a freespace dedicated (non rendering, no pilot) server
@@ -2048,6 +2075,7 @@ time_t load_post_level_init;
 time_t load_mission_stuff;
 
 // tells the server to load the mission and initialize structures
+extern "C"
 int game_start_mission()
 {      
        mprintf(( "=================== STARTING LEVEL LOAD ==================\n" ));
@@ -2259,6 +2287,9 @@ DCF(gamma,"Sets Gamma factor")
        }
 }
 
+extern void bm_init();
+
+extern "C"
 void game_init()
 {
        Game_current_mission_filename[0] = 0;
@@ -2273,7 +2304,6 @@ void game_init()
        load_filter_info();
        #endif
 
-       extern void bm_init();
        bm_init();
 
        // encrypt stuff
@@ -4896,6 +4926,7 @@ void end_demo_campaign_do()
 
 // All code to process events.   This is the only place
 // that you should change the state of the game.
+extern "C"
 void game_process_event( int current_state, int event )
 {
        mprintf(("Got event %s in state %s\n", GS_event_text[event], GS_state_text[current_state]));
@@ -5732,7 +5763,7 @@ void game_leave_state( int old_state, int new_state )
 // from.    You should never try to change the state
 // in here... if you think you need to, you probably really
 // need to post an event, not change the state.
-
+extern "C"
 void game_enter_state( int old_state, int new_state )
 {
        switch (new_state) {
@@ -5926,7 +5957,6 @@ void game_enter_state( int old_state, int new_state )
 
 #ifndef NDEBUG
                        // required to truely make mouse deltas zeroed in debug mouse code
-void mouse_force_pos(int x, int y);
                        if (!Is_standalone) {
                                mouse_force_pos(gr_screen.max_w / 2, gr_screen.max_h / 2);
                        }
@@ -6701,16 +6731,16 @@ static bool game_loop()
 }
 
 #ifdef __EMSCRIPTEN__
-static void game_loop_caller()
+extern "C"
+void game_loop_caller()
 {
        if ( !game_loop() ) {
-               emscripten_log(EM_LOG_CONSOLE, "got quit game!");
                game_shutdown();
-               //emscripten_cancel_main_loop();
        }
 }
 #endif
 
+extern "C"
 int game_main(const char *szCmdLine)
 {
        // Find out how much RAM is on this machine
@@ -8174,11 +8204,10 @@ int game_hacked_data()
        return 0;
 }
 
+#if defined(FS2_DEMO) || defined(OEM_BUILD)
+extern "C"
 void display_title_screen()
 {
-#if defined(FS2_DEMO) || defined(OEM_BUILD)
-       ///int title_bitmap;
-
        // load bitmap
        int title_bitmap = bm_load(Game_demo_title_screen_fname[gr_screen.res]);
        if (title_bitmap == -1) {
@@ -8195,11 +8224,15 @@ void display_title_screen()
        gr_flip();
 
        // give it some time on screen
+#ifdef __EMSCRIPTEN__
+       emscripten_sleep(1000);
+#else
        SDL_Delay(1000);
+#endif
 
        bm_unload(title_bitmap);
-#endif  // FS2_DEMO || OEM_BUILD
 }
+#endif  // FS2_DEMO || OEM_BUILD
 
 // return true if the game is running with "low memory", which is less than 48MB
 bool game_using_low_mem()
index 8107e62..b23add0 100644 (file)
@@ -80,6 +80,7 @@ extern void message_pagein_mission_messages();
 
 // Pages in all the texutures for the currently
 // loaded mission.  Call game_busy() occasionally...
+extern "C"
 void level_page_in()
 {
 
index 9a8d592..069f734 100644 (file)
@@ -17,7 +17,7 @@
 #endif
 
 
-extern int game_main(const char *szCmdLine);
+extern "C" int game_main(const char *szCmdLine);
 
 
 #ifdef PLAT_UNIX
index 36e5fa2..cdf3c73 100644 (file)
@@ -456,6 +456,7 @@ int gameseq_get_depth()
        return gs_current_stack;
 }
 
+extern "C"
 void gameseq_set_state(int new_state, int override)
 {
        int event, old_state;
@@ -580,7 +581,7 @@ int gameseq_get_pushed_state()
 // Returns the current state.
                // pull events game sequence events off of the queue.  Process one at a time
                // based on the current state and the new event.
-
+extern "C"
 int gameseq_process_events()   
 {
        int event, old_state;
index 9e40673..6db42a5 100644 (file)
@@ -205,6 +205,7 @@ void gamesnd_play_iface(int n)
 // The method currently used is to load all those sounds that have the hardware flag
 // set.  This works well since we don't want to try and load hardware sounds in on the
 // fly (too slow).
+extern "C"
 void gamesnd_preload_common_sounds()
 {
        int             i;
index 7d78ef2..bf8e597 100644 (file)
@@ -290,6 +290,7 @@ static int cb_delta_step = -1;
 // by calling game_busy_callback(NULL).   Game_busy_callback
 // returns the current count, so you can tell how many times
 // game_busy got called.
+extern "C"
 int game_busy_callback( void (*callback)(int count), int delta_step )
 {
        if ( !callback ) {
@@ -319,6 +320,7 @@ int game_busy_callback( void (*callback)(int count), int delta_step )
 }
 
 // Call whenever loading to display cursor
+extern "C"
 void game_busy()
 {
        if ( cf_in_callback != 0 ) return;      // don't call callback if we're already in it.