From dd05afea6ed75552707738a9a3f9a0996b173f8c Mon Sep 17 00:00:00 2001 From: Jeff Harris Date: Wed, 23 Sep 2020 12:03:00 -0700 Subject: [PATCH] Feature/loading race screen (#40) * Adds loading splash screen, switch to single threaded mode --- src/DETHRACE/common/cutscene.c | 26 +++++--- src/DETHRACE/common/graphics.c | 45 ++++++++++++- src/DETHRACE/common/newgame.c | 93 +++++++++++++++++++++++++-- src/DETHRACE/common/utility.c | 2 +- src/DETHRACE/main.c | 14 +--- src/DETHRACE/pc-dos/dossys.c | 1 + src/harness/harness.c | 57 ++++++++-------- src/harness/harness.h | 3 +- src/harness/renderers/gl_renderer.c | 23 ++----- src/harness/renderers/null_renderer.c | 1 - 10 files changed, 187 insertions(+), 78 deletions(-) diff --git a/src/DETHRACE/common/cutscene.c b/src/DETHRACE/common/cutscene.c index 4716f560..1e3644ce 100644 --- a/src/DETHRACE/common/cutscene.c +++ b/src/DETHRACE/common/cutscene.c @@ -1,13 +1,14 @@ #include "cutscene.h" -#include "common/errors.h" -#include "common/globvars.h" -#include "common/graphics.h" -#include "common/input.h" -#include "common/loading.h" -#include "common/utility.h" +#include "errors.h" +#include "globvars.h" +#include "globvrpb.h" +#include "graphics.h" +#include "input.h" #include "libsmacker/smacker.h" +#include "loading.h" #include "pc-dos/dossys.h" #include "sound.h" +#include "utility.h" #include #include #include @@ -141,7 +142,14 @@ void DoNewGameAnimation() { // IDA: void __cdecl DoGoToRaceAnimation() void DoGoToRaceAnimation() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + if (!gNet_mode) { + if (PercentageChance(50)) { + PlaySmackerFile("GARAGE2.SMK"); + } else { + PlaySmackerFile("GARAGE1.SMK"); + } + } } // IDA: void __cdecl DoEndRaceAnimation() @@ -167,5 +175,7 @@ void DoGameCompletedAnimation() { // IDA: void __cdecl StartLoadingScreen() void StartLoadingScreen() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + PossibleService(); + SplashScreenWith("LOADSCRN.PIX"); } diff --git a/src/DETHRACE/common/graphics.c b/src/DETHRACE/common/graphics.c index c5036f04..181d0922 100644 --- a/src/DETHRACE/common/graphics.c +++ b/src/DETHRACE/common/graphics.c @@ -721,7 +721,10 @@ void MungePalette() { // IDA: void __cdecl ResetPalette() void ResetPalette() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + gPalette_index = 0; + gPalette_munged = 0; + DRSetPalette2(gRender_palette, 1); } // IDA: void __usercall Darken(tU8 *pPtr@, unsigned int pDarken_amount@) @@ -824,7 +827,45 @@ void EnsureRenderPalette() { void SplashScreenWith(char* pPixmap_name) { br_pixelmap* the_map; LOG_TRACE("(\"%s\")", pPixmap_name); - NOT_IMPLEMENTED(); + + the_map = BrMapFind(pPixmap_name); + if (!gCurrent_splash || the_map != gCurrent_splash) { + FadePaletteDown(); + if (gPalette_munged) { + ResetPalette(); + gPalette_munged = 0; + } + if (gCurrent_splash) { + BrMapRemove(gCurrent_splash); + BrPixelmapFree(gCurrent_splash); + gCurrent_splash = 0; + FadePaletteDown(); + ClearEntireScreen(); + } + gCurrent_splash = the_map; + if (!the_map) { + the_map = LoadPixelmap(pPixmap_name); + gCurrent_splash = the_map; + if (the_map) { + BrMapAdd(the_map); + } + } + if (gCurrent_splash) { + BrPixelmapRectangleCopy( + gBack_screen, + 0, + 0, + gCurrent_splash, + 0, + 0, + gCurrent_splash->width, + gCurrent_splash->height); + PDScreenBufferSwap(0); + if (gFaded_palette) { + FadePaletteUp(); + } + } + } } // IDA: void __cdecl EnsurePaletteUp() diff --git a/src/DETHRACE/common/newgame.c b/src/DETHRACE/common/newgame.c index 48a05de5..5eb28744 100644 --- a/src/DETHRACE/common/newgame.c +++ b/src/DETHRACE/common/newgame.c @@ -221,14 +221,95 @@ int FrankieOrAnnie() { // IDA: int __cdecl SelectSkillLevel() int SelectSkillLevel() { - static tFlicette flicker_on[4]; - static tFlicette flicker_off[4]; - static tFlicette push[4]; - static tMouse_area mouse_areas[4]; - static tInterface_spec interface_spec; + static tFlicette flicker_on[4] = { + { 116, { 38, 76 }, { 55, 132 } }, + { 119, { 36, 72 }, { 83, 199 } }, + { 121, { 38, 76 }, { 111, 266 } }, + { 43, { 227, 454 }, { 158, 379 } } + }; + + static tFlicette flicker_off[4] = { + { 115, { 38, 76 }, { 55, 132 } }, + { 118, { 36, 72 }, { 83, 199 } }, + { 120, { 38, 76 }, { 111, 266 } }, + { 42, { 227, 454 }, { 158, 379 } } + }; + + static tFlicette push[4] = { + { 117, { 38, 76 }, { 55, 132 } }, + { 117, { 36, 72 }, { 83, 199 } }, + { 117, { 38, 76 }, { 111, 266 } }, + { 45, { 227, 454 }, { 158, 379 } } + }; + static tMouse_area mouse_areas[4] = { + { { 38, 76 }, { 55, 132 }, { 205, 410 }, { 69, 166 }, 0, 0, 0, NULL }, + { { 36, 72 }, { 83, 199 }, { 205, 410 }, { 98, 235 }, 1, 0, 0, NULL }, + { { 38, 76 }, { 111, 266 }, { 205, 410 }, { 125, 300 }, 2, 0, 0, NULL }, + { { 227, 454 }, { 158, 379 }, { 290, 580 }, { 178, 427 }, 3, 0, 0, NULL } + }; + + static tInterface_spec interface_spec = { + 0, // initial_imode + 110, // first_opening_flic + 0, // second_opening_flic + -1, // end_flic_go_ahead + 111, // end_flic_escaped + -1, // end_flic_otherwise + 0, // flic_bunch_to_load + { -1, 0 }, // move_left_new_mode + { 0, 0 }, // move_left_delta + { 0, 0 }, // move_left_min + { 0, 0 }, // move_left_max + { NULL, NULL }, // move_left_proc + { -1, 0 }, // move_right_new_mode + { 0, 0 }, // move_right_delta + { 0, 0 }, // move_right_min + { 0, 0 }, // move_right_max + { NULL, NULL }, // move_right_proc + { -1, 0 }, // move_up_new_mode + { -1, 0 }, // move_up_delta + { 0, 0 }, // move_up_min + { 3, 0 }, // move_up_max + { NULL, NULL }, // move_up_proc + { -1, 0 }, // move_down_new_mode + { 1, 0 }, // move_down_delta + { 0, 0 }, // move_down_min + { 3, 0 }, // move_down_max + { NULL, NULL }, // move_down_proc + { 1, 1 }, // go_ahead_allowed + { NULL, NULL }, // go_ahead_proc + { 1, 1 }, // escape_allowed + { NULL, NULL }, // escape_proc + NULL, // exit_proc + NULL, // draw_proc + 0u, // time_out + NULL, // start_proc1 + NULL, // start_proc2 + NULL, // done_proc + 0, // font_needed + { 0, 0 }, // typeable + NULL, // get_original_string + 3, // escape_code + 1, // dont_save_or_load + 4, // number_of_button_flics + flicker_on, // flicker_on_flics + flicker_off, // flicker_off_flics + push, // pushed_flics + 4, // number_of_mouse_areas + mouse_areas, // mouse_areas + 0, // number_of_recopy_areas + NULL // recopy_areas + }; + int result; LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + result = DoInterfaceScreen(&interface_spec, 0, gProgram_state.skill_level); + if (result > 2) { + return 0; + } + gProgram_state.skill_level = result; + return 1; } // IDA: int __cdecl DoOnePlayerStart() diff --git a/src/DETHRACE/common/utility.c b/src/DETHRACE/common/utility.c index 9ede1c4e..62cda84f 100644 --- a/src/DETHRACE/common/utility.c +++ b/src/DETHRACE/common/utility.c @@ -146,7 +146,7 @@ int IRandomBetween(int pA, int pB) { // IDA: int __usercall PercentageChance@(int pC@) int PercentageChance(int pC) { LOG_TRACE("(%d)", pC); - NOT_IMPLEMENTED(); + return (rand() % 100) < pC; } // IDA: int __usercall IRandomPosNeg@(int pN@) diff --git a/src/DETHRACE/main.c b/src/DETHRACE/main.c index e229095b..177cc692 100644 --- a/src/DETHRACE/main.c +++ b/src/DETHRACE/main.c @@ -6,19 +6,7 @@ extern int original_main(int pArgc, char* pArgv[]); -int _argc; -char** _argv; - -int game_thread_func(void* args) { - int exit_code; - exit_code = original_main(_argc, _argv); - // TODO: maybe we should be kinder here and post a message to the window thread to shutdown cleanly. - exit(exit_code); -} - int main(int argc, char* argv[]) { - _argc = argc; - _argv = argv; int result; Harness_Init(argv[0], &OpenGLRenderer); @@ -33,5 +21,5 @@ int main(int argc, char* argv[]) { LOG_PANIC("Failed to chdir. Returned %d", result); } - Harness_RunWindowLoop(&game_thread_func, NULL); + return original_main(argc, argv); } diff --git a/src/DETHRACE/pc-dos/dossys.c b/src/DETHRACE/pc-dos/dossys.c index 3ea742eb..42cf95ac 100644 --- a/src/DETHRACE/pc-dos/dossys.c +++ b/src/DETHRACE/pc-dos/dossys.c @@ -545,6 +545,7 @@ int PDGetTotalTime() { // IDA: int __usercall PDServiceSystem@(tU32 pTime_since_last_call@) int PDServiceSystem(tU32 pTime_since_last_call) { + Harness_Hook_PDServiceSystem(pTime_since_last_call); return 0; } diff --git a/src/harness/harness.c b/src/harness/harness.c index d7f1b854..9db19f02 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -4,7 +4,6 @@ #include "stack_trace_handler.h" SDL_Window* window; -SDL_Thread* game_thread; renderer* current_renderer; br_pixelmap* palette; uint32_t* screen_buffer; @@ -18,16 +17,39 @@ void Harness_Init(char* name, renderer* renderer) { current_renderer = renderer; screen_buffer = NULL; game_mode = eGame_mode_Carmageddon; + + if (SDL_Init(SDL_INIT_TIMER) != 0) { + LOG_PANIC("SDL_INIT_TIMER error: %s", SDL_GetError()); + } +} + +void Harness_PumpEvents() { + SDL_Event event; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + + case SDL_KEYDOWN: + case SDL_KEYUP: + Keyboard_HandleEvent(&event.key); + break; + + case SDL_QUIT: + LOG_PANIC("QuitGame"); + break; + } + } } eGame_mode Harness_GameMode() { return game_mode; } -void Harness_RunWindowLoop(harness_game_func* game_func, void* arg) { - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { - LOG_PANIC("SDL_Init Error: %s", SDL_GetError()); +void Harness_Hook_DOSGfxBegin() { + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + LOG_PANIC("SDL_INIT_VIDEO error: %s", SDL_GetError()); } + window = SDL_CreateWindow("Dethrace", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, @@ -37,31 +59,11 @@ void Harness_RunWindowLoop(harness_game_func* game_func, void* arg) { if (!window) { LOG_PANIC("Failed to create window"); } - current_renderer->init(window); - - game_thread = SDL_CreateThread(game_func, "game_thread", arg); - - SDL_Event event; - int keep_pumping = 1; - while (keep_pumping) { - if (SDL_WaitEvent(&event)) { - switch (event.type) { - - case SDL_KEYDOWN: - case SDL_KEYUP: - Keyboard_HandleEvent(&event.key); - break; - case SDL_QUIT: - keep_pumping = 0; - } - } - } - LOG_PANIC("leaving loop"); } -void Harness_Hook_DOSGfxBegin() { - current_renderer->activate(window); +void Harness_Hook_PDServiceSystem(int pTime_since_last_call) { + Harness_PumpEvents(); } void Harness_RenderScreen(br_pixelmap* dst, br_pixelmap* src) { @@ -78,8 +80,6 @@ void Harness_RenderScreen(br_pixelmap* dst, br_pixelmap* src) { memset(screen_buffer, 0, src->width * src->height * sizeof(uint32_t)); } - //LOG_DEBUG("%d %d, %d", src->width, src->height, src->row_bytes); - // generate 32 bit texture from src + palette for (y = 0; y < src->height; y++) { inc = 0; @@ -91,6 +91,7 @@ void Harness_RenderScreen(br_pixelmap* dst, br_pixelmap* src) { } } current_renderer->doubleBuffer(screen_buffer, window); + Harness_PumpEvents(); } void Harness_Hook_BrPixelmapDoubleBuffer(br_pixelmap* dst, br_pixelmap* src) { diff --git a/src/harness/harness.h b/src/harness/harness.h index b6c8e041..94c5f760 100644 --- a/src/harness/harness.h +++ b/src/harness/harness.h @@ -10,7 +10,6 @@ typedef int harness_game_func(void*); typedef struct renderer { int (*get_window_flags)(); void (*init)(SDL_Window* window); - void (*activate)(SDL_Window* window); void (*doubleBuffer)(uint32_t* src, SDL_Window* window); } renderer; @@ -33,4 +32,6 @@ void Harness_Hook_BrPixelmapDoubleBuffer(br_pixelmap* dst, br_pixelmap* src); void Harness_Hook_KeyBegin(); int Harness_Hook_KeyDown(unsigned char pScan_code); +void Harness_Hook_PDServiceSystem(int pTime_since_last_call); + #endif \ No newline at end of file diff --git a/src/harness/renderers/gl_renderer.c b/src/harness/renderers/gl_renderer.c index 5aeb6127..76998172 100644 --- a/src/harness/renderers/gl_renderer.c +++ b/src/harness/renderers/gl_renderer.c @@ -15,11 +15,10 @@ renderer OpenGLRenderer = { Harness_GLRenderer_GetWindowFlags, Harness_GLRenderer_Init, - Harness_GLRenderer_Activate, Harness_GLRenderer_DoubleBuffer, }; -SDL_GLContext context, context2; +SDL_GLContext context; GLuint VBO, VAO, EBO; GLuint screen_texture; GLuint shader_program; @@ -33,18 +32,6 @@ int Harness_GLRenderer_GetWindowFlags() { return SDL_WINDOW_OPENGL; } -void Harness_GLRenderer_Init(SDL_Window* window) { - - context = SDL_GL_CreateContext(window); - if (!context) { - LOG_PANIC("Failed to call SDL_GL_CreateContext. %s", SDL_GetError()); - } - context2 = SDL_GL_CreateContext(window); - if (!context2) { - LOG_PANIC("Failed to call SDL_GL_CreateContext (2). %s", SDL_GetError()); - } -} - void CompileShader(GLuint shader_id, const GLchar* source) { int success; char log[512]; @@ -57,12 +44,12 @@ void CompileShader(GLuint shader_id, const GLchar* source) { } } -void Harness_GLRenderer_Activate(SDL_Window* window) { +void Harness_GLRenderer_Init(SDL_Window* window) { GLuint vs, fs; - int result = SDL_GL_MakeCurrent(window, context); - if (result != 0) { - LOG_PANIC("Failed to call SDL_GL_MakeCurrent. %s", SDL_GetError()); + context = SDL_GL_CreateContext(window); + if (!context) { + LOG_PANIC("Failed to call SDL_GL_CreateContext. %s", SDL_GetError()); } const char* vs_source = "#version 330 core\n" diff --git a/src/harness/renderers/null_renderer.c b/src/harness/renderers/null_renderer.c index f20e3d3a..8076ef08 100644 --- a/src/harness/renderers/null_renderer.c +++ b/src/harness/renderers/null_renderer.c @@ -10,6 +10,5 @@ void Harness_NullRenderer_DoubleBuffer(uint32_t* src, SDL_Window* window) {} renderer NullRenderer = { Harness_NullRenderer_GetWindowFlags, Harness_NullRenderer_Init, - Harness_NullRenderer_Activate, Harness_NullRenderer_DoubleBuffer }; \ No newline at end of file