From f98ec8c36c80056d0244c699f04150d02d28a1a7 Mon Sep 17 00:00:00 2001 From: Taylor Richards Date: Sun, 14 Jan 2018 15:21:59 -0500 Subject: [PATCH] make loading screen and title screen work with emterpreter async --- CMakeLists.txt | 53 +++++++++++---------- include/bmpman.h | 2 +- include/freespace.h | 2 +- include/gamesequence.h | 8 ++-- include/gamesnd.h | 2 +- include/levelpaging.h | 2 +- include/pstypes.h | 4 +- src/bmpman/bmpman.cpp | 1 + src/freespace2/freespace.cpp | 79 ++++++++++++++++++++++--------- src/freespace2/levelpaging.cpp | 1 + src/freespace2/main.cpp | 2 +- src/gamesequence/gamesequence.cpp | 3 +- src/gamesnd/gamesnd.cpp | 1 + src/globalincs/systemvars.cpp | 2 + 14 files changed, 101 insertions(+), 61 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7be6276..5f7d3ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/include/bmpman.h b/include/bmpman.h index 8e82b84..bb03f56 100644 --- a/include/bmpman.h +++ b/include/bmpman.h @@ -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. diff --git a/include/freespace.h b/include/freespace.h index ee4cce3..042b32a 100644 --- a/include/freespace.h +++ b/include/freespace.h @@ -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(); diff --git a/include/gamesequence.h b/include/gamesequence.h index 169544e..6dec9ef 100644 --- a/include/gamesequence.h +++ b/include/gamesequence.h @@ -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__ */ diff --git a/include/gamesnd.h b/include/gamesnd.h index 233b4c6..4a1be72 100644 --- a/include/gamesnd.h +++ b/include/gamesnd.h @@ -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(); diff --git a/include/levelpaging.h b/include/levelpaging.h index aa26c1f..f8db5f6 100644 --- a/include/levelpaging.h +++ b/include/levelpaging.h @@ -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 diff --git a/include/pstypes.h b/include/pstypes.h index 2d55ac0..98da92c 100644 --- a/include/pstypes.h +++ b/include/pstypes.h @@ -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(); //========================================================= diff --git a/src/bmpman/bmpman.cpp b/src/bmpman/bmpman.cpp index babe672..35f9661 100644 --- a/src/bmpman/bmpman.cpp +++ b/src/bmpman/bmpman.cpp @@ -2118,6 +2118,7 @@ void bm_page_in_start() } +extern "C" void bm_page_in_stop() { int i; diff --git a/src/freespace2/freespace.cpp b/src/freespace2/freespace.cpp index 05bfd4b..f3745be 100644 --- a/src/freespace2/freespace.cpp +++ b/src/freespace2/freespace.cpp @@ -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() diff --git a/src/freespace2/levelpaging.cpp b/src/freespace2/levelpaging.cpp index 8107e62..b23add0 100644 --- a/src/freespace2/levelpaging.cpp +++ b/src/freespace2/levelpaging.cpp @@ -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() { diff --git a/src/freespace2/main.cpp b/src/freespace2/main.cpp index 9a8d592..069f734 100644 --- a/src/freespace2/main.cpp +++ b/src/freespace2/main.cpp @@ -17,7 +17,7 @@ #endif -extern int game_main(const char *szCmdLine); +extern "C" int game_main(const char *szCmdLine); #ifdef PLAT_UNIX diff --git a/src/gamesequence/gamesequence.cpp b/src/gamesequence/gamesequence.cpp index 36e5fa2..cdf3c73 100644 --- a/src/gamesequence/gamesequence.cpp +++ b/src/gamesequence/gamesequence.cpp @@ -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; diff --git a/src/gamesnd/gamesnd.cpp b/src/gamesnd/gamesnd.cpp index 9e40673..6db42a5 100644 --- a/src/gamesnd/gamesnd.cpp +++ b/src/gamesnd/gamesnd.cpp @@ -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; diff --git a/src/globalincs/systemvars.cpp b/src/globalincs/systemvars.cpp index 7d78ef2..bf8e597 100644 --- a/src/globalincs/systemvars.cpp +++ b/src/globalincs/systemvars.cpp @@ -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. -- 2.39.2