Feature/loading race screen (#40)

* Adds loading splash screen, switch to single threaded mode
This commit is contained in:
Jeff Harris 2020-09-23 12:03:00 -07:00 committed by GitHub
parent f665dbf6cf
commit dd05afea6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 187 additions and 78 deletions

View File

@ -1,13 +1,14 @@
#include "cutscene.h" #include "cutscene.h"
#include "common/errors.h" #include "errors.h"
#include "common/globvars.h" #include "globvars.h"
#include "common/graphics.h" #include "globvrpb.h"
#include "common/input.h" #include "graphics.h"
#include "common/loading.h" #include "input.h"
#include "common/utility.h"
#include "libsmacker/smacker.h" #include "libsmacker/smacker.h"
#include "loading.h"
#include "pc-dos/dossys.h" #include "pc-dos/dossys.h"
#include "sound.h" #include "sound.h"
#include "utility.h"
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
@ -141,7 +142,14 @@ void DoNewGameAnimation() {
// IDA: void __cdecl DoGoToRaceAnimation() // IDA: void __cdecl DoGoToRaceAnimation()
void DoGoToRaceAnimation() { void DoGoToRaceAnimation() {
LOG_TRACE("()"); LOG_TRACE("()");
NOT_IMPLEMENTED();
if (!gNet_mode) {
if (PercentageChance(50)) {
PlaySmackerFile("GARAGE2.SMK");
} else {
PlaySmackerFile("GARAGE1.SMK");
}
}
} }
// IDA: void __cdecl DoEndRaceAnimation() // IDA: void __cdecl DoEndRaceAnimation()
@ -167,5 +175,7 @@ void DoGameCompletedAnimation() {
// IDA: void __cdecl StartLoadingScreen() // IDA: void __cdecl StartLoadingScreen()
void StartLoadingScreen() { void StartLoadingScreen() {
LOG_TRACE("()"); LOG_TRACE("()");
NOT_IMPLEMENTED();
PossibleService();
SplashScreenWith("LOADSCRN.PIX");
} }

View File

@ -721,7 +721,10 @@ void MungePalette() {
// IDA: void __cdecl ResetPalette() // IDA: void __cdecl ResetPalette()
void ResetPalette() { void ResetPalette() {
LOG_TRACE("()"); LOG_TRACE("()");
NOT_IMPLEMENTED();
gPalette_index = 0;
gPalette_munged = 0;
DRSetPalette2(gRender_palette, 1);
} }
// IDA: void __usercall Darken(tU8 *pPtr@<EAX>, unsigned int pDarken_amount@<EDX>) // IDA: void __usercall Darken(tU8 *pPtr@<EAX>, unsigned int pDarken_amount@<EDX>)
@ -824,7 +827,45 @@ void EnsureRenderPalette() {
void SplashScreenWith(char* pPixmap_name) { void SplashScreenWith(char* pPixmap_name) {
br_pixelmap* the_map; br_pixelmap* the_map;
LOG_TRACE("(\"%s\")", pPixmap_name); 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() // IDA: void __cdecl EnsurePaletteUp()

View File

@ -221,14 +221,95 @@ int FrankieOrAnnie() {
// IDA: int __cdecl SelectSkillLevel() // IDA: int __cdecl SelectSkillLevel()
int SelectSkillLevel() { int SelectSkillLevel() {
static tFlicette flicker_on[4]; static tFlicette flicker_on[4] = {
static tFlicette flicker_off[4]; { 116, { 38, 76 }, { 55, 132 } },
static tFlicette push[4]; { 119, { 36, 72 }, { 83, 199 } },
static tMouse_area mouse_areas[4]; { 121, { 38, 76 }, { 111, 266 } },
static tInterface_spec interface_spec; { 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; int result;
LOG_TRACE("()"); 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() // IDA: int __cdecl DoOnePlayerStart()

View File

@ -146,7 +146,7 @@ int IRandomBetween(int pA, int pB) {
// IDA: int __usercall PercentageChance@<EAX>(int pC@<EAX>) // IDA: int __usercall PercentageChance@<EAX>(int pC@<EAX>)
int PercentageChance(int pC) { int PercentageChance(int pC) {
LOG_TRACE("(%d)", pC); LOG_TRACE("(%d)", pC);
NOT_IMPLEMENTED(); return (rand() % 100) < pC;
} }
// IDA: int __usercall IRandomPosNeg@<EAX>(int pN@<EAX>) // IDA: int __usercall IRandomPosNeg@<EAX>(int pN@<EAX>)

View File

@ -6,19 +6,7 @@
extern int original_main(int pArgc, char* pArgv[]); 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[]) { int main(int argc, char* argv[]) {
_argc = argc;
_argv = argv;
int result; int result;
Harness_Init(argv[0], &OpenGLRenderer); Harness_Init(argv[0], &OpenGLRenderer);
@ -33,5 +21,5 @@ int main(int argc, char* argv[]) {
LOG_PANIC("Failed to chdir. Returned %d", result); LOG_PANIC("Failed to chdir. Returned %d", result);
} }
Harness_RunWindowLoop(&game_thread_func, NULL); return original_main(argc, argv);
} }

View File

@ -545,6 +545,7 @@ int PDGetTotalTime() {
// IDA: int __usercall PDServiceSystem@<EAX>(tU32 pTime_since_last_call@<EAX>) // IDA: int __usercall PDServiceSystem@<EAX>(tU32 pTime_since_last_call@<EAX>)
int PDServiceSystem(tU32 pTime_since_last_call) { int PDServiceSystem(tU32 pTime_since_last_call) {
Harness_Hook_PDServiceSystem(pTime_since_last_call);
return 0; return 0;
} }

View File

@ -4,7 +4,6 @@
#include "stack_trace_handler.h" #include "stack_trace_handler.h"
SDL_Window* window; SDL_Window* window;
SDL_Thread* game_thread;
renderer* current_renderer; renderer* current_renderer;
br_pixelmap* palette; br_pixelmap* palette;
uint32_t* screen_buffer; uint32_t* screen_buffer;
@ -18,16 +17,39 @@ void Harness_Init(char* name, renderer* renderer) {
current_renderer = renderer; current_renderer = renderer;
screen_buffer = NULL; screen_buffer = NULL;
game_mode = eGame_mode_Carmageddon; 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() { eGame_mode Harness_GameMode() {
return game_mode; return game_mode;
} }
void Harness_RunWindowLoop(harness_game_func* game_func, void* arg) { void Harness_Hook_DOSGfxBegin() {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { if (SDL_Init(SDL_INIT_VIDEO) != 0) {
LOG_PANIC("SDL_Init Error: %s", SDL_GetError()); LOG_PANIC("SDL_INIT_VIDEO error: %s", SDL_GetError());
} }
window = SDL_CreateWindow("Dethrace", window = SDL_CreateWindow("Dethrace",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
@ -37,31 +59,11 @@ void Harness_RunWindowLoop(harness_game_func* game_func, void* arg) {
if (!window) { if (!window) {
LOG_PANIC("Failed to create window"); LOG_PANIC("Failed to create window");
} }
current_renderer->init(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() { void Harness_Hook_PDServiceSystem(int pTime_since_last_call) {
current_renderer->activate(window); Harness_PumpEvents();
} }
void Harness_RenderScreen(br_pixelmap* dst, br_pixelmap* src) { 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)); 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 // generate 32 bit texture from src + palette
for (y = 0; y < src->height; y++) { for (y = 0; y < src->height; y++) {
inc = 0; inc = 0;
@ -91,6 +91,7 @@ void Harness_RenderScreen(br_pixelmap* dst, br_pixelmap* src) {
} }
} }
current_renderer->doubleBuffer(screen_buffer, window); current_renderer->doubleBuffer(screen_buffer, window);
Harness_PumpEvents();
} }
void Harness_Hook_BrPixelmapDoubleBuffer(br_pixelmap* dst, br_pixelmap* src) { void Harness_Hook_BrPixelmapDoubleBuffer(br_pixelmap* dst, br_pixelmap* src) {

View File

@ -10,7 +10,6 @@ typedef int harness_game_func(void*);
typedef struct renderer { typedef struct renderer {
int (*get_window_flags)(); int (*get_window_flags)();
void (*init)(SDL_Window* window); void (*init)(SDL_Window* window);
void (*activate)(SDL_Window* window);
void (*doubleBuffer)(uint32_t* src, SDL_Window* window); void (*doubleBuffer)(uint32_t* src, SDL_Window* window);
} renderer; } renderer;
@ -33,4 +32,6 @@ void Harness_Hook_BrPixelmapDoubleBuffer(br_pixelmap* dst, br_pixelmap* src);
void Harness_Hook_KeyBegin(); void Harness_Hook_KeyBegin();
int Harness_Hook_KeyDown(unsigned char pScan_code); int Harness_Hook_KeyDown(unsigned char pScan_code);
void Harness_Hook_PDServiceSystem(int pTime_since_last_call);
#endif #endif

View File

@ -15,11 +15,10 @@
renderer OpenGLRenderer = { renderer OpenGLRenderer = {
Harness_GLRenderer_GetWindowFlags, Harness_GLRenderer_GetWindowFlags,
Harness_GLRenderer_Init, Harness_GLRenderer_Init,
Harness_GLRenderer_Activate,
Harness_GLRenderer_DoubleBuffer, Harness_GLRenderer_DoubleBuffer,
}; };
SDL_GLContext context, context2; SDL_GLContext context;
GLuint VBO, VAO, EBO; GLuint VBO, VAO, EBO;
GLuint screen_texture; GLuint screen_texture;
GLuint shader_program; GLuint shader_program;
@ -33,18 +32,6 @@ int Harness_GLRenderer_GetWindowFlags() {
return SDL_WINDOW_OPENGL; 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) { void CompileShader(GLuint shader_id, const GLchar* source) {
int success; int success;
char log[512]; 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; GLuint vs, fs;
int result = SDL_GL_MakeCurrent(window, context); context = SDL_GL_CreateContext(window);
if (result != 0) { if (!context) {
LOG_PANIC("Failed to call SDL_GL_MakeCurrent. %s", SDL_GetError()); LOG_PANIC("Failed to call SDL_GL_CreateContext. %s", SDL_GetError());
} }
const char* vs_source = "#version 330 core\n" const char* vs_source = "#version 330 core\n"

View File

@ -10,6 +10,5 @@ void Harness_NullRenderer_DoubleBuffer(uint32_t* src, SDL_Window* window) {}
renderer NullRenderer = { renderer NullRenderer = {
Harness_NullRenderer_GetWindowFlags, Harness_NullRenderer_GetWindowFlags,
Harness_NullRenderer_Init, Harness_NullRenderer_Init,
Harness_NullRenderer_Activate,
Harness_NullRenderer_DoubleBuffer Harness_NullRenderer_DoubleBuffer
}; };