From 2510f216a9a56dfa5ce38749269069ef7167ad3d Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 14 Mar 2022 14:13:39 +1300 Subject: [PATCH 01/28] wip --- src/DETHRACE/common/mainloop.c | 2 - src/harness/CMakeLists.txt | 29 +- src/harness/harness.c | 99 +++-- src/harness/harness.h | 26 +- src/harness/include/harness/hooks.h | 5 +- src/harness/include/harness/trace.h | 32 +- src/harness/platforms/platform.h | 6 +- src/harness/platforms/platform_linux.c | 212 ++++++++++- src/harness/platforms/platform_macosx.c | 216 ++++++++++- src/harness/platforms/platform_windows.c | 154 +++++++- src/harness/platforms/sdl_gl.h | 25 -- .../{sdl => renderers/gl}/gl_renderer.c | 75 +--- .../{sdl => renderers/gl}/gl_renderer.h | 9 +- .../gl/shaders.c} | 0 .../gl/shaders.h} | 0 .../gl/stored_context.c} | 2 +- .../gl/stored_context.h} | 0 src/harness/{platforms => renderers}/null.h | 16 +- src/harness/renderers/renderer.h | 20 ++ src/harness/sdl/common.h | 11 - src/harness/stack_trace_handler.h | 338 ------------------ .../{sdl/common.c => window_io/sdl/sdl_gl.c} | 85 ++++- test/CMakeLists.txt | 2 + test/main.c | 2 + 24 files changed, 785 insertions(+), 581 deletions(-) delete mode 100644 src/harness/platforms/sdl_gl.h rename src/harness/{sdl => renderers/gl}/gl_renderer.c (92%) rename src/harness/{sdl => renderers/gl}/gl_renderer.h (69%) rename src/harness/{sdl/gl_renderer_shaders.c => renderers/gl/shaders.c} (100%) rename src/harness/{sdl/gl_renderer_shaders.h => renderers/gl/shaders.h} (100%) rename src/harness/{sdl/gl_brender_stored_context.c => renderers/gl/stored_context.c} (96%) rename src/harness/{sdl/gl_brender_stored_context.h => renderers/gl/stored_context.h} (100%) rename src/harness/{platforms => renderers}/null.h (64%) create mode 100644 src/harness/renderers/renderer.h delete mode 100644 src/harness/sdl/common.h delete mode 100644 src/harness/stack_trace_handler.h rename src/harness/{sdl/common.c => window_io/sdl/sdl_gl.c} (58%) diff --git a/src/DETHRACE/common/mainloop.c b/src/DETHRACE/common/mainloop.c index 349cd4c0..7df5a5c8 100644 --- a/src/DETHRACE/common/mainloop.c +++ b/src/DETHRACE/common/mainloop.c @@ -635,8 +635,6 @@ tRace_result MainGameLoop() { gAbandon_game = 0; } - Harness_Hook_MainGameLoop(); - } while (gProgram_state.prog_status == eProg_game_ongoing && !MungeRaceFinished() && !gAbandon_game diff --git a/src/harness/CMakeLists.txt b/src/harness/CMakeLists.txt index 350c27cb..3ddb96f7 100644 --- a/src/harness/CMakeLists.txt +++ b/src/harness/CMakeLists.txt @@ -1,5 +1,9 @@ add_library(harness STATIC) +if (NOT DEFINED RENDERER_PLATFORM) + set(RENDERER_PLATFORM "SDL_OpenGL") +endif() + target_include_directories(harness PRIVATE . @@ -36,23 +40,26 @@ target_sources(harness PRIVATE harness_trace.c harness.c harness.h - sdl/gl_renderer.c - sdl/gl_renderer.h - sdl/gl_renderer_shaders.c - sdl/gl_renderer_shaders.h - sdl/gl_brender_stored_context.c - sdl/gl_brender_stored_context.h + platforms/null.h + renderers/renderer.h brender_emu/renderer_impl.c brender_emu/renderer_impl.h sound/sound.c sound/sound.h - sdl/common.c - sdl/common.h - platforms/sdl_gl.h - platforms/null.h - stack_trace_handler.h ) +if (RENDERER_PLATFORM STREQUAL "SDL_OpenGL") + target_sources(harness PRIVATE + window_io/sdl/sdl_gl.c + renderers/gl/gl_renderer.c + renderers/gl/gl_renderer.h + renderers/gl/shaders.c + renderers/gl/shaders.h + renderers/gl/stored_context.c + renderers/gl/stored_context.h + ) +endif() + if(WIN32) target_sources(harness PRIVATE platforms/platform_windows.c diff --git a/src/harness/harness.c b/src/harness/harness.c index 425542c6..50b29d58 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -2,16 +2,17 @@ #include "harness.h" #include "brender_emu/renderer_impl.h" #include "include/harness/config.h" -#include "platforms/null.h" -#include "platforms/sdl_gl.h" +#include "platforms/platform.h" +#include "renderers/null.h" #include "sound/sound.h" -#include "stack_trace_handler.h" +#include +#include #include #include #include -tPlatform* platform; +tRenderer* renderer; br_pixelmap* palette; uint32_t* screen_buffer; harness_br_renderer* renderer_state; @@ -22,6 +23,7 @@ br_pixelmap* last_src = NULL; br_pixelmap *last_colour_buffer, *last_depth_buffer; unsigned int last_frame_time = 0; +int force_nullrenderer = 0; extern unsigned int GetTotalTime(); extern uint8_t gScan_code[123][2]; @@ -72,11 +74,10 @@ void Harness_Init(int* argc, char* argv[]) { Harness_ProcessCommandLine(argc, argv); if (harness_game_config.install_signalhandler) { - install_signal_handler(argv[0]); + Platform_InstallSignalHandler(argv[0]); } - platform->Init(); - int* keymap = platform->GetKeyMap(); + int* keymap = Input_GetKeyMap(); if (keymap != NULL) { for (int i = 0; i < 123; i++) { gScan_code[i][0] = keymap[i]; @@ -99,15 +100,16 @@ void Harness_Init(int* argc, char* argv[]) { } } +void Harness_ForceNullRenderer() { + force_nullrenderer = 1; + renderer = &null_renderer; +} + void Harness_Debug_PrintStack() { -#ifndef _WIN32 - posix_print_stack_trace(); -#endif + Platform_PrintStacktrace(); } int Harness_ProcessCommandLine(int* argc, char* argv[]) { - char* platform_name = NULL; - for (int i = 1; i < *argc; i++) { int handled = 0; @@ -119,10 +121,6 @@ int Harness_ProcessCommandLine(int* argc, char* argv[]) { harness_debug_level = atoi(s + 1); LOG_INFO("debug level set to %d", harness_debug_level); handled = 1; - } else if (strstr(argv[i], "--platform=") != NULL) { - platform_name = strstr(argv[i], "=") + 1; - LOG_INFO("Platform set to: %s", platform_name); - handled = 1; } else if (strstr(argv[i], "--physics-step-time=") != NULL) { char* s = strstr(argv[i], "="); harness_game_config.physics_step_time = atof(s + 1); @@ -153,39 +151,31 @@ int Harness_ProcessCommandLine(int* argc, char* argv[]) { } } - if (platform_name == NULL) { - platform_name = "sdl_gl"; - } - - if (strcmp(platform_name, "sdl_gl") == 0) { - platform = &sdl_gl_platform; - } else if (strcmp(platform_name, "null") == 0) { - platform = &null_platform; - } else { - LOG_PANIC("Invalid platform: %s", platform_name); - } return 0; } void Harness_Hook_DOSGfxBegin() { - platform->NewWindow("Dethrace", 640, 400, 320, 200); + if (force_nullrenderer) { + return; + } + renderer = Window_Create("Dethrace", 640, 400, 320, 200); } // Render 2d back buffer void Harness_RenderScreen(br_pixelmap* dst, br_pixelmap* src) { - platform->RenderFullScreenQuad((uint8_t*)src->pixels, 320, 200); + renderer->FullScreenQuad((uint8_t*)src->pixels, 320, 200); last_dst = dst; last_src = src; } void Harness_Hook_BrDevPaletteSetOld(br_pixelmap* pm) { - platform->SetPalette((uint8_t*)pm->pixels); + renderer->SetPalette((uint8_t*)pm->pixels); palette = pm; if (last_dst) { Harness_RenderScreen(last_dst, last_src); - platform->Swap(); + Window_Swap(0); } } @@ -201,74 +191,78 @@ void Harness_Hook_BrV1dbRendererBegin(br_v1db_state* v1db) { v1db->renderer = (br_renderer*)renderer_state; } -void Harness_Hook_MainGameLoop() { +int Harness_CalculateFrameDelay() { if (harness_game_config.fps == 0) { - return; + return 0; } - if (last_frame_time) { - unsigned int frame_time = GetTotalTime() - last_frame_time; + unsigned int now = GetTotalTime(); + if (last_frame_time != 0) { + unsigned int frame_time = now - last_frame_time; + last_frame_time = now; if (frame_time < 100) { - int sleep_time = (1000 / harness_game_config.fps) - frame_time; if (sleep_time > 5) { - SDL_Delay(sleep_time); + return sleep_time; } } } - - last_frame_time = GetTotalTime(); + return 0; } // Begin 3d scene void Harness_Hook_BrZbSceneRenderBegin(br_actor* world, br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer) { last_colour_buffer = colour_buffer; last_depth_buffer = depth_buffer; - platform->BeginScene(camera, colour_buffer); + renderer->BeginScene(camera, colour_buffer); } void Harness_Hook_BrZbSceneRenderAdd(br_actor* tree) { } void Harness_Hook_renderFaces(br_actor* actor, br_model* model, br_material* material, br_token type) { - platform->RenderModel(actor, model, renderer_state->state.matrix.model_to_view); + renderer->Model(actor, model, renderer_state->state.matrix.model_to_view); } void Harness_Hook_BrZbSceneRenderEnd() { - platform->EndScene(); + renderer->EndScene(); } // Called by game to swap buffers at end of frame rendering void Harness_Hook_BrPixelmapDoubleBuffer(br_pixelmap* dst, br_pixelmap* src) { // draw the current colour_buffer (2d screen) contents - platform->FlushBuffers(last_colour_buffer, last_depth_buffer); + renderer->FlushBuffers(last_colour_buffer, last_depth_buffer); Harness_RenderScreen(dst, src); - platform->Swap(); - platform->PollEvents(); + int delay_ms = Harness_CalculateFrameDelay(); + Window_Swap(delay_ms); + + renderer->ClearBuffers(); + Window_PollEvents(); + + last_frame_time = GetTotalTime(); } int Harness_Hook_KeyDown(unsigned char pScan_code) { - return platform->IsKeyDown(pScan_code); + return Input_IsKeyDown(pScan_code); } void Harness_Hook_PDServiceSystem() { - platform->PollEvents(); + Window_PollEvents(); } void Harness_Hook_PDSetKeyArray() { - platform->PollEvents(); + Window_PollEvents(); } void Harness_Hook_BrMaterialUpdate(br_material* mat, br_uint_16 flags) { - // LOG_DEBUG("buffermat %s", mat->identifier); - platform->BufferMaterial(mat); + renderer->BufferMaterial(mat); } void Harness_Hook_BrBufferUpdate(br_pixelmap* pm, br_token use, br_uint_16 flags) { if (use == BRT_COLOUR_MAP_O || use == BRT_UNKNOWN) { - platform->BufferTexture(pm); + renderer->BufferTexture(pm); } else { LOG_PANIC("use %d", use); } @@ -282,6 +276,5 @@ void Harness_Hook_S3StopAllOutletSounds() { } void Harness_Hook_FlushRenderer() { - platform->FlushBuffers(last_colour_buffer, last_depth_buffer); + renderer->FlushBuffers(last_colour_buffer, last_depth_buffer); } - diff --git a/src/harness/harness.h b/src/harness/harness.h index cd134d49..8c8e1d64 100644 --- a/src/harness/harness.h +++ b/src/harness/harness.h @@ -3,24 +3,9 @@ #include "brender/br_types.h" #include "harness/trace.h" +#include "renderers/renderer.h" -typedef struct tPlatform { - void (*Init)(); - void (*NewWindow)(char* title, int width, int height, int render_width, int render_height); - void (*PollEvents)(); - int* (*GetKeyMap)(); - int (*IsKeyDown)(unsigned char pScan_code); - void (*BeginScene)(br_actor* camera, br_pixelmap* colour_buffer); - void (*EndScene)(); - void (*SetPalette)(uint8_t* palette); - void (*RenderFullScreenQuad)(uint8_t* src, int width, int height); - void (*RenderModel)(br_actor* actor, br_model* model, br_matrix34 model_matrix); - void (*Swap)(); - void (*BufferTexture)(br_pixelmap* pm); - void (*BufferMaterial)(br_material* mat); - void (*FlushBuffers)(br_pixelmap* color_buffer, br_pixelmap* depth_buffer); - -} tPlatform; +void Harness_ForceNullRenderer(); typedef struct tCamera { void (*update)(); @@ -29,4 +14,11 @@ typedef struct tCamera { void (*setPosition)(); } tCamera; +// platform stuff. See cmake variable RENDERER_PLATFORM +tRenderer* Window_Create(char* title, int width, int height, int pRender_width, int pRender_height); +void Window_PollEvents(void); +void Window_Swap(int delay_ms_after_swap); +int* Input_GetKeyMap(void); +int Input_IsKeyDown(unsigned char scan_code); + #endif \ No newline at end of file diff --git a/src/harness/include/harness/hooks.h b/src/harness/include/harness/hooks.h index 913963d5..7eba5faf 100644 --- a/src/harness/include/harness/hooks.h +++ b/src/harness/include/harness/hooks.h @@ -3,14 +3,15 @@ #include "brender/br_types.h" +void Harness_Init(int* argc, char* argv[]); + // Hooks are called from original game code. // Dethrace hooks -void Harness_Init(int* argc, char* argv[]); int Harness_Hook_KeyDown(unsigned char pScan_code); void Harness_Hook_PDServiceSystem(); void Harness_Hook_PDSetKeyArray(); -void Harness_Hook_MainGameLoop(); // limit FPS +// void Harness_Hook_MainGameLoop(); // limit FPS void Harness_Hook_FlushRenderer(); // synchronize in-memory framebuffer and depthbuffer // BRender hooks diff --git a/src/harness/include/harness/trace.h b/src/harness/include/harness/trace.h index 9485f168..fd2d6ca2 100644 --- a/src/harness/include/harness/trace.h +++ b/src/harness/include/harness/trace.h @@ -10,7 +10,7 @@ #endif extern int harness_debug_level; -extern int PlatformIsDebuggerPresent(void); +extern int Platform_IsDebuggerPresent(void); void Harness_Debug_PrintStack(); @@ -46,26 +46,26 @@ void debug_print_matrix4(const char* fmt, const char* fn, char* name, br_matrix4 #define LOG_MATRIX4(msg, m) debug_print_matrix4("\033[0;34m[DEBUG] %s ", __FUNCTION__, msg, m) #define LOG_INFO(...) debug_printf("\033[0;34m[INFO] %s ", __FUNCTION__, __VA_ARGS__) #define LOG_WARN(...) debug_printf("\033[0;33m[WARN] %s ", __FUNCTION__, __VA_ARGS__) -#define LOG_PANIC(...) \ - do { \ - debug_printf("\033[0;31m[PANIC] %s ", __FUNCTION__, __VA_ARGS__); \ - if (PlatformIsDebuggerPresent()) \ - abort(); \ - else \ - exit(1); \ +#define LOG_PANIC(...) \ + do { \ + debug_printf("\033[0;31m[PANIC] %s ", __FUNCTION__, __VA_ARGS__); \ + if (Platform_IsDebuggerPresent()) \ + abort(); \ + else \ + exit(1); \ } while (0) -#define LOG_WARN_ONCE(...) \ - static int warn_printed = 0; \ - if (!warn_printed) { \ - debug_printf("\033[0;33m[WARN] %s ", __FUNCTION__, __VA_ARGS__); \ - warn_printed = 1; \ +#define LOG_WARN_ONCE(...) \ + static int warn_printed = 0; \ + if (!warn_printed) { \ + debug_printf("\033[0;33m[WARN] %s ", __FUNCTION__, __VA_ARGS__); \ + warn_printed = 1; \ } -#define NOT_IMPLEMENTED() \ +#define NOT_IMPLEMENTED() \ LOG_PANIC("not implemented") -#define TELL_ME_IF_WE_PASS_THIS_WAY() \ +#define TELL_ME_IF_WE_PASS_THIS_WAY() \ LOG_PANIC("code path not expected") #define STUB() \ @@ -78,6 +78,6 @@ void debug_print_matrix4(const char* fmt, const char* fn, char* name, br_matrix4 stub_printed = 1; \ } -//int count_open_fds(); +// int count_open_fds(); #endif diff --git a/src/harness/platforms/platform.h b/src/harness/platforms/platform.h index d2262f24..3102fa76 100644 --- a/src/harness/platforms/platform.h +++ b/src/harness/platforms/platform.h @@ -1,6 +1,10 @@ #ifndef HARNESS_PLATFORM_H #define HARNESS_PLATFORM_H -int PlatformIsDebuggerPresent(void); +int Platform_IsDebuggerPresent(void); + +void Platform_InstallSignalHandler(char* program_name); + +void Platform_PrintStacktrace(void); #endif diff --git a/src/harness/platforms/platform_linux.c b/src/harness/platforms/platform_linux.c index bd981f5b..d2670e86 100644 --- a/src/harness/platforms/platform_linux.c +++ b/src/harness/platforms/platform_linux.c @@ -1,14 +1,32 @@ -#include "platforms/platform.h" +// Based on https://gist.github.com/jvranish/4441299 -#include -#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include "platform.h" + +static int stack_nbr = 0; +static char _program_name[1024]; +#define MAX_STACK_FRAMES 64 +static void* stack_traces[MAX_STACK_FRAMES]; #define TRACER_PID_STRING "TracerPid:" -int PlatformIsDebuggerPresent() { +int Platform_IsDebuggerPresent() { char buf[4096]; int status_fd; ssize_t num_read; @@ -32,8 +50,7 @@ int PlatformIsDebuggerPresent() { return 0; } - for (char_ptr = tracer_pid_ptr + sizeof(TRACER_PID_STRING) - 1; char_ptr <= buf + num_read; ++char_ptr) - { + for (char_ptr = tracer_pid_ptr + sizeof(TRACER_PID_STRING) - 1; char_ptr <= buf + num_read; ++char_ptr) { if (isspace(*char_ptr)) { continue; } else { @@ -43,3 +60,184 @@ int PlatformIsDebuggerPresent() { return 0; } + +// Resolve symbol name and source location given the path to the executable and an address +int addr2line(char const* const program_name, void const* const addr) { + char addr2line_cmd[512] = { 0 }; + + /* have addr2line map the address to the related line in the code */ + sprintf(addr2line_cmd, "addr2line -f -p -e %.256s %p", program_name, addr); + + fprintf(stderr, "%d: ", stack_nbr++); + return system(addr2line_cmd); +} + +void signal_handler(int sig, siginfo_t* siginfo, void* context) { + (void)context; + fputs("\n******************\n", stderr); + + switch (sig) { + case SIGSEGV: + fputs("Caught SIGSEGV\n", stderr); + break; + case SIGINT: + fputs("Caught SIGINT\n", stderr); + break; + case SIGFPE: + switch (siginfo->si_code) { + case FPE_INTDIV: + fputs("Caught SIGFPE: FPE_INTDIV\n", stderr); + break; + case FPE_INTOVF: + fputs("Caught SIGFPE: FPE_INTOVF\n", stderr); + break; + case FPE_FLTDIV: + fputs("Caught SIGFPE: FPE_FLTDIV\n", stderr); + break; + case FPE_FLTOVF: + fputs("Caught SIGFPE: FPE_FLTOVF\n", stderr); + break; + case FPE_FLTUND: + fputs("Caught SIGFPE: FPE_FLTUND\n", stderr); + break; + case FPE_FLTRES: + fputs("Caught SIGFPE: FPE_FLTRES\n", stderr); + break; + case FPE_FLTINV: + fputs("Caught SIGFPE: FPE_FLTINV\n", stderr); + break; + case FPE_FLTSUB: + fputs("Caught SIGFPE: FPE_FLTSUB\n", stderr); + break; + default: + fputs("Caught SIGFPE: Arithmetic Exception\n", stderr); + break; + } + break; + case SIGILL: + switch (siginfo->si_code) { + case ILL_ILLOPC: + fputs("Caught SIGILL: ILL_ILLOPC\n", stderr); + break; + case ILL_ILLOPN: + fputs("Caught SIGILL: ILL_ILLOPN\n", stderr); + break; + case ILL_ILLADR: + fputs("Caught SIGILL: ILL_ILLADR\n", stderr); + break; + case ILL_ILLTRP: + fputs("Caught SIGILL: ILL_ILLTRP\n", stderr); + break; + case ILL_PRVOPC: + fputs("Caught SIGILL: ILL_PRVOPC\n", stderr); + break; + case ILL_PRVREG: + fputs("Caught SIGILL: ILL_PRVREG\n", stderr); + break; + case ILL_COPROC: + fputs("Caught SIGILL: ILL_COPROC\n", stderr); + break; + case ILL_BADSTK: + fputs("Caught SIGILL: ILL_BADSTK\n", stderr); + break; + default: + fputs("Caught SIGILL: Illegal Instruction\n", stderr); + break; + } + break; + case SIGTERM: + fputs("Caught SIGTERM\n", stderr); + break; + case SIGABRT: + fputs("Caught SIGABRT\n", stderr); + break; + default: + break; + } + fputs("******************\n", stderr); + Platform_PrintStacktrace(); + exit(1); +} + +static uint8_t alternate_stack[SIGSTKSZ]; + +void resolve_full_path(char* path, const char* argv0) { + if (argv0[0] == '/') { // run with absolute path + strcpy(path, argv0); + } else { // run with relative path + if (NULL == getcwd(path, PATH_MAX)) { + perror("getcwd error"); + return; + } + strcat(path, "/"); + strcat(path, argv0); + } +} + +void Platform_InstallSignalHandler(char* program_name) { + + resolve_full_path(_program_name, program_name); + + /* setup alternate stack */ + { + stack_t ss = {}; + /* malloc is usually used here, I'm not 100% sure my static allocation + is valid but it seems to work just fine. */ + ss.ss_sp = (void*)alternate_stack; + ss.ss_size = SIGSTKSZ; + ss.ss_flags = 0; + + if (sigaltstack(&ss, NULL) != 0) { + err(1, "sigaltstack"); + } + } + + /* register our signal handlers */ + { + struct sigaction sig_action = {}; + sig_action.sa_sigaction = signal_handler; + sigemptyset(&sig_action.sa_mask); + + sig_action.sa_flags = SA_SIGINFO | SA_ONSTACK; + + if (sigaction(SIGSEGV, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + if (sigaction(SIGFPE, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + if (sigaction(SIGINT, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + if (sigaction(SIGILL, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + if (sigaction(SIGTERM, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + if (sigaction(SIGABRT, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + } +} + +void Platform_PrintStacktrace() { + int i, trace_size = 0; + char** messages = (char**)NULL; + + fputs("\nStack trace:\n", stderr); + + trace_size = backtrace(stack_traces, MAX_STACK_FRAMES); + messages = backtrace_symbols(stack_traces, trace_size); + + /* skip the first couple stack frames (as they are this function and + our handler) and also skip the last frame as it's (always?) junk. */ + for (i = 3; i < (trace_size - 1); ++i) { + if (addr2line(_program_name, stack_traces[i]) != 0) { + printf(" error determining line # for: %s\n", messages[i]); + } + } + if (messages) { + free(messages); + } +} \ No newline at end of file diff --git a/src/harness/platforms/platform_macosx.c b/src/harness/platforms/platform_macosx.c index e51c6e39..f294fcb2 100644 --- a/src/harness/platforms/platform_macosx.c +++ b/src/harness/platforms/platform_macosx.c @@ -1,25 +1,42 @@ +// Based on https://gist.github.com/jvranish/4441299 + #include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include #include #include -#include +#include "platform.h" + +static int stack_nbr = 0; +static char _program_name[1024]; +#define MAX_STACK_FRAMES 64 +static void* stack_traces[MAX_STACK_FRAMES]; // https://developer.apple.com/library/archive/qa/qa1361/_index.html // FIXME: // Important: Because the definition of the kinfo_proc structure (in ) is conditionalized by __APPLE_API_UNSTABLE, // you should restrict use of the above code to the debug build of your program. -int PlatformIsDebuggerPresent() - // Returns true if the current process is being debugged (either - // running under the debugger or has a debugger attached post facto). +int Platform_IsDebuggerPresent() +// Returns true if the current process is being debugged (either +// running under the debugger or has a debugger attached post facto). { - int junk; - int mib[4]; - struct kinfo_proc info; - size_t size; + int junk; + int mib[4]; + struct kinfo_proc info; + size_t size; - // Initialize the flags so that, if sysctl fails for some bizarre + // Initialize the flags so that, if sysctl fails for some bizarre // reason, we get a predictable result. info.kp_proc.p_flag = 0; @@ -42,3 +59,184 @@ int PlatformIsDebuggerPresent() return ((info.kp_proc.p_flag & P_TRACED) != 0); } + +// Resolve symbol name and source location given the path to the executable and an address +int addr2line(char const* const program_name, void const* const addr) { + char addr2line_cmd[512] = { 0 }; + + /* have addr2line map the address to the related line in the code */ + sprintf(addr2line_cmd, "atos -o %.256s %p", program_name, addr); + + fprintf(stderr, "%d: ", stack_nbr++); + return system(addr2line_cmd); +} + +void signal_handler(int sig, siginfo_t* siginfo, void* context) { + (void)context; + fputs("\n******************\n", stderr); + + switch (sig) { + case SIGSEGV: + fputs("Caught SIGSEGV\n", stderr); + break; + case SIGINT: + fputs("Caught SIGINT\n", stderr); + break; + case SIGFPE: + switch (siginfo->si_code) { + case FPE_INTDIV: + fputs("Caught SIGFPE: FPE_INTDIV\n", stderr); + break; + case FPE_INTOVF: + fputs("Caught SIGFPE: FPE_INTOVF\n", stderr); + break; + case FPE_FLTDIV: + fputs("Caught SIGFPE: FPE_FLTDIV\n", stderr); + break; + case FPE_FLTOVF: + fputs("Caught SIGFPE: FPE_FLTOVF\n", stderr); + break; + case FPE_FLTUND: + fputs("Caught SIGFPE: FPE_FLTUND\n", stderr); + break; + case FPE_FLTRES: + fputs("Caught SIGFPE: FPE_FLTRES\n", stderr); + break; + case FPE_FLTINV: + fputs("Caught SIGFPE: FPE_FLTINV\n", stderr); + break; + case FPE_FLTSUB: + fputs("Caught SIGFPE: FPE_FLTSUB\n", stderr); + break; + default: + fputs("Caught SIGFPE: Arithmetic Exception\n", stderr); + break; + } + break; + case SIGILL: + switch (siginfo->si_code) { + case ILL_ILLOPC: + fputs("Caught SIGILL: ILL_ILLOPC\n", stderr); + break; + case ILL_ILLOPN: + fputs("Caught SIGILL: ILL_ILLOPN\n", stderr); + break; + case ILL_ILLADR: + fputs("Caught SIGILL: ILL_ILLADR\n", stderr); + break; + case ILL_ILLTRP: + fputs("Caught SIGILL: ILL_ILLTRP\n", stderr); + break; + case ILL_PRVOPC: + fputs("Caught SIGILL: ILL_PRVOPC\n", stderr); + break; + case ILL_PRVREG: + fputs("Caught SIGILL: ILL_PRVREG\n", stderr); + break; + case ILL_COPROC: + fputs("Caught SIGILL: ILL_COPROC\n", stderr); + break; + case ILL_BADSTK: + fputs("Caught SIGILL: ILL_BADSTK\n", stderr); + break; + default: + fputs("Caught SIGILL: Illegal Instruction\n", stderr); + break; + } + break; + case SIGTERM: + fputs("Caught SIGTERM\n", stderr); + break; + case SIGABRT: + fputs("Caught SIGABRT\n", stderr); + break; + default: + break; + } + fputs("******************\n", stderr); + Platform_PrintStacktrace(); + exit(1); +} + +static uint8_t alternate_stack[SIGSTKSZ]; + +void resolve_full_path(char* path, const char* argv0) { + if (argv0[0] == '/') { // run with absolute path + strcpy(path, argv0); + } else { // run with relative path + if (NULL == getcwd(path, PATH_MAX)) { + perror("getcwd error"); + return; + } + strcat(path, "/"); + strcat(path, argv0); + } +} + +void Platform_InstallSignalHandler(char* program_name) { + + resolve_full_path(_program_name, program_name); + + /* setup alternate stack */ + { + stack_t ss = {}; + /* malloc is usually used here, I'm not 100% sure my static allocation + is valid but it seems to work just fine. */ + ss.ss_sp = (void*)alternate_stack; + ss.ss_size = SIGSTKSZ; + ss.ss_flags = 0; + + if (sigaltstack(&ss, NULL) != 0) { + err(1, "sigaltstack"); + } + } + + /* register our signal handlers */ + { + struct sigaction sig_action = {}; + sig_action.sa_sigaction = signal_handler; + sigemptyset(&sig_action.sa_mask); + + sig_action.sa_flags = SA_SIGINFO; + + if (sigaction(SIGSEGV, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + if (sigaction(SIGFPE, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + if (sigaction(SIGINT, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + if (sigaction(SIGILL, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + if (sigaction(SIGTERM, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + if (sigaction(SIGABRT, &sig_action, NULL) != 0) { + err(1, "sigaction"); + } + } +} + +void Platform_PrintStacktrace() { + int i, trace_size = 0; + char** messages = (char**)NULL; + + fputs("\nStack trace:\n", stderr); + + trace_size = backtrace(stack_traces, MAX_STACK_FRAMES); + messages = backtrace_symbols(stack_traces, trace_size); + + /* skip the first couple stack frames (as they are this function and + our handler) and also skip the last frame as it's (always?) junk. */ + for (i = 3; i < (trace_size - 1); ++i) { + if (addr2line(_program_name, stack_traces[i]) != 0) { + printf(" error determining line # for: %s\n", messages[i]); + } + } + if (messages) { + free(messages); + } +} \ No newline at end of file diff --git a/src/harness/platforms/platform_windows.c b/src/harness/platforms/platform_windows.c index da742259..cfa75a00 100644 --- a/src/harness/platforms/platform_windows.c +++ b/src/harness/platforms/platform_windows.c @@ -1,5 +1,157 @@ +// Based on https://gist.github.com/jvranish/4441299 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include -int PlatformIsDebuggerPresent() { +#ifdef _WIN64 +#define Esp Rsp +#define Eip Rip +#define Ebp Rbp +#endif + +static char _program_name[1024]; + +int Platform_IsDebuggerPresent() { return IsDebuggerPresent(); } + +int addr2line(char const* const program_name, void const* const addr) { + char addr2line_cmd[512] = { 0 }; + + sprintf(addr2line_cmd, "addr2line -f -p -e %.256s %p", program_name, addr); + + fprintf(stderr, "%d: ", stack_nbr++); + return system(addr2line_cmd); +} + +void Platform_PrintStacktrace() { + fprintf(stderr, "cannot print stack without context\n"); + return; +} + +void print_stacktrace_internal(CONTEXT* context) { + if (!context) { + fprintf(stderr, "cannot print stack without context\n"); + return; + } + + SymInitialize(GetCurrentProcess(), 0, true); + + STACKFRAME frame = { 0 }; + + /* setup initial stack frame */ + frame.AddrPC.Offset = context->Eip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrStack.Offset = context->Esp; + frame.AddrStack.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context->Ebp; + frame.AddrFrame.Mode = AddrModeFlat; + + while (StackWalk(IMAGE_FILE_MACHINE_I386, + GetCurrentProcess(), + GetCurrentThread(), + &frame, + context, + 0, + SymFunctionTableAccess, + SymGetModuleBase, + 0)) { + addr2line(_program_name, (void*)frame.AddrPC.Offset); + } + + SymCleanup(GetCurrentProcess()); +} + +LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) { + switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { + case EXCEPTION_ACCESS_VIOLATION: + fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr); + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + fputs("Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n", stderr); + break; + case EXCEPTION_BREAKPOINT: + fputs("Error: EXCEPTION_BREAKPOINT\n", stderr); + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + fputs("Error: EXCEPTION_DATATYPE_MISALIGNMENT\n", stderr); + break; + case EXCEPTION_FLT_DENORMAL_OPERAND: + fputs("Error: EXCEPTION_FLT_DENORMAL_OPERAND\n", stderr); + break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + fputs("Error: EXCEPTION_FLT_DIVIDE_BY_ZERO\n", stderr); + break; + case EXCEPTION_FLT_INEXACT_RESULT: + fputs("Error: EXCEPTION_FLT_INEXACT_RESULT\n", stderr); + break; + case EXCEPTION_FLT_INVALID_OPERATION: + fputs("Error: EXCEPTION_FLT_INVALID_OPERATION\n", stderr); + break; + case EXCEPTION_FLT_OVERFLOW: + fputs("Error: EXCEPTION_FLT_OVERFLOW\n", stderr); + break; + case EXCEPTION_FLT_STACK_CHECK: + fputs("Error: EXCEPTION_FLT_STACK_CHECK\n", stderr); + break; + case EXCEPTION_FLT_UNDERFLOW: + fputs("Error: EXCEPTION_FLT_UNDERFLOW\n", stderr); + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + fputs("Error: EXCEPTION_ILLEGAL_INSTRUCTION\n", stderr); + break; + case EXCEPTION_IN_PAGE_ERROR: + fputs("Error: EXCEPTION_IN_PAGE_ERROR\n", stderr); + break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + fputs("Error: EXCEPTION_INT_DIVIDE_BY_ZERO\n", stderr); + break; + case EXCEPTION_INT_OVERFLOW: + fputs("Error: EXCEPTION_INT_OVERFLOW\n", stderr); + break; + case EXCEPTION_INVALID_DISPOSITION: + fputs("Error: EXCEPTION_INVALID_DISPOSITION\n", stderr); + break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + fputs("Error: EXCEPTION_NONCONTINUABLE_EXCEPTION\n", stderr); + break; + case EXCEPTION_PRIV_INSTRUCTION: + fputs("Error: EXCEPTION_PRIV_INSTRUCTION\n", stderr); + break; + case EXCEPTION_SINGLE_STEP: + fputs("Error: EXCEPTION_SINGLE_STEP\n", stderr); + break; + case EXCEPTION_STACK_OVERFLOW: + fputs("Error: EXCEPTION_STACK_OVERFLOW\n", stderr); + break; + default: + fputs("Error: Unrecognized Exception\n", stderr); + break; + } + fflush(stderr); + /* If this is a stack overflow then we can't walk the stack, so just show + where the error happened */ + if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) { + print_stacktrace_internal(ExceptionInfo->ContextRecord); + } else { + addr2line(_program_name, (void*)ExceptionInfo->ContextRecord->Eip); + } + + return EXCEPTION_EXECUTE_HANDLER; +} + +void Platform_InstallSignalHandler(char* program_name) { + strcpy(_program_name, program_name); + SetUnhandledExceptionFilter(windows_exception_handler); +} \ No newline at end of file diff --git a/src/harness/platforms/sdl_gl.h b/src/harness/platforms/sdl_gl.h deleted file mode 100644 index 05591e8d..00000000 --- a/src/harness/platforms/sdl_gl.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef SDL_GL_PLATFORM_H -#define SDL_GL_PLATFORM_H - -#include "harness.h" -#include "sdl/common.h" -#include "sdl/gl_renderer.h" - -tPlatform sdl_gl_platform = { - SDLPlatform_Init, - GLRenderer_CreateWindow, - SDLPlatform_PollEvents, - SDLPlatform_GetKeyMap, - SDLPlatform_IsKeyDown, - GLRenderer_BeginScene, - GLRenderer_EndScene, - GLRenderer_SetPalette, - GLRenderer_RenderFullScreenQuad, - GLRenderer_RenderModel, - GLRenderer_Swap, - GLRenderer_BufferTexture, - GLRenderer_BufferMaterial, - GLRenderer_FlushBuffers -}; - -#endif \ No newline at end of file diff --git a/src/harness/sdl/gl_renderer.c b/src/harness/renderers/gl/gl_renderer.c similarity index 92% rename from src/harness/sdl/gl_renderer.c rename to src/harness/renderers/gl/gl_renderer.c index c065b3ca..2717b83e 100644 --- a/src/harness/sdl/gl_renderer.c +++ b/src/harness/renderers/gl/gl_renderer.c @@ -1,20 +1,16 @@ #include "gl_renderer.h" #include "brender/brender.h" #include "cameras/debug_camera.h" -#include "gl_brender_stored_context.h" -#include "gl_renderer_shaders.h" #include "harness.h" #include "harness/trace.h" #include "platforms/platform.h" +#include "shaders.h" +#include "stored_context.h" #include #include +#include -// this needs to be included after glad.h -#include - -SDL_Window* window; -SDL_GLContext context; GLuint screen_buffer_vao, screen_buffer_ebo; GLuint screen_texture, palette_texture, depth_texture; @@ -178,18 +174,12 @@ void SetupFullScreenRectGeometry() { glBindVertexArray(0); } -void InitializeOpenGLContext() { - - context = SDL_GL_CreateContext(window); - if (!context) { - LOG_PANIC("Failed to call SDL_GL_CreateContext. %s", SDL_GetError()); - } +void GLRenderer_Init(int width, int height, int pRender_width, int pRender_height) { - // Load GL extensions using glad - if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) { - LOG_PANIC("Failed to initialize the OpenGL context with GLAD."); - exit(1); - } + window_width = width; + window_height = height; + render_width = pRender_width; + render_height = pRender_height; int maxTextureImageUnits; glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits); @@ -235,48 +225,10 @@ void InitializeOpenGLContext() { } glBindFramebuffer(GL_FRAMEBUFFER, 0); - CHECK_GL_ERROR("initializeOpenGLContext"); -} - -void GLRenderer_CreateWindow(char* title, int width, int height, int pRender_width, int pRender_height) { - window_width = width; - window_height = height; - render_width = pRender_width; - render_height = pRender_height; - - if (SDL_Init(SDL_INIT_VIDEO) != 0) { - LOG_PANIC("SDL_INIT_VIDEO error: %s", SDL_GetError()); - } - - if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE) != 0) { - LOG_PANIC("Failed to set SDL_GL_CONTEXT_PROFILE_MASK attribute. %s", SDL_GetError()); - }; - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - - SDL_GL_SetSwapInterval(1); - - window = SDL_CreateWindow(title, - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - width, height, - SDL_WINDOW_OPENGL); - - if (!window) { - LOG_PANIC("Failed to create window"); - } - - // Don't grab the mouse when a debugger is present - if (!PlatformIsDebuggerPresent()) { - SDL_SetRelativeMouseMode(SDL_TRUE); - } - - // SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); - - InitializeOpenGLContext(); - screen_buffer_flip_pixels = malloc(sizeof(uint8_t) * render_width * render_height); depth_buffer_flip_pixels = malloc(sizeof(uint16_t) * render_width * render_height); + + CHECK_GL_ERROR("initializeOpenGLContext"); } void GLRenderer_SetPalette(uint8_t* rgba_colors) { @@ -374,7 +326,7 @@ void GLRenderer_EndScene() { CHECK_GL_ERROR("GLRenderer_RenderFullScreenQuad"); } -void GLRenderer_RenderFullScreenQuad(uint8_t* screen_buffer, int width, int height) { +void GLRenderer_FullScreenQuad(uint8_t* screen_buffer, int width, int height) { glViewport(0, 0, window_width, window_height); glBindFramebuffer(GL_FRAMEBUFFER, 0); glDisable(GL_DEPTH_TEST); @@ -392,8 +344,7 @@ void GLRenderer_RenderFullScreenQuad(uint8_t* screen_buffer, int width, int heig CHECK_GL_ERROR("GLRenderer_RenderFullScreenQuad"); } -void GLRenderer_Swap() { - SDL_GL_SwapWindow(window); +void GLRenderer_ClearBuffers() { // clear our virtual framebuffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id); @@ -519,7 +470,7 @@ void setActiveMaterial(tStored_material* material) { } } -void GLRenderer_RenderModel(br_actor* actor, br_model* model, br_matrix34 model_matrix) { +void GLRenderer_Model(br_actor* actor, br_model* model, br_matrix34 model_matrix) { tStored_model_context* ctx; ctx = model->stored; v11model* v11 = model->prepared; diff --git a/src/harness/sdl/gl_renderer.h b/src/harness/renderers/gl/gl_renderer.h similarity index 69% rename from src/harness/sdl/gl_renderer.h rename to src/harness/renderers/gl/gl_renderer.h index 54dc76f7..656da0a6 100644 --- a/src/harness/sdl/gl_renderer.h +++ b/src/harness/renderers/gl/gl_renderer.h @@ -2,7 +2,6 @@ #define HARNESS_GL_RENDERER #include "harness.h" -#include #define CHECK_GL_ERROR(msg) \ { \ @@ -12,15 +11,15 @@ } \ } -void GLRenderer_CreateWindow(char* title, int width, int height, int render_width, int render_height); +void GLRenderer_Init(int width, int height, int render_width, int render_height); void GLRenderer_SetPalette(uint8_t* rgba_colors); void GLRenderer_BeginScene(br_actor* camera, br_pixelmap* colour_buffer); void GLRenderer_EndScene(); -void GLRenderer_RenderFullScreenQuad(uint8_t* screen_buffer, int width, int height); -void GLRenderer_Swap(); -void GLRenderer_RenderModel(br_actor* actor, br_model* model, br_matrix34 model_matrix); +void GLRenderer_FullScreenQuad(uint8_t* screen_buffer, int width, int height); +void GLRenderer_Model(br_actor* actor, br_model* model, br_matrix34 model_matrix); void GLRenderer_BufferTexture(br_pixelmap* pm); void GLRenderer_BufferMaterial(br_material* mat); +void GLRenderer_ClearBuffers(); void GLRenderer_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffer); #endif \ No newline at end of file diff --git a/src/harness/sdl/gl_renderer_shaders.c b/src/harness/renderers/gl/shaders.c similarity index 100% rename from src/harness/sdl/gl_renderer_shaders.c rename to src/harness/renderers/gl/shaders.c diff --git a/src/harness/sdl/gl_renderer_shaders.h b/src/harness/renderers/gl/shaders.h similarity index 100% rename from src/harness/sdl/gl_renderer_shaders.h rename to src/harness/renderers/gl/shaders.h diff --git a/src/harness/sdl/gl_brender_stored_context.c b/src/harness/renderers/gl/stored_context.c similarity index 96% rename from src/harness/sdl/gl_brender_stored_context.c rename to src/harness/renderers/gl/stored_context.c index 4b886400..1853fe76 100644 --- a/src/harness/sdl/gl_brender_stored_context.c +++ b/src/harness/renderers/gl/stored_context.c @@ -1,4 +1,4 @@ -#include "gl_brender_stored_context.h" +#include "stored_context.h" #include "../include/harness/trace.h" #include diff --git a/src/harness/sdl/gl_brender_stored_context.h b/src/harness/renderers/gl/stored_context.h similarity index 100% rename from src/harness/sdl/gl_brender_stored_context.h rename to src/harness/renderers/gl/stored_context.h diff --git a/src/harness/platforms/null.h b/src/harness/renderers/null.h similarity index 64% rename from src/harness/platforms/null.h rename to src/harness/renderers/null.h index 149e4259..88737bfa 100644 --- a/src/harness/platforms/null.h +++ b/src/harness/renderers/null.h @@ -1,33 +1,25 @@ -#include "harness.h" +#include "renderer.h" void Null_Init() {} -void Null_CreateWindow(char* title, int width, int height, int render_width, int render_height) {} -void Null_PollEvents() {} -int* Null_GetKeyMap() { return NULL; } -int Null_IsKeyDown(unsigned char pScan_code) { return 0; } void Null_BeginFrame(br_actor* camera, br_pixelmap* colour_buffer) {} void Null_EndFrame() {} void Null_SetPalette(uint8_t* palette) {} void Null_RenderFullScreenQuad(uint8_t* src, int width, int height) {} void Null_RenderModel(br_actor* actor, br_model* model, br_matrix34 model_matrix) {} void Null_RenderFrameBuffer() {} -void Null_Swap() {} +void Null_ClearBuffers() {} void Null_BufferTexture(br_pixelmap* pm) {} void Null_BufferMaterial(br_material* mat) {} void Null_FlushBuffers(br_pixelmap* color_buffer, br_pixelmap* depth_buffer) {} -tPlatform null_platform = { +tRenderer null_renderer = { Null_Init, - Null_CreateWindow, - Null_PollEvents, - Null_GetKeyMap, - Null_IsKeyDown, Null_BeginFrame, Null_EndFrame, Null_SetPalette, Null_RenderFullScreenQuad, Null_RenderModel, - Null_Swap, + Null_ClearBuffers, Null_BufferTexture, Null_BufferMaterial, Null_FlushBuffers diff --git a/src/harness/renderers/renderer.h b/src/harness/renderers/renderer.h new file mode 100644 index 00000000..7c8936d6 --- /dev/null +++ b/src/harness/renderers/renderer.h @@ -0,0 +1,20 @@ +#ifndef HARNESS_RENDERER_H +#define HARNESS_RENDERER_H + +#include "brender/br_types.h" + +typedef struct tRenderer { + void (*Init)(int width, int height, int pRender_width, int pRender_height); + void (*BeginScene)(br_actor* camera, br_pixelmap* colour_buffer); + void (*EndScene)(); + void (*SetPalette)(uint8_t* palette); + void (*FullScreenQuad)(uint8_t* src, int width, int height); + void (*Model)(br_actor* actor, br_model* model, br_matrix34 model_matrix); + void (*ClearBuffers)(); + void (*BufferTexture)(br_pixelmap* pm); + void (*BufferMaterial)(br_material* mat); + void (*FlushBuffers)(br_pixelmap* color_buffer, br_pixelmap* depth_buffer); + +} tRenderer; + +#endif \ No newline at end of file diff --git a/src/harness/sdl/common.h b/src/harness/sdl/common.h deleted file mode 100644 index 493310a2..00000000 --- a/src/harness/sdl/common.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef SDL_PLATFORM_H -#define SDL_PLATFORM_H - -#include "harness.h" - -void SDLPlatform_Init(); -void SDLPlatform_PollEvents(); -int* SDLPlatform_GetKeyMap(); -int SDLPlatform_IsKeyDown(unsigned char scan_code); - -#endif \ No newline at end of file diff --git a/src/harness/stack_trace_handler.h b/src/harness/stack_trace_handler.h deleted file mode 100644 index 38c5e676..00000000 --- a/src/harness/stack_trace_handler.h +++ /dev/null @@ -1,338 +0,0 @@ -// Based on https://gist.github.com/jvranish/4441299 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#ifdef _WIN64 -#define Esp Rsp -#define Eip Rip -#define Ebp Rbp -#endif -#else -#include -#include -#endif - -static int stack_nbr = 0; -static char _program_name[1024]; - -/* Resolve symbol name and source location given the path to the executable - and an address */ -int addr2line(char const* const program_name, void const* const addr) { - char addr2line_cmd[512] = { 0 }; - -/* have addr2line map the address to the relent line in the code */ -#ifdef __APPLE__ - /* apple does things differently... */ - sprintf(addr2line_cmd, "atos -o %.256s %p", program_name, addr); -#else - sprintf(addr2line_cmd, "addr2line -f -p -e %.256s %p", program_name, addr); -#endif - - fprintf(stderr, "%d: ", stack_nbr++); - return system(addr2line_cmd); -} - -#ifdef _WIN32 -void windows_print_stacktrace(CONTEXT* context) { - SymInitialize(GetCurrentProcess(), 0, true); - - STACKFRAME frame = { 0 }; - - /* setup initial stack frame */ - frame.AddrPC.Offset = context->Eip; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrStack.Offset = context->Esp; - frame.AddrStack.Mode = AddrModeFlat; - frame.AddrFrame.Offset = context->Ebp; - frame.AddrFrame.Mode = AddrModeFlat; - - while (StackWalk(IMAGE_FILE_MACHINE_I386, - GetCurrentProcess(), - GetCurrentThread(), - &frame, - context, - 0, - SymFunctionTableAccess, - SymGetModuleBase, - 0)) { - addr2line(_program_name, (void*)frame.AddrPC.Offset); - } - - SymCleanup(GetCurrentProcess()); -} - -LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) { - switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { - case EXCEPTION_ACCESS_VIOLATION: - fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr); - break; - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - fputs("Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n", stderr); - break; - case EXCEPTION_BREAKPOINT: - fputs("Error: EXCEPTION_BREAKPOINT\n", stderr); - break; - case EXCEPTION_DATATYPE_MISALIGNMENT: - fputs("Error: EXCEPTION_DATATYPE_MISALIGNMENT\n", stderr); - break; - case EXCEPTION_FLT_DENORMAL_OPERAND: - fputs("Error: EXCEPTION_FLT_DENORMAL_OPERAND\n", stderr); - break; - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - fputs("Error: EXCEPTION_FLT_DIVIDE_BY_ZERO\n", stderr); - break; - case EXCEPTION_FLT_INEXACT_RESULT: - fputs("Error: EXCEPTION_FLT_INEXACT_RESULT\n", stderr); - break; - case EXCEPTION_FLT_INVALID_OPERATION: - fputs("Error: EXCEPTION_FLT_INVALID_OPERATION\n", stderr); - break; - case EXCEPTION_FLT_OVERFLOW: - fputs("Error: EXCEPTION_FLT_OVERFLOW\n", stderr); - break; - case EXCEPTION_FLT_STACK_CHECK: - fputs("Error: EXCEPTION_FLT_STACK_CHECK\n", stderr); - break; - case EXCEPTION_FLT_UNDERFLOW: - fputs("Error: EXCEPTION_FLT_UNDERFLOW\n", stderr); - break; - case EXCEPTION_ILLEGAL_INSTRUCTION: - fputs("Error: EXCEPTION_ILLEGAL_INSTRUCTION\n", stderr); - break; - case EXCEPTION_IN_PAGE_ERROR: - fputs("Error: EXCEPTION_IN_PAGE_ERROR\n", stderr); - break; - case EXCEPTION_INT_DIVIDE_BY_ZERO: - fputs("Error: EXCEPTION_INT_DIVIDE_BY_ZERO\n", stderr); - break; - case EXCEPTION_INT_OVERFLOW: - fputs("Error: EXCEPTION_INT_OVERFLOW\n", stderr); - break; - case EXCEPTION_INVALID_DISPOSITION: - fputs("Error: EXCEPTION_INVALID_DISPOSITION\n", stderr); - break; - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - fputs("Error: EXCEPTION_NONCONTINUABLE_EXCEPTION\n", stderr); - break; - case EXCEPTION_PRIV_INSTRUCTION: - fputs("Error: EXCEPTION_PRIV_INSTRUCTION\n", stderr); - break; - case EXCEPTION_SINGLE_STEP: - fputs("Error: EXCEPTION_SINGLE_STEP\n", stderr); - break; - case EXCEPTION_STACK_OVERFLOW: - fputs("Error: EXCEPTION_STACK_OVERFLOW\n", stderr); - break; - default: - fputs("Error: Unrecognized Exception\n", stderr); - break; - } - fflush(stderr); - /* If this is a stack overflow then we can't walk the stack, so just show - where the error happened */ - if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) { - windows_print_stacktrace(ExceptionInfo->ContextRecord); - } else { - addr2line(_program_name, (void*)ExceptionInfo->ContextRecord->Eip); - } - - return EXCEPTION_EXECUTE_HANDLER; -} - -void install_signal_handler(char* program_name) { - strcpy(_program_name, program_name); - SetUnhandledExceptionFilter(windows_exception_handler); -} -#else - -#define MAX_STACK_FRAMES 64 -static void* stack_traces[MAX_STACK_FRAMES]; - -void posix_print_stack_trace() { - int i, trace_size = 0; - char** messages = (char**)NULL; - - fputs("\nStack trace:\n", stderr); - - trace_size = backtrace(stack_traces, MAX_STACK_FRAMES); - messages = backtrace_symbols(stack_traces, trace_size); - - /* skip the first couple stack frames (as they are this function and - our handler) and also skip the last frame as it's (always?) junk. */ - for (i = 3; i < (trace_size - 1); ++i) { - if (addr2line(_program_name, stack_traces[i]) != 0) { - printf(" error determining line # for: %s\n", messages[i]); - } - } - if (messages) { - free(messages); - } -} - -void posix_signal_handler(int sig, siginfo_t* siginfo, void* context) { - (void)context; - fputs("\n******************\n", stderr); - - switch (sig) { - case SIGSEGV: - fputs("Caught SIGSEGV\n", stderr); - break; - case SIGINT: - fputs("Caught SIGINT\n", stderr); - break; - case SIGFPE: - switch (siginfo->si_code) { - case FPE_INTDIV: - fputs("Caught SIGFPE: FPE_INTDIV\n", stderr); - break; - case FPE_INTOVF: - fputs("Caught SIGFPE: FPE_INTOVF\n", stderr); - break; - case FPE_FLTDIV: - fputs("Caught SIGFPE: FPE_FLTDIV\n", stderr); - break; - case FPE_FLTOVF: - fputs("Caught SIGFPE: FPE_FLTOVF\n", stderr); - break; - case FPE_FLTUND: - fputs("Caught SIGFPE: FPE_FLTUND\n", stderr); - break; - case FPE_FLTRES: - fputs("Caught SIGFPE: FPE_FLTRES\n", stderr); - break; - case FPE_FLTINV: - fputs("Caught SIGFPE: FPE_FLTINV\n", stderr); - break; - case FPE_FLTSUB: - fputs("Caught SIGFPE: FPE_FLTSUB\n", stderr); - break; - default: - fputs("Caught SIGFPE: Arithmetic Exception\n", stderr); - break; - } - break; - case SIGILL: - switch (siginfo->si_code) { - case ILL_ILLOPC: - fputs("Caught SIGILL: ILL_ILLOPC\n", stderr); - break; - case ILL_ILLOPN: - fputs("Caught SIGILL: ILL_ILLOPN\n", stderr); - break; - case ILL_ILLADR: - fputs("Caught SIGILL: ILL_ILLADR\n", stderr); - break; - case ILL_ILLTRP: - fputs("Caught SIGILL: ILL_ILLTRP\n", stderr); - break; - case ILL_PRVOPC: - fputs("Caught SIGILL: ILL_PRVOPC\n", stderr); - break; - case ILL_PRVREG: - fputs("Caught SIGILL: ILL_PRVREG\n", stderr); - break; - case ILL_COPROC: - fputs("Caught SIGILL: ILL_COPROC\n", stderr); - break; - case ILL_BADSTK: - fputs("Caught SIGILL: ILL_BADSTK\n", stderr); - break; - default: - fputs("Caught SIGILL: Illegal Instruction\n", stderr); - break; - } - break; - case SIGTERM: - fputs("Caught SIGTERM\n", stderr); - break; - case SIGABRT: - fputs("Caught SIGABRT\n", stderr); - break; - default: - break; - } - fputs("******************\n", stderr); - posix_print_stack_trace(); - exit(1); -} - -static uint8_t alternate_stack[SIGSTKSZ]; - -void resolve_full_path(char* path, const char* argv0) { - if (argv0[0] == '/') { // run with absolute path - strcpy(path, argv0); - } else { // run with relative path - if (NULL == getcwd(path, PATH_MAX)) { - perror("getcwd error"); - return; - } - strcat(path, "/"); - strcat(path, argv0); - } -} - -void install_signal_handler(char* program_name) { - - resolve_full_path(_program_name, program_name); - - /* setup alternate stack */ - { - stack_t ss = {}; - /* malloc is usually used here, I'm not 100% sure my static allocation - is valid but it seems to work just fine. */ - ss.ss_sp = (void*)alternate_stack; - ss.ss_size = SIGSTKSZ; - ss.ss_flags = 0; - - if (sigaltstack(&ss, NULL) != 0) { - err(1, "sigaltstack"); - } - } - - /* register our signal handlers */ - { - struct sigaction sig_action = {}; - sig_action.sa_sigaction = posix_signal_handler; - sigemptyset(&sig_action.sa_mask); - -#ifdef __APPLE__ - /* for some reason we backtrace() doesn't work on osx - when we use an alternate stack */ - sig_action.sa_flags = SA_SIGINFO; -#else - sig_action.sa_flags = SA_SIGINFO | SA_ONSTACK; -#endif - - if (sigaction(SIGSEGV, &sig_action, NULL) != 0) { - err(1, "sigaction"); - } - if (sigaction(SIGFPE, &sig_action, NULL) != 0) { - err(1, "sigaction"); - } - if (sigaction(SIGINT, &sig_action, NULL) != 0) { - err(1, "sigaction"); - } - if (sigaction(SIGILL, &sig_action, NULL) != 0) { - err(1, "sigaction"); - } - if (sigaction(SIGTERM, &sig_action, NULL) != 0) { - err(1, "sigaction"); - } - if (sigaction(SIGABRT, &sig_action, NULL) != 0) { - err(1, "sigaction"); - } - } -} -#endif diff --git a/src/harness/sdl/common.c b/src/harness/window_io/sdl/sdl_gl.c similarity index 58% rename from src/harness/sdl/common.c rename to src/harness/window_io/sdl/sdl_gl.c index ae2140e5..1ce5afbe 100644 --- a/src/harness/sdl/common.c +++ b/src/harness/window_io/sdl/sdl_gl.c @@ -1,5 +1,12 @@ -#include "common.h" +#include + +// this needs to be included after glad.h #include +#include + +#include "../renderers/gl/gl_renderer.h" +#include "../renderers/renderer.h" +#include "harness/trace.h" // Errol's keymap int keymap[123] = { @@ -112,15 +119,69 @@ int keymap[123] = { SDL_SCANCODE_SPACE }; +SDL_Window* window; +SDL_GLContext context; uint8_t sdl_key_state[256]; -void SDLPlatform_Init() { - if (SDL_Init(SDL_INIT_TIMER) != 0) { - LOG_PANIC("SDL_INIT_TIMER error: %s", SDL_GetError()); +tRenderer gl_renderer = { + GLRenderer_Init, + GLRenderer_BeginScene, + GLRenderer_EndScene, + GLRenderer_SetPalette, + GLRenderer_FullScreenQuad, + GLRenderer_Model, + GLRenderer_ClearBuffers, + GLRenderer_BufferTexture, + GLRenderer_BufferMaterial, + GLRenderer_FlushBuffers +}; + +tRenderer* Window_Create(char* title, int width, int height, int pRender_width, int pRender_height) { + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + LOG_PANIC("SDL_INIT_VIDEO error: %s", SDL_GetError()); + } + + if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE) != 0) { + LOG_PANIC("Failed to set SDL_GL_CONTEXT_PROFILE_MASK attribute. %s", SDL_GetError()); + }; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + + SDL_GL_SetSwapInterval(1); + + window = SDL_CreateWindow(title, + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + width, height, + SDL_WINDOW_OPENGL); + + if (!window) { + LOG_PANIC("Failed to create window"); + } + + // Don't grab the mouse when a debugger is present + if (!Platform_IsDebuggerPresent()) { + SDL_SetRelativeMouseMode(SDL_TRUE); } + + // SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); + + context = SDL_GL_CreateContext(window); + if (!context) { + LOG_PANIC("Failed to call SDL_GL_CreateContext. %s", SDL_GetError()); + } + + // Load GL extensions using glad + if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) { + LOG_PANIC("Failed to initialize the OpenGL context with GLAD."); + exit(1); + } + + gl_renderer.Init(width, height, pRender_width, pRender_height); + return &gl_renderer; } -void SDLPlatform_PollEvents() { +void Window_PollEvents() { SDL_Event event; while (SDL_PollEvent(&event)) { @@ -134,7 +195,7 @@ void SDLPlatform_PollEvents() { } if (event.key.type == SDL_KEYDOWN) { sdl_key_state[event.key.keysym.scancode] = 1; - //LOG_DEBUG("key %d", key->keysym.scancode); + // LOG_DEBUG("key %d", key->keysym.scancode); } else { sdl_key_state[event.key.keysym.scancode] = 0; } @@ -148,10 +209,18 @@ void SDLPlatform_PollEvents() { } } -int* SDLPlatform_GetKeyMap() { +void Window_Swap(int delay_ms_after_swap) { + SDL_GL_SwapWindow(window); + + if (delay_ms_after_swap != 0) { + SDL_Delay(delay_ms_after_swap); + } +} + +int* Input_GetKeyMap() { return (int*)keymap; } -int SDLPlatform_IsKeyDown(unsigned char scan_code) { +int Input_IsKeyDown(unsigned char scan_code) { return sdl_key_state[scan_code]; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5863e66e..3d1b34ef 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,8 @@ add_executable(dethrace_test) add_test(NAME test_dethrace COMMAND dethrace_test) +set(RENDERER_PLATFORM "SDL_OpenGL2") + target_link_libraries(dethrace_test PRIVATE glad dethrace_obj) target_include_directories(dethrace_test PRIVATE diff --git a/test/main.c b/test/main.c index 757dd78f..dace502d 100644 --- a/test/main.c +++ b/test/main.c @@ -182,6 +182,8 @@ void setup_global_vars(int argc, char* argv[]) { fake_argv[fake_argc++] = "--no-signal-handler"; } Harness_Init(&fake_argc, fake_argv); + + Harness_ForceNullRenderer(); } int has_data_directory() { From eb905c58d8ebff5f220c703de36659ef938b42e1 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 14 Mar 2022 14:23:33 +1300 Subject: [PATCH 02/28] wip2 --- src/harness/CMakeLists.txt | 10 ++-- src/harness/harness.c | 6 +-- src/harness/include/harness/trace.h | 4 +- .../platform_linux.c => os/linux.c} | 10 ++-- .../platform_macosx.c => os/macosx.c} | 50 +++++++++---------- src/harness/os/os.h | 10 ++++ .../platform_windows.c => os/windows.c} | 6 +-- src/harness/platforms/platform.h | 10 ---- .../{window_io/sdl => platforms}/sdl_gl.c | 2 +- src/harness/renderers/gl/gl_renderer.c | 1 - 10 files changed, 52 insertions(+), 57 deletions(-) rename src/harness/{platforms/platform_linux.c => os/linux.c} (97%) rename src/harness/{platforms/platform_macosx.c => os/macosx.c} (97%) create mode 100644 src/harness/os/os.h rename src/harness/{platforms/platform_windows.c => os/windows.c} (97%) delete mode 100644 src/harness/platforms/platform.h rename src/harness/{window_io/sdl => platforms}/sdl_gl.c (99%) diff --git a/src/harness/CMakeLists.txt b/src/harness/CMakeLists.txt index 3ddb96f7..972753af 100644 --- a/src/harness/CMakeLists.txt +++ b/src/harness/CMakeLists.txt @@ -40,7 +40,7 @@ target_sources(harness PRIVATE harness_trace.c harness.c harness.h - platforms/null.h + renderers/null.h renderers/renderer.h brender_emu/renderer_impl.c brender_emu/renderer_impl.h @@ -50,7 +50,7 @@ target_sources(harness PRIVATE if (RENDERER_PLATFORM STREQUAL "SDL_OpenGL") target_sources(harness PRIVATE - window_io/sdl/sdl_gl.c + platforms/sdl_gl.c renderers/gl/gl_renderer.c renderers/gl/gl_renderer.h renderers/gl/shaders.c @@ -62,14 +62,14 @@ endif() if(WIN32) target_sources(harness PRIVATE - platforms/platform_windows.c + os/windows.c ) elseif(APPLE) target_sources(harness PRIVATE - platforms/platform_macosx.c + os/macosx.c ) else() target_sources(harness PRIVATE - platforms/platform_linux.c + os/linux.c ) endif() diff --git a/src/harness/harness.c b/src/harness/harness.c index 50b29d58..ffe1c932 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -2,7 +2,7 @@ #include "harness.h" #include "brender_emu/renderer_impl.h" #include "include/harness/config.h" -#include "platforms/platform.h" +#include "os/os.h" #include "renderers/null.h" #include "sound/sound.h" @@ -74,7 +74,7 @@ void Harness_Init(int* argc, char* argv[]) { Harness_ProcessCommandLine(argc, argv); if (harness_game_config.install_signalhandler) { - Platform_InstallSignalHandler(argv[0]); + OS_InstallSignalHandler(argv[0]); } int* keymap = Input_GetKeyMap(); @@ -106,7 +106,7 @@ void Harness_ForceNullRenderer() { } void Harness_Debug_PrintStack() { - Platform_PrintStacktrace(); + OS_PrintStacktrace(); } int Harness_ProcessCommandLine(int* argc, char* argv[]) { diff --git a/src/harness/include/harness/trace.h b/src/harness/include/harness/trace.h index fd2d6ca2..1dc20ece 100644 --- a/src/harness/include/harness/trace.h +++ b/src/harness/include/harness/trace.h @@ -10,7 +10,7 @@ #endif extern int harness_debug_level; -extern int Platform_IsDebuggerPresent(void); +extern int OS_IsDebuggerPresent(void); void Harness_Debug_PrintStack(); @@ -49,7 +49,7 @@ void debug_print_matrix4(const char* fmt, const char* fn, char* name, br_matrix4 #define LOG_PANIC(...) \ do { \ debug_printf("\033[0;31m[PANIC] %s ", __FUNCTION__, __VA_ARGS__); \ - if (Platform_IsDebuggerPresent()) \ + if (OS_IsDebuggerPresent()) \ abort(); \ else \ exit(1); \ diff --git a/src/harness/platforms/platform_linux.c b/src/harness/os/linux.c similarity index 97% rename from src/harness/platforms/platform_linux.c rename to src/harness/os/linux.c index d2670e86..a38bfa99 100644 --- a/src/harness/platforms/platform_linux.c +++ b/src/harness/os/linux.c @@ -18,15 +18,13 @@ #include #include -#include "platform.h" - static int stack_nbr = 0; static char _program_name[1024]; #define MAX_STACK_FRAMES 64 static void* stack_traces[MAX_STACK_FRAMES]; #define TRACER_PID_STRING "TracerPid:" -int Platform_IsDebuggerPresent() { +int OS_IsDebuggerPresent() { char buf[4096]; int status_fd; ssize_t num_read; @@ -155,7 +153,7 @@ void signal_handler(int sig, siginfo_t* siginfo, void* context) { break; } fputs("******************\n", stderr); - Platform_PrintStacktrace(); + OS_PrintStacktrace(); exit(1); } @@ -174,7 +172,7 @@ void resolve_full_path(char* path, const char* argv0) { } } -void Platform_InstallSignalHandler(char* program_name) { +void OS_InstallSignalHandler(char* program_name) { resolve_full_path(_program_name, program_name); @@ -221,7 +219,7 @@ void Platform_InstallSignalHandler(char* program_name) { } } -void Platform_PrintStacktrace() { +void OS_PrintStacktrace() { int i, trace_size = 0; char** messages = (char**)NULL; diff --git a/src/harness/platforms/platform_macosx.c b/src/harness/os/macosx.c similarity index 97% rename from src/harness/platforms/platform_macosx.c rename to src/harness/os/macosx.c index f294fcb2..070f9f8c 100644 --- a/src/harness/platforms/platform_macosx.c +++ b/src/harness/os/macosx.c @@ -15,8 +15,6 @@ #include #include -#include "platform.h" - static int stack_nbr = 0; static char _program_name[1024]; #define MAX_STACK_FRAMES 64 @@ -27,7 +25,7 @@ static void* stack_traces[MAX_STACK_FRAMES]; // Important: Because the definition of the kinfo_proc structure (in ) is conditionalized by __APPLE_API_UNSTABLE, // you should restrict use of the above code to the debug build of your program. -int Platform_IsDebuggerPresent() +int OS_IsDebuggerPresent() // Returns true if the current process is being debugged (either // running under the debugger or has a debugger attached post facto). { @@ -71,6 +69,27 @@ int addr2line(char const* const program_name, void const* const addr) { return system(addr2line_cmd); } +void OS_PrintStacktrace() { + int i, trace_size = 0; + char** messages = (char**)NULL; + + fputs("\nStack trace:\n", stderr); + + trace_size = backtrace(stack_traces, MAX_STACK_FRAMES); + messages = backtrace_symbols(stack_traces, trace_size); + + /* skip the first couple stack frames (as they are this function and + our handler) and also skip the last frame as it's (always?) junk. */ + for (i = 3; i < (trace_size - 1); ++i) { + if (addr2line(_program_name, stack_traces[i]) != 0) { + printf(" error determining line # for: %s\n", messages[i]); + } + } + if (messages) { + free(messages); + } +} + void signal_handler(int sig, siginfo_t* siginfo, void* context) { (void)context; fputs("\n******************\n", stderr); @@ -154,7 +173,7 @@ void signal_handler(int sig, siginfo_t* siginfo, void* context) { break; } fputs("******************\n", stderr); - Platform_PrintStacktrace(); + OS_PrintStacktrace(); exit(1); } @@ -173,7 +192,7 @@ void resolve_full_path(char* path, const char* argv0) { } } -void Platform_InstallSignalHandler(char* program_name) { +void OS_InstallSignalHandler(char* program_name) { resolve_full_path(_program_name, program_name); @@ -219,24 +238,3 @@ void Platform_InstallSignalHandler(char* program_name) { } } } - -void Platform_PrintStacktrace() { - int i, trace_size = 0; - char** messages = (char**)NULL; - - fputs("\nStack trace:\n", stderr); - - trace_size = backtrace(stack_traces, MAX_STACK_FRAMES); - messages = backtrace_symbols(stack_traces, trace_size); - - /* skip the first couple stack frames (as they are this function and - our handler) and also skip the last frame as it's (always?) junk. */ - for (i = 3; i < (trace_size - 1); ++i) { - if (addr2line(_program_name, stack_traces[i]) != 0) { - printf(" error determining line # for: %s\n", messages[i]); - } - } - if (messages) { - free(messages); - } -} \ No newline at end of file diff --git a/src/harness/os/os.h b/src/harness/os/os.h new file mode 100644 index 00000000..44621ce5 --- /dev/null +++ b/src/harness/os/os.h @@ -0,0 +1,10 @@ +#ifndef HARNESS_PLATFORM_H +#define HARNESS_PLATFORM_H + +int OS_IsDebuggerPresent(void); + +void OS_InstallSignalHandler(char* program_name); + +void OS_PrintStacktrace(void); + +#endif diff --git a/src/harness/platforms/platform_windows.c b/src/harness/os/windows.c similarity index 97% rename from src/harness/platforms/platform_windows.c rename to src/harness/os/windows.c index cfa75a00..e3b00750 100644 --- a/src/harness/platforms/platform_windows.c +++ b/src/harness/os/windows.c @@ -22,7 +22,7 @@ static char _program_name[1024]; -int Platform_IsDebuggerPresent() { +int OS_IsDebuggerPresent() { return IsDebuggerPresent(); } @@ -35,7 +35,7 @@ int addr2line(char const* const program_name, void const* const addr) { return system(addr2line_cmd); } -void Platform_PrintStacktrace() { +void OS_PrintStacktrace() { fprintf(stderr, "cannot print stack without context\n"); return; } @@ -151,7 +151,7 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) { return EXCEPTION_EXECUTE_HANDLER; } -void Platform_InstallSignalHandler(char* program_name) { +void OS_InstallSignalHandler(char* program_name) { strcpy(_program_name, program_name); SetUnhandledExceptionFilter(windows_exception_handler); } \ No newline at end of file diff --git a/src/harness/platforms/platform.h b/src/harness/platforms/platform.h deleted file mode 100644 index 3102fa76..00000000 --- a/src/harness/platforms/platform.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef HARNESS_PLATFORM_H -#define HARNESS_PLATFORM_H - -int Platform_IsDebuggerPresent(void); - -void Platform_InstallSignalHandler(char* program_name); - -void Platform_PrintStacktrace(void); - -#endif diff --git a/src/harness/window_io/sdl/sdl_gl.c b/src/harness/platforms/sdl_gl.c similarity index 99% rename from src/harness/window_io/sdl/sdl_gl.c rename to src/harness/platforms/sdl_gl.c index 1ce5afbe..54e1b72d 100644 --- a/src/harness/window_io/sdl/sdl_gl.c +++ b/src/harness/platforms/sdl_gl.c @@ -160,7 +160,7 @@ tRenderer* Window_Create(char* title, int width, int height, int pRender_width, } // Don't grab the mouse when a debugger is present - if (!Platform_IsDebuggerPresent()) { + if (!OS_IsDebuggerPresent()) { SDL_SetRelativeMouseMode(SDL_TRUE); } diff --git a/src/harness/renderers/gl/gl_renderer.c b/src/harness/renderers/gl/gl_renderer.c index 2717b83e..a0f1609d 100644 --- a/src/harness/renderers/gl/gl_renderer.c +++ b/src/harness/renderers/gl/gl_renderer.c @@ -3,7 +3,6 @@ #include "cameras/debug_camera.h" #include "harness.h" #include "harness/trace.h" -#include "platforms/platform.h" #include "shaders.h" #include "stored_context.h" From 85367710a60348eb6108fd356f171537991aa334 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 14 Mar 2022 14:25:11 +1300 Subject: [PATCH 03/28] wip2 --- src/harness/CMakeLists.txt | 2 +- src/harness/os/{macosx.c => macos.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/harness/os/{macosx.c => macos.c} (100%) diff --git a/src/harness/CMakeLists.txt b/src/harness/CMakeLists.txt index 972753af..67fdb1ea 100644 --- a/src/harness/CMakeLists.txt +++ b/src/harness/CMakeLists.txt @@ -66,7 +66,7 @@ if(WIN32) ) elseif(APPLE) target_sources(harness PRIVATE - os/macosx.c + os/macos.c ) else() target_sources(harness PRIVATE diff --git a/src/harness/os/macosx.c b/src/harness/os/macos.c similarity index 100% rename from src/harness/os/macosx.c rename to src/harness/os/macos.c From 8fcad2afa0e392a0c20bd5538d15bdcd627f4cbf Mon Sep 17 00:00:00 2001 From: Dethrace Engineering Department <78985374+dethrace-labs@users.noreply.github.com> Date: Mon, 14 Mar 2022 14:29:57 +1300 Subject: [PATCH 04/28] Create PORTING.md --- docs/PORTING.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 docs/PORTING.md diff --git a/docs/PORTING.md b/docs/PORTING.md new file mode 100644 index 00000000..991af73b --- /dev/null +++ b/docs/PORTING.md @@ -0,0 +1,26 @@ +# Porting Dethrace to other systems + +## Operating Systems + +See: xxx + +Assuming an operating system called _foo_, follow the steps to add support for it. + +1. Add a new file `os/foo.h` and implement the following functions defined in `os/os.h`: + +- `OS_IsDebuggerPresent` +- `OS_InstallSignalHandler` +- `OS_PrintStacktrace` + +2. Update `CMakeLists.h` and add a new conditional section for "os/foo.h", based on existing conditions for Windows, MacOS etc. + +``` +... +elseif( FOO ) +target_sources(harness PRIVATE + os/foo.c +) +... +``` + +## Rendering / Windowing / Input From cb3c5caf045907df1257569b11cd18dd3e6cb08e Mon Sep 17 00:00:00 2001 From: Dethrace Engineering Department <78985374+dethrace-labs@users.noreply.github.com> Date: Tue, 15 Mar 2022 10:08:22 +1300 Subject: [PATCH 05/28] Update PORTING.md --- docs/PORTING.md | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/docs/PORTING.md b/docs/PORTING.md index 991af73b..b8d2fe12 100644 --- a/docs/PORTING.md +++ b/docs/PORTING.md @@ -6,21 +6,60 @@ See: xxx Assuming an operating system called _foo_, follow the steps to add support for it. -1. Add a new file `os/foo.h` and implement the following functions defined in `os/os.h`: +1. Add a new file `os/foo.h` and implement the required functions defined in `os.h`: - `OS_IsDebuggerPresent` - `OS_InstallSignalHandler` - `OS_PrintStacktrace` -2. Update `CMakeLists.h` and add a new conditional section for "os/foo.h", based on existing conditions for Windows, MacOS etc. +2. Update `src/harness/CMakeLists.h` and add a new conditional section for "os/foo.h", based on existing conditions for Windows, MacOS etc. + +For example: ``` ... -elseif( FOO ) +elseif( _FOO_ ) target_sources(harness PRIVATE os/foo.c ) ... ``` -## Rendering / Windowing / Input +## IO Platform (windowing / input / rendering) + +An `IOPlatform` in _dethrace_ implements windowing and input handling, and points to a _renderer_. + +The default IO platform is `SDL_OpenGL`, which uses SDL for windowing and input, and OpenGL for rendering. See `io_platforms/sdl_gl.c`. + +To add a new `IOPlatform`: + +1. Create `io_platforms/my_platform.c` file and implement the required functions defined in `io_platform.h`: +- `Window_Create` +- `Window_PollEvents` +- `Window_Swap` +- `Input_GetKeyMap` +- `Input_IsKeyDown` + +`Window_Create` returns a `tRenderer*`, which must implement the interface defined in `renderers/renderer.h`. See `renderers/gl` for an example. + +2. Add a new conditional section in `src/harness/CMakeLists.txt` for your new platform + +For example: +``` +if (RENDERER_PLATFORM STREQUAL "My_Platform") + target_sources(harness PRIVATE + io_platforms/my_platform.c + ) +endif() +``` + +3. Run cmake to update your build with the new platform +```sh +cd build +cmake -DRENDERER_PLATFORM=My_Platform .. +``` + +4. Build +``` +cmake --build . +``` From db30529daf33a9920c465f92ba0ea16c970e6f55 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Tue, 15 Mar 2022 10:09:38 +1300 Subject: [PATCH 06/28] io_platform --- src/BRSRC13/CORE/FW/datafile.c | 88 +++++++++---------- src/DETHRACE/common/drmem.c | 2 - src/DETHRACE/common/loading.c | 3 - src/harness/CMakeLists.txt | 3 +- src/harness/harness.c | 1 + src/harness/harness.h | 8 +- src/harness/io_platforms/io_platform.h | 12 +++ .../{platforms => io_platforms}/sdl_gl.c | 0 8 files changed, 60 insertions(+), 57 deletions(-) create mode 100644 src/harness/io_platforms/io_platform.h rename src/harness/{platforms => io_platforms}/sdl_gl.c (100%) diff --git a/src/BRSRC13/CORE/FW/datafile.c b/src/BRSRC13/CORE/FW/datafile.c index 35b12f7e..17bf9ef0 100644 --- a/src/BRSRC13/CORE/FW/datafile.c +++ b/src/BRSRC13/CORE/FW/datafile.c @@ -11,38 +11,38 @@ br_file_primitives _BrFilePrimsNull = { "NULL", - (int(*)(br_datafile*,br_uint_32))&BrNullOther, - (int(*)(br_datafile*, br_uint_32, br_uint_32))&BrNullOther, - (int(*)(br_datafile*, br_uint_32*))&BrNullOther, - (void(*)(br_datafile*, br_uint_32))&BrNullOther, - (br_uint_32(*)(br_datafile*))&BrNullOther, - (int(*)(br_datafile*))&BrNullOther, - (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, - (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, - (int(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, - (int(*)(br_datafile*, void*, int, int, int, int))&BrNullOther, - (void*(*)(br_datafile*, void*, int*, int, int))&BrNullOther, - (int(*)(br_datafile*, void*, int, int, int, int))&BrNullOther, - (int(*)(br_datafile*, char*))&BrNullOther, - (char*(*)(br_datafile*, char*))&BrNullOther, - (int(*)(br_datafile*, char*))&BrNullOther, + (int (*)(br_datafile*, br_uint_32)) & BrNullOther, + (int (*)(br_datafile*, br_uint_32, br_uint_32)) & BrNullOther, + (int (*)(br_datafile*, br_uint_32*)) & BrNullOther, + (void (*)(br_datafile*, br_uint_32)) & BrNullOther, + (br_uint_32(*)(br_datafile*)) & BrNullOther, + (int (*)(br_datafile*)) & BrNullOther, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, + (int (*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, + (int (*)(br_datafile*, void*, int, int, int, int)) & BrNullOther, + (void* (*)(br_datafile*, void*, int*, int, int)) & BrNullOther, + (int (*)(br_datafile*, void*, int, int, int, int)) & BrNullOther, + (int (*)(br_datafile*, char*)) & BrNullOther, + (char* (*)(br_datafile*, char*)) & BrNullOther, + (int (*)(br_datafile*, char*)) & BrNullOther, }; br_file_primitives _BrFilePrimsReadBinary = { "Read Binary", &DfSkipBinary, - (int(*)(br_datafile*, br_uint_32, br_uint_32))&BrNullOther, + (int (*)(br_datafile*, br_uint_32, br_uint_32)) & BrNullOther, &DfChunkReadBinary, - (void(*)(br_datafile*, br_uint_32))&BrNullOther, + (void (*)(br_datafile*, br_uint_32)) & BrNullOther, &DfCountReadBinary, &DfCountSizeBinary, - (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, &DfStructReadBinary, &DfStructSizeBinary, - (int(*)(br_datafile*, void*, int, int, int, int))&BrNullOther, + (int (*)(br_datafile*, void*, int, int, int, int)) & BrNullOther, &DfBlockReadBinary, &DfBlockSizeBinary, - (int(*)(br_datafile*, char*))&BrNullOther, + (int (*)(br_datafile*, char*)) & BrNullOther, &DfNameReadBinary, &DfNameSizeBinary, }; @@ -51,36 +51,36 @@ br_file_primitives _BrFilePrimsWriteBinary = { "Write Binary", &DfSkipBinary, &DfChunkWriteBinary, - (int(*)(br_datafile*, br_uint_32*))&BrNullOther, + (int (*)(br_datafile*, br_uint_32*)) & BrNullOther, &DfCountWriteBinary, - (br_uint_32(*)(br_datafile*))&BrNullOther, + (br_uint_32(*)(br_datafile*)) & BrNullOther, &DfCountSizeBinary, &DfStructWriteBinary, - (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, &DfStructSizeBinary, &DfBlockWriteBinary, - (void*(*)(br_datafile*, void*, int*, int, int))&BrNullOther, + (void* (*)(br_datafile*, void*, int*, int, int)) & BrNullOther, &DfBlockSizeBinary, &DfNameWriteBinary, - (char*(*)(br_datafile*, char*))&BrNullOther, + (char* (*)(br_datafile*, char*)) & BrNullOther, &DfNameSizeBinary, }; br_file_primitives _BrFilePrimsReadText = { "Read Text", &DfSkipText, - (int(*)(br_datafile*, br_uint_32, br_uint_32))&BrNullOther, + (int (*)(br_datafile*, br_uint_32, br_uint_32)) & BrNullOther, &DfChunkReadText, - (void(*)(br_datafile*, br_uint_32))&BrNullOther, + (void (*)(br_datafile*, br_uint_32)) & BrNullOther, &DfCountReadText, &DfCountSizeText, - (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, &DfStructReadText, &DfStructSizeText, - (int(*)(br_datafile*, void*, int, int, int, int))&BrNullOther, + (int (*)(br_datafile*, void*, int, int, int, int)) & BrNullOther, &DfBlockReadText, &DfBlockSizeText, - (int(*)(br_datafile*, char*))&BrNullOther, + (int (*)(br_datafile*, char*)) & BrNullOther, &DfNameReadText, &DfNameSizeText, }; @@ -89,18 +89,18 @@ br_file_primitives _BrFilePrimsWriteText = { "Write Text", &DfSkipText, &DfChunkWriteText, - (int(*)(br_datafile*, br_uint_32*))&BrNullOther, + (int (*)(br_datafile*, br_uint_32*)) & BrNullOther, &DfCountWriteText, - (br_uint_32(*)(br_datafile*))&BrNullOther, + (br_uint_32(*)(br_datafile*)) & BrNullOther, &DfCountSizeText, &DfStructWriteText, - (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, &DfStructSizeText, &DfBlockWriteText, - (void*(*)(br_datafile*, void*, int*, int, int))&BrNullOther, + (void* (*)(br_datafile*, void*, int*, int, int)) & BrNullOther, &DfBlockSizeText, &DfNameWriteText, - (char*(*)(br_datafile*, char*))&BrNullOther, + (char* (*)(br_datafile*, char*)) & BrNullOther, &DfNameSizeText, }; @@ -289,7 +289,8 @@ int TextReadLine(br_datafile* df, char** ident, char** data) { } for (; (*cp == ' ') || (*cp == '\t'); cp++) { } - if (*cp != '\0') break; + if (*cp != '\0') + break; } *ident = cp; while ((*cp != ' ') && (*cp != '\t') && (*cp != '\0')) { @@ -320,7 +321,7 @@ br_uint_16 scalarTypeConvert(br_datafile* df, br_uint_16 t) { LOG_TRACE9("(%p, %d)", df, t); if (df->scalar_type == BRT_FIXED) { - switch(t) { + switch (t) { case DF_TYPE_BR_SCALAR: return DF_TYPE_BR_FIXED; case DF_TYPE_BR_FRACTION: @@ -418,8 +419,8 @@ br_uint_32 DfStructWriteBinary(br_datafile* df, br_file_struct* str, void* base) DfStructWriteBinary(df, sm->extra, mp); break; case DF_TYPE_ASCIZ: - if (*(char **)mp != NULL) { - BrFileWrite(*(char **)mp, 1, BrStrLen(*(char**)mp), df->h); + if (*(char**)mp != NULL) { + BrFileWrite(*(char**)mp, 1, BrStrLen(*(char**)mp), df->h); } BrFilePutChar('\0', df->h); break; @@ -822,14 +823,14 @@ br_uint_32 StructWriteTextSub(br_datafile* df, br_file_struct* str, void* base, StructWriteTextSub(df, sm->extra, mp, indent + 2); break; case DF_TYPE_ASCIZ: - if (*(char **)mp == NULL) { + if (*(char**)mp == NULL) { w = BrFilePrintf(df->h, "NULL"); } else { - w = BrFilePrintf(df->h, "\"%s\"", *(char **)mp); + w = BrFilePrintf(df->h, "\"%s\"", *(char**)mp); } break; case DF_TYPE_BR_COLOUR: - w = BrFilePrintf(df->h, "%d,%d,%d", (br_uint_8)((*(br_uint_32 *)mp) >> 16), (br_uint_8)((*(br_uint_32 *)mp) >> 8), (br_uint_8)((*(br_uint_32 *)mp))); + w = BrFilePrintf(df->h, "%d,%d,%d", (br_uint_8)((*(br_uint_32*)mp) >> 16), (br_uint_8)((*(br_uint_32*)mp) >> 8), (br_uint_8)((*(br_uint_32*)mp))); break; case DF_TYPE_BR_FRACTION_X: w = BrFilePrintf(df->h, "%g", (double)BrFixedFractionToFloat(*(br_fraction_x*)mp)); @@ -1499,7 +1500,7 @@ int DfChunksInterpret(br_datafile* df, br_chunks_table* table) { while (1) { id = df->prims->chunk_read(df, &length); - //LOG_DEBUG("chunk id=%d, len=%d", id, length); + // LOG_DEBUG("chunk id=%d, len=%d", id, length); if (id == (br_uint_32)-1) { break; } @@ -1563,7 +1564,6 @@ br_datafile* DfOpen(char* name, int write, br_token scalar_type) { h = BrFileOpenRead(name, 8u, DfFileIdentify, &mode); } if (h == NULL) { - LOG_WARN("returning NULL"); return NULL; } df = BrResAllocate(fw.res, sizeof(br_datafile), BR_MEMORY_DATAFILE); diff --git a/src/DETHRACE/common/drmem.c b/src/DETHRACE/common/drmem.c index 299c03a5..13a06ed8 100644 --- a/src/DETHRACE/common/drmem.c +++ b/src/DETHRACE/common/drmem.c @@ -282,8 +282,6 @@ void MAMSInitMem() { FILE* f; tPath_name the_path; LOG_TRACE("()"); - - LOG_WARN("nop in Windows (doing something for DOS?)"); } // IDA: void __usercall PrintMemoryDump(int pFlags@, char *pTitle@) diff --git a/src/DETHRACE/common/loading.c b/src/DETHRACE/common/loading.c index 8a4c2189..32222377 100644 --- a/src/DETHRACE/common/loading.c +++ b/src/DETHRACE/common/loading.c @@ -3193,9 +3193,6 @@ FILE* DRfopen(char* pFilename, char* pMode) { PDFatalError(msg); } } - if (!result) { - LOG_WARN("failed for %d", errno); - } return result; } diff --git a/src/harness/CMakeLists.txt b/src/harness/CMakeLists.txt index 67fdb1ea..7abc4014 100644 --- a/src/harness/CMakeLists.txt +++ b/src/harness/CMakeLists.txt @@ -40,6 +40,7 @@ target_sources(harness PRIVATE harness_trace.c harness.c harness.h + io_platforms/io_platform.h renderers/null.h renderers/renderer.h brender_emu/renderer_impl.c @@ -50,7 +51,7 @@ target_sources(harness PRIVATE if (RENDERER_PLATFORM STREQUAL "SDL_OpenGL") target_sources(harness PRIVATE - platforms/sdl_gl.c + io_platforms/sdl_gl.c renderers/gl/gl_renderer.c renderers/gl/gl_renderer.h renderers/gl/shaders.c diff --git a/src/harness/harness.c b/src/harness/harness.c index ffe1c932..0cf21f8d 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -2,6 +2,7 @@ #include "harness.h" #include "brender_emu/renderer_impl.h" #include "include/harness/config.h" +#include "io_platforms/io_platform.h" #include "os/os.h" #include "renderers/null.h" #include "sound/sound.h" diff --git a/src/harness/harness.h b/src/harness/harness.h index 8c8e1d64..f5b6708c 100644 --- a/src/harness/harness.h +++ b/src/harness/harness.h @@ -3,7 +3,6 @@ #include "brender/br_types.h" #include "harness/trace.h" -#include "renderers/renderer.h" void Harness_ForceNullRenderer(); @@ -14,11 +13,6 @@ typedef struct tCamera { void (*setPosition)(); } tCamera; -// platform stuff. See cmake variable RENDERER_PLATFORM -tRenderer* Window_Create(char* title, int width, int height, int pRender_width, int pRender_height); -void Window_PollEvents(void); -void Window_Swap(int delay_ms_after_swap); -int* Input_GetKeyMap(void); -int Input_IsKeyDown(unsigned char scan_code); + #endif \ No newline at end of file diff --git a/src/harness/io_platforms/io_platform.h b/src/harness/io_platforms/io_platform.h new file mode 100644 index 00000000..e4ee4ea3 --- /dev/null +++ b/src/harness/io_platforms/io_platform.h @@ -0,0 +1,12 @@ +#ifndef PLATFORM_H +#define PLATFORM_H + +#include "../renderers/renderer.h" + +tRenderer* Window_Create(char* title, int width, int height, int pRender_width, int pRender_height); +void Window_PollEvents(void); +void Window_Swap(int delay_ms_after_swap); +int* Input_GetKeyMap(void); +int Input_IsKeyDown(unsigned char scan_code); + +#endif \ No newline at end of file diff --git a/src/harness/platforms/sdl_gl.c b/src/harness/io_platforms/sdl_gl.c similarity index 100% rename from src/harness/platforms/sdl_gl.c rename to src/harness/io_platforms/sdl_gl.c From 37b8c9f83f2c0823bef00bc91546d43e2ee2f492 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Thu, 17 Mar 2022 19:41:34 +1300 Subject: [PATCH 07/28] wip --- src/DETHRACE/common/cutscene.c | 15 ++--- src/DETHRACE/common/errors.c | 51 ++++++++++------ src/DETHRACE/pc-dos/dosnet.c | 2 + src/DETHRACE/pc-dos/dossys.c | 80 ++++++++++---------------- src/harness/CMakeLists.txt | 1 + src/harness/harness.c | 2 +- src/harness/include/harness/trace.h | 4 -- src/harness/os/linux.c | 14 +++++ src/harness/os/macos.c | 14 +++++ src/harness/os/os.h | 10 ---- src/harness/os/windows.c | 17 ++++++ src/harness/renderers/gl/gl_renderer.c | 2 + test/DETHRACE/test_controls.c | 2 +- test/DETHRACE/test_input.c | 2 +- test/main.c | 8 --- test/tests.h | 23 ++++---- 16 files changed, 133 insertions(+), 114 deletions(-) delete mode 100644 src/harness/os/os.h diff --git a/src/DETHRACE/common/cutscene.c b/src/DETHRACE/common/cutscene.c index 79103d10..0a44cdc6 100644 --- a/src/DETHRACE/common/cutscene.c +++ b/src/DETHRACE/common/cutscene.c @@ -4,6 +4,7 @@ #include "globvrpb.h" #include "graphics.h" #include "harness/config.h" +#include "harness/os.h" #include "harness/trace.h" #include "input.h" #include "loading.h" @@ -38,7 +39,7 @@ void PlaySmackerFile(char* pSmack_name) { tPath_name the_path; br_colour* br_colours_ptr; tU8* smack_colours_ptr; - //Smack* smk; + // Smack* smk; int i; int j; int len; @@ -83,10 +84,7 @@ void PlaySmackerFile(char* pSmack_name) { smk_info_video(s, &w, &h, NULL); double fps = 1000000.0 / usf; int delay_ms = (1 / fps) * 1000; -#ifndef _WIN32 - ts.tv_sec = delay_ms / 1000; - ts.tv_nsec = (delay_ms % 1000) * 1000000; -#endif + smk_enable_video(s, 1); smk_first(s); @@ -112,13 +110,8 @@ void PlaySmackerFile(char* pSmack_name) { if (AnyKeyDown() || EitherMouseButtonDown()) { break; } - // wait until its time for the next frame -#ifndef _WIN32 - nanosleep(&ts, &ts); -#else - Sleep(delay_ms); -#endif + OS_Sleep(delay_ms); } while (smk_next(s) == SMK_MORE); smk_close(s); diff --git a/src/DETHRACE/common/errors.c b/src/DETHRACE/common/errors.c index e32612cd..79b19e3a 100644 --- a/src/DETHRACE/common/errors.c +++ b/src/DETHRACE/common/errors.c @@ -5,6 +5,7 @@ #include #include +#include "globvars.h" #include "graphics.h" #include "harness/trace.h" #include "network.h" @@ -148,27 +149,25 @@ void FatalError(int pStr_index, ...) { va_start(ap, pStr_index); - int read_timer = PDGetTotalTime(); - gError_code = 0x20000000 + read_timer; - strcpy(the_str, gError_messages[pStr_index - 1]); + gError_code = 0x20000000 + PDGetTotalTime(); + strcpy(the_str, gError_messages[pStr_index]); sub_pt = temp_str; - for (i = 0; i < strlen(the_str); i++) { - if (the_str[i] == '%') { - sub_str = va_arg(ap, char*); - StripCR(sub_str); - strcpy(sub_pt, sub_str); - sub_pt += strlen(sub_str); - } else { - *sub_pt = the_str[i]; - sub_pt++; + while (1) { + sub_pt = strchr(the_str, '%'); + if (!sub_pt) { + break; } + sub_str = va_arg(ap, char*); + StripCR(sub_str); + strcpy(temp_str, sub_pt + 1); + strcpy(sub_pt, sub_str); + strcat(the_str, temp_str); } - *sub_pt = 0; va_end(ap); dr_dprintf(the_str); FadePaletteUp(); - PDFatalError(temp_str); + PDFatalError(the_str); } // IDA: void __cdecl NonFatalError(int pStr_index, ...) @@ -205,22 +204,40 @@ void NonFatalError(int pStr_index, ...) { // IDA: void __cdecl CloseDiagnostics() void CloseDiagnostics() { LOG_TRACE("()"); + + fclose(gDiagnostic_file); } // IDA: void __cdecl OpenDiagnostics() void OpenDiagnostics() { LOG_TRACE("()"); + + gDiagnostic_file = fopen("DIAGNOST.TXT", "w"); + + fputs("DIAGNOSTIC OUTPUT\n", gDiagnostic_file); + // todo: generate a real date + fprintf(gDiagnostic_file, "Date / time : %s\n\n\n", "Mon Mar 24 16 : 32 : 33 1997"); } // Renamed from dprintf to avoid collisions to stdio +// This function is stripped from the retail binary, we've guessed at the implementation void dr_dprintf(char* fmt_string, ...) { + static tU32 first_time = 0; va_list args; + tU32 the_time; + + if (first_time == 0) { + first_time = GetTotalTime(); + } + the_time = GetTotalTime() - first_time; + + fprintf(gDiagnostic_file, "%7d.%02d: ", the_time / 1000, the_time % 100); - printf("dprintf: "); va_start(args, fmt_string); - vprintf(fmt_string, args); + vfprintf(gDiagnostic_file, fmt_string, args); va_end(args); - printf("\n"); + + fputs("\n", gDiagnostic_file); } // IDA: int __usercall DoErrorInterface@(int pMisc_text_index@) diff --git a/src/DETHRACE/pc-dos/dosnet.c b/src/DETHRACE/pc-dos/dosnet.c index 3c9b76c5..e17269ca 100644 --- a/src/DETHRACE/pc-dos/dosnet.c +++ b/src/DETHRACE/pc-dos/dosnet.c @@ -352,6 +352,8 @@ void PDNetObtainSystemUserName(char* pName, int pMax_length) { int size; char buffer[16]; BOOL result; + + PDNetObtainSystemUserName_win95sys(pName, pMax_length); #endif dr_dprintf("PDNetObtainSystemUserName()\n"); diff --git a/src/DETHRACE/pc-dos/dossys.c b/src/DETHRACE/pc-dos/dossys.c index 123c41cb..0f09fe9c 100644 --- a/src/DETHRACE/pc-dos/dossys.c +++ b/src/DETHRACE/pc-dos/dossys.c @@ -6,6 +6,7 @@ #include "graphics.h" #include "harness/config.h" #include "harness/hooks.h" +#include "harness/os.h" #include "harness/trace.h" #include "input.h" #include "loadsave.h" @@ -24,33 +25,6 @@ #include #include -#ifdef _WIN32 -#define NS_PER_SEC (1000ULL * 1000ULL * 1000ULL) -#define CLOCK_MONOTONIC 1 - -int clock_gettime(int dummy, struct timespec* tv) { - static LARGE_INTEGER ticksPerSec; - LARGE_INTEGER ticks; - double seconds; - - if (!ticksPerSec.QuadPart) { - QueryPerformanceFrequency(&ticksPerSec); - if (!ticksPerSec.QuadPart) { - errno = ENOTSUP; - return -1; - } - } - - QueryPerformanceCounter(&ticks); - - seconds = (double)ticks.QuadPart / (double)ticksPerSec.QuadPart; - tv->tv_sec = (time_t)seconds; - tv->tv_nsec = (long)((ULONGLONG)(seconds * NS_PER_SEC) % NS_PER_SEC); - - return 0; -} -#endif - #ifdef __DOS__ #define GFX_INIT_STRING_32X20X8 "MCGA,W:320,H:200,B:8" #define GFX_INIT_STRING_64X48X8 "VESA,W:640,H:480,B:8" @@ -230,9 +204,9 @@ void KeyBegin() { // *(_WORD *)gScan_code[9] = 56; // *(_WORD *)gScan_code[10] = 29; - //gPrev_keyboard_handler = (void (__fastcall *)())dos_getvect(9); - //unk_142E6C = v2; - //dos_setvect(9, KeyboardHandler); + // gPrev_keyboard_handler = (void (__fastcall *)())dos_getvect(9); + // unk_142E6C = v2; + // dos_setvect(9, KeyboardHandler); } // IDA: void __cdecl KeyEnd() @@ -318,9 +292,9 @@ void PDInitialiseSystem() { KeyBegin(); - //v4 = DOSMouseBegin(); + // v4 = DOSMouseBegin(); gJoystick_deadzone = 8000; - //gUpper_loop_limit = sub_A1940(v4, v5, v3, v6) / 2; + // gUpper_loop_limit = sub_A1940(v4, v5, v3, v6) / 2; // Demo does not ship with KEYBOARD.COK file if (harness_game_info.mode != eGame_carmageddon_demo) { @@ -520,25 +494,32 @@ void PDBuildAppPath(char* pThe_path) { void PDForEveryFile(char* pThe_path, void (*pAction_routine)(char*)) { char find_path[256]; char found_path[256]; - //find_t the_find_buffer; + // find_t the_find_buffer; DIR* d; struct dirent* entry; - d = opendir(pThe_path); - if (d) { - while ((entry = readdir(d)) != NULL) { - // only files, and only files that don't start with '.' -#ifdef _WIN32 - if ((GetFileAttributesA(pThe_path) & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) { -#else - if (entry->d_type == DT_REG && entry->d_name[0] != '.') { -#endif - PathCat(found_path, pThe_path, entry->d_name); - pAction_routine(found_path); - } - } - closedir(d); + char* results[200]; + + int count = OS_GetFilesInDirectory(pThe_path, results, 200); + + for (int i = 0; i < count; i++) { } + + // d = opendir(pThe_path); + // if (d) { + // while ((entry = readdir(d)) != NULL) { + // // only files, and only files that don't start with '.' + // #ifdef _WIN32 + // if ((GetFileAttributesA(pThe_path) & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) { + // #else + // if (entry->d_type == DT_REG && entry->d_name[0] != '.') { + // #endif + // PathCat(found_path, pThe_path, entry->d_name); + // pAction_routine(found_path); + // } + // } + // closedir(d); + // } } // IDA: void __usercall PDSetPalette(br_pixelmap *pThe_palette@) @@ -596,9 +577,8 @@ void PDGetMousePosition(int* pX_coord, int* pY_coord) { // IDA: int __cdecl PDGetTotalTime() int PDGetTotalTime() { - struct timespec spec; - clock_gettime(CLOCK_MONOTONIC, &spec); - return spec.tv_sec * 1000 + spec.tv_nsec / 1000000; + + return OS_GetTime(); } // IDA: int __usercall PDServiceSystem@(tU32 pTime_since_last_call@) diff --git a/src/harness/CMakeLists.txt b/src/harness/CMakeLists.txt index 7abc4014..66b44f04 100644 --- a/src/harness/CMakeLists.txt +++ b/src/harness/CMakeLists.txt @@ -34,6 +34,7 @@ target_sources(harness PRIVATE include/harness/hooks.h include/harness/trace.h include/harness/config.h + include/harness/os.h cameras/debug_camera.c cameras/debug_camera.h diff --git a/src/harness/harness.c b/src/harness/harness.c index 0cf21f8d..fd17f608 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -2,8 +2,8 @@ #include "harness.h" #include "brender_emu/renderer_impl.h" #include "include/harness/config.h" +#include "include/harness/os.h" #include "io_platforms/io_platform.h" -#include "os/os.h" #include "renderers/null.h" #include "sound/sound.h" diff --git a/src/harness/include/harness/trace.h b/src/harness/include/harness/trace.h index 1dc20ece..e8ef26aa 100644 --- a/src/harness/include/harness/trace.h +++ b/src/harness/include/harness/trace.h @@ -5,10 +5,6 @@ #include #include -#if defined _WIN32 && !defined sleep -#define sleep(x) _sleep(x) -#endif - extern int harness_debug_level; extern int OS_IsDebuggerPresent(void); diff --git a/src/harness/os/linux.c b/src/harness/os/linux.c index a38bfa99..8d76c434 100644 --- a/src/harness/os/linux.c +++ b/src/harness/os/linux.c @@ -16,6 +16,7 @@ #include #include #include +#include #include static int stack_nbr = 0; @@ -24,6 +25,19 @@ static char _program_name[1024]; static void* stack_traces[MAX_STACK_FRAMES]; #define TRACER_PID_STRING "TracerPid:" +uint32_t OS_GetTime() { + struct timespec spec; + clock_gettime(CLOCK_MONOTONIC, &spec); + return spec.tv_sec * 1000 + spec.tv_nsec / 1000000; +} + +void OS_Sleep(int delay_ms) { + struct timespec ts; + ts.tv_sec = delay_ms / 1000; + ts.tv_nsec = (delay_ms % 1000) * 1000000; + nanosleep(&ts, &ts); +} + int OS_IsDebuggerPresent() { char buf[4096]; int status_fd; diff --git a/src/harness/os/macos.c b/src/harness/os/macos.c index 070f9f8c..4f558149 100644 --- a/src/harness/os/macos.c +++ b/src/harness/os/macos.c @@ -13,6 +13,7 @@ #include #include #include +#include #include static int stack_nbr = 0; @@ -20,6 +21,19 @@ static char _program_name[1024]; #define MAX_STACK_FRAMES 64 static void* stack_traces[MAX_STACK_FRAMES]; +uint32_t OS_GetTime() { + struct timespec spec; + clock_gettime(CLOCK_MONOTONIC, &spec); + return spec.tv_sec * 1000 + spec.tv_nsec / 1000000; +} + +void OS_Sleep(int delay_ms) { + struct timespec ts; + ts.tv_sec = delay_ms / 1000; + ts.tv_nsec = (delay_ms % 1000) * 1000000; + nanosleep(&ts, &ts); +} + // https://developer.apple.com/library/archive/qa/qa1361/_index.html // FIXME: // Important: Because the definition of the kinfo_proc structure (in ) is conditionalized by __APPLE_API_UNSTABLE, diff --git a/src/harness/os/os.h b/src/harness/os/os.h deleted file mode 100644 index 44621ce5..00000000 --- a/src/harness/os/os.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef HARNESS_PLATFORM_H -#define HARNESS_PLATFORM_H - -int OS_IsDebuggerPresent(void); - -void OS_InstallSignalHandler(char* program_name); - -void OS_PrintStacktrace(void); - -#endif diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index e3b00750..8c266fd8 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -21,6 +21,23 @@ #endif static char _program_name[1024]; +LARGE_INTEGER qpc_start_time, EndingTime, ElapsedMicroseconds; +LARGE_INTEGER qpc_ticks_per_sec; + +void OS_Sleep(int delay_ms) { + Sleep(delay_ms); +} + +uint32_t OS_GetTime() { + LARGE_INTEGER now; + if (qpc_start_time == 0) { + QueryPerformanceFrequency(&qpc_ticks_per_sec); + QueryPerformanceCounter(&qpc_start_time); + } + + QueryPerformanceCounter(&now); + return (((now.QuadPart - qpc_start_time.QuadPart) * 1000) / qpc_ticks_per_sec.QuadPart); +} int OS_IsDebuggerPresent() { return IsDebuggerPresent(); diff --git a/src/harness/renderers/gl/gl_renderer.c b/src/harness/renderers/gl/gl_renderer.c index a0f1609d..b1dbb2a8 100644 --- a/src/harness/renderers/gl/gl_renderer.c +++ b/src/harness/renderers/gl/gl_renderer.c @@ -357,6 +357,8 @@ void build_model(br_model* model) { tStored_model_context* ctx; v11model* v11; + LOG_DEBUG("called %s", model->identifier); + v11 = model->prepared; ctx = NewStoredModelContext(); diff --git a/test/DETHRACE/test_controls.c b/test/DETHRACE/test_controls.c index d8251db2..8c9d2027 100644 --- a/test/DETHRACE/test_controls.c +++ b/test/DETHRACE/test_controls.c @@ -24,7 +24,7 @@ void test_controls_CheckKevKeys() { gKeys_pressed = 0; result = KevKeyService(); } - sleep_s(2); + OS_Sleep(2000); gKeys_pressed = 0; CheckKevKeys(); diff --git a/test/DETHRACE/test_input.c b/test/DETHRACE/test_input.c index ce471f42..ead31982 100644 --- a/test/DETHRACE/test_input.c +++ b/test/DETHRACE/test_input.c @@ -15,7 +15,7 @@ void test_input_KevKeyService() { gKeys_pressed = 0; result = KevKeyService(); } - sleep_s(2); + OS_Sleep(2000); gKeys_pressed = 0; result = KevKeyService(); diff --git a/test/main.c b/test/main.c index dace502d..f415a9fa 100644 --- a/test/main.c +++ b/test/main.c @@ -190,14 +190,6 @@ int has_data_directory() { return root_dir != NULL; } -void sleep_s(int sec) { -#ifdef _WIN32 - Sleep(1000 * sec); -#else - sleep(sec); -#endif -} - void create_temp_file(char buffer[PATH_MAX + 1], const char* prefix) { #ifdef _WIN32 DWORD attributes; diff --git a/test/tests.h b/test/tests.h index 75aeb9f5..2ef52ac1 100644 --- a/test/tests.h +++ b/test/tests.h @@ -2,6 +2,7 @@ #define TESTS_H #include "framework/unity.h" +#include "harness/os.h" #include "harness/trace.h" #ifndef PATH_MAX @@ -14,23 +15,23 @@ #define HOST_NL "\n" #endif -void TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(const uint8_t *expected, char *filename, int len); -void TEST_ASSERT_EQUAL_FILE_TEXT(const char *expected, char *filename); +void TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(const uint8_t* expected, char* filename, int len); +void TEST_ASSERT_EQUAL_FILE_TEXT(const char* expected, char* filename); extern int has_data_directory(); -extern void sleep_s(int sec); -void create_temp_file(char buffer[PATH_MAX+1], const char *prefix); +void create_temp_file(char buffer[PATH_MAX + 1], const char* prefix); #define REQUIRES_DATA_DIRECTORY() \ if (!has_data_directory()) \ TEST_IGNORE(); -#define TEST_ASSERT_FLOAT_ARRAY_WITHIN(delta, expected, actual, num_elements) do { \ - float *priv_expected = (float*)(expected); \ - float *priv_actual = (float*)(actual); \ - for(int it = (num_elements); it != 0; --it, ++priv_expected, ++priv_actual) { \ - TEST_ASSERT_FLOAT_WITHIN((delta), *priv_expected, *priv_actual); \ - } \ -} while (0) +#define TEST_ASSERT_FLOAT_ARRAY_WITHIN(delta, expected, actual, num_elements) \ + do { \ + float* priv_expected = (float*)(expected); \ + float* priv_actual = (float*)(actual); \ + for (int it = (num_elements); it != 0; --it, ++priv_expected, ++priv_actual) { \ + TEST_ASSERT_FLOAT_WITHIN((delta), *priv_expected, *priv_actual); \ + } \ + } while (0) #endif From 6c89c3eb2f06ad2117c08fc35b62e17dbe9bbe27 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Fri, 18 Mar 2022 11:10:36 +1300 Subject: [PATCH 08/28] removes miniposix --- CMakeLists.txt | 2 +- src/BRSRC13/CMakeLists.txt | 2 +- src/DETHRACE/CMakeLists.txt | 2 +- src/DETHRACE/pc-dos/dosnet.c | 1 - src/DETHRACE/pc-dos/dossys.c | 39 +++------------- src/harness/CMakeLists.txt | 2 +- src/harness/harness.c | 5 +-- src/harness/include/harness/os.h | 26 +++++++++++ src/harness/include/harness/trace.h | 2 - src/harness/os/linux.c | 70 ++++++++++++++++++++--------- src/harness/os/macos.c | 31 ++++++++++++- src/harness/os/windows.c | 42 ++++++++++++----- 12 files changed, 145 insertions(+), 79 deletions(-) create mode 100644 src/harness/include/harness/os.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 389dea72..ea7caba5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ option(BUILD_TESTS "Build unit tests." OFF) find_package(SDL2 REQUIRED) add_subdirectory(lib/libsmacker) -add_subdirectory(lib/miniposix) +#add_subdirectory(lib/miniposix) add_subdirectory(lib/glad) add_subdirectory(lib/cglm EXCLUDE_FROM_ALL) diff --git a/src/BRSRC13/CMakeLists.txt b/src/BRSRC13/CMakeLists.txt index 9ab1423e..2375948b 100644 --- a/src/BRSRC13/CMakeLists.txt +++ b/src/BRSRC13/CMakeLists.txt @@ -10,7 +10,7 @@ target_include_directories(brender include ) -target_link_libraries(brender PRIVATE harness miniposix) +target_link_libraries(brender PRIVATE harness) if(NOT MSVC) target_compile_options(brender PRIVATE diff --git a/src/DETHRACE/CMakeLists.txt b/src/DETHRACE/CMakeLists.txt index 83e1cbc7..653a44b4 100644 --- a/src/DETHRACE/CMakeLists.txt +++ b/src/DETHRACE/CMakeLists.txt @@ -10,7 +10,7 @@ target_include_directories(dethrace_obj pd ) -target_link_libraries(dethrace_obj PUBLIC miniposix SDL2::SDL2 smacker harness brender s3 cglm) +target_link_libraries(dethrace_obj PUBLIC SDL2::SDL2 smacker harness brender s3 cglm) if (CMAKE_C_COMPILER_ID MATCHES "Clang") target_compile_options(dethrace_obj PRIVATE diff --git a/src/DETHRACE/pc-dos/dosnet.c b/src/DETHRACE/pc-dos/dosnet.c index abaa1421..806453ee 100644 --- a/src/DETHRACE/pc-dos/dosnet.c +++ b/src/DETHRACE/pc-dos/dosnet.c @@ -353,7 +353,6 @@ void PDNetObtainSystemUserName(char* pName, int pMax_length) { char buffer[16]; BOOL result; - PDNetObtainSystemUserName_win95sys(pName, pMax_length); #endif dr_dprintf("PDNetObtainSystemUserName()\n"); diff --git a/src/DETHRACE/pc-dos/dossys.c b/src/DETHRACE/pc-dos/dossys.c index 55048769..f6ce0cc5 100644 --- a/src/DETHRACE/pc-dos/dossys.c +++ b/src/DETHRACE/pc-dos/dossys.c @@ -271,8 +271,6 @@ void PDFatalError(char* pThe_str) { // wait for keypress - Harness_Debug_PrintStack(); - if (!_unittest_do_not_exit) { exit(1); } @@ -494,37 +492,13 @@ void PDBuildAppPath(char* pThe_path) { void PDForEveryFile(char* pThe_path, void (*pAction_routine)(char*)) { char find_path[256]; char found_path[256]; - // find_t the_find_buffer; - DIR* d; - struct dirent* entry; - - d = opendir(pThe_path); - if (d) { - while ((entry = readdir(d)) != NULL) { - // only files, and only files that don't start with '.' - if (entry->d_type == DT_REG && entry->d_name[0] != '.') { - PathCat(found_path, pThe_path, entry->d_name); - pAction_routine(found_path); - } - } - closedir(d); - } - // d = opendir(pThe_path); - // if (d) { - // while ((entry = readdir(d)) != NULL) { - // // only files, and only files that don't start with '.' - // #ifdef _WIN32 - // if ((GetFileAttributesA(pThe_path) & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) { - // #else - // if (entry->d_type == DT_REG && entry->d_name[0] != '.') { - // #endif - // PathCat(found_path, pThe_path, entry->d_name); - // pAction_routine(found_path); - // } - // } - // closedir(d); - // } + char* found = OS_GetFirstFileInDirectory(pThe_path); + while (found != NULL) { + PathCat(found_path, pThe_path, found); + pAction_routine(found_path); + found = OS_GetNextFileInDirectory(); + } } // IDA: void __usercall PDSetPalette(br_pixelmap *pThe_palette@) @@ -582,7 +556,6 @@ void PDGetMousePosition(int* pX_coord, int* pY_coord) { // IDA: int __cdecl PDGetTotalTime() int PDGetTotalTime() { - return OS_GetTime(); } diff --git a/src/harness/CMakeLists.txt b/src/harness/CMakeLists.txt index 66b44f04..0cbb61c9 100644 --- a/src/harness/CMakeLists.txt +++ b/src/harness/CMakeLists.txt @@ -13,7 +13,7 @@ target_include_directories(harness include ) -target_link_libraries(harness PRIVATE miniposix brender SDL2::SDL2 glad s3 cglm_headers) +target_link_libraries(harness PRIVATE brender SDL2::SDL2 glad s3 cglm_headers) if(WIN32) target_link_libraries(harness PRIVATE dbghelp) diff --git a/src/harness/harness.c b/src/harness/harness.c index 0379cffe..a865015a 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -100,15 +100,12 @@ void Harness_Init(int* argc, char* argv[]) { } } +// used by unit tests void Harness_ForceNullRenderer() { force_nullrenderer = 1; renderer = &null_renderer; } -void Harness_Debug_PrintStack() { - OS_PrintStacktrace(); -} - int Harness_ProcessCommandLine(int* argc, char* argv[]) { for (int i = 1; i < *argc; i++) { int handled = 0; diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h new file mode 100644 index 00000000..97bc8a4c --- /dev/null +++ b/src/harness/include/harness/os.h @@ -0,0 +1,26 @@ +#ifndef HARNESS_PLATFORM_H +#define HARNESS_PLATFORM_H + +#include + +// Required + +// Required: return timestamp in milliseconds. +uint32_t OS_GetTime(void); + +// Required: begin a directory iteration and return name of first file +char* OS_GetFirstFileInDirectory(char* path); + +// Required: continue directory iteration. If no more files, return NULL +char* OS_GetNextFileInDirectory(void); + +// Required: sleep for specified milliseconds +void OS_Sleep(int ms); + +// Optional: return true if a debugger is detected +int OS_IsDebuggerPresent(void); + +// Optional: install a handler to print stack trace during a crash +void OS_InstallSignalHandler(char* program_name); + +#endif diff --git a/src/harness/include/harness/trace.h b/src/harness/include/harness/trace.h index e8ef26aa..45a1a588 100644 --- a/src/harness/include/harness/trace.h +++ b/src/harness/include/harness/trace.h @@ -8,8 +8,6 @@ extern int harness_debug_level; extern int OS_IsDebuggerPresent(void); -void Harness_Debug_PrintStack(); - void debug_printf(const char* fmt, const char* fn, const char* fmt2, ...); void debug_print_vector3(const char* fmt, const char* fn, char* msg, br_vector3* v); void debug_print_matrix34(const char* fmt, const char* fn, char* name, br_matrix34* m); diff --git a/src/harness/os/linux.c b/src/harness/os/linux.c index 8d76c434..97feeb17 100644 --- a/src/harness/os/linux.c +++ b/src/harness/os/linux.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -24,6 +25,7 @@ static char _program_name[1024]; #define MAX_STACK_FRAMES 64 static void* stack_traces[MAX_STACK_FRAMES]; #define TRACER_PID_STRING "TracerPid:" +DIR* directory_iterator; uint32_t OS_GetTime() { struct timespec spec; @@ -38,6 +40,30 @@ void OS_Sleep(int delay_ms) { nanosleep(&ts, &ts); } +char* OS_GetFirstFileInDirectory(char* path) { + directory_iterator = opendir(path); + if (directory_iterator == NULL) { + return NULL; + } + return OS_GetNextFileInDirectory(); +} + +char* OS_GetNextFileInDirectory(void) { + struct dirent* entry; + + if (directory_iterator == NULL) { + return NULL; + } + while ((entry = readdir(directory_iterator)) != NULL) { + if (entry->d_type == DT_REG) { + return entry->d_name; + } + } + closedir(directory_iterator); + directory_iterator = NULL; + return NULL; +} + int OS_IsDebuggerPresent() { char buf[4096]; int status_fd; @@ -84,6 +110,27 @@ int addr2line(char const* const program_name, void const* const addr) { return system(addr2line_cmd); } +void print_stack_trace() { + int i, trace_size = 0; + char** messages = (char**)NULL; + + fputs("\nStack trace:\n", stderr); + + trace_size = backtrace(stack_traces, MAX_STACK_FRAMES); + messages = backtrace_symbols(stack_traces, trace_size); + + /* skip the first couple stack frames (as they are this function and + our handler) and also skip the last frame as it's (always?) junk. */ + for (i = 3; i < (trace_size - 1); ++i) { + if (addr2line(_program_name, stack_traces[i]) != 0) { + printf(" error determining line # for: %s\n", messages[i]); + } + } + if (messages) { + free(messages); + } +} + void signal_handler(int sig, siginfo_t* siginfo, void* context) { (void)context; fputs("\n******************\n", stderr); @@ -167,7 +214,7 @@ void signal_handler(int sig, siginfo_t* siginfo, void* context) { break; } fputs("******************\n", stderr); - OS_PrintStacktrace(); + print_stack_trace(); exit(1); } @@ -232,24 +279,3 @@ void OS_InstallSignalHandler(char* program_name) { } } } - -void OS_PrintStacktrace() { - int i, trace_size = 0; - char** messages = (char**)NULL; - - fputs("\nStack trace:\n", stderr); - - trace_size = backtrace(stack_traces, MAX_STACK_FRAMES); - messages = backtrace_symbols(stack_traces, trace_size); - - /* skip the first couple stack frames (as they are this function and - our handler) and also skip the last frame as it's (always?) junk. */ - for (i = 3; i < (trace_size - 1); ++i) { - if (addr2line(_program_name, stack_traces[i]) != 0) { - printf(" error determining line # for: %s\n", messages[i]); - } - } - if (messages) { - free(messages); - } -} \ No newline at end of file diff --git a/src/harness/os/macos.c b/src/harness/os/macos.c index 4f558149..83d19567 100644 --- a/src/harness/os/macos.c +++ b/src/harness/os/macos.c @@ -1,6 +1,8 @@ // Based on https://gist.github.com/jvranish/4441299 +#include "harness/os.h" #include +#include #include #include #include @@ -20,6 +22,7 @@ static int stack_nbr = 0; static char _program_name[1024]; #define MAX_STACK_FRAMES 64 static void* stack_traces[MAX_STACK_FRAMES]; +DIR* directory_iterator; uint32_t OS_GetTime() { struct timespec spec; @@ -34,6 +37,30 @@ void OS_Sleep(int delay_ms) { nanosleep(&ts, &ts); } +char* OS_GetFirstFileInDirectory(char* path) { + directory_iterator = opendir(path); + if (directory_iterator == NULL) { + return NULL; + } + return OS_GetNextFileInDirectory(); +} + +char* OS_GetNextFileInDirectory(void) { + struct dirent* entry; + + if (directory_iterator == NULL) { + return NULL; + } + while ((entry = readdir(directory_iterator)) != NULL) { + if (entry->d_type == DT_REG) { + return entry->d_name; + } + } + closedir(directory_iterator); + directory_iterator = NULL; + return NULL; +} + // https://developer.apple.com/library/archive/qa/qa1361/_index.html // FIXME: // Important: Because the definition of the kinfo_proc structure (in ) is conditionalized by __APPLE_API_UNSTABLE, @@ -83,7 +110,7 @@ int addr2line(char const* const program_name, void const* const addr) { return system(addr2line_cmd); } -void OS_PrintStacktrace() { +void print_stack_trace() { int i, trace_size = 0; char** messages = (char**)NULL; @@ -187,7 +214,7 @@ void signal_handler(int sig, siginfo_t* siginfo, void* context) { break; } fputs("******************\n", stderr); - OS_PrintStacktrace(); + print_stack_trace(); exit(1); } diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 8c266fd8..0c0f191c 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -24,6 +24,8 @@ static char _program_name[1024]; LARGE_INTEGER qpc_start_time, EndingTime, ElapsedMicroseconds; LARGE_INTEGER qpc_ticks_per_sec; +HANDLE directory_handle = NULL; + void OS_Sleep(int delay_ms) { Sleep(delay_ms); } @@ -39,6 +41,33 @@ uint32_t OS_GetTime() { return (((now.QuadPart - qpc_start_time.QuadPart) * 1000) / qpc_ticks_per_sec.QuadPart); } +char* OS_GetFirstFileInDirectory(char* path) { + + WIN32_FIND_DATA fdFile; + HANDLE hFind = NULL; + directory_handle = FindFirstFile(sPath, &fdFile)); + if (directory_handle == INVALID_HANDLE_VALUE) { + return NULL; + } + return fdFile.cFileName; +} + +// Required: continue directory iteration. If no more files, return NULL +char* OS_GetNextFileInDirectory(void) { + WIN32_FIND_DATA fdFile; + if (directory_handle == NULL) { + return NULL; + } + + while (FindNextFile(directory_handle, &fdFile)) { + if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) { + return fdFile.cFileName; + } + } + FindClose(directory_handle); + return NULL; +} + int OS_IsDebuggerPresent() { return IsDebuggerPresent(); } @@ -52,16 +81,7 @@ int addr2line(char const* const program_name, void const* const addr) { return system(addr2line_cmd); } -void OS_PrintStacktrace() { - fprintf(stderr, "cannot print stack without context\n"); - return; -} - -void print_stacktrace_internal(CONTEXT* context) { - if (!context) { - fprintf(stderr, "cannot print stack without context\n"); - return; - } +void print_stacktrace(CONTEXT* context) { SymInitialize(GetCurrentProcess(), 0, true); @@ -160,7 +180,7 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) { /* If this is a stack overflow then we can't walk the stack, so just show where the error happened */ if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) { - print_stacktrace_internal(ExceptionInfo->ContextRecord); + print_stacktrace(ExceptionInfo->ContextRecord); } else { addr2line(_program_name, (void*)ExceptionInfo->ContextRecord->Eip); } From 100e8b8bb37a18d80a7d2a4aee14e4c3bc29db8d Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Fri, 18 Mar 2022 20:57:22 +1300 Subject: [PATCH 09/28] removes miniposix 2 --- src/DETHRACE/pc-dos/dossys.c | 1 - src/harness/harness.c | 2 +- src/harness/include/harness/os.h | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/DETHRACE/pc-dos/dossys.c b/src/DETHRACE/pc-dos/dossys.c index f6ce0cc5..84fc1ce3 100644 --- a/src/DETHRACE/pc-dos/dossys.c +++ b/src/DETHRACE/pc-dos/dossys.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/src/harness/harness.c b/src/harness/harness.c index a865015a..b6c2c14f 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h index 97bc8a4c..f1c5a69f 100644 --- a/src/harness/include/harness/os.h +++ b/src/harness/include/harness/os.h @@ -1,7 +1,7 @@ #ifndef HARNESS_PLATFORM_H #define HARNESS_PLATFORM_H -#include +#include // Required From 7ff629fc28ea48508eb0a5daf621119da2872310 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Fri, 18 Mar 2022 20:59:58 +1300 Subject: [PATCH 10/28] removes miniposix 3 --- src/harness/os/linux.c | 1 + src/harness/os/windows.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/harness/os/linux.c b/src/harness/os/linux.c index 97feeb17..2fa7a450 100644 --- a/src/harness/os/linux.c +++ b/src/harness/os/linux.c @@ -1,5 +1,6 @@ // Based on https://gist.github.com/jvranish/4441299 +#include "harness/os.h" #include #include #include diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 0c0f191c..60c85e40 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -1,5 +1,6 @@ // Based on https://gist.github.com/jvranish/4441299 +#include "harness/os.h" #include #include #include From 4affe0e5e0d614e151e17b427564cdcfefd47791 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Fri, 18 Mar 2022 21:03:48 +1300 Subject: [PATCH 11/28] removes miniposix 4 --- src/harness/include/harness/trace.h | 1 - src/harness/os/windows.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/harness/include/harness/trace.h b/src/harness/include/harness/trace.h index 45a1a588..d29003ce 100644 --- a/src/harness/include/harness/trace.h +++ b/src/harness/include/harness/trace.h @@ -3,7 +3,6 @@ #include "brender/br_types.h" #include -#include extern int harness_debug_level; extern int OS_IsDebuggerPresent(void); diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 60c85e40..e960decb 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include From 10793cfad1d15b91b7014033819b4ea1a7834af4 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sat, 19 Mar 2022 20:13:28 +1300 Subject: [PATCH 12/28] fix tests --- src/DETHRACE/common/errors.c | 1 + test/DETHRACE/test_errors.c | 2 +- test/main.c | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/DETHRACE/common/errors.c b/src/DETHRACE/common/errors.c index 79b19e3a..88fbed3e 100644 --- a/src/DETHRACE/common/errors.c +++ b/src/DETHRACE/common/errors.c @@ -154,6 +154,7 @@ void FatalError(int pStr_index, ...) { sub_pt = temp_str; while (1) { + sub_pt = strchr(the_str, '%'); if (!sub_pt) { break; diff --git a/test/DETHRACE/test_errors.c b/test/DETHRACE/test_errors.c index 7e36b54e..01866c45 100644 --- a/test/DETHRACE/test_errors.c +++ b/test/DETHRACE/test_errors.c @@ -5,7 +5,7 @@ #include void test_errors_FatalError() { - FatalError(0x6c, "test_errors", "FATAL"); + FatalError(107, "test_errors", "FATAL"); TEST_ASSERT_EQUAL_STRING("Can't open 'test_errors'", _unittest_last_fatal_error); } diff --git a/test/main.c b/test/main.c index f415a9fa..27777023 100644 --- a/test/main.c +++ b/test/main.c @@ -15,6 +15,7 @@ #include "CORE/PIXELMAP/pixelmap.h" #include "CORE/V1DB/actsupt.h" #include "CORE/V1DB/dbsetup.h" +#include "common/errors.h" #include "common/newgame.h" #include "common/utility.h" @@ -167,6 +168,8 @@ void setup_global_vars(int argc, char* argv[]) { strcpy(gBasic_car_names[0], "BLKEAGLE.TXT"); + OpenDiagnostics(); + setup_temp_folder(); printf("INFO: temp folder is \"%s\"\n", temp_folder); From be856d07f0306c679bd239d347f2eefb6f5b8ab3 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sat, 19 Mar 2022 20:26:31 +1300 Subject: [PATCH 13/28] fix windows build --- src/DETHRACE/pc-dos/dossys.c | 1 - src/harness/harness_trace.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/DETHRACE/pc-dos/dossys.c b/src/DETHRACE/pc-dos/dossys.c index 84fc1ce3..9c6dd4b4 100644 --- a/src/DETHRACE/pc-dos/dossys.c +++ b/src/DETHRACE/pc-dos/dossys.c @@ -15,7 +15,6 @@ #include "sound.h" #include "utility.h" #include "watcom_functions.h" -#include #include #include #include diff --git a/src/harness/harness_trace.c b/src/harness/harness_trace.c index d12271b1..fe36bad0 100644 --- a/src/harness/harness_trace.c +++ b/src/harness/harness_trace.c @@ -1,6 +1,5 @@ #include "harness/trace.h" -#include #include #include #include From d6476323783060a5abfde14740479130ec9cccf9 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sun, 20 Mar 2022 22:19:07 +1300 Subject: [PATCH 14/28] remove unistd refs --- src/BRSRC13/CORE/FW/brlists.c | 2 +- src/DETHRACE/common/cutscene.c | 1 - src/DETHRACE/common/flicplay.c | 15 +++++++-------- src/DETHRACE/common/graphics.c | 9 ++++----- src/DETHRACE/common/utility.c | 3 +-- src/DETHRACE/main.c | 1 - src/DETHRACE/pc-dos/dossys.c | 1 - src/harness/harness.c | 14 ++++++++++---- src/harness/include/harness/os.h | 2 ++ src/harness/os/macos.c | 4 ++++ test/DETHRACE/test_controls.c | 1 - test/DETHRACE/test_dossys.c | 1 - test/DETHRACE/test_input.c | 1 - test/DETHRACE/test_loading.c | 1 - test/DETHRACE/test_powerup.c | 1 - test/main.c | 1 - 16 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/BRSRC13/CORE/FW/brlists.c b/src/BRSRC13/CORE/FW/brlists.c index ffae26bf..8c2c240c 100644 --- a/src/BRSRC13/CORE/FW/brlists.c +++ b/src/BRSRC13/CORE/FW/brlists.c @@ -2,7 +2,7 @@ #include "harness/trace.h" #include #include -#include + // IDA: void __cdecl BrNewList(br_list *list) void BrNewList(br_list* list) { diff --git a/src/DETHRACE/common/cutscene.c b/src/DETHRACE/common/cutscene.c index 0a44cdc6..3b21598f 100644 --- a/src/DETHRACE/common/cutscene.c +++ b/src/DETHRACE/common/cutscene.c @@ -14,7 +14,6 @@ #include "utility.h" #include #include -#include tS32 gLast_demo_end_anim; diff --git a/src/DETHRACE/common/flicplay.c b/src/DETHRACE/common/flicplay.c index d259b678..3b9fcf02 100644 --- a/src/DETHRACE/common/flicplay.c +++ b/src/DETHRACE/common/flicplay.c @@ -12,7 +12,6 @@ #include "sound.h" #include "utility.h" #include -#include int gPalette_allocate_count; int gPalette_fuck_prevention; @@ -694,7 +693,7 @@ int StartFlic(char* pFile_name, int pIndex, tFlic_descriptor_ptr pFlic_info, tU3 } else { pFlic_info->f = NULL; pFlic_info->data = (char*)pData_ptr; - //TOOD: remove this - we added this line because of the padding hack in PlayNextFlicFrame2 + // TOOD: remove this - we added this line because of the padding hack in PlayNextFlicFrame2 pFlic_info->data_start = (char*)pData_ptr; } pFlic_info->bytes_remaining = MemReadU32(&pFlic_info->data); @@ -746,7 +745,7 @@ int StartFlic(char* pFile_name, int pIndex, tFlic_descriptor_ptr pFlic_info, tU3 if (pDest_pixelmap) { pFlic_info->first_pixel = (tU8*)pDest_pixelmap->pixels + pDest_pixelmap->row_bytes * pFlic_info->y_offset + pFlic_info->x_offset; } - //LOG_DEBUG("first pixel %p %p", pFlic_info->first_pixel, pDest_pixelmap->pixels); + // LOG_DEBUG("first pixel %p %p", pFlic_info->first_pixel, pDest_pixelmap->pixels); pFlic_info->the_pixelmap = pDest_pixelmap; return 0; } @@ -809,7 +808,7 @@ void DoColourMap(tFlic_descriptor_ptr pFlic_info, tU32 chunk_length) { red = MemReadU8(&pFlic_info->data); blue = MemReadU8(&pFlic_info->data); green = MemReadU8(&pFlic_info->data); - //argb + // argb palette_pixels[0] = green * 4; palette_pixels[1] = blue * 4; palette_pixels[2] = red * 4; @@ -887,13 +886,13 @@ void DoColour256(tFlic_descriptor* pFlic_info, tU32 chunk_length) { red = MemReadU8(&pFlic_info->data); blue = MemReadU8(&pFlic_info->data); green = MemReadU8(&pFlic_info->data); - //argb + // argb palette_pixels[0] = green; palette_pixels[1] = blue; palette_pixels[2] = red; palette_pixels[3] = 0; palette_pixels += 4; - //LOG_DEBUG("color %d", current_colour); + // LOG_DEBUG("color %d", current_colour); } if (!gPalette_fuck_prevention) { DRSetPaletteEntries(gPalette, current_colour, change_count); @@ -1172,7 +1171,7 @@ int PlayNextFlicFrame2(tFlic_descriptor* pFlic_info, int pPanel_flic) { int data_knocked_off; int read_amount; - //LOG_DEBUG("%d (%p), frames left: %d offset: %d", pFlic_info->the_index, pFlic_info, pFlic_info->frames_left, (pFlic_info->data - pFlic_info->data_start) + 4); + // LOG_DEBUG("%d (%p), frames left: %d offset: %d", pFlic_info->the_index, pFlic_info, pFlic_info->frames_left, (pFlic_info->data - pFlic_info->data_start) + 4); PossibleService(); frame_length = MemReadU32(&pFlic_info->data); magic_bytes = MemReadU16(&pFlic_info->data); @@ -1229,7 +1228,7 @@ int PlayNextFlicFrame2(tFlic_descriptor* pFlic_info, int pPanel_flic) { MemSkipBytes(&pFlic_info->data, chunk_length - 6); break; } - //TODO: something like // p &= 0xfffffffffffffffe; + // TODO: something like // p &= 0xfffffffffffffffe; int a = (pFlic_info->data - pFlic_info->data_start); if (a % 2 == 1) { pFlic_info->data++; diff --git a/src/DETHRACE/common/graphics.c b/src/DETHRACE/common/graphics.c index d9038727..7bd76cff 100644 --- a/src/DETHRACE/common/graphics.c +++ b/src/DETHRACE/common/graphics.c @@ -32,7 +32,6 @@ #include "utility.h" #include "world.h" #include -#include #include @@ -2389,7 +2388,7 @@ void DropInImageFromTop(br_pixelmap* pImage, int pLeft, int pTop, int pTop_clip, tS32 the_time; int drop_distance; LOG_TRACE("(%p, %d, %d, %d, %d)", pImage, pLeft, pTop, pTop_clip, pBottom_clip); - + start_time = PDGetTotalTime(); drop_distance = pImage->height - pTop_clip + pTop; while (1) { @@ -2413,7 +2412,7 @@ void DropOutImageThruBottom(br_pixelmap* pImage, int pLeft, int pTop, int pTop_c tS32 the_time; int drop_distance; LOG_TRACE("(%p, %d, %d, %d, %d)", pImage, pLeft, pTop, pTop_clip, pBottom_clip); - + start_time = PDGetTotalTime(); drop_distance = pBottom_clip - pTop; while (1) { @@ -2437,7 +2436,7 @@ void DropInImageFromBottom(br_pixelmap* pImage, int pLeft, int pTop, int pTop_cl tS32 the_time; int drop_distance; LOG_TRACE("(%p, %d, %d, %d, %d)", pImage, pLeft, pTop, pTop_clip, pBottom_clip); - + start_time = PDGetTotalTime(); drop_distance = pBottom_clip - pTop; while (1) { @@ -2461,7 +2460,7 @@ void DropOutImageThruTop(br_pixelmap* pImage, int pLeft, int pTop, int pTop_clip tS32 the_time; int drop_distance; LOG_TRACE("(%p, %d, %d, %d, %d)", pImage, pLeft, pTop, pTop_clip, pBottom_clip); - + start_time = PDGetTotalTime(); drop_distance = pImage->height - pTop_clip + pTop; while (1) { diff --git a/src/DETHRACE/common/utility.c b/src/DETHRACE/common/utility.c index 49750b9e..1309c3f7 100644 --- a/src/DETHRACE/common/utility.c +++ b/src/DETHRACE/common/utility.c @@ -21,7 +21,6 @@ #include #include #include -#include // Added >> #define MIN_SERVICE_INTERVAL 200 @@ -1312,7 +1311,7 @@ void EncodeFile(char* pThe_path) { fclose(d); PDFileUnlock(pThe_path); - unlink(pThe_path); + remove(pThe_path); rename(new_file, pThe_path); } diff --git a/src/DETHRACE/main.c b/src/DETHRACE/main.c index 98961bfd..0366ff68 100644 --- a/src/DETHRACE/main.c +++ b/src/DETHRACE/main.c @@ -1,7 +1,6 @@ #include "harness/hooks.h" #include "pd/sys.h" #include -#include extern int original_main(int pArgc, char* pArgv[]); diff --git a/src/DETHRACE/pc-dos/dossys.c b/src/DETHRACE/pc-dos/dossys.c index 9c6dd4b4..4d14f899 100644 --- a/src/DETHRACE/pc-dos/dossys.c +++ b/src/DETHRACE/pc-dos/dossys.c @@ -21,7 +21,6 @@ #include #include #include -#include #ifdef __DOS__ #define GFX_INIT_STRING_32X20X8 "MCGA,W:320,H:200,B:8" diff --git a/src/harness/harness.c b/src/harness/harness.c index b6c2c14f..7b109940 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -10,7 +10,6 @@ #include #include #include -#include tRenderer* renderer; br_pixelmap* palette; @@ -38,12 +37,16 @@ tHarness_game_config harness_game_config; int Harness_ProcessCommandLine(int* argc, char* argv[]); void Harness_DetectGameMode() { - if (access("DATA/RACES/CITY01.TXT", F_OK) == -1 && access("DATA/RACES/CITYA1.TXT", F_OK) == -1) { + FILE* city01 = fopen("DATA/RACES/CITY01.TXT", "r"); + FILE* citya1 = fopen("DATA/RACES/CITYA1.TXT", "r"); + FILE* splintro = fopen("DATA/CUTSCENE/SPLINTRO.SMK", "r"); + + if (city01 == NULL && citya1 == NULL) { harness_game_info.defines.INTRO_SMK_FILE = ""; harness_game_info.defines.GERMAN_LOADSCRN = "COWLESS.PIX"; harness_game_info.mode = eGame_carmageddon_demo; LOG_INFO("\"%s\"", "Carmageddon demo"); - } else if (access("DATA/CUTSCENE/SPLINTRO.SMK", F_OK) != -1) { + } else if (splintro != NULL) { harness_game_info.defines.INTRO_SMK_FILE = "SPLINTRO.SMK"; harness_game_info.defines.GERMAN_LOADSCRN = "LOADSCRN.PIX"; harness_game_info.mode = eGame_splatpack; @@ -54,6 +57,9 @@ void Harness_DetectGameMode() { harness_game_info.mode = eGame_carmageddon; LOG_INFO("\"%s\"", "Carmageddon"); } + fclose(city01); + fclose(citya1); + fclose(splintro); } void Harness_Init(int* argc, char* argv[]) { @@ -90,7 +96,7 @@ void Harness_Init(int* argc, char* argv[]) { LOG_INFO("DETHRACE_ROOT_DIR is not set, assuming '.'"); } else { printf("DETHRACE_ROOT_DIR: %s\n", root_dir); - result = chdir(root_dir); + result = OS_SetCurrentDirectory(root_dir); if (result != 0) { LOG_PANIC("Failed to chdir. Error is %s", strerror(errno)); } diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h index f1c5a69f..fb3c04b4 100644 --- a/src/harness/include/harness/os.h +++ b/src/harness/include/harness/os.h @@ -17,6 +17,8 @@ char* OS_GetNextFileInDirectory(void); // Required: sleep for specified milliseconds void OS_Sleep(int ms); +int OS_SetCurrentDirectory(char* path); + // Optional: return true if a debugger is detected int OS_IsDebuggerPresent(void); diff --git a/src/harness/os/macos.c b/src/harness/os/macos.c index 83d19567..72dacfde 100644 --- a/src/harness/os/macos.c +++ b/src/harness/os/macos.c @@ -37,6 +37,10 @@ void OS_Sleep(int delay_ms) { nanosleep(&ts, &ts); } +int OS_SetCurrentDirectory(char* path) { + return chdir(path); +} + char* OS_GetFirstFileInDirectory(char* path) { directory_iterator = opendir(path); if (directory_iterator == NULL) { diff --git a/test/DETHRACE/test_controls.c b/test/DETHRACE/test_controls.c index 8c9d2027..4e7ffd5a 100644 --- a/test/DETHRACE/test_controls.c +++ b/test/DETHRACE/test_controls.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "tests.h" diff --git a/test/DETHRACE/test_dossys.c b/test/DETHRACE/test_dossys.c index 251f3862..35109274 100644 --- a/test/DETHRACE/test_dossys.c +++ b/test/DETHRACE/test_dossys.c @@ -1,7 +1,6 @@ #include "tests.h" #include -#include #include "common/globvars.h" #include "pd/sys.h" diff --git a/test/DETHRACE/test_input.c b/test/DETHRACE/test_input.c index ead31982..85525d81 100644 --- a/test/DETHRACE/test_input.c +++ b/test/DETHRACE/test_input.c @@ -3,7 +3,6 @@ #include "common/globvars.h" #include "common/input.h" #include -#include void test_input_KevKeyService() { int i; diff --git a/test/DETHRACE/test_loading.c b/test/DETHRACE/test_loading.c index b0d37a17..11c34805 100644 --- a/test/DETHRACE/test_loading.c +++ b/test/DETHRACE/test_loading.c @@ -1,7 +1,6 @@ #include "tests.h" #include -#include #include "CORE/PIXELMAP/pixelmap.h" #include "common/globvars.h" diff --git a/test/DETHRACE/test_powerup.c b/test/DETHRACE/test_powerup.c index 7bab01a6..e9461b4f 100644 --- a/test/DETHRACE/test_powerup.c +++ b/test/DETHRACE/test_powerup.c @@ -1,7 +1,6 @@ #include "tests.h" #include -#include #include "common/globvars.h" #include "common/powerup.h" diff --git a/test/main.c b/test/main.c index 27777023..a55bc1c9 100644 --- a/test/main.c +++ b/test/main.c @@ -6,7 +6,6 @@ #include #include #include -#include #define UNITY_USE_COMMAND_LINE_ARGS 1 From 4dd0608d4b39e5edb75a1fab8aa9458f39c97941 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sun, 20 Mar 2022 22:22:45 +1300 Subject: [PATCH 15/28] fix again --- src/harness/os/windows.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index e960decb..2622c21a 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -1,5 +1,8 @@ // Based on https://gist.github.com/jvranish/4441299 +#include +#include + #include "harness/os.h" #include #include @@ -11,9 +14,6 @@ #include #include -#include -#include - #ifdef _WIN64 #define Esp Rsp #define Eip Rip From aa1c48af91a839cd6651c99f7e729b9df8fb7f96 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sun, 20 Mar 2022 22:40:46 +1300 Subject: [PATCH 16/28] fix again --- src/harness/harness.c | 2 +- src/harness/include/harness/os.h | 10 ++++++++-- src/harness/os/macos.c | 4 ---- src/harness/os/windows.c | 1 + test/main.c | 2 ++ 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/harness/harness.c b/src/harness/harness.c index 7b109940..7b646330 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -96,7 +96,7 @@ void Harness_Init(int* argc, char* argv[]) { LOG_INFO("DETHRACE_ROOT_DIR is not set, assuming '.'"); } else { printf("DETHRACE_ROOT_DIR: %s\n", root_dir); - result = OS_SetCurrentDirectory(root_dir); + result = chdir(root_dir); if (result != 0) { LOG_PANIC("Failed to chdir. Error is %s", strerror(errno)); } diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h index fb3c04b4..920a6a29 100644 --- a/src/harness/include/harness/os.h +++ b/src/harness/include/harness/os.h @@ -3,6 +3,14 @@ #include +#ifdef _WIN32 +#include +#define getcwd _getcwd +#define chdir _chdir +#else +#include +#endif + // Required // Required: return timestamp in milliseconds. @@ -17,8 +25,6 @@ char* OS_GetNextFileInDirectory(void); // Required: sleep for specified milliseconds void OS_Sleep(int ms); -int OS_SetCurrentDirectory(char* path); - // Optional: return true if a debugger is detected int OS_IsDebuggerPresent(void); diff --git a/src/harness/os/macos.c b/src/harness/os/macos.c index 72dacfde..83d19567 100644 --- a/src/harness/os/macos.c +++ b/src/harness/os/macos.c @@ -37,10 +37,6 @@ void OS_Sleep(int delay_ms) { nanosleep(&ts, &ts); } -int OS_SetCurrentDirectory(char* path) { - return chdir(path); -} - char* OS_GetFirstFileInDirectory(char* path) { directory_iterator = opendir(path); if (directory_iterator == NULL) { diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 2622c21a..11d49145 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -5,6 +5,7 @@ #include "harness/os.h" #include +#include /* _chdir() */ #include #include #include diff --git a/test/main.c b/test/main.c index a55bc1c9..7599b952 100644 --- a/test/main.c +++ b/test/main.c @@ -1,4 +1,5 @@ #include "harness/hooks.h" +#include "harness/os.h" #include "tests.h" #include #include @@ -23,6 +24,7 @@ #include "common/grafdata.h" #include "harness.h" #include "harness/config.h" +#include "harness/os.h" #define debug(format_, ...) fprintf(stderr, format_, __VA_ARGS__) From f666d3dfe0cfb60ec4d7892aac871e33f92c3ea6 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sun, 20 Mar 2022 22:43:37 +1300 Subject: [PATCH 17/28] fix again --- src/harness/os/windows.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 11d49145..6077cefc 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -1,11 +1,12 @@ // Based on https://gist.github.com/jvranish/4441299 -#include +// this has to be first #include +#include + #include "harness/os.h" #include -#include /* _chdir() */ #include #include #include From 44f22a6bd262215a8e6be9feacec042fc2f7f72f Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sun, 20 Mar 2022 22:48:51 +1300 Subject: [PATCH 18/28] fix again --- src/harness/os/windows.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 6077cefc..6452d15d 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -22,6 +22,7 @@ #define Ebp Rbp #endif +static int stack_nbr = 0; static char _program_name[1024]; LARGE_INTEGER qpc_start_time, EndingTime, ElapsedMicroseconds; LARGE_INTEGER qpc_ticks_per_sec; @@ -34,7 +35,7 @@ void OS_Sleep(int delay_ms) { uint32_t OS_GetTime() { LARGE_INTEGER now; - if (qpc_start_time == 0) { + if (qpc_start_time.QuadPart == 0) { QueryPerformanceFrequency(&qpc_ticks_per_sec); QueryPerformanceCounter(&qpc_start_time); } @@ -47,7 +48,7 @@ char* OS_GetFirstFileInDirectory(char* path) { WIN32_FIND_DATA fdFile; HANDLE hFind = NULL; - directory_handle = FindFirstFile(sPath, &fdFile)); + directory_handle = FindFirstFile(path, &fdFile)); if (directory_handle == INVALID_HANDLE_VALUE) { return NULL; } From 71077b46bb99070d166c508dd40215d6f6c9e184 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Sun, 20 Mar 2022 22:54:53 +1300 Subject: [PATCH 19/28] fix again --- src/harness/os/windows.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 6452d15d..5499edf0 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -46,25 +46,25 @@ uint32_t OS_GetTime() { char* OS_GetFirstFileInDirectory(char* path) { - WIN32_FIND_DATA fdFile; + WIN32_FIND_DATA find_data; HANDLE hFind = NULL; - directory_handle = FindFirstFile(path, &fdFile)); + directory_handle = FindFirstFile(path, &find_data); if (directory_handle == INVALID_HANDLE_VALUE) { return NULL; } - return fdFile.cFileName; + return find_data.cFileName; } // Required: continue directory iteration. If no more files, return NULL char* OS_GetNextFileInDirectory(void) { - WIN32_FIND_DATA fdFile; + WIN32_FIND_DATA find_data; if (directory_handle == NULL) { return NULL; } - while (FindNextFile(directory_handle, &fdFile)) { - if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) { - return fdFile.cFileName; + while (FindNextFile(directory_handle, &find_data)) { + if (find_data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) { + return find_data.cFileName; } } FindClose(directory_handle); From 0fa0a0eb4db5b4f1aa7ed52753521248df965f52 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 21 Mar 2022 06:41:00 +1300 Subject: [PATCH 20/28] removes watcom functions --- src/DETHRACE/CMakeLists.txt | 2 -- src/DETHRACE/main.c | 6 +++--- src/DETHRACE/pc-dos/dossys.c | 6 +++--- src/harness/include/harness/os.h | 17 ++++++++++++++++- src/harness/os/linux.c | 5 +++++ src/harness/os/macos.c | 5 +++++ src/harness/os/windows.c | 4 ++++ 7 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/DETHRACE/CMakeLists.txt b/src/DETHRACE/CMakeLists.txt index 653a44b4..47209999 100644 --- a/src/DETHRACE/CMakeLists.txt +++ b/src/DETHRACE/CMakeLists.txt @@ -154,8 +154,6 @@ target_sources(dethrace_obj PRIVATE pd/net.h pc-dos/dossys.c pd/sys.h - watcom_functions.c - watcom_functions.h ) # Create our main game binary. diff --git a/src/DETHRACE/main.c b/src/DETHRACE/main.c index 0366ff68..836963e9 100644 --- a/src/DETHRACE/main.c +++ b/src/DETHRACE/main.c @@ -9,15 +9,15 @@ int main(int argc, char* argv[]) { /* Attach to the console that started us if any */ if (AttachConsole(ATTACH_PARENT_PROCESS)) { /* We attached successfully, lets redirect IO to the consoles handles if not already redirected */ - if (_fileno(stdout) == -2 || _get_osfhandle(fileno(stdout)) == -2) { + if (_fileno(stdout) == -2 || _get_osfhandle(_fileno(stdout)) == -2) { freopen("CONOUT$", "w", stdout); } - if (_fileno(stderr) == -2 || _get_osfhandle(fileno(stderr)) == -2) { + if (_fileno(stderr) == -2 || _get_osfhandle(_fileno(stderr)) == -2) { freopen("CONOUT$", "w", stderr); } - if (_fileno(stdin) == -2 || _get_osfhandle(fileno(stdin)) == -2) { + if (_fileno(stdin) == -2 || _get_osfhandle(_fileno(stdin)) == -2) { freopen("CONIN$", "r", stdin); } } diff --git a/src/DETHRACE/pc-dos/dossys.c b/src/DETHRACE/pc-dos/dossys.c index 4d14f899..a1e0a375 100644 --- a/src/DETHRACE/pc-dos/dossys.c +++ b/src/DETHRACE/pc-dos/dossys.c @@ -14,7 +14,6 @@ #include "pd/sys.h" #include "sound.h" #include "utility.h" -#include "watcom_functions.h" #include #include #include @@ -596,9 +595,10 @@ void PDDisposeActionReplayBuffer(char* pBuffer) { // IDA: void __usercall Usage(char *pProgpath@) void Usage(char* pProgpath) { - char basename[9]; + // char basename[9]; + char basename[256]; // fix: changed from 9 to avoid overflow on longer filenames - splitpath(pProgpath, NULL, NULL, basename, NULL); + OS_Basename(pProgpath, basename); fprintf(stderr, "Usage: %s [%s] [%s YonFactor] [%s CarSimplificationLevel] [%s SoundDetailLevel] [%s] [%s] [%s] [%s] [%s] [%s]\nWhere YonFactor is between 0 and 1,\nCarSimplificationLevel is a whole number between 0 and %d,\nand SoundDetailLevel is a whole number.\n", diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h index 920a6a29..81099e52 100644 --- a/src/harness/include/harness/os.h +++ b/src/harness/include/harness/os.h @@ -3,14 +3,27 @@ #include -#ifdef _WIN32 +#if defined(_WIN32) || defined(_WIN64) #include #define getcwd _getcwd #define chdir _chdir +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#define strcasecmp _stricmp +#define strncasecmp _strnicmp #else #include #endif +// #if defined(_WIN32) || defined(_WIN64) +// #define snprintf _snprintf +// #define vsnprintf _vsnprintf +// #define strcasecmp _stricmp +// #define strncasecmp _strnicmp +// #else +// #include +// #endif + // Required // Required: return timestamp in milliseconds. @@ -25,6 +38,8 @@ char* OS_GetNextFileInDirectory(void); // Required: sleep for specified milliseconds void OS_Sleep(int ms); +void OS_Basename(char* path, char* base); + // Optional: return true if a debugger is detected int OS_IsDebuggerPresent(void); diff --git a/src/harness/os/linux.c b/src/harness/os/linux.c index 2fa7a450..80c0e526 100644 --- a/src/harness/os/linux.c +++ b/src/harness/os/linux.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,10 @@ char* OS_GetNextFileInDirectory(void) { return NULL; } +void OS_Basename(char* path, char* base) { + strcpy(base, basename(path)); +} + int OS_IsDebuggerPresent() { char buf[4096]; int status_fd; diff --git a/src/harness/os/macos.c b/src/harness/os/macos.c index 83d19567..b0f13249 100644 --- a/src/harness/os/macos.c +++ b/src/harness/os/macos.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,10 @@ char* OS_GetNextFileInDirectory(void) { return NULL; } +void OS_Basename(char* path, char* base) { + strcpy(base, basename(path)); +} + // https://developer.apple.com/library/archive/qa/qa1361/_index.html // FIXME: // Important: Because the definition of the kinfo_proc structure (in ) is conditionalized by __APPLE_API_UNSTABLE, diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 5499edf0..68b22423 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -71,6 +71,10 @@ char* OS_GetNextFileInDirectory(void) { return NULL; } +void OS_Basename(char* path, char* base) { + _splitpath(path, NULL, NULL, base, NULL); +} + int OS_IsDebuggerPresent() { return IsDebuggerPresent(); } From 90dd2944c1148152eeb02cd2cb1e0016edfd64a6 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 21 Mar 2022 07:01:00 +1300 Subject: [PATCH 21/28] removes watcom functions --- src/harness/include/harness/os.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h index 81099e52..a944ce92 100644 --- a/src/harness/include/harness/os.h +++ b/src/harness/include/harness/os.h @@ -1,5 +1,5 @@ -#ifndef HARNESS_PLATFORM_H -#define HARNESS_PLATFORM_H +#ifndef HARNESS_OS_H +#define HARNESS_OS_H #include @@ -7,8 +7,8 @@ #include #define getcwd _getcwd #define chdir _chdir -#define snprintf _snprintf -#define vsnprintf _vsnprintf +// #define snprintf _snprintf +// #define vsnprintf _vsnprintf #define strcasecmp _stricmp #define strncasecmp _strnicmp #else From df1f999a2d180ae65c10b1024d14794bf601d74c Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 21 Mar 2022 07:05:21 +1300 Subject: [PATCH 22/28] removes watcom functions --- src/harness/include/harness/os.h | 8 ++++++-- src/harness/os/windows.c | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h index a944ce92..e6ebd601 100644 --- a/src/harness/include/harness/os.h +++ b/src/harness/include/harness/os.h @@ -7,10 +7,14 @@ #include #define getcwd _getcwd #define chdir _chdir -// #define snprintf _snprintf -// #define vsnprintf _vsnprintf #define strcasecmp _stricmp #define strncasecmp _strnicmp + +#if _MSC_VER < 1900 +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#endif + #else #include #endif diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 68b22423..368e64fe 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -7,6 +7,7 @@ #include "harness/os.h" #include +#include #include #include #include From 78aa3ed572f34ec38c71b580f8f1c03d309edf18 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 21 Mar 2022 10:28:19 +1300 Subject: [PATCH 23/28] access --- src/harness/harness.c | 11 ++--------- src/harness/include/harness/os.h | 2 ++ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/harness/harness.c b/src/harness/harness.c index 7b646330..6db57fda 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -37,16 +37,12 @@ tHarness_game_config harness_game_config; int Harness_ProcessCommandLine(int* argc, char* argv[]); void Harness_DetectGameMode() { - FILE* city01 = fopen("DATA/RACES/CITY01.TXT", "r"); - FILE* citya1 = fopen("DATA/RACES/CITYA1.TXT", "r"); - FILE* splintro = fopen("DATA/CUTSCENE/SPLINTRO.SMK", "r"); - - if (city01 == NULL && citya1 == NULL) { + if (access("DATA/RACES/CITY01.TXT", F_OK) == -1 && access("DATA/RACES/CITYA1.TXT", F_OK) == -1) { harness_game_info.defines.INTRO_SMK_FILE = ""; harness_game_info.defines.GERMAN_LOADSCRN = "COWLESS.PIX"; harness_game_info.mode = eGame_carmageddon_demo; LOG_INFO("\"%s\"", "Carmageddon demo"); - } else if (splintro != NULL) { + } else if (access("DATA/CUTSCENE/SPLINTRO.SMK", F_OK) != -1) { harness_game_info.defines.INTRO_SMK_FILE = "SPLINTRO.SMK"; harness_game_info.defines.GERMAN_LOADSCRN = "LOADSCRN.PIX"; harness_game_info.mode = eGame_splatpack; @@ -57,9 +53,6 @@ void Harness_DetectGameMode() { harness_game_info.mode = eGame_carmageddon; LOG_INFO("\"%s\"", "Carmageddon"); } - fclose(city01); - fclose(citya1); - fclose(splintro); } void Harness_Init(int* argc, char* argv[]) { diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h index e6ebd601..6dc1acc9 100644 --- a/src/harness/include/harness/os.h +++ b/src/harness/include/harness/os.h @@ -5,8 +5,10 @@ #if defined(_WIN32) || defined(_WIN64) #include +#include #define getcwd _getcwd #define chdir _chdir +#define access _access #define strcasecmp _stricmp #define strncasecmp _strnicmp From 028605fb8f184abdc51e03b4016e86004da4e831 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 21 Mar 2022 10:29:22 +1300 Subject: [PATCH 24/28] access --- src/harness/include/harness/os.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h index 6dc1acc9..dbd1d6f7 100644 --- a/src/harness/include/harness/os.h +++ b/src/harness/include/harness/os.h @@ -9,6 +9,7 @@ #define getcwd _getcwd #define chdir _chdir #define access _access +#define F_OK 0 #define strcasecmp _stricmp #define strncasecmp _strnicmp From 12f647b488b336229e1f828f1b33b80f59b0bb5e Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 21 Mar 2022 11:05:23 +1300 Subject: [PATCH 25/28] windows fixes --- src/DETHRACE/common/cutscene.c | 2 +- src/harness/os/windows.c | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/DETHRACE/common/cutscene.c b/src/DETHRACE/common/cutscene.c index 3b21598f..b06df457 100644 --- a/src/DETHRACE/common/cutscene.c +++ b/src/DETHRACE/common/cutscene.c @@ -130,7 +130,7 @@ void DoOpeningAnimation() { LOG_TRACE("()"); PlaySmackerFile("LOGO.SMK"); PlaySmackerFile(harness_game_info.defines.INTRO_SMK_FILE); - return WaitForNoKeys(); + WaitForNoKeys(); } // IDA: void __cdecl DoNewGameAnimation() diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 368e64fe..098417fb 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -29,6 +29,7 @@ LARGE_INTEGER qpc_start_time, EndingTime, ElapsedMicroseconds; LARGE_INTEGER qpc_ticks_per_sec; HANDLE directory_handle = NULL; +char last_found_file[260]; void OS_Sleep(int delay_ms) { Sleep(delay_ms); @@ -42,18 +43,22 @@ uint32_t OS_GetTime() { } QueryPerformanceCounter(&now); - return (((now.QuadPart - qpc_start_time.QuadPart) * 1000) / qpc_ticks_per_sec.QuadPart); + return (uint32_t)(((now.QuadPart - qpc_start_time.QuadPart) * 1000) / qpc_ticks_per_sec.QuadPart); } char* OS_GetFirstFileInDirectory(char* path) { - + char with_extension[256]; WIN32_FIND_DATA find_data; HANDLE hFind = NULL; - directory_handle = FindFirstFile(path, &find_data); + + strcpy(with_extension, path); + strcat(with_extension, "\\*.???"); + directory_handle = FindFirstFile(with_extension, &find_data); if (directory_handle == INVALID_HANDLE_VALUE) { return NULL; } - return find_data.cFileName; + strcpy(last_found_file, find_data.cFileName); + return last_found_file; } // Required: continue directory iteration. If no more files, return NULL @@ -64,9 +69,8 @@ char* OS_GetNextFileInDirectory(void) { } while (FindNextFile(directory_handle, &find_data)) { - if (find_data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) { - return find_data.cFileName; - } + strcpy(last_found_file, find_data.cFileName); + return last_found_file; } FindClose(directory_handle); return NULL; From 249c8624a34f1a6779d8349f42bcb36f624698b4 Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 21 Mar 2022 11:55:27 +1300 Subject: [PATCH 26/28] fixes shadow rendering memory leak --- CMakeLists.txt | 1 - lib/miniposix/CMakeLists.txt | 50 --- lib/miniposix/dirent/dirent.c | 382 ---------------------- lib/miniposix/dirent/dirent.h | 144 -------- lib/miniposix/fnmatch/fnmatch.c | 311 ------------------ lib/miniposix/fnmatch/fnmatch.h | 55 ---- lib/miniposix/getopt/getopt.c | 361 -------------------- lib/miniposix/getopt/getopt.h | 69 ---- lib/miniposix/libgen/libgen.c | 263 --------------- lib/miniposix/libgen/libgen.h | 27 -- lib/miniposix/strings/strings.c | 25 -- lib/miniposix/strings/strings.h | 105 ------ lib/miniposix/unistd/unistd.h | 265 --------------- src/harness/renderers/gl/gl_renderer.c | 9 +- src/harness/renderers/gl/stored_context.c | 1 + src/harness/renderers/gl/stored_context.h | 2 +- 16 files changed, 7 insertions(+), 2063 deletions(-) delete mode 100644 lib/miniposix/CMakeLists.txt delete mode 100644 lib/miniposix/dirent/dirent.c delete mode 100644 lib/miniposix/dirent/dirent.h delete mode 100644 lib/miniposix/fnmatch/fnmatch.c delete mode 100644 lib/miniposix/fnmatch/fnmatch.h delete mode 100644 lib/miniposix/getopt/getopt.c delete mode 100644 lib/miniposix/getopt/getopt.h delete mode 100644 lib/miniposix/libgen/libgen.c delete mode 100644 lib/miniposix/libgen/libgen.h delete mode 100644 lib/miniposix/strings/strings.c delete mode 100644 lib/miniposix/strings/strings.h delete mode 100644 lib/miniposix/unistd/unistd.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ea7caba5..e4de246a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,6 @@ option(BUILD_TESTS "Build unit tests." OFF) find_package(SDL2 REQUIRED) add_subdirectory(lib/libsmacker) -#add_subdirectory(lib/miniposix) add_subdirectory(lib/glad) add_subdirectory(lib/cglm EXCLUDE_FROM_ALL) diff --git a/lib/miniposix/CMakeLists.txt b/lib/miniposix/CMakeLists.txt deleted file mode 100644 index 44429475..00000000 --- a/lib/miniposix/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -include(CheckIncludeFile) - -# Check if we are missing any posix headers we consider required. -check_include_file(strings.h HAVE_STRINGS_H) -check_include_file(libgen.h HAVE_LIBGEN_H) -check_include_file(dirent.h HAVE_DIRENT_H) -check_include_file(fnmatch.h HAVE_FNMATCH_H) -check_include_file(getopt.h HAVE_GETOPT_H) -check_include_file(unistd.h HAVE_UNISTD_H) - -if(HAVE_STRINGS_H AND HAVE_UNISTD_H AND HAVE_LIBGEN_H AND HAVE_DIRENT_H AND HAVE_FNMATCH_H AND HAVE_GETOPT_H) - add_library(miniposix INTERFACE) -else() - add_library(miniposix STATIC) - - # Only win32 targets should really need miniposix at all, but just to be safe. - if(WIN32) - target_compile_definitions(miniposix PUBLIC _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE WIN32_LEAN_AND_MEAN) - endif() -endif() - -if(NOT HAVE_STRINGS_H) - target_sources(miniposix PRIVATE strings/strings.c strings/strings.h) - target_include_directories(miniposix PUBLIC strings) -endif() - -if(NOT HAVE_LIBGEN_H) - target_sources(miniposix PRIVATE libgen/libgen.c libgen/libgen.h) - target_include_directories(miniposix PUBLIC libgen) -endif() - -if(NOT HAVE_DIRENT_H) - target_sources(miniposix PRIVATE dirent/dirent.c dirent/dirent.h) - target_include_directories(miniposix PUBLIC dirent) -endif() - -if(NOT HAVE_FNMATCH_H) - target_sources(miniposix PRIVATE fnmatch/fnmatch.c fnmatch/fnmatch.h) - target_include_directories(miniposix PUBLIC fnmatch) -endif() - -if(NOT HAVE_GETOPT_H) - target_sources(miniposix PRIVATE getopt/getopt.c getopt/getopt.h) - target_include_directories(miniposix PUBLIC getopt) -endif() - -if(NOT HAVE_UNISTD_H) - target_sources(miniposix PRIVATE unistd/unistd.h) - target_include_directories(miniposix PUBLIC unistd) -endif() diff --git a/lib/miniposix/dirent/dirent.c b/lib/miniposix/dirent/dirent.c deleted file mode 100644 index 2a156be6..00000000 --- a/lib/miniposix/dirent/dirent.c +++ /dev/null @@ -1,382 +0,0 @@ -#include -#include -#include -#include - -struct __dir -{ - struct dirent *entries; - HANDLE fd; - long int count; - long int index; -}; - -static void __seterrno(int value) -{ -#ifdef _MSC_VER - _set_errno(value); -#else /* _MSC_VER */ - errno = value; -#endif /* _MSC_VER */ -} - -int closedir(DIR *dirp) -{ - struct __dir *data = NULL; - if (!dirp) { - __seterrno(EBADF); - return -1; - } - data = (struct __dir *)dirp; - CloseHandle((HANDLE)data->fd); - free(data->entries); - free(data); - return 0; -} - -static int __islink(const wchar_t *name, char *buffer) -{ - DWORD io_result = 0; - DWORD bytes_returned = 0; - HANDLE hFile = - CreateFileW(name, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0); - if (hFile == INVALID_HANDLE_VALUE) - return 0; - - io_result = DeviceIoControl( - hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytes_returned, NULL); - - CloseHandle(hFile); - - if (io_result == 0) - return 0; - - return ((REPARSE_GUID_DATA_BUFFER *)buffer)->ReparseTag == IO_REPARSE_TAG_SYMLINK; -} - -static __ino_t __inode(const wchar_t *name) -{ - __ino_t value = { 0 }; - BOOL result; - FILE_ID_INFO fileid; - BY_HANDLE_FILE_INFORMATION info; - HANDLE hFile = CreateFileW(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); - if (hFile == INVALID_HANDLE_VALUE) - return value; - - result = GetFileInformationByHandleEx(hFile, FileIdInfo, &fileid, sizeof(fileid)); - if (result) { - value.serial = fileid.VolumeSerialNumber; - memcpy(value.fileid, fileid.FileId.Identifier, 16); - } else { - result = GetFileInformationByHandle(hFile, &info); - if (result) { - value.serial = info.dwVolumeSerialNumber; - memcpy(value.fileid + 8, &info.nFileIndexHigh, 4); - memcpy(value.fileid + 12, &info.nFileIndexLow, 4); - } - } - CloseHandle(hFile); - return value; -} - -static DIR *__internal_opendir(wchar_t *wname, int size) -{ - struct __dir *data = NULL; - struct dirent *tmp_entries = NULL; - static char default_char = '?'; - static wchar_t *prefix = L"\\\\?\\"; - static wchar_t *suffix = L"\\*.*"; - int extra_prefix = 4; /* use prefix "\\?\" to handle long file names */ - static int extra_suffix = 4; /* use suffix "\*.*" to find everything */ - WIN32_FIND_DATAW w32fd = { 0 }; - HANDLE hFindFile = INVALID_HANDLE_VALUE; - static int grow_factor = 2; - char *buffer = NULL; - - /* Ensure path only uses windows separator, of FindFirstFileW will fail. */ - wchar_t* rep = wname; - while ((rep = wcschr(rep, L'/')) != NULL) { - *rep++ = L'\\'; - } - - memcpy(wname + extra_prefix + size - 1, suffix, sizeof(wchar_t) * extra_prefix); - wname[size + extra_prefix + extra_suffix - 1] = 0; - - if (memcmp(wname + extra_prefix, L"\\\\?\\", sizeof(wchar_t) * extra_prefix) == 0) { - wname += extra_prefix; - extra_prefix = 0; - } - - hFindFile = FindFirstFileW(wname, &w32fd); - if (INVALID_HANDLE_VALUE == hFindFile) { - __seterrno(ENOENT); - return NULL; - } - - data = (struct __dir *)malloc(sizeof(struct __dir)); - if (!data) - goto out_of_memory; - wname[extra_prefix + size - 1] = 0; - data->fd = CreateFileW(wname, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); - wname[extra_prefix + size - 1] = L'\\'; - data->count = 16; - data->index = 0; - data->entries = (struct dirent *)malloc(sizeof(struct dirent) * data->count); - if (!data->entries) - goto out_of_memory; - buffer = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); - if (!buffer) - goto out_of_memory; - do { - WideCharToMultiByte( - CP_UTF8, 0, w32fd.cFileName, -1, data->entries[data->index].d_name, NAME_MAX, &default_char, NULL); - - memcpy(wname + extra_prefix + size, w32fd.cFileName, sizeof(wchar_t) * NAME_MAX); - - if (((w32fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT) - && __islink(wname, buffer)) - data->entries[data->index].d_type = DT_LNK; - else if ((w32fd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) == FILE_ATTRIBUTE_DEVICE) - data->entries[data->index].d_type = DT_CHR; - else if ((w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) - data->entries[data->index].d_type = DT_DIR; - else - data->entries[data->index].d_type = DT_REG; - - data->entries[data->index].d_ino = __inode(wname); - data->entries[data->index].d_reclen = sizeof(struct dirent); - data->entries[data->index].d_namelen = (unsigned char)wcslen(w32fd.cFileName); - data->entries[data->index].d_off = 0; - - if (++data->index == data->count) { - tmp_entries = (struct dirent *)realloc(data->entries, sizeof(struct dirent) * data->count * grow_factor); - if (!tmp_entries) - goto out_of_memory; - data->entries = tmp_entries; - data->count *= grow_factor; - } - } while (FindNextFileW(hFindFile, &w32fd) != 0); - - free(buffer); - FindClose(hFindFile); - - data->count = data->index; - data->index = 0; - return (DIR *)data; -out_of_memory: - if (data) { - if (INVALID_HANDLE_VALUE != (HANDLE)data->fd) - CloseHandle((HANDLE)data->fd); - free(data->entries); - } - free(buffer); - free(data); - if (INVALID_HANDLE_VALUE != hFindFile) - FindClose(hFindFile); - __seterrno(ENOMEM); - return NULL; -} - -static wchar_t *__get_buffer() -{ - wchar_t *name = malloc(sizeof(wchar_t) * (NTFS_MAX_PATH + NAME_MAX + 8)); - if (name) - memcpy(name, L"\\\\?\\", sizeof(wchar_t) * 4); - return name; -} - -DIR *opendir(const char *name) -{ - DIR *dirp = NULL; - wchar_t *wname = __get_buffer(); - int size = 0; - if (!wname) { - __seterrno(ENOMEM); - return NULL; - } - size = MultiByteToWideChar(CP_UTF8, 0, name, -1, wname + 4, NTFS_MAX_PATH); - if (0 == size) { - free(wname); - return NULL; - } - dirp = __internal_opendir(wname, size); - free(wname); - return dirp; -} - -DIR *_wopendir(const wchar_t *name) -{ - DIR *dirp = NULL; - wchar_t *wname = __get_buffer(); - int size = 0; - if (!wname) { - __seterrno(ENOMEM); - return NULL; - } - size = (int)wcslen(name); - if (size > NTFS_MAX_PATH) { - free(wname); - return NULL; - } - memcpy(wname + 4, name, sizeof(wchar_t) * (size + 1)); - dirp = __internal_opendir(wname, size + 1); - free(wname); - return dirp; -} - -DIR *fdopendir(int fd) -{ - DIR *dirp = NULL; - wchar_t *wname = __get_buffer(); - int size = 0; - if (!wname) { - __seterrno(ENOMEM); - return NULL; - } - size = GetFinalPathNameByHandleW((HANDLE)((intptr_t)fd), wname, NTFS_MAX_PATH, FILE_NAME_NORMALIZED); - if (0 == size) { - free(wname); - __seterrno(ENOTDIR); - return NULL; - } - dirp = __internal_opendir(wname, size + 1); - free(wname); - return dirp; -} - -struct dirent *readdir(DIR *dirp) -{ - struct __dir *data = (struct __dir *)dirp; - if (!data) { - __seterrno(EBADF); - return NULL; - } - if (data->index < data->count) { - return &data->entries[data->index++]; - } - return NULL; -} - -int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) -{ - struct __dir *data = (struct __dir *)dirp; - if (!data) { - return EBADF; - } - if (data->index < data->count) { - if (entry) - memcpy(entry, &data->entries[data->index++], sizeof(struct dirent)); - if (result) - *result = entry; - } else if (result) - *result = NULL; - return 0; -} - -void seekdir(DIR *dirp, long int offset) -{ - if (dirp) { - struct __dir *data = (struct __dir *)dirp; - data->index = (offset < data->count) ? offset : data->index; - } -} - -void rewinddir(DIR *dirp) -{ - seekdir(dirp, 0); -} - -long int telldir(DIR *dirp) -{ - if (!dirp) { - __seterrno(EBADF); - return -1; - } - return ((struct __dir *)dirp)->count; -} - -int dirfd(DIR *dirp) -{ - if (!dirp) { - __seterrno(EINVAL); - return -1; - } - return (int)((struct __dir *)dirp)->fd; -} - -int scandir(const char *dirp, - struct dirent ***namelist, - int (*filter)(const struct dirent *), - int (*compar)(const struct dirent **, const struct dirent **)) -{ - struct dirent **entries = NULL, **tmp_entries = NULL; - long int i = 0, index = 0, count = 16; - DIR *d = opendir(dirp); - struct __dir *data = (struct __dir *)d; - if (!data) { - closedir(d); - __seterrno(ENOENT); - return -1; - } - entries = (struct dirent **)malloc(sizeof(struct dirent *) * count); - if (!entries) { - closedir(d); - __seterrno(ENOMEM); - return -1; - } - for (i = 0; i < data->count; ++i) { - if (!filter || filter(&data->entries[i])) { - entries[index] = (struct dirent *)malloc(sizeof(struct dirent)); - if (!entries[index]) { - closedir(d); - for (i = 0; i < index; ++i) - free(entries[index]); - free(entries); - __seterrno(ENOMEM); - return -1; - } - memcpy(entries[index], &data->entries[i], sizeof(struct dirent)); - if (++index == count) { - tmp_entries = (struct dirent **)realloc(entries, sizeof(struct dirent *) * count * 2); - if (!tmp_entries) { - closedir(d); - for (i = 0; i < index; ++i) - free(entries[index - 1]); - free(entries); - __seterrno(ENOMEM); - return -1; - } - entries = tmp_entries; - count *= 2; - } - } - } - qsort(entries, index, sizeof(struct dirent *), compar); - entries[index] = NULL; - if (namelist) - *namelist = entries; - closedir(d); - return 0; -} - -int alphasort(const void *a, const void *b) -{ - struct dirent **dira = (struct dirent **)a, **dirb = (struct dirent **)b; - if (!dira || !dirb) - return 0; - return strcoll((*dira)->d_name, (*dirb)->d_name); -} - -static int __strverscmp(const char *s1, const char *s2) -{ - return alphasort(s1, s2); -} - -int versionsort(const void *a, const void *b) -{ - struct dirent **dira = (struct dirent **)a, **dirb = (struct dirent **)b; - if (!dira || !dirb) - return 0; - return __strverscmp((*dira)->d_name, (*dirb)->d_name); -} diff --git a/lib/miniposix/dirent/dirent.h b/lib/miniposix/dirent/dirent.h deleted file mode 100644 index dff42581..00000000 --- a/lib/miniposix/dirent/dirent.h +++ /dev/null @@ -1,144 +0,0 @@ -/* -MIT License -Copyright (c) 2019 win32ports -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#ifndef WIN32PORTS_DIRENT_H -#define WIN32PORTS_DIRENT_H - -#ifndef _WIN32 - -#pragma message("this dirent.h implementation is for Windows only!") - -#elif defined __MINGW32__ - -#include <../include/dirent.h> - -#else - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#include -#include - -#ifndef NAME_MAX -#define NAME_MAX 260 -#endif /* NAME_MAX */ - -#ifndef DT_UNKNOWN -#define DT_UNKNOWN 0 -#endif /* DT_UNKNOWN */ - -#ifndef DT_FIFO -#define DT_FIFO 1 -#endif /* DT_FIFO */ - -#ifndef DT_CHR -#define DT_CHR 2 -#endif /* DT_CHR */ - -#ifndef DT_DIR -#define DT_DIR 4 -#endif /* DT_DIR */ - -#ifndef DT_BLK -#define DT_BLK 6 -#endif /* DT_BLK */ - -#ifndef DT_REG -#define DT_REG 8 -#endif /* DT_REF */ - -#ifndef DT_LNK -#define DT_LNK 10 -#endif /* DT_LNK */ - -#ifndef DT_SOCK -#define DT_SOCK 12 -#endif /* DT_SOCK */ - -#ifndef DT_WHT -#define DT_WHT 14 -#endif /* DT_WHT */ - -#ifndef _DIRENT_HAVE_D_NAMLEN -#define _DIRENT_HAVE_D_NAMLEN 1 -#endif /* _DIRENT_HAVE_D_NAMLEN */ - -#ifndef _DIRENT_HAVE_D_RECLEN -#define _DIRENT_HAVE_D_RECLEN 1 -#endif /* _DIRENT_HAVE_D_RECLEN */ - -#ifndef _DIRENT_HAVE_D_OFF -#define _DIRENT_HAVE_D_OFF 1 -#endif /* _DIRENT_HAVE_D_OFF */ - -#ifndef _DIRENT_HAVE_D_TYPE -#define _DIRENT_HAVE_D_TYPE 1 -#endif /* _DIRENT_HAVE_D_TYPE */ - -#ifndef NTFS_MAX_PATH -#define NTFS_MAX_PATH 32768 -#endif /* NTFS_MAX_PATH */ - -typedef struct __dir DIR; - -typedef struct ino_t -{ - unsigned long long serial; - unsigned char fileid[16]; -} __ino_t; - -struct dirent -{ - __ino_t d_ino; - off_t d_off; - unsigned short d_reclen; - unsigned char d_namelen; - unsigned char d_type; - char d_name[NAME_MAX]; -}; - -int closedir(DIR *dirp); -DIR *opendir(const char *name); -DIR *_wopendir(const wchar_t *name); -DIR *fdopendir(int fd); -struct dirent *readdir(DIR *dirp); -int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); -void seekdir(DIR *dirp, long int offset); -void rewinddir(DIR *dirp); -long int telldir(DIR *dirp); -int dirfd(DIR *dirp); -int scandir(const char *dirp, - struct dirent ***namelist, - int (*filter)(const struct dirent *), - int (*compar)(const struct dirent **, const struct dirent **)); -int alphasort(const void *a, const void *b); -int versionsort(const void *a, const void *b); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _WIN32 */ - -#endif /* WIN32PORTS_DIRENT_H */ diff --git a/lib/miniposix/fnmatch/fnmatch.c b/lib/miniposix/fnmatch/fnmatch.c deleted file mode 100644 index a8a6a15c..00000000 --- a/lib/miniposix/fnmatch/fnmatch.c +++ /dev/null @@ -1,311 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Guido van Rossum. - * - * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. - * Portions of this software were developed by David Chisnall - * under sponsorship from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. - * Compares a filename or pathname to a pattern. - */ - -/* - * Some notes on multibyte character support: - * 1. Patterns with illegal byte sequences match nothing. - * 2. Illegal byte sequences in the "string" argument are handled by treating - * them as single-byte characters with a value of the first byte of the - * sequence cast to wchar_t. - * 3. Multibyte conversion state objects (mbstate_t) are passed around and - * used for most, but not all, conversions. Further work will be required - * to support state-dependent encodings. - */ - -#include -#include -#include -#include -#include - -#define EOS '\0' - -#define RANGE_MATCH 1 -#define RANGE_NOMATCH 0 -#define RANGE_ERROR (-1) - -static int rangematch(const char *, wchar_t, int, char **, mbstate_t *); -static int fnmatch1(const char *, const char *, const char *, int, mbstate_t, - mbstate_t); - -int -fnmatch(const char *pattern, const char *string, int flags) -{ - static const mbstate_t initial; - - return (fnmatch1(pattern, string, string, flags, initial, initial)); -} - -static int -fnmatch1(const char *pattern, const char *string, const char *stringstart, - int flags, mbstate_t patmbs, mbstate_t strmbs) -{ - const char *bt_pattern, *bt_string; - mbstate_t bt_patmbs, bt_strmbs; - char *newp; - char c; - wchar_t pc, sc; - size_t pclen, sclen; - - bt_pattern = bt_string = NULL; - for (;;) { - pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); - if (pclen == (size_t)-1 || pclen == (size_t)-2) - return (FNM_NOMATCH); - pattern += pclen; - sclen = mbrtowc(&sc, string, MB_LEN_MAX, &strmbs); - if (sclen == (size_t)-1 || sclen == (size_t)-2) { - sc = (unsigned char)*string; - sclen = 1; - memset(&strmbs, 0, sizeof(strmbs)); - } - switch (pc) { - case EOS: - if ((flags & FNM_LEADING_DIR) && sc == '/') - return (0); - if (sc == EOS) - return (0); - goto backtrack; - case '?': - if (sc == EOS) - return (FNM_NOMATCH); - if (sc == '/' && (flags & FNM_PATHNAME)) - goto backtrack; - if (sc == '.' && (flags & FNM_PERIOD) && - (string == stringstart || - ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) - goto backtrack; - string += sclen; - break; - case '*': - c = *pattern; - /* Collapse multiple stars. */ - while (c == '*') - c = *++pattern; - - if (sc == '.' && (flags & FNM_PERIOD) && - (string == stringstart || - ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) - goto backtrack; - - /* Optimize for pattern with * at end or before /. */ - if (c == EOS) - if (flags & FNM_PATHNAME) - return ((flags & FNM_LEADING_DIR) || - strchr(string, '/') == NULL ? - 0 : FNM_NOMATCH); - else - return (0); - else if (c == '/' && flags & FNM_PATHNAME) { - if ((string = strchr(string, '/')) == NULL) - return (FNM_NOMATCH); - break; - } - - /* - * First try the shortest match for the '*' that - * could work. We can forget any earlier '*' since - * there is no way having it match more characters - * can help us, given that we are already here. - */ - bt_pattern = pattern, bt_patmbs = patmbs; - bt_string = string, bt_strmbs = strmbs; - break; - case '[': - if (sc == EOS) - return (FNM_NOMATCH); - if (sc == '/' && (flags & FNM_PATHNAME)) - goto backtrack; - if (sc == '.' && (flags & FNM_PERIOD) && - (string == stringstart || - ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) - goto backtrack; - - switch (rangematch(pattern, sc, flags, &newp, - &patmbs)) { - case RANGE_ERROR: - goto norm; - case RANGE_MATCH: - pattern = newp; - break; - case RANGE_NOMATCH: - goto backtrack; - } - string += sclen; - break; - case '\\': - if (!(flags & FNM_NOESCAPE)) { - pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, - &patmbs); - if (pclen == 0 || pclen == (size_t)-1 || - pclen == (size_t)-2) - return (FNM_NOMATCH); - pattern += pclen; - } - /* FALLTHROUGH */ - default: - norm: - string += sclen; - if (pc == sc) - ; - else if ((flags & FNM_CASEFOLD) && - (towlower(pc) == towlower(sc))) - ; - else { - backtrack: - /* - * If we have a mismatch (other than hitting - * the end of the string), go back to the last - * '*' seen and have it match one additional - * character. - */ - if (bt_pattern == NULL) - return (FNM_NOMATCH); - sclen = mbrtowc(&sc, bt_string, MB_LEN_MAX, - &bt_strmbs); - if (sclen == (size_t)-1 || - sclen == (size_t)-2) { - sc = (unsigned char)*bt_string; - sclen = 1; - memset(&bt_strmbs, 0, - sizeof(bt_strmbs)); - } - if (sc == EOS) - return (FNM_NOMATCH); - if (sc == '/' && flags & FNM_PATHNAME) - return (FNM_NOMATCH); - bt_string += sclen; - pattern = bt_pattern, patmbs = bt_patmbs; - string = bt_string, strmbs = bt_strmbs; - } - break; - } - } - /* NOTREACHED */ -} - -static int __wcollate_range_cmp(wchar_t c1, wchar_t c2) -{ - wchar_t s1[2], s2[2]; - - s1[0] = c1; - s1[1] = L'\0'; - s2[0] = c2; - s2[1] = L'\0'; - return (wcscoll(s1, s2)); -} - -static int -rangematch(const char *pattern, wchar_t test, int flags, char **newp, - mbstate_t *patmbs) -{ - int negate, ok; - wchar_t c, c2; - size_t pclen; - const char *origpat; - - /* - * A bracket expression starting with an unquoted circumflex - * character produces unspecified results (IEEE 1003.2-1992, - * 3.13.2). This implementation treats it like '!', for - * consistency with the regular expression syntax. - * J.T. Conklin (conklin@ngai.kaleida.com) - */ - if ((negate = (*pattern == '!' || *pattern == '^'))) - ++pattern; - - if (flags & FNM_CASEFOLD) - test = towlower(test); - - /* - * A right bracket shall lose its special meaning and represent - * itself in a bracket expression if it occurs first in the list. - * -- POSIX.2 2.8.3.2 - */ - ok = 0; - origpat = pattern; - for (;;) { - if (*pattern == ']' && pattern > origpat) { - pattern++; - break; - } else if (*pattern == '\0') { - return (RANGE_ERROR); - } else if (*pattern == '/' && (flags & FNM_PATHNAME)) { - return (RANGE_NOMATCH); - } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) - pattern++; - pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs); - if (pclen == (size_t)-1 || pclen == (size_t)-2) - return (RANGE_NOMATCH); - pattern += pclen; - - if (flags & FNM_CASEFOLD) - c = towlower(c); - - if (*pattern == '-' && *(pattern + 1) != EOS && - *(pattern + 1) != ']') { - if (*++pattern == '\\' && !(flags & FNM_NOESCAPE)) - if (*pattern != EOS) - pattern++; - pclen = mbrtowc(&c2, pattern, MB_LEN_MAX, patmbs); - if (pclen == (size_t)-1 || pclen == (size_t)-2) - return (RANGE_NOMATCH); - pattern += pclen; - if (c2 == EOS) - return (RANGE_ERROR); - - if (flags & FNM_CASEFOLD) - c2 = towlower(c2); - - if (__wcollate_range_cmp(c, test) <= 0 - && __wcollate_range_cmp(test, c2) <= 0 - ) - ok = 1; - } else if (c == test) - ok = 1; - } - - *newp = (char *)pattern; - return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); -} diff --git a/lib/miniposix/fnmatch/fnmatch.h b/lib/miniposix/fnmatch/fnmatch.h deleted file mode 100644 index 8f9193de..00000000 --- a/lib/miniposix/fnmatch/fnmatch.h +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef WIN32PORTS_FNMATCH_H -#define WIN32PORTS_FNMATCH_H - -#define FNM_NOMATCH 1 /* Match failed. */ - -#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ -#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ -#define FNM_PERIOD 0x04 /* Period must be matched by period. */ - -#if __XSI_VISIBLE -#define FNM_NOSYS (-1) /* Reserved. */ -#endif - -#define FNM_LEADING_DIR 0x08 /* Ignore / after Imatch. */ -#define FNM_CASEFOLD 0x10 /* Case insensitive search. */ -#define FNM_IGNORECASE FNM_CASEFOLD -#define FNM_FILE_NAME FNM_PATHNAME - -int fnmatch(const char *, const char *, int); - -#endif /* !WIN32PORTS_FNMATCH_H */ diff --git a/lib/miniposix/getopt/getopt.c b/lib/miniposix/getopt/getopt.c deleted file mode 100644 index e1b27ba1..00000000 --- a/lib/miniposix/getopt/getopt.c +++ /dev/null @@ -1,361 +0,0 @@ -/* -Copyright (C) 1997 Gregory Pietsch - -[These files] are hereby placed in the public domain without restrictions. Just -give the author credit, don't claim you wrote it or prevent anyone else from -using it. -*/ - -/**************************************************************************** - -getopt.c - Read command line options - -AUTHOR: Gregory Pietsch -CREATED Fri Jan 10 21:13:05 1997 - -DESCRIPTION: - -The getopt() function parses the command line arguments. Its arguments argc -and argv are the argument count and array as passed to the main() function -on program invocation. The argument optstring is a list of available option -characters. If such a character is followed by a colon (`:'), the option -takes an argument, which is placed in optarg. If such a character is -followed by two colons, the option takes an optional argument, which is -placed in optarg. If the option does not take an argument, optarg is NULL. - -The external variable optind is the index of the next array element of argv -to be processed; it communicates from one call to the next which element to -process. - -The getopt_long() function works like getopt() except that it also accepts -long options started by two dashes `--'. If these take values, it is either -in the form - ---arg=value - - or - ---arg value - -It takes the additional arguments longopts which is a pointer to the first -element of an array of type GETOPT_LONG_OPTION_T. The last element of the -array has to be filled with NULL for the name field. - -The longind pointer points to the index of the current long option relative -to longopts if it is non-NULL. - -The getopt() function returns the option character if the option was found -successfully, `:' if there was a missing parameter for one of the options, -`?' for an unknown option character, and EOF for the end of the option list. - -The getopt_long() function's return value is described in the header file. - -The function getopt_long_only() is identical to getopt_long(), except that a -plus sign `+' can introduce long options as well as `--'. - -The following describes how to deal with options that follow non-option -argv-elements. - -If the caller did not specify anything, the default is REQUIRE_ORDER if the -environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. - -REQUIRE_ORDER means don't recognize them as options; stop option processing -when the first non-option is seen. This is what Unix does. This mode of -operation is selected by either setting the environment variable -POSIXLY_CORRECT, or using `+' as the first character of the optstring -parameter. - -PERMUTE is the default. We permute the contents of ARGV as we scan, so that -eventually all the non-options are at the end. This allows options to be -given in any order, even with programs that were not written to expect this. - -RETURN_IN_ORDER is an option available to programs that were written to -expect options and other argv-elements in any order and that care about the -ordering of the two. We describe each non-option argv-element as if it were -the argument of an option with character code 1. Using `-' as the first -character of the optstring parameter selects this mode of operation. - -The special argument `--' forces an end of option-scanning regardless of the -value of ordering. In the case of RETURN_IN_ORDER, only `--' can cause -getopt() and friends to return EOF with optind != argc. - -COPYRIGHT NOTICE AND DISCLAIMER: - -Copyright (C) 1997 Gregory Pietsch - -This file and the accompanying getopt.h header file are hereby placed in the -public domain without restrictions. Just give the author credit, don't -claim you wrote it or prevent anyone else from using it. - -Gregory Pietsch's current e-mail address: -gpietsch@comcast.net -****************************************************************************/ - -/* include files */ -#include -#include -#include -#include - -/* macros */ - -/* types */ -typedef enum GETOPT_ORDERING_T -{ - PERMUTE, - RETURN_IN_ORDER, - REQUIRE_ORDER -} GETOPT_ORDERING_T; - -/* globally-defined variables */ -char *optarg = NULL; -int optind = 0; -int opterr = 1; -int optopt = '?'; - -/* functions */ - -/* reverse_argv_elements: reverses num elements starting at argv */ -static void reverse_argv_elements(char **argv, int num) -{ - int i; - char *tmp; - - for (i = 0; i < (num >> 1); i++) { - tmp = argv[i]; - argv[i] = argv[num - i - 1]; - argv[num - i - 1] = tmp; - } -} - -/* permute: swap two blocks of argv-elements given their lengths */ -static void permute(char **argv, int len1, int len2) -{ - reverse_argv_elements(argv, len1); - reverse_argv_elements(argv, len1 + len2); - reverse_argv_elements(argv, len2); -} - -/* is_option: is this argv-element an option or the end of the option list? */ -static int is_option(char *argv_element, int only) -{ - return ((argv_element == NULL) || (argv_element[0] == '-') || (only && argv_element[0] == '+')); -} - -/* getopt_internal: the function that does all the dirty work */ -static int getopt_internal(int argc, char **argv, char *shortopts, GETOPT_LONG_OPTION_T *longopts, int *longind, int only) -{ - GETOPT_ORDERING_T ordering = PERMUTE; - static size_t optwhere = 0; - size_t permute_from = 0; - int num_nonopts = 0; - int optindex = 0; - size_t match_chars = 0; - char *possible_arg = NULL; - int longopt_match = -1; - int has_arg = -1; - char *cp = NULL; - int arg_next = 0; - - /* first, deal with silly parameters and easy stuff */ - if (argc == 0 || argv == NULL || (shortopts == NULL && longopts == NULL)) - return (optopt = '?'); - if (optind >= argc || argv[optind] == NULL) - return EOF; - if (strcmp(argv[optind], "--") == 0) { - optind++; - return EOF; - } - /* if this is our first time through */ - if (optind == 0) { - optind = 1; - optwhere = 1; - } - - /* define ordering */ - if (shortopts != NULL && (*shortopts == '-' || *shortopts == '+')) { - ordering = (*shortopts == '-') ? RETURN_IN_ORDER : REQUIRE_ORDER; - shortopts++; - } else - ordering = (getenv("POSIXLY_CORRECT") != NULL) ? REQUIRE_ORDER : PERMUTE; - - /* - * based on ordering, find our next option, if we're at the beginning of - * one - */ - if (optwhere == 1) { - switch (ordering) { - case PERMUTE: - permute_from = optind; - num_nonopts = 0; - while (!is_option(argv[optind], only)) { - optind++; - num_nonopts++; - } - if (argv[optind] == NULL) { - /* no more options */ - optind = (int)permute_from; - return EOF; - } else if (strcmp(argv[optind], "--") == 0) { - /* no more options, but have to get `--' out of the way */ - permute(argv + permute_from, num_nonopts, 1); - optind = (int)(permute_from + 1); - return EOF; - } - break; - case RETURN_IN_ORDER: - if (!is_option(argv[optind], only)) { - optarg = argv[optind++]; - return (optopt = 1); - } - break; - case REQUIRE_ORDER: - if (!is_option(argv[optind], only)) - return EOF; - break; - } - } - /* we've got an option, so parse it */ - - /* first, is it a long option? */ - if (longopts != NULL && (strncmp(argv[optind], "--", 2) == 0 || (only && argv[optind][0] == '+')) && optwhere == 1) { - /* handle long options */ - if (strncmp(argv[optind], "--", 2) == 0) - optwhere = 2; - longopt_match = -1; - possible_arg = strchr(argv[optind] + optwhere, '='); - if (possible_arg == NULL) { - /* no =, so next argv might be arg */ - match_chars = strlen(argv[optind]); - possible_arg = argv[optind] + match_chars; - match_chars = match_chars - optwhere; - } else - match_chars = (possible_arg - argv[optind]) - optwhere; - for (optindex = 0; longopts[optindex].name != NULL; optindex++) { - if (strncmp(argv[optind] + optwhere, longopts[optindex].name, match_chars) == 0) { - /* do we have an exact match? */ - if (match_chars == strlen(longopts[optindex].name)) { - longopt_match = optindex; - break; - } - /* do any characters match? */ - else { - if (longopt_match < 0) - longopt_match = optindex; - else { - /* we have ambiguous options */ - if (opterr) - fprintf(stderr, - "%s: option `%s' is ambiguous " - "(could be `--%s' or `--%s')\n", - argv[0], - argv[optind], - longopts[longopt_match].name, - longopts[optindex].name); - return (optopt = '?'); - } - } - } - } - if (longopt_match >= 0) - has_arg = longopts[longopt_match].has_arg; - } - /* if we didn't find a long option, is it a short option? */ - if (longopt_match < 0 && shortopts != NULL) { - cp = strchr(shortopts, argv[optind][optwhere]); - if (cp == NULL) { - /* couldn't find option in shortopts */ - if (opterr) - fprintf(stderr, "%s: invalid option -- `-%c'\n", argv[0], argv[optind][optwhere]); - optwhere++; - if (argv[optind][optwhere] == '\0') { - optind++; - optwhere = 1; - } - return (optopt = '?'); - } - has_arg = ((cp[1] == ':') ? ((cp[2] == ':') ? optional_argument : required_argument) : no_argument); - possible_arg = argv[optind] + optwhere + 1; - optopt = *cp; - } - /* get argument and reset optwhere */ - arg_next = 0; - switch (has_arg) { - case optional_argument: - if (*possible_arg == '=') - possible_arg++; - if (*possible_arg != '\0') { - optarg = possible_arg; - optwhere = 1; - } else - optarg = NULL; - break; - case required_argument: - if (*possible_arg == '=') - possible_arg++; - if (*possible_arg != '\0') { - optarg = possible_arg; - optwhere = 1; - } else if (optind + 1 >= argc) { - if (opterr) { - fprintf(stderr, "%s: argument required for option `", argv[0]); - if (longopt_match >= 0) - fprintf(stderr, "--%s'\n", longopts[longopt_match].name); - else - fprintf(stderr, "-%c'\n", *cp); - } - optind++; - return (optopt = ':'); - } else { - optarg = argv[optind + 1]; - arg_next = 1; - optwhere = 1; - } - break; - case no_argument: - if (longopt_match < 0) { - optwhere++; - if (argv[optind][optwhere] == '\0') - optwhere = 1; - } else - optwhere = 1; - optarg = NULL; - break; - } - - /* do we have to permute or otherwise modify optind? */ - if (ordering == PERMUTE && optwhere == 1 && num_nonopts != 0) { - permute(argv + permute_from, num_nonopts, 1 + arg_next); - optind = (int)(permute_from + 1 + arg_next); - } else if (optwhere == 1) - optind = optind + 1 + arg_next; - - /* finally return */ - if (longopt_match >= 0) { - if (longind != NULL) - *longind = longopt_match; - if (longopts[longopt_match].flag != NULL) { - *(longopts[longopt_match].flag) = longopts[longopt_match].val; - return 0; - } else - return longopts[longopt_match].val; - } else - return optopt; -} - -int getopt(int argc, char **argv, char *optstring) -{ - return getopt_internal(argc, argv, optstring, NULL, NULL, 0); -} - -int getopt_long(int argc, char **argv, const char *shortopts, const GETOPT_LONG_OPTION_T *longopts, int *longind) -{ - return getopt_internal(argc, argv, (char *)shortopts, (GETOPT_LONG_OPTION_T *)longopts, longind, 0); -} - -int getopt_long_only(int argc, char **argv, const char *shortopts, const GETOPT_LONG_OPTION_T *longopts, int *longind) -{ - return getopt_internal(argc, argv, (char *)shortopts, (GETOPT_LONG_OPTION_T *)longopts, longind, 1); -} - -/* end of file GETOPT.C */ diff --git a/lib/miniposix/getopt/getopt.h b/lib/miniposix/getopt/getopt.h deleted file mode 100644 index e38f8921..00000000 --- a/lib/miniposix/getopt/getopt.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright (C) 1997 Gregory Pietsch - -[These files] are hereby placed in the public domain without restrictions. Just -give the author credit, don't claim you wrote it or prevent anyone else from -using it. -*/ -#pragma once - -#ifndef WIN32PORTS_GETOPT_H -#define WIN32PORTS_GETOPT_H -#ifndef _WIN32 - -#pragma message("this getopt.h implementation is for Windows only!") - -#elif defined __MINGW32__ - -#include <../include/getopt.h> - -#else - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* include files needed by this include file */ - -/* macros defined by this include file */ -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -/* types defined by this include file */ - -/* GETOPT_LONG_OPTION_T: The type of long option */ -typedef struct GETOPT_LONG_OPTION_T -{ - const char *name; /* the name of the long option */ - int has_arg; /* one of the above macros */ - int *flag; /* determines if getopt_long() returns a - * value for a long option; if it is - * non-NULL, 0 is returned as a function - * value and the value of val is stored in - * the area pointed to by flag. Otherwise, - * val is returned. */ - int val; /* determines the value to return if flag is - * NULL. */ -} GETOPT_LONG_OPTION_T; - -typedef GETOPT_LONG_OPTION_T option; - -/* externally-defined variables */ -extern char *optarg; -extern int optind; -extern int opterr; -extern int optopt; - -/* function prototypes */ -int getopt(int argc, char **argv, char *optstring); -int getopt_long(int argc, char **argv, const char *shortopts, const GETOPT_LONG_OPTION_T *longopts, int *longind); -int getopt_long_only(int argc, char **argv, const char *shortopts, const GETOPT_LONG_OPTION_T *longopts, int *longind); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _WIN32 */ - -#endif /* WIN32PORTS_GETOPT_H */ diff --git a/lib/miniposix/libgen/libgen.c b/lib/miniposix/libgen/libgen.c deleted file mode 100644 index a0afbc1f..00000000 --- a/lib/miniposix/libgen/libgen.c +++ /dev/null @@ -1,263 +0,0 @@ -/* basename.c - * - * $Id: basename.c,v 1.2 2007/03/08 23:15:58 keithmarshall Exp $ - * - * Provides an implementation of the "basename" function, conforming - * to SUSv3, with extensions to accommodate Win32 drive designators, - * and suitable for use on native Microsoft(R) Win32 platforms. - * - * Written by Keith Marshall - * - * This is free software. You may redistribute and/or modify it as you - * see fit, without restriction of copyright. - * - * This software is provided "as is", in the hope that it may be useful, - * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of - * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no - * time will the author accept any form of liability for any damages, - * however caused, resulting from the use of this software. - * - */ - -#include -#include -#include -#include -#include -#include - -char *basename(char *path) -{ - static char *retfail = NULL; - size_t len; - /* to handle path names for files in multibyte character locales, - * we need to set up LC_CTYPE to match the host file system locale - */ - char *locale = setlocale(LC_CTYPE, NULL); - - if (locale != NULL) - locale = strdup(locale); - setlocale(LC_CTYPE, ""); - - if (path && *path) { - /* allocate sufficient local storage space, - * in which to create a wide character reference copy of path - */ - len = mbstowcs(NULL, path, 0); - wchar_t *refcopy = malloc(sizeof(wchar_t) * (1 + len)); - /* create the wide character reference copy of path, - * and step over the drive designator, if present ... - */ - wchar_t *refpath = refcopy; - - if ((len = mbstowcs(refpath, path, len)) > 1 && refpath[1] == L':') { - /* FIXME: maybe should confirm *refpath is a valid drive designator */ - refpath += 2; - } - /* ensure that our wide character reference path is NUL terminated */ - refcopy[len] = L'\0'; - /* check again, just to ensure we still have a non-empty path name ... */ - if (*refpath) { - /* and, when we do, process it in the wide character domain ... - * scanning from left to right, to the char after the final dir separator. */ - wchar_t *refname; - - for (refname = refpath; *refpath; ++refpath) { - if (*refpath == L'/' || *refpath == L'\\') { - /* we found a dir separator ... - * step over it, and any others which immediately follow it. */ - while (*refpath == L'/' || *refpath == L'\\') - ++refpath; - /* if we didn't reach the end of the path string ... */ - if (*refpath) - /* then we have a new candidate for the base name. */ - refname = refpath; - /* otherwise ... - * strip off any trailing dir separators which we found. */ - else - while (refpath > refname && (*--refpath == L'/' || *refpath == L'\\')) - *refpath = L'\0'; - } - } - /* in the wide character domain ... - * refname now points at the resolved base name ... */ - if (*refname) { - /* if it's not empty, - * then we transform the full normalised path back into - * the multibyte character domain, and skip over the dirname, - * to return the resolved basename. */ - if ((len = wcstombs(path, refcopy, len)) != (size_t)(-1)) - path[len] = '\0'; - *refname = L'\0'; - if ((len = wcstombs(NULL, refcopy, 0)) != (size_t)(-1)) - path += len; - } else { - /* the basename is empty, so return the default value of "/", - * transforming from wide char to multibyte char domain, and - * returning it in our own buffer. */ - retfail = realloc(retfail, len = 1 + wcstombs(NULL, L"/", 0)); - wcstombs(path = retfail, L"/", len); - } - /* restore the caller's locale, clean up, and return the result */ - setlocale(LC_CTYPE, locale); - free(locale); - free(refcopy); - return path; - } - /* or we had an empty residual path name, after the drive designator, - * in which case we simply fall through ... */ - free(refcopy); - } - /* and, if we get to here ... - * the path name is either NULL, or it decomposes to an empty string; - * in either case, we return the default value of "." in our own buffer, - * reloading it with the correct value, transformed from the wide char - * to the multibyte char domain, just in case the caller trashed it - * after a previous call. - */ - retfail = realloc(retfail, len = 1 + wcstombs(NULL, L".", 0)); - wcstombs(retfail, L".", len); - - /* restore the caller's locale, clean up, and return the result. */ - setlocale(LC_CTYPE, locale); - free(locale); - return retfail; -} - -char *dirname(char *path) -{ - static char *retfail = NULL; - size_t len; - /* to handle path names for files in multibyte character locales, - * we need to set up LC_CTYPE to match the host file system locale. */ - char *locale = setlocale(LC_CTYPE, NULL); - - if (locale != NULL) - locale = strdup(locale); - setlocale(LC_CTYPE, ""); - - if (path && *path) { - /* allocate sufficient local storage space, - * in which to create a wide character reference copy of path. */ - len = mbstowcs(NULL, path, 0); - wchar_t *refcopy = malloc(sizeof(wchar_t) * (1 + len)); - /* create the wide character reference copy of path */ - wchar_t *refpath = refcopy; - - len = mbstowcs(refpath, path, len); - refcopy[len] = L'\0'; - /* SUSv3 identifies a special case, where path is exactly equal to "//"; - * (we will also accept "\\" in the Win32 context, but not "/\" or "\/", - * and neither will we consider paths with an initial drive designator). - * For this special case, SUSv3 allows the implementation to choose to - * return "/" or "//", (or "\" or "\\", since this is Win32); we will - * simply return the path unchanged, (i.e. "//" or "\\"). */ - if (len > 1 && (refpath[0] == L'/' || refpath[0] == L'\\')) { - if (refpath[1] == refpath[0] && refpath[2] == L'\0') { - setlocale(LC_CTYPE, locale); - free(locale); - free(refcopy); - return path; - } - } - /* For all other cases ... - * step over the drive designator, if present ... */ - else if (len > 1 && refpath[1] == L':') { - /* FIXME: maybe should confirm *refpath is a valid drive designator. */ - refpath += 2; - } - /* check again, just to ensure we still have a non-empty path name ... */ - if (*refpath) { - /* reproduce the scanning logic of the "basename" function - * to locate the basename component of the current path string, - * (but also remember where the dirname component starts). */ - wchar_t *refname, *the_basename; - for (refname = the_basename = refpath; *refpath; ++refpath) { - if (*refpath == L'/' || *refpath == L'\\') { - /* we found a dir separator ... - * step over it, and any others which immediately follow it. */ - while (*refpath == L'/' || *refpath == L'\\') - ++refpath; - /* if we didn't reach the end of the path string ... */ - if (*refpath) - /* then we have a new candidate for the base name. */ - the_basename = refpath; - else - /* we struck an early termination of the path string, - * with trailing dir separators following the base name, - * so break out of the for loop, to avoid overrun. */ - break; - } - } - /* now check, - * to confirm that we have distinct dirname and basename components. */ - if (the_basename > refname) { - /* and, when we do ... - * backtrack over all trailing separators on the dirname component, - * (but preserve exactly two initial dirname separators, if identical), - * and add a NUL terminator in their place. */ - do - --the_basename; - while (the_basename > refname && (*the_basename == L'/' || *the_basename == L'\\')); - if (the_basename == refname && (refname[0] == L'/' || refname[0] == L'\\') && refname[1] == refname[0] - && refname[2] != L'/' && refname[2] != L'\\') - ++the_basename; - *++the_basename = L'\0'; - /* if the resultant dirname begins with EXACTLY two dir separators, - * AND both are identical, then we preserve them. */ - refpath = refcopy; - while ((*refpath == L'/' || *refpath == L'\\')) - ++refpath; - if ((refpath - refcopy) > 2 || refcopy[1] != refcopy[0]) - refpath = refcopy; - /* and finally ... - * we remove any residual, redundantly duplicated separators from the dirname, - * reterminate, and return it. */ - refname = refpath; - while (*refpath) { - if ((*refname++ = *refpath) == L'/' || *refpath++ == L'\\') { - while (*refpath == L'/' || *refpath == L'\\') - ++refpath; - } - } - *refname = L'\0'; - /* finally ... - * transform the resolved dirname back into the multibyte char domain, - * restore the caller's locale, and return the resultant dirname. */ - if ((len = wcstombs(path, refcopy, len)) != (size_t)(-1)) - path[len] = '\0'; - } else { - /* either there were no dirname separators in the path name, - * or there was nothing else ... */ - if (*refname == L'/' || *refname == L'\\') { - /* it was all separators, so return one. */ - ++refname; - } else { - /* there were no separators, so return '.'. */ - *refname++ = L'.'; - } - /* add a NUL terminator, in either case, - * then transform to the multibyte char domain, - * using our own buffer. */ - *refname = L'\0'; - retfail = realloc(retfail, len = 1 + wcstombs(NULL, refcopy, 0)); - wcstombs(path = retfail, refcopy, len); - } - /* restore caller's locale, clean up, and return the resolved dirname. */ - setlocale(LC_CTYPE, locale); - free(locale); - free(refcopy); - return path; - } - } - /* path is NULL, or an empty string; default return value is "." ... - * return this in our own buffer, regenerated by wide char transform, - * in case the caller trashed it after a previous call. - */ - retfail = realloc(retfail, len = 1 + wcstombs(NULL, L".", 0)); - wcstombs(retfail, L".", len); - /* restore caller's locale, clean up, and return the default dirname. */ - setlocale(LC_CTYPE, locale); - free(locale); - return retfail; -} diff --git a/lib/miniposix/libgen/libgen.h b/lib/miniposix/libgen/libgen.h deleted file mode 100644 index fabfb679..00000000 --- a/lib/miniposix/libgen/libgen.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef WIN32PORTS_LIBGEN_H -#define WIN32PORTS_LIBGEN_H - -#ifndef _WIN32 - -#pragma message("this libgen.h implementation is for Windows only!") - -#elif defined __MINGW32__ - -#include <../include/libgen.h> - -#else - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -char *basename(char *); -char *dirname(char *); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _WIN32 */ - -#endif /* WIN32PORTS_LIBGEN_H */ diff --git a/lib/miniposix/strings/strings.c b/lib/miniposix/strings/strings.c deleted file mode 100644 index 440a1e3e..00000000 --- a/lib/miniposix/strings/strings.c +++ /dev/null @@ -1,25 +0,0 @@ -/* -MIT License -Copyright (c) 2019 win32ports -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -#include - -extern inline void explicit_bzero(void *s, size_t n); -extern inline int ffs(int i); -extern inline int ffsl(long i); -extern inline int ffsll(long long i); diff --git a/lib/miniposix/strings/strings.h b/lib/miniposix/strings/strings.h deleted file mode 100644 index 6c751f4b..00000000 --- a/lib/miniposix/strings/strings.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -MIT License -Copyright (c) 2019 win32ports -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once -#ifndef WIN32PORTS_STRINGS_H -#define WIN32PORTS_STRINGS_H - -#ifndef _WIN32 - -#pragma message("this strings.h implementation is for Windows only!") - -#elif defined __MINGW32__ - -#include <../include/strings.h> - -#else - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#include -#include - -#define bcmp(s1, s2, n) memcmp(s1, s2, n) -#define bcopy(s, d, n) memcpy(d, s, n) -#define bzero(s, n) memset(s, 0, n) - -inline void explicit_bzero(void *s, size_t n) -{ - volatile char *vs = (volatile char *)s; - while (n) { - *vs++ = 0; - n--; - } -} - -#define index(s, c) strchr(s, c) -#define rindex(s, c) strrchr(s, c) - -inline int ffs(int i) -{ - int bit; - - if (0 == i) - return 0; - - for (bit = 1; !(i & 1); ++bit) - i >>= 1; - return bit; -} - -inline int ffsl(long i) -{ - int bit; - - if (0 == i) - return 0; - - for (bit = 1; !(i & 1); ++bit) - i >>= 1; - return bit; -} - -inline int ffsll(long long i) -{ - int bit; - - if (0 == i) - return 0; - - for (bit = 1; !(i & 1); ++bit) - i >>= 1; - return bit; -} - -#define strcasecmp(s1, s2) _stricmp(s1, s2) -#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n) -#define strcasecmp_l(s1, s2, loc) _stricmp_l(s1, s2, loc) -#define strncasecmp_l(s1, s2, n, loc) _strnicmp_l(s1, s2, n, loc) - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _WIN32 */ - -#endif /* WIN32PORTS_STRINGS_H */ diff --git a/lib/miniposix/unistd/unistd.h b/lib/miniposix/unistd/unistd.h deleted file mode 100644 index a7a088c4..00000000 --- a/lib/miniposix/unistd/unistd.h +++ /dev/null @@ -1,265 +0,0 @@ -/* -MIT License -Copyright (c) 2019 win32ports -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#ifndef WIN32PORTS_UNISTD_H -#define WIN32PORTS_UNISTD_H - -#ifndef _WIN32 - -#pragma message("this unistd.h implementation is for Windows only!") - -#else -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#include - -#ifndef _INC_IO -#include /* _access() */ -#endif /* _INC_IO */ - -#ifndef _INC_DIRECT -#include /* _chdir() */ -#endif /* _INC_DIRECT */ - -#ifndef _INC_PROCESS -#include /* _execl() */ -#endif /* _INC_PROCESS */ - -#include /* */ - -#include - -#ifndef R_OK -#define R_OK 04 -#endif /* R_OK */ - -#ifndef W_OK -#define W_OK 02 -#endif /* W_OK */ - -#ifndef X_OK -#define X_OK R_OK -#endif /* X_OK */ - -#ifndef F_OK -#define F_OK 00 -#endif /* F_OK */ - -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif /* STDIN_FILENO */ - -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif /* STDOUT_FILENO */ - -#ifndef STDERR_FILENO -#define STDERR_FILENO 2 -#endif /* STDERR_FILENO */ - -/* permission bits below must be defined in sys/stat.h, but MSVC lacks them */ - -#ifndef S_IRWXU -#define S_IRWXU 0700 -#endif /* S_IRWXU */ - -#ifndef S_IRUSR -#define S_IRUSR 0400 -#endif /* S_IRUSR */ - -#ifndef S_IWUSR -#define S_IWUSR 0200 -#endif /* S_IWUSR */ - -#ifndef S_IXUSR -#define S_IXUSR 0100 -#endif /* S_IXUSR */ - -#ifndef S_IRWXG -#define S_IRWXG 070 -#endif /* S_IRWXG */ - -#ifndef S_IRGRP -#define S_IRGRP 040 -#endif /* S_IRGRP */ - -#ifndef S_IWGRP -#define S_IWGRP 020 -#endif /* S_IWGRP */ - -#ifndef S_IXGRP -#define S_IXGRP 010 -#endif /* S_IXGRP */ - -#ifndef S_IRWXO -#define S_IRWXO 07 -#endif /* S_IRWXO */ - -#ifndef S_IROTH -#define S_IROTH 04 -#endif /* S_IROTH */ - -#ifndef S_IWOTH -#define S_IWOTH 02 -#endif /* S_IWOTH */ - -#ifndef S_IXOTH -#define S_IXOTH 01 -#endif /* S_IXOTH */ - -#ifndef S_ISUID -#define S_ISUID 04000 -#endif /* S_ISUID */ - -#ifndef S_ISGID -#define S_ISGID 02000 -#endif /* S_ISGID */ - -#ifndef S_ISVTX -#define S_ISVTX 01000 -#endif /* S_ISVTX */ - -#ifndef S_IRWXUGO -#define S_IRWXUGO 0777 -#endif /* S_IRWXUGO */ - -#ifndef S_IALLUGO -#define S_IALLUGO 0777 -#endif /* S_IALLUGO */ - -#ifndef S_IRUGO -#define S_IRUGO 0444 -#endif /* S_IRUGO */ - -#ifndef S_IWUGO -#define S_IWUGO 0222 -#endif /* S_IWUGO */ - -#ifndef S_IXUGO -#define S_IXUGO 0111 -#endif /* S_IXUGO */ - -#ifndef _S_IFMT -#define _S_IFMT 0xF000 -#endif /* _S_IFMT */ - -#ifndef _S_IFIFO -#define _S_IFIFO 0x1000 -#endif /* _S_IFIFO */ - -#ifndef _S_IFCHR -#define _S_IFCHR 0x2000 -#endif /* _S_IFCHR */ - -#ifndef _S_IFDIR -#define _S_IFDIR 0x4000 -#endif /* _S_IFDIR */ - -#ifndef _S_IFBLK -#define _S_IFBLK 0x6000 -#endif /* _S_IFBLK */ - -#ifndef _S_IFREG -#define _S_IFREG 0x8000 -#endif /* _S_IFREG */ - -#ifndef _S_IFLNK -#define _S_IFLNK 0xA000 -#endif /* _S_IFLNK */ - -#ifndef _S_IFSOCK -#define _S_IFSOCK 0xC000 -#endif /* _S_IFSOCK */ - -#ifndef S_IFMT -#define S_IFMT _S_IFMT -#endif /* S_IFMT */ - -#ifndef S_IFIFO -#define S_IFIFO _S_IFIFO -#endif /* S_IFIFO */ - -#ifndef S_IFCHR -#define S_IFCHR _S_IFCHR -#endif /* S_IFCHR */ - -#ifndef S_IFDIR -#define S_IFDIR _S_IFDIR -#endif /* S_IFDIR */ - -#ifndef S_IFBLK -#define S_IFBLK _S_IFBLK -#endif /* S_IFBLK */ - -#ifndef S_IFREG -#define S_IFREG _S_IFREG -#endif /* S_IFREG */ - -#ifndef S_IFLNK -#define S_IFLNK _S_IFLNK -#endif /* S_IFLNK */ - -#ifndef S_IFSOCK -#define S_IFSOCK _S_IFSOCK -#endif /* S_IFSOCK */ - -#ifndef S_ISTYPE -#define S_ISTYPE(mode, mask) (((mode)&S_IFMT) == (mask)) -#endif /* S_ISTYPE */ - -#ifndef S_ISFIFO -#define S_ISFIFO(mode) S_ISTYPE(mode, S_IFIFO) -#endif /* S_ISFIFO */ - -#ifndef S_ISCHR -#define S_ISCHR(mode) S_ISTYPE(mode, S_IFCHR) -#endif /* S_ISCHR */ - -#ifndef S_ISDIR -#define S_ISDIR(mode) S_ISTYPE(mode, S_IFDIR) -#endif /* S_ISDIR */ - -#ifndef S_ISBLK -#define S_ISBLK(mode) S_ISTYPE(mode, S_IFBLK) -#endif /* S_ISBLK */ - -#ifndef S_ISREG -#define S_ISREG(mode) S_ISTYPE(mode, S_IFREG) -#endif /* S_ISREG */ - -#ifndef S_ISLNK -#define S_ISLNK(mode) S_ISTYPE(mode, S_IFLNK) -#endif /* S_ISLNK */ - -#ifndef S_ISSOCK -#define S_ISSOCK(mode) S_ISTYPE(mode, S_IFSOCK) -#endif /* S_ISSOCK */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _WIN32 */ - -#endif /* WIN32PORTS_UNISTD_H */ diff --git a/src/harness/renderers/gl/gl_renderer.c b/src/harness/renderers/gl/gl_renderer.c index b1dbb2a8..1f7590ff 100644 --- a/src/harness/renderers/gl/gl_renderer.c +++ b/src/harness/renderers/gl/gl_renderer.c @@ -421,13 +421,12 @@ void build_model(br_model* model) { } glGenVertexArrays(1, &ctx->vao_id); - GLuint vbo_id; - glGenBuffers(1, &vbo_id); + glGenBuffers(1, &ctx->vbo_id); glGenBuffers(1, &ctx->ebo_id); - // Vertices } + // Vertices glBindVertexArray(ctx->vao_id); - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBindBuffer(GL_ARRAY_BUFFER, ctx->vbo_id); glBufferData(GL_ARRAY_BUFFER, sizeof(fmt_vertex) * total_verts, verts, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(fmt_vertex), (void*)offsetof(fmt_vertex, p)); glEnableVertexAttribArray(0); @@ -443,6 +442,7 @@ void build_model(br_model* model) { free(verts); free(indices); + model->stored = ctx; CHECK_GL_ERROR("after build model"); @@ -485,6 +485,7 @@ void GLRenderer_Model(br_actor* actor, br_model* model, br_matrix34 model_matrix if (ctx == NULL) { build_model(model); ctx = model->stored; + // DebugCamera_SetPosition(model_matrix.m[3][0], model_matrix.m[3][1], model_matrix.m[3][2]); } CHECK_GL_ERROR("rm1"); diff --git a/src/harness/renderers/gl/stored_context.c b/src/harness/renderers/gl/stored_context.c index 1853fe76..3bdf2ce7 100644 --- a/src/harness/renderers/gl/stored_context.c +++ b/src/harness/renderers/gl/stored_context.c @@ -5,6 +5,7 @@ void _free(br_object* o) { tStored_model_context* ctx = (tStored_model_context*)o; glDeleteVertexArrays(1, &ctx->vao_id); + glDeleteBuffers(1, &ctx->vbo_id); glDeleteBuffers(1, &ctx->ebo_id); free(o); } diff --git a/src/harness/renderers/gl/stored_context.h b/src/harness/renderers/gl/stored_context.h index 9665a070..3f134399 100644 --- a/src/harness/renderers/gl/stored_context.h +++ b/src/harness/renderers/gl/stored_context.h @@ -6,7 +6,7 @@ typedef struct tStored_model_context { br_object_dispatch* dispatch; - GLuint vao_id, ebo_id; + GLuint vao_id, vbo_id, ebo_id; } tStored_model_context; typedef struct tStored_pixelmap { From aaa3e7e54fe84ec5444041bbeadccb277fbab68a Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 21 Mar 2022 12:06:47 +1300 Subject: [PATCH 27/28] cmake tidy --- docs/PORTING.md | 11 +++++++---- src/harness/CMakeLists.txt | 9 +++++---- src/harness/include/harness/os.h | 18 ++++-------------- src/harness/os/windows.c | 8 ++++---- test/CMakeLists.txt | 2 +- 5 files changed, 21 insertions(+), 27 deletions(-) diff --git a/docs/PORTING.md b/docs/PORTING.md index b8d2fe12..b084e9c3 100644 --- a/docs/PORTING.md +++ b/docs/PORTING.md @@ -7,10 +7,13 @@ See: xxx Assuming an operating system called _foo_, follow the steps to add support for it. 1. Add a new file `os/foo.h` and implement the required functions defined in `os.h`: - +- `OS_GetTime` +- `OS_Sleep` +- `OS_Basename` +- `OS_GetFirstFileInDirectory` +- `OS_GetNextFileInDirectory` - `OS_IsDebuggerPresent` - `OS_InstallSignalHandler` -- `OS_PrintStacktrace` 2. Update `src/harness/CMakeLists.h` and add a new conditional section for "os/foo.h", based on existing conditions for Windows, MacOS etc. @@ -46,7 +49,7 @@ To add a new `IOPlatform`: For example: ``` -if (RENDERER_PLATFORM STREQUAL "My_Platform") +if (IO_PLATFORM STREQUAL "My_Platform") target_sources(harness PRIVATE io_platforms/my_platform.c ) @@ -56,7 +59,7 @@ endif() 3. Run cmake to update your build with the new platform ```sh cd build -cmake -DRENDERER_PLATFORM=My_Platform .. +cmake -DIO_PLATFORM=My_Platform .. ``` 4. Build diff --git a/src/harness/CMakeLists.txt b/src/harness/CMakeLists.txt index 0cbb61c9..5168b074 100644 --- a/src/harness/CMakeLists.txt +++ b/src/harness/CMakeLists.txt @@ -1,7 +1,7 @@ add_library(harness STATIC) -if (NOT DEFINED RENDERER_PLATFORM) - set(RENDERER_PLATFORM "SDL_OpenGL") +if (NOT DEFINED IO_PLATFORM) + set(IO_PLATFORM "SDL_OpenGL") endif() target_include_directories(harness @@ -13,7 +13,7 @@ target_include_directories(harness include ) -target_link_libraries(harness PRIVATE brender SDL2::SDL2 glad s3 cglm_headers) +target_link_libraries(harness PRIVATE brender s3 cglm_headers) if(WIN32) target_link_libraries(harness PRIVATE dbghelp) @@ -50,7 +50,7 @@ target_sources(harness PRIVATE sound/sound.h ) -if (RENDERER_PLATFORM STREQUAL "SDL_OpenGL") +if (IO_PLATFORM STREQUAL "SDL_OpenGL") target_sources(harness PRIVATE io_platforms/sdl_gl.c renderers/gl/gl_renderer.c @@ -60,6 +60,7 @@ if (RENDERER_PLATFORM STREQUAL "SDL_OpenGL") renderers/gl/stored_context.c renderers/gl/stored_context.h ) + target_link_libraries(harness PRIVATE SDL2::SDL2 glad) endif() if(WIN32) diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h index dbd1d6f7..52ab9386 100644 --- a/src/harness/include/harness/os.h +++ b/src/harness/include/harness/os.h @@ -22,29 +22,19 @@ #include #endif -// #if defined(_WIN32) || defined(_WIN64) -// #define snprintf _snprintf -// #define vsnprintf _vsnprintf -// #define strcasecmp _stricmp -// #define strncasecmp _strnicmp -// #else -// #include -// #endif - -// Required - // Required: return timestamp in milliseconds. uint32_t OS_GetTime(void); +// Required: sleep for specified milliseconds +void OS_Sleep(int ms); + // Required: begin a directory iteration and return name of first file char* OS_GetFirstFileInDirectory(char* path); // Required: continue directory iteration. If no more files, return NULL char* OS_GetNextFileInDirectory(void); -// Required: sleep for specified milliseconds -void OS_Sleep(int ms); - +// Required: copy the `basename` component of `path` into `base` void OS_Basename(char* path, char* base); // Optional: return true if a debugger is detected diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 098417fb..0b5e6f0e 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -31,10 +31,6 @@ LARGE_INTEGER qpc_ticks_per_sec; HANDLE directory_handle = NULL; char last_found_file[260]; -void OS_Sleep(int delay_ms) { - Sleep(delay_ms); -} - uint32_t OS_GetTime() { LARGE_INTEGER now; if (qpc_start_time.QuadPart == 0) { @@ -46,6 +42,10 @@ uint32_t OS_GetTime() { return (uint32_t)(((now.QuadPart - qpc_start_time.QuadPart) * 1000) / qpc_ticks_per_sec.QuadPart); } +void OS_Sleep(int delay_ms) { + Sleep(delay_ms); +} + char* OS_GetFirstFileInDirectory(char* path) { char with_extension[256]; WIN32_FIND_DATA find_data; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3d1b34ef..1dbf5950 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,7 +1,7 @@ add_executable(dethrace_test) add_test(NAME test_dethrace COMMAND dethrace_test) -set(RENDERER_PLATFORM "SDL_OpenGL2") +set(IO_PLATFORM "SDL_OpenGL") target_link_libraries(dethrace_test PRIVATE glad dethrace_obj) From 49e7b592530de32f49c0ab8ac6f545f8c92a9b2a Mon Sep 17 00:00:00 2001 From: Dethrace Labs Date: Mon, 21 Mar 2022 12:09:47 +1300 Subject: [PATCH 28/28] remove watcom files --- src/DETHRACE/watcom_functions.c | 26 -------------------------- src/DETHRACE/watcom_functions.h | 6 ------ 2 files changed, 32 deletions(-) delete mode 100644 src/DETHRACE/watcom_functions.c delete mode 100644 src/DETHRACE/watcom_functions.h diff --git a/src/DETHRACE/watcom_functions.c b/src/DETHRACE/watcom_functions.c deleted file mode 100644 index b8f75887..00000000 --- a/src/DETHRACE/watcom_functions.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "watcom_functions.h" - -#include -#include -#include -#include - -#if defined(_WIN32) || defined(_WIN64) -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#define strcasecmp _stricmp -#define strncasecmp _strnicmp -#else -#include -#endif - -void splitpath(char* path, char* drive, char* dir, char* fname, char* ext) { -#if defined(_WIN32) || defined(_WIN64) - _splitpath(path, drive, dir, fname, ext); -#else - // shortcut - we only ever call this method asking for 'fname' - // 9 is hardcoded to match `basename` defined in `Usage` - strncpy(fname, basename(path), 9); - -#endif -} diff --git a/src/DETHRACE/watcom_functions.h b/src/DETHRACE/watcom_functions.h deleted file mode 100644 index e627db45..00000000 --- a/src/DETHRACE/watcom_functions.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _WATCOM_FUNCTIONS_H_ -#define _WATCOM_FUNCTIONS_H_ - -void splitpath(char* path, char* drive, char* dir, char* fname, char* ext); - -#endif