From ef9e4d668d799ab31b998a8e7877e36c8af4fe44 Mon Sep 17 00:00:00 2001 From: Dethrace Engineering Department <78985374+dethrace-labs@users.noreply.github.com> Date: Tue, 18 Apr 2023 22:50:05 +1200 Subject: [PATCH] Implements win95sys.c (#301) * refactor to use win95sys instead of dossys * added underscore to avoid conflict with windows functions --- docs/PORTING.md | 27 +- src/BRSRC13/CORE/FW/devsetup.c | 4 +- src/BRSRC13/CORE/V1DB/prepmap.c | 8 +- src/BRSRC13/CORE/V1DB/prepmatl.c | 5 +- src/BRSRC13/CORE/V1DB/prepmesh.c | 3 +- src/BRSRC13/CORE/V1DB/render.c | 20 +- src/DETHRACE/CMakeLists.txt | 5 +- src/DETHRACE/common/cutscene.c | 15 +- src/DETHRACE/common/errors.h | 6 +- src/DETHRACE/common/flicplay.c | 16 +- src/DETHRACE/common/graphics.c | 10 +- src/DETHRACE/common/init.c | 1 + src/DETHRACE/common/sound.c | 5 + src/DETHRACE/constants.h | 2 +- src/DETHRACE/dr_types.h | 356 +++--- src/DETHRACE/main.c | 6 +- src/DETHRACE/pc-dos/dosnet.c | 55 +- src/DETHRACE/pc-dos/dossys.c | 329 +---- src/DETHRACE/pc-win95/dinput.h | 153 +++ src/DETHRACE/pc-win95/ssdx.c | 64 + src/DETHRACE/pc-win95/ssdx.h | 18 + src/DETHRACE/pc-win95/win95sys.c | 1131 +++++++++++++++++ src/DETHRACE/pd/net.h | 18 +- src/DETHRACE/pd/sys.h | 48 +- src/S3/s3_defs.h | 4 +- src/S3/s3sound.c | 9 +- src/harness/CMakeLists.txt | 12 +- src/harness/harness.c | 129 +- src/harness/harness.h | 6 +- src/harness/include/harness/hooks.h | 82 +- src/harness/include/harness/os.h | 21 - src/harness/include/harness/trace.h | 5 +- src/harness/include/harness/win95_polyfill.h | 88 ++ .../include/harness/win95_polyfill_defs.h | 72 ++ src/harness/io_platforms/io_platform.h | 16 - src/harness/io_platforms/sdl_gl.c | 339 ----- src/harness/os/linux.c | 109 -- src/harness/os/macos.c | 114 -- src/harness/os/windows.c | 146 --- src/harness/platforms/null.h | 83 ++ .../platforms/sdl2_scancode_to_dinput.h | 392 ++++++ src/harness/platforms/sdl_opengl.c | 247 ++++ src/harness/renderers/gl/gl_renderer.c | 53 +- src/harness/renderers/gl/gl_renderer.h | 9 +- src/harness/renderers/null.h | 47 - src/harness/renderers/renderer.h | 29 - src/harness/resources/framebuffer_frag.glsl | 2 +- src/harness/win95/polyfill.c | 249 ++++ test/DETHRACE/test_controls.c | 4 +- test/DETHRACE/test_input.c | 3 +- test/main.c | 5 +- test/tests.h | 1 + 52 files changed, 2996 insertions(+), 1585 deletions(-) create mode 100644 src/DETHRACE/pc-win95/dinput.h create mode 100644 src/DETHRACE/pc-win95/ssdx.c create mode 100644 src/DETHRACE/pc-win95/ssdx.h create mode 100644 src/DETHRACE/pc-win95/win95sys.c create mode 100644 src/harness/include/harness/win95_polyfill.h create mode 100644 src/harness/include/harness/win95_polyfill_defs.h delete mode 100644 src/harness/io_platforms/io_platform.h delete mode 100644 src/harness/io_platforms/sdl_gl.c create mode 100644 src/harness/platforms/null.h create mode 100644 src/harness/platforms/sdl2_scancode_to_dinput.h create mode 100644 src/harness/platforms/sdl_opengl.c delete mode 100644 src/harness/renderers/null.h delete mode 100644 src/harness/renderers/renderer.h create mode 100644 src/harness/win95/polyfill.c diff --git a/docs/PORTING.md b/docs/PORTING.md index 545f7dc5..32374300 100644 --- a/docs/PORTING.md +++ b/docs/PORTING.md @@ -5,13 +5,9 @@ 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](https://github.com/dethrace-labs/dethrace/blob/main/src/harness/include/harness/os.h): -- `OS_GetTime` -- `OS_Sleep` -- `OS_Basename` -- `OS_GetFirstFileInDirectory` -- `OS_GetNextFileInDirectory` -- `OS_IsDebuggerPresent` - `OS_InstallSignalHandler` +- `OS_fopen` +- `OS_ConsoleReadPassword` 2. Update `src/harness/CMakeLists.h` and add a new conditional section for "os/foo.h", based on existing conditions for Windows, MacOS etc. @@ -28,24 +24,13 @@ target_sources(harness PRIVATE ## IO Platform (windowing / input / rendering) -An `IOPlatform` in _dethrace_ implements windowing and input handling, and points to a _renderer_. +A `Platform` in _dethrace_ implements windowing, rendering and input handling. -The default IO platform is `SDL_OpenGL`, which uses SDL for windowing and input, and OpenGL for rendering. See [io_platforms/sdl_gl.c](https://github.com/dethrace-labs/dethrace/blob/main/src/harness/io_platforms/sdl_gl.c). +The default platform is `SDL_OpenGL`, which uses SDL for windowing and input, and OpenGL for rendering. See [platforms/sdl_opengl.c](https://github.com/dethrace-labs/dethrace/blob/main/src/harness/platforms/sdl_opengl.c). -To add a new `IOPlatform`: +To add a new `Platform`: -1. Create `io_platforms/my_platform.c` file and implement the required functions defined in [io_platforms/io_platform.h](https://github.com/dethrace-labs/dethrace/blob/main/src/harness/io_platforms/io_platform.h): -- `IOPlatform_Init` -- `IOPlatform_CreateWindow` -- `IOPlatform_PollEvents` -- `IOPlatform_SwapWindow` -- `IOPlatform_GetKeyMap` -- `IOPlatform_IsKeyDown` -- `IOPlatform_GetMousePosition` -- `IOPlatform_GetMouseButtons` -- `IOPlatform_Shutdown` - -`IOPlatform_CreateWindow` returns a `tRenderer*`, which must implement the interface defined in [renderers/renderer.h](https://github.com/dethrace-labs/dethrace/blob/main/src/harness/renderers/renderer.h). See [renderers/gl](https://github.com/dethrace-labs/dethrace/tree/main/src/harness/renderers/gl) for an example. +1. Create `platforms/my_platform.c` file and add a `Harness_Platform_Init` function. Hook up all the function pointers using the `sdl_opengl` [implementation](https://github.com/dethrace-labs/dethrace/blob/main/src/harness/platforms/sdl_opengl.h) as a guide. 2. Add a new conditional section in `src/harness/CMakeLists.txt` for your new platform diff --git a/src/BRSRC13/CORE/FW/devsetup.c b/src/BRSRC13/CORE/FW/devsetup.c index e8942b15..3ac61128 100644 --- a/src/BRSRC13/CORE/FW/devsetup.c +++ b/src/BRSRC13/CORE/FW/devsetup.c @@ -72,12 +72,12 @@ void BrDevEndOld() { // IDA: void __cdecl BrDevPaletteSetOld(br_pixelmap *pm) void BrDevPaletteSetOld(br_pixelmap* pm) { - Harness_Hook_BrDevPaletteSetOld(pm); + NOT_IMPLEMENTED(); } // IDA: void __cdecl BrDevPaletteSetEntryOld(int i, br_colour colour) void BrDevPaletteSetEntryOld(int i, br_colour colour) { - Harness_Hook_BrDevPaletteSetEntryOld(i, colour); + NOT_IMPLEMENTED(); } // IDA: br_error __cdecl BrRendererFacilityFind(br_renderer_facility **prf, br_device_pixelmap *destination, br_token scalar_type) diff --git a/src/BRSRC13/CORE/V1DB/prepmap.c b/src/BRSRC13/CORE/V1DB/prepmap.c index a694cebe..483cbb64 100644 --- a/src/BRSRC13/CORE/V1DB/prepmap.c +++ b/src/BRSRC13/CORE/V1DB/prepmap.c @@ -11,9 +11,13 @@ void BrMapUpdate(br_pixelmap* map, br_uint_16 flags) { void BrBufferUpdate(br_pixelmap* pm, br_token use, br_uint_16 flags) { br_token_value tv[3]; - Harness_Hook_BrBufferUpdate(pm, use, flags); - // renderer->dispatch->bufferStoredNew ... + + // Added by dethrace + if (use != BRT_COLOUR_MAP_O && use != BRT_UNKNOWN) { + LOG_PANIC("use %d", use); + } + gHarness_platform.Renderer_BufferTexture(pm); } // IDA: void __usercall BrBufferClear(br_pixelmap *pm@) diff --git a/src/BRSRC13/CORE/V1DB/prepmatl.c b/src/BRSRC13/CORE/V1DB/prepmatl.c index 6a8d200d..34d681de 100644 --- a/src/BRSRC13/CORE/V1DB/prepmatl.c +++ b/src/BRSRC13/CORE/V1DB/prepmatl.c @@ -9,9 +9,10 @@ void BrMaterialUpdate(br_material* mat, br_uint_16 flags) { br_token t; br_int_32 c; - //TODO: ? + // TODO: ? - Harness_Hook_BrMaterialUpdate(mat, flags); + // Added by dethrace + gHarness_platform.Renderer_BufferMaterial(mat); } // IDA: void __usercall BrMaterialClear(br_material *mat@) diff --git a/src/BRSRC13/CORE/V1DB/prepmesh.c b/src/BRSRC13/CORE/V1DB/prepmesh.c index 2616d884..719e1e7d 100644 --- a/src/BRSRC13/CORE/V1DB/prepmesh.c +++ b/src/BRSRC13/CORE/V1DB/prepmesh.c @@ -700,7 +700,8 @@ void BrModelUpdate(br_model* model, br_uint_16 flags) { model->stored = NULL; } - Harness_Hook_BrModelUpdate(model); + // Added by dethrace + gHarness_platform.Renderer_BufferModel(model); } // IDA: void __usercall BrModelClear(br_model *model@) diff --git a/src/BRSRC13/CORE/V1DB/render.c b/src/BRSRC13/CORE/V1DB/render.c index 0c23a25c..d8eea597 100644 --- a/src/BRSRC13/CORE/V1DB/render.c +++ b/src/BRSRC13/CORE/V1DB/render.c @@ -269,13 +269,13 @@ void BrDbSceneRenderBegin(br_actor* world, br_actor* camera) { // this is not complete STUB_ONCE(); -/* - * Collect transforms from camera to root - * - * Make a stack of cumulative transforms for each level between - * the camera and the root - this is so that model->view - * transforms can use the shortest route, rather than via the root - */ + /* + * Collect transforms from camera to root + * + * Make a stack of cumulative transforms for each level between + * the camera and the root - this is so that model->view + * transforms can use the shortest route, rather than via the root + */ for (i = 0; i < BR_ASIZE(v1db.camera_path); i++) { v1db.camera_path[i].a = NULL; } @@ -323,7 +323,7 @@ void BrZbSceneRenderBegin(br_actor* world, br_actor* camera, br_pixelmap* colour // LOG_TRACE("(%p, %p, %p, %p)", world, camera, colour_buffer, depth_buffer); BrDbSceneRenderBegin(world, camera); - Harness_Hook_BrZbSceneRenderBegin(world, camera, colour_buffer, depth_buffer); + gHarness_platform.Renderer_BeginScene(camera, colour_buffer, depth_buffer); } // IDA: void __cdecl BrZbSceneRenderAdd(br_actor *tree) @@ -335,7 +335,9 @@ void BrZbSceneRenderAdd(br_actor* tree) { // IDA: void __cdecl BrZbSceneRenderEnd() void BrZbSceneRenderEnd() { // LOG_TRACE("()"); - Harness_Hook_BrZbSceneRenderEnd(); + + gHarness_platform.Renderer_FlushBuffers(); + gHarness_platform.Renderer_EndScene(); } // IDA: void __cdecl BrZbSceneRender(br_actor *world, br_actor *camera, br_pixelmap *colour_buffer, br_pixelmap *depth_buffer) diff --git a/src/DETHRACE/CMakeLists.txt b/src/DETHRACE/CMakeLists.txt index 45c739c4..37c265b6 100644 --- a/src/DETHRACE/CMakeLists.txt +++ b/src/DETHRACE/CMakeLists.txt @@ -13,7 +13,6 @@ target_include_directories(dethrace_obj target_link_libraries(dethrace_obj PUBLIC SDL2::SDL2 smacker harness brender s3) - if (CMAKE_C_COMPILER_ID MATCHES "MSVC") target_compile_definitions(dethrace_obj PRIVATE -D_CRT_SECURE_NO_WARNINGS) target_compile_options(dethrace_obj PRIVATE @@ -158,6 +157,10 @@ target_sources(dethrace_obj PRIVATE pd/net.h pc-dos/dossys.c pd/sys.h + pc-win95/win95sys.c + pc-win95/dinput.h + pc-win95/ssdx.c + pc-win95/ssdx.h ) # Create our main game binary. diff --git a/src/DETHRACE/common/cutscene.c b/src/DETHRACE/common/cutscene.c index 2d41a9dc..f72adb3c 100644 --- a/src/DETHRACE/common/cutscene.c +++ b/src/DETHRACE/common/cutscene.c @@ -6,6 +6,7 @@ #include "globvrpb.h" #include "graphics.h" #include "harness/config.h" +#include "harness/hooks.h" #include "harness/os.h" #include "harness/trace.h" #include "input.h" @@ -72,7 +73,7 @@ void PlaySmackerFile(char* pSmack_name) { unsigned long w, h, f; unsigned char r, g, b; double usf; - struct timespec ts; + tU32 last_frame_time; if (!gSound_override && !gCut_scene_override) { StopMusic(); @@ -126,12 +127,16 @@ void PlaySmackerFile(char* pSmack_name) { } } PDScreenBufferSwap(0); - - if (AnyKeyDown() || EitherMouseButtonDown()) { + last_frame_time = PDGetTotalTime(); + + do { + fuck_off = AnyKeyDown() || EitherMouseButtonDown(); + // added by dethrace to avoid 100% cpu + gHarness_platform.Sleep(1); + } while (!fuck_off && PDGetTotalTime() - last_frame_time < delay_ms); + if (fuck_off) { break; } - // wait until its time for the next frame - OS_Sleep(delay_ms); } while (smk_next(s) == SMK_MORE); smk_close(s); diff --git a/src/DETHRACE/common/errors.h b/src/DETHRACE/common/errors.h index 2752835a..0c2ea871 100644 --- a/src/DETHRACE/common/errors.h +++ b/src/DETHRACE/common/errors.h @@ -2,15 +2,15 @@ #define _ERRORS_H_ #include "brender/br_types.h" -#include "harness/compiler.h" #include "dr_types.h" +#include "harness/compiler.h" extern char* gError_messages[126]; extern int gError_code; -extern char* gPalette_copy__errors; // suffix added to avoid duplicate symbol +extern char* gPalette_copy__errors; // suffix added to avoid duplicate symbol extern int gPixel_buffer_size__errors; // suffix added to avoid duplicate symbol extern int gMouse_was_started__errors; // suffix added to avoid duplicate symbol -extern char* gPixels_copy__errors; // suffix added to avoid duplicate symbol +extern char* gPixels_copy__errors; // suffix added to avoid duplicate symbol HARNESS_NORETURN void FatalError(int pStr_index, ...); diff --git a/src/DETHRACE/common/flicplay.c b/src/DETHRACE/common/flicplay.c index 8b0ae041..a7081a4e 100644 --- a/src/DETHRACE/common/flicplay.c +++ b/src/DETHRACE/common/flicplay.c @@ -1136,12 +1136,12 @@ void DoBlack(tFlic_descriptor* pFlic_info, tU32 chunk_length) { the_row_bytes = pFlic_info->the_pixelmap->row_bytes; the_width = pFlic_info->width; for (i = 0; i < pFlic_info->height; i++) { - line_pixel_ptr = (tU32*)pixel_ptr; - for (j = 0; j < the_width / sizeof(tU32); j++) { - *line_pixel_ptr = 0; - line_pixel_ptr++; - } - pixel_ptr += the_row_bytes; + line_pixel_ptr = (tU32*)pixel_ptr; + for (j = 0; j < the_width / sizeof(tU32); j++) { + *line_pixel_ptr = 0; + line_pixel_ptr++; + } + pixel_ptr += the_row_bytes; } } @@ -1268,7 +1268,7 @@ void DoUncompressedTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) { for (i = 0; i < pFlic_info->height; i++) { line_pixel_ptr = pixel_ptr; for (j = 0; j < the_width; j++) { -#if defined (DETHRACE_FIX_BUGS) +#if defined(DETHRACE_FIX_BUGS) the_byte = MemReadU8(&pFlic_info->data); #else the_byte = MemReadU32(&pFlic_info->data); @@ -1465,13 +1465,13 @@ int PlayFlic(int pIndex, tU32 pSize, tS8* pData_ptr, br_pixelmap* pDest_pixelmap gSound_time = 0; } if (frame_period >= the_flic.frame_period) { + last_frame = new_time; finished_playing = PlayNextFlicFrame(&the_flic); DoPerFrame(); if (!gDark_mode) { EnsurePaletteUp(); } ServiceGame(); - last_frame = new_time; } } ServiceGame(); diff --git a/src/DETHRACE/common/graphics.c b/src/DETHRACE/common/graphics.c index 31e60502..38a61550 100644 --- a/src/DETHRACE/common/graphics.c +++ b/src/DETHRACE/common/graphics.c @@ -637,7 +637,7 @@ void ScreenLarger() { // IDA: void __usercall DRSetPaletteEntries(br_pixelmap *pPalette@, int pFirst_colour@, int pCount@) void DRSetPaletteEntries(br_pixelmap* pPalette, int pFirst_colour, int pCount) { LOG_TRACE("(%p, %d, %d)", pPalette, pFirst_colour, pCount); - if (!pFirst_colour) { + if (pFirst_colour == 0) { ((br_int_32*)pPalette->pixels)[0] = 0; } memcpy(gCurrent_palette_pixels + 4 * pFirst_colour, (char*)pPalette->pixels + 4 * pFirst_colour, 4 * pCount); @@ -1671,7 +1671,7 @@ void RenderAFrame(int pDepth_mask_on) { RenderLollipops(); // dethrace: must flush gpu buffer before rendering depth effect into framebuffer - Harness_Hook_FlushRenderer(); + gHarness_platform.Renderer_FlushBuffers(); DepthEffectSky(gRender_screen, gDepth_buffer, gCamera, &gCamera_to_world); DepthEffect(gRender_screen, gDepth_buffer, gCamera, &gCamera_to_world); if (!gAusterity_mode) { @@ -1679,7 +1679,7 @@ void RenderAFrame(int pDepth_mask_on) { } RenderSplashes(); // dethrace: must flush gpu buffer before rendering smoke into framebuffer - Harness_Hook_FlushRenderer(); + gHarness_platform.Renderer_FlushBuffers(); RenderSmoke(gRender_screen, gDepth_buffer, gCamera, &gCamera_to_world, gFrame_period); RenderSparks(gRender_screen, gDepth_buffer, gCamera, &gCamera_to_world, gFrame_period); RenderProximityRays(gRender_screen, gDepth_buffer, gCamera, &gCamera_to_world, gFrame_period); @@ -2574,10 +2574,10 @@ int DoMouseCursor() { period = 1000; } while (period <= 20) { - // Sleep 1 ms to avoid 100% CPU usage - OS_Sleep(1); this_call_time = PDGetTotalTime(); period = this_call_time - last_call_time; + // added by dethrace to avoid 100% CPU usage + gHarness_platform.Sleep(1); } GetMousePosition(&x_coord, &y_coord); mouse_moved = x_coord != gMouse_last_x_coord || y_coord != gMouse_last_y_coord; diff --git a/src/DETHRACE/common/init.c b/src/DETHRACE/common/init.c index 8188786a..c6f54cd5 100644 --- a/src/DETHRACE/common/init.c +++ b/src/DETHRACE/common/init.c @@ -362,6 +362,7 @@ void InitialiseApplication(int pArgc, char** pArgv) { FatalError(kFatalError_UnsupportedScreenDepth); } CalcGrafDataIndex(); + PDInitScreen(); InitializeBRenderEnvironment(); InitDRFonts(); InitBRFonts(); diff --git a/src/DETHRACE/common/sound.c b/src/DETHRACE/common/sound.c index 6a920c8e..19ce6d83 100644 --- a/src/DETHRACE/common/sound.c +++ b/src/DETHRACE/common/sound.c @@ -46,6 +46,11 @@ br_vector3 gCamera_velocity; // IDA: void __cdecl UsePathFileToDetermineIfFullInstallation() void UsePathFileToDetermineIfFullInstallation() { + // changed by dethrace for compatibility + // char line1[80]; + // char line2[80]; + // char line3[80]; + // char path_file[80]; char line1[MAX_PATH_LENGTH]; char line2[MAX_PATH_LENGTH]; char line3[MAX_PATH_LENGTH]; diff --git a/src/DETHRACE/constants.h b/src/DETHRACE/constants.h index b62bd5c7..2abdbb09 100644 --- a/src/DETHRACE/constants.h +++ b/src/DETHRACE/constants.h @@ -475,7 +475,7 @@ enum { #define FONT_LITPLAQ1 19 #define FONT_DRKPLAQ1 20 -#define MAX_PATH_LENGTH 256 +#define MAX_PATH_LENGTH 1024 #define ROLLING_LETTER_LOOP_RANDOM 96 #define PLAYER_NAME_MAX_LENGTH 13 diff --git a/src/DETHRACE/dr_types.h b/src/DETHRACE/dr_types.h index 9238cad9..7be37ac2 100644 --- a/src/DETHRACE/dr_types.h +++ b/src/DETHRACE/dr_types.h @@ -11,35 +11,34 @@ #include #include -#ifdef _WIN32 -#include -#else -typedef short SHORT; -typedef unsigned short USHORT; -typedef int INT; -typedef int BOOL; -typedef unsigned int UINT; -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef long LONG; -typedef unsigned long DWORD; -typedef BYTE* PBYTE; -typedef char* PSTR; -typedef WORD* PWORD; -typedef unsigned short* PSHORT; -typedef LONG* PLONG; -typedef void* PVOID; -typedef BYTE* LPBYTE; -typedef BYTE* LPSTR; -typedef WORD* LPWORD; -typedef LONG* LPLONG; -typedef void* LPVOID; -typedef BYTE* HPBYTE; -typedef BYTE* HPSTR; -typedef LONG* HPLONG; -typedef void* HPVOID; -typedef unsigned int HANDLE; -#endif +// #ifdef _WIN32 +// #include +// #else +// typedef short short; +// typedef unsigned short unsigned short; +// typedef int INT; +// typedef int BOOL; +// typedef unsigned int UINT; +// typedef unsigned char unsigned char; +// typedef unsigned short WORD; +// typedef long long; +// typedef unsigned long unsigned long; +// typedef unsigned char* Punsigned char; +// typedef char* char*; +// typedef WORD* PWORD; +// typedef unsigned short* Pshort; +// typedef long* Plong; +// typedef void* PVOID; +// typedef unsigned char* LPunsigned char; +// typedef unsigned char* Lchar*; +// typedef WORD* LPWORD; +// typedef long* LPlong; +// typedef void* LPVOID; +// typedef unsigned char* HPunsigned char; +// typedef unsigned char* Hchar*; +// typedef long* HPlong; +// typedef void* HPVOID; +// #endif typedef unsigned int W32; typedef unsigned short W16; typedef W32* LPW32; @@ -534,27 +533,27 @@ typedef struct _HMI_REGS { } _HMI_REGS; typedef struct _tagIPX_HEADER { - USHORT wChecksum; - USHORT wLength; - BYTE bTransportControl; - BYTE bPacketType; - BYTE bDestNetworkNumber[4]; - BYTE bDestNetworkNode[6]; - USHORT wDestNetworkSocket; - BYTE bSourceNetworkNumber[4]; - BYTE bSourceNetworkNode[6]; - USHORT wSourceNetworkSocket; + unsigned short wChecksum; + unsigned short wLength; + unsigned char bTransportControl; + unsigned char bPacketType; + unsigned char bDestNetworkNumber[4]; + unsigned char bDestNetworkNode[6]; + unsigned short wDestNetworkSocket; + unsigned char bSourceNetworkNumber[4]; + unsigned char bSourceNetworkNode[6]; + unsigned short wSourceNetworkSocket; } _IPX_HEADER; typedef struct _PACKET { - PSTR pData; - USHORT wLength; + char* pData; + unsigned short wLength; } _PACKET; typedef struct _REAL_PACKET { - SHORT wOffset; - SHORT wSegment; - USHORT wLength; + short wOffset; + short wSegment; + unsigned short wLength; } _REAL_PACKET; typedef struct _ECB_PACKET { @@ -563,52 +562,52 @@ typedef struct _ECB_PACKET { } _ECB_PACKET; typedef struct _tagIPX_ECB { - PSTR pLinkAddress; - PSTR pESRRoutine; - BYTE bInUse; - BYTE bCompletionCode; - USHORT wSocket; - USHORT wConnectionID; - USHORT wWorkSpace; - BYTE bDriverWorkSpace[12]; - BYTE bImmediateAddress[6]; - USHORT wPacketCount; + char* pLinkAddress; + char* pESRRoutine; + unsigned char bInUse; + unsigned char bCompletionCode; + unsigned short wSocket; + unsigned short wConnectionID; + unsigned short wWorkSpace; + unsigned char bDriverWorkSpace[12]; + unsigned char bImmediateAddress[6]; + unsigned short wPacketCount; _ECB_PACKET sPacket[2]; } _IPX_ECB; typedef struct _tagIPX_INTERNET_ADDR { - BYTE bNetwork[4]; - BYTE bNode[6]; + unsigned char bNetwork[4]; + unsigned char bNode[6]; } _IPX_INTERNET_ADDR; typedef struct _tagIPX_NETWORK_ADDR { _IPX_INTERNET_ADDR sInternetAddr; - BYTE bSocket[2]; + unsigned char bSocket[2]; } _IPX_NETWORK_ADDR; typedef struct _tagIPX_LOCAL_TARGET { _IPX_INTERNET_ADDR sInternetAddr; - BYTE bImmediate[6]; + unsigned char bImmediate[6]; } _IPX_LOCAL_TARGET; typedef struct _tagIPX_ELEMENT { - USHORT wFlags; - USHORT wOffset; + unsigned short wFlags; + unsigned short wOffset; _IPX_HEADER sHeader; _IPX_ECB sECB; _IPX_ECB* pECB; _IPX_HEADER* pIPXHeader; - PSTR pHeader; - USHORT wHSize; + char* pHeader; + unsigned short wHSize; } _IPX_ELEMENT; typedef struct _PROT_PTR { - PSTR pData; + char* pData; } _PROT_PTR; typedef struct _REAL_PTR { - SHORT wOffset; - SHORT wSegment; + short wOffset; + short wSegment; } _REAL_PTR; typedef struct _PTR { @@ -617,68 +616,68 @@ typedef struct _PTR { } _PTR; typedef struct _tag_NETBIOS_NCB { - BYTE bCommand; - BYTE bReturnCode; - BYTE bLocalSession; - BYTE bNetworkNameNumber; + unsigned char bCommand; + unsigned char bReturnCode; + unsigned char bLocalSession; + unsigned char bNetworkNameNumber; _PTR sPtr; - USHORT wLength; - BYTE bCallName[16]; - BYTE bName[16]; - BYTE bReceiveTimeOut; - BYTE bSendTimeOut; - PSTR pPostFunction; - BYTE bAdapter; - BYTE bCompletionCode; - BYTE bReserve[14]; + unsigned short wLength; + unsigned char bCallName[16]; + unsigned char bName[16]; + unsigned char bReceiveTimeOut; + unsigned char bSendTimeOut; + char* pPostFunction; + unsigned char bAdapter; + unsigned char bCompletionCode; + unsigned char bReserve[14]; } _NETBIOS_NCB; typedef struct _tagNETBIOS_ADAPTER_STATUS { - BYTE bCardID[6]; - BYTE bReleaseLevel; - BYTE bReserved1; - BYTE bTypeOfAdapter; - BYTE bOldOrNewParameters; - USHORT wReportingPeriodMinutes; - USHORT wFrameRejectReceivedCount; - USHORT wFrameRejectSentCount; - USHORT wReceivedDataFrameErrors; - USHORT wUnsuccessfulTransmissions; - LONG dwGoodTransmissions; - LONG dwGoodReceptions; - USHORT wRetransmissions; - USHORT wExhaustedResourceCount; - USHORT wT1TimerExpiredCount; - USHORT wTITimerExpiredCount; - BYTE bReserved2[4]; - USHORT wAvailableNCBS; - USHORT wMaxNCBSConfigured; - USHORT wMaxNCBSPossible; - USHORT wBufferOrStationBusyCount; - USHORT wMaxDatagramSize; - USHORT wPendingSessions; - USHORT wMaxSessionsConfigured; - USHORT wMaxSessionsPossible; - USHORT wMaxFrameSize; - USHORT wNameCount; + unsigned char bCardID[6]; + unsigned char bReleaseLevel; + unsigned char bReserved1; + unsigned char bTypeOfAdapter; + unsigned char bOldOrNewParameters; + unsigned short wReportingPeriodMinutes; + unsigned short wFrameRejectReceivedCount; + unsigned short wFrameRejectSentCount; + unsigned short wReceivedDataFrameErrors; + unsigned short wUnsuccessfulTransmissions; + long dwGoodTransmissions; + long dwGoodReceptions; + unsigned short wRetransmissions; + unsigned short wExhaustedResourceCount; + unsigned short wT1TimerExpiredCount; + unsigned short wTITimerExpiredCount; + unsigned char bReserved2[4]; + unsigned short wAvailableNCBS; + unsigned short wMaxNCBSConfigured; + unsigned short wMaxNCBSPossible; + unsigned short wBufferOrStationBusyCount; + unsigned short wMaxDatagramSize; + unsigned short wPendingSessions; + unsigned short wMaxSessionsConfigured; + unsigned short wMaxSessionsPossible; + unsigned short wMaxFrameSize; + unsigned short wNameCount; struct { - BYTE bName[16]; - BYTE bNameNumber; - BYTE bNameStatus; + unsigned char bName[16]; + unsigned char bNameNumber; + unsigned char bNameStatus; } sNameTable[20]; } _NETBIOS_ADAPTER_STATUS; typedef struct _tagNETBIOS_ELEMENT { - USHORT wFlags; - USHORT wOffset; + unsigned short wFlags; + unsigned short wOffset; _NETBIOS_NCB sNCB; _NETBIOS_NCB* pNCB; - PSTR pHeader; - USHORT wHSize; + char* pHeader; + unsigned short wHSize; } _NETBIOS_ELEMENT; typedef struct _tagNETBIOS_LOCAL_TARGET { - BYTE bNode[16]; + unsigned char bNode[16]; } _NETBIOS_LOCAL_TARGET; typedef struct _tagXFER_BLOCK_HEADER { @@ -2793,40 +2792,40 @@ typedef struct _tag_sos_vds_struct { } _SOS_VDS_STRUCT; typedef struct _tag_sos_sample { - PSTR pSample; - PSTR pSampleCurrent; - PSTR pSampleLoop; - DWORD wLength; - DWORD wLoopLength; - DWORD wLoopEndLength; - DWORD wLoopStage; - DWORD wID; - DWORD wFlags; - DWORD wPriority; - DWORD hSample; - DWORD wVolume; - DWORD wLoopCount; - DWORD wRate; - DWORD wBitsPerSample; - DWORD wChannels; - DWORD wFormat; - DWORD wPanPosition; - DWORD wPanSpeed; - DWORD wPanStart; - DWORD wPanEnd; - DWORD wPanMode; - DWORD wTotalBytesProcessed; + char* pSample; + char* pSampleCurrent; + char* pSampleLoop; + unsigned long wLength; + unsigned long wLoopLength; + unsigned long wLoopEndLength; + unsigned long wLoopStage; + unsigned long wID; + unsigned long wFlags; + unsigned long wPriority; + unsigned long hSample; + unsigned long wVolume; + unsigned long wLoopCount; + unsigned long wRate; + unsigned long wBitsPerSample; + unsigned long wChannels; + unsigned long wFormat; + unsigned long wPanPosition; + unsigned long wPanSpeed; + unsigned long wPanStart; + unsigned long wPanEnd; + unsigned long wPanMode; + unsigned long wTotalBytesProcessed; void (*pfnSampleProcessed)(PSOSSAMPLE*); void (*pfnSampleDone)(PSOSSAMPLE*); void (*pfnSampleLoop)(PSOSSAMPLE*); - DWORD wSystem[16]; - DWORD wUser[16]; + unsigned long wSystem[16]; + unsigned long wUser[16]; PSOSSAMPLE* pLink; PSOSSAMPLE* pNext; } _SOS_SAMPLE; typedef struct _tagCAPABILITIES { - BYTE szDeviceName[32]; + unsigned char szDeviceName[32]; W32 wDeviceVersion; W32 wBitsPerSample; W32 wChannels; @@ -2853,35 +2852,35 @@ typedef struct _SOS_HARDWARE { typedef struct _tag_sos_driver { W32 wFlags; - DWORD wDriverRate; - DWORD wDriverChannels; - DWORD wDriverBitsPerSample; - DWORD wDriverFormat; - DWORD wMixerChannels; - DWORD wDMACountRegister; - DWORD wDMAPosition; - DWORD wDMALastPosition; - DWORD wDMADistance; - PSTR pXFERPosition; - DWORD wXFERJumpAhead; + unsigned long wDriverRate; + unsigned long wDriverChannels; + unsigned long wDriverBitsPerSample; + unsigned long wDriverFormat; + unsigned long wMixerChannels; + unsigned long wDMACountRegister; + unsigned long wDMAPosition; + unsigned long wDMALastPosition; + unsigned long wDMADistance; + char* pXFERPosition; + unsigned long wXFERJumpAhead; _SOS_SAMPLE* pSampleList; void (*pfnPseudoDMAFunction)(void); - PSTR pDMABuffer; - PSTR pDMABufferEnd; - DWORD wDMABufferSize; - PSTR pMixingBuffer; - PSTR pMixingBufferEnd; - DWORD wMixingBufferSize; - DWORD wActiveChannels; + char* pDMABuffer; + char* pDMABufferEnd; + unsigned long wDMABufferSize; + char* pMixingBuffer; + char* pMixingBufferEnd; + unsigned long wMixingBufferSize; + unsigned long wActiveChannels; _SOS_SAMPLE* pSamples; _SOS_HARDWARE sHardware; _SOS_CAPABILITIES sCaps; - LPSTR lpDriverDS; - LPSTR lpDriverCS; + char* lpDriverDS; + char* lpDriverCS; W32 wSize; - DWORD dwLinear; - DWORD dwDMAPhysical; - LPSTR lpDMABuffer; + unsigned long dwLinear; + unsigned long dwDMAPhysical; + char* lpDMABuffer; W32 hMemory; W32 wDMARealSeg; W32 wID; @@ -2889,14 +2888,14 @@ typedef struct _tag_sos_driver { } _SOS_DIGI_DRIVER; typedef struct _SOS_DRV_FILEHEADER { - BYTE szName[32]; + unsigned char szName[32]; W32 wDrivers; W32 lOffset; W32 lFileSize; } _SOS_DRV_FILEHEADER; typedef struct _SOS_DRV_DRIVERHEADER { - BYTE szName[32]; + unsigned char szName[32]; W32 lNextDriver; W32 wSize; W32 wDeviceID; @@ -2905,32 +2904,31 @@ typedef struct _SOS_DRV_DRIVERHEADER { typedef struct _tag_sos_system { W32 wFlags; - BYTE szDriverPath[128]; - BYTE szTempDriverPath[128]; + unsigned char szDriverPath[128]; + unsigned char szTempDriverPath[128]; PSOSDIGIDRIVER pDriver[5]; _SOS_VDS_STRUCT sVDS; _SOS_DRV_FILEHEADER sFileHeader; _SOS_DRV_DRIVERHEADER sDriverHeader; - PSTR(*pMemAllocFunction) - (DWORD); - void (*pMemFreeFunction)(PSTR, W32); + char* (*pMemAllocFunction)(unsigned long); + void (*pMemFreeFunction)(char*, W32); } _SOS_SYSTEM; typedef struct _tag_sos_det_system { W32 wFlags; - BYTE szDriverPath[128]; - BYTE szTempDriverPath[128]; + unsigned char szDriverPath[128]; + unsigned char szTempDriverPath[128]; _SOS_DRV_FILEHEADER sFileHeader; _SOS_DRV_DRIVERHEADER sDriverHeader; _SOS_CAPABILITIES sCaps; PSOSCAPABILITIES pCaps; - LPSTR lpBufferDS; - LPSTR lpBufferCS; + char* lpBufferDS; + char* lpBufferCS; W32 hFile; - DWORD dwDriverIndex; + unsigned long dwDriverIndex; W32 wDriverIndexCur; W32 hMemory; - DWORD dwLinear; + unsigned long dwLinear; } _SOS_DET_SYSTEM; typedef struct _tag_sos_timer_system { @@ -2938,8 +2936,8 @@ typedef struct _tag_sos_timer_system { W32 wChipDivisor; void (*pfnEvent[16])(void); W32 wEventRate[16]; - DWORD dwAdditiveFraction[16]; - DWORD dwCurrentSummation[16]; + unsigned long dwAdditiveFraction[16]; + unsigned long dwCurrentSummation[16]; W32 wMIDIEventSongHandle[16]; W32 wMIDIActiveSongHandle; } _SOS_TIMER_SYSTEM; @@ -3935,7 +3933,7 @@ typedef struct BYTEREGS { unsigned short _4; } BYTEREGS; -typedef struct REGS { +typedef union REGS { DWORDREGS x; WORDREGS w; BYTEREGS h; @@ -4131,7 +4129,7 @@ typedef struct tPD_net_game_info { } tPD_net_game_info; typedef struct tIPX_netnum { - BYTE bNetwork[4]; + unsigned char bNetwork[4]; } tIPX_netnum; typedef struct tRM_info { diff --git a/src/DETHRACE/main.c b/src/DETHRACE/main.c index abc2a7fa..c84719d1 100644 --- a/src/DETHRACE/main.c +++ b/src/DETHRACE/main.c @@ -1,11 +1,13 @@ -#include "harness/hooks.h" -#include "pd/sys.h" + #include #ifdef _WIN32 #include +#include +#include #endif +extern void Harness_Init(int* argc, char* argv[]); extern int original_main(int pArgc, char* pArgv[]); int main(int argc, char* argv[]) { diff --git a/src/DETHRACE/pc-dos/dosnet.c b/src/DETHRACE/pc-dos/dosnet.c index ad80bbc4..6ec8654b 100644 --- a/src/DETHRACE/pc-dos/dosnet.c +++ b/src/DETHRACE/pc-dos/dosnet.c @@ -32,7 +32,7 @@ int gNumber_of_hosts; tRM_info RMI; _IPX_HEADER gLast_received_IPX_header; tU16 gSocket_number_network_order; -USHORT gECB_offset; +unsigned short gECB_offset; tU16 gListen_selector; tU16 gSend_selector; @@ -125,8 +125,8 @@ int BroadcastMessage() { NOT_IMPLEMENTED(); } -// IDA: BOOL __usercall hmiIPXCloseSocket@(W32 wSocket@) -BOOL hmiIPXCloseSocket(W32 wSocket) { +// IDA: int __usercall hmiIPXCloseSocket@(W32 wSocket@) +int hmiIPXCloseSocket(W32 wSocket) { REGS regs; SREGS sregs; LOG_TRACE("(%d)", wSocket); @@ -143,14 +143,14 @@ void hmiIPXListenForPacket(_IPX_ECB* pECB_ptr, tU32 pOffset) { NOT_IMPLEMENTED(); } -// IDA: BOOL __usercall hmiIPXPostListen@(_IPX_ECB *pECB_ptr@, tU32 pOffset@) -BOOL hmiIPXPostListen(_IPX_ECB* pECB_ptr, tU32 pOffset) { +// IDA: int __usercall hmiIPXPostListen@(_IPX_ECB *pECB_ptr@, tU32 pOffset@) +int hmiIPXPostListen(_IPX_ECB* pECB_ptr, tU32 pOffset) { LOG_TRACE("(%p, %d)", pECB_ptr, pOffset); NOT_IMPLEMENTED(); } -// IDA: BOOL __cdecl hmiIPXGetData(PSTR pData, tU32 wDSize) -BOOL hmiIPXGetData(PSTR pData, tU32 wDSize) { +// IDA: int __cdecl hmiIPXGetData(char* pData, tU32 wDSize) +int hmiIPXGetData(char* pData, tU32 wDSize) { tU32 packets_checked; tU32 full_packet_ooer_missus; _IPX_ECB* ECB_ptr; @@ -159,19 +159,19 @@ BOOL hmiIPXGetData(PSTR pData, tU32 wDSize) { NOT_IMPLEMENTED(); } -// IDA: void __usercall hmiIPXSendPacket(_IPX_ECB *sECB@, _IPX_ECB **pPacket@, PSTR pHeader@, W32 wSize@) -void hmiIPXSendPacket(_IPX_ECB* sECB, _IPX_ECB** pPacket, PSTR pHeader, W32 wSize) { +// IDA: void __usercall hmiIPXSendPacket(_IPX_ECB *sECB@, _IPX_ECB **pPacket@, char* pHeader@, W32 wSize@) +void hmiIPXSendPacket(_IPX_ECB* sECB, _IPX_ECB** pPacket, char* pHeader, W32 wSize) { SREGS sregs; REGS regs; _IPX_HEADER* sIPXHeader; _IPX_ECB* sIPXECB; - PSTR pIPXData; + char* pIPXData; LOG_TRACE("(%p, %p, %d, %d)", sECB, pPacket, pHeader, wSize); NOT_IMPLEMENTED(); } -// IDA: BOOL __usercall hmiIPXSendDataDirect@(PSTR pHeader@, W32 wHSize@, PSTR pData@, W32 wDSize@, _NETNOW_NODE_ADDR *sNode) -BOOL hmiIPXSendDataDirect(PSTR pHeader, W32 wHSize, PSTR pData, W32 wDSize, _NETNOW_NODE_ADDR* sNode) { +// IDA: int __usercall hmiIPXSendDataDirect@(char* pHeader@, W32 wHSize@, char* pData@, W32 wDSize@, _NETNOW_NODE_ADDR *sNode) +int hmiIPXSendDataDirect(char* pHeader, W32 wHSize, char* pData, W32 wDSize, _NETNOW_NODE_ADDR* sNode) { W32 wIndex; _IPX_ELEMENT* sElement; W32* pSequence; @@ -195,8 +195,8 @@ void hmiIPXGetLocalTarget(_IPX_LOCAL_TARGET* sNetworkAddr) { NOT_IMPLEMENTED(); } -// IDA: BOOL __usercall AllocateRealMem@(W32 wSize@, PSTR *pPtr@, W32 *pSegment@, tU16 *pSelector@) -BOOL AllocateRealMem(W32 wSize, PSTR* pPtr, W32* pSegment, tU16* pSelector) { +// IDA: int __usercall AllocateRealMem@(W32 wSize@, char* *pPtr@, W32 *pSegment@, tU16 *pSelector@) +int AllocateRealMem(W32 wSize, char** pPtr, W32* pSegment, tU16* pSelector) { REGS regs; SREGS sregs; W32 wAddress; @@ -207,8 +207,8 @@ BOOL AllocateRealMem(W32 wSize, PSTR* pPtr, W32* pSegment, tU16* pSelector) { NOT_IMPLEMENTED(); } -// IDA: BOOL __usercall FreeRealMem@(tU16 pSelector@) -BOOL FreeRealMem(tU16 pSelector) { +// IDA: int __usercall FreeRealMem@(tU16 pSelector@) +int FreeRealMem(tU16 pSelector) { REGS regs; SREGS sregs; W32 wAddress; @@ -219,16 +219,16 @@ BOOL FreeRealMem(tU16 pSelector) { NOT_IMPLEMENTED(); } -// IDA: BOOL __cdecl hmiIPXInstalled() -BOOL hmiIPXInstalled() { +// IDA: int __cdecl hmiIPXInstalled() +int hmiIPXInstalled() { SREGS sregs; REGS regs; LOG_TRACE("()"); NOT_IMPLEMENTED(); } -// IDA: BOOL __usercall hmiIPXOpenSocket@(W32 wSocket@) -BOOL hmiIPXOpenSocket(W32 wSocket) { +// IDA: int __usercall hmiIPXOpenSocket@(W32 wSocket@) +int hmiIPXOpenSocket(W32 wSocket) { SREGS sregs; REGS regs; LOG_TRACE("(%d)", wSocket); @@ -243,13 +243,13 @@ void GetLargestPacketSizeOoErBetterInsertLinfordChristieJokeHere() { NOT_IMPLEMENTED(); } -// IDA: BOOL __usercall hmiIPXInitSystem@(W32 wSocket@) -BOOL hmiIPXInitSystem(W32 wSocket) { +// IDA: int __usercall hmiIPXInitSystem@(W32 wSocket@) +int hmiIPXInitSystem(W32 wSocket) { W32 wNIndex; W32 wIndex; W32 wMIndex; - USHORT wSOffset; - USHORT wLOffset; + unsigned short wSOffset; + unsigned short wLOffset; LOG_TRACE("(%d)", wSocket); NOT_IMPLEMENTED(); } @@ -349,14 +349,15 @@ tPlayer_ID PDNetExtractPlayerID(tNet_game_details* pDetails) { // IDA: void __usercall PDNetObtainSystemUserName(char *pName@, int pMax_length@) void PDNetObtainSystemUserName(char* pName, int pMax_length) { #ifdef _WIN32 - DWORD size; + uint32_t size; char buffer[16]; - BOOL result; + int result; #endif dr_dprintf("PDNetObtainSystemUserName()\n"); -#ifdef _WIN32 + // todo +#if 0 size = COUNT_OF(buffer); result = GetComputerNameA(buffer, &size); if (result == 0) { diff --git a/src/DETHRACE/pc-dos/dossys.c b/src/DETHRACE/pc-dos/dossys.c index 9ad402df..09a9562b 100644 --- a/src/DETHRACE/pc-dos/dossys.c +++ b/src/DETHRACE/pc-dos/dossys.c @@ -24,42 +24,12 @@ #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" -#else -#define GFX_INIT_STRING_32X20X8 "320x200 init string" -#define GFX_INIT_STRING_64X48X8 "640x480 init string" -#endif int gDOSGfx_initialized; -int gExtra_mem; -int gReplay_override; -tGraf_spec gGraf_specs[2] = { - { 8, 1, 0, 320, 200, 0, 0, "32X20X8", GFX_INIT_STRING_32X20X8, 320, 320, 200, NULL }, - { 8, 1, 0, 640, 480, 0, 0, "64X48X8", GFX_INIT_STRING_64X48X8, 640, 640, 480, NULL } -}; -int gASCII_table[128]; -tU32 gKeyboard_bits[8]; -int gASCII_shift_table[128]; -char gNetwork_profile_fname[256]; -tS32 gJoystick_min1y; -tS32 gJoystick_min2y; -tS32 gJoystick_min2x; -tS32 gRaw_joystick2y; -tS32 gRaw_joystick2x; -tS32 gRaw_joystick1y; -tS32 gRaw_joystick1x; -tS32 gJoystick_range2y; -tS32 gJoystick_range2x; -tS32 gJoystick_range1y; -tS32 gJoystick_range1x; -int gNo_voodoo; -int gSwitched_resolution; -br_pixelmap* gReal_back_screen; -tS32 gJoystick_min1x; -br_pixelmap* gTemp_screen; + tU32 gUpper_loop_limit; int gReal_back_screen_locked; void (*gPrev_keyboard_handler)(); -tU8 gScan_code[123][2]; char* _unittest_last_fatal_error; @@ -74,7 +44,7 @@ void KeyboardHandler() { // IDA: int __usercall KeyDown@(tU8 pScan_code@) int KeyDown(tU8 pScan_code) { - return Harness_Hook_KeyDown(pScan_code); + NOT_IMPLEMENTED(); } // IDA: void __usercall KeyTranslation(tU8 pKey_index@, tU8 pScan_code_1@, tU8 pScan_code_2@) @@ -85,123 +55,7 @@ void KeyTranslation(tU8 pKey_index, tU8 pScan_code_1, tU8 pScan_code_2) { // IDA: void __cdecl KeyBegin() void KeyBegin() { - - // int v0; // edx@0 - // int v1; // ST00_4@1 - // __int16 v2; // dx@1 - - // *(_WORD *)gScan_code[11] = 11; - // *(_WORD *)gScan_code[13] = 3; - // *(_WORD *)gScan_code[14] = 4; - // *(_WORD *)gScan_code[12] = 2; - // *(_WORD *)gScan_code[15] = 5; - // *(_WORD *)gScan_code[17] = 7; - // *(_WORD *)gScan_code[18] = 8; - // *(_WORD *)gScan_code[16] = 6; - // *(_WORD *)gScan_code[19] = 9; - // *(_WORD *)gScan_code[21] = 30; - // *(_WORD *)gScan_code[22] = 48; - // *(_WORD *)gScan_code[20] = 10; - // *(_WORD *)gScan_code[23] = 46; - // *(_WORD *)gScan_code[25] = 18; - // *(_WORD *)gScan_code[26] = 33; - // *(_WORD *)gScan_code[24] = 32; - // *(_WORD *)gScan_code[27] = 34; - // *(_WORD *)gScan_code[29] = 23; - // *(_WORD *)gScan_code[30] = 36; - // *(_WORD *)gScan_code[28] = 35; - // *(_WORD *)gScan_code[31] = 37; - // *(_WORD *)gScan_code[33] = 50; - // *(_WORD *)gScan_code[34] = 49; - // *(_WORD *)gScan_code[32] = 38; - // *(_WORD *)gScan_code[35] = 24; - // *(_WORD *)gScan_code[37] = 16; - // *(_WORD *)gScan_code[38] = 19; - // *(_WORD *)gScan_code[36] = 25; - // *(_WORD *)gScan_code[39] = 31; - // *(_WORD *)gScan_code[41] = 22; - // *(_WORD *)gScan_code[42] = 47; - // *(_WORD *)gScan_code[40] = 20; - // *(_WORD *)gScan_code[43] = 17; - // *(_WORD *)gScan_code[44] = 45; - // *(_WORD *)gScan_code[45] = 21; - // *(_WORD *)gScan_code[46] = 44; - // *(_WORD *)gScan_code[47] = 41; - // *(_WORD *)gScan_code[48] = 12; - // *(_WORD *)gScan_code[49] = 13; - // *(_WORD *)gScan_code[50] = 14; - // *(_WORD *)gScan_code[51] = 28; - // *(_WORD *)gScan_code[52] = 156; - - // *(_WORD *)gScan_code[0] = 13866; - // *(_WORD *)gScan_code[1] = -18376; - // *(_WORD *)gScan_code[2] = -25315; - // *(_WORD *)gScan_code[3] = -25315; - // *(_WORD *)gScan_code[4] = 58; - // *(_WORD *)gScan_code[55] = 86; - // *(_WORD *)gScan_code[54] = 53; - // *(_WORD *)gScan_code[56] = 39; - // *(_WORD *)gScan_code[59] = 51; - // *(_WORD *)gScan_code[53] = 15; - // *(_WORD *)gScan_code[58] = 52; - // *(_WORD *)gScan_code[60] = 26; - // *(_WORD *)gScan_code[63] = 1; - // *(_WORD *)gScan_code[57] = 40; - // *(_WORD *)gScan_code[62] = 43; - // *(_WORD *)gScan_code[64] = 210; - // *(_WORD *)gScan_code[67] = 207; - // *(_WORD *)gScan_code[61] = 27; - // *(_WORD *)gScan_code[66] = 199; - // *(_WORD *)gScan_code[68] = 201; - // *(_WORD *)gScan_code[71] = 205; - // *(_WORD *)gScan_code[65] = 211; - // *(_WORD *)gScan_code[70] = 203; - // *(_WORD *)gScan_code[72] = 200; - // *(_WORD *)gScan_code[69] = 209; - // *(_WORD *)gScan_code[74] = 69; - // *(_WORD *)gScan_code[73] = 208; - // *(_WORD *)gScan_code[75] = 181; - // *(_WORD *)gScan_code[76] = 55; - // *(_WORD *)gScan_code[78] = 78; - // *(_WORD *)gScan_code[77] = 74; - // *(_WORD *)gScan_code[80] = 0; - // *(_WORD *)gScan_code[79] = 83; - // *(_WORD *)gScan_code[82] = 79; - // *(_WORD *)gScan_code[84] = 81; - // *(_WORD *)gScan_code[81] = 82; - // *(_WORD *)gScan_code[83] = 80; - // *(_WORD *)gScan_code[86] = 76; - // *(_WORD *)gScan_code[88] = 71; - // *(_WORD *)gScan_code[85] = 75; - // *(_WORD *)gScan_code[87] = 77; - // *(_WORD *)gScan_code[90] = 73; - // *(_WORD *)gScan_code[92] = 60; - // *(_WORD *)gScan_code[89] = 72; - // *(_WORD *)gScan_code[91] = 59; - // *(_WORD *)gScan_code[94] = 62; - // *(_WORD *)gScan_code[96] = 64; - // *(_WORD *)gScan_code[93] = 61; - // *(_WORD *)gScan_code[95] = 63; - // *(_WORD *)gScan_code[98] = 66; - // *(_WORD *)gScan_code[100] = 68; - // *(_WORD *)gScan_code[97] = 65; - // *(_WORD *)gScan_code[99] = 67; - // *(_WORD *)gScan_code[102] = 88; - // *(_WORD *)gScan_code[104] = 70; - // *(_WORD *)gScan_code[101] = 87; - // *(_WORD *)gScan_code[103] = 0; - // *(_WORD *)gScan_code[105] = 0; - // *(_WORD *)gScan_code[106] = 57; - // *(_WORD *)gScan_code[5] = 54; - // *(_WORD *)gScan_code[6] = 184; - // *(_WORD *)gScan_code[7] = 157; - // *(_WORD *)gScan_code[8] = 42; - // *(_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); + NOT_IMPLEMENTED(); } // IDA: void __cdecl KeyEnd() @@ -222,29 +76,6 @@ void PDSetKeyArray(int* pKeys, int pMark) { tS32 joyX; tS32 joyY; LOG_TRACE10("(%p, %d)", pKeys, pMark); - - Harness_Hook_PDSetKeyArray(); - - gKeys_pressed = 0; - for (i = 0; i < COUNT_OF(gScan_code); i++) { - if (KeyDown(gScan_code[i][0])) { //} || KeyDown(gScan_code[i][1])) { - gKeys_pressed = (gKeys_pressed << 8) + i + 1; - pKeys[i] = pMark; - } else if (pKeys[i] == pMark) { - pKeys[i] = 0; - } - } -} - -// IDA: int __usercall PDGetASCIIFromKey@(int pKey@) -int PDGetASCIIFromKey(int pKey) { - LOG_TRACE("(%d)", pKey); - - if (PDKeyDown(KEY_LSHIFT)) { - return gASCII_shift_table[pKey]; - } else { - return gASCII_table[pKey]; - } } // IDA: void __usercall PDFatalError(char *pThe_str@) @@ -614,8 +445,6 @@ void Usage(char* pProgpath) { // char basename[9]; char basename[256]; // fix: changed from 9 to avoid overflow on longer filenames - 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", basename, @@ -687,63 +516,6 @@ int OurGetChar() { NOT_IMPLEMENTED(); } -int CheckGorePasswordFile(char* pPassword) { - tPath_name path; - FILE* f; - char line[10]; - - PathCat(path, "DATA", "PASS.TXT"); - f = fopen(path, "rb"); - if (f == NULL) { - return 0; - } - if (fgets(line, sizeof(line), f) == NULL) { - fclose(f); - return 0; - } - fclose(f); -#if defined(DETHRACE_FIX_BUGS) - // Allow a final newline in DATA/PASS.TXT - while (strlen(line) > 0 && (line[strlen(line) - 1] == '\n' || line[strlen(line) - 1] == '\r')) { - line[strlen(line) - 1] = '\0'; - } -#endif -#ifdef _WIN32 - return stricmp(line, pPassword) == 0; -#else - return strcasecmp(line, pPassword) == 0; -#endif -} - -// IDA: int __cdecl PDGetGorePassword() -int PDGetGorePassword() { - int ch; - int len; - int chances; - char password[17]; - LOG_TRACE("()"); - - for (chances = 0; chances < 3; chances++) { - printf(chances == 0 ? "\n\n\n\n\nEnter password for uncut version...\n" : "\nIncorrect password, please try again...\n"); - OS_ConsoleReadPassword(password, sizeof(password)); - dr_dprintf("Password entered is '%s'", password); - if (CheckGorePasswordFile(password)) { - return 1; - } - } - return 0; -} - -// IDA: void __usercall PDDisplayGoreworthiness(int pGory@) -void PDDisplayGoreworthiness(int pGory) { - tU32 delay_start; - LOG_TRACE("(%d)", pGory); - - printf(pGory ? "\nPlaying full version...\n" : "\nPlaying zombie version...\n"); - delay_start = 2; - OS_Sleep(delay_start * 1000); -} - // IDA: void __usercall PDEnterDebugger(char *pStr@) void PDEnterDebugger(char* pStr) { static unsigned char* save_it; @@ -758,42 +530,6 @@ void PDEnterDebugger(char* pStr) { // ShowCursor(0); } -// Added function -br_material* PDMissingMaterial(char* name) { - LOG_TRACE("(\"%s\")", name); - - // FIXME: call functiont in harness - dr_dprintf("SOMETHING MISSING WARNING - Can't find material '%s'", name); - return NULL; -} - -// Added function -br_pixelmap* PDMissingTable(char* name) { - LOG_TRACE("(\"%s\")", name); - - // FIXME: call function in harness - dr_dprintf("SOMETHING MISSING WARNING - Can't find shade table '%s'", name); - return NULL; -} - -// Added function -br_model* PDMissingModel(char* name) { - LOG_TRACE("(\"%s\")", name); - - // FIXME: call function in harness - dr_dprintf("SOMETHING MISSING WARNING - Can't find model '%s'", name); - return NULL; -} - -// Added function -br_pixelmap* PDMissingMap(char* name) { - LOG_TRACE("(\"%s\")", name); - - // FIXME: call function in harness - dr_dprintf("SOMETHING MISSING WARNING - Can't find pixelmap '%s'", name); - return NULL; -} - // IDA: void __cdecl PDEndItAllAndReRunTheBastard() void PDEndItAllAndReRunTheBastard() { LOG_TRACE("()"); @@ -970,3 +706,62 @@ int PDDoWeLeadAnAustereExistance() { } return block < 15000000; } + +#endif + +int CheckGorePasswordFile(char* pPassword) { + tPath_name path; + FILE* f; + char line[10]; + + PathCat(path, "DATA", "PASS.TXT"); + f = fopen(path, "rb"); + if (f == NULL) { + return 0; + } + if (fgets(line, sizeof(line), f) == NULL) { + fclose(f); + return 0; + } + fclose(f); +#if defined(DETHRACE_FIX_BUGS) + // Allow a final newline in DATA/PASS.TXT + while (strlen(line) > 0 && (line[strlen(line) - 1] == '\n' || line[strlen(line) - 1] == '\r')) { + line[strlen(line) - 1] = '\0'; + } +#endif +#ifdef _WIN32 + return stricmp(line, pPassword) == 0; +#else + return strcasecmp(line, pPassword) == 0; +#endif +} + +// IDA: int __cdecl PDGetGorePassword() +int PDGetGorePassword() { + int ch; + int len; + int chances; + char password[17]; + LOG_TRACE("()"); + + for (chances = 0; chances < 3; chances++) { + printf(chances == 0 ? "\n\n\n\n\nEnter password for uncut version...\n" : "\nIncorrect password, please try again...\n"); + OS_ConsoleReadPassword(password, sizeof(password)); + dr_dprintf("Password entered is '%s'", password); + if (CheckGorePasswordFile(password)) { + return 1; + } + } + return 0; +} + +// IDA: void __usercall PDDisplayGoreworthiness(int pGory@) +void PDDisplayGoreworthiness(int pGory) { + tU32 delay_start; + LOG_TRACE("(%d)", pGory); + + printf(pGory ? "\nPlaying full version...\n" : "\nPlaying zombie version...\n"); + delay_start = 2; + gHarness_platform.Sleep(delay_start * 1000); +} diff --git a/src/DETHRACE/pc-win95/dinput.h b/src/DETHRACE/pc-win95/dinput.h new file mode 100644 index 00000000..17b2d95e --- /dev/null +++ b/src/DETHRACE/pc-win95/dinput.h @@ -0,0 +1,153 @@ +/**************************************************************************** + * + * DirectInput keyboard scan codes + * + ****************************************************************************/ +#define DIK_ESCAPE 0x01 +#define DIK_1 0x02 +#define DIK_2 0x03 +#define DIK_3 0x04 +#define DIK_4 0x05 +#define DIK_5 0x06 +#define DIK_6 0x07 +#define DIK_7 0x08 +#define DIK_8 0x09 +#define DIK_9 0x0A +#define DIK_0 0x0B +#define DIK_MINUS 0x0C /* - on main keyboard */ +#define DIK_EQUALS 0x0D +#define DIK_BACK 0x0E /* backspace */ +#define DIK_TAB 0x0F +#define DIK_Q 0x10 +#define DIK_W 0x11 +#define DIK_E 0x12 +#define DIK_R 0x13 +#define DIK_T 0x14 +#define DIK_Y 0x15 +#define DIK_U 0x16 +#define DIK_I 0x17 +#define DIK_O 0x18 +#define DIK_P 0x19 +#define DIK_LBRACKET 0x1A +#define DIK_RBRACKET 0x1B +#define DIK_RETURN 0x1C /* Enter on main keyboard */ +#define DIK_LCONTROL 0x1D +#define DIK_A 0x1E +#define DIK_S 0x1F +#define DIK_D 0x20 +#define DIK_F 0x21 +#define DIK_G 0x22 +#define DIK_H 0x23 +#define DIK_J 0x24 +#define DIK_K 0x25 +#define DIK_L 0x26 +#define DIK_SEMICOLON 0x27 +#define DIK_APOSTROPHE 0x28 +#define DIK_GRAVE 0x29 /* accent grave */ +#define DIK_LSHIFT 0x2A +#define DIK_BACKSLASH 0x2B +#define DIK_Z 0x2C +#define DIK_X 0x2D +#define DIK_C 0x2E +#define DIK_V 0x2F +#define DIK_B 0x30 +#define DIK_N 0x31 +#define DIK_M 0x32 +#define DIK_COMMA 0x33 +#define DIK_PERIOD 0x34 /* . on main keyboard */ +#define DIK_SLASH 0x35 /* / on main keyboard */ +#define DIK_RSHIFT 0x36 +#define DIK_MULTIPLY 0x37 /* * on numeric keypad */ +#define DIK_LMENU 0x38 /* left Alt */ +#define DIK_SPACE 0x39 +#define DIK_CAPITAL 0x3A +#define DIK_F1 0x3B +#define DIK_F2 0x3C +#define DIK_F3 0x3D +#define DIK_F4 0x3E +#define DIK_F5 0x3F +#define DIK_F6 0x40 +#define DIK_F7 0x41 +#define DIK_F8 0x42 +#define DIK_F9 0x43 +#define DIK_F10 0x44 +#define DIK_NUMLOCK 0x45 +#define DIK_SCROLL 0x46 /* Scroll Lock */ +#define DIK_NUMPAD7 0x47 +#define DIK_NUMPAD8 0x48 +#define DIK_NUMPAD9 0x49 +#define DIK_SUBTRACT 0x4A /* - on numeric keypad */ +#define DIK_NUMPAD4 0x4B +#define DIK_NUMPAD5 0x4C +#define DIK_NUMPAD6 0x4D +#define DIK_ADD 0x4E /* + on numeric keypad */ +#define DIK_NUMPAD1 0x4F +#define DIK_NUMPAD2 0x50 +#define DIK_NUMPAD3 0x51 +#define DIK_NUMPAD0 0x52 +#define DIK_DECIMAL 0x53 /* . on numeric keypad */ +#define DIK_OEM_102 0x56 /* <> or \| on RT 102-key keyboard (Non-U.S.) */ +#define DIK_F11 0x57 +#define DIK_F12 0x58 +#define DIK_F13 0x64 /* (NEC PC98) */ +#define DIK_F14 0x65 /* (NEC PC98) */ +#define DIK_F15 0x66 /* (NEC PC98) */ +#define DIK_KANA 0x70 /* (Japanese keyboard) */ +#define DIK_ABNT_C1 0x73 /* /? on Brazilian keyboard */ +#define DIK_CONVERT 0x79 /* (Japanese keyboard) */ +#define DIK_NOCONVERT 0x7B /* (Japanese keyboard) */ +#define DIK_YEN 0x7D /* (Japanese keyboard) */ +#define DIK_ABNT_C2 0x7E /* Numpad . on Brazilian keyboard */ +#define DIK_NUMPADEQUALS 0x8D /* = on numeric keypad (NEC PC98) */ +#define DIK_PREVTRACK 0x90 /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */ +#define DIK_AT 0x91 /* (NEC PC98) */ +#define DIK_COLON 0x92 /* (NEC PC98) */ +#define DIK_UNDERLINE 0x93 /* (NEC PC98) */ +#define DIK_KANJI 0x94 /* (Japanese keyboard) */ +#define DIK_STOP 0x95 /* (NEC PC98) */ +#define DIK_AX 0x96 /* (Japan AX) */ +#define DIK_UNLABELED 0x97 /* (J3100) */ +#define DIK_NEXTTRACK 0x99 /* Next Track */ +#define DIK_NUMPADENTER 0x9C /* Enter on numeric keypad */ +#define DIK_RCONTROL 0x9D +#define DIK_MUTE 0xA0 /* Mute */ +#define DIK_CALCULATOR 0xA1 /* Calculator */ +#define DIK_PLAYPAUSE 0xA2 /* Play / Pause */ +#define DIK_MEDIASTOP 0xA4 /* Media Stop */ +#define DIK_VOLUMEDOWN 0xAE /* Volume - */ +#define DIK_VOLUMEUP 0xB0 /* Volume + */ +#define DIK_WEBHOME 0xB2 /* Web home */ +#define DIK_NUMPADCOMMA 0xB3 /* , on numeric keypad (NEC PC98) */ +#define DIK_DIVIDE 0xB5 /* / on numeric keypad */ +#define DIK_SYSRQ 0xB7 +#define DIK_RMENU 0xB8 /* right Alt */ +#define DIK_PAUSE 0xC5 /* Pause */ +#define DIK_HOME 0xC7 /* Home on arrow keypad */ +#define DIK_UP 0xC8 /* UpArrow on arrow keypad */ +#define DIK_PRIOR 0xC9 /* PgUp on arrow keypad */ +#define DIK_LEFT 0xCB /* LeftArrow on arrow keypad */ +#define DIK_RIGHT 0xCD /* RightArrow on arrow keypad */ +#define DIK_END 0xCF /* End on arrow keypad */ +#define DIK_DOWN 0xD0 /* DownArrow on arrow keypad */ +#define DIK_NEXT 0xD1 /* PgDn on arrow keypad */ +#define DIK_INSERT 0xD2 /* Insert on arrow keypad */ +#define DIK_DELETE 0xD3 /* Delete on arrow keypad */ + +/* + * Alternate names for keys, to facilitate transition from DOS. + */ +#define DIK_BACKSPACE DIK_BACK /* backspace */ +#define DIK_NUMPADSTAR DIK_MULTIPLY /* * on numeric keypad */ +#define DIK_LALT DIK_LMENU /* left Alt */ +#define DIK_CAPSLOCK DIK_CAPITAL /* CapsLock */ +#define DIK_NUMPADMINUS DIK_SUBTRACT /* - on numeric keypad */ +#define DIK_NUMPADPLUS DIK_ADD /* + on numeric keypad */ +#define DIK_NUMPADPERIOD DIK_DECIMAL /* . on numeric keypad */ +#define DIK_NUMPADSLASH DIK_DIVIDE /* / on numeric keypad */ +#define DIK_RALT DIK_RMENU /* right Alt */ +#define DIK_UPARROW DIK_UP /* UpArrow on arrow keypad */ +#define DIK_PGUP DIK_PRIOR /* PgUp on arrow keypad */ +#define DIK_LEFTARROW DIK_LEFT /* LeftArrow on arrow keypad */ +#define DIK_RIGHTARROW DIK_RIGHT /* RightArrow on arrow keypad */ +#define DIK_DOWNARROW DIK_DOWN /* DownArrow on arrow keypad */ +#define DIK_PGDN DIK_NEXT /* PgDn on arrow keypad */ diff --git a/src/DETHRACE/pc-win95/ssdx.c b/src/DETHRACE/pc-win95/ssdx.c new file mode 100644 index 00000000..55ded3a3 --- /dev/null +++ b/src/DETHRACE/pc-win95/ssdx.c @@ -0,0 +1,64 @@ +#include "ssdx.h" +#include "errors.h" +#include "harness/hooks.h" + +int gSSDX_windowed; +void* gSSDX_hwnd; + +int SSDXStart(void* hWnd, int windowed, int flags) { + int res = 0; + dr_dprintf("SSDXStart(): START..."); + if (windowed) { + gSSDX_windowed = 1; + } + gSSDX_hwnd = hWnd; + + // Not required + + // if ((flags & 1) != 0) { + // dr_dprintf("Calling DirectDrawCreate()..."); + // res = DirectDrawCreate(0, &gDirect_draw, 0); + // if (!res) { + // dr_dprintf("Calling SetCooperativeLevel()..."); + // if (gSSDX_windowed) { + // res = gDirect_draw->lpVtbl->SetCooperativeLevel(gDirect_draw, gSSDX_hwnd, 8); + // } else { + // res = gDirect_draw->lpVtbl->SetCooperativeLevel(gDirect_draw, gSSDX_hwnd, 83); + // } + // } + // } + // if (!res && (flags & 2) != 0) { + // dr_dprintf("Calling DirectSoundCreate()..."); + // res = DirectSoundCreate(0, &gDirect_sound, 0); + // } + // if (res) { + // SSDXHandleError(res); + // } + dr_dprintf("SSDXStart(): END."); + return res; +} + +int SSDXInitDirectDraw(int width, int height, int* row_bytes) { + DirectDraw_CreateSurface(width, height); + *row_bytes = width; + return 0; +} + +void SSDXRelease() {} + +void SSDXGetWindowRect(void* hWnd) { + // none of this is required + + // GetClientRect(hWnd, &gSSDX_rect); + // ClientToScreen(hWnd, (LPPOINT)&gSSDX_rect); + // ClientToScreen(hWnd, (LPPOINT)&gSSDX_rect.right); + // dr_dprintf("New window rect: (%d,%d)(%d,%d)", gSSDX_rect.left, gSSDX_rect.top, gSSDX_rect.right, gSSDX_rect.bottom); +} + +void SSDXHandleError(int error) { + // no-op +} + +void SSDXSetPaleeteEntries(PALETTEENTRY_* palette, int pFirst_color, int pCount) { + DirectDrawDevice_SetPaletteEntries(palette, pFirst_color, pCount); +} diff --git a/src/DETHRACE/pc-win95/ssdx.h b/src/DETHRACE/pc-win95/ssdx.h new file mode 100644 index 00000000..fb304f24 --- /dev/null +++ b/src/DETHRACE/pc-win95/ssdx.h @@ -0,0 +1,18 @@ +#ifndef SSDX_H +#define SSDX_H + +#include "harness/win95_polyfill.h" + +// All we know about these functions are two names - "SSDXStart" and "SSDXLockAttachedSurface". +// SSDX stands for Stainless Software Direct X ? + +int SSDXStart(void* hWnd, int windowed, int flags); +int SSDXInitDirectDraw(int width, int height, int* row_bytes); +void SSDXRelease(); +void SSDXLockAttachedSurface(); +void SSDXGetWindowRect(void* hWnd); +void SSDXHandleError(int error); + +void SSDXSetPaleeteEntries(PALETTEENTRY_* palette, int pFirst_color, int pCount); + +#endif diff --git a/src/DETHRACE/pc-win95/win95sys.c b/src/DETHRACE/pc-win95/win95sys.c new file mode 100644 index 00000000..a9815948 --- /dev/null +++ b/src/DETHRACE/pc-win95/win95sys.c @@ -0,0 +1,1131 @@ +#include "brender/brender.h" +#include "car.h" +#include "dinput.h" +#include "errors.h" +#include "globvars.h" +#include "grafdata.h" +#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" +#include "main.h" +#include "pd/sys.h" +#include "sound.h" +#include "ssdx.h" +#include "utility.h" +#include +#include +#include +#include +#include + +#include "harness/win95_polyfill.h" + +#define GFX_INIT_STRING_32X20X8 "320x200 init string" +#define GFX_INIT_STRING_64X48X8 "640x480 init string" + +#define KEYDOWN(var, key) (var[key] & 0x80) + +int gExtra_mem; +int gReplay_override; +tGraf_spec gGraf_specs[2] = { + { 8, 1, 0, 320, 200, 0, 0, "32X20X8", GFX_INIT_STRING_32X20X8, 320, 320, 200, NULL }, + { 8, 1, 0, 640, 480, 0, 0, "64X48X8", GFX_INIT_STRING_64X48X8, 640, 640, 480, NULL } +}; +int gASCII_table[128]; +tU32 gKeyboard_bits[8]; +int gASCII_shift_table[128]; +char gNetwork_profile_fname[256]; +tS32 gJoystick_min1y; +tS32 gJoystick_min2y; +tS32 gJoystick_min2x; +tS32 gRaw_joystick2y; +tS32 gRaw_joystick2x; +tS32 gRaw_joystick1y; +tS32 gRaw_joystick1x; +tS32 gJoystick_range2y; +tS32 gJoystick_range2x; +tS32 gJoystick_range1y; +tS32 gJoystick_range1x; +int gNo_voodoo; +int gSwitched_resolution; +br_pixelmap* gReal_back_screen; +tS32 gJoystick_min1x; +br_pixelmap* gTemp_screen; +int gGfx_initialized; // maybe renamed here +tU32 gUpper_loop_limit; +int gReal_back_screen_locked; +tU32 gScan_code[123]; // was tU8 [123][2] in symbol dump + +// Added by dethrace. Windows-specific. Original variable names unknown. +int gWin32_fatal_error_exit_code; +int gWin32_show_fatal_error_message; +char gWin32_fatal_error_message[512]; +int gWin32_action_replay_buffer_allocated; +void* gWin32_action_replay_buffer; +int gWin32_action_replay_buffer_size; +void* gWin32_hwnd; +int gWin32_lbutton_down; +int gWin32_rbutton_down; +PALETTEENTRY_ gWin32_palette[256]; +br_diaghandler gWin32_br_diaghandler; +int gWin32_window_has_focus = 1; +int gNetwork_profile_file_exists = 0; + +char* _unittest_last_fatal_error; + +void Win32InitScreen(); +void Win32PumpMessages(); +void Win32ReleaseInputDevice(); +void Win32FatalError(char* pStr_1, char* pStr_2); +void Win32BRenderWarningFunc(char* msg); +void Win32BRenderFailureFunc(char* msg); +void Win32AllocateActionReplayBuffer(); +void Win32CreateWindow(); +void Win32InitInputDevice(); + +extern void QuitGame(); + +void KeyboardHandler() { + tU8 scan_code; + tU8 up; + static tU8 extended; + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int KeyDown(tU8 pScan_code) { + NOT_IMPLEMENTED(); +} + +void KeyTranslation(tU8 pKey_index, tU8 pScan_code_1, tU8 pScan_code_2) { + LOG_TRACE("(%d, %d, %d)", pKey_index, pScan_code_1, pScan_code_2); + NOT_IMPLEMENTED(); +} + +void KeyBegin() { + gScan_code[KEY_0] = DIK_0; + gScan_code[KEY_1] = DIK_1; + gScan_code[KEY_2] = DIK_2; + gScan_code[KEY_3] = DIK_3; + gScan_code[KEY_4] = DIK_4; + gScan_code[KEY_5] = DIK_5; + gScan_code[KEY_6] = DIK_6; + gScan_code[KEY_7] = DIK_7; + gScan_code[KEY_8] = DIK_8; + gScan_code[KEY_9] = DIK_9; + gScan_code[KEY_A] = DIK_A; + gScan_code[KEY_B] = DIK_B; + gScan_code[KEY_C] = DIK_C; + gScan_code[KEY_D] = DIK_D; + gScan_code[KEY_E] = DIK_E; + gScan_code[KEY_F] = DIK_F; + gScan_code[KEY_G] = DIK_G; + gScan_code[KEY_H] = DIK_H; + gScan_code[KEY_I] = DIK_I; + gScan_code[KEY_J] = DIK_J; + gScan_code[KEY_K] = DIK_K; + gScan_code[KEY_L] = DIK_L; + gScan_code[KEY_M] = DIK_M; + gScan_code[KEY_N] = DIK_N; + gScan_code[KEY_O] = DIK_O; + gScan_code[KEY_P] = DIK_P; + gScan_code[KEY_Q] = DIK_Q; + gScan_code[KEY_R] = DIK_R; + gScan_code[KEY_S] = DIK_S; + gScan_code[KEY_T] = DIK_T; + gScan_code[KEY_U] = DIK_U; + gScan_code[KEY_V] = DIK_V; + gScan_code[KEY_W] = DIK_W; + gScan_code[KEY_X] = DIK_X; + gScan_code[KEY_Y] = DIK_Y; + gScan_code[KEY_Z] = DIK_Z; + gScan_code[KEY_GRAVE] = DIK_GRAVE; + gScan_code[KEY_MINUS] = DIK_MINUS; + gScan_code[KEY_EQUALS] = DIK_EQUALS; + gScan_code[KEY_BACKSPACE] = DIK_BACK; + gScan_code[KEY_RETURN] = DIK_RETURN; + gScan_code[KEY_KP_ENTER] = DIK_NUMPADENTER; + gScan_code[KEY_CAPSLOCK] = DIK_CAPSLOCK; + gScan_code[KEY_TAB] = DIK_TAB; + gScan_code[KEY_SLASH] = DIK_SLASH; + gScan_code[KEY_UNKNOWN_55] = 0; + gScan_code[KEY_SEMICOLON] = DIK_SEMICOLON; + gScan_code[KEY_APOSTROPHE] = DIK_APOSTROPHE; + gScan_code[KEY_PERIOD] = DIK_PERIOD; + gScan_code[KEY_COMMA] = DIK_COMMA; + gScan_code[KEY_LBRACKET] = DIK_LBRACKET; + gScan_code[KEY_RBRACKET] = DIK_RBRACKET; + gScan_code[KEY_ESCAPE] = DIK_ESCAPE; + gScan_code[KEY_INSERT] = DIK_INSERT; + gScan_code[KEY_DELETE] = DIK_DELETE; + gScan_code[KEY_HOME] = DIK_HOME; + gScan_code[KEY_END] = DIK_END; + gScan_code[KEY_PAGEUP] = DIK_PGUP; + gScan_code[KEY_PAGEDOWN] = DIK_PGDN; + gScan_code[KEY_LEFT] = DIK_LEFT; + gScan_code[KEY_RIGHT] = DIK_RIGHT; + gScan_code[KEY_UP] = DIK_UP; + gScan_code[KEY_DOWN] = DIK_DOWN; + gScan_code[KEY_KP_NUMLOCK] = DIK_NUMLOCK; + gScan_code[KEY_KP_DIVIDE] = DIK_DIVIDE; + gScan_code[KEY_KP_MULTIPLY] = DIK_MULTIPLY; + gScan_code[KEY_KP_MINUS] = DIK_SUBTRACT; + gScan_code[KEY_KP_PLUS] = DIK_ADD; + gScan_code[KEY_KP_PERIOD] = DIK_DECIMAL; + gScan_code[KEY_KP_0] = DIK_NUMPAD0; + gScan_code[KEY_KP_1] = DIK_NUMPAD1; + gScan_code[KEY_KP_2] = DIK_NUMPAD2; + gScan_code[KEY_KP_3] = DIK_NUMPAD3; + gScan_code[KEY_KP_4] = DIK_NUMPAD4; + gScan_code[KEY_KP_5] = DIK_NUMPAD5; + gScan_code[KEY_KP_6] = DIK_NUMPAD6; + gScan_code[KEY_KP_7] = DIK_NUMPAD7; + gScan_code[KEY_KP_8] = DIK_NUMPAD8; + gScan_code[KEY_KP_9] = DIK_NUMPAD9; + gScan_code[KEY_F1] = DIK_F1; + gScan_code[KEY_F2] = DIK_F2; + gScan_code[KEY_F3] = DIK_F3; + gScan_code[KEY_F4] = DIK_F4; + gScan_code[KEY_F5] = DIK_F5; + gScan_code[KEY_F6] = DIK_F6; + gScan_code[KEY_F7] = DIK_F7; + gScan_code[KEY_F8] = DIK_F8; + gScan_code[KEY_F9] = DIK_F9; + gScan_code[KEY_F10] = DIK_F10; + gScan_code[KEY_F11] = DIK_F11; + gScan_code[KEY_F12] = DIK_F12; + gScan_code[KEY_PRTSCN] = DIK_SYSRQ; + gScan_code[KEY_SCRLK] = DIK_SCROLL; + gScan_code[KEY_SPACE] = DIK_SPACE; + gScan_code[KEY_RSHIFT] = DIK_RSHIFT; + gScan_code[KEY_RALT] = DIK_RALT; + gScan_code[KEY_RCTRL] = DIK_RCONTROL; + gScan_code[KEY_LSHIFT] = DIK_LSHIFT; + gScan_code[KEY_LALT] = DIK_LALT; + gScan_code[KEY_LCTRL] = DIK_LCONTROL; + gScan_code[KEY_KP_EQUALS] = 0; + gScan_code[KEY_BACKSLASH] = DIK_BACKSLASH; + gScan_code[KEY_CTRL_ANY_2] = 0xff; + gScan_code[KEY_PAUSE] = 0xff; + gScan_code[KEY_SHIFT_ANY] = 0xff; + gScan_code[KEY_ALT_ANY] = 0xff; + gScan_code[KEY_CTRL_ANY] = 0xff; +} + +void KeyEnd() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int KeyDown22(int pKey_index) { + LOG_TRACE("(%d)", pKey_index); + NOT_IMPLEMENTED(); +} + +void PDSetKeyArray(int* pKeys, int pMark) { + int i; + uint8_t keystate[256]; + LOG_TRACE10("(%p, %d)", pKeys, pMark); + + gKeys_pressed = 0; + Win32PumpMessages(); + DirectInputDevice_GetDeviceState(COUNT_OF(keystate), keystate); + + for (i = 0; i < COUNT_OF(gScan_code); i++) { + if (gScan_code[i] == 0) { + continue; + } + if (gScan_code[i] == 0xff) { + switch (i) { + case KEY_SHIFT_ANY: + if (KEYDOWN(keystate, gScan_code[KEY_LSHIFT]) || KEYDOWN(keystate, gScan_code[KEY_RSHIFT])) { + pKeys[KEY_SHIFT_ANY] = pMark; + } else { + if (pKeys[KEY_SHIFT_ANY] == pMark) { + pKeys[KEY_SHIFT_ANY] = 0; + } + } + break; + case KEY_ALT_ANY: + if (KEYDOWN(keystate, gScan_code[KEY_LALT]) || KEYDOWN(keystate, gScan_code[KEY_RALT])) { + pKeys[KEY_ALT_ANY] = pMark; + + } else { + if (pKeys[KEY_ALT_ANY] == pMark) { + pKeys[KEY_ALT_ANY] = 0; + } + } + break; + case KEY_CTRL_ANY: + case KEY_CTRL_ANY_2: + if (KEYDOWN(keystate, gScan_code[KEY_LCTRL]) || KEYDOWN(keystate, gScan_code[KEY_RCTRL])) { + pKeys[KEY_CTRL_ANY] = pMark; + pKeys[KEY_CTRL_ANY_2] = pMark; + } else { + if (pKeys[KEY_CTRL_ANY] == pMark || pKeys[KEY_CTRL_ANY_2] == pMark) { + pKeys[KEY_CTRL_ANY] = 0; + pKeys[KEY_CTRL_ANY_2] = 0; + } + } + break; + default: + continue; + } + } else if (KEYDOWN(keystate, gScan_code[i])) { + pKeys[i] = pMark; + gKeys_pressed = i + (gKeys_pressed << 8) + 1; + } else { + if (pKeys[i] == pMark) { + pKeys[i] = 0; + } + } + } +} + +void Win32ReleaseInputDevice() { +} + +int PDGetASCIIFromKey(int pKey) { + LOG_TRACE("(%d)", pKey); + + if (PDKeyDown(KEY_LSHIFT)) { + return gASCII_shift_table[pKey]; + } else { + return gASCII_table[pKey]; + } +} + +void Win32PumpMessages() { + MSG_ msg; // [esp+Ch] [ebp-20h] BYREF + + PDUnlockRealBackScreen(); + while ((!gWin32_window_has_focus || PeekMessageA_(&msg, 0, 0, 0, 1u)) && (gWin32_window_has_focus || GetMessageA_(&msg, 0, 0, 0) != -1)) { + if (msg.message == WM_QUIT) { + dr_dprintf("WM_QUIT received."); + if (gWin32_window_has_focus) { + dr_dprintf("Active, so lock the surface"); + PDLockRealBackScreen(); + dr_dprintf("QuitGame being called..."); + QuitGame(); + } + PDShutdownSystem(); + } + TranslateMessage_(&msg); + DispatchMessageA_(&msg); + } + PDLockRealBackScreen(); +} + +void PDFatalError(char* pThe_str) { + LOG_TRACE("(\"%s\")", pThe_str); + + dr_dprintf("FATAL ERROR: %s", pThe_str); + Win32FatalError(pThe_str, NULL); +} + +void Win32FatalError(char* pStr_1, char* pStr_2) { + gWin32_show_fatal_error_message = 1; + sprintf(gWin32_fatal_error_message, "%s\n%s", pStr_1, pStr_2); + gWin32_fatal_error_exit_code = 15; + PDShutdownSystem(); +} + +void PDNonFatalError(char* pThe_str) { + LOG_TRACE("(\"%s\")", pThe_str); + NOT_IMPLEMENTED(); +} + +void PDInitialiseSystem() { + tPath_name the_path; + FILE* f; + int len; + + Win32AllocateActionReplayBuffer(); + gBack_screen = NULL; + gScreen = NULL; + Win32CreateWindow(); + ShowCursor_(0); + KeyBegin(); + + // dethrace: demos do not ship with KEYBOARD.COK file + if (harness_game_info.defines.ascii_table == NULL) { + PathCat(the_path, gApplication_path, "KEYBOARD.COK"); + f = fopen(the_path, "rb"); + if (!f) { + PDFatalError("This .exe must have KEYBOARD.COK in the DATA folder."); + } + fseek(f, 0, 2); + len = ftell(f) / 2; + rewind(f); + fread(gASCII_table, len, 1u, f); + fread(gASCII_shift_table, len, 1u, f); + fclose(f); + } else { + memcpy(gASCII_table, harness_game_info.defines.ascii_table, sizeof(gASCII_table)); + memcpy(gASCII_shift_table, harness_game_info.defines.ascii_shift_table, sizeof(gASCII_shift_table)); + } + Win32InitInputDevice(); +} + +void Win32CreateWindow() { + // wnd_class.style = 3; + // wnd_class.lpfnWndProc = window_proc; + // wnd_class.cbClsExtra = 0; + // wnd_class.cbWndExtra = 0; + // wnd_class.hInstance = gWin32_hinst; + // wnd_class.hIcon = LoadIconA(0, (LPCSTR)0x7F00); + // wnd_class.hCursor = LoadCursorA(0, (LPCSTR)0x7F00); + // wnd_class.hbrBackground = (HBRUSH)GetStockObject(4); + // wnd_class.lpszMenuName = 0; + // wnd_class.lpszClassName = "CarmageddonClass"; + // LOWORD(v5) = RegisterClassA(&wnd_class); + // v5 = (unsigned __int16)v5; + // v2 = gWin32_hinst; + + // int height = GetSystemMetrics(SM_CYSCREEN); + // int width = GetSystemMetrics(SM_CXSCREEN); + int height = 200; + int width = 320; + // WS_VISIBLE | WS_POPUP + gWin32_hwnd = CreateWindowExA_(0, "CarmageddonClass", "Carmageddon", 0x90000000, 0, 0, width, height, 0, NULL, NULL, NULL); + SSDXGetWindowRect(gWin32_hwnd); + // hdc = GetDC(gWin32_hwnd); + // GetSystemPaletteEntries(hdc, 0, 256u, &gWin32_palette); + // ReleaseDC(gWin32_hwnd, hdc); + // UpdateWindow(gWin32_hwnd); + // SetFocus(gWin32_hwnd); +} + +void PDShutdownSystem() { + static int been_here = 0; + LOG_TRACE("()"); + + if (!been_here) { + been_here = 1; + dr_dprintf("PDShutdownSystem()..."); + SSDXRelease(); + Win32ReleaseInputDevice(); + ShowCursor_(1); + if (gWin32_hwnd) { + dr_dprintf("Resizing main window..."); + SetWindowPos_(gWin32_hwnd, 0, -100, -100, 64, 64, 0x414u); + } + dr_dprintf("Servicing messages..."); + Win32PumpMessages(); + dr_dprintf("Sending WM_SHOWWINDOW broadcast message..."); + SendMessageA_(HWND_BROADCAST, 0x18u, 1u, 0); + if (gWin32_show_fatal_error_message) { + dr_dprintf("Displaying fatal error..."); + MessageBoxA_(0, gWin32_fatal_error_message, "Carmageddon Fatal Error", 0x10u); + } + if (gWin32_hwnd) { + dr_dprintf("Destroying window..."); + DestroyWindow_(gWin32_hwnd); + gWin32_hwnd = 0; + } + dr_dprintf("End of PDShutdownSystem()."); + CloseDiagnostics(); + ExitProcess_(gWin32_fatal_error_exit_code); + } + ExitProcess_(8u); +} + +void PDSaveOriginalPalette() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +void PDRevertPalette() { + LOG_TRACE("()"); + + // empty function +} + +int PDInitScreenVars(int pArgc, char** pArgv) { + // this codes from dossys + gGraf_specs[gGraf_spec_index].phys_width = gGraf_specs[gGraf_spec_index].total_width; + gGraf_specs[gGraf_spec_index].phys_height = gGraf_specs[gGraf_spec_index].total_height; + return 1; +} + +void PDInitScreen() { + Win32InitScreen(); +} + +void Win32InitScreen() { + // SWP_NOSENDCHANGING | SWP_NOACTIVATE | SWP_NOZORDER + SetWindowPos_(gWin32_hwnd, 0, 0, 0, gGraf_specs[gReal_graf_data_index].total_width, gGraf_specs[gReal_graf_data_index].total_height, 0x414u); + // get_window_rect(gWin32_hwnd); + Win32PumpMessages(); +} + +void PDLockRealBackScreen() { + LOG_TRACE("()"); + + // no-op +} + +void PDUnlockRealBackScreen() { + LOG_TRACE("()"); + + // no-op +} + +void PDAllocateScreenAndBack() { + // this is a mix of windows and dos code + + dr_dprintf("PDAllocateScreenAndBack() - START..."); + BrMaterialFindHook(PDMissingMaterial); + BrTableFindHook(PDMissingTable); + BrModelFindHook(PDMissingModel); + BrMapFindHook(PDMissingMap); + + int row_bytes; + SSDXInitDirectDraw(gGraf_specs[gGraf_spec_index].total_width, gGraf_specs[gGraf_spec_index].total_height, &row_bytes); + gScreen = BrPixelmapAllocate(BR_PMT_INDEX_8, gGraf_specs[gGraf_spec_index].total_width, gGraf_specs[gGraf_spec_index].total_height, NULL, BR_PMAF_NORMAL); + + gScreen->origin_x = 0; + gGfx_initialized = 1; + gScreen->origin_y = 0; + gBack_screen = BrPixelmapMatch(gScreen, BR_PMMATCH_OFFSCREEN); + gBack_screen->origin_x = 0; + gBack_screen->origin_y = 0; + gTemp_screen = BrPixelmapMatch(gScreen, BR_PMMATCH_OFFSCREEN); + gTemp_screen->origin_x = 0; + gTemp_screen->origin_y = 0; + dr_dprintf("PDAllocateScreenAndBack() - END."); + + // dr_dprintf("PDAllocateScreenAndBack() - START..."); + // BrMaterialFindHook(PDMissingMaterial); + // BrTableFindHook(PDMissingTable); + // BrModelFindHook(PDMissingModel); + // BrMapFindHook(PDMissingMap); + // dr_dprintf("Setting up DirectDraw stuff..."); + // SSDXStart(gWin32_hwnd, 0, 1); + // dr_dprintf("Setting up DirectSound stuff..."); + // int result = SSDXStart(gWin32_hwnd, 0, 2); + // int row_bytes; + // if (result == 0) { + // result = SSDXInitDirectDraw(gGraf_specs[gGraf_spec_index].total_width, gGraf_specs[gGraf_spec_index].total_height, &row_bytes); + // } + // if (result) { + // SSDXHandleError(result); + // PDFatalError("Unable to setup DirectDraw - please check that DirectX is installed"); + // } + // gGraf_specs[gGraf_spec_index].row_bytes = row_bytes; + // gGraf_specs[gGraf_spec_index].phys_width = gGraf_specs[gGraf_spec_index].row_bytes; + // gGraf_specs[gGraf_spec_index].phys_height = gGraf_specs[gGraf_spec_index].total_height; + // dr_dprintf( + // "Graf spec info after screen allocation:\n" + // " Total width: %d\n" + // " Total height: %d\n" + // " Phys width: %d\n" + // " Phys height: %d\n" + // " Row bytes: %d\n", + // gGraf_specs[gGraf_spec_index].total_width, + // gGraf_specs[gGraf_spec_index].total_height, + // gGraf_specs[gGraf_spec_index].phys_width, + // gGraf_specs[gGraf_spec_index].phys_height, + // gGraf_specs[gGraf_spec_index].row_bytes); + // dr_dprintf("First attempt at locking surface..."); + // PDLockRealBackScreen(); + // dr_dprintf("Done first surface lock; gOffscreen_pixels 0x%p", gOffscreen_pixels); + // gBack_screen = BrPixelmapAllocate( + // 3u, + // gGraf_specs[gGraf_spec_index].phys_width, + // gGraf_specs[gGraf_spec_index].phys_height, + // gOffscreen_pixels, + // 0); + // gScreen = gBack_screen; + // gBack_screen->origin_x = 0; + // gBack_screen->origin_y = 0; + // gBack_screen->base_x = 0; + // gBack_screen->base_y = 0; + // gBack_screen->row_bytes = gGraf_specs[gGraf_spec_index].row_bytes; + // gTemp_screen = (br_pixelmap*)BrPixelmapMatch(gBack_screen, 0); + // gGfx_initialized = 1; + // memset(gBack_screen->pixels, 0, gBack_screen->row_bytes * gBack_screen->height); + // PDScreenBufferSwap(0); + // dr_dprintf("PDAllocateScreenAndBack() - END."); +} + +void Copy8BitTo16BitPixelmap(br_pixelmap* pDst, br_pixelmap* pSrc, br_pixelmap* pPalette) { + int x; + int y; + tU8* src; + tU8 value; + tU8 red; + tU8 green; + tU8 blue; + tU16* dst; + tU16* palette_entry; + LOG_TRACE("(%p, %p, %p)", pDst, pSrc, pPalette); + NOT_IMPLEMENTED(); +} + +void Double8BitTo16BitPixelmap(br_pixelmap* pDst, br_pixelmap* pSrc, br_pixelmap* pPalette, tU16 pOff, tU16 pSrc_width, tU16 pSrc_height) { + int x; + int y; + tU8* src; + tU8 value; + tU8 red; + tU8 green; + tU8 blue; + tU16* dst0; + tU16* dst1; + tU16 sixteen; + tU16* palette_entry; + LOG_TRACE("(%p, %p, %p, %d, %d, %d)", pDst, pSrc, pPalette, pOff, pSrc_width, pSrc_height); + NOT_IMPLEMENTED(); +} + +br_pixelmap* PDInterfacePixelmap() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +void SwapBackScreen() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +void ReallyCopyBackScreen(int pRendering_area_only, int pClear_top_and_bottom) { + LOG_TRACE("(%d, %d)", pRendering_area_only, pClear_top_and_bottom); + NOT_IMPLEMENTED(); +} + +void CopyBackScreen(int pRendering_area_only) { + LOG_TRACE("(%d)", pRendering_area_only); + NOT_IMPLEMENTED(); +} + +void PDScreenBufferSwap(int pRendering_area_only) { + // taken from dossys + + if (pRendering_area_only) { + BrPixelmapRectangleCopy(gScreen, gY_offset, gX_offset, gRender_screen, 0, 0, gWidth, gHeight); + } else { + if (gReal_graf_data_index == gGraf_data_index) { + BrPixelmapDoubleBuffer(gScreen, gBack_screen); + } else { + DRPixelmapDoubledCopy(gTemp_screen, gBack_screen, 320, 200, 0, 40); + BrPixelmapDoubleBuffer(gScreen, gTemp_screen); + } + } +} + +void PDPixelmapToScreenRectangleCopy(br_pixelmap* dst, br_int_16 dx, br_int_16 dy, br_pixelmap* src, br_int_16 sx, br_int_16 sy, br_uint_16 w, br_uint_16 h) { + LOG_TRACE("(%p, %d, %d, %p, %d, %d, %d, %d)", dst, dx, dy, src, sx, sy, w, h); + NOT_IMPLEMENTED(); +} + +void PDPixelmapHLineOnScreen(br_pixelmap* dst, br_int_16 x1, br_int_16 y1, br_int_16 x2, br_int_16 y2, br_uint_32 colour) { + LOG_TRACE("(%p, %d, %d, %d, %d, %d)", dst, x1, y1, x2, y2, colour); + NOT_IMPLEMENTED(); +} + +void PDPixelmapVLineOnScreen(br_pixelmap* dst, br_int_16 x1, br_int_16 y1, br_int_16 x2, br_int_16 y2, br_uint_32 colour) { + LOG_TRACE("(%p, %d, %d, %d, %d, %d)", dst, x1, y1, x2, y2, colour); + NOT_IMPLEMENTED(); +} + +void PDInstallErrorHandlers() { + LOG_TRACE("()"); + + gWin32_br_diaghandler.identifier = "LlantisilioBlahBlahBlahOgOgOch"; + gWin32_br_diaghandler.warning = Win32BRenderWarningFunc; + gWin32_br_diaghandler.failure = Win32BRenderFailureFunc; + BrDiagHandlerSet(&gWin32_br_diaghandler); +} + +void PDSetFileVariables() { + + // Changed by dethrace for cross-platform + // strcpy(gDir_separator, "\\"); + strcpy(gDir_separator, "/"); +} + +void PDBuildAppPath(char* pThe_path) { + GetCurrentDirectoryA_(253, pThe_path); + // GetShortPathNameA(pThe_path, pThe_path, 253); + strcat(pThe_path, "/"); // original: strcat(pThe_path, "\\") + dr_dprintf("Application path '%s'", pThe_path); +} + +void PDForEveryFile(char* pThe_path, void (*pAction_routine)(char*)) { + char found_path[256]; // [esp+Ch] [ebp-448h] BYREF + WIN32_FIND_DATAA_ find_data; // [esp+10Ch] [ebp-348h] BYREF + HANDLE_ hFindFile; // [esp+24Ch] [ebp-208h] + char file_filter[256]; // [esp+250h] [ebp-204h] BYREF + char current_dir[260]; // [esp+350h] [ebp-104h] BYREF + + GetCurrentDirectoryA_(sizeof(current_dir), current_dir); + if (SetCurrentDirectoryA_(pThe_path)) { + strcpy(file_filter, "*.???"); + hFindFile = FindFirstFileA_(file_filter, &find_data); + if (hFindFile != INVALID_HANDLE_VALUE) { + do { + PathCat(found_path, pThe_path, find_data.cFileName); + pAction_routine(found_path); + } while (FindNextFileA_(hFindFile, &find_data)); + FindClose_(hFindFile); + } + SetCurrentDirectoryA_(current_dir); + } +} + +void PDSetPalette(br_pixelmap* pThe_palette) { + PDSetPaletteEntries(pThe_palette, 0, 256); +} + +void Win32SetPaletteEntries(uint8_t* entries, int pFirst_colour, int pCount) { + int i; // [esp+Ch] [ebp-Ch] + int last_colour; // [esp+14h] [ebp-4h] + + last_colour = pFirst_colour + pCount - 1; + if (last_colour > 255) { + last_colour = 255; + } + for (i = pFirst_colour; i <= last_colour; i++) { + gWin32_palette[i].peFlags = 0; + gWin32_palette[i].peRed = entries[i * 4 + 2]; + gWin32_palette[i].peGreen = entries[i * 4 + 1]; + gWin32_palette[i].peBlue = entries[i * 4]; + } + SSDXSetPaleeteEntries(gWin32_palette, 0, 256); +} + +void PDSetPaletteEntries(br_pixelmap* pPalette, int pFirst_colour, int pCount) { + Win32SetPaletteEntries(pPalette->pixels, pFirst_colour, pCount); +} + +void PDSwitchToRealResolution() { + LOG_TRACE("()"); +} + +void PDSwitchToLoresMode() { + LOG_TRACE("()"); +} + +void PDMouseButtons(int* pButton_1, int* pButton_2) { + br_uint_32 mouse_buttons; + br_int_32 mouse_x; + br_int_32 mouse_y; + LOG_TRACE("(%p, %p)", pButton_1, pButton_2); + + // added by dethrace + gHarness_platform.GetMouseButtons(pButton_1, pButton_2); +} + +void PDGetMousePosition(int* pX_coord, int* pY_coord) { + POINT_ p; + LOG_TRACE("(%p, %p)", pX_coord, pY_coord); + + GetCursorPos_(&p); + ScreenToClient_(gWin32_hwnd, &p); + *pX_coord = p.x; + *pY_coord = p.y; +} + +int PDGetTotalTime() { + return timeGetTime_(); +} + +int PDServiceSystem(tU32 pTime_since_last_call) { + Win32PumpMessages(); + return 0; +} + +void Win32InitInputDevice() { + // do directinput stuff + gJoystick_deadzone = 8000; +} + +void Win32AllocateActionReplayBuffer() { + MEMORYSTATUS_ mem_status; // [esp+Ch] [ebp-28h] BYREF + size_t buf_size; // [esp+2Ch] [ebp-8h] + void* buf; // [esp+30h] [ebp-4h] + + buf = 0; + if (gWin32_action_replay_buffer_allocated) { + return; + } + gWin32_action_replay_buffer_allocated = 1; + mem_status.dwLength = sizeof(mem_status); + GlobalMemoryStatus_(&mem_status); + dr_dprintf( + "Win32AllocateActionReplayBuffer(): Memory Status BEFORE Action Replay Allocation:\n" + " dwLength %u\n" + " dwMemoryLoad %u\n" + " dwTotalPhys %u\n" + " dwAvailPhys %u\n" + " dwTotalPageFile %u\n" + " dwAvailPageFile %u\n" + " dwTotalVirtual %u\n" + " dwAvailVirtual %u", + mem_status.dwLength, + mem_status.dwMemoryLoad, + mem_status.dwTotalPhys, + mem_status.dwAvailPhys, + mem_status.dwTotalPageFile, + mem_status.dwAvailPageFile, + mem_status.dwTotalVirtual, + mem_status.dwAvailVirtual); + + buf_size = 20000000; + + if (mem_status.dwTotalPhys < 16000000) { + buf_size = 500000; + } + if (mem_status.dwTotalPhys < 24000000) { + buf_size = 4000000; + } + if (mem_status.dwTotalPhys < 32000000) { + buf_size = 6000000; + } + if (mem_status.dwTotalPhys < 48000000) { + buf_size = 12000000; + } + + dr_dprintf("Win32AllocateActionReplayBuffer(): We want %d bytes...", buf_size); + if (mem_status.dwAvailPhys + mem_status.dwAvailPageFile < buf_size) { + buf_size = mem_status.dwAvailPhys + mem_status.dwAvailPageFile - 1048576; + dr_dprintf("Win32AllocateActionReplayBuffer(): ...but there's only %d bytes available...", buf_size); + } + if (buf_size < 65536) { + buf_size = 65536; + dr_dprintf("Win32AllocateActionReplayBuffer(): ...but we have to have a minimum size of %d bytes...", 65536); + } + while (buf_size >= 65536) { + buf = malloc(buf_size); + if (buf) { + break; + } + buf_size -= 65536; + } + gWin32_action_replay_buffer = buf; + if (buf) { + gWin32_action_replay_buffer_size = buf_size; + Sleep_(1000u); + } else { + gWin32_action_replay_buffer_size = 0; + } + dr_dprintf("Win32AllocateActionReplayBuffer(): Actually allocated %d bytes.", buf_size); + GlobalMemoryStatus_(&mem_status); + dr_dprintf( + "Win32AllocateActionReplayBuffer(): Memory Status AFTER Action Replay Allocation:\n" + " dwLength %u\n" + " dwMemoryLoad %u\n" + " dwTotalPhys %u\n" + " dwAvailPhys %u\n" + " dwTotalPageFile %u\n" + " dwAvailPageFile %u\n" + " dwTotalVirtual %u\n" + " dwAvailVirtual %u", + mem_status.dwLength, + mem_status.dwMemoryLoad, + mem_status.dwTotalPhys, + mem_status.dwAvailPhys, + mem_status.dwTotalPageFile, + mem_status.dwAvailPageFile, + mem_status.dwTotalVirtual, + mem_status.dwAvailVirtual); +} + +void PDAllocateActionReplayBuffer(char** pBuffer, tU32* pBuffer_size) { + LOG_TRACE("(%p, %p)", pBuffer, pBuffer_size); + + Win32AllocateActionReplayBuffer(); + *pBuffer = gWin32_action_replay_buffer; + *pBuffer_size = gWin32_action_replay_buffer_size; +} + +void PDDisposeActionReplayBuffer(char* pBuffer) { + LOG_TRACE("(\"%s\")", pBuffer); +} + +// this function is taken from dossys +void Usage(char* pProgpath) { + char base_name[256]; // fix: changed from 9 to avoid overflow on longer filenames + + _splitpath_(pProgpath, NULL, NULL, base_name, NULL); + + 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", + base_name, + "-hires", + "-yon", + "-simple", + "-sound", + "-robots", + "-lomem", + "-nosound", + "-spamfritter", + "-nocutscenes", + "-noreplay", + CAR_MAX_SIMPLIFICATION_LEVEL); + exit(1); +} + +// Renamed from "main" to "original_main" to allow for harness + unit testing +int original_main(int pArgc, char** pArgv) { + int arg; + int i; + float f; + + for (i = 1; i < pArgc; i++) { + if (strcasecmp(pArgv[i], "-hires") == 0) { + gGraf_spec_index = 1; + } else if (strcasecmp(pArgv[i], "-yon") == 0 && i < pArgc - 1) { + i++; + sscanf(pArgv[i], "%f", &f); + if (f >= 0.0 && f <= 1.0f) { + gYon_multiplier = f; + } + } else if (strcasecmp(pArgv[i], "-simple") == 0 && i < pArgc - 1) { + i++; + sscanf(pArgv[i], "%d", &arg); + if (arg >= 0 && arg < 5) { + gCar_simplification_level = arg; + } + } else if (strcasecmp(pArgv[i], "-sound") == 0 && i < pArgc - 1) { + i++; + sscanf(pArgv[i], "%d", &arg); + gSound_detail_level = arg; + + } else if (strcasecmp(pArgv[i], "-robots") == 0) { + gSausage_override = 1; + } else if (strcasecmp(pArgv[i], "-lomem") == 0) { + gAustere_override = 1; + } else if (strcasecmp(pArgv[i], "-nosound") == 0) { + gSound_override = 1; + } else if (strcasecmp(pArgv[i], "-spamfritter") == 0) { + gExtra_mem = 2000000; + } else if (strcasecmp(pArgv[i], "-nocutscenes") == 0) { + gCut_scene_override = 1; + } else if (strcasecmp(pArgv[i], "-noreplay") == 0) { + gReplay_override = 1; + } else { + Usage(pArgv[0]); + } + } + + gNetwork_profile_fname[0] = 0; + uint32_t len = GetCurrentDirectoryA_(240, gNetwork_profile_fname); + if (len > 0 && len == strlen(gNetwork_profile_fname)) { + gNetwork_profile_file_exists = 1; + strcat(gNetwork_profile_fname, "/"); + strcat(gNetwork_profile_fname, "NETWORK.INI"); + } + + GameMain(pArgc, pArgv); + return 0; +} + +int OurGetChar() { + int key; + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +void PDEnterDebugger(char* pStr) { + static unsigned char* save_it; + LOG_TRACE("(\"%s\")", pStr); + + dr_dprintf("PDEnterDebugger(): %s", pStr); + ShowCursor_(1); +#ifdef DETHRACE_FIX_BUGS + if (strcmp(pStr, "Bet you weren't expecting this") != 0 +#else + if (pStr != "Bet you weren't expecting this" +#endif + && _CrtDbgReport_(_CRT_ASSERT, "C:\\Msdev\\Projects\\DethRace\\Win95sys.c", 437, 0, 0) == 1) { + + abort(); // original: __debugbreak(); + } + ShowCursor_(0); +} + +// Added function +br_material* PDMissingMaterial(char* name) { + LOG_TRACE("(\"%s\")", name); + + // FIXME: call functiont in harness + dr_dprintf("SOMETHING MISSING WARNING - Can't find material '%s'", name); + return NULL; +} + +// Added function +br_pixelmap* PDMissingTable(char* name) { + LOG_TRACE("(\"%s\")", name); + + // FIXME: call function in harness + dr_dprintf("SOMETHING MISSING WARNING - Can't find shade table '%s'", name); + return NULL; +} + +// Added function +br_model* PDMissingModel(char* name) { + LOG_TRACE("(\"%s\")", name); + + // FIXME: call function in harness + dr_dprintf("SOMETHING MISSING WARNING - Can't find model '%s'", name); + return NULL; +} + +// Added function +br_pixelmap* PDMissingMap(char* name) { + LOG_TRACE("(\"%s\")", name); + + // FIXME: call function in harness + dr_dprintf("SOMETHING MISSING WARNING - Can't find pixelmap '%s'", name); + return NULL; +} + +void PDEndItAllAndReRunTheBastard() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int InitJoysticks() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +tU32 ReadJoystickAxis(int pBit) { + tU32 val; + tU32 count; + LOG_TRACE("(%d)", pBit); + NOT_IMPLEMENTED(); +} + +void PDReadJoySticks() { + tU32 temp1x; + tU32 temp1y; + tU32 temp2x; + tU32 temp2y; + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +tS32 PDGetJoy1X() { + tS32 joy; + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +tS32 PDGetJoy1Y() { + tS32 joy; + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +tS32 PDGetJoy2X() { + tS32 joy; + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +tS32 PDGetJoy2Y() { + tS32 joy; + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int PDGetJoy1Button1() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int PDGetJoy1Button2() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int PDGetJoy1Button3() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int PDGetJoy1Button4() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int PDGetJoy2Button1() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int PDGetJoy2Button2() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int PDGetJoy2Button3() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int PDGetJoy2Button4() { + LOG_TRACE("()"); + NOT_IMPLEMENTED(); +} + +int PDFileUnlock(char* pThe_path) { + uint32_t dwFileAttributes; // [esp+Ch] [ebp-4h] + LOG_TRACE("(\"%s\")", pThe_path); + + dwFileAttributes = GetFileAttributesA_(pThe_path); + return dwFileAttributes != INVALID_FILE_ATTRIBUTES && SetFileAttributesA_(pThe_path, dwFileAttributes & ~FILE_ATTRIBUTE_READONLY); +} + +int PDCheckDriveExists2(char* pThe_path, char* pFile_name, tU32 pMin_size) { + + char the_path[256]; // [esp+Ch] [ebp-108h] BYREF + tU32 file_size; // [esp+10Ch] [ebp-8h] + HANDLE_ hFile; // [esp+110h] [ebp-4h] + LOG_TRACE("(\"%s\", \"%s\", %d)", pThe_path, pFile_name, pMin_size); + + file_size = 0; + if (pFile_name) { + PathCat(the_path, pThe_path, pFile_name); + } else { + strcpy(the_path, pThe_path); + } + if (the_path[0] && the_path[1] == ':' && !the_path[2]) { + strcat(the_path, gDir_separator); + } + if (GetFileAttributesA_(pThe_path) == INVALID_FILE_ATTRIBUTES) { + return 0; + } + hFile = CreateFileA_(the_path, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (hFile != INVALID_HANDLE_VALUE) { + file_size = GetFileSize_(hFile, 0); + CloseHandle_(hFile); + } + return file_size >= pMin_size; +} + +int PDDoWeLeadAnAustereExistance() { + return 0; +} + +// Windows-specific functions. The only name we know for sure is "Win32AllocateReplayBuffer". + +void Win32BRenderWarningFunc(char* msg) { + dr_dprintf("*******************************************************************************"); + dr_dprintf("BRender WARNING: '%s'", msg); + dr_dprintf("*******************************************************************************"); +} + +void Win32BRenderFailureFunc(char* msg) { + dr_dprintf("*******************************************************************************"); + dr_dprintf("BRender FAILURE: '%s'", msg); + dr_dprintf("*******************************************************************************"); + Win32FatalError("BRender error detected:", msg); +} diff --git a/src/DETHRACE/pd/net.h b/src/DETHRACE/pd/net.h index 0ff68382..53dae38b 100644 --- a/src/DETHRACE/pd/net.h +++ b/src/DETHRACE/pd/net.h @@ -34,33 +34,33 @@ // int BroadcastMessage(void); -// BOOL hmiIPXCloseSocket(W32 wSocket); +// int hmiIPXCloseSocket(W32 wSocket); // void hmiIPXListenForPacket(_IPX_ECB* pECB_ptr, tU32 pOffset); -// BOOL hmiIPXPostListen(_IPX_ECB* pECB_ptr, tU32 pOffset); +// int hmiIPXPostListen(_IPX_ECB* pECB_ptr, tU32 pOffset); -// BOOL hmiIPXGetData(PSTR pData, tU32 wDSize); +// int hmiIPXGetData(PSTR pData, tU32 wDSize); // void hmiIPXSendPacket(_IPX_ECB* sECB, _IPX_ECB** pPacket, PSTR pHeader, W32 wSize); -// BOOL hmiIPXSendDataDirect(PSTR pHeader, W32 wHSize, PSTR pData, W32 wDSize, _NETNOW_NODE_ADDR* sNode); +// int hmiIPXSendDataDirect(PSTR pHeader, W32 wHSize, PSTR pData, W32 wDSize, _NETNOW_NODE_ADDR* sNode); // void hmiIPXGetInternetworkAddr(_IPX_INTERNET_ADDR* sInterworkAddr); // void hmiIPXGetLocalTarget(_IPX_LOCAL_TARGET* sNetworkAddr); -// BOOL AllocateRealMem(W32 wSize, PSTR* pPtr, W32* pSegment, tU16* pSelector); +// int AllocateRealMem(W32 wSize, PSTR* pPtr, W32* pSegment, tU16* pSelector); -// BOOL FreeRealMem(tU16 pSelector); +// int FreeRealMem(tU16 pSelector); -// BOOL hmiIPXInstalled(void); +// int hmiIPXInstalled(void); -// BOOL hmiIPXOpenSocket(W32 wSocket); +// int hmiIPXOpenSocket(W32 wSocket); // void GetLargestPacketSizeOoErBetterInsertLinfordChristieJokeHere(void); -// BOOL hmiIPXInitSystem(W32 wSocket); +// int hmiIPXInitSystem(W32 wSocket); // void GetIPXToStickItsEarToTheGround(void); diff --git a/src/DETHRACE/pd/sys.h b/src/DETHRACE/pd/sys.h index 4a06bdc4..d9ddead3 100644 --- a/src/DETHRACE/pd/sys.h +++ b/src/DETHRACE/pd/sys.h @@ -39,38 +39,42 @@ extern int gReplay_override; extern br_pixelmap* gReal_back_screen; extern tS32 gJoystick_min1x; extern br_pixelmap* gTemp_screen; -//extern int gDOSGfx_initialized; +extern int gDOSGfx_initialized; extern tU32 gUpper_loop_limit; extern int gExtra_mem; extern int gReal_back_screen_locked; extern void (*gPrev_keyboard_handler)(void); -extern tU8 gScan_code[123][2]; + +// DOS +// extern tU8 gScan_code[123][2]; +// Windows +extern tU32 gScan_code[123]; extern char* _unittest_last_fatal_error; // void KeyboardHandler(void); -//int KeyDown(tU8 pScan_code); +// int KeyDown(tU8 pScan_code); // void KeyTranslation(tU8 pKey_index, tU8 pScan_code_1, tU8 pScan_code_2); -//void KeyBegin(void); +// void KeyBegin(void); -//void KeyEnd(void); +// void KeyEnd(void); -//int KeyDown22(int pKey_index); +// int KeyDown22(int pKey_index); void PDSetKeyArray(int* pKeys, int pMark); int PDGetASCIIFromKey(int pKey); -HARNESS_NORETURN void PDFatalError(char* pThe_str); +void PDFatalError(char* pThe_str); void PDNonFatalError(char* pThe_str); void PDInitialiseSystem(void); -void PDShutdownSystem(void); +HARNESS_NORETURN void PDShutdownSystem(void); void PDSaveOriginalPalette(void); @@ -86,17 +90,17 @@ void PDUnlockRealBackScreen(void); void PDAllocateScreenAndBack(void); -//void Copy8BitTo16BitPixelmap(br_pixelmap* pDst, br_pixelmap* pSrc, br_pixelmap* pPalette); +// void Copy8BitTo16BitPixelmap(br_pixelmap* pDst, br_pixelmap* pSrc, br_pixelmap* pPalette); -//void Double8BitTo16BitPixelmap(br_pixelmap* pDst, br_pixelmap* pSrc, br_pixelmap* pPalette, tU16 pOff, tU16 pSrc_width, tU16 pSrc_height); +// void Double8BitTo16BitPixelmap(br_pixelmap* pDst, br_pixelmap* pSrc, br_pixelmap* pPalette, tU16 pOff, tU16 pSrc_width, tU16 pSrc_height); br_pixelmap* PDInterfacePixelmap(void); -//void SwapBackScreen(void); +// void SwapBackScreen(void); -//void ReallyCopyBackScreen(int pRendering_area_only, int pClear_top_and_bottom); +// void ReallyCopyBackScreen(int pRendering_area_only, int pClear_top_and_bottom); -//void CopyBackScreen(int pRendering_area_only); +// void CopyBackScreen(int pRendering_area_only); void PDScreenBufferSwap(int pRendering_area_only); @@ -130,7 +134,7 @@ int PDGetTotalTime(void); int PDServiceSystem(tU32 pTime_since_last_call); -//tU32 LargestBlockAvail(void); +// tU32 LargestBlockAvail(void); void* PDGrabLargestMammaryWeCanPlayWith(tU32 pMaximum_required, tU32* pAmount_allocated); @@ -138,15 +142,15 @@ void PDAllocateActionReplayBuffer(char** pBuffer, tU32* pBuffer_size); void PDDisposeActionReplayBuffer(char* pBuffer); -//void Usage(char* pProgpath); +// void Usage(char* pProgpath); -//int OurGetChar(void); +// int OurGetChar(void); int PDGetGorePassword(void); void PDDisplayGoreworthiness(int pGory); -HARNESS_NORETURN void PDEnterDebugger(char* pStr); +void PDEnterDebugger(char* pStr); // Added function br_material* PDMissingMaterial(char* name); @@ -162,15 +166,15 @@ br_pixelmap* PDMissingMap(char* name); void PDEndItAllAndReRunTheBastard(void); -//int matherr(struct exception_* err); +// int matherr(struct exception_* err); -//int LoopLimitTooLow(tU32 limit); +// int LoopLimitTooLow(tU32 limit); -//tS32 UpperLoopLimit(void); +// tS32 UpperLoopLimit(void); -//int InitJoysticks(void); +// int InitJoysticks(void); -//tU32 ReadJoystickAxis(int pBit); +// tU32 ReadJoystickAxis(int pBit); void PDReadJoySticks(void); diff --git a/src/S3/s3_defs.h b/src/S3/s3_defs.h index b1b0cfbf..1ee06c2b 100644 --- a/src/S3/s3_defs.h +++ b/src/S3/s3_defs.h @@ -200,6 +200,4 @@ typedef struct tWAVEFORMATEX_ { } tWAVEFORMATEX_; #pragma pack(pop) -#define MAX_PATH_LENGTH 256 - -#endif \ No newline at end of file +#endif diff --git a/src/S3/s3sound.c b/src/S3/s3sound.c index 452ad200..31e96670 100644 --- a/src/S3/s3sound.c +++ b/src/S3/s3sound.c @@ -7,6 +7,7 @@ #include #include +#define MAX_PATH_LENGTH 1024 extern void dr_dprintf(char* fmt_string, ...); int gS3_sample_filter_funcs_registered; @@ -17,10 +18,12 @@ tS3_sample_filter* gS3_sample_filter_disable_func; extern ma_engine miniaudio_engine; int S3LoadSample(tS3_sound_id id) { + // changed by dethrace for compatibility + // char filename[80]; // [esp+10h] [ebp-5Ch] BYREF + char filename[MAX_PATH_LENGTH]; + tS3_descriptor* descriptor; // [esp+60h] [ebp-Ch] + tS3_sample* sample; // [esp+68h] [ebp-4h] // LPDIRECTSOUNDBUFFER WavFile; // eax - char filename[MAX_PATH_LENGTH]; // [esp+10h] [ebp-5Ch] BYREF - tS3_descriptor* descriptor; // [esp+60h] [ebp-Ch] - tS3_sample* sample; // [esp+68h] [ebp-4h] if (!gS3_enabled) { return 0; diff --git a/src/harness/CMakeLists.txt b/src/harness/CMakeLists.txt index eb3229bb..f419a4fa 100644 --- a/src/harness/CMakeLists.txt +++ b/src/harness/CMakeLists.txt @@ -48,19 +48,20 @@ target_sources(harness PRIVATE include/harness/trace.h include/harness/config.h include/harness/os.h - + include/harness/win95_polyfill.h + include/harness/win95_polyfill_defs.h # cameras/debug_camera.c # cameras/debug_camera.h harness_trace.c harness.c harness.h - io_platforms/io_platform.h - renderers/null.h - renderers/renderer.h brender_emu/renderer_impl.c brender_emu/renderer_impl.h sound/sound.c sound/sound.h + win95/polyfill.c + platforms/null.h + "${CMAKE_CURRENT_BINARY_DIR}/version.h" ) @@ -75,7 +76,8 @@ if (IO_PLATFORM STREQUAL "SDL_OpenGL") endforeach() target_sources(harness PRIVATE - io_platforms/sdl_gl.c + platforms/sdl_opengl.c + platforms/sdl2_scancode_to_dinput.h renderers/gl/gl_renderer.c renderers/gl/gl_renderer.h renderers/gl/stored_context.c diff --git a/src/harness/harness.c b/src/harness/harness.c index 4bf1d440..d88ec26d 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -1,9 +1,9 @@ #include "harness.h" #include "brender_emu/renderer_impl.h" #include "include/harness/config.h" +#include "include/harness/hooks.h" #include "include/harness/os.h" -#include "io_platforms/io_platform.h" -#include "renderers/null.h" +#include "platforms/null.h" #include "sound/sound.h" #include "version.h" @@ -12,7 +12,6 @@ #include #include -tRenderer* renderer; br_pixelmap* palette; uint32_t* screen_buffer; harness_br_renderer* renderer_state; @@ -21,10 +20,10 @@ br_pixelmap* last_dst = NULL; br_pixelmap* last_src = NULL; unsigned int last_frame_time = 0; -int force_nullrenderer = 0; +int force_null_platform = 0; extern unsigned int GetTotalTime(); -extern uint8_t gScan_code[123][2]; + extern br_v1db_state v1db; extern uint32_t gI_am_cheating; @@ -34,6 +33,9 @@ tHarness_game_info harness_game_info; // Configuration options tHarness_game_config harness_game_config; +// Platform hooks +tHarness_platform gHarness_platform; + /* clang-format off */ // German ASCII codes static int carmageddon_german_ascii_table[128] = { @@ -78,6 +80,8 @@ static int splatpack_xmasdemo_ascii_shift_table[128] = { }; /* clang-format on */ +extern void Harness_Platform_Init(); + int Harness_ProcessCommandLine(int* argc, char* argv[]); void Harness_DetectGameMode() { @@ -221,19 +225,16 @@ void Harness_Init(int* argc, char* argv[]) { Harness_DetectGameMode(); } - IOPlatform_Init(); - int* keymap = IOPlatform_GetKeyMap(); - if (keymap != NULL) { - for (int i = 0; i < 123; i++) { - gScan_code[i][0] = keymap[i]; - } + if (force_null_platform) { + Null_Platform_Init(&gHarness_platform); + } else { + Harness_Platform_Init(&gHarness_platform); } } // used by unit tests -void Harness_ForceNullRenderer() { - force_nullrenderer = 1; - renderer = &null_renderer; +void Harness_ForceNullPlatform() { + force_null_platform = 1; } int Harness_ProcessCommandLine(int* argc, char* argv[]) { @@ -306,50 +307,14 @@ int Harness_ProcessCommandLine(int* argc, char* argv[]) { return 0; } -void Harness_Hook_GraphicsInit(int render_width, int render_height) { - int window_width, window_height; - if (force_nullrenderer) { - return; - } - if (render_width == 320) { - window_width = render_width * 2; - window_height = render_height * 2; - } else { - window_width = render_width; - window_height = render_height; - } - renderer = IOPlatform_CreateWindow("Dethrace", window_width, window_height, render_width, render_height); -} - -void Harness_Hook_PDShutdownSystem() { - IOPlatform_Shutdown(); -} - // Render 2d back buffer void Harness_RenderScreen(br_pixelmap* dst, br_pixelmap* src) { - renderer->FullScreenQuad((uint8_t*)src->pixels); + gHarness_platform.Renderer_FullScreenQuad((uint8_t*)src->pixels); last_dst = dst; last_src = src; } -void Harness_Hook_BrDevPaletteSetOld(br_pixelmap* pm) { - renderer->SetPalette((uint8_t*)pm->pixels); - palette = pm; - - if (last_dst) { - Harness_RenderScreen(last_dst, last_src); - IOPlatform_SwapWindow(0); - } -} - -void Harness_Hook_BrDevPaletteSetEntryOld(int i, br_colour colour) { - if (palette != NULL) { - uint32_t* colors = palette->pixels; - colors[i] = colour; - } -} - void Harness_Hook_BrV1dbRendererBegin(br_v1db_state* v1db) { renderer_state = NewHarnessBrRenderer(); v1db->renderer = (br_renderer*)renderer_state; @@ -375,18 +340,8 @@ int Harness_CalculateFrameDelay() { return 0; } -// Begin 3d scene -void Harness_Hook_BrZbSceneRenderBegin(br_actor* world, br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer) { - renderer->BeginScene(camera, colour_buffer, depth_buffer); -} - void Harness_Hook_renderActor(br_actor* actor, br_model* model, br_material* material, br_token type) { - renderer->Model(actor, model, material, type, renderer_state->state.matrix.model_to_view); -} - -void Harness_Hook_BrZbSceneRenderEnd() { - renderer->FlushBuffers(eFlush_all); - renderer->EndScene(); + gHarness_platform.Renderer_Model(actor, model, material, type, renderer_state->state.matrix.model_to_view); } // Called by game to swap buffers at end of frame rendering @@ -396,54 +351,22 @@ void Harness_Hook_BrPixelmapDoubleBuffer(br_pixelmap* dst, br_pixelmap* src) { Harness_RenderScreen(dst, src); int delay_ms = Harness_CalculateFrameDelay(); - IOPlatform_SwapWindow(delay_ms); - - renderer->ClearBuffers(); - IOPlatform_PollEvents(); + gHarness_platform.SwapWindow(); + if (delay_ms > 0) { + gHarness_platform.Sleep(delay_ms); + } + gHarness_platform.Renderer_ClearBuffers(); last_frame_time = GetTotalTime(); } -int Harness_Hook_KeyDown(unsigned char pScan_code) { - return IOPlatform_IsKeyDown(pScan_code); -} - -void Harness_Hook_PDServiceSystem() { - IOPlatform_PollEvents(); -} -void Harness_Hook_PDSetKeyArray() { - IOPlatform_PollEvents(); -} - -void Harness_Hook_FlushRenderer() { - renderer->FlushBuffers(eFlush_all); -} - -void Harness_Hook_BrMaterialUpdate(br_material* mat, br_uint_16 flags) { - 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) { - renderer->BufferTexture(pm); - } else { - LOG_PANIC("use %d", use); +void Harness_RenderLastScreen() { + if (last_dst) { + Harness_RenderScreen(last_dst, last_src); + gHarness_platform.SwapWindow(0); } } -void Harness_Hook_BrModelUpdate(br_model* model) { - renderer->BufferModel(model); -} - -// Input hooks -void Harness_Hook_GetMousePosition(int* pX, int* pY) { - IOPlatform_GetMousePosition(pX, pY); -} - -void Harness_Hook_GetMouseButtons(int* pButton1, int* pButton2) { - IOPlatform_GetMouseButtons(pButton1, pButton2); -} - // Filesystem hooks FILE* Harness_Hook_fopen(const char* pathname, const char* mode) { return OS_fopen(pathname, mode); diff --git a/src/harness/harness.h b/src/harness/harness.h index f5b6708c..76c418da 100644 --- a/src/harness/harness.h +++ b/src/harness/harness.h @@ -4,7 +4,7 @@ #include "brender/br_types.h" #include "harness/trace.h" -void Harness_ForceNullRenderer(); +void Harness_ForceNullPlatform(); typedef struct tCamera { void (*update)(); @@ -13,6 +13,4 @@ typedef struct tCamera { void (*setPosition)(); } tCamera; - - -#endif \ No newline at end of file +#endif diff --git a/src/harness/include/harness/hooks.h b/src/harness/include/harness/hooks.h index c66e46fc..50a6b407 100644 --- a/src/harness/include/harness/hooks.h +++ b/src/harness/include/harness/hooks.h @@ -2,37 +2,75 @@ #define HARNESS_HOOKS_H #include "brender/br_types.h" - +#include "harness/win95_polyfill_defs.h" #include +typedef enum { + eFlush_all, + eFlush_color_buffer +} tRenderer_flush_type; + +// Platform implementation functions +typedef struct tHarness_platform { + // Initialize the renderer + void (*Renderer_Init)(int width, int height, int pRender_width, int pRender_height); + // Called when beginning a 3D scene + void (*Renderer_BeginScene)(br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer); + // Called at the end of a 3D scene + void (*Renderer_EndScene)(); + // Render a fullscreen quad using the specified pixel data + void (*Renderer_FullScreenQuad)(uint8_t* src); + // Render a model + void (*Renderer_Model)(br_actor* actor, br_model* model, br_material* material, br_token render_type, br_matrix34 model_matrix); + // Clear frame and depth buffers + void (*Renderer_ClearBuffers)(); + // Load pixelmap into video memory + void (*Renderer_BufferTexture)(br_pixelmap* pm); + // Load material + void (*Renderer_BufferMaterial)(br_material* mat); + // Load model into video memory + void (*Renderer_BufferModel)(br_model* model); + // Pull contents of frame and depth buffers from video into main memory for software effects + void (*Renderer_FlushBuffers)(); + // Set the 256 color palette to use (BGRA format) + void (*Renderer_SetPalette)(PALETTEENTRY_* palette); + // Set the viewport for 3d rendering + void (*Renderer_SetViewport)(int x, int y, int width, int height); + // Create a window. Return a handle to the window + void* (*CreateWindowAndRenderer)(char* title, int x, int y, int nWidth, int nHeight); + // Get mouse button state + int (*GetMouseButtons)(int* button_1, int* button_2); + // Get mouse position + int (*GetMousePosition)(int* pX, int* pY); + // Close specified window + void (*DestroyWindow)(void* window); + // Process window messages, return any WM_QUIT message + int (*ProcessWindowMessages)(MSG_* msg); + // Set position of a window + int (*SetWindowPos)(void* hWnd, int x, int y, int nWidth, int nHeight); + // Show/hide the cursor + int (*ShowCursor)(int show); + // Get keyboard state. Expected to be in DirectInput key codes + void (*GetKeyboardState)(unsigned int count, uint8_t* buffer); + // Sleep + void (*Sleep)(uint32_t dwMilliseconds); + // Get ticks + uint32_t (*GetTicks)(); + // Swap window + void (*SwapWindow)(); + +} tHarness_platform; + +extern tHarness_platform gHarness_platform; + void Harness_Init(int* argc, char* argv[]); // Hooks are called from original game code. -// Dethrace hooks -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_FlushRenderer(); // synchronize in-memory framebuffer and depthbuffer -void Harness_Hook_GraphicsInit(int render_width, int render_height); -void Harness_Hook_PDShutdownSystem(); - // BRender hooks -void Harness_Hook_BrDevPaletteSetOld(br_pixelmap* pm); -void Harness_Hook_BrDevPaletteSetEntryOld(int i, br_colour colour); void Harness_Hook_BrPixelmapDoubleBuffer(br_pixelmap* dst, br_pixelmap* src); void Harness_Hook_BrV1dbRendererBegin(br_v1db_state* v1db); -void Harness_Hook_BrZbSceneRenderBegin(br_actor* world, br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer); void Harness_Hook_renderActor(br_actor* actor, br_model* model, br_material* material, br_token type); -void Harness_Hook_BrZbSceneRenderEnd(); -void Harness_Hook_BrBufferUpdate(br_pixelmap* pm, br_token use, br_uint_16 flags); -void Harness_Hook_BrMaterialUpdate(br_material* mat, br_uint_16 flags); -void Harness_Hook_BrModelUpdate(br_model* model); - -// Input hooks -void Harness_Hook_GetMousePosition(int* pX, int* pY); -void Harness_Hook_GetMouseButtons(int* pButton1, int* pButton2); // Sound hooks void Harness_Hook_S3Service(int unk1, int unk2); @@ -41,4 +79,6 @@ void Harness_Hook_S3StopAllOutletSounds(); // Filesystem hooks FILE* Harness_Hook_fopen(const char* pathname, const char* mode); +void Harness_RenderLastScreen(); + #endif diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h index c66cfbbb..4e543426 100644 --- a/src/harness/include/harness/os.h +++ b/src/harness/include/harness/os.h @@ -23,32 +23,11 @@ #include #endif -// 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: copy the `basename` component of `path` into `base` -void OS_Basename(char* path, char* base); - -// 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); FILE* OS_fopen(const char* pathname, const char* mode); -// Required: return a buffer for action replay. Preferably 20MB. If that is not available, then allocate a buffer of 12MB, 6MB, 4MB, 500kB or 64kiB -void OS_AllocateActionReplayBuffer(char** pBuffer, unsigned* pBuffer_size); - size_t OS_ConsoleReadPassword(char* pBuffer, size_t pBufferLen); #endif diff --git a/src/harness/include/harness/trace.h b/src/harness/include/harness/trace.h index b0cf62d7..4c92d393 100644 --- a/src/harness/include/harness/trace.h +++ b/src/harness/include/harness/trace.h @@ -42,10 +42,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 (OS_IsDebuggerPresent()) { \ - abort(); \ - } \ - exit(1); \ + abort(); \ } while (0) #define LOG_WARN_ONCE(...) \ diff --git a/src/harness/include/harness/win95_polyfill.h b/src/harness/include/harness/win95_polyfill.h new file mode 100644 index 00000000..1a9bb626 --- /dev/null +++ b/src/harness/include/harness/win95_polyfill.h @@ -0,0 +1,88 @@ +#ifndef _POLYFILL_H_ +#define _POLYFILL_H_ + +#include "harness/compiler.h" +#include "win95_polyfill_defs.h" +#include +#include +#include +#include +#include + +// All functions have a "_" suffix to avoid collisions with -defined types + +uint32_t GetFileAttributesA_(char* path); + +int SetFileAttributesA_(char* lpFileName, uint32_t dwFileAttributes); + +void* CreateFileA_( + char* lpFileName, + uint32_t dwDesiredAccess, + uint32_t dwShareMode, + void* lpSecurityAttributes, + uint32_t dwCreationDisposition, + uint32_t dwFlagsAndAttributes, + void* hTemplateFile); + +uint32_t GetFileSize_( + void* hFile, + uint32_t* lpFileSizeHigh); + +int CloseHandle_( + void* hObject); + +void GlobalMemoryStatus_(MEMORYSTATUS_* lpBuffer); + +int GetCursorPos_(POINT_* lpPoint); + +int ScreenToClient_(void* hWnd, POINT_* lpPoint); + +uint32_t timeGetTime_(); + +uint32_t GetCurrentDirectoryA_(uint32_t nBufferLength, char* lpBuffer); + +int SetCurrentDirectoryA_(char* lpPathName); + +uint32_t GetShortPathNameA_(char* lpszLongPath, char* lpszShortPath, uint32_t cchBuffer); + +HANDLE_ FindFirstFileA_(char* lpFileName, WIN32_FIND_DATAA_* lpFindFileData); + +int FindNextFileA_(HANDLE_ hFindFile, WIN32_FIND_DATAA_* lpFindFileData); + +int FindClose_(HANDLE_ hFindFile); + +void* CreateWindowExA_(uint32_t dwExStyle, char* lpClassName, char* lpWindowName, uint32_t dwStyle, int X, int Y, int nWidth, int nHeight, void* hWndParent, void* hMenu, void* hInstance, void* lpParam); + +int SetWindowPos_(void* hWnd, void* hWndInsertAfter, int X, int Y, int cx, int cy, unsigned int uFlags); + +int ShowCursor_(int bShow); + +int SendMessageA_(void* hWnd, unsigned int Msg, unsigned int wParam, long lParam); + +int MessageBoxA_(void* hWnd, char* lpText, char* lpCaption, unsigned int uType); + +int DestroyWindow_(void* hWnd); + +HARNESS_NORETURN void ExitProcess_(unsigned int uExitCode); + +void TranslateMessage_(MSG_* lpMsg); + +void DispatchMessageA_(MSG_* lpMsg); + +int PeekMessageA_(MSG_* lpMsg, void* hWnd, unsigned int wMsgFilterMin, unsigned int wMsgFilterMax, unsigned int wRemoveMsg); + +int GetMessageA_(MSG_* lpMsg, void* hWnd, unsigned int wMsgFilterMin, unsigned int wMsgFilterMax); + +void Sleep_(uint32_t dwMilliseconds); + +void DirectDraw_CreateSurface(); + +void DirectDrawDevice_SetPaletteEntries(PALETTEENTRY_* palette, int pFirst_colour, int pCount); + +void DirectInputDevice_GetDeviceState(unsigned int keys, uint8_t* buffer); + +void _splitpath_(char* path, char* drive, char* dir, char* fname, char* ext); + +int _CrtDbgReport_(int reportType, const char* filename, int linenumber, const char* moduleName, const char* format, ...); + +#endif diff --git a/src/harness/include/harness/win95_polyfill_defs.h b/src/harness/include/harness/win95_polyfill_defs.h new file mode 100644 index 00000000..b95b35a3 --- /dev/null +++ b/src/harness/include/harness/win95_polyfill_defs.h @@ -0,0 +1,72 @@ +#ifndef WIN95_POLYFILL_TYPES_H +#define WIN95_POLYFILL_TYPES_H + +#include +#include + +typedef void* HANDLE_; + +#define GENERIC_READ 0x80000000 +#define OPEN_EXISTING 3 +#define FILE_ATTRIBUTE_NORMAL 0x80 +#define INVALID_HANDLE_VALUE ((HANDLE_*)-1) +#define INVALID_FILE_ATTRIBUTES -1 + +#define FILE_ATTRIBUTE_READONLY 0x01 +#define FILE_ATTRIBUTE_NORMAL 0x80 + +#define HWND_BROADCAST ((void*)0xffff) + +#define _CRT_ASSERT 2 + +#define WM_QUIT 0x0012 + +typedef struct _MEMORYSTATUS_ { + uint32_t dwLength; + uint32_t dwMemoryLoad; + size_t dwTotalPhys; + size_t dwAvailPhys; + size_t dwTotalPageFile; + size_t dwAvailPageFile; + size_t dwTotalVirtual; + size_t dwAvailVirtual; +} MEMORYSTATUS_; + +typedef struct tagPOINT_ { + long x; + long y; +} POINT_; + +#pragma pack(push, 1) +typedef struct tagPALETTEENTRY_ { + uint8_t peRed; + uint8_t peGreen; + uint8_t peBlue; + uint8_t peFlags; +} PALETTEENTRY_; +#pragma pack(pop) + +typedef struct _WIN32_FIND_DATA_ { + // uint32_t dwFileAttributes; + // FILETIME ftCreationTime; + // FILETIME ftLastAccessTime; + // FILETIME ftLastWriteTime; + // uint32_t nFileSizeHigh; + // uint32_t nFileSizeLow; + // uint32_t dwReserved0; + // uint32_t dwReserved1; + char cFileName[1024]; + // char cAlternateFileName[14]; +} WIN32_FIND_DATAA_; + +typedef struct tagMSG_ { + void* hwnd; + unsigned int message; + int wParam; + long lParam; + uint32_t time; + POINT_ pt; + uint32_t lPrivate; +} MSG_; + +#endif diff --git a/src/harness/io_platforms/io_platform.h b/src/harness/io_platforms/io_platform.h deleted file mode 100644 index 68ed7e79..00000000 --- a/src/harness/io_platforms/io_platform.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef PLATFORM_H -#define PLATFORM_H - -#include "../renderers/renderer.h" - -void IOPlatform_Init(); -tRenderer* IOPlatform_CreateWindow(char* title, int width, int height, int pRender_width, int pRender_height); -void IOPlatform_PollEvents(void); -void IOPlatform_SwapWindow(int delay_ms_after_swap); -int* IOPlatform_GetKeyMap(void); -int IOPlatform_IsKeyDown(unsigned char scan_code); -void IOPlatform_GetMousePosition(int* pX, int* pY); -void IOPlatform_GetMouseButtons(int* pButton1, int* pButton2); -void IOPlatform_Shutdown(); - -#endif diff --git a/src/harness/io_platforms/sdl_gl.c b/src/harness/io_platforms/sdl_gl.c deleted file mode 100644 index ba62fdc1..00000000 --- a/src/harness/io_platforms/sdl_gl.c +++ /dev/null @@ -1,339 +0,0 @@ -#include - -// this needs to be included after glad.h -#include -#include - -#include "../renderers/gl/gl_renderer.h" -#include "../renderers/renderer.h" - -#include "harness/config.h" -#include "harness/trace.h" - -#include "globvars.h" -#include "grafdata.h" -#include "pd/sys.h" - -extern void QuitGame(); - -#define ARRAY_LEN(array) (sizeof((array)) / sizeof((array)[0])) - -int scancode_map[123]; -const int scancodes_dethrace2sdl[123] = { - -1, // 0 (LSHIFT || RSHIFT) - -1, // 1 (LALT || RALT) - -1, // 2 (LCTRL || RCTRL) - -1, // 3 (LCTRL || RCTRL) - SDL_SCANCODE_CAPSLOCK, // 4 - SDL_SCANCODE_RSHIFT, // 5 - SDL_SCANCODE_RALT, // 6 - SDL_SCANCODE_RCTRL, // 7 - SDL_SCANCODE_LSHIFT, // 8 - SDL_SCANCODE_LALT, // 9 - SDL_SCANCODE_LCTRL, // 10 - SDL_SCANCODE_0, // 11 - SDL_SCANCODE_1, // 12 - SDL_SCANCODE_2, // 13 - SDL_SCANCODE_3, // 14 - SDL_SCANCODE_4, // 15 - SDL_SCANCODE_5, // 16 - SDL_SCANCODE_6, // 17 - SDL_SCANCODE_7, // 18 - SDL_SCANCODE_8, // 19 - SDL_SCANCODE_9, // 20 - SDL_SCANCODE_A, // 21 - SDL_SCANCODE_B, // 22 - SDL_SCANCODE_C, // 23 - SDL_SCANCODE_D, // 24 - SDL_SCANCODE_E, // 25 - SDL_SCANCODE_F, // 26 - SDL_SCANCODE_G, // 27 - SDL_SCANCODE_H, // 28 - SDL_SCANCODE_I, // 29 - SDL_SCANCODE_J, // 30 - SDL_SCANCODE_K, // 31 - SDL_SCANCODE_L, // 32 - SDL_SCANCODE_M, // 33 - SDL_SCANCODE_N, // 34 - SDL_SCANCODE_O, // 35 - SDL_SCANCODE_P, // 36 - SDL_SCANCODE_Q, // 37 - SDL_SCANCODE_R, // 38 - SDL_SCANCODE_S, // 39 - SDL_SCANCODE_T, // 40 - SDL_SCANCODE_U, // 41 - SDL_SCANCODE_V, // 42 - SDL_SCANCODE_W, // 43 - SDL_SCANCODE_X, // 44 - SDL_SCANCODE_Y, // 45 - SDL_SCANCODE_Z, // 46 - SDL_SCANCODE_GRAVE, // 47 - SDL_SCANCODE_MINUS, // 48 - SDL_SCANCODE_EQUALS, // 49 - SDL_SCANCODE_BACKSPACE, // 50 - SDL_SCANCODE_RETURN, // 51 - SDL_SCANCODE_KP_ENTER, // 52 - SDL_SCANCODE_TAB, // 53 - SDL_SCANCODE_SLASH, // 54 - -1, // 55 - SDL_SCANCODE_SEMICOLON, // 56 - SDL_SCANCODE_APOSTROPHE, // 57 - SDL_SCANCODE_PERIOD, // 58 - SDL_SCANCODE_COMMA, // 59 - SDL_SCANCODE_LEFTBRACKET, // 60 - SDL_SCANCODE_RIGHTBRACKET, // 61 - SDL_SCANCODE_BACKSLASH, // 62 - SDL_SCANCODE_ESCAPE, // 63 - SDL_SCANCODE_INSERT, // 64 - SDL_SCANCODE_DELETE, // 65 - SDL_SCANCODE_HOME, // 66 - SDL_SCANCODE_END, // 67 - SDL_SCANCODE_PAGEUP, // 68 - SDL_SCANCODE_PAGEDOWN, // 69 - SDL_SCANCODE_LEFT, // 70 - SDL_SCANCODE_RIGHT, // 71 - SDL_SCANCODE_UP, // 72 - SDL_SCANCODE_DOWN, // 73 - SDL_SCANCODE_NUMLOCKCLEAR, // 74 - SDL_SCANCODE_KP_DIVIDE, // 75 - SDL_SCANCODE_KP_MULTIPLY, // 76 - SDL_SCANCODE_KP_MINUS, // 77 - SDL_SCANCODE_KP_PLUS, // 78 - SDL_SCANCODE_KP_PERIOD, // 79 - SDL_SCANCODE_KP_EQUALS, // 80 - SDL_SCANCODE_KP_0, // 81 - SDL_SCANCODE_KP_1, // 82 - SDL_SCANCODE_KP_2, // 83 - SDL_SCANCODE_KP_3, // 84 - SDL_SCANCODE_KP_4, // 85 - SDL_SCANCODE_KP_5, // 86 - SDL_SCANCODE_KP_6, // 87 - SDL_SCANCODE_KP_7, // 88 - SDL_SCANCODE_KP_8, // 89 - SDL_SCANCODE_KP_9, // 90 - SDL_SCANCODE_F1, // 91 - SDL_SCANCODE_F2, // 92 - SDL_SCANCODE_F3, // 93 - SDL_SCANCODE_F4, // 94 - SDL_SCANCODE_F5, // 95 - SDL_SCANCODE_F6, // 96 - SDL_SCANCODE_F7, // 97 - SDL_SCANCODE_F8, // 98 - SDL_SCANCODE_F9, // 99 - SDL_SCANCODE_F10, // 100 - SDL_SCANCODE_F11, // 101 - SDL_SCANCODE_F12, // 102 - SDL_SCANCODE_PRINTSCREEN, // 103 - SDL_SCANCODE_SCROLLLOCK, // 104 - SDL_SCANCODE_PAUSE, // 105 - SDL_SCANCODE_SPACE, // 106 -}; -int scancodes_sdl2dethrace[SDL_NUM_SCANCODES]; - -SDL_Window* window; -SDL_GLContext context; -uint8_t sdl_key_state[256]; -struct { - float x; - float y; -} sdl_window_scale; - -tRenderer gl_renderer = { - GLRenderer_Init, - GLRenderer_BeginScene, - GLRenderer_EndScene, - GLRenderer_SetPalette, - GLRenderer_FullScreenQuad, - GLRenderer_Model, - GLRenderer_ClearBuffers, - GLRenderer_BufferTexture, - GLRenderer_BufferMaterial, - GLRenderer_BufferModel, - GLRenderer_FlushBuffers, - GLRenderer_GetRenderSize, - GLRenderer_GetWindowSize, - GLRenderer_SetWindowSize, - GLRenderer_GetViewport -}; - -tRenderer* IOPlatform_CreateWindow(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, 1); - - SDL_GL_SetSwapInterval(1); - - window = SDL_CreateWindow(title, - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - width, height, - SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); - - if (window == NULL) { - LOG_PANIC("Failed to create window. %s", SDL_GetError()); - } - - sdl_window_scale.x = ((float)pRender_width) / width; - sdl_window_scale.y = ((float)pRender_height) / height; - - if (harness_game_config.start_full_screen) { - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); - } - - SDL_ShowCursor(SDL_DISABLE); - - 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 IOPlatform_Shutdown() { - SDL_GL_DeleteContext(context); - SDL_DestroyWindow(window); - SDL_Quit(); - window = NULL; -} - -// Checks whether the `flag_check` is the only modifier applied. -// e.g. is_only_modifier(event.key.keysym.mod, KMOD_ALT) returns true when only the ALT key was pressed -static int is_only_key_modifier(int modifier_flags, int flag_check) { - return (modifier_flags & flag_check) && (modifier_flags & (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_GUI)) == (modifier_flags & flag_check); -} - -void IOPlatform_PollEvents() { - SDL_Event event; - int dethrace_key; - int w_w, w_h; - int vp_x, vp_y; - int vp_w, vp_h; - int r_w, r_h; - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYDOWN: - case SDL_KEYUP: - if (event.key.keysym.sym == SDLK_RETURN) { - if (event.key.type == SDL_KEYDOWN) { - if ((event.key.keysym.mod & (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_GUI))) { - // Ignore keydown of RETURN when used together with some modifier - return; - } - } else if (event.key.type == SDL_KEYUP) { - if (is_only_key_modifier(event.key.keysym.mod, KMOD_ALT)) { - SDL_SetWindowFullscreen(window, (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP); - } - } - } - dethrace_key = scancodes_sdl2dethrace[event.key.keysym.scancode]; - if (dethrace_key == -1) { - LOG_WARN("unexpected scan code %s (%d)", SDL_GetScancodeName(event.key.keysym.scancode), event.key.keysym.scancode); - return; - } - sdl_key_state[scancodes_sdl2dethrace[event.key.keysym.scancode]] = event.type == SDL_KEYDOWN; - - sdl_key_state[0] = sdl_key_state[scancodes_sdl2dethrace[SDL_SCANCODE_LSHIFT]] || sdl_key_state[scancodes_sdl2dethrace[SDL_SCANCODE_RSHIFT]]; - sdl_key_state[1] = sdl_key_state[scancodes_sdl2dethrace[SDL_SCANCODE_LALT]] || sdl_key_state[scancodes_sdl2dethrace[SDL_SCANCODE_RALT]]; - sdl_key_state[2] = sdl_key_state[scancodes_sdl2dethrace[SDL_SCANCODE_LCTRL]] || sdl_key_state[scancodes_sdl2dethrace[SDL_SCANCODE_RCTRL]]; - sdl_key_state[3] = sdl_key_state[2]; - break; - - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_SIZE_CHANGED: - SDL_GetWindowSize(window, &w_w, &w_h); - gl_renderer.SetWindowSize(w_w, w_h); - gl_renderer.GetViewport(&vp_x, &vp_y, &vp_w, &vp_h); - gl_renderer.GetRenderSize(&r_w, &r_h); - sdl_window_scale.x = (float)r_w / vp_w; - sdl_window_scale.y = (float)r_h / vp_h; - break; - } - break; - case SDL_QUIT: - QuitGame(); - break; - } - } -} - -void IOPlatform_SwapWindow(int delay_ms_after_swap) { - SDL_GL_SwapWindow(window); - - if (delay_ms_after_swap != 0) { - SDL_Delay(delay_ms_after_swap); - } -} - -void IOPlatform_Init() { - for (size_t i = 0; i < ARRAY_LEN(scancodes_sdl2dethrace); i++) { - scancodes_sdl2dethrace[i] = -1; - } - for (size_t i = 0; i < ARRAY_LEN(scancodes_dethrace2sdl); i++) { - if (scancodes_dethrace2sdl[i] != -1) { - scancodes_sdl2dethrace[scancodes_dethrace2sdl[i]] = i; - } - } - for (size_t i = 0; i < ARRAY_LEN(scancode_map); i++) { - scancode_map[i] = i; - } -} - -int* IOPlatform_GetKeyMap() { - return (int*)scancode_map; -} - -int IOPlatform_IsKeyDown(unsigned char scan_code) { - return sdl_key_state[scan_code]; -} - -void IOPlatform_GetMousePosition(int* pX, int* pY) { - int vp_x, vp_y, vp_w, vp_h; - - SDL_GetMouseState(pX, pY); - gl_renderer.GetViewport(&vp_x, &vp_y, &vp_w, &vp_h); - if (*pX < vp_x) { - *pX = vp_x; - } else if (*pX >= vp_x + vp_w) { - *pX = vp_x + vp_w - 1; - } - if (*pY < vp_y) { - *pY = vp_y; - } else if (*pY >= vp_y + vp_h) { - *pY = vp_y + vp_h - 1; - } - *pX -= vp_x; - *pY -= vp_y; - *pX *= sdl_window_scale.x; - *pY *= sdl_window_scale.y; - -#if defined(DETHRACE_FIX_BUGS) - // In hires mode (640x480), the menus are still rendered at (320x240), - // so prescale the cursor coordinates accordingly. - *pX *= gGraf_specs[gGraf_data_index].phys_width; - *pX /= gGraf_specs[gReal_graf_data_index].phys_width; - *pY *= gGraf_specs[gGraf_data_index].phys_height; - *pY /= gGraf_specs[gReal_graf_data_index].phys_height; -#endif -} - -void IOPlatform_GetMouseButtons(int* pButton1, int* pButton2) { - int state = SDL_GetMouseState(NULL, NULL); - *pButton1 = state & SDL_BUTTON_LMASK; - *pButton2 = state & SDL_BUTTON_RMASK; -} diff --git a/src/harness/os/linux.c b/src/harness/os/linux.c index eb8b9151..b02e5e44 100644 --- a/src/harness/os/linux.c +++ b/src/harness/os/linux.c @@ -31,8 +31,6 @@ 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 first_clock_time = 0; struct dl_iterate_callback_data { int initialized; @@ -56,85 +54,6 @@ static intptr_t get_dethrace_offset() { return dethrace_dl_data.start; } -uint32_t OS_GetTime() { - struct timespec spec; - clock_gettime(CLOCK_MONOTONIC, &spec); - if (first_clock_time == 0) { - first_clock_time = spec.tv_sec * 1000 + spec.tv_nsec / 1000000; - } - return (spec.tv_sec * 1000 + spec.tv_nsec / 1000000) - first_clock_time; -} - -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); -} - -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; -} - -void OS_Basename(char* path, char* base) { - strcpy(base, basename(path)); -} - -int OS_IsDebuggerPresent() { - char buf[4096]; - int status_fd; - ssize_t num_read; - char* tracer_pid_ptr; - char* char_ptr; - - status_fd = open("/proc/self/status", O_RDONLY); - if (status_fd == -1) { - return 0; - } - - num_read = read(status_fd, buf, sizeof(buf) - 1); - close(status_fd); - if (num_read <= 0) { - return 0; - } - - buf[num_read] = '\0'; - tracer_pid_ptr = strstr(buf, TRACER_PID_STRING); - if (tracer_pid_ptr == NULL) { - return 0; - } - - for (char_ptr = tracer_pid_ptr + sizeof(TRACER_PID_STRING) - 1; char_ptr <= buf + num_read; ++char_ptr) { - if (isspace(*char_ptr)) { - continue; - } else { - return isdigit(*char_ptr) != 0 && *char_ptr != '0'; - } - } - - 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 }; @@ -341,34 +260,6 @@ FILE* OS_fopen(const char* pathname, const char* mode) { return f; } -void OS_AllocateActionReplayBuffer(char** pBuffer, unsigned* pBuffer_size) { - static int allocated = 0; - static char* buffer = NULL; - static unsigned buffer_size = 0; - unsigned i; - const int wanted_sizes[] = { - 20000000, - 16000000, - 6000000, - 4000000, - 500000, - }; - - if (!allocated) { - allocated = 1; - buffer_size = 0; - for (i = 0; i < ARRAY_SIZE(wanted_sizes); i++) { - buffer = malloc(wanted_sizes[i]); - if (buffer != NULL) { - buffer_size = wanted_sizes[i]; - break; - } - } - } - *pBuffer = buffer; - *pBuffer_size = buffer_size; -} - size_t OS_ConsoleReadPassword(char* pBuffer, size_t pBufferLen) { struct termios old, new; char c; diff --git a/src/harness/os/macos.c b/src/harness/os/macos.c index fec72d51..04306c6c 100644 --- a/src/harness/os/macos.c +++ b/src/harness/os/macos.c @@ -25,92 +25,6 @@ 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 first_clock_time = 0; - -uint32_t OS_GetTime() { - struct timespec spec; - clock_gettime(CLOCK_MONOTONIC, &spec); - if (first_clock_time == 0) { - first_clock_time = spec.tv_sec * 1000 + spec.tv_nsec / 1000000; - } - return (spec.tv_sec * 1000 + spec.tv_nsec / 1000000) - first_clock_time; -} - -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); -} - -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; -} - -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, -// you should restrict use of the above code to the debug build of your program. - -int OS_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; - - // Initialize the flags so that, if sysctl fails for some bizarre - // reason, we get a predictable result. - - info.kp_proc.p_flag = 0; - - // Initialize mib, which tells sysctl the info we want, in this case - // we're looking for information about a specific process ID. - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - - // Call sysctl. - - size = sizeof(info); - junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0); - (void)junk; - assert(junk == 0); - - // We're being debugged if the P_TRACED flag is set. - - 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) { @@ -297,34 +211,6 @@ FILE* OS_fopen(const char* pathname, const char* mode) { return fopen(pathname, mode); } -void OS_AllocateActionReplayBuffer(char** pBuffer, unsigned* pBuffer_size) { - static int allocated = 0; - static char* buffer = NULL; - static unsigned buffer_size = 0; - unsigned i; - const int wanted_sizes[] = { - 20000000, - 16000000, - 6000000, - 4000000, - 500000, - }; - - if (!allocated) { - allocated = 1; - buffer_size = 0; - for (i = 0; i < ARRAY_SIZE(wanted_sizes); i++) { - buffer = malloc(wanted_sizes[i]); - if (buffer != NULL) { - buffer_size = wanted_sizes[i]; - break; - } - } - } - *pBuffer = buffer; - *pBuffer_size = buffer_size; -} - size_t OS_ConsoleReadPassword(char* pBuffer, size_t pBufferLen) { // FIXME: unsafe implementation (echos the password) pBuffer[0] = '\0'; diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 6fe1ed7d..a77944f1 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -28,63 +28,6 @@ void dr_dprintf(char* fmt_string, ...); static int stack_nbr = 0; static char _program_name[1024]; -LARGE_INTEGER qpc_start_time, EndingTime, ElapsedMicroseconds; -LARGE_INTEGER qpc_ticks_per_sec; - -HANDLE directory_handle = NULL; -char last_found_file[260]; - -uint32_t OS_GetTime() { - LARGE_INTEGER now; - if (qpc_start_time.QuadPart == 0) { - QueryPerformanceFrequency(&qpc_ticks_per_sec); - QueryPerformanceCounter(&qpc_start_time); - } - - QueryPerformanceCounter(&now); - 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; - - strcpy(with_extension, path); - strcat(with_extension, "\\*.???"); - directory_handle = FindFirstFile(with_extension, &find_data); - if (directory_handle == INVALID_HANDLE_VALUE) { - return NULL; - } - strcpy(last_found_file, find_data.cFileName); - return last_found_file; -} - -// Required: continue directory iteration. If no more files, return NULL -char* OS_GetNextFileInDirectory(void) { - WIN32_FIND_DATA find_data; - if (directory_handle == NULL) { - return NULL; - } - - while (FindNextFile(directory_handle, &find_data)) { - strcpy(last_found_file, find_data.cFileName); - return last_found_file; - } - FindClose(directory_handle); - return NULL; -} - -void OS_Basename(char* path, char* base) { - _splitpath(path, NULL, NULL, base, NULL); -} - -int OS_IsDebuggerPresent() { - return IsDebuggerPresent(); -} int addr2line(char const* const program_name, void const* const addr) { char addr2line_cmd[512] = { 0 }; @@ -220,95 +163,6 @@ FILE* OS_fopen(const char* pathname, const char* mode) { return f; } -void OS_AllocateActionReplayBuffer(char** pBuffer, unsigned* pBuffer_size) { - static int allocated = 0; - static char* buffer = NULL; - static unsigned buffer_size = 0; - MEMORYSTATUS memory_status; - unsigned wanted; - - if (allocated) { - *pBuffer = buffer; - *pBuffer_size = buffer_size; - return; - } - allocated = 1; - buffer = NULL; - memory_status.dwLength = sizeof(memory_status); - GlobalMemoryStatus(&memory_status); - dr_dprintf( - "Win32AllocateActionReplayBuffer(): Memory Status BEFORE Action Replay Allocation:\n" - " dwLength %u\n" - " dwMemoryLoad %u\n" - " dwTotalPhys %u\n" - " dwAvailPhys %u\n" - " dwTotalPageFile %u\n" - " dwAvailPageFile %u\n" - " dwTotalVirtual %u\n" - " dwAvailVirtual %u", - memory_status.dwLength, - memory_status.dwMemoryLoad, - memory_status.dwTotalPhys, - memory_status.dwAvailPhys, - memory_status.dwTotalPageFile, - memory_status.dwAvailPageFile, - memory_status.dwTotalVirtual, - memory_status.dwAvailVirtual); - wanted = 20000000; - if (memory_status.dwTotalPhys < 16000000) { - wanted = 500000; - } else if (memory_status.dwTotalPhys < 24000000) { - wanted = 4000000; - } else if (memory_status.dwTotalPhys < 32000000) { - wanted = 6000000; - } else if (memory_status.dwTotalPhys < 48000000) { - wanted = 12000000; - } - dr_dprintf("Win32AllocateActionReplayBuffer(): We want %d bytes...", wanted); - if (memory_status.dwAvailPageFile + memory_status.dwAvailPhys < wanted) { - wanted = (memory_status.dwAvailPageFile + memory_status.dwAvailPhys) - 0x100000; - dr_dprintf("Win32AllocateActionReplayBuffer(): ...but there's only %d bytes available...", wanted); - } - if (wanted < 0x10000) { - wanted = 0x10000; - dr_dprintf("Win32AllocateActionReplayBuffer(): ...but we have to have a minimum size of %d bytes...", wanted); - } - while (wanted >= 0x10000) { - buffer = malloc(wanted); - if (buffer != NULL) { - break; - } - } - if (buffer == NULL) { - buffer_size = 0; - } else { - buffer_size = wanted; - // Sleep(1000); // Commented out 1s sleep - } - dr_dprintf("Win32AllocateActionReplayBuffer(): Actually allocated %d bytes.", wanted); - GlobalMemoryStatus(&memory_status); - dr_dprintf( - "Win32AllocateActionReplayBuffer(): Memory Status AFTER Action Replay Allocation:\n" - " dwLength %u\n" - " dwMemoryLoad %u\n" - " dwTotalPhys %u\n" - " dwAvailPhys %u\n" - " dwTotalPageFile %u\n" - " dwAvailPageFile %u\n" - " dwTotalVirtual %u\n" - " dwAvailVirtual %u", - memory_status.dwLength, - memory_status.dwMemoryLoad, - memory_status.dwTotalPhys, - memory_status.dwAvailPhys, - memory_status.dwTotalPageFile, - memory_status.dwAvailPageFile, - memory_status.dwTotalVirtual, - memory_status.dwAvailVirtual); - *pBuffer = buffer; - *pBuffer_size = buffer_size; -} - size_t OS_ConsoleReadPassword(char* pBuffer, size_t pBufferLen) { // FIXME: unsafe implementation (echos the password) pBuffer[0] = '\0'; diff --git a/src/harness/platforms/null.h b/src/harness/platforms/null.h new file mode 100644 index 00000000..c43aa5ac --- /dev/null +++ b/src/harness/platforms/null.h @@ -0,0 +1,83 @@ +#ifndef PLATFORM_NULL +#define PLATFORM_NULL + +#include "harness/hooks.h" +// todo: shouldnt depend on sdl... +#include + +void* null_create_window_and_renderer(char* title, int x, int y, int width, int height) { + return 0; +} + +int null_set_window_pos(void* hWnd, int x, int y, int nWidth, int nHeight) { + return 0; +} + +void null_destroy_window(void* hWnd) { +} + +int null_get_and_handle_message(MSG_* msg) { + return 0; +} + +void null_swap_window() { +} + +void null_get_keyboard_state(unsigned int count, uint8_t* buffer) { +} + +int null_get_mouse_buttons(int* pButton1, int* pButton2) { + return 0; +} + +int null_get_mouse_position(int* pX, int* pY) { + return 0; +} + +int null_show_cursor(int show) { + return 0; +} + +void NullRenderer_Init() {} +void NullRenderer_BeginScene(br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer) {} +void NullRenderer_EndScene() {} +void NullRenderer_SetPalette(PALETTEENTRY_* palette) {} +void NullRenderer_FullScreenQuad(uint8_t* src) {} +void NullRenderer_Model(br_actor* actor, br_model* model, br_material* material, br_token render_type, br_matrix34 model_matrix) {} +void NullRenderer_RenderFrameBuffer() {} +void NullRenderer_ClearBuffers() {} +void NullRenderer_BufferTexture(br_pixelmap* pm) {} +void NullRenderer_BufferMaterial(br_material* mat) {} +void NullRenderer_BufferModel(br_model* model) {} +void NullRenderer_FlushBuffers() {} +void NullRenderer_SetViewport(int x, int y, int width, int height) {} + +void Null_Platform_Init(tHarness_platform* platform) { + platform->ProcessWindowMessages = null_get_and_handle_message; + // todo: shouldnt depend on sdl... + platform->Sleep = SDL_Delay; + platform->GetTicks = SDL_GetTicks; + platform->CreateWindowAndRenderer = null_create_window_and_renderer; + platform->ShowCursor = null_show_cursor; + platform->SetWindowPos = null_set_window_pos; + platform->SwapWindow = null_swap_window; + platform->DestroyWindow = null_destroy_window; + platform->GetKeyboardState = null_get_keyboard_state; + platform->GetMousePosition = null_get_mouse_position; + platform->GetMouseButtons = null_get_mouse_buttons; + platform->DestroyWindow = null_destroy_window; + + platform->Renderer_BufferModel = NullRenderer_BufferModel; + platform->Renderer_BufferMaterial = NullRenderer_BufferMaterial; + platform->Renderer_BufferTexture = NullRenderer_BufferTexture; + platform->Renderer_SetPalette = NullRenderer_SetPalette; + platform->Renderer_FullScreenQuad = NullRenderer_FullScreenQuad; + platform->Renderer_Model = NullRenderer_Model; + platform->Renderer_ClearBuffers = NullRenderer_ClearBuffers; + platform->Renderer_FlushBuffers = NullRenderer_FlushBuffers; + platform->Renderer_BeginScene = NullRenderer_BeginScene; + platform->Renderer_EndScene = NullRenderer_EndScene; + platform->Renderer_SetViewport = NullRenderer_SetViewport; +} + +#endif diff --git a/src/harness/platforms/sdl2_scancode_to_dinput.h b/src/harness/platforms/sdl2_scancode_to_dinput.h new file mode 100644 index 00000000..96f9f929 --- /dev/null +++ b/src/harness/platforms/sdl2_scancode_to_dinput.h @@ -0,0 +1,392 @@ +/* + * Maps SDL2 scancodes to directinput keynums/scancodes. + * Useful if you're porting a game that uses dinput scancodes internally + * (for key bindings etc) or any other lib (like CEGUI) that uses them. + * + * (C) 2015 Daniel Gibson + * + * Homepage: https://github.com/DanielGibson/Snippets/ + * + * License: + * This software is dual-licensed to the public domain and under the following + * license: you are granted a perpetual, irrevocable license to copy, modify, + * publish, and distribute this file as you see fit. + * No warranty implied; use at your own risk. + * + * So you can do whatever you want with this code, including copying it + * (or parts of it) into your own source. + * No need to mention me or this "license" in your code or docs, even though + * it would be appreciated, of course. + * + */ + +#include + +#include + +#if 0 // Usage Example: +#include "sdl2_scancode_to_dinput.h" + static int SDLScanCodeToKeyNum(SDL_Scancode sc) + { + int idx = (int)sc; + assert(idx >= 0 && idx < SDL_NUM_SCANCODES); + return scanCodeToKeyNum[idx]; + } + + static SDL_Scancode KeyNumToSDLScanCode( int keyNum ) + { + if( keyNum >= 0 && keyNum < 0xEF ) + { + for(int i = 0; i < SDL_NUM_SCANCODES; ++i) + { + if(scanCodeToKeyNum[i] == keyNum) return (SDL_Scancode)i; + } + } + return SDL_SCANCODE_UNKNOWN; + } +#endif // 0 + +#ifndef _SDL2_SCANCODE_TO_DINPUT_H_ +#define _SDL2_SCANCODE_TO_DINPUT_H_ + +// TODO: map the following keys, if possible: +// #define DIK_UNDERLINE 0x93 /* (NEC PC98) */ +// #define DIK_KANJI 0x94 /* (Japanese keyboard) */ +// #define DIK_AX 0x96 /* (Japan AX) */ +// #define DIK_UNLABELED 0x97 /* (J3100) */ +// +// #define DIK_WAKE 0xE3 /* System Wake */ +// +// (#define DIK_ABNT_C2 0x7E /* Numpad . on Brazilian keyboard */ - system should map this to KP_COMMA or something, +// according to USB doc, so probably it doesn't need mapping here) + +// maps SDL2 scancodes to directinput keynums/scancodes - dinput_key = sdlScanCodeToDirectInputKeyNum[(int)your_sdl2_scancode]; +static int sdlScanCodeToDirectInputKeyNum[SDL_NUM_SCANCODES] = { + 0x0, // SDL_SCANCODE_UNKNOWN = 0, => 0 should also work for dinput codes as "not assigned/unknown" + 0x0, // // 1 (unused) + 0x0, // // 2 (unused) + 0x0, // // 3 (unused) + 0x1E, // SDL_SCANCODE_A = 4, - DIK_A + 0x30, // SDL_SCANCODE_B = 5, - DIK_B + 0x2E, // SDL_SCANCODE_C = 6, - DIK_C + 0x20, // SDL_SCANCODE_D = 7, - DIK_D + 0x12, // SDL_SCANCODE_E = 8, - DIK_E + 0x21, // SDL_SCANCODE_F = 9, - DIK_F + 0x22, // SDL_SCANCODE_G = 10, - DIK_G + 0x23, // SDL_SCANCODE_H = 11, - DIK_H + 0x17, // SDL_SCANCODE_I = 12, - DIK_I + 0x24, // SDL_SCANCODE_J = 13, - DIK_J + 0x25, // SDL_SCANCODE_K = 14, - DIK_K + 0x26, // SDL_SCANCODE_L = 15, - DIK_L + 0x32, // SDL_SCANCODE_M = 16, - DIK_M + 0x31, // SDL_SCANCODE_N = 17, - DIK_N + 0x18, // SDL_SCANCODE_O = 18, - DIK_O + 0x19, // SDL_SCANCODE_P = 19, - DIK_P + 0x10, // SDL_SCANCODE_Q = 20, - DIK_Q + 0x13, // SDL_SCANCODE_R = 21, - DIK_R + 0x1F, // SDL_SCANCODE_S = 22, - DIK_S + 0x14, // SDL_SCANCODE_T = 23, - DIK_T + 0x16, // SDL_SCANCODE_U = 24, - DIK_U + 0x2F, // SDL_SCANCODE_V = 25, - DIK_V + 0x11, // SDL_SCANCODE_W = 26, - DIK_W + 0x2D, // SDL_SCANCODE_X = 27, - DIK_X + 0x15, // SDL_SCANCODE_Y = 28, - DIK_Y + 0x2C, // SDL_SCANCODE_Z = 29, - DIK_Z + + 0x02, // SDL_SCANCODE_1 = 30, - DIK_1 + 0x03, // SDL_SCANCODE_2 = 31, - DIK_2 + 0x04, // SDL_SCANCODE_3 = 32, - DIK_3 + 0x05, // SDL_SCANCODE_4 = 33, - DIK_4 + 0x06, // SDL_SCANCODE_5 = 34, - DIK_5 + 0x07, // SDL_SCANCODE_6 = 35, - DIK_6 + 0x08, // SDL_SCANCODE_7 = 36, - DIK_7 + 0x09, // SDL_SCANCODE_8 = 37, - DIK_8 + 0x0A, // SDL_SCANCODE_9 = 38, - DIK_9 + 0x0B, // SDL_SCANCODE_0 = 39, - DIK_0 + + 0x1C, // SDL_SCANCODE_RETURN = 40, - DIK_RETURN + 0x01, // SDL_SCANCODE_ESCAPE = 41, - DIK_ESCAPE + 0x0E, // SDL_SCANCODE_BACKSPACE = 42, - DIK_BACK + 0x0F, // SDL_SCANCODE_TAB = 43, - DIK_TAB + 0x39, // SDL_SCANCODE_SPACE = 44, - DIK_SPACE + + 0x0C, // SDL_SCANCODE_MINUS = 45, - DIK_MINUS + 0x0D, // SDL_SCANCODE_EQUALS = 46, - DIK_EQUALS + 0x1A, // SDL_SCANCODE_LEFTBRACKET = 47, - DIK_LBRACKET + 0x1B, // SDL_SCANCODE_RIGHTBRACKET = 48, - DIK_RBRACKET + 0x2B, // SDL_SCANCODE_BACKSLASH = 49, // next to enter, US: [\|] DE: [#'] UK: [#~] - DIK_BACKSLASH + 0x2B, // SDL_SCANCODE_NONUSHASH = 50, // same key as before actually on some layouts, systems should map this to SDL_SCANCODE_BACKSLASH - DIK_BACKSLASH + 0x27, // SDL_SCANCODE_SEMICOLON = 51, - DIK_SEMICOLON + 0x28, // SDL_SCANCODE_APOSTROPHE = 52, - DIK_APOSTROPHE + 0x29, // SDL_SCANCODE_GRAVE = 53, // "quake/doom3 console key" - DIK_GRAVE + 0x33, // SDL_SCANCODE_COMMA = 54, - DIK_COMMA + 0x34, // SDL_SCANCODE_PERIOD = 55, - DIK_PERIOD + 0x35, // SDL_SCANCODE_SLASH = 56, - DIK_SLASH + + 0x3A, // SDL_SCANCODE_CAPSLOCK = 57, - DIK_CAPITAL + + 0x3B, // SDL_SCANCODE_F1 = 58, - DIK_F1 + 0x3C, // SDL_SCANCODE_F2 = 59, - DIK_F2 + 0x3D, // SDL_SCANCODE_F3 = 60, - DIK_F3 + 0x3E, // SDL_SCANCODE_F4 = 61, - DIK_F4 + 0x3F, // SDL_SCANCODE_F5 = 62, - DIK_F5 + 0x40, // SDL_SCANCODE_F6 = 63, - DIK_F6 + 0x41, // SDL_SCANCODE_F7 = 64, - DIK_F7 + 0x42, // SDL_SCANCODE_F8 = 65, - DIK_F8 + 0x43, // SDL_SCANCODE_F9 = 66, - DIK_F9 + 0x44, // SDL_SCANCODE_F10 = 67, - DIK_F10 + 0x57, // SDL_SCANCODE_F11 = 68, - DIK_F11 + 0x58, // SDL_SCANCODE_F12 = 69, - DIK_F12 + + 0xB7, // SDL_SCANCODE_PRINTSCREEN = 70, // - DIK_SYSRQ; SDL_SCANCODE_SYSREQ also maps to this! + + 0x46, // SDL_SCANCODE_SCROLLLOCK = 71, - DIK_SCROLL + 0xC5, // SDL_SCANCODE_PAUSE = 72, - DIK_PAUSE + 0xD2, // SDL_SCANCODE_INSERT = 73, // insert on PC, help on some Mac keyboards (but does send code 73, not 117) - DIK_INSERT + 0xC7, // SDL_SCANCODE_HOME = 74, - DIK_HOME + 0xC9, // SDL_SCANCODE_PAGEUP = 75, - DIK_PRIOR + 0xD3, // SDL_SCANCODE_DELETE = 76, - DIK_DELETE + 0xCF, // SDL_SCANCODE_END = 77, - DIK_END + 0xD1, // SDL_SCANCODE_PAGEDOWN = 78, - DIK_NEXT + 0xCD, // SDL_SCANCODE_RIGHT = 79, - DIK_RIGHT + 0xCB, // SDL_SCANCODE_LEFT = 80, - DIK_LEFT + 0xD0, // SDL_SCANCODE_DOWN = 81, - DIK_DOWN + 0xC8, // SDL_SCANCODE_UP = 82, - DIK_UP + + 0x45, // SDL_SCANCODE_NUMLOCKCLEAR = 83, // num lock on PC, clear on Mac keyboards - DIK_NUMLOCK + + 0xB5, // SDL_SCANCODE_KP_DIVIDE = 84, - DIK_DIVIDE + 0x37, // SDL_SCANCODE_KP_MULTIPLY = 85, - DIK_MULTIPLY + 0x4A, // SDL_SCANCODE_KP_MINUS = 86, - DIK_SUBTRACT + 0x4E, // SDL_SCANCODE_KP_PLUS = 87, - DIK_ADD + 0x9C, // SDL_SCANCODE_KP_ENTER = 88, - DIK_NUMPADENTER + 0x4F, // SDL_SCANCODE_KP_1 = 89, - DIK_NUMPAD1 + 0x50, // SDL_SCANCODE_KP_2 = 90, - DIK_NUMPAD2 + 0x51, // SDL_SCANCODE_KP_3 = 91, - DIK_NUMPAD3 + 0x4B, // SDL_SCANCODE_KP_4 = 92, - DIK_NUMPAD4 + 0x4C, // SDL_SCANCODE_KP_5 = 93, - DIK_NUMPAD5 + 0x4D, // SDL_SCANCODE_KP_6 = 94, - DIK_NUMPAD6 + 0x47, // SDL_SCANCODE_KP_7 = 95, - DIK_NUMPAD7 + 0x48, // SDL_SCANCODE_KP_8 = 96, - DIK_NUMPAD8 + 0x49, // SDL_SCANCODE_KP_9 = 97, - DIK_NUMPAD9 + 0x52, // SDL_SCANCODE_KP_0 = 98, - DIK_NUMPAD0 + 0x53, // SDL_SCANCODE_KP_PERIOD = 99, - DIK_DECIMAL + + 0x56, // SDL_SCANCODE_NONUSBACKSLASH = 100, // [<>|] on german keyboard, next to left shift - DIK_OEM_102 + 0xDD, // SDL_SCANCODE_APPLICATION = 101, // windows contextual menu, compose - DIK_APPS + 0xDE, // SDL_SCANCODE_POWER = 102, // should be a status flag, but some mac keyboards have a power key - DIK_POWER + + 0x8D, // SDL_SCANCODE_KP_EQUALS = 103, - DIK_NUMPADEQUALS + 0x64, // SDL_SCANCODE_F13 = 104, - DIK_F13 + 0x65, // SDL_SCANCODE_F14 = 105, - DIK_F14 + 0x66, // SDL_SCANCODE_F15 = 106, - DIK_F15 + 0x67, // SDL_SCANCODE_F16 = 107, // TODO: F16 and up don't have DIK_ constants! is this right? + 0x68, // SDL_SCANCODE_F17 = 108, // (at least 0x67-0x6F have no DIK_constants at all) + 0x69, // SDL_SCANCODE_F18 = 109, + 0x6A, // SDL_SCANCODE_F19 = 110, + 0x6B, // SDL_SCANCODE_F20 = 111, + 0x6C, // SDL_SCANCODE_F21 = 112, + 0x6D, // SDL_SCANCODE_F22 = 113, + 0x6E, // SDL_SCANCODE_F23 = 114, + 0x6F, // SDL_SCANCODE_F24 = 115, + + 0x0, // SDL_SCANCODE_EXECUTE = 116, + 0x0, // SDL_SCANCODE_HELP = 117, + 0x0, // SDL_SCANCODE_MENU = 118, + 0x0, // SDL_SCANCODE_SELECT = 119, + + 0x95, // SDL_SCANCODE_STOP = 120, - DIK_STOP + + 0x0, // SDL_SCANCODE_AGAIN = 121, // redo + 0x0, // SDL_SCANCODE_UNDO = 122, + 0x0, // SDL_SCANCODE_CUT = 123, + 0x0, // SDL_SCANCODE_COPY = 124, + 0x0, // SDL_SCANCODE_PASTE = 125, + 0x0, // SDL_SCANCODE_FIND = 126, + 0x0, // SDL_SCANCODE_MUTE = 127, + + 0xB0, // SDL_SCANCODE_VOLUMEUP = 128, - DIK_VOLUMEUP + 0xAE, // SDL_SCANCODE_VOLUMEDOWN = 129, - DIK_VOLUMEDOWN + + // /* not sure whether there's a reason to enable these */ + 0x0, // /* SDL_SCANCODE_LOCKINGCAPSLOCK = 130, */ + 0x0, // /* SDL_SCANCODE_LOCKINGNUMLOCK = 131, */ + 0x0, // /* SDL_SCANCODE_LOCKINGSCROLLLOCK = 132, */ + + 0xB3, // SDL_SCANCODE_KP_COMMA = 133, - DIK_NUMPADCOMMA + + 0x0, // SDL_SCANCODE_KP_EQUALSAS400 = 134, + + 0x73, // SDL_SCANCODE_INTERNATIONAL1 = 135, // this is really brazilian / and ? - DIK_ABNT_C1 + 0x0, // SDL_SCANCODE_INTERNATIONAL2 = 136, // TODO: Hut1_12v2.pdf page 60, footnote 16 + 0x7D, // SDL_SCANCODE_INTERNATIONAL3 = 137, - DIK_YEN + 0x79, // SDL_SCANCODE_INTERNATIONAL4 = 138, // Japan: XFER/"convert kana -> kanji", right of space - DIK_CONVERT + 0x7B, // SDL_SCANCODE_INTERNATIONAL5 = 139, // Japan: NFER/"don't convert kana -> kanji", left of space - DIK_NOCONVERT + 0x0, // SDL_SCANCODE_INTERNATIONAL6 = 140, // TODO: Hut1_12v2.pdf page 60, footnote 20 + 0x0, // SDL_SCANCODE_INTERNATIONAL7 = 141, // Toggle Double-Byte/Single-Byte mode. + 0x0, // SDL_SCANCODE_INTERNATIONAL8 = 142, // Undefined, available for other Front End Language Processors + 0x0, // SDL_SCANCODE_INTERNATIONAL9 = 143, // Undefined, available for other Front End Language Processors + 0x0, // SDL_SCANCODE_LANG1 = 144, // Hangul/English toggle (Korea) + 0x0, // SDL_SCANCODE_LANG2 = 145, // Hanja conversion (Korea) + 0x70, // SDL_SCANCODE_LANG3 = 146, // Katakana (Japan) - DIK_KANA + 0x0, // SDL_SCANCODE_LANG4 = 147, // Hiragana (Japan) + 0x0, // SDL_SCANCODE_LANG5 = 148, // Zenkaku/Hankaku (Japan) + 0x0, // SDL_SCANCODE_LANG6 = 149, // reserved + 0x0, // SDL_SCANCODE_LANG7 = 150, // reserved + 0x0, // SDL_SCANCODE_LANG8 = 151, // reserved + 0x0, // SDL_SCANCODE_LANG9 = 152, // reserved + + 0x0, // SDL_SCANCODE_ALTERASE = 153, // Erase-Eaze + + 0xB7, // SDL_SCANCODE_SYSREQ = 154, - DIK_SYSRQ; SDL_SCANCODE_PRINTSCREEN also maps to this! + + 0x0, // SDL_SCANCODE_CANCEL = 155, + 0x0, // SDL_SCANCODE_CLEAR = 156, + 0x0, // SDL_SCANCODE_PRIOR = 157, + 0x0, // SDL_SCANCODE_RETURN2 = 158, + 0x0, // SDL_SCANCODE_SEPARATOR = 159, + 0x0, // SDL_SCANCODE_OUT = 160, + 0x0, // SDL_SCANCODE_OPER = 161, + 0x0, // SDL_SCANCODE_CLEARAGAIN = 162, + 0x0, // SDL_SCANCODE_CRSEL = 163, + 0x0, // SDL_SCANCODE_EXSEL = 164, + + 0x0, // 165 (unused) + 0x0, // 166 (unused) + 0x0, // 167 (unused) + 0x0, // 168 (unused) + 0x0, // 169 (unused) + 0x0, // 170 (unused) + 0x0, // 171 (unused) + 0x0, // 172 (unused) + 0x0, // 173 (unused) + 0x0, // 174 (unused) + 0x0, // 175 (unused) + + 0x0, // SDL_SCANCODE_KP_00 = 176, + 0x0, // SDL_SCANCODE_KP_000 = 177, + 0x0, // SDL_SCANCODE_THOUSANDSSEPARATOR = 178, + 0x0, // SDL_SCANCODE_DECIMALSEPARATOR = 179, + 0x0, // SDL_SCANCODE_CURRENCYUNIT = 180, + 0x0, // SDL_SCANCODE_CURRENCYSUBUNIT = 181, + 0x0, // SDL_SCANCODE_KP_LEFTPAREN = 182, + 0x0, // SDL_SCANCODE_KP_RIGHTPAREN = 183, + 0x0, // SDL_SCANCODE_KP_LEFTBRACE = 184, + 0x0, // SDL_SCANCODE_KP_RIGHTBRACE = 185, + 0x0, // SDL_SCANCODE_KP_TAB = 186, + 0x0, // SDL_SCANCODE_KP_BACKSPACE = 187, + 0x0, // SDL_SCANCODE_KP_A = 188, + 0x0, // SDL_SCANCODE_KP_B = 189, + 0x0, // SDL_SCANCODE_KP_C = 190, + 0x0, // SDL_SCANCODE_KP_D = 191, + 0x0, // SDL_SCANCODE_KP_E = 192, + 0x0, // SDL_SCANCODE_KP_F = 193, + 0x0, // SDL_SCANCODE_KP_XOR = 194, + 0x0, // SDL_SCANCODE_KP_POWER = 195, + 0x0, // SDL_SCANCODE_KP_PERCENT = 196, + 0x0, // SDL_SCANCODE_KP_LESS = 197, + 0x0, // SDL_SCANCODE_KP_GREATER = 198, + 0x0, // SDL_SCANCODE_KP_AMPERSAND = 199, + 0x0, // SDL_SCANCODE_KP_DBLAMPERSAND = 200, + 0x0, // SDL_SCANCODE_KP_VERTICALBAR = 201, + 0x0, // SDL_SCANCODE_KP_DBLVERTICALBAR = 202, + + 0x92, // SDL_SCANCODE_KP_COLON = 203, - DIK_COLON + + 0x0, // SDL_SCANCODE_KP_HASH = 204, + 0x0, // SDL_SCANCODE_KP_SPACE = 205, + + 0x91, // SDL_SCANCODE_KP_AT = 206, - DIK_AT + + 0x0, // SDL_SCANCODE_KP_EXCLAM = 207, + 0x0, // SDL_SCANCODE_KP_MEMSTORE = 208, + 0x0, // SDL_SCANCODE_KP_MEMRECALL = 209, + 0x0, // SDL_SCANCODE_KP_MEMCLEAR = 210, + 0x0, // SDL_SCANCODE_KP_MEMADD = 211, + 0x0, // SDL_SCANCODE_KP_MEMSUBTRACT = 212, + 0x0, // SDL_SCANCODE_KP_MEMMULTIPLY = 213, + 0x0, // SDL_SCANCODE_KP_MEMDIVIDE = 214, + 0x0, // SDL_SCANCODE_KP_PLUSMINUS = 215, + 0x0, // SDL_SCANCODE_KP_CLEAR = 216, + 0x0, // SDL_SCANCODE_KP_CLEARENTRY = 217, + 0x0, // SDL_SCANCODE_KP_BINARY = 218, + 0x0, // SDL_SCANCODE_KP_OCTAL = 219, + 0x0, // SDL_SCANCODE_KP_DECIMAL = 220, + 0x0, // SDL_SCANCODE_KP_HEXADECIMAL = 221, + + 0x0, // 222 (unused) + 0x0, // 223 (unused) + + 0x1D, // SDL_SCANCODE_LCTRL = 224, - DIK_LCONTROL + 0x2A, // SDL_SCANCODE_LSHIFT = 225, - DIK_LSHIFT + 0x38, // SDL_SCANCODE_LALT = 226, // left Alt, option - DIK_LMENU + 0xDB, // SDL_SCANCODE_LGUI = 227, // left windows, command (apple), meta - DIK_LWIN + 0x9D, // SDL_SCANCODE_RCTRL = 228, - DIK_RCONTROL + 0x36, // SDL_SCANCODE_RSHIFT = 229, - DIK_RSHIFT + 0xB8, // SDL_SCANCODE_RALT = 230, // right Alt/AltGr, option - DIK_RMENU, also used for SDL_SCANCODE_MODE! + 0xDC, // SDL_SCANCODE_RGUI = 231, // left windows, command (apple), meta - DIK_RWIN + + // 232 - 256 unused + 0, 0, 0, 0, 0, 0, 0, 0, 0, // 232 - 240 unused + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 241-250 unused + 0, 0, 0, 0, 0, 0, // 251-256 unused + + 0xB8, // SDL_SCANCODE_MODE = 257, // this seems to be the AltGr Key? - DIK_RMENU (right alt) + + // These values are mapped from usage page 0x0C (USB consumer page). + 0x99, // SDL_SCANCODE_AUDIONEXT = 258, - DIK_NEXTTRACK + 0x90, // SDL_SCANCODE_AUDIOPREV = 259, - DIK_PREVTRACK, which is DIK_CIRCUMFLEX on japanese keyboards + 0xA4, // SDL_SCANCODE_AUDIOSTOP = 260, - DIK_MEDIASTOP + 0xA2, // SDL_SCANCODE_AUDIOPLAY = 261, - DIK_PLAYPAUSE + 0xA0, // SDL_SCANCODE_AUDIOMUTE = 262, - DIK_MUTE + 0xED, // SDL_SCANCODE_MEDIASELECT = 263, - DIK_MEDIASELECT + + 0x0, // SDL_SCANCODE_WWW = 264, + + 0xEC, // SDL_SCANCODE_MAIL = 265, - DIK_MAIL + 0xA1, // SDL_SCANCODE_CALCULATOR = 266, - DIK_CALCULATOR + 0xEB, // SDL_SCANCODE_COMPUTER = 267, - DIK_MYCOMPUTER + 0xE5, // SDL_SCANCODE_AC_SEARCH = 268, - DIK_WEBSEARCH + 0xB2, // SDL_SCANCODE_AC_HOME = 269, - DIK_WEBHOME + 0xEA, // SDL_SCANCODE_AC_BACK = 270, - DIK_WEBBACK + 0xE9, // SDL_SCANCODE_AC_FORWARD = 271, - DIK_WEBFORWARD + 0xE8, // SDL_SCANCODE_AC_STOP = 272, - DIK_WEBSTOP + 0xE7, // SDL_SCANCODE_AC_REFRESH = 273, - DIK_WEBREFRESH + 0xE6, // SDL_SCANCODE_AC_BOOKMARKS = 274, - DIK_WEBFAVORITES + + // These are values that Christian Walther added (for mac keyboard?). + 0x0, // SDL_SCANCODE_BRIGHTNESSDOWN = 275, + 0x0, // SDL_SCANCODE_BRIGHTNESSUP = 276, + 0x0, // SDL_SCANCODE_DISPLAYSWITCH = 277, // display mirroring/dual display switch, video mode switch + 0x0, // SDL_SCANCODE_KBDILLUMTOGGLE = 278, + 0x0, // SDL_SCANCODE_KBDILLUMDOWN = 279, + 0x0, // SDL_SCANCODE_KBDILLUMUP = 280, + 0x0, // SDL_SCANCODE_EJECT = 281, + + 0xDF, // SDL_SCANCODE_SLEEP = 282, - DIK_SLEEP + + 0x0, // SDL_SCANCODE_APP1 = 283, + 0x0, // SDL_SCANCODE_APP2 = 284, + // end of Walther-keys + + // the rest up to 511 are currently not named in SDL + + 0, 0, 0, 0, 0, 0, // 285-290 unused + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 291-300 unused + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 301-320 unused + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 321-340 unused + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 341-360 unused + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 361-380 unused + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 381-400 unused + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 401-420 unused + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 421-440 unused + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 441-460 unused + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 461-480 unused + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 481-500 unused + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 501-511 unused +}; + +#endif /* _SDL2_SCANCODE_TO_DINPUT_H_ */ diff --git a/src/harness/platforms/sdl_opengl.c b/src/harness/platforms/sdl_opengl.c new file mode 100644 index 00000000..5161f5a5 --- /dev/null +++ b/src/harness/platforms/sdl_opengl.c @@ -0,0 +1,247 @@ +#include + +// this needs to be included after glad.h +#include +#include + +#include "../renderers/gl/gl_renderer.h" +#include "harness/config.h" +#include "harness/hooks.h" +#include "harness/trace.h" +#include "sdl2_scancode_to_dinput.h" + +#include "globvars.h" +#include "grafdata.h" +#include "pd/sys.h" + +SDL_Window* window; +SDL_GLContext context; +uint8_t directinput_key_state[SDL_NUM_SCANCODES]; +int render_width, render_height; +int window_width, window_height; +int vp_x, vp_y, vp_width, vp_height; + +struct { + float x; + float y; +} sdl_window_scale; + +static void update_viewport() { + const float target_aspect_ratio = (float)render_width / render_height; + const float aspect_ratio = (float)window_width / window_height; + + vp_width = window_width; + vp_height = window_height; + if (aspect_ratio != target_aspect_ratio) { + if (aspect_ratio > target_aspect_ratio) { + vp_width = window_height * target_aspect_ratio + .5f; + } else { + vp_height = window_width / target_aspect_ratio + .5f; + } + } + vp_x = (window_width - vp_width) / 2; + vp_y = (window_height - vp_height) / 2; + GLRenderer_SetViewport(vp_x, vp_y, vp_width, vp_height); +} + +void* create_window_and_renderer(char* title, int x, int y, int width, int height) { + window_width = width; + window_height = height; + render_width = width; + render_height = 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, 1); + + SDL_GL_SetSwapInterval(1); + + window = SDL_CreateWindow(title, + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + width, height, + SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + + if (window == NULL) { + LOG_PANIC("Failed to create window. %s", SDL_GetError()); + } + + sdl_window_scale.x = ((float)render_width) / width; + sdl_window_scale.y = ((float)render_height) / height; + + if (harness_game_config.start_full_screen) { + SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + } + + 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); + } + + GLRenderer_Init(render_width, render_height); + update_viewport(); + + return window; +} + +int set_window_pos(void* hWnd, int x, int y, int nWidth, int nHeight) { + // SDL_SetWindowPosition(hWnd, x, y); + if (nWidth == 320 && nHeight == 200) { + nWidth = 640; + nHeight = 400; + } + SDL_SetWindowSize(hWnd, nWidth, nHeight); + return 0; +} + +void destroy_window(void* hWnd) { + SDL_GL_DeleteContext(context); + SDL_DestroyWindow(window); + SDL_Quit(); + window = NULL; +} + +// Checks whether the `flag_check` is the only modifier applied. +// e.g. is_only_modifier(event.key.keysym.mod, KMOD_ALT) returns true when only the ALT key was pressed +static int is_only_key_modifier(int modifier_flags, int flag_check) { + return (modifier_flags & flag_check) && (modifier_flags & (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_GUI)) == (modifier_flags & flag_check); +} + +int get_and_handle_message(MSG_* msg) { + SDL_Event event; + int dinput_key; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + if (event.key.keysym.sym == SDLK_RETURN) { + if (event.key.type == SDL_KEYDOWN) { + if ((event.key.keysym.mod & (KMOD_CTRL | KMOD_SHIFT | KMOD_ALT | KMOD_GUI))) { + // Ignore keydown of RETURN when used together with some modifier + return 0; + } + } else if (event.key.type == SDL_KEYUP) { + if (is_only_key_modifier(event.key.keysym.mod, KMOD_ALT)) { + SDL_SetWindowFullscreen(window, (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP); + } + } + } + + // Map incoming SDL scancode to DirectInput DIK_* key code. + // https://github.com/DanielGibson/Snippets/blob/master/sdl2_scancode_to_dinput.h + dinput_key = sdlScanCodeToDirectInputKeyNum[event.key.keysym.scancode]; + if (dinput_key == 0) { + LOG_WARN("unexpected scan code %s (%d)", SDL_GetScancodeName(event.key.keysym.scancode), event.key.keysym.scancode); + return 0; + } + // DInput expects high bit to be set if key is down + // https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ee418261(v=vs.85) + directinput_key_state[dinput_key] = (event.type == SDL_KEYDOWN ? 0x80 : 0); + break; + + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_SIZE_CHANGED: + SDL_GetWindowSize(window, &window_width, &window_height); + update_viewport(); + sdl_window_scale.x = (float)render_width / vp_width; + sdl_window_scale.y = (float)render_height / vp_height; + break; + } + break; + + case SDL_QUIT: + msg->message = WM_QUIT; + return 1; + } + } + return 0; +} + +void swap_window() { + SDL_GL_SwapWindow(window); +} + +void get_keyboard_state(unsigned int count, uint8_t* buffer) { + memcpy(buffer, directinput_key_state, count); +} + +int get_mouse_buttons(int* pButton1, int* pButton2) { + int state = SDL_GetMouseState(NULL, NULL); + *pButton1 = state & SDL_BUTTON_LMASK; + *pButton2 = state & SDL_BUTTON_RMASK; + return 0; +} + +int get_mouse_position(int* pX, int* pY) { + SDL_GetMouseState(pX, pY); + + if (*pX < vp_x) { + *pX = vp_x; + } else if (*pX >= vp_x + vp_width) { + *pX = vp_x + vp_width - 1; + } + if (*pY < vp_y) { + *pY = vp_y; + } else if (*pY >= vp_y + vp_height) { + *pY = vp_y + vp_height - 1; + } + *pX -= vp_x; + *pY -= vp_y; + *pX *= sdl_window_scale.x; + *pY *= sdl_window_scale.y; + +#if defined(DETHRACE_FIX_BUGS) + // In hires mode (640x480), the menus are still rendered at (320x240), + // so prescale the cursor coordinates accordingly. + *pX *= gGraf_specs[gGraf_data_index].phys_width; + *pX /= gGraf_specs[gReal_graf_data_index].phys_width; + *pY *= gGraf_specs[gGraf_data_index].phys_height; + *pY /= gGraf_specs[gReal_graf_data_index].phys_height; +#endif + return 0; +} + +void set_palette(PALETTEENTRY_* pal) { + GLRenderer_SetPalette((uint8_t*)pal); +} + +void Harness_Platform_Init(tHarness_platform* platform) { + platform->ProcessWindowMessages = get_and_handle_message; + platform->Sleep = SDL_Delay; + platform->GetTicks = SDL_GetTicks; + platform->CreateWindowAndRenderer = create_window_and_renderer; + platform->ShowCursor = SDL_ShowCursor; + platform->SetWindowPos = set_window_pos; + platform->SwapWindow = swap_window; + platform->DestroyWindow = destroy_window; + platform->GetKeyboardState = get_keyboard_state; + platform->GetMousePosition = get_mouse_position; + platform->GetMouseButtons = get_mouse_buttons; + platform->DestroyWindow = destroy_window; + + platform->Renderer_BufferModel = GLRenderer_BufferModel; + platform->Renderer_BufferMaterial = GLRenderer_BufferMaterial; + platform->Renderer_BufferTexture = GLRenderer_BufferTexture; + platform->Renderer_SetPalette = set_palette; + platform->Renderer_FullScreenQuad = GLRenderer_FullScreenQuad; + platform->Renderer_Model = GLRenderer_Model; + platform->Renderer_ClearBuffers = GLRenderer_ClearBuffers; + platform->Renderer_FlushBuffers = GLRenderer_FlushBuffers; + platform->Renderer_BeginScene = GLRenderer_BeginScene; + platform->Renderer_EndScene = GLRenderer_EndScene; + platform->Renderer_SetViewport = GLRenderer_SetViewport; +} diff --git a/src/harness/renderers/gl/gl_renderer.c b/src/harness/renderers/gl/gl_renderer.c index 4e631415..a4aa2de9 100644 --- a/src/harness/renderers/gl/gl_renderer.c +++ b/src/harness/renderers/gl/gl_renderer.c @@ -26,10 +26,11 @@ static uint8_t gl_palette[4 * 256]; // RGBA static uint8_t* screen_buffer_flip_pixels; static uint16_t* depth_buffer_flip_pixels; -static int window_width, window_height, render_width, render_height; +static int render_width, render_height; static int vp_x, vp_y, vp_width, vp_height; -static br_pixelmap *last_colour_buffer, *last_depth_buffer; +static br_pixelmap *last_colour_buffer, + *last_depth_buffer; static int dirty_buffers = 0; static br_pixelmap *last_colour_buffer, *last_depth_buffer; @@ -207,29 +208,9 @@ void SetupFullScreenRectGeometry() { glBindVertexArray(0); } -static void update_viewport() { - const float target_aspect_ratio = (float)render_width / render_height; - const float aspect_ratio = (float)window_width / window_height; - - vp_width = window_width; - vp_height = window_height; - if (aspect_ratio != target_aspect_ratio) { - if (aspect_ratio > target_aspect_ratio) { - vp_width = window_height * target_aspect_ratio + .5f; - } else { - vp_height = window_width / target_aspect_ratio + .5f; - } - } - vp_x = (window_width - vp_width) / 2; - vp_y = (window_height - vp_height) / 2; -} - -void GLRenderer_Init(int width, int height, int pRender_width, int pRender_height) { - window_width = width; - window_height = height; +void GLRenderer_Init(int pRender_width, int pRender_height) { render_width = pRender_width; render_height = pRender_height; - update_viewport(); LOG_INFO("OpenGL vendor string: %s", glGetString(GL_VENDOR)); LOG_INFO("OpenGL renderer string: %s", glGetString(GL_RENDERER)); @@ -750,25 +731,9 @@ void GLRenderer_FlushBuffers(tRenderer_flush_type flush_type) { dirty_buffers = 0; } -void GLRenderer_GetRenderSize(int* width, int* height) { - *width = render_width; - *height = render_height; -} - -void GLRenderer_GetWindowSize(int* width, int* height) { - *width = window_width; - *height = window_height; -} - -void GLRenderer_SetWindowSize(int width, int height) { - window_width = width; - window_height = height; - update_viewport(); -} - -void GLRenderer_GetViewport(int* x, int* y, int* width, int* height) { - *x = vp_x; - *y = vp_y; - *width = vp_width; - *height = vp_height; +void GLRenderer_SetViewport(int x, int y, int width, int height) { + vp_x = x; + vp_y = y; + vp_width = width; + vp_height = height; } diff --git a/src/harness/renderers/gl/gl_renderer.h b/src/harness/renderers/gl/gl_renderer.h index a4bb994b..93a9379a 100644 --- a/src/harness/renderers/gl/gl_renderer.h +++ b/src/harness/renderers/gl/gl_renderer.h @@ -2,7 +2,7 @@ #define HARNESS_GL_RENDERER #include "harness.h" -#include "renderers/renderer.h" +#include "harness/hooks.h" #define CHECK_GL_ERROR(msg) \ { \ @@ -42,7 +42,7 @@ } \ } -void GLRenderer_Init(int width, int height, int render_width, int render_height); +void GLRenderer_Init(int render_width, int render_height); void GLRenderer_SetPalette(uint8_t* rgba_colors); void GLRenderer_BeginScene(br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer); void GLRenderer_EndScene(); @@ -53,9 +53,6 @@ void GLRenderer_BufferMaterial(br_material* mat); void GLRenderer_BufferModel(br_model* model); void GLRenderer_ClearBuffers(); void GLRenderer_FlushBuffers(tRenderer_flush_type flush_type); -void GLRenderer_GetRenderSize(int* width, int* height); -void GLRenderer_GetWindowSize(int* width, int* height); -void GLRenderer_SetWindowSize(int width, int height); -void GLRenderer_GetViewport(int* x, int* y, int* width, int* height); +void GLRenderer_SetViewport(int x, int y, int width, int height); #endif diff --git a/src/harness/renderers/null.h b/src/harness/renderers/null.h deleted file mode 100644 index 4ec360cc..00000000 --- a/src/harness/renderers/null.h +++ /dev/null @@ -1,47 +0,0 @@ -#include "renderer.h" - -void Null_Init() {} -void Null_BeginFrame(br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer) {} -void Null_EndFrame() {} -void Null_SetPalette(uint8_t* palette) {} -void Null_RenderFullScreenQuad(uint8_t* src) {} -void Null_RenderModel(br_actor* actor, br_model* model, br_material* material, br_token render_type, br_matrix34 model_matrix) {} -void Null_RenderFrameBuffer() {} -void Null_ClearBuffers() {} -void Null_BufferTexture(br_pixelmap* pm) {} -void Null_BufferMaterial(br_material* mat) {} -void Null_BufferModel(br_model* model) {} -void Null_FlushBuffers() {} -void Null_GetRenderSize(int* width, int* height) { - *width = 640; - *height = 480; -} -void Null_GetWindowSize(int* width, int* height) { - *width = 640; - *height = 480; -} -void Null_SetWindowSize(int width, int height) {} -void Null_GetViewportSize(int* x, int* y, int* width, int* height) { - *x = 0; - *y = 0; - *width = 640; - *height = 480; -} - -tRenderer null_renderer = { - Null_Init, - Null_BeginFrame, - Null_EndFrame, - Null_SetPalette, - Null_RenderFullScreenQuad, - Null_RenderModel, - Null_ClearBuffers, - Null_BufferTexture, - Null_BufferMaterial, - Null_BufferModel, - Null_FlushBuffers, - Null_GetRenderSize, - Null_GetWindowSize, - Null_SetWindowSize, - Null_GetViewportSize -}; diff --git a/src/harness/renderers/renderer.h b/src/harness/renderers/renderer.h deleted file mode 100644 index 6229b617..00000000 --- a/src/harness/renderers/renderer.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef HARNESS_RENDERER_H -#define HARNESS_RENDERER_H - -#include "brender/br_types.h" - -typedef enum { - eFlush_all, - eFlush_color_buffer -} tRenderer_flush_type; - -typedef struct tRenderer { - void (*Init)(int width, int height, int pRender_width, int pRender_height); - void (*BeginScene)(br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer); - void (*EndScene)(); - void (*SetPalette)(uint8_t* palette); - void (*FullScreenQuad)(uint8_t* src); - void (*Model)(br_actor* actor, br_model* model, br_material* material, br_token render_type, br_matrix34 model_matrix); - void (*ClearBuffers)(); - void (*BufferTexture)(br_pixelmap* pm); - void (*BufferMaterial)(br_material* mat); - void (*BufferModel)(br_model* model); - void (*FlushBuffers)(tRenderer_flush_type); - void (*GetRenderSize)(int* width, int* height); - void (*GetWindowSize)(int* width, int* height); - void (*SetWindowSize)(int width, int height); - void (*GetViewport)(int* x, int* y, int* width, int* height); -} tRenderer; - -#endif diff --git a/src/harness/resources/framebuffer_frag.glsl b/src/harness/resources/framebuffer_frag.glsl index 1af906f9..82e382ea 100644 --- a/src/harness/resources/framebuffer_frag.glsl +++ b/src/harness/resources/framebuffer_frag.glsl @@ -11,5 +11,5 @@ layout (location = 0) out vec4 out_frag_color; void main() { uint palette_index = texture(u_pixels, v_tex_coord.xy).r; vec4 texel = texelFetch(u_palette, ivec2(palette_index, 0), 0); - out_frag_color = texel; + out_frag_color = vec4(texel.bgra); } diff --git a/src/harness/win95/polyfill.c b/src/harness/win95/polyfill.c new file mode 100644 index 00000000..f8d1fde4 --- /dev/null +++ b/src/harness/win95/polyfill.c @@ -0,0 +1,249 @@ + +#include "harness/hooks.h" +#include "harness/win95_polyfill.h" + +#include +#include +#include +#include + +#if defined(_WIN32) || defined(_WIN64) + +#include +#include +// https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getcwd-wgetcwd?view=msvc-170 +#define getcwd _getcwd +#define chdir _chdir +#else +#include +#include +#include +#endif + +// All functions have a "_" suffix to avoid collisions with -defined types + +uint32_t GetFileAttributesA_(char* lpFileName) { + + FILE* f = fopen(lpFileName, "r"); + if (!f) { + return INVALID_FILE_ATTRIBUTES; + } + return FILE_ATTRIBUTE_NORMAL; +} + +int SetFileAttributesA_(char* lpFileName, uint32_t dwFileAttributes) { + // no-op for now + return 0; +} + +void* CreateFileA_(char* lpFileName, uint32_t dwDesiredAccess, uint32_t dwShareMode, void* lpSecurityAttributes, uint32_t dwCreationDisposition, uint32_t dwFlagsAndAttributes, void* hTemplateFile) { + + assert(dwDesiredAccess == GENERIC_READ); + assert(lpSecurityAttributes == NULL); + assert(dwCreationDisposition == OPEN_EXISTING); + + FILE* f = fopen(lpFileName, "r"); + if (!f) { + return INVALID_HANDLE_VALUE; + } + + return f; +} + +uint32_t GetFileSize_(void* hFile, uint32_t* lpFileSizeHigh) { + assert(lpFileSizeHigh == NULL); + + long current_offset = ftell(hFile); + fseek(hFile, 0, SEEK_END); + long size = ftell(hFile); + fseek(hFile, current_offset, SEEK_SET); + return size; +} + +int CloseHandle_(void* hObject) { + fclose(hObject); + return 0; +} + +void GlobalMemoryStatus_(MEMORYSTATUS_* lpBuffer) { + lpBuffer->dwTotalPhys = 64000000; + lpBuffer->dwAvailPhys = 64000000; // pretend we have a whole 64mb of ram! + lpBuffer->dwAvailPageFile = 0; + lpBuffer->dwTotalVirtual = 0; + lpBuffer->dwAvailVirtual = 0; + lpBuffer->dwMemoryLoad = 0; + lpBuffer->dwTotalPageFile = 0; +} + +int GetCursorPos_(POINT_* lpPoint) { + int x, y; + gHarness_platform.GetMousePosition(&x, &y); + lpPoint->x = x; + lpPoint->y = y; + return 0; +} + +int ScreenToClient_(void* hWnd, POINT_* lpPoint) { + // no-op, we assume the point is already relative to client + return 0; +} + +uint32_t timeGetTime_() { + return gHarness_platform.GetTicks(); +} + +uint32_t GetCurrentDirectoryA_(uint32_t nBufferLength, char* lpBuffer) { + char* ret = getcwd(lpBuffer, nBufferLength); + if (ret == NULL) { + return 0; + } + return strlen(lpBuffer); +} + +int SetCurrentDirectoryA_(char* lpPathName) { + int ret = chdir(lpPathName); + // chdir returning zero means success, SetCurrentDirectory returning non-zero means success + if (ret == 0) { + return 1; + } else { + return 0; + } +} + +HANDLE_ FindFirstFileA_(char* lpFileName, WIN32_FIND_DATAA_* lpFindFileData) { + assert(strcmp(lpFileName, "*.???") == 0); + +#if defined(_WIN32) || defined(_WIN64) + WIN32_FIND_DATA fd; + void* hFile = FindFirstFile(lpFileName, &fd); + if (hFile != INVALID_HANDLE_VALUE) { + strcpy(lpFindFileData->cFileName, fd.cFileName); + } + return hFile; +#else + DIR* dir; + strcpy(lpFileName, "."); + dir = opendir(lpFileName); + if (dir == NULL) { + return INVALID_HANDLE_VALUE; + } + if (FindNextFileA_(dir, lpFindFileData)) { + return dir; + } else { + closedir(dir); + return INVALID_HANDLE_VALUE; + } +#endif +} + +int FindNextFileA_(HANDLE_ hFindFile, WIN32_FIND_DATAA_* lpFindFileData) { +#if defined(_WIN32) || defined(_WIN64) + WIN32_FIND_DATA fd; + int result = FindNextFile(hFindFile, &fd); + if (result) { + strcpy(lpFindFileData->cFileName, fd.cFileName); + } + return result; +#else + struct dirent* entry; + + if (hFindFile == NULL) { + return 0; + } + while ((entry = readdir(hFindFile)) != NULL) { + if (entry->d_type == DT_REG) { + strcpy(lpFindFileData->cFileName, entry->d_name); + return 1; + } + } + return 0; +#endif +} + +int FindClose_(HANDLE_ hFindFile) { +#if defined(_WIN32) || defined(_WIN64) + return FindClose(hFindFile); +#else + return closedir(hFindFile); + +#endif +} + +void* CreateWindowExA_(uint32_t dwExStyle, char* lpClassName, char* lpWindowName, uint32_t dwStyle, int X, int Y, int nWidth, int nHeight, void* hWndParent, void* hMenu, void* hInstance, void* lpParam) { + return gHarness_platform.CreateWindowAndRenderer(lpWindowName, X, Y, nWidth, nHeight); +} + +int SetWindowPos_(void* hWnd, void* hWndInsertAfter, int X, int Y, int cx, int cy, unsigned int uFlags) { + return gHarness_platform.SetWindowPos(hWnd, X, Y, cx, cy); +} + +int ShowCursor_(int bShow) { + gHarness_platform.ShowCursor(bShow); + return 0; +} + +int SendMessageA_(void* hWnd, unsigned int Msg, unsigned int wParam, long lParam) { + return 0; +} + +int MessageBoxA_(void* hWnd, char* lpText, char* lpCaption, unsigned int uType) { + return 0; +} + +int DestroyWindow_(void* hWnd) { + gHarness_platform.DestroyWindow(hWnd); + return 0; +} + +void ExitProcess_(unsigned int uExitCode) { + exit(uExitCode); +} + +void TranslateMessage_(MSG_* lpMsg) { + // no-op +} + +void DispatchMessageA_(MSG_* lpMsg) { + // no-op +} + +int PeekMessageA_(MSG_* lpMsg, void* hWnd, unsigned int wMsgFilterMin, unsigned int wMsgFilterMax, unsigned int wRemoveMsg) { + return gHarness_platform.ProcessWindowMessages(lpMsg); +} + +int GetMessageA_(MSG_* lpMsg, void* hWnd, unsigned int wMsgFilterMin, unsigned int wMsgFilterMax) { + return gHarness_platform.ProcessWindowMessages(lpMsg); +} + +void Sleep_(uint32_t dwMilliseconds) { + gHarness_platform.Sleep(dwMilliseconds); +} + +void DirectDraw_CreateSurface(int width, int height) { + // no-op +} + +void DirectInputDevice_GetDeviceState(unsigned int count, uint8_t* buffer) { + gHarness_platform.GetKeyboardState(count, buffer); +} + +void DirectDrawDevice_SetPaletteEntries(PALETTEENTRY_* palette, int pFirst_colour, int pCount) { + assert(pFirst_colour == 0); + assert(pCount == 256); + gHarness_platform.Renderer_SetPalette(palette); + Harness_RenderLastScreen(); +} + +void _splitpath_(char* path, char* drive, char* dir, char* fname, char* ext) { +#ifdef _WIN32 + _splitpath(path, NULL, NULL, fname, NULL); +#else + char* base = basename(path); + strcpy(fname, base); +#endif +} + +int _CrtDbgReport_(int reportType, const char* filename, int linenumber, const char* moduleName, const char* format, ...) { + printf("_CrtDbgReport: (TODO)\n"); + return 1; +} diff --git a/test/DETHRACE/test_controls.c b/test/DETHRACE/test_controls.c index 4e7ffd5a..6ced87db 100644 --- a/test/DETHRACE/test_controls.c +++ b/test/DETHRACE/test_controls.c @@ -10,6 +10,7 @@ #include "common/input.h" #include "common/loading.h" #include "common/utility.h" +#include "harness/hooks.h" extern int _unittest_controls_lastGetPowerup; @@ -23,7 +24,8 @@ void test_controls_CheckKevKeys() { gKeys_pressed = 0; result = KevKeyService(); } - OS_Sleep(2000); + gHarness_platform.Sleep(2000); + gKeys_pressed = 0; CheckKevKeys(); diff --git a/test/DETHRACE/test_input.c b/test/DETHRACE/test_input.c index 85525d81..e4c9507d 100644 --- a/test/DETHRACE/test_input.c +++ b/test/DETHRACE/test_input.c @@ -2,6 +2,7 @@ #include "common/globvars.h" #include "common/input.h" +#include "harness/hooks.h" #include void test_input_KevKeyService() { @@ -14,7 +15,7 @@ void test_input_KevKeyService() { gKeys_pressed = 0; result = KevKeyService(); } - OS_Sleep(2000); + gHarness_platform.Sleep(2000); gKeys_pressed = 0; result = KevKeyService(); diff --git a/test/main.c b/test/main.c index 429469c7..2dec0fe4 100644 --- a/test/main.c +++ b/test/main.c @@ -183,9 +183,10 @@ void setup_global_vars(int argc, char* argv[]) { if (getenv("NO_SIGNAL_HANDLER") != NULL) { fake_argv[fake_argc++] = "--no-signal-handler"; } - Harness_Init(&fake_argc, fake_argv); - Harness_ForceNullRenderer(); + Harness_ForceNullPlatform(); + + Harness_Init(&fake_argc, fake_argv); } int has_data_directory() { diff --git a/test/tests.h b/test/tests.h index 2ef52ac1..aa162c7d 100644 --- a/test/tests.h +++ b/test/tests.h @@ -11,6 +11,7 @@ #ifdef _WIN32 #define HOST_NL "\r\n" +#include #else #define HOST_NL "\n" #endif