├── src ├── S3 │ ├── ioserv.c │ ├── profile.c │ ├── ioserv.h │ ├── profile.h │ ├── resource.c │ ├── s3cda.h │ ├── s3music.h │ ├── include │ │ └── s3 │ │ │ ├── s3_brender.h │ │ │ └── s3.h │ ├── s3sound.h │ ├── s3music.c │ ├── 3d.h │ ├── CMakeLists.txt │ ├── s3cda.c │ ├── resource.h │ └── s3.h ├── harness │ ├── version.h.in │ ├── platforms │ │ ├── null.h │ │ ├── sdl1_syms.h │ │ ├── null.c │ │ ├── sdl_dyn_common.h │ │ └── sdl2_syms.h │ ├── include │ │ └── harness │ │ │ ├── compiler.h │ │ │ ├── os.h │ │ │ ├── audio.h │ │ │ ├── config.h │ │ │ ├── hooks.h │ │ │ └── trace.h │ ├── cameras │ │ ├── debug_camera.h │ │ └── debug_camera.c │ ├── harness.h │ ├── harness_trace.c │ ├── os │ │ └── null.c │ ├── audio │ │ └── null.c │ └── dethrace_scancodes.h ├── DETHRACE │ ├── common │ │ ├── demo.h │ │ ├── globvrme.c │ │ ├── globvrme.h │ │ ├── grafdata.h │ │ ├── main.h │ │ ├── globvrkm.h │ │ ├── drfile.h │ │ ├── cutscene.h │ │ ├── errors.h │ │ ├── drmem.h │ │ ├── globvrpb.h │ │ ├── intrface.h │ │ ├── globvrkm.c │ │ ├── skidmark.h │ │ ├── oppoproc.h │ │ ├── globvrbm.c │ │ ├── loadsave.h │ │ ├── mainloop.h │ │ ├── mainmenu.h │ │ ├── globvrbm.h │ │ ├── globvrpb.c │ │ ├── brucetrk.h │ │ ├── oppocar.h │ │ ├── structur.h │ │ ├── oil.h │ │ ├── init.h │ │ ├── pratcam.h │ │ ├── oppocar.c │ │ ├── replay.h │ │ ├── demo.c │ │ ├── trig.h │ │ ├── drfile.c │ │ ├── crush.h │ │ ├── raycast.h │ │ ├── input.h │ │ ├── netgame.h │ │ ├── sound.h │ │ ├── options.h │ │ ├── racesumm.h │ │ ├── depth.h │ │ ├── finteray.h │ │ └── main.c │ ├── pc-win95 │ │ ├── ssdx.h │ │ └── ssdx.c │ ├── pc-all │ │ └── net_types.h │ ├── main.c │ ├── pd │ │ └── net.h │ ├── pc-dos │ │ └── scancodes.h │ └── macros.h └── smackw32 │ ├── README.md │ ├── CMakeLists.txt │ └── include │ └── smackw32 │ └── smackw32.h ├── docs ├── discord-badge.jpg ├── CODE_LAYOUT.md ├── SCREENSHOTS.md ├── CONFIGURATION.md ├── RENDERING_PIPELINE.md ├── PORTING.md └── CHANGELOG.md ├── packaging ├── windows │ ├── dethrace.rc │ ├── dethrace.ico │ └── generate_ico.sh ├── icon_source.png └── macos │ ├── dethrace.icns │ └── generate_icns.sh ├── .gitignore ├── .gitmodules ├── lib ├── stb │ └── CMakeLists.txt ├── miniaudio │ ├── CMakeLists.txt │ └── LICENSE ├── inih │ ├── CMakeLists.txt │ └── LICENSE.TXT └── libsmacker │ ├── CMakeLists.txt │ ├── smk_bitstream.h │ ├── README │ ├── smk_malloc.h │ ├── smk_bitstream.c │ ├── smk_hufftree.h │ └── smacker.h ├── cmake ├── toolchains │ └── linux-aarch64.cmake ├── GetGitRevisionDescription.cmake.in ├── EmbedResource.cmake └── reccmp.cmake ├── test ├── DETHRACE │ ├── test_dossys.c │ ├── test_init.c │ ├── test_powerup.c │ ├── test_graphics.c │ ├── test_input.c │ ├── test_controls.c │ └── test_flicplay.c ├── CMakeLists.txt └── tests.h ├── tools ├── add_enum_values.py ├── keymap_to_keycode.py ├── watcom-codegen │ ├── split-dump.sh │ └── README.md ├── comment_struct_var.py └── progress.py ├── reccmp ├── set-env.reg ├── entrypoint.sh ├── Dockerfile └── README.md ├── NOTES.md └── .clang-format /src/S3/ioserv.c: -------------------------------------------------------------------------------- 1 | #include "ioserv.h" 2 | -------------------------------------------------------------------------------- /src/S3/profile.c: -------------------------------------------------------------------------------- 1 | #include "profile.h" 2 | -------------------------------------------------------------------------------- /docs/discord-badge.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buzz/dethrace/main/docs/discord-badge.jpg -------------------------------------------------------------------------------- /packaging/windows/dethrace.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "dethrace.ico" 2 | -------------------------------------------------------------------------------- /packaging/icon_source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buzz/dethrace/main/packaging/icon_source.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build* 2 | .DS_Store 3 | .vscode 4 | reccmp-user.yml 5 | reccmp-build.yml 6 | reccmp-report* 7 | -------------------------------------------------------------------------------- /packaging/macos/dethrace.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buzz/dethrace/main/packaging/macos/dethrace.icns -------------------------------------------------------------------------------- /src/S3/ioserv.h: -------------------------------------------------------------------------------- 1 | #ifndef _IOSERV_H_ 2 | #define _IOSERV_H_ 3 | 4 | #include "s3_defs.h" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /packaging/windows/dethrace.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/buzz/dethrace/main/packaging/windows/dethrace.ico -------------------------------------------------------------------------------- /src/S3/profile.h: -------------------------------------------------------------------------------- 1 | #ifndef _PROFILE_H_ 2 | #define _PROFILE_H_ 3 | 4 | #include "s3_defs.h" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/BRender-v1.3.2"] 2 | path = lib/BRender-v1.3.2 3 | url = https://github.com/dethrace-labs/BRender-v1.3.2.git 4 | -------------------------------------------------------------------------------- /lib/stb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(stb INTERFACE) 2 | 3 | target_include_directories(stb 4 | SYSTEM INTERFACE 5 | include 6 | ) 7 | -------------------------------------------------------------------------------- /lib/miniaudio/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(miniaudio INTERFACE) 2 | 3 | target_include_directories(miniaudio 4 | SYSTEM INTERFACE 5 | include 6 | ) 7 | -------------------------------------------------------------------------------- /src/harness/version.h.in: -------------------------------------------------------------------------------- 1 | #ifndef HARNESS_VERSION_H 2 | #define HARNESS_VERSION_H 3 | 4 | #cmakedefine DETHRACE_VERSION "@DETHRACE_VERSION@" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/DETHRACE/common/demo.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEMO_H_ 2 | #define _DEMO_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern int gLast_demo; 7 | 8 | void DoDemo(void); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/harness/platforms/null.h: -------------------------------------------------------------------------------- 1 | #ifndef PLATFORM_NULL 2 | #define PLATFORM_NULL 3 | 4 | #include "harness/hooks.h" 5 | 6 | void Null_Platform_Init(tHarness_platform* platform); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /cmake/toolchains/linux-aarch64.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME "Linux") 2 | set(CMAKE_SYSTEM_PROCESSOR "arm64") 3 | set(CMAKE_C_COMPILER "aarch64-linux-gnu-gcc") 4 | set(CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++") 5 | -------------------------------------------------------------------------------- /src/DETHRACE/common/globvrme.c: -------------------------------------------------------------------------------- 1 | #include "globvrme.h" 2 | #include 3 | 4 | // GLOBAL: CARM95 0x005508f0 5 | tCar_spec* gViewable_car_list[50]; 6 | 7 | // GLOBAL: CARM95 0x005509b8 8 | int gNum_viewable_cars; 9 | -------------------------------------------------------------------------------- /src/DETHRACE/common/globvrme.h: -------------------------------------------------------------------------------- 1 | #ifndef _GLOBVRME_H_ 2 | #define _GLOBVRME_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern tCar_spec* gViewable_car_list[50]; 7 | extern int gNum_viewable_cars; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/S3/resource.c: -------------------------------------------------------------------------------- 1 | #include "resource.h" 2 | 3 | void* S3MemAllocate(br_size_t size, br_uint_8 type) { 4 | return BrMemAllocate(size, type); 5 | } 6 | 7 | void S3MemFree(void* p) { 8 | BrMemFree(p); 9 | } 10 | -------------------------------------------------------------------------------- /test/DETHRACE/test_dossys.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | 3 | #include 4 | 5 | #include "common/globvars.h" 6 | #include "pd/sys.h" 7 | 8 | void test_dossys_suite() { 9 | UnitySetTestFile(__FILE__); 10 | } 11 | -------------------------------------------------------------------------------- /src/harness/include/harness/compiler.h: -------------------------------------------------------------------------------- 1 | #ifndef HARNESS_COMPILER_H 2 | #define HARNESS_COMPILER_H 3 | 4 | #if defined(_MSC_VER) 5 | #define HARNESS_NORETURN __declspec(noreturn) 6 | #else 7 | #define HARNESS_NORETURN __attribute__((noreturn)) 8 | #endif 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/DETHRACE/common/grafdata.h: -------------------------------------------------------------------------------- 1 | #ifndef _GRAFDATA_H_ 2 | #define _GRAFDATA_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern tGraf_data gGraf_data[2]; 7 | extern tGraf_data* gCurrent_graf_data; 8 | extern int gGraf_data_index; 9 | 10 | void CalcGrafDataIndex(void); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /tools/add_enum_values.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 -u 2 | 3 | import sys 4 | 5 | input = sys.argv[1] 6 | values = input.split('\n') 7 | i = 0 8 | for v in values: 9 | v = v.replace(',', '') 10 | print(v.strip(), '=', i, ',', '// ', hex(i)) 11 | i = i + 1 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /reccmp/set-env.reg: -------------------------------------------------------------------------------- 1 | Windows Registry Editor Version 5.00 2 | 3 | [HKEY_CURRENT_USER\Environment] 4 | "INCLUDE"="C:\\msvc\\include;C:\\msvc\\mfc\\include" 5 | "LIB"="C:\\msvc\\lib;C:\\msvc\\mfc\\lib" 6 | "TMP"="Z:\\build" 7 | "TEMP"="Z:\\build" 8 | "PATH"="C:\\msvc\\bin;C:\\msvc\\bin\\winnt;C:\\cmake\\bin;C:\\windows\\system32;C:\\ninja" 9 | -------------------------------------------------------------------------------- /src/harness/cameras/debug_camera.h: -------------------------------------------------------------------------------- 1 | #ifndef HARNESS_DEBUG_CAMERA_H 2 | #define HARNESS_DEBUG_CAMERA_H 3 | 4 | #include 5 | 6 | extern int gDebugCamera_active; 7 | 8 | void DebugCamera_Update(); 9 | float* DebugCamera_Projection(); 10 | float* DebugCamera_View(); 11 | void DebugCamera_SetPosition(float x, float y, float z); 12 | 13 | #endif -------------------------------------------------------------------------------- /test/DETHRACE/test_init.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | 3 | #include "common/globvars.h" 4 | #include "common/init.h" 5 | 6 | void test_init_AllocateCamera() { 7 | AllocateCamera(); 8 | TEST_ASSERT_NOT_NULL(gRearview_camera); 9 | } 10 | 11 | void test_init_suite() { 12 | UnitySetTestFile(__FILE__); 13 | RUN_TEST(test_init_AllocateCamera); 14 | } 15 | -------------------------------------------------------------------------------- /src/smackw32/README.md: -------------------------------------------------------------------------------- 1 | # smackw32 2 | 3 | Implementation of a minimal form of the Smacker API used by dethrace. 4 | 5 | See: 6 | - https://wiki.multimedia.cx/index.php/RAD_Game_Tools_Smacker_API 7 | - https://github.com/OpenSourcedGames/Aliens-vs-Predator/blob/master/source/AvP_vc/3dc/win95/SMACK.H 8 | 9 | 10 | Backed by http://libsmacker.sourceforge.net 11 | -------------------------------------------------------------------------------- /src/S3/s3cda.h: -------------------------------------------------------------------------------- 1 | #ifndef _S3CDA_H_ 2 | #define _S3CDA_H_ 3 | 4 | #include "s3_defs.h" 5 | 6 | void S3EnableCDA(void); 7 | void S3DisableCDA(void); 8 | int S3StopCDAOutlets(void); 9 | 10 | int S3PlayCDA(tS3_channel* chan); 11 | int S3StopCDA(tS3_channel* chan); 12 | int S3SetCDAVolume(tS3_channel* chan, int pVolume); 13 | int S3IsCDAPlaying(void); 14 | int S3IsCDAPlaying2(void); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/harness/harness.h: -------------------------------------------------------------------------------- 1 | #ifndef HARNESS_H 2 | #define HARNESS_H 3 | 4 | #include "harness/trace.h" 5 | 6 | void Harness_ForceNullPlatform(void); 7 | int Harness_CalculateFrameDelay(int last_frame_time); 8 | 9 | typedef struct tCamera { 10 | void (*update)(void); 11 | float* (*getProjection)(void); 12 | float* (*getView)(void); 13 | void (*setPosition)(void); 14 | } tCamera; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /tools/keymap_to_keycode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 -u 2 | 3 | # Used to discover the key referenced in `KeyIsDown` calls. 4 | # Input: keymap index 5 | # Output: keycode index 6 | 7 | import os 8 | import sys 9 | 10 | f = open(os.environ['DETHRACE_ROOT_DIR'] + '/data/KEYMAP_0.TXT') 11 | content = f.readlines() 12 | f.close() 13 | 14 | keymap_code = int(sys.argv[1]) 15 | print(content[keymap_code].strip()) 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/S3/s3music.h: -------------------------------------------------------------------------------- 1 | #ifndef _S3MUSIC_H_ 2 | #define _S3MUSIC_H_ 3 | 4 | #include "s3_defs.h" 5 | 6 | void S3DisableMIDI(void); 7 | void S3StopMIDIOutlets(void); 8 | void S3ReleaseMIDI(tS3_sound_tag); 9 | int S3PlayMIDI(tS3_channel* chan); 10 | int S3MIDILoadSong(tS3_channel* chan); 11 | int S3SetMIDIVolume(tS3_channel* chan); 12 | int S3StopMIDI(tS3_channel* chan); 13 | 14 | int S3IsMIDIStopped(tS3_channel* chan); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /test/DETHRACE/test_powerup.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | 3 | #include 4 | 5 | #include "common/globvars.h" 6 | #include "common/powerup.h" 7 | 8 | void test_loading_powerups() { 9 | REQUIRES_DATA_DIRECTORY(); 10 | 11 | LoadPowerups(); 12 | TEST_ASSERT_EQUAL_INT(51, gNumber_of_powerups); 13 | } 14 | 15 | void test_powerup_suite() { 16 | UnitySetTestFile(__FILE__); 17 | RUN_TEST(test_loading_powerups); 18 | } 19 | -------------------------------------------------------------------------------- /packaging/windows/generate_ico.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | SOURCE_IMAGE=$1 5 | TEMP_ICON_IMAGE=icon.png 6 | 7 | # resize to 412x with black canvas 8 | convert ${SOURCE_IMAGE} -resize 412x412 -background Black -gravity center -extent 412x412 ${TEMP_ICON_IMAGE} 9 | # convert to ico format 10 | convert -background transparent ${TEMP_ICON_IMAGE} -define icon:auto-resize=16,24,32,48,64,72,96,128,256 "dethrace.ico" 11 | 12 | rm ${TEMP_ICON_IMAGE} 13 | -------------------------------------------------------------------------------- /src/DETHRACE/common/main.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAIN_H_ 2 | #define _MAIN_H_ 3 | 4 | #include "dr_types.h" 5 | #include "harness/compiler.h" 6 | 7 | void QuitGame(void); 8 | 9 | tU32 TrackCount(br_actor* pActor, tU32* pCount); 10 | 11 | void CheckNumberOfTracks(void); 12 | 13 | void ServiceTheGame(int pRacing); 14 | 15 | void ServiceGame(void); 16 | 17 | void ServiceGameInRace(void); 18 | 19 | void GameMain(int pArgc, char** pArgv); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/S3/include/s3/s3_brender.h: -------------------------------------------------------------------------------- 1 | #ifndef S3_S3_BRENDER_H 2 | #define S3_S3_BRENDER_H 3 | 4 | #include "s3.h" 5 | 6 | #include "brender.h" 7 | 8 | tS3_sound_source_ptr S3CreateSoundSourceBR(br_vector3* pPosition, br_vector3* pVelocity, tS3_outlet_ptr pBound_outlet); 9 | 10 | void S3BindListenerPositionBRender(br_vector3* pos); 11 | void S3BindListenerVelocityBRender(br_vector3* vel); 12 | void S3BindListenerLeftBRender(br_vector3* left); 13 | 14 | #endif /* S3_S3_BRENDER_H */ 15 | -------------------------------------------------------------------------------- /lib/inih/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") 4 | 5 | if(NOT DEFINED CMAKE_BUILD_TYPE) 6 | set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo" FORCE) 7 | endif() 8 | 9 | project(inih C) 10 | 11 | add_library(inih STATIC) 12 | 13 | target_include_directories(inih 14 | SYSTEM PUBLIC 15 | . 16 | ) 17 | 18 | target_sources(inih PRIVATE 19 | ini.c 20 | ) 21 | -------------------------------------------------------------------------------- /test/DETHRACE/test_graphics.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | 3 | #include "common/graphics.h" 4 | 5 | void test_graphics_loadfont() { 6 | REQUIRES_DATA_DIRECTORY(); 7 | 8 | TEST_ASSERT_EQUAL_INT(0, gFonts[kFont_TYPEABLE].file_read_once); 9 | LoadFont(kFont_TYPEABLE); 10 | TEST_ASSERT_EQUAL_INT(1, gFonts[kFont_TYPEABLE].file_read_once); 11 | TEST_ASSERT_NOT_NULL(gFonts[kFont_TYPEABLE].images); 12 | } 13 | 14 | void test_graphics_suite() { 15 | UnitySetTestFile(__FILE__); 16 | RUN_TEST(test_graphics_loadfont); 17 | } 18 | -------------------------------------------------------------------------------- /src/DETHRACE/common/globvrkm.h: -------------------------------------------------------------------------------- 1 | #ifndef _GLOBVRKM_H_ 2 | #define _GLOBVRKM_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern br_scalar gCamera_zoom; 7 | extern br_angle gCamera_yaw; 8 | extern br_vector3 gView_direction; 9 | extern int gCamera_sign; 10 | extern int gCar_flying; 11 | extern int gCamera_reset; 12 | extern tCar_spec* gCar_to_view; 13 | extern br_actor* gCamera_list[2]; 14 | extern tCar_spec* gActive_car_list[25]; 15 | extern int gNum_active_cars; 16 | extern float gRecovery_cost[3]; 17 | extern br_scalar gCamera_height; 18 | extern br_scalar gMin_camera_car_distance; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /reccmp/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | export WINEPREFIX=/wineprefix 5 | 6 | # Configure build with CMake 7 | wine cmake -B build source $CMAKE_FLAGS 8 | 9 | # Build 10 | wine cmake --build build -- -j1 11 | 12 | # Update path to original binary 13 | cd /source 14 | reccmp-project detect --search-path /original 15 | 16 | # Fix up wine paths to underlying linux paths so we can run reccmp outside of wine 17 | cd /build 18 | sed -i 's/Z://g' reccmp-build.yml 19 | 20 | if [ "$#" -gt 0 ]; then 21 | exec "$@" 22 | fi 23 | 24 | 25 | # Unlock directories 26 | #chmod -R 777 source build 27 | -------------------------------------------------------------------------------- /src/DETHRACE/common/drfile.h: -------------------------------------------------------------------------------- 1 | #ifndef _DRFILE_H_ 2 | #define _DRFILE_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern br_filesystem gFilesystem; 7 | extern br_filesystem* gOld_file_system; 8 | 9 | void* DRStdioOpenRead(char* name, br_size_t n_magics, br_mode_test_cbfn* identify, int* mode_result); 10 | 11 | void* DRStdioOpenWrite(char* name, int mode); 12 | 13 | void DRStdioClose(void* f); 14 | 15 | br_size_t DRStdioRead(void* buf, br_size_t size, unsigned int n, void* f); 16 | 17 | br_size_t DRStdioWrite(void* buf, br_size_t size, unsigned int n, void* f); 18 | 19 | void InstallDRFileCalls(void); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/DETHRACE/pc-win95/ssdx.h: -------------------------------------------------------------------------------- 1 | #ifndef SSDX_H 2 | #define SSDX_H 3 | 4 | #include "harness/win95_polyfill.h" 5 | 6 | // All we know about these functions are two names - "SSDXStart" and "SSDXLockAttachedSurface". 7 | // SSDX stands for Stainless Software Direct X ? 8 | 9 | int SSDXStart(void* hWnd, int windowed, int flags); 10 | int SSDXInitDirectDraw(int width, int height, int* row_bytes); 11 | void SSDXRelease(void); 12 | void SSDXLockAttachedSurface(void); 13 | void SSDXGetWindowRect(void* hWnd); 14 | void SSDXHandleError(int error); 15 | 16 | void SSDXSetPaleeteEntries(PALETTEENTRY_* palette, int pFirst_color, int pCount); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/smackw32/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(smackw32 STATIC) 2 | 3 | target_include_directories(smackw32 4 | PUBLIC 5 | include 6 | PRIVATE 7 | ${CMAKE_SOURCE_DIR} 8 | ) 9 | 10 | target_link_libraries(smackw32 PRIVATE harness brender libsmacker compile_with_werror) 11 | 12 | if(NOT MSVC) 13 | add_compile_flags_if_supported(smackw32 14 | -Wstrict-prototypes 15 | ) 16 | else() 17 | target_compile_definitions(smackw32 PRIVATE -D_CRT_SECURE_NO_WARNINGS) 18 | target_compile_options(smackw32 PRIVATE 19 | /wd4101 20 | /wd4996 21 | ) 22 | endif() 23 | 24 | target_sources(smackw32 PRIVATE 25 | smackw32.c 26 | ) 27 | -------------------------------------------------------------------------------- /src/S3/s3sound.h: -------------------------------------------------------------------------------- 1 | #ifndef S3_SOUND2_H 2 | #define S3_SOUND2_H 3 | 4 | #include "s3_defs.h" 5 | 6 | extern int gS3_sample_filter_funcs_registered; 7 | extern tS3_sample_filter* gS3_sample_filter_func; 8 | extern tS3_sample_filter* gS3_sample_filter_disable_func; 9 | 10 | int S3LoadSample(tS3_sound_id id); 11 | void* S3LoadWavFile_DOS(char* pFile_name); 12 | void* S3LoadWavFile_Win95(char* pFile_name, tS3_sample* pSample); 13 | int S3PlaySample(tS3_channel* chan); 14 | int S3CreateTypeStructs(tS3_channel* chan); 15 | int S3ReleaseTypeStructs(tS3_channel* chan); 16 | int S3StopSample(tS3_channel* chan); 17 | int S3ExecuteSampleFilterFuncs(tS3_channel* chan); 18 | int S3SyncSampleVolumeAndPan(tS3_channel* chan); 19 | int S3SyncSampleRate(tS3_channel* chan); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /tools/watcom-codegen/split-dump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ####################################################### 4 | # Splits a Watcom "exedump" output file into a separate 5 | # file per module for easier debugging. 6 | # exedump: https://github.com/jeff-1amstudios/open-watcom-v2/tree/master/bld/exedump 7 | # 8 | # Writes per module files into "./_generated_dump" directory 9 | # 10 | # Usage: split_dump.sh 11 | ####################################################### 12 | 13 | FILE=$1 14 | SECTION=-1 15 | 16 | mkdir -p _generated_dump 17 | 18 | while IFS= read -r line 19 | do 20 | if [[ "$line" == *") Name: "* ]]; then 21 | (( SECTION++ )) 22 | fi 23 | if [ ${SECTION} -gt -1 ]; then 24 | echo "$line" >> "_generated_dump/${SECTION}_dump.txt" 25 | fi 26 | done <$FILE 27 | -------------------------------------------------------------------------------- /src/S3/s3music.c: -------------------------------------------------------------------------------- 1 | #include "s3music.h" 2 | #include "harness/trace.h" 3 | 4 | int gS3_midi_enabled; 5 | 6 | void S3DisableMIDI(void) { 7 | S3StopMIDIOutlets(); 8 | gS3_midi_enabled = 0; 9 | } 10 | 11 | void S3StopMIDIOutlets(void) { 12 | } 13 | 14 | void S3ReleaseMIDI(tS3_sound_tag tag) { 15 | } 16 | 17 | int S3PlayMIDI(tS3_channel* chan) { 18 | return 0; 19 | } 20 | int S3MIDILoadSong(tS3_channel* chan) { 21 | return 0; 22 | } 23 | int S3SetMIDIVolume(tS3_channel* chan) { 24 | return 0; 25 | } 26 | 27 | int S3StopMIDI(tS3_channel* chan) { 28 | // if (gS3_midi_enabled && chan->active && chan->type == 1) { 29 | // S3SendMCICloseCommand(chan); 30 | // chan->active = 0; 31 | // } 32 | return 0; 33 | } 34 | 35 | int S3IsMIDIStopped(tS3_channel* chan) { 36 | return 1; 37 | } 38 | -------------------------------------------------------------------------------- /src/DETHRACE/common/cutscene.h: -------------------------------------------------------------------------------- 1 | #ifndef _CUTSCENE_H_ 2 | #define _CUTSCENE_H_ 3 | 4 | #include "brender.h" 5 | 6 | #include "dr_types.h" 7 | 8 | extern tS32 gLast_demo_end_anim; 9 | 10 | void ShowCutScene(int pIndex, int pWait_end, int pSound_ID, br_scalar pDelay); 11 | 12 | void DoSCILogo(void); 13 | 14 | void DoStainlessLogo(void); 15 | 16 | void PlaySmackerFile(char* pSmack_name); 17 | 18 | void DoOpeningAnimation(void); 19 | 20 | void DoNewGameAnimation(void); 21 | 22 | void DoGoToRaceAnimation(void); 23 | 24 | void DoEndRaceAnimation(void); 25 | 26 | void DoGameOverAnimation(void); 27 | 28 | void DoGameCompletedAnimation(void); 29 | 30 | void DoFeatureUnavailableInDemo(void); 31 | 32 | void DoFullVersionPowerpoint(void); 33 | 34 | void DoDemoGoodbye(void); 35 | 36 | void StartLoadingScreen(void); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/DETHRACE/common/errors.h: -------------------------------------------------------------------------------- 1 | #ifndef _ERRORS_H_ 2 | #define _ERRORS_H_ 3 | 4 | #include "dr_types.h" 5 | #include "harness/compiler.h" 6 | 7 | extern char* gError_messages[126]; 8 | extern int gError_code; 9 | extern char* gPalette_copy__errors; // suffix added to avoid duplicate symbol 10 | extern int gPixel_buffer_size__errors; // suffix added to avoid duplicate symbol 11 | extern int gMouse_was_started__errors; // suffix added to avoid duplicate symbol 12 | extern char* gPixels_copy__errors; // suffix added to avoid duplicate symbol 13 | 14 | void FatalError(int pStr_index, ...); 15 | 16 | void NonFatalError(int pStr_index, ...); 17 | 18 | void CloseDiagnostics(void); 19 | 20 | void OpenDiagnostics(void); 21 | 22 | void dr_dprintf(char* fmt_string, ...); 23 | 24 | int DoErrorInterface(int pMisc_text_index); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /test/DETHRACE/test_input.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | 3 | #include "common/globvars.h" 4 | #include "common/input.h" 5 | #include "harness/hooks.h" 6 | #include 7 | 8 | void test_input_KevKeyService() { 9 | int i; 10 | char* input = "iwanttofiddle"; 11 | tU32* result; 12 | for (i = 0; i < strlen(input); i++) { 13 | gKeys_pressed = input[i] - 75; 14 | result = KevKeyService(); 15 | gKeys_pressed = 0; 16 | result = KevKeyService(); 17 | } 18 | gHarness_platform.Sleep(2000); 19 | gKeys_pressed = 0; 20 | result = KevKeyService(); 21 | 22 | TEST_ASSERT_EQUAL_UINT32(0x33f75455, result[0]); 23 | TEST_ASSERT_EQUAL_UINT32(0xc10aaaf2, result[1]); 24 | } 25 | 26 | void test_input_suite() { 27 | UnitySetTestFile(__FILE__); 28 | RUN_TEST(test_input_KevKeyService); 29 | } 30 | -------------------------------------------------------------------------------- /lib/libsmacker/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") 4 | 5 | if(NOT DEFINED CMAKE_BUILD_TYPE) 6 | set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo" FORCE) 7 | endif() 8 | 9 | project(libsmacker C) 10 | 11 | add_library(libsmacker STATIC) 12 | 13 | target_include_directories(libsmacker 14 | SYSTEM PUBLIC 15 | . 16 | ) 17 | 18 | if(NOT MSVC) 19 | target_compile_options(libsmacker PRIVATE -Wall) 20 | else() 21 | target_compile_definitions(libsmacker PRIVATE -D_CRT_SECURE_NO_WARNINGS) 22 | endif() 23 | 24 | target_sources(libsmacker PRIVATE 25 | smacker.c 26 | smk_bitstream.c 27 | smk_hufftree.c 28 | smacker.h 29 | smk_bitstream.h 30 | smk_hufftree.h 31 | smk_malloc.h 32 | ) 33 | -------------------------------------------------------------------------------- /src/DETHRACE/common/drmem.h: -------------------------------------------------------------------------------- 1 | #ifndef _DRMEM_H_ 2 | #define _DRMEM_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern br_allocator gAllocator; 7 | extern int gNon_fatal_allocation_errors; 8 | extern char* gMem_names[246]; 9 | extern br_resource_class gStainless_classes[117]; 10 | 11 | void SetNonFatalAllocationErrors(void); 12 | 13 | void ResetNonFatalAllocationErrors(void); 14 | 15 | int AllocationErrorsAreFatal(void); 16 | 17 | void MAMSInitMem(void); 18 | 19 | void PrintMemoryDump(int pFlags, char* pTitle); 20 | 21 | void* DRStdlibAllocate(br_size_t size, br_uint_8 type); 22 | 23 | void DRStdlibFree(void* mem); 24 | 25 | br_size_t DRStdlibInquire(br_uint_8 type); 26 | 27 | br_uint_32 Claim4ByteAlignment(br_uint_8 type); 28 | 29 | void InstallDRMemCalls(void); 30 | 31 | void MAMSUnlock(void** pPtr); 32 | 33 | void MAMSLock(void** pPtr); 34 | 35 | void CreateStainlessClasses(void); 36 | 37 | void CheckMemory(void); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/DETHRACE/common/globvrpb.h: -------------------------------------------------------------------------------- 1 | #ifndef _GLOBVRPB_H_ 2 | #define _GLOBVRPB_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern tNet_mode gNet_mode; 7 | extern tNet_game_player_info gNet_players[6]; 8 | extern br_matrix34 gRoot_to_camera; 9 | extern tCar_detail_info gCar_details[60]; 10 | extern int gThis_net_player_index; 11 | extern br_scalar gPedestrian_distance_squared; 12 | extern int gPending_race; 13 | extern tPlayer_ID gLocal_net_ID; 14 | extern int gNumber_of_net_players; 15 | extern int gStart_race_sent; 16 | extern int gSynch_race_start; 17 | extern tNet_game_details* gCurrent_net_game; 18 | extern int gReceived_car_details; 19 | extern int gWaiting_for_unpause; 20 | extern tNet_game_options* gNet_options; 21 | extern br_vector3 gCamera_direction; 22 | extern int gNetwork_available; 23 | extern int gPedestrian_image; 24 | extern int gHighest_pedestrian_value; 25 | extern int gNeed_to_send_start_race; 26 | extern int gRendering_mirror; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/DETHRACE/common/intrface.h: -------------------------------------------------------------------------------- 1 | #ifndef _INTRFACE_H_ 2 | #define _INTRFACE_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern int gDisabled_choices[10]; 7 | extern int gCurrent_mode; 8 | extern tU32 gStart_time; 9 | extern int gCurrent_choice; 10 | extern tInterface_spec* gSpec; 11 | extern int gAlways_typing; 12 | extern int gDisabled_count; 13 | 14 | void SetAlwaysTyping(void); 15 | 16 | void ClearAlwaysTyping(void); 17 | 18 | int ChoiceDisabled(int pChoice); 19 | 20 | void ResetInterfaceTimeout(void); 21 | 22 | void ChangeSelection(tInterface_spec* pSpec, int* pOld_selection, int* pNew_selection, int pMode, int pSkip_disabled); 23 | 24 | void RecopyAreas(tInterface_spec* pSpec, br_pixelmap** pCopy_areas); 25 | 26 | void DisableChoice(int pChoice); 27 | 28 | void EnableChoice(int pChoice); 29 | 30 | int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice); 31 | 32 | void ChangeSelectionTo(int pNew_choice, int pNew_mode); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/harness/harness_trace.c: -------------------------------------------------------------------------------- 1 | #include "harness/trace.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int harness_debug_level = 4; 9 | 10 | void debug_printf(const char* fmt, const char* fn, const char* fmt2, ...) { 11 | va_list ap; 12 | 13 | printf(fmt, fn); 14 | 15 | va_start(ap, fmt2); 16 | vprintf(fmt2, ap); 17 | va_end(ap); 18 | 19 | puts("\033[0m"); 20 | } 21 | 22 | void panic_printf(const char* fmt, const char* fn, const char* fmt2, ...) { 23 | va_list ap; 24 | 25 | FILE* fp = fopen("dethrace.log", "w"); 26 | 27 | puts("\033[0;31m"); 28 | printf(fmt, fn); 29 | 30 | if (fp != NULL) { 31 | fprintf(fp, fmt, fn); 32 | } 33 | 34 | va_start(ap, fmt2); 35 | vprintf(fmt2, ap); 36 | if (fp != NULL) { 37 | vfprintf(fp, fmt2, ap); 38 | } 39 | va_end(ap); 40 | if (fp != NULL) { 41 | fclose(fp); 42 | } 43 | puts("\033[0m"); 44 | } 45 | -------------------------------------------------------------------------------- /src/DETHRACE/common/globvrkm.c: -------------------------------------------------------------------------------- 1 | #include "globvrkm.h" 2 | #include "globvars.h" 3 | #include 4 | 5 | // GLOBAL: CARM95 0x0050d380 6 | br_scalar gCamera_zoom = 0.2f; 7 | 8 | // GLOBAL: CARM95 0x0050d384 9 | br_angle gCamera_yaw; 10 | 11 | // GLOBAL: CARM95 0x0050d388 12 | br_vector3 gView_direction = { { 0.0, 0.0, -1.0 } }; 13 | 14 | // GLOBAL: CARM95 0x0050d394 15 | int gCamera_sign; 16 | 17 | // GLOBAL: CARM95 0x0050d398 18 | int gCar_flying; 19 | 20 | // GLOBAL: CARM95 0x0050d39c 21 | int gCamera_reset; 22 | 23 | // GLOBAL: CARM95 0x0050d3a0 24 | tCar_spec* gCar_to_view = &gProgram_state.current_car; 25 | 26 | // GLOBAL: CARM95 0x00551438 27 | br_actor* gCamera_list[2]; 28 | 29 | // GLOBAL: CARM95 0x00551450 30 | tCar_spec* gActive_car_list[25]; 31 | 32 | // GLOBAL: CARM95 0x005514cc 33 | int gNum_active_cars; 34 | 35 | // GLOBAL: CARM95 0x005514c0 36 | float gRecovery_cost[3]; 37 | 38 | // GLOBAL: CARM95 0x005514d0 39 | br_scalar gCamera_height; 40 | 41 | // GLOBAL: CARM95 0x00551440 42 | br_scalar gMin_camera_car_distance; 43 | -------------------------------------------------------------------------------- /src/DETHRACE/common/skidmark.h: -------------------------------------------------------------------------------- 1 | #ifndef _SKIDMARK_H_ 2 | #define _SKIDMARK_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern tSkid gSkids[100]; 7 | extern char* gBoring_material_names[2]; 8 | extern char* gMaterial_names[2]; 9 | 10 | void StretchMark(tSkid* pMark, br_vector3* pFrom, br_vector3* pTo, br_scalar pTexture_start); 11 | 12 | br_material* MaterialFromIndex(int pIndex); 13 | 14 | void AdjustSkid(int pSkid_num, br_matrix34* pMatrix, int pMaterial_index); 15 | 16 | int FarFromLine2D(br_vector3* pPt, br_vector3* pL1, br_vector3* pL2); 17 | 18 | int Reflex2D(br_vector3* pPt, br_vector3* pL1, br_vector3* pL2); 19 | 20 | void InitSkids(void); 21 | 22 | void HideSkid(int pSkid_num); 23 | 24 | void HideSkids(void); 25 | 26 | br_scalar SkidLen(int pSkid); 27 | 28 | void SkidSection(tCar_spec* pCar, int pWheel_num, br_vector3* pPos, int pMaterial_index); 29 | 30 | void SkidMark(tCar_spec* pCar, int pWheel_num); 31 | 32 | void InitCarSkidStuff(tCar_spec* pCar); 33 | 34 | void SkidsPerFrame(void); 35 | 36 | void RemoveMaterialsFromSkidmarks(void); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /NOTES.md: -------------------------------------------------------------------------------- 1 | # Unused functions 2 | 3 | ### ToggleControls 4 | Appears to have been a way to change the steering handling? "Original Controls", "Accelerated steering", "0.75 Accelerated", "0.5 Accelerated", "New controls". The game is hardcoded to use "0.5 Accelerated" and this function is not called from anywhere. 5 | 6 | ### DrawSomeText / DrawSomeText2 7 | Not accessible in the retail game, but the functions still exists. Can be invoked in a very early demo build. For each of 7 fonts, it prints 15 lines of dummy text and saves a screenshot each time. 8 | 9 | ### ToggleArrow 10 | Does a `return` at the top of the function in the retail game. Appears to have been used for debugging. Replaces the current car model with an arrow(?). Also enables debug output showing the car location and stats. 11 | 12 | ### SetFlag2 / ToggleFlying 13 | TBA 14 | 15 | ### DoDemo 16 | Reads `DEMOFILE.TXT` which lists a number of `.CNT` files. Each `.CNT` file appears to contain a number of full-screen background images which are displayed as a slideshow. Sound ID `10000` is played during the slideshow. 17 | -------------------------------------------------------------------------------- /src/S3/3d.h: -------------------------------------------------------------------------------- 1 | #ifndef _3D_H_ 2 | #define _3D_H_ 3 | 4 | #include "brender.h" 5 | #include "s3_defs.h" 6 | 7 | void S3Set3DSoundEnvironment(float a1, float a2, float a3); 8 | 9 | void S3UpdateListenerVectors(void); 10 | void S3ServiceAmbientSoundSources(void); 11 | int S3UpdateSpatialSound(tS3_channel* chan); 12 | int S3BindAmbientSoundToOutlet(tS3_outlet* pOutlet, int pSound, tS3_sound_source* source, float pMax_distance, int pPeriod, int pRepeats, int pVolume, int pPitch, int pSpeed); 13 | void S3UpdateSoundSource(tS3_outlet* outlet, tS3_sound_tag tag, tS3_sound_source* src, float pMax_distance_squared, int pPeriod, tS3_repeats pAmbient_repeats, tS3_volume pVolume, int pPitch, tS3_speed pSpeed); 14 | void S3StopSoundSource(tS3_sound_source* src); 15 | 16 | tS3_sound_tag S3ServiceSoundSource(tS3_sound_source* src); 17 | 18 | int S3Calculate3D(tS3_channel* chan, int pIs_ambient); 19 | 20 | void S3CopyVector3(void* a1, void* a2, int pBrender_vector); 21 | void S3CopyBrVector3(tS3_vector3* a1, br_vector3* a2); 22 | void S3CopyS3Vector3(tS3_vector3* a1, tS3_vector3* a2); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/DETHRACE/common/oppoproc.h: -------------------------------------------------------------------------------- 1 | #ifndef _OPPOPROC_H_ 2 | #define _OPPOPROC_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | int StraightestArcForCorner2D(br_vector2* pCent, br_scalar* pRadius, br_scalar* pEntry_length, int* pLeft_not_right, br_vector2* p1, br_vector2* p2, br_vector2* p3, br_scalar pWidth12, br_scalar pWidth23); 7 | 8 | br_scalar CornerFudge(tCar_spec* pCar_spec); 9 | 10 | br_scalar MaxCurvatureForCarSpeed(tCar_spec* pCar, br_scalar pSpeed); 11 | 12 | br_scalar Vector2Cross(br_vector2* pA, br_vector2* pB); 13 | 14 | tFollow_path_result EndOfPath(tOpponent_spec* pOpponent_spec); 15 | 16 | int RoughlyColinear(br_vector2* p1, br_vector2* p2, br_vector2* p3); 17 | 18 | int GetStraight(br_vector2* pStart, br_vector2* pFinish, br_scalar* pWidth, int section1, tOpponent_spec* pOpponent_spec, tFollow_path_data* data); 19 | 20 | tFollow_path_result ProcessFollowPath(tOpponent_spec* pOpponent_spec, tProcess_objective_command pCommand, int pPursuit_mode, int pIgnore_end, int pNever_struggle); 21 | 22 | tFollow_path_result FollowCheatyPath(tOpponent_spec* pOpponent_spec); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /test/DETHRACE/test_controls.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "tests.h" 6 | 7 | #include "common/controls.h" 8 | #include "common/errors.h" 9 | #include "common/globvars.h" 10 | #include "common/input.h" 11 | #include "common/loading.h" 12 | #include "common/utility.h" 13 | #include "harness/hooks.h" 14 | 15 | extern int _unittest_controls_lastGetPowerup; 16 | 17 | void test_controls_CheckKevKeys() { 18 | int i; 19 | char* input = "spamfritters"; 20 | tU32* result; 21 | for (i = 0; i < strlen(input); i++) { 22 | gKeys_pressed = input[i] - 75; // 0x1e; 23 | result = KevKeyService(); 24 | gKeys_pressed = 0; 25 | result = KevKeyService(); 26 | } 27 | gHarness_platform.Sleep(2000); 28 | 29 | gKeys_pressed = 0; 30 | 31 | CheckKevKeys(); 32 | 33 | // 'spamfritters' cheat code should enable powerup #8 34 | TEST_ASSERT_EQUAL_INT(8, _unittest_controls_lastGetPowerup); 35 | } 36 | 37 | void test_controls_suite() { 38 | UnitySetTestFile(__FILE__); 39 | RUN_TEST(test_controls_CheckKevKeys); 40 | } 41 | -------------------------------------------------------------------------------- /src/S3/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(s3 STATIC) 2 | 3 | target_include_directories(s3 4 | PUBLIC 5 | include 6 | ) 7 | 8 | target_link_libraries(s3 PRIVATE brender harness compile_with_werror) 9 | 10 | if(NOT MSVC) 11 | target_link_libraries(s3 PUBLIC pthread m) 12 | add_compile_flags_if_supported(s3 13 | -Wstrict-prototypes 14 | ) 15 | else() 16 | target_compile_definitions(s3 PRIVATE -D_CRT_SECURE_NO_WARNINGS) 17 | target_compile_options(s3 PRIVATE 18 | /wd4101 19 | /wd4996 20 | ) 21 | endif() 22 | if(DETHRACE_FIX_BUGS) 23 | target_compile_definitions(s3 PRIVATE DETHRACE_FIX_BUGS) 24 | endif() 25 | 26 | if(IS_BIGENDIAN) 27 | target_compile_definitions(s3 PRIVATE BR_ENDIAN_BIG=1) 28 | else() 29 | target_compile_definitions(s3 PRIVATE BR_ENDIAN_LITTLE=1) 30 | endif() 31 | 32 | target_sources(s3 PRIVATE 33 | 3d.c 34 | 3d.h 35 | s3.c 36 | s3.h 37 | ioserv.c 38 | ioserv.h 39 | profile.c 40 | profile.h 41 | resource.c 42 | resource.h 43 | s3cda.c 44 | s3cda.h 45 | s3music.c 46 | s3music.h 47 | s3sound.c 48 | s3sound.h 49 | ) 50 | -------------------------------------------------------------------------------- /test/DETHRACE/test_flicplay.c: -------------------------------------------------------------------------------- 1 | #include "brender.h" 2 | #include "common/flicplay.h" 3 | #include "common/graphics.h" 4 | #include "tests.h" 5 | 6 | int nbr_frames_rendered; 7 | 8 | void frame_render_callback() { 9 | nbr_frames_rendered++; 10 | } 11 | void test_flicplay_playflic() { 12 | REQUIRES_DATA_DIRECTORY(); 13 | int pIndex = 31; // main menu swing in 14 | br_pixelmap* target; 15 | 16 | gCurrent_palette_pixels = malloc(0x400); 17 | FlicPaletteAllocate(); 18 | TEST_ASSERT_EQUAL_INT(1, LoadFlic(pIndex)); 19 | 20 | target = BrPixelmapAllocate(BR_MEMORY_PIXELS, 320, 200, NULL, 0); 21 | PlayFlic( 22 | pIndex, 23 | gMain_flic_list[pIndex].the_size, 24 | gMain_flic_list[pIndex].data_ptr, 25 | target, 26 | gMain_flic_list[pIndex].x_offset, 27 | gMain_flic_list[pIndex].y_offset, 28 | frame_render_callback, 29 | gMain_flic_list[pIndex].interruptable, 30 | gMain_flic_list[pIndex].frame_rate); 31 | 32 | TEST_ASSERT_EQUAL_INT(3, nbr_frames_rendered); 33 | } 34 | 35 | void test_flicplay_suite() { 36 | UnitySetTestFile(__FILE__); 37 | RUN_TEST(test_flicplay_playflic); 38 | } 39 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(dethrace_test) 2 | add_test(NAME test_dethrace COMMAND dethrace_test) 3 | 4 | target_link_libraries(dethrace_test PRIVATE dethrace_obj) 5 | 6 | target_include_directories(dethrace_test PRIVATE 7 | . 8 | ${CMAKE_SOURCE_DIR}/lib 9 | ${CMAKE_SOURCE_DIR}/src/harness 10 | ${CMAKE_SOURCE_DIR}/lib/BRender-v1.3.2 11 | ${CMAKE_SOURCE_DIR}/src/DETHRACE 12 | ${CMAKE_SOURCE_DIR}/src/DETHRACE/common 13 | ${CMAKE_SOURCE_DIR}/src/DETHRACE/pd 14 | ) 15 | 16 | if(NOT MSVC) 17 | else() 18 | target_compile_definitions(dethrace_test PRIVATE -D_CRT_SECURE_NO_WARNINGS -DSDL_MAIN_HANDLED -DWIN32_LEAN_AND_MEAN) 19 | target_link_libraries(dethrace_test PRIVATE dbghelp) 20 | endif() 21 | 22 | target_sources(dethrace_test PRIVATE 23 | DETHRACE/test_controls.c 24 | DETHRACE/test_dossys.c 25 | DETHRACE/test_flicplay.c 26 | DETHRACE/test_graphics.c 27 | DETHRACE/test_init.c 28 | DETHRACE/test_input.c 29 | DETHRACE/test_loading.c 30 | DETHRACE/test_powerup.c 31 | DETHRACE/test_utility.c 32 | framework/unity.c 33 | framework/unity.h 34 | framework/unity_internals.h 35 | framework 36 | main.c 37 | tests.h 38 | ) 39 | -------------------------------------------------------------------------------- /src/harness/os/null.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void OS_InstallSignalHandler(char* program_name) { 5 | } 6 | 7 | char* OS_GetFirstFileInDirectory(char* path) { 8 | return NULL; 9 | } 10 | 11 | // Required: continue directory iteration. If no more files, return NULL 12 | char* OS_GetNextFileInDirectory(void) { 13 | return NULL; 14 | } 15 | 16 | FILE* OS_fopen(const char* pathname, const char* mode) { 17 | return NULL; 18 | } 19 | 20 | size_t OS_ConsoleReadPassword(char* pBuffer, size_t pBufferLen) { 21 | return 0; 22 | } 23 | 24 | char* OS_Dirname(const char* path) { 25 | return NULL; 26 | } 27 | 28 | char* OS_Basename(const char* path) { 29 | return NULL; 30 | } 31 | 32 | char* OS_GetWorkingDirectory(char* argv0) { 33 | return NULL; 34 | } 35 | 36 | int OS_GetAdapterAddress(char* name, void* pSockaddr_in) { 37 | return 0; 38 | } 39 | 40 | int OS_InitSockets(void) { 41 | return 0; 42 | } 43 | 44 | int OS_GetLastSocketError(void) { 45 | return 0; 46 | } 47 | 48 | void OS_CleanupSockets(void) { 49 | } 50 | 51 | int OS_SetSocketNonBlocking(int socket) { 52 | return 0; 53 | } 54 | 55 | int OS_CloseSocket(int socket) { 56 | return 1; 57 | } 58 | -------------------------------------------------------------------------------- /src/DETHRACE/common/globvrbm.c: -------------------------------------------------------------------------------- 1 | #include "globvrbm.h" 2 | #include 3 | 4 | // GLOBAL: CARM95 0x00520038 5 | br_scalar gYon_factor; 6 | 7 | // GLOBAL: CARM95 0x00530c80 8 | br_material* gMaterial[2]; 9 | 10 | // These variables are all used only by the 3dfx patch 11 | int g16bit_palette_valid; 12 | tException_list gExceptions; 13 | br_actor* g2d_camera; 14 | int gAlready_copied; 15 | br_actor* gBlend_actor; 16 | br_actor* gLine_actor; 17 | br_model* gBlend_model; 18 | br_model* gPrat_model; 19 | char* gExceptions_general_file; 20 | br_model* gDim_model; 21 | br_material* gPrat_material; 22 | br_material* gBlend_material; 23 | char* gExceptions_file_suffix; 24 | br_material* gDim_material; 25 | br_actor* gPrat_actor; 26 | br_material* gLine_material; 27 | br_model* gLine_model; 28 | br_actor* gDim_actor; 29 | int gNo_transients; 30 | int gSmall_frames_are_slow; 31 | int gShade_tables_do_not_work; 32 | int gInterpolate_textures; 33 | int gNo_2d_effects; 34 | int gPerspective_is_fast; 35 | int gUse_mip_maps; 36 | int gBlitting_is_slow; 37 | int gTextures_need_powers_of_2; 38 | int gMax_texture_side; 39 | int gDevious_2d; 40 | int gMax_texture_aspect_ratio; 41 | int gMaterial_fogging; 42 | 43 | // Added 44 | int gVoodoo_rush_mode; 45 | -------------------------------------------------------------------------------- /src/DETHRACE/common/loadsave.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOADSAVE_H_ 2 | #define _LOADSAVE_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern tSave_game* gSaved_games[8]; 7 | extern int gStarted_typing; 8 | extern int gSave_allowed; 9 | 10 | void CorrectLoadByteOrdering(int pIndex); 11 | 12 | tU32 CalcLSChecksum(tSave_game* pSaved_game); 13 | 14 | void LoadSavedGames(void); 15 | 16 | void DisposeSavedGames(void); 17 | 18 | void LoadTheGame(int pSlot_index); 19 | 20 | void StartRollingSaveNamesIn(void); 21 | 22 | void LoadStart(void); 23 | 24 | int DoLoadGame(void); 25 | 26 | void CorrectSaveByteOrdering(int pIndex); 27 | 28 | void SaveTheGame(int pSlot_number); 29 | 30 | int ConfirmMidGameSave(void); 31 | 32 | void MakeSavedGame(tSave_game** pSave_record); 33 | 34 | void SaveStart(void); 35 | 36 | void GetSaveName(int pStarting_to_type, int pCurrent_choice, char* pString, int* pMax_length); 37 | 38 | int SaveDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out); 39 | 40 | int SaveGoAhead(int* pCurrent_choice, int* pCurrent_mode); 41 | 42 | int SaveEscape(int* pCurrent_choice, int* pCurrent_mode); 43 | 44 | int SaveGameInterface(int pDefault_choice); 45 | 46 | void DoSaveGame(int pSave_allowed); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/DETHRACE/common/mainloop.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAINLOOP_H_ 2 | #define _MAINLOOP_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern int gNasty_kludgey_cockpit_variable; 7 | extern tInfo_mode gInfo_mode; 8 | extern tU32 gLast_tick_count; 9 | extern tU32 gActual_last_tick_count; 10 | extern tU32 gAverage_frame_period; 11 | extern tU32 gOld_camera_time; 12 | extern tU32 gLast_wasted_massage_start; 13 | extern float gMr_odo; 14 | extern tU32 gWasted_last_flash; 15 | extern tTime_bonus_state gTime_bonus_state; 16 | extern int gQueued_wasted_massages_count; 17 | extern int gTime_bonus; 18 | extern int gRace_bonus_headup; 19 | extern int gWasted_flash_state; 20 | extern int gLast_time_headup; 21 | extern int gTime_bonus_headup; 22 | extern int gQueued_wasted_massages[5]; 23 | extern tU32 gTime_bonus_start; 24 | extern int gLast_credit_headup__mainloop; // suffix added to avoid duplicate symbol 25 | 26 | void ToggleInfo(void); 27 | 28 | void CalculateFrameRate(void); 29 | 30 | void LoseOldestWastedMassage(void); 31 | 32 | void QueueWastedMassage(int pIndex); 33 | 34 | void MungeHeadups(void); 35 | 36 | void UpdateFramePeriod(tU32* pCamera_period); 37 | 38 | tU32 GetLastTickCount(void); 39 | 40 | void CheckTimer(void); 41 | 42 | int MungeRaceFinished(void); 43 | 44 | tRace_result MainGameLoop(void); 45 | 46 | tRace_result DoRace(void); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/harness/include/harness/os.h: -------------------------------------------------------------------------------- 1 | #ifndef HARNESS_OS_H 2 | #define HARNESS_OS_H 3 | 4 | #include 5 | 6 | #if defined(_WIN32) || defined(_WIN64) 7 | #include 8 | #include 9 | #define getcwd _getcwd 10 | #define chdir _chdir 11 | #define access _access 12 | #define F_OK 0 13 | #define strcasecmp _stricmp 14 | #define strncasecmp _strnicmp 15 | 16 | #if _MSC_VER < 1900 17 | #define snprintf _snprintf 18 | #define vsnprintf _vsnprintf 19 | #endif 20 | 21 | #else 22 | #include 23 | #endif 24 | 25 | // Optional: install a handler to print stack trace during a crash 26 | void OS_InstallSignalHandler(char* program_name); 27 | 28 | char* OS_GetFirstFileInDirectory(char* path); 29 | 30 | char* OS_GetNextFileInDirectory(void); 31 | 32 | FILE* OS_fopen(const char* pathname, const char* mode); 33 | 34 | size_t OS_ConsoleReadPassword(char* pBuffer, size_t pBufferLen); 35 | 36 | char* OS_Dirname(const char* path); 37 | 38 | char* OS_Basename(const char* path); 39 | 40 | char* OS_GetWorkingDirectory(char* argv0); 41 | 42 | int OS_GetAdapterAddress(char* name, void* pSockaddr_in); 43 | 44 | int OS_InitSockets(void); 45 | 46 | void OS_CleanupSockets(void); 47 | 48 | int OS_GetLastSocketError(void); 49 | 50 | int OS_SetSocketNonBlocking(int socket); 51 | 52 | int OS_CloseSocket(int socket); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/DETHRACE/common/mainmenu.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAINMENU_H_ 2 | #define _MAINMENU_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern char* gPalette_copy__mainmenu; // suffix added to avoid duplicate symbol 7 | extern int gPixel_buffer_size__mainmenu; // suffix added to avoid duplicate symbol 8 | extern tInterface_spec* gMain_menu_spec; 9 | extern int gMouse_was_started__mainmenu; // suffix added to avoid duplicate symbol 10 | extern int gReplace_background; 11 | extern char* gPixels_copy__mainmenu; // suffix added to avoid duplicate symbol 12 | 13 | int MainMenuDone1(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out); 14 | 15 | int MainMenuDone2(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out); 16 | 17 | void StartMainMenu(void); 18 | 19 | int DoMainMenuInterface(tU32 pTime_out, int pContinue_allowed); 20 | 21 | tMM_result GetMainMenuOption(tU32 pTime_out, int pContinue_allowed); 22 | 23 | void QuitVerifyStart(void); 24 | 25 | int QuitVerifyDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out); 26 | 27 | int DoVerifyQuit(int pReplace_background); 28 | 29 | tMM_result DoMainMenu(tU32 pTime_out, int pSave_allowed, int pContinue_allowed); 30 | 31 | void DoMainMenuScreen(tU32 pTime_out, int pSave_allowed, int pContinue_allowed); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/DETHRACE/common/globvrbm.h: -------------------------------------------------------------------------------- 1 | #ifndef _GLOBVRBM_H_ 2 | #define _GLOBVRBM_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern br_scalar gYon_factor; 7 | extern br_material* gMaterial[2]; 8 | extern int g16bit_palette_valid; 9 | extern tException_list gExceptions; 10 | extern br_actor* g2d_camera; 11 | extern int gAlready_copied; 12 | extern br_actor* gBlend_actor; 13 | extern br_actor* gLine_actor; 14 | extern br_model* gBlend_model; 15 | extern br_model* gPrat_model; 16 | extern char* gExceptions_general_file; 17 | extern br_model* gDim_model; 18 | extern br_material* gPrat_material; 19 | extern br_material* gBlend_material; 20 | extern char* gExceptions_file_suffix; 21 | extern br_material* gDim_material; 22 | extern br_actor* gPrat_actor; 23 | extern br_material* gLine_material; 24 | extern br_model* gLine_model; 25 | extern br_actor* gDim_actor; 26 | extern int gNo_transients; 27 | extern int gSmall_frames_are_slow; 28 | extern int gShade_tables_do_not_work; 29 | extern int gInterpolate_textures; 30 | extern int gNo_2d_effects; 31 | extern int gPerspective_is_fast; 32 | extern int gUse_mip_maps; 33 | extern int gBlitting_is_slow; 34 | extern int gTextures_need_powers_of_2; 35 | extern int gMax_texture_side; 36 | extern int gDevious_2d; 37 | extern int gMax_texture_aspect_ratio; 38 | extern int gMaterial_fogging; 39 | 40 | extern int gVoodoo_rush_mode; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/DETHRACE/pc-all/net_types.h: -------------------------------------------------------------------------------- 1 | #ifndef PC_ALL_NET_TYPES_H 2 | #define PC_ALL_NET_TYPES_H 3 | 4 | #include 5 | 6 | #if _MSC_VER == 1020 7 | typedef struct sockaddr_ipx { 8 | short sa_family; // AF_IPX = 6 9 | char sa_netnum[4]; // network number 10 | char sa_nodenum[6]; // node number (MAC addr) 11 | unsigned short sa_socket; // socket number 12 | } SOCKADDR_IPX, *PSOCKADDR_IPX; 13 | #endif 14 | 15 | // This file added dethrace 16 | // - have switched out IPX implementation for IP 17 | // - cross-platform instead of per-platform implementation 18 | // cannot be a regular sockaddr_in because it is transmitted between OS's 19 | typedef struct tCopyable_sockaddr_in { 20 | #if _MSC_VER == 1020 21 | SOCKADDR_IPX addr_ipx; 22 | #else 23 | uint64_t address; 24 | uint32_t port; 25 | #endif 26 | 27 | } tCopyable_sockaddr_in; 28 | 29 | typedef struct tPD_net_player_info { 30 | // cannot be a regular sockaddr_in because it is transmitted between OS's 31 | tCopyable_sockaddr_in addr_in; 32 | 33 | } tPD_net_player_info; 34 | 35 | // has to match `tPD_net_player_info` - see `PDNetGetNextJoinGame` 36 | typedef struct tPD_net_game_info { 37 | // cannot be a regular sockaddr_in because it is transmitted between OS's 38 | tCopyable_sockaddr_in addr_in; 39 | 40 | unsigned int last_response; 41 | } tPD_net_game_info; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/DETHRACE/common/globvrpb.c: -------------------------------------------------------------------------------- 1 | #include "globvrpb.h" 2 | #include 3 | 4 | // GLOBAL: CARM95 0x0050dd94 5 | tNet_mode gNet_mode; 6 | 7 | // GLOBAL: CARM95 0x00550fa0 8 | tNet_game_player_info gNet_players[6]; 9 | 10 | br_matrix34 gRoot_to_camera; 11 | 12 | // GLOBAL: CARM95 0x00550af0 13 | tCar_detail_info gCar_details[60]; 14 | 15 | // GLOBAL: CARM95 0x00550ae0 16 | int gThis_net_player_index; 17 | 18 | br_scalar gPedestrian_distance_squared; 19 | 20 | // GLOBAL: CARM95 0x00551434 21 | int gPending_race; 22 | 23 | // GLOBAL: CARM95 0x00550aec 24 | tPlayer_ID gLocal_net_ID; 25 | 26 | // GLOBAL: CARM95 0x00550ae4 27 | int gNumber_of_net_players; 28 | 29 | // GLOBAL: CARM95 0x00550ad8 30 | int gStart_race_sent; 31 | 32 | // GLOBAL: CARM95 0x00551424 33 | int gSynch_race_start; 34 | 35 | // GLOBAL: CARM95 0x00550adc 36 | tNet_game_details* gCurrent_net_game; 37 | 38 | // GLOBAL: CARM95 0x00550ad4 39 | int gReceived_car_details; 40 | 41 | // GLOBAL: CARM95 0x00550ae8 42 | int gWaiting_for_unpause; 43 | 44 | // GLOBAL: CARM95 0x00551428 45 | tNet_game_options* gNet_options; 46 | 47 | // GLOBAL: CARM95 0x00550ac0 48 | br_vector3 gCamera_direction; 49 | 50 | int gNetwork_available; 51 | 52 | int gPedestrian_image; 53 | 54 | int gHighest_pedestrian_value; 55 | 56 | // GLOBAL: CARM95 0x00551430 57 | int gNeed_to_send_start_race; 58 | 59 | // GLOBAL: CARM95 0x00550ad0 60 | int gRendering_mirror; 61 | -------------------------------------------------------------------------------- /test/tests.h: -------------------------------------------------------------------------------- 1 | #ifndef TESTS_H 2 | #define TESTS_H 3 | 4 | #include "framework/unity.h" 5 | #include "harness/os.h" 6 | #include "harness/trace.h" 7 | 8 | #ifndef PATH_MAX 9 | #define PATH_MAX 300 10 | #endif 11 | 12 | #ifdef _WIN32 13 | #define HOST_NL "\r\n" 14 | #include 15 | #else 16 | #define HOST_NL "\n" 17 | #endif 18 | 19 | void TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(const uint8_t* expected, char* filename, int len); 20 | void TEST_ASSERT_EQUAL_FILE_TEXT(const char* expected, char* filename); 21 | 22 | extern int has_data_directory(); 23 | void create_temp_file(char buffer[PATH_MAX + 1], const char* prefix); 24 | 25 | #define REQUIRES_DATA_DIRECTORY() \ 26 | if (!has_data_directory()) \ 27 | TEST_IGNORE(); 28 | 29 | #define TEST_ASSERT_FLOAT_ARRAY_WITHIN(delta, expected, actual, num_elements) \ 30 | do { \ 31 | float* priv_expected = (float*)(expected); \ 32 | float* priv_actual = (float*)(actual); \ 33 | for (int it = (num_elements); it != 0; --it, ++priv_expected, ++priv_actual) { \ 34 | TEST_ASSERT_FLOAT_WITHIN((delta), *priv_expected, *priv_actual); \ 35 | } \ 36 | } while (0) 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/DETHRACE/common/brucetrk.h: -------------------------------------------------------------------------------- 1 | #ifndef _BRUCETRK_H_ 2 | #define _BRUCETRK_H_ 3 | 4 | #include "brender.h" 5 | #include "dr_types.h" 6 | 7 | extern br_actor* gMr_blendy; 8 | extern int gDefault_blend_pc; 9 | 10 | void AllocateActorMatrix(tTrack_spec* pTrack_spec, br_actor**** pDst); 11 | 12 | void DisposeActorMatrix(tTrack_spec* pTrack_spec, br_actor**** pVictim, int pRemove_act_mod); 13 | 14 | void DisposeColumns(tTrack_spec* pTrack_spec); 15 | 16 | void XZToColumnXZ(tU8* pColumn_x, tU8* pColumn_z, br_scalar pX, br_scalar pZ, tTrack_spec* pTrack_spec); 17 | 18 | void StripBlendedFaces(br_actor* pActor, br_model* pModel); 19 | 20 | /*br_uint_32*/ br_uintptr_t FindNonCarsCB(br_actor* pActor, tTrack_spec* pTrack_spec); 21 | 22 | /*br_uint_32*/ br_uintptr_t ProcessModelsCB(br_actor* pActor, tTrack_spec* pTrack_spec); 23 | 24 | void ProcessModels(tTrack_spec* pTrack_spec); 25 | 26 | void ExtractColumns(tTrack_spec* pTrack_spec); 27 | 28 | void LollipopizeActor4(br_actor* pActor, br_matrix34* pRef_to_world, br_actor* pCamera); 29 | 30 | /*br_uint_32*/ br_uintptr_t LollipopizeChildren(br_actor* pActor, void* pArg); 31 | 32 | void DrawColumns(int pDraw_blends, tTrack_spec* pTrack_spec, int pMin_x, int pMax_x, int pMin_z, int pMax_z, br_matrix34* pCamera_to_world); 33 | 34 | void RenderTrack(br_actor* pWorld, tTrack_spec* pTrack_spec, br_actor* pCamera, br_matrix34* pCamera_to_world, int pRender_blends); 35 | 36 | br_scalar GetYonFactor(void); 37 | 38 | void SetYonFactor(br_scalar pNew); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/DETHRACE/common/oppocar.h: -------------------------------------------------------------------------------- 1 | #ifndef _OPPOCAR_H_ 2 | #define _OPPOCAR_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern int gCollision_detection_on__oppocar; // suffix added to avoid duplicate symbol 7 | extern br_vector3 gGround_normal__oppocar; // suffix added to avoid duplicate symbol 8 | extern void (*ControlCar__oppocar[6])(tCar_spec*, br_scalar); // suffix added to avoid duplicate symbol 9 | extern int gControl__oppocar; // suffix added to avoid duplicate symbol 10 | extern int gFace_num__oppocar; // suffix added to avoid duplicate symbol 11 | extern br_angle gOld_yaw__oppocar; // suffix added to avoid duplicate symbol 12 | extern int gMetal_crunch_sound_id__oppocar[5]; // suffix added to avoid duplicate symbol 13 | extern int gMetal_scrape_sound_id__oppocar[3]; // suffix added to avoid duplicate symbol 14 | extern tFace_ref gFace_list__oppocar[32]; // suffix added to avoid duplicate symbol 15 | extern br_scalar gOur_yaw__oppocar; // suffix added to avoid duplicate symbol 16 | extern br_scalar gGravity__oppocar; // suffix added to avoid duplicate symbol 17 | extern br_vector3 gNew_ground_normal__oppocar; // suffix added to avoid duplicate symbol 18 | 19 | void MakeCarStationary(tCar_spec* pCar_spec); 20 | 21 | void MoveThisCar(tU32 pTime_difference, tCar_spec* car); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/DETHRACE/common/structur.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRUCTUR_H_ 2 | #define _STRUCTUR_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern int gLast_wrong_checkpoint; 7 | extern int gMirror_on__structur; // suffix added to avoid duplicate symbol 8 | extern int gPratcam_on; 9 | extern int gCockpit_on; 10 | extern int gOpponent_mix[10][5]; 11 | extern tU32 gLast_checkpoint_time; 12 | extern tRace_over_reason gRace_over_reason; 13 | 14 | int NumberOfOpponentsLeft(void); 15 | 16 | void RaceCompleted(tRace_over_reason pReason); 17 | 18 | void Checkpoint(int pCheckpoint_index, int pDo_sound); 19 | 20 | void IncrementCheckpoint(void); 21 | 22 | void IncrementLap(void); 23 | 24 | int RayHitFace(br_vector3* pV0, br_vector3* pV1, br_vector3* pV2, br_vector3* pNormal, br_vector3* pStart, br_vector3* pDir); 25 | 26 | void WrongCheckpoint(int pCheckpoint_index); 27 | 28 | void CheckCheckpoints(void); 29 | 30 | void TotalRepair(void); 31 | 32 | void DoLogos(void); 33 | 34 | void DoProgOpeningAnimation(void); 35 | 36 | void DoProgramDemo(void); 37 | 38 | int ChooseOpponent(int pNastiness, int* pHad_scum); 39 | 40 | void SelectOpponents(tRace_info* pRace_info); 41 | 42 | int PickNetRace(int pCurrent_race, tNet_sequence_type pNet_race_sequence); 43 | 44 | void SwapNetCarsLoad(void); 45 | 46 | void SwapNetCarsDispose(void); 47 | 48 | void DoGame(void); 49 | 50 | void InitialiseProgramState(void); 51 | 52 | void DoProgram(void); 53 | 54 | void JumpTheStart(void); 55 | 56 | void GoingToInterfaceFromRace(void); 57 | 58 | void GoingBackToRaceFromInterface(void); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /cmake/GetGitRevisionDescription.cmake.in: -------------------------------------------------------------------------------- 1 | # 2 | # Internal file for GetGitRevisionDescription.cmake 3 | # 4 | # Requires CMake 2.6 or newer (uses the 'function' command) 5 | # 6 | # Original Author: 7 | # 2009-2010 Ryan Pavlik 8 | # http://academic.cleardefinition.com 9 | # Iowa State University HCI Graduate Program/VRAC 10 | # 11 | # Copyright 2009-2012, Iowa State University 12 | # Copyright 2011-2015, Contributors 13 | # Distributed under the Boost Software License, Version 1.0. 14 | # (See accompanying file LICENSE_1_0.txt or copy at 15 | # http://www.boost.org/LICENSE_1_0.txt) 16 | # SPDX-License-Identifier: BSL-1.0 17 | 18 | set(HEAD_HASH) 19 | 20 | file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) 21 | 22 | string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) 23 | if(HEAD_CONTENTS MATCHES "ref") 24 | # named branch 25 | string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") 26 | if(EXISTS "@GIT_DIR@/${HEAD_REF}") 27 | configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) 28 | else() 29 | configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) 30 | file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) 31 | if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") 32 | set(HEAD_HASH "${CMAKE_MATCH_1}") 33 | endif() 34 | endif() 35 | else() 36 | # detached HEAD 37 | configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) 38 | endif() 39 | 40 | if(NOT HEAD_HASH) 41 | file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) 42 | string(STRIP "${HEAD_HASH}" HEAD_HASH) 43 | endif() 44 | -------------------------------------------------------------------------------- /src/DETHRACE/common/oil.h: -------------------------------------------------------------------------------- 1 | #ifndef _OIL_H_ 2 | #define _OIL_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern char* gOil_pixie_names[1]; 7 | extern int gNext_oil_pixie; 8 | extern br_scalar gZ_buffer_diff; 9 | extern br_scalar gMin_z_diff; 10 | extern br_pixelmap* gOil_pixies[1]; 11 | extern tOil_spill_info gOily_spills[15]; 12 | 13 | void InitOilSpills(void); 14 | 15 | void ResetOilSpills(void); 16 | 17 | void QueueOilSpill(tCar_spec* pCar); 18 | 19 | int OKToSpillOil(tOil_spill_info* pOil); 20 | 21 | void Vector3Interpolate(br_vector3* pDst, br_vector3* pFrom, br_vector3* pTo, br_scalar pP); 22 | 23 | void EnsureGroundDetailVisible(br_vector3* pNew_pos, br_vector3* pGround_normal, br_vector3* pOld_pos); 24 | 25 | void MungeOilsHeightAboveGround(tOil_spill_info* pOil); 26 | 27 | void MungeIndexedOilsHeightAboveGround(int pIndex); 28 | 29 | void SetInitialOilStuff(tOil_spill_info* pOil, br_model* pModel); 30 | 31 | void ProcessOilSpills(tU32 pFrame_period); 32 | 33 | int GetOilSpillCount(void); 34 | 35 | void GetOilSpillDetails(int pIndex, br_actor** pActor, br_scalar* pSize); 36 | 37 | int PointInSpill(br_vector3* pV, int pSpill); 38 | 39 | void GetOilFrictionFactors(tCar_spec* pCar, br_scalar* pFl_factor, br_scalar* pFr_factor, br_scalar* pRl_factor, br_scalar* pRr_factor); 40 | 41 | void AdjustOilSpill(int pIndex, br_matrix34* pMat, br_scalar pFull_size, br_scalar pGrow_rate, tU32 pSpill_time, tU32 pStop_time, tCar_spec* pCar, br_vector3* pOriginal_pos, br_pixelmap* pPixelmap); 42 | 43 | void ReceivedOilSpill(tNet_contents* pContents); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/DETHRACE/common/init.h: -------------------------------------------------------------------------------- 1 | #ifndef _INIT_H_ 2 | #define _INIT_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern int gGame_initialized; 7 | extern int gBr_initialized; 8 | extern int gBrZb_initialized; 9 | extern int gInitialisation_finished; 10 | extern int gRender_indent; 11 | extern tU32 gAustere_time; 12 | extern int gInitial_rank; 13 | extern int gCredits_per_rank[3]; 14 | extern int gInitial_credits[3]; 15 | extern int gNet_mode_of_last_game; 16 | extern br_material* gDefault_track_material; 17 | 18 | void AllocateSelf(void); 19 | 20 | void AllocateCamera(void); 21 | 22 | void ReinitialiseForwardCamera(void); 23 | 24 | void AllocateRearviewPixelmap(void); 25 | 26 | void ReinitialiseRearviewCamera(void); 27 | 28 | void ReinitialiseRenderStuff(void); 29 | 30 | void InstallFindFailedHooks(void); 31 | 32 | void AllocateStandardLamp(void); 33 | 34 | void InitializeBRenderEnvironment(void); 35 | 36 | void InitBRFonts(void); 37 | 38 | void AustereWarning(void); 39 | 40 | void InitLineStuff(void); 41 | 42 | void InitSmokeStuff(void); 43 | 44 | void Init2DStuff(void); 45 | 46 | void InitialiseApplication(int pArgc, char** pArgv); 47 | 48 | void InitialiseDeathRace(int pArgc, char** pArgv); 49 | 50 | void InitGame(int pStart_race); 51 | 52 | void DisposeGameIfNecessary(void); 53 | 54 | void LoadInTrack(void); 55 | 56 | void DisposeTrack(void); 57 | 58 | void CopyMaterialColourFromIndex(br_material* pMaterial); 59 | 60 | void InitRace(void); 61 | 62 | void DisposeRace(void); 63 | 64 | int GetScreenSize(void); 65 | 66 | void SetScreenSize(int pNew_size); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /reccmp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/library/debian:stable-slim 2 | 3 | # Gather dependencies 4 | RUN dpkg --add-architecture i386 5 | RUN apt-get update -y 6 | RUN apt-get install git wine wine64 wine32 wget unzip pip -y 7 | 8 | ENV WINEPREFIX=/wineprefix 9 | # Silence debug warnings in wine (creates noise during compile) 10 | ENV WINEDEBUG="-all" 11 | 12 | COPY set-env.reg /tmp/set-env.reg 13 | 14 | # Create and initialize Wine prefix 15 | RUN mkdir -p $WINEPREFIX && \ 16 | wineboot --init && \ 17 | # wait for wineboot to finish 18 | wineserver -w && \ 19 | wine regedit /S /tmp/set-env.reg && \ 20 | # wait for regedit to finish 21 | wineserver -w 22 | 23 | # Install MSVC 4.20 and CMake for Windows 24 | RUN git clone https://github.com/itsmattkc/MSVC420 $WINEPREFIX/drive_c/msvc 25 | 26 | # Install CMake for Windows 27 | RUN wget --quiet https://github.com/Kitware/CMake/releases/download/v3.26.6/cmake-3.26.6-windows-i386.zip 28 | RUN unzip -q cmake-3.26.6-windows-i386.zip -d $WINEPREFIX/drive_c 29 | RUN mv $WINEPREFIX/drive_c/cmake-3.26.6-windows-i386 $WINEPREFIX/drive_c/cmake 30 | RUN rm cmake-3.26.6-windows-i386.zip 31 | 32 | # Install Ninja for Windows 33 | RUN wget --quiet https://github.com/ninja-build/ninja/releases/download/v1.13.1/ninja-win.zip 34 | RUN unzip -q ninja-win.zip -d $WINEPREFIX/drive_c/ninja 35 | RUN rm ninja-win.zip 36 | 37 | # Install reccmp 38 | RUN pip install --break-system-packages git+https://github.com/isledecomp/reccmp 39 | 40 | # Set up entrypoint script to perform the build 41 | COPY entrypoint.sh entrypoint.sh 42 | ENTRYPOINT [ "./entrypoint.sh" ] 43 | -------------------------------------------------------------------------------- /cmake/EmbedResource.cmake: -------------------------------------------------------------------------------- 1 | # EmbedResource.cmake 2 | 3 | #################################################################################################### 4 | # original function by amir-saniyan https://gist.github.com/amir-saniyan/de99cee82fa9d8d615bb69f3f53b6004 5 | function(embed_resource resource_file_name source_file_name variable_name) 6 | 7 | if(EXISTS "${source_file_name}") 8 | if("${source_file_name}" IS_NEWER_THAN "${resource_file_name}") 9 | return() 10 | endif() 11 | endif() 12 | 13 | file(READ "${resource_file_name}" hex_content HEX) 14 | 15 | string(REPEAT "[0-9a-f]" 32 pattern) 16 | string(REGEX REPLACE "(${pattern})" "\\1\n" content "${hex_content}") 17 | string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " content "${content}") 18 | string(REGEX REPLACE ", $" "" content "${content}") 19 | set(array_definition "static const char ${variable_name}[] =\n{\n${content}\n};") 20 | set(source "// Auto generated file.\n${array_definition}\n") 21 | file(WRITE "${source_file_name}" "${source}") 22 | 23 | endfunction() 24 | #################################################################################################### 25 | 26 | 27 | if(NOT DEFINED SOURCE_DIR) 28 | message(FATAL_ERROR "SOURCE_DIR is not set") 29 | endif(NOT DEFINED SOURCE_DIR) 30 | 31 | if(NOT DEFINED FILE) 32 | message(FATAL_ERROR "FILE is not set") 33 | endif(NOT DEFINED FILE) 34 | 35 | string(REPLACE "." "_" generated_name "${FILE}") 36 | string(REPLACE "/" "_" generated_name "${generated_name}") 37 | string(TOUPPER "${generated_name}" generated_name) 38 | embed_resource("${SOURCE_DIR}/${FILE}" "${FILE}.h" "${generated_name}") 39 | -------------------------------------------------------------------------------- /src/S3/s3cda.c: -------------------------------------------------------------------------------- 1 | #include "s3cda.h" 2 | #include "harness/audio.h" 3 | #include "harness/trace.h" 4 | #include "s3.h" 5 | 6 | int gS3_cda_enabled; 7 | 8 | void S3EnableCDA(void) { 9 | gS3_cda_enabled = 1; 10 | } 11 | 12 | void S3DisableCDA(void) { 13 | S3StopCDAOutlets(); 14 | gS3_cda_enabled = 0; 15 | } 16 | 17 | int S3StopCDAOutlets(void) { 18 | tS3_channel* chan; 19 | tS3_outlet* o; 20 | 21 | if (gS3_cda_enabled) { 22 | for (o = gS3_outlets; o; o = o->next) { 23 | for (chan = o->channel_list; chan; chan = chan->next) { 24 | if (chan->type == eS3_ST_cda) { 25 | AudioBackend_StopCDA(); 26 | // S3SetMCIStopCommand(chan); 27 | } 28 | } 29 | } 30 | } 31 | return 1; 32 | } 33 | 34 | int S3CDAEnabled(void) { 35 | return gS3_cda_enabled; 36 | } 37 | 38 | int S3PlayCDA(tS3_channel* chan) { 39 | int track; 40 | if (gS3_cda_enabled) { 41 | track = strtoul(chan->descriptor->filename, NULL, 10); 42 | if (AudioBackend_PlayCDA(track) == eAB_error) { 43 | return eS3_error_start_cda; 44 | } 45 | } 46 | return eS3_error_none; 47 | } 48 | 49 | int S3StopCDA(tS3_channel* chan) { 50 | AudioBackend_StopCDA(); 51 | return eS3_error_none; 52 | } 53 | 54 | int S3SetCDAVolume(tS3_channel* chan, int pVolume) { 55 | if (gS3_cda_enabled) { 56 | AudioBackend_SetCDAVolume(pVolume); 57 | } 58 | return 0; 59 | } 60 | 61 | int S3IsCDAPlaying2(void) { 62 | return AudioBackend_CDAIsPlaying(); 63 | } 64 | 65 | int S3IsCDAPlaying(void) { 66 | return S3IsCDAPlaying2(); 67 | } 68 | -------------------------------------------------------------------------------- /lib/inih/LICENSE.TXT: -------------------------------------------------------------------------------- 1 | // Taken from https://github.com/benhoyt/inih/blob/master/LICENSE.txt 2 | 3 | The "inih" library is distributed under the New BSD license: 4 | 5 | Copyright (c) 2009, Ben Hoyt 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | * Neither the name of Ben Hoyt nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY BEN HOYT ''AS IS'' AND ANY 20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL BEN HOYT BE LIABLE FOR ANY 23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /lib/libsmacker/smk_bitstream.h: -------------------------------------------------------------------------------- 1 | /** 2 | libsmacker - A C library for decoding .smk Smacker Video files 3 | Copyright (C) 2012-2017 Greg Kennedy 4 | 5 | See smacker.h for more information. 6 | 7 | smk_bitstream.h 8 | SMK bitstream structure. Presents a block of raw bytes one 9 | bit at a time, and protects against over-read. 10 | */ 11 | 12 | #ifndef SMK_BITSTREAM_H 13 | #define SMK_BITSTREAM_H 14 | 15 | /** Bitstream structure, Forward declaration */ 16 | struct smk_bit_t; 17 | 18 | /* BITSTREAM Functions */ 19 | /** Initialize a bitstream */ 20 | struct smk_bit_t* smk_bs_init(const unsigned char* b, unsigned long size); 21 | 22 | /** This macro checks return code from _smk_bs_read_1 and 23 | jumps to error label if problems occur. */ 24 | #define smk_bs_read_1(t,uc) \ 25 | { \ 26 | if ((char)(uc = _smk_bs_read_1(t)) < 0) \ 27 | { \ 28 | fprintf(stderr, "libsmacker::smk_bs_read_1(" #t ", " #uc ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \ 29 | goto error; \ 30 | } \ 31 | } 32 | /** Read a single bit from the bitstream, and advance. 33 | Returns -1 on error. */ 34 | char _smk_bs_read_1(struct smk_bit_t* bs); 35 | 36 | /** This macro checks return code from _smk_bs_read_8 and 37 | jumps to error label if problems occur. */ 38 | #define smk_bs_read_8(t,s) \ 39 | { \ 40 | if ((short)(s = _smk_bs_read_8(t)) < 0) \ 41 | { \ 42 | fprintf(stderr, "libsmacker::smk_bs_read_8(" #t ", " #s ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \ 43 | goto error; \ 44 | } \ 45 | } 46 | /** Read eight bits from the bitstream (one byte), and advance. 47 | Returns -1 on error. */ 48 | short _smk_bs_read_8(struct smk_bit_t* bs); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/harness/platforms/sdl1_syms.h: -------------------------------------------------------------------------------- 1 | #ifndef sdl1_syms_h 2 | #define sdl1_syms_h 3 | 4 | #include 5 | 6 | #define FOREACH_SDL1_SYM(X) \ 7 | X(Init, int, (Uint32)) \ 8 | X(Quit, void, (void)) \ 9 | X(Delay, void, (Uint32)) \ 10 | X(GetTicks, Uint32, (void)) \ 11 | X(GetError, char*, (void)) \ 12 | X(PollEvent, int, (SDL_Event*)) \ 13 | X(SetVideoMode, SDL_Surface*, (int, int, int, Uint32)) \ 14 | X(FreeSurface, void, (SDL_Surface*)) \ 15 | X(LockSurface, int, (SDL_Surface*)) \ 16 | X(UnlockSurface, void, (SDL_Surface*)) \ 17 | X(UpdateRect, void, (SDL_Surface*, Sint32, Sint32, Sint32, Sint32)) \ 18 | X(WM_SetCaption, void, (const char*, const char*)) \ 19 | X(WM_ToggleFullScreen, int, (SDL_Surface*)) \ 20 | X(Flip, int, (SDL_Surface*)) \ 21 | X(ShowCursor, int, (int)) \ 22 | X(GetMouseState, Uint8, (int*, int*)) \ 23 | X(GetKeyName, char*, (SDLKey)) \ 24 | X(GL_GetProcAddress, void*, (const char*)) \ 25 | X(GL_SwapBuffers, void, (void)) 26 | 27 | #endif /* sdl1_syms_h */ 28 | -------------------------------------------------------------------------------- /docs/CODE_LAYOUT.md: -------------------------------------------------------------------------------- 1 | # Code layout 2 | 3 | ### DETHRACE 4 | Game logic. According to the symbol dump, these files were originally stored in `C:\DETHRACE\src`. 5 | 6 | - `DETHRACE/common` - common game logic 7 | - `DETHRACE/pc-dos` - DOS-specific functions 8 | - `DETHRACE/win95sys.c` - Windows-specific functions 9 | - `DETHRACE/pd` - platform-dependent generic headers. 10 | 11 | _All code here is kept as similar to how we think the original code might have looked. Any changes required are implemented as hooks into `harness`._ 12 | 13 | ### BRSRC13 14 | 15 | Graphics rendering library. [BRender](https://en.wikipedia.org/wiki/Argonaut_Games#BRender), originally stored in `C:\BRSRC13`. 16 | 17 | - Stainless Software used their own build of BRender with unknown modifications. 18 | 19 | _All code here is kept as similar to how we think the original code might have looked. Any changes required are implemented as hooks into `harness`._ 20 | 21 | ### S3 22 | 23 | Audio library. Possibly short for "Stainless Sound System"?! Supports at least two audio backends - [SOS](http://web.archive.org/web/19990221132448/http://www.humanmachine.com/sos.html) (DOS) and DirectSound. 24 | 25 | _All code here is kept as similar to how we think the original code might have looked, with the addition of a small amount of code integrating [miniaudio](https://miniaud.io) 26 | 27 | ### smackw32 28 | 29 | Implements the [RAD Smacker lib](https://wiki.multimedia.cx/index.php/RAD_Game_Tools_Smacker_API) interface. The implementation is backed by [libsmacker](https://libsmacker.sourceforge.net/). 30 | 31 | ### harness 32 | 33 | - Provides functions that the original game logic calls to implement modern cross-platform support. 34 | - SDL2, OpenGL, miniaudio 35 | -------------------------------------------------------------------------------- /docs/SCREENSHOTS.md: -------------------------------------------------------------------------------- 1 | # Progress screenshots 2 | 3 | 4 | ### September 2020 5 | --- 6 | ![Sep-17-2020 20-52-30](https://user-images.githubusercontent.com/1063652/110867229-54888e80-832b-11eb-8507-c6451694c8c4.gif) 7 | 8 | 9 | ### August 2020 10 | --- 11 | menu-animation 12 | 13 | menu-animation3 14 | 15 | 16 | ### July 2020 17 | --- 18 | font-test1 19 | 20 | font-debug-screen 21 | 22 | ![screen7](https://user-images.githubusercontent.com/1063652/110866243-b47e3580-8329-11eb-9a7a-340f8323dd18.jpeg) 23 | ![screen6](https://user-images.githubusercontent.com/1063652/110866242-b3e59f00-8329-11eb-9365-b65757db211f.jpeg) 24 | ![screen5](https://user-images.githubusercontent.com/1063652/110866238-b34d0880-8329-11eb-9493-3bc76e356b9a.jpeg) 25 | ![screen4](https://user-images.githubusercontent.com/1063652/110866235-b21bdb80-8329-11eb-813e-c1e61649c9d0.jpeg) 26 | ![screen3](https://user-images.githubusercontent.com/1063652/110866231-b1834500-8329-11eb-9dc0-4b51cef18f6a.jpeg) 27 | ![screen2](https://user-images.githubusercontent.com/1063652/110866227-b0521800-8329-11eb-93b9-f67f293f971c.jpeg) 28 | ![screen1](https://user-images.githubusercontent.com/1063652/110866209-aaf4cd80-8329-11eb-81ba-9f9b9b655a23.jpeg) 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/DETHRACE/common/pratcam.h: -------------------------------------------------------------------------------- 1 | #ifndef _PRATCAM_H_ 2 | #define _PRATCAM_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern tS3_sound_tag gWhirr_noise; 7 | extern tFlic_descriptor gPrat_flic; 8 | extern tPrat_sequence* gPratcam_sequences; 9 | extern tPrat_flic_spec* gPratcam_flics; 10 | extern int gCurrent_pratcam_chunk; 11 | extern int gPending_ambient_prat; 12 | extern int gCurrent_pratcam_index; 13 | extern br_pixelmap* gPrat_buffer; 14 | extern int gNumber_of_prat_sequences; 15 | extern int gNumber_of_prat_flics; 16 | extern tU32 gLast_pratcam_frame_time; 17 | extern int gCurrent_pratcam_precedence; 18 | extern int gCurrent_ambient_prat_sequence; 19 | extern int gCurrent_pratcam_alternative; 20 | 21 | int PratcamGetCurrent(void); 22 | 23 | int PratcamGetAmbient(void); 24 | 25 | int PratcamGetPending(void); 26 | 27 | void TogglePratcam(void); 28 | 29 | void LoadPratcam(char* pFolder_name); 30 | 31 | void NextPratcamChunk(void); 32 | 33 | void NewPratcamSequence(int pSequence_index, int pStart_chunk); 34 | 35 | void ChangeAmbientPratcamNow(int pIndex, int pStart_chunk); 36 | 37 | void ChangeAmbientPratcam(int pIndex); 38 | 39 | void PratcamEventNow(int pIndex); 40 | 41 | void PratcamEvent(int pIndex); 42 | 43 | int HighResPratBufferWidth(void); 44 | 45 | int HighResPratBufferHeight(void); 46 | 47 | void InitPratcam(void); 48 | 49 | void DisposePratcam(void); 50 | 51 | void DoPratcam(tU32 pThe_time); 52 | 53 | void TestPratCam(int pIndex); 54 | 55 | void PratCam0(void); 56 | 57 | void PratCam1(void); 58 | 59 | void PratCam2(void); 60 | 61 | void PratCam3(void); 62 | 63 | void PratCam4(void); 64 | 65 | void PratCam5(void); 66 | 67 | void PratCam6(void); 68 | 69 | void PratCam7(void); 70 | 71 | void PratCam8(void); 72 | 73 | void PratCam9(void); 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/DETHRACE/common/oppocar.c: -------------------------------------------------------------------------------- 1 | #include "oppocar.h" 2 | #include "harness/trace.h" 3 | #include 4 | 5 | int gCollision_detection_on__oppocar; // suffix added to avoid duplicate symbol 6 | br_vector3 gGround_normal__oppocar; // suffix added to avoid duplicate symbol 7 | void (*ControlCar__oppocar[6])(tCar_spec*, br_scalar); // suffix added to avoid duplicate symbol 8 | int gControl__oppocar; // suffix added to avoid duplicate symbol 9 | int gFace_num__oppocar; // suffix added to avoid duplicate symbol 10 | br_angle gOld_yaw__oppocar; // suffix added to avoid duplicate symbol 11 | int gMetal_crunch_sound_id__oppocar[5]; // suffix added to avoid duplicate symbol 12 | int gMetal_scrape_sound_id__oppocar[3]; // suffix added to avoid duplicate symbol 13 | tFace_ref gFace_list__oppocar[32]; // suffix added to avoid duplicate symbol 14 | br_scalar gOur_yaw__oppocar; // suffix added to avoid duplicate symbol 15 | br_scalar gGravity__oppocar; // suffix added to avoid duplicate symbol 16 | br_vector3 gNew_ground_normal__oppocar; // suffix added to avoid duplicate symbol 17 | 18 | // IDA: void __usercall MakeCarStationary(tCar_spec *pCar_spec@) 19 | void MakeCarStationary(tCar_spec* pCar_spec) { 20 | NOT_IMPLEMENTED(); 21 | } 22 | 23 | // IDA: void __usercall MoveThisCar(tU32 pTime_difference@, tCar_spec *car@) 24 | void MoveThisCar(tU32 pTime_difference, tCar_spec* car) { 25 | br_scalar dt; 26 | br_scalar ts; 27 | br_vector3 r; 28 | br_vector3 minus_k; 29 | int i; 30 | int j; 31 | br_angle phi; 32 | NOT_IMPLEMENTED(); 33 | } 34 | -------------------------------------------------------------------------------- /lib/libsmacker/README: -------------------------------------------------------------------------------- 1 | libsmacker 2 | A C library for decoding .smk Smacker Video files 3 | 4 | version 1.1.1 5 | 2020-01-05 6 | 7 | (c) Greg Kennedy 2013-2020 8 | http://libsmacker.sourceforge.net 9 | ---- 10 | 11 | --- 12 | Introduction 13 | --- 14 | libsmacker is a cross-platform C library which can be used for decoding Smacker Video files produced by RAD Game Tools. Smacker Video was the king of video middleware in the 1990s, and its 256-color compressed video format was used in over 2600 software titles. 15 | 16 | libsmacker implements the minimum feature set required from smackw32.dll to get an smk off a disk and the frames / audio into a buffer in the correct order. 17 | 18 | --- 19 | License 20 | --- 21 | libsmacker is released under the Lesser GNU Public License, v2.1. See the file COPYING for more information. 22 | 23 | --- 24 | Usage 25 | --- 26 | See the webpage for sample code and function documentation. The source package additionally includes a pair of driver programs: 27 | * driver.c - dumps all frames of a file to a bmp/ subdirectory, and all audio as raw streams to out_*.raw files in CWD 28 | * smk2avi.c - converts smk file(s) to AVI files - uncompressed 24-bit color and PCM audio stream. 29 | 30 | Though the libraries are "bulletproofed" the sample apps are not: be cautious if you plan to implement in some critical environment. 31 | 32 | --- 33 | Changelog 34 | --- 35 | 1.1.1 36 | * Re-license under LGPL 2.1 37 | 1.1 38 | * Switch to autotools-based build 39 | * Incorporates patches from Dalerank Slim, Gennady Trafimenkov, and Bianca van Schaik 40 | * Performance improvements and code cleanup / safety. 41 | 1.0 42 | * Initial revision 43 | 44 | --- 45 | Contact 46 | --- 47 | Questions/comments: 48 | * by email: kennedy.greg@gmail.com 49 | * by website: http://libsmacker.sourceforge.net 50 | 51 | Enjoy! 52 | -------------------------------------------------------------------------------- /src/harness/include/harness/audio.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HARNESS_AUDIO_H 3 | #define HARNESS_AUDIO_H 4 | 5 | typedef enum tAudioBackend_error_code { 6 | eAB_success = 0, 7 | eAB_error = 1 8 | } tAudioBackend_error_code; 9 | 10 | typedef void tAudioBackend_stream; 11 | 12 | // Used by S3 13 | tAudioBackend_error_code AudioBackend_Init(void); 14 | void AudioBackend_UnInit(void); 15 | tAudioBackend_error_code AudioBackend_InitCDA(void); 16 | void AudioBackend_UnInitCDA(void); 17 | void* AudioBackend_AllocateSampleTypeStruct(void); 18 | tAudioBackend_error_code AudioBackend_PlaySample(void* type_struct_sample, int channels, void* data, int size, int rate, int loop); 19 | int AudioBackend_SoundIsPlaying(void* type_struct_sample); 20 | tAudioBackend_error_code AudioBackend_StopSample(void* type_struct_sample); 21 | tAudioBackend_error_code AudioBackend_SetVolume(void* type_struct_sample, int volume); 22 | tAudioBackend_error_code AudioBackend_SetPan(void* type_struct_sample, int pan); 23 | tAudioBackend_error_code AudioBackend_SetFrequency(void* type_struct_sample, int original_rate, int new_rate); 24 | tAudioBackend_error_code AudioBackend_SetVolumeSeparate(void* type_struct_sample, int left_volume, int right_volume); 25 | 26 | tAudioBackend_error_code AudioBackend_PlayCDA(int track); 27 | tAudioBackend_error_code AudioBackend_StopCDA(void); 28 | int AudioBackend_CDAIsPlaying(void); 29 | tAudioBackend_error_code AudioBackend_SetCDAVolume(int volume); 30 | 31 | // Used by smackw32 32 | tAudioBackend_stream* AudioBackend_StreamOpen(int bitdepth, int channels, unsigned int sample_rate); 33 | tAudioBackend_error_code AudioBackend_StreamWrite(tAudioBackend_stream* stream_handle, const unsigned char* data, unsigned long size); 34 | tAudioBackend_error_code AudioBackend_StreamClose(tAudioBackend_stream* stream_handle); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /tools/comment_struct_var.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 -u 2 | 3 | # Used to comment each line of a struct variable with the name of the associated field. 4 | # For example: 5 | # tInterface_spec s = { 6 | # 0, // initial_imode 7 | # 0, // first_opening_flic 8 | # }; 9 | # 10 | # Usage: 11 | # `tools/comment_struct_var.py 'tInterface_spec s = { 12 | # 0, 13 | # 0, 14 | # };` 15 | 16 | import sys 17 | 18 | struct_var = sys.argv[1] 19 | lines = struct_var.split('\n') 20 | 21 | var_header = lines[0] 22 | tokens = var_header.split(' ') 23 | struct_name = tokens[0] 24 | 25 | f = open("src/DETHRACE/dr_types.h", 'r') 26 | 27 | match_line = 'typedef struct {0} {{'.format(struct_name) 28 | 29 | found = False 30 | while True: 31 | l = f.readline() 32 | if l == "": 33 | break 34 | 35 | if l.strip() == match_line: 36 | found = True 37 | break 38 | 39 | if found == False: 40 | print('Couldnt find struct in dr_types.h. Looking for', match_line) 41 | sys.exit(1) 42 | 43 | print(var_header.strip()) 44 | 45 | for i in range(1, len(lines)): 46 | var_line = lines[i] 47 | def_line = f.readline().strip() 48 | 49 | if '};' in var_line: 50 | print(var_line) 51 | break 52 | 53 | # comment_index = line.find('//') 54 | # if comment_index > 0: 55 | # line = line[:comment_index] 56 | 57 | parts = def_line.split(' ') 58 | name = parts[1] 59 | array_index = name.find('[') 60 | if array_index > 0: 61 | name = name[0: array_index] 62 | 63 | if name.startswith('(*'): 64 | name = name[2:] 65 | paren_index = name.find(')') 66 | if paren_index > 0: 67 | name = name[0:paren_index] 68 | 69 | if ';' in name: 70 | name = name[:-1] 71 | 72 | print(var_line, '\t\t//', name) 73 | -------------------------------------------------------------------------------- /src/DETHRACE/common/replay.h: -------------------------------------------------------------------------------- 1 | #ifndef _REPLAY_H_ 2 | #define _REPLAY_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern char* gReplay_pixie_names[10]; 7 | extern int gSingle_frame_mode; 8 | extern tU32 gCam_change_time; 9 | extern int gSave_file; 10 | extern int gProgress_line_left[2]; 11 | extern int gProgress_line_right[2]; 12 | extern int gProgress_line_top[2]; 13 | extern br_pixelmap* gReplay_pixies[10]; 14 | extern int gKey_down; 15 | extern int gNo_cursor; 16 | extern int gSave_frame_number; 17 | extern int gCam_change_button_down; 18 | extern tU32 gAction_replay_start_time; 19 | extern tU32 gLast_replay_zappy_screen; 20 | extern tS32 gStopped_time; 21 | extern float gPending_replay_rate; 22 | extern tU32 gAction_replay_end_time; 23 | extern float gReplay_rate; 24 | extern int gSave_bunch_ID; 25 | extern int gPlay_direction; 26 | extern int gPaused; 27 | extern tAction_replay_camera_type gAction_replay_camera_mode; 28 | 29 | int ReplayIsPaused(void); 30 | 31 | float GetReplayRate(void); 32 | 33 | int GetReplayDirection(void); 34 | 35 | void StopSaving(void); 36 | 37 | void ActualActionReplayHeadups(int pSpecial_zappy_bastard); 38 | 39 | void DoActionReplayPostSwap(void); 40 | 41 | void DoZappyActionReplayHeadups(int pSpecial_zappy_bastard); 42 | 43 | void DoActionReplayHeadups(void); 44 | 45 | void MoveReplayBuffer(tS32 pMove_amount); 46 | 47 | void MoveToEndOfReplay(void); 48 | 49 | void MoveToStartOfReplay(void); 50 | 51 | void ToggleReplay(void); 52 | 53 | void ReverseSound(tS3_effect_tag pEffect_index, tS3_sound_tag pSound_tag); 54 | 55 | int FindUniqueFile(void); 56 | 57 | void PollActionReplayControls(tU32 pFrame_period); 58 | 59 | void CheckReplayTurnOn(void); 60 | 61 | void InitializeActionReplay(void); 62 | 63 | void DoActionReplay(tU32 pFrame_period); 64 | 65 | void SynchronizeActionReplay(void); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /tools/watcom-codegen/README.md: -------------------------------------------------------------------------------- 1 | # Watcom symbol dump codegen tools 2 | 3 | ## codegen.py 4 | 5 | Takes an [exedump](https://github.com/jeff-1amstudios/open-watcom-v2/tree/master/bld/exedump) output file and generates skeleton "c" project files containing functions, structs, enums and global variables. 6 | 7 | Was used to generate the first commits of [src](../../src) directory. 8 | 9 | Example output: 10 | ```c 11 | 12 | typedef enum tPowerup_type { 13 | ePowerup_dummy = 0, 14 | ePowerup_instantaneous = 1, 15 | ePowerup_timed = 2, 16 | ePowerup_whole_race = 3 17 | } tPowerup_type; 18 | 19 | struct tPedestrian_action { 20 | float danger_level; 21 | float percentage_chance; 22 | int number_of_bearings; 23 | int number_of_sounds; 24 | int sounds[3]; 25 | tBearing_sequence sequences[7]; 26 | float initial_speed; 27 | float looping_speed; 28 | tU32 reaction_time; 29 | }; 30 | 31 | // Offset: 9548 32 | // Size: 1603 33 | // EAX: c 34 | void CalcEngineForce(tCar_spec *c, br_scalar dt) { 35 | br_scalar torque; 36 | br_scalar ts; 37 | br_scalar ts2; 38 | br_scalar brake_temp; 39 | int sign; 40 | tS32 temp_for_swap; 41 | } 42 | ``` 43 | 44 | ### Usage 45 | 46 | 1. Concatenate the executable file and the symbol file 47 | ```sh 48 | cat carma1.exe dethrace.sym > carma_with_symbols.exe 49 | ``` 50 | 51 | 2. Execute wdump and pipe the output to file 52 | ```sh 53 | wdump -Daglmt carma_with_symbols.exe > dump.txt 54 | ``` 55 | 56 | 3. Execute the codegen tool 57 | ```sh 58 | codegen.py dump.txt 59 | ``` 60 | 61 | You now have the C skeleton files in `./_generated`. 62 | 63 | 64 | ## split-dump.sh 65 | Takes a [exedump](https://github.com/jeff-1amstudios/open-watcom-v2/tree/master/bld/exedump) output file and splits it into a single file per module for easier debugging. 66 | 67 | -------------------------------------------------------------------------------- /packaging/macos/generate_icns.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | SOURCE_IMAGE=$1 5 | TEMP_ICON_IMAGE=icon.png 6 | 7 | # resize to 412x with black canvas 8 | convert ${SOURCE_IMAGE} -resize 412x412 -background Black -gravity center -extent 412x412 ${TEMP_ICON_IMAGE} 9 | 10 | # add rounded corners 11 | convert ${TEMP_ICON_IMAGE} \ 12 | \( +clone -alpha extract \ 13 | -draw 'fill black polygon 0,0 0,50 50,0 fill white circle 50,50 50,0' \ 14 | \( +clone -flip \) -compose Multiply -composite \ 15 | \( +clone -flop \) -compose Multiply -composite \ 16 | \) -alpha off -compose CopyOpacity -composite ${TEMP_ICON_IMAGE} 17 | 18 | # add margin 19 | convert ${TEMP_ICON_IMAGE} -bordercolor transparent -border 40x40 ${TEMP_ICON_IMAGE} 20 | 21 | # add drop shadow 22 | convert ${TEMP_ICON_IMAGE} \ 23 | \( +clone -background black -shadow 100x5+0+0 \) +swap \ 24 | -background none -layers merge +repage ${TEMP_ICON_IMAGE} 25 | 26 | 27 | rm -r dethrace.iconset || true 28 | mkdir -p dethrace.iconset 29 | sips -z 16 16 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_16x16.png 30 | sips -z 32 32 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_16x16@2x.png 31 | sips -z 32 32 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_32x32.png 32 | sips -z 64 64 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_32x32@2x.png 33 | sips -z 128 128 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_128x128.png 34 | sips -z 256 256 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_128x128@2x.png 35 | sips -z 256 256 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_256x256.png 36 | sips -z 512 512 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_256x256@2x.png 37 | sips -z 512 512 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_512x512.png 38 | sips -z 1024 1024 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_512x512@2x.png 39 | iconutil -c icns dethrace.iconset 40 | rm -r dethrace.iconset ${TEMP_ICON_IMAGE} 41 | -------------------------------------------------------------------------------- /src/DETHRACE/main.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #ifdef _WIN32 5 | #include 6 | #include 7 | #include 8 | #endif 9 | 10 | #include "brender.h" 11 | 12 | extern int Harness_Init(int* argc, char* argv[]); 13 | extern int original_main(int pArgc, char* pArgv[]); 14 | 15 | void BR_CALLBACK _BrBeginHook(void) { 16 | struct br_device* BR_EXPORT BrDrv1SoftPrimBegin(char* arguments); 17 | struct br_device* BR_EXPORT BrDrv1SoftRendBegin(char* arguments); 18 | struct br_device* BR_EXPORT BrDrv1VirtualFramebufferBegin(char* arguments); 19 | struct br_device* BR_EXPORT BrDrv1GLBegin(char* arguments); 20 | 21 | #if _MSC_VER != 1020 22 | BrDevAddStatic(NULL, BrDrv1SoftPrimBegin, NULL); 23 | BrDevAddStatic(NULL, BrDrv1SoftRendBegin, NULL); 24 | BrDevAddStatic(NULL, BrDrv1VirtualFramebufferBegin, NULL); 25 | BrDevAddStatic(NULL, BrDrv1GLBegin, NULL); 26 | #endif 27 | } 28 | 29 | void BR_CALLBACK _BrEndHook(void) { 30 | } 31 | 32 | int main(int argc, char* argv[]) { 33 | int result; 34 | 35 | #ifdef _WIN32 36 | #if _MSC_VER != 1020 37 | /* Attach to the console that started us if any */ 38 | if (AttachConsole(ATTACH_PARENT_PROCESS)) { 39 | /* We attached successfully, lets redirect IO to the consoles handles if not already redirected */ 40 | if (_fileno(stdout) == -2 || _get_osfhandle(_fileno(stdout)) == -2) { 41 | freopen("CONOUT$", "w", stdout); 42 | } 43 | 44 | if (_fileno(stderr) == -2 || _get_osfhandle(_fileno(stderr)) == -2) { 45 | freopen("CONOUT$", "w", stderr); 46 | } 47 | 48 | if (_fileno(stdin) == -2 || _get_osfhandle(_fileno(stdin)) == -2) { 49 | freopen("CONIN$", "r", stdin); 50 | } 51 | } 52 | #endif 53 | #endif 54 | 55 | result = Harness_Init(&argc, argv); 56 | if (result != 0) { 57 | return result; 58 | } 59 | 60 | return original_main(argc, argv); 61 | } 62 | -------------------------------------------------------------------------------- /src/S3/resource.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOURCE_H_ 2 | #define _RESOURCE_H_ 3 | 4 | #include "brender.h" 5 | #include "s3_defs.h" 6 | 7 | typedef enum s3_memory_classes { 8 | kMem_S3_scan_name = 223, // 0xdf 9 | kMem_S3_sound_header = 224, // 0xe0 10 | kMem_S3_sample = 225, // 0xe1 11 | kMem_S3_mac_channel = 226, // 0xe2 12 | kMem_S3_mac_path = 227, // 0xe3 13 | kMem_S3_sentinel = 228, // 0xe4 14 | kMem_S3_outlet = 229, // 0xe5 15 | kMem_S3_channel = 230, // 0xe6 16 | kMem_S3_descriptor = 231, // 0xe7 17 | kMem_S3_reverse_buffer = 232, // 0xe8 18 | kMem_S3_source = 233, // 0xe9 19 | kMem_S3_DOS_SOS_channel = 234, // 0xea 20 | kMem_S3_PC_DOS_path = 235, // 0xeb 21 | kMem_S3_DOS_SOS_patch = 236, // 0xec 22 | kMem_S3_DOS_SOS_song_structure = 237, // 0xed 23 | kMem_S3_DOS_SOS_song_data = 238, // 0xee 24 | kMem_S3_Windows_95_load_WAV_file = 239, // 0xef 25 | kMem_S3_Windows_95_create_temp_buffer_space_to_reverse_sample = 240, // 0xf0 26 | kMem_S3_Windows_95_path = 241, // 0xf1 27 | kMem_DOS_HMI_file_open = 242, // 0xf2 28 | } s3_memory_classes; 29 | 30 | void* S3MemAllocate(br_size_t size, br_uint_8 type); 31 | void S3MemFree(void* p); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /docs/CONFIGURATION.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | Dethrace looks for a `dethrace.ini` file in the [system preferences directory](https://wiki.libsdl.org/SDL2/SDL_GetPrefPath): 4 | | Platform | Example Path | 5 | |----------|----------------------------------------------------------------------| 6 | | Windows | `C:\Users\bob\AppData\Roaming\dethrace\dethrace.ini` | 7 | | macOS | `/Users/bob/Library/Application Support/dethrace/dethrace.ini` | 8 | | Linux | `/home/bob/.local/share/dethrace/dethrace.ini` | 9 | 10 | 11 | If this file is not present, dethrace will run with default configuration and attempt to discover the correct Carmageddon directory to use (see below). 12 | 13 | ## Example dethrace.ini file 14 | ```ini 15 | [General] 16 | ; Enable original CD check 17 | CdCheck = 0 18 | 19 | ; Enable original censorship check 20 | GoreCheck = 0 21 | 22 | ; set to 0 to disable 23 | FPSLimit = 60 24 | 25 | ; Full screen or window 26 | Windowed = 1 27 | 28 | ; 3dfx mode (via OpenGL) 29 | Emulate3DFX = 0 30 | 31 | ; Censored zombie/robots mode 32 | BoringMode = 0 33 | 34 | ; Play cut scenes on startup and between races 35 | Cutscenes = 0 36 | 37 | ; "hires" mode is 640x480, otherwise default 320x200 38 | Hires = 1 39 | 40 | ; Only used in 'demo' mode. Default demo time out is 240s (5 mins) 41 | DemoTimeout = 240 42 | 43 | ; Which directory in the [Games] section to run 44 | DefaultGame = c1 45 | 46 | [Games] 47 | c1 = /opt/carma/c1 48 | c1demo = /opt/carma/c1demo 49 | sp = /opt/carma/splatpack 50 | 51 | [Cheats] 52 | EditMode = 0 53 | FreezeTimer = 0 54 | GameCompleted = 0 55 | 56 | [Sound] 57 | Enabled = 1 58 | SoundOptionsScreen = 1 59 | VolumeMultiplier = 1 60 | 61 | [Network] 62 | AdapterName = "" 63 | ``` 64 | 65 | ## Order of precedence for game directory detection: 66 | 1. Directory pointed to by DefaultGame 67 | 2. First game in the list if at least 1 game dir is specified 68 | 3. `DETHRACE_ROOT_DIR` environment variable 69 | 4. Current working directory (if `DATA/GENERAL.TXT` exists) 70 | 5. `SDL_GetPrefPath` directory 71 | -------------------------------------------------------------------------------- /reccmp/README.md: -------------------------------------------------------------------------------- 1 | # Docker container for running cross-platform MSVC 4.20 2 | 3 | To run MSVC 4.20 outside of a non-Windows environment, you can use a Docker image and [Wine](https://www.winehq.org/) 4 | 5 | ## Original binary 6 | We are targetting being accurate to CARM95.EXE. 7 | - Created date: "16 October 1997" 8 | - SHA256 hash: `c6040203856b71e6a22d2a29053a1eadd1a2ab41bce97b6031d745079bc07bdf` 9 | 10 | ## Build container image 11 | ```sh 12 | docker buildx build --platform linux/amd64 -t msvc420-wine . 13 | ``` 14 | 15 | ## Running the container 16 | 17 | When running this container, you must define: 18 | 19 | | Name | Example value | Description 20 | |------------|----------|-------| 21 | | `CMAKE_FLAGS` | `-G Ninja -DCMAKE_BUILD_TYPE=Debug -DMSVC_42_FOR_RECCMP=on` | Environment variable | 22 | | `/source` | `/code/dethrace` | Volume mount. Path to the top-level dethrace directory | 23 | | `/build` | `/code/dethrace/build-msvc420` | Volume mount. This directory must exist but can start off empty. Note that this build directory _cannot be_ the same as your "regular" build directory. | 24 | | `/original` | `/games/carma` | Volume mount. Path to a directory with a copy of the original CARM95.EXE file | 25 | 26 | ### Generating an HTML diff 27 | 28 | This is the primary flow for making a change to the code and viewing the comparison to the original executable. 29 | 30 | ```sh 31 | docker run --platform linux/amd64 \ 32 | -e CMAKE_FLAGS="-G Ninja -DCMAKE_BUILD_TYPE=Debug -DMSVC_42_FOR_RECCMP=on" \ 33 | -v :/source \ 34 | -v :/build \ 35 | -v :/original:ro \ 36 | msvc420-wine -- \ 37 | reccmp-reccmp --target CARM95 --silent --html report.html 38 | ``` 39 | 40 | After running, a `report.html` file will be created in the build-msvc420 directory. 41 | 42 | ### Make a pull request change 43 | 44 | reccmp will run against the code in the PR branch. If any functions decrease in accuracy the PR validation will fail. 45 | 46 | When the PR is merged, the updated report is stored in https://github.com/dethrace-labs/reccmp-report, and this is used to compare the next PR 47 | -------------------------------------------------------------------------------- /src/DETHRACE/pc-win95/ssdx.c: -------------------------------------------------------------------------------- 1 | #if 0 2 | #include "ssdx.h" 3 | #include "errors.h" 4 | #include "harness/hooks.h" 5 | 6 | int gSSDX_windowed; 7 | void* gSSDX_hwnd; 8 | 9 | int SSDXStart(void* hWnd, int windowed, int flags) { 10 | int res = 0; 11 | dr_dprintf("SSDXStart(): START..."); 12 | if (windowed) { 13 | gSSDX_windowed = 1; 14 | } 15 | gSSDX_hwnd = hWnd; 16 | 17 | // Not required 18 | 19 | // if ((flags & 1) != 0) { 20 | // dr_dprintf("Calling DirectDrawCreate()..."); 21 | // res = DirectDrawCreate(0, &gDirect_draw, 0); 22 | // if (!res) { 23 | // dr_dprintf("Calling SetCooperativeLevel()..."); 24 | // if (gSSDX_windowed) { 25 | // res = gDirect_draw->lpVtbl->SetCooperativeLevel(gDirect_draw, gSSDX_hwnd, 8); 26 | // } else { 27 | // res = gDirect_draw->lpVtbl->SetCooperativeLevel(gDirect_draw, gSSDX_hwnd, 83); 28 | // } 29 | // } 30 | // } 31 | // if (!res && (flags & 2) != 0) { 32 | // dr_dprintf("Calling DirectSoundCreate()..."); 33 | // res = DirectSoundCreate(0, &gDirect_sound, 0); 34 | // } 35 | // if (res) { 36 | // SSDXHandleError(res); 37 | // } 38 | dr_dprintf("SSDXStart(): END."); 39 | return res; 40 | } 41 | 42 | int SSDXInitDirectDraw(int width, int height, int* row_bytes) { 43 | DirectDraw_CreateSurface(width, height); 44 | *row_bytes = width; 45 | return 0; 46 | } 47 | 48 | void SSDXRelease(void) {} 49 | 50 | void SSDXGetWindowRect(void* hWnd) { 51 | // none of this is required 52 | 53 | // GetClientRect(hWnd, &gSSDX_rect); 54 | // ClientToScreen(hWnd, (LPPOINT)&gSSDX_rect); 55 | // ClientToScreen(hWnd, (LPPOINT)&gSSDX_rect.right); 56 | // dr_dprintf("New window rect: (%d,%d)(%d,%d)", gSSDX_rect.left, gSSDX_rect.top, gSSDX_rect.right, gSSDX_rect.bottom); 57 | } 58 | 59 | void SSDXHandleError(int error) { 60 | // no-op 61 | } 62 | 63 | void SSDXSetPaleeteEntries(PALETTEENTRY_* palette, int pFirst_color, int pCount) { 64 | DirectDrawDevice_SetPaletteEntries(palette, pFirst_color, pCount); 65 | } 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/harness/platforms/null.c: -------------------------------------------------------------------------------- 1 | #include "null.h" 2 | #include 3 | 4 | static br_uint_32 null_time; 5 | 6 | static int null_set_window_pos(void* hWnd, int x, int y, int nWidth, int nHeight) { 7 | null_time += 1; 8 | return 0; 9 | } 10 | 11 | static void null_destroy_window(void) { 12 | null_time += 1; 13 | } 14 | 15 | static int null_show_error_message(char* title, char* text) { 16 | null_time += 1; 17 | return 0; 18 | } 19 | 20 | static void null_get_and_handle_message(void) { 21 | null_time += 1; 22 | } 23 | 24 | static void null_get_keyboard_state(br_uint_32* buffer) { 25 | null_time += 1; 26 | } 27 | 28 | static int null_get_mouse_buttons(int* pButton1, int* pButton2) { 29 | null_time += 1; 30 | return 0; 31 | } 32 | 33 | static int null_get_mouse_position(int* pX, int* pY) { 34 | null_time += 1; 35 | return 0; 36 | } 37 | 38 | static int null_show_cursor(int show) { 39 | null_time += 1; 40 | return 0; 41 | } 42 | 43 | static void null_set_palette(br_colour* palette) { 44 | null_time += 1; 45 | } 46 | 47 | static void null_sleep(br_uint_32 milliseconds) { 48 | null_time += 1; 49 | null_time += milliseconds; 50 | } 51 | 52 | static br_uint_32 null_getticks(void) { 53 | null_time += 1; 54 | return null_time; 55 | } 56 | 57 | static void null_get_pref_path(char* path, char* app_name) { 58 | strcpy(path, "."); 59 | } 60 | 61 | void Null_Platform_Init(tHarness_platform* platform) { 62 | null_time = 0; 63 | platform->ProcessWindowMessages = null_get_and_handle_message; 64 | 65 | platform->Sleep = null_sleep; 66 | platform->GetTicks = null_getticks; 67 | platform->ShowCursor = null_show_cursor; 68 | platform->SetWindowPos = null_set_window_pos; 69 | platform->DestroyWindow = null_destroy_window; 70 | platform->GetKeyboardState = null_get_keyboard_state; 71 | platform->GetMousePosition = null_get_mouse_position; 72 | platform->GetMouseButtons = null_get_mouse_buttons; 73 | platform->ShowErrorMessage = null_show_error_message; 74 | 75 | platform->Renderer_SetPalette = null_set_palette; 76 | platform->GetPrefPath = null_get_pref_path; 77 | } 78 | -------------------------------------------------------------------------------- /src/harness/audio/null.c: -------------------------------------------------------------------------------- 1 | #include "harness/audio.h" 2 | #include 3 | 4 | tAudioBackend_error_code AudioBackend_Init(void) { 5 | return eAB_error; 6 | } 7 | 8 | void AudioBackend_UnInit(void) { 9 | } 10 | 11 | tAudioBackend_error_code AudioBackend_InitCDA(void) { 12 | return eAB_error; 13 | } 14 | 15 | void AudioBackend_UnInitCDA(void) { 16 | } 17 | 18 | void* AudioBackend_AllocateSampleTypeStruct(void) { 19 | } 20 | 21 | tAudioBackend_error_code AudioBackend_PlaySample(void* type_struct_sample, int channels, void* data, int size, int rate, int loop) { 22 | return eAB_error; 23 | } 24 | 25 | int AudioBackend_SoundIsPlaying(void* type_struct_sample) { 26 | } 27 | 28 | tAudioBackend_error_code AudioBackend_StopSample(void* type_struct_sample) { 29 | return eAB_error; 30 | } 31 | 32 | tAudioBackend_error_code AudioBackend_SetVolume(void* type_struct_sample, int volume) { 33 | return eAB_error; 34 | } 35 | 36 | tAudioBackend_error_code AudioBackend_SetPan(void* type_struct_sample, int pan) { 37 | return eAB_error; 38 | } 39 | 40 | tAudioBackend_error_code AudioBackend_SetFrequency(void* type_struct_sample, int original_rate, int new_rate) { 41 | return eAB_error; 42 | } 43 | 44 | tAudioBackend_error_code AudioBackend_SetVolumeSeparate(void* type_struct_sample, int left_volume, int right_volume) { 45 | return eAB_error; 46 | } 47 | 48 | tAudioBackend_error_code AudioBackend_PlayCDA(int track) { 49 | return eAB_error; 50 | } 51 | 52 | tAudioBackend_error_code AudioBackend_StopCDA(void) { 53 | return eAB_error; 54 | } 55 | 56 | int AudioBackend_CDAIsPlaying(void) { 57 | } 58 | 59 | tAudioBackend_error_code AudioBackend_SetCDAVolume(int volume) { 60 | return eAB_error; 61 | } 62 | 63 | // Used by smackw32 64 | tAudioBackend_stream* AudioBackend_StreamOpen(int bitdepth, int channels, unsigned int sample_rate) { 65 | return NULL; 66 | } 67 | 68 | tAudioBackend_error_code AudioBackend_StreamWrite(tAudioBackend_stream* stream_handle, const unsigned char* data, unsigned long size) { 69 | return eAB_error; 70 | } 71 | 72 | tAudioBackend_error_code AudioBackend_StreamClose(tAudioBackend_stream* stream_handle) { 73 | return eAB_error; 74 | } 75 | -------------------------------------------------------------------------------- /src/DETHRACE/common/demo.c: -------------------------------------------------------------------------------- 1 | #include "demo.h" 2 | #include "globvars.h" 3 | #include "graphics.h" 4 | #include "harness/trace.h" 5 | #include "input.h" 6 | #include "loading.h" 7 | #include "pd/sys.h" 8 | #include "s3/s3.h" 9 | #include "sound.h" 10 | #include "utility.h" 11 | #include 12 | 13 | // GLOBAL: CARM95 0x00512080 14 | int gLast_demo; 15 | 16 | // IDA: void __cdecl DoDemo() 17 | // FUNCTION: CARM95 0x00461110 18 | void DoDemo(void) { 19 | tS32 start_time; 20 | tS32 frame_time; 21 | FILE* f; 22 | tPath_name the_path; 23 | int i; 24 | int count; 25 | char s[256]; 26 | char* str; 27 | tS3_sound_tag song_tag; 28 | 29 | PathCat(the_path, gApplication_path, "DEMOFILE.TXT"); 30 | f = DRfopen(the_path, "rt"); 31 | if (f == NULL) { 32 | return; 33 | } 34 | count = GetAnInt(f); 35 | gLast_demo++; 36 | if (gLast_demo >= count) { 37 | gLast_demo = 0; 38 | } 39 | for (i = 0; i <= gLast_demo; i++) { 40 | GetALineAndDontArgue(f, s); 41 | } 42 | fclose(f); 43 | PathCat(the_path, gApplication_path, s); 44 | f = DRfopen(the_path, "rb"); 45 | if (f == NULL) { 46 | return; 47 | } 48 | 49 | ClearEntireScreen(); 50 | song_tag = S3StartSound(gEffects_outlet, 10000); 51 | DRSetPalette(gRender_palette); 52 | FadePaletteUp(); 53 | 54 | while (1) { 55 | SoundService(); 56 | start_time = PDGetTotalTime(); 57 | frame_time = ReadS32(f); 58 | fread(gBack_screen->pixels, gBack_screen->height * gBack_screen->width, 1, f); 59 | PDScreenBufferSwap(0); 60 | while (frame_time > PDGetTotalTime() - start_time && !AnyKeyDown() && !EitherMouseButtonDown()) { 61 | // FIXME: sleep? SoundService? 62 | } 63 | if (!S3SoundStillPlaying(song_tag)) { 64 | song_tag = S3StartSound(gEffects_outlet, 10000); 65 | } 66 | if (AnyKeyDown() || EitherMouseButtonDown() || feof(f)) { 67 | break; 68 | } 69 | } 70 | S3StopSound(song_tag); 71 | S3StopOutletSound(gEffects_outlet); 72 | S3StopAllOutletSounds(); 73 | fclose(f); 74 | FadePaletteDown(); 75 | WaitForNoKeys(); 76 | } 77 | -------------------------------------------------------------------------------- /src/harness/platforms/sdl_dyn_common.h: -------------------------------------------------------------------------------- 1 | #ifndef sdl_dyn_common_h 2 | #define sdl_dyn_common_h 3 | 4 | #ifdef DETHRACE_SDL_DYNAMIC 5 | #ifdef _WIN32 6 | #include 7 | #ifdef CreateWindow 8 | #undef CreateWindow 9 | #endif 10 | static void *Harness_LoadObject(const char *name) { 11 | return LoadLibraryA(name); 12 | } 13 | static void Harness_UnloadObject(void *obj) { 14 | FreeLibrary(obj); 15 | } 16 | static void *Harness_LoadFunction(void *obj, const char *name) { 17 | return GetProcAddress(obj, name); 18 | } 19 | #else 20 | #include 21 | static void *Harness_LoadObject(const char *name) { 22 | return dlopen(name, RTLD_NOW | RTLD_LOCAL); 23 | } 24 | static void Harness_UnloadObject(void *obj) { 25 | dlclose(obj); 26 | } 27 | static void *Harness_LoadFunction(void *obj, const char *name) { 28 | return dlsym(obj, name); 29 | } 30 | #endif 31 | #endif 32 | 33 | #define STR2_JOIN(A,B) A##B 34 | #define STR_JOIN(A,B) STR2_JOIN(A, B) 35 | 36 | #define X_TYPEDEF(name, ret, args) typedef ret SDLCALL t##SDL_##name##_fn args; 37 | #define X_STATIC_SYMBOL(name, ret, args) static t##SDL_##name##_fn* STR_JOIN(SYMBOL_PREFIX, name); 38 | #ifdef DETHRACE_SDL_DYNAMIC 39 | #define X_LOAD_FUNCTION(name, ret, args) \ 40 | STR_JOIN(SYMBOL_PREFIX, name) = Harness_LoadFunction(OBJECT_NAME, "SDL_" #name); \ 41 | if (STR_JOIN(SYMBOL_PREFIX, name) == NULL) { \ 42 | goto failure; \ 43 | } 44 | #else 45 | #define X_LOAD_FUNCTION(name, ret, args) STR_JOIN(SYMBOL_PREFIX, name) = SDL_##name; 46 | #endif 47 | 48 | FOREACH_SDLX_SYM(X_TYPEDEF) 49 | FOREACH_SDLX_SYM(X_STATIC_SYMBOL) 50 | 51 | static int STR_JOIN(SYMBOL_PREFIX,LoadSymbols)(void) { 52 | #ifdef DETHRACE_SDL_DYNAMIC 53 | for (size_t i = 0; i < BR_ASIZE(possible_locations); i++) { 54 | OBJECT_NAME = Harness_LoadObject(possible_locations[i]); 55 | if (OBJECT_NAME != NULL) { 56 | break; 57 | } 58 | } 59 | if (OBJECT_NAME == NULL) { 60 | return 1; 61 | } 62 | #endif 63 | FOREACH_SDLX_SYM(X_LOAD_FUNCTION) 64 | return 0; 65 | #ifdef DETHRACE_SDL_DYNAMIC 66 | failure: 67 | Harness_UnloadObject(OBJECT_NAME); 68 | return 1; 69 | #endif 70 | } 71 | 72 | #endif /* sdl_dyn_common_h */ 73 | -------------------------------------------------------------------------------- /lib/libsmacker/smk_malloc.h: -------------------------------------------------------------------------------- 1 | /** 2 | libsmacker - A C library for decoding .smk Smacker Video files 3 | Copyright (C) 2012-2017 Greg Kennedy 4 | 5 | See smacker.h for more information. 6 | 7 | smk_malloc.h 8 | "Safe" implementations of malloc and free. 9 | Verbose implementation of assert. 10 | */ 11 | 12 | #ifndef SMK_MALLOC_H 13 | #define SMK_MALLOC_H 14 | 15 | /* calloc */ 16 | #include 17 | /* fprintf */ 18 | #include 19 | 20 | /* Error messages from calloc */ 21 | #include 22 | #include 23 | 24 | /** 25 | Verbose assert: 26 | branches to an error block if pointer is null 27 | */ 28 | #define smk_assert(p) \ 29 | { \ 30 | if (!p) \ 31 | { \ 32 | fprintf(stderr, "libsmacker::smk_assert(" #p "): ERROR: NULL POINTER at line %lu, file %s\n", (unsigned long)__LINE__, __FILE__); \ 33 | goto error; \ 34 | } \ 35 | } 36 | 37 | /** 38 | Safe free: attempts to prevent double-free by setting pointer to NULL. 39 | Optionally warns on attempts to free a NULL pointer. 40 | */ 41 | #define smk_free(p) \ 42 | { \ 43 | if (p) \ 44 | { \ 45 | free(p); \ 46 | p = NULL; \ 47 | } \ 48 | /* else \ 49 | { \ 50 | fprintf(stderr, "libsmacker::smk_free(" #p ") - Warning: attempt to free NULL pointer (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \ 51 | } */ \ 52 | } 53 | 54 | /** 55 | Safe malloc: exits if calloc() returns NULL. 56 | Also initializes blocks to 0. 57 | Optionally warns on attempts to malloc over an existing pointer. 58 | Ideally, one should not exit() in a library. However, if you cannot 59 | calloc(), you probably have bigger problems. 60 | */ 61 | #define smk_malloc(p, x) \ 62 | { \ 63 | /* if (p) \ 64 | { \ 65 | fprintf(stderr, "libsmacker::smk_malloc(" #p ", %lu) - Warning: freeing non-NULL pointer before calloc (file: %s, line: %lu)\n", (unsigned long) (x), __FILE__, (unsigned long)__LINE__); \ 66 | free(p); \ 67 | } */ \ 68 | p = calloc(1, x); \ 69 | if (!p) \ 70 | { \ 71 | fprintf(stderr, "libsmacker::smk_malloc(" #p ", %lu) - ERROR: calloc() returned NULL (file: %s, line: %lu)\n\tReason: [%d] %s\n", \ 72 | (unsigned long) (x), __FILE__, (unsigned long)__LINE__, errno, strerror(errno)); \ 73 | exit(EXIT_FAILURE); \ 74 | } \ 75 | } 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /src/harness/include/harness/config.h: -------------------------------------------------------------------------------- 1 | #ifndef HARNESS_CONFIG_H 2 | #define HARNESS_CONFIG_H 3 | 4 | #define MAX_PATH 1024 5 | 6 | typedef enum tHarness_game_type { 7 | eGame_none, 8 | eGame_carmageddon, 9 | eGame_splatpack, 10 | eGame_carmageddon_demo, 11 | eGame_splatpack_demo, 12 | eGame_splatpack_xmas_demo, 13 | } tHarness_game_type; 14 | 15 | typedef enum { 16 | eGameLocalization_none, 17 | eGameLocalization_german, 18 | eGameLocalization_polish, 19 | } tHarness_game_localization; 20 | 21 | typedef struct tHarness_game_info { 22 | tHarness_game_type mode; 23 | tHarness_game_localization localization; 24 | struct { 25 | // different between carmageddon and splatpack 26 | char* INTRO_SMK_FILE; 27 | // different between demo and full game 28 | char* GERMAN_LOADSCRN; 29 | // some versions have an ascii table built-in, others provide it through KEYBOARD.COK 30 | int requires_ascii_table; 31 | // built-in keyboard look-up table for certain localized Carmageddon releases 32 | int* ascii_table; 33 | // built-in shifted keyboard look-up table for certain localized Carmageddon releases 34 | int* ascii_shift_table; 35 | } defines; 36 | int data_dir_has_3dfx_assets; 37 | } tHarness_game_info; 38 | 39 | typedef struct tHarness_game_dir { 40 | char name[256]; 41 | char directory[MAX_PATH]; 42 | } tHarness_game_dir; 43 | 44 | typedef struct tHarness_game_config { 45 | int enable_cd_check; 46 | int physics_step_time; 47 | float fps; 48 | int freeze_timer; 49 | unsigned demo_timeout; 50 | int enable_diagnostics; 51 | float volume_multiplier; 52 | int start_full_screen; 53 | int gore_check; 54 | int sound_options; 55 | 56 | int verbose; 57 | int opengl_3dfx_mode; 58 | int game_completed; 59 | 60 | int install_signalhandler; 61 | int no_bind; 62 | char network_adapter_name[256]; 63 | 64 | tHarness_game_dir* selected_dir; 65 | int game_dirs_count; 66 | tHarness_game_dir game_dirs[10]; 67 | char default_game[256]; 68 | } tHarness_game_config; 69 | 70 | extern tHarness_game_info harness_game_info; 71 | extern tHarness_game_config harness_game_config; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/smackw32/include/smackw32/smackw32.h: -------------------------------------------------------------------------------- 1 | #include "harness/audio.h" 2 | #include 3 | 4 | #define SMACKTRACK1 0x02000 // Play audio track 1 5 | #define SMACKTRACK2 0x04000 // Play audio track 2 6 | #define SMACKTRACK3 0x08000 // Play audio track 3 7 | #define SMACKTRACK4 0x10000 // Play audio track 4 8 | #define SMACKTRACK5 0x20000 // Play audio track 5 9 | #define SMACKTRACK6 0x40000 // Play audio track 6 10 | #define SMACKTRACK7 0x80000 // Play audio track 7 11 | #define SMACKTRACKS (SMACKTRACK1 | SMACKTRACK2 | SMACKTRACK3 | SMACKTRACK4 | SMACKTRACK5 | SMACKTRACK6 | SMACKTRACK7) 12 | #define SMACKAUTOEXTRA 0xffffffff 13 | 14 | typedef struct SmackTag { 15 | unsigned long Version; 16 | unsigned long Width; 17 | unsigned long Height; 18 | unsigned long Frames; 19 | unsigned long MSPerFrame; 20 | unsigned long SmackerType; 21 | unsigned long LargestInTrack[7]; 22 | unsigned long tablesize; 23 | unsigned long codesize; 24 | unsigned long absize; 25 | unsigned long detailsize; 26 | unsigned long typesize; 27 | unsigned long TrackType[7]; 28 | unsigned long extra; 29 | unsigned long NewPalette; 30 | unsigned char Palette[772]; 31 | unsigned long PalType; 32 | unsigned long FrameNum; 33 | unsigned long FrameSize; 34 | unsigned long SndSize; 35 | unsigned long LastRectx; 36 | unsigned long LastRecty; 37 | unsigned long LastRectw; 38 | unsigned long LastRecth; 39 | unsigned long OpenFlags; 40 | unsigned long LeftOfs; 41 | unsigned long TopOfs; 42 | unsigned long ReadError; 43 | unsigned long addr32; 44 | 45 | // added by dethrace 46 | void* smk_handle; // opaque pointer to the libsmacker instance 47 | void* f; // opaque file pointer 48 | tAudioBackend_stream* audio_stream; 49 | } Smack; 50 | 51 | Smack* SmackOpen(const char* name, unsigned int flags, unsigned int extrabuf); 52 | int SmackSoundUseDirectSound(void* dd); // NULL mean create instance (apparently) 53 | void SmackToBuffer(Smack* smack, unsigned int left, unsigned int top, unsigned int pitch, unsigned int destheight, void* buf, unsigned int flags); 54 | int SmackDoFrame(Smack* smack); 55 | void SmackNextFrame(Smack* smack); 56 | int SmackWait(Smack* smack); 57 | void SmackClose(Smack* smack); 58 | -------------------------------------------------------------------------------- /cmake/reccmp.cmake: -------------------------------------------------------------------------------- 1 | function(reccmp_find_project RESULT) 2 | set(curdir "${CMAKE_CURRENT_SOURCE_DIR}") 3 | while(1) 4 | if(EXISTS "${curdir}/reccmp-project.yml") 5 | break() 6 | endif() 7 | get_filename_component(nextdir "${curdir}" DIRECTORY) 8 | if(nextdir STREQUAL curdir) 9 | set(curdir "${RESULT}-NOTFOUND") 10 | break() 11 | endif() 12 | set(curdir "${nextdir}") 13 | endwhile() 14 | set("${RESULT}" "${curdir}" PARENT_SCOPE) 15 | endfunction() 16 | 17 | function(reccmp_add_target TARGET) 18 | cmake_parse_arguments(ARGS "" "ID" "" ${ARGN}) 19 | if(NOT ARGS_ID) 20 | message(FATAL_ERROR "Missing ID argument") 21 | endif() 22 | set_property(TARGET ${TARGET} PROPERTY INTERFACE_RECCMP_ID "${ARGS_ID}") 23 | set_property(GLOBAL APPEND PROPERTY RECCMP_TARGETS ${TARGET}) 24 | endfunction() 25 | 26 | function(reccmp_configure) 27 | cmake_parse_arguments(ARGS "COPY_TO_SOURCE_FOLDER" "DIR" "" ${ARGN}) 28 | set(binary_dir "${CMAKE_BINARY_DIR}") 29 | if(ARGS_DIR) 30 | set(binary_dir "${ARGS_DIR}") 31 | endif() 32 | 33 | reccmp_find_project(reccmp_project_dir) 34 | if(NOT reccmp_project_dir) 35 | message(FATAL_ERROR "Cannot find reccmp-project.yml") 36 | endif() 37 | 38 | if(CMAKE_CONFIGURATION_TYPES) 39 | set(outputdir "${binary_dir}/$") 40 | else() 41 | set(outputdir "${binary_dir}") 42 | endif() 43 | set(build_yml_txt "project: '${reccmp_project_dir}'\ntargets:\n") 44 | get_property(RECCMP_TARGETS GLOBAL PROPERTY RECCMP_TARGETS) 45 | foreach(target ${RECCMP_TARGETS}) 46 | get_property(id TARGET "${target}" PROPERTY INTERFACE_RECCMP_ID) 47 | string(APPEND build_yml_txt " ${id}:\n") 48 | string(APPEND build_yml_txt " path: '$'\n") 49 | if(WIN32 AND MSVC) 50 | string(APPEND build_yml_txt " pdb: '$'\n") 51 | endif() 52 | endforeach() 53 | file(GENERATE OUTPUT "${outputdir}/reccmp-build.yml" CONTENT "${build_yml_txt}") 54 | 55 | if(ARGS_COPY_TO_SOURCE_FOLDER) 56 | file(GENERATE OUTPUT "${CMAKE_SOURCE_DIR}/reccmp-build.yml" CONTENT "${build_yml_txt}" CONDITION $) 57 | endif() 58 | endfunction() 59 | -------------------------------------------------------------------------------- /src/DETHRACE/common/trig.h: -------------------------------------------------------------------------------- 1 | #ifndef _TRIG_H_ 2 | #define _TRIG_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern float gFloat_sine_table[91]; 7 | extern br_fixed_ls gFixed_sine_table[91]; 8 | extern br_matrix23 mat23tmp1; 9 | extern br_matrix23 mat23tmp2; 10 | extern br_matrix34 mattmp1__trig; // suffix added to avoid duplicate symbol 11 | extern br_matrix34 mattmp2__trig; // suffix added to avoid duplicate symbol 12 | 13 | float FastFloatSin(int pAngle_in_degrees); 14 | 15 | float FastFloatCos(int pAngle_in_degrees); 16 | 17 | float FastFloatTan(int pAngle_in_degrees); 18 | 19 | br_scalar FastScalarSin(int pAngle_in_degrees); 20 | 21 | br_scalar FastScalarCos(int pAngle_in_degrees); 22 | 23 | br_scalar FastScalarTan(int pAngle_in_degrees); 24 | 25 | br_scalar FastScalarSinAngle(br_angle pBR_angle); 26 | 27 | br_scalar FastScalarCosAngle(br_angle pBR_angle); 28 | 29 | br_scalar FastScalarTanAngle(br_angle pBR_angle); 30 | 31 | float FastFloatArcSin(float pValue); 32 | 33 | float FastFloatArcCos(float pValue); 34 | 35 | br_scalar FastScalarArcSin(br_scalar pValue); 36 | 37 | br_scalar FastScalarArcCos(br_scalar pValue); 38 | 39 | float FastFloatArcTan2(float pY, float pX); 40 | 41 | br_scalar FastScalarArcTan2(br_scalar pY, br_scalar pX); 42 | 43 | br_angle FastFloatArcTan2Angle(float pY, float pX); 44 | 45 | br_angle FastScalarArcTan2Angle(br_scalar pY, br_scalar pX); 46 | 47 | void DRMatrix34RotateX(br_matrix34* mat, br_angle rx); 48 | 49 | void DRMatrix34RotateY(br_matrix34* mat, br_angle ry); 50 | 51 | void DRMatrix34RotateZ(br_matrix34* mat, br_angle rz); 52 | 53 | void DRMatrix34Rotate(br_matrix34* mat, br_angle r, br_vector3* a); 54 | 55 | void DRMatrix34PreRotateX(br_matrix34* mat, br_angle rx); 56 | 57 | void DRMatrix34PostRotateX(br_matrix34* mat, br_angle rx); 58 | 59 | void DRMatrix34PreRotateY(br_matrix34* mat, br_angle ry); 60 | 61 | void DRMatrix34PostRotateY(br_matrix34* mat, br_angle ry); 62 | 63 | void DRMatrix34PreRotateZ(br_matrix34* mat, br_angle rz); 64 | 65 | void DRMatrix34PostRotateZ(br_matrix34* mat, br_angle rz); 66 | 67 | void DRMatrix34PreRotate(br_matrix34* mat, br_angle r, br_vector3* axis); 68 | 69 | void DRMatrix34PostRotate(br_matrix34* mat, br_angle r, br_vector3* axis); 70 | 71 | void DRMatrix23Rotate(br_matrix23* mat, br_angle rz); 72 | 73 | void DRMatrix23PreRotate(br_matrix23* mat, br_angle rz); 74 | 75 | void DRMatrix23PostRotate(br_matrix23* mat, br_angle rz); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /src/DETHRACE/pd/net.h: -------------------------------------------------------------------------------- 1 | #ifndef _PD_NET_H_ 2 | #define _PD_NET_H_ 3 | 4 | // Jeff: 5 | // Header files are generated from information in the original symbol dump, but we don't exactly know what this used to look like or be called. 6 | // Each platform build included a platform-dependant `sys` and `net` files. From the symbol dump and debug/error messages in the binaries, 7 | // we know of at least `pc-dos/dossys.c`, `pc-dos/dosnet.c`, `Win95sys.c`. 8 | // Functions contained within these files are prefixed with `PD` - we assume that is short for something like `Platform Dependant`. 9 | 10 | #include "dr_types.h" 11 | 12 | void ClearupPDNetworkStuff(void); 13 | 14 | void MATTMessageCheck(char* pFunction_name, tNet_message* pMessage, int pAlleged_size); 15 | 16 | int GetMessageTypeFromMessage(char* pMessage_str); 17 | 18 | void MakeMessageToSend(int pMessage_type); 19 | 20 | int ReceiveHostResponses(void); 21 | 22 | int BroadcastMessage(void); 23 | 24 | int PDNetInitialise(void); 25 | 26 | int PDNetShutdown(void); 27 | 28 | void PDNetStartProducingJoinList(void); 29 | 30 | void PDNetEndJoinList(void); 31 | 32 | int PDNetGetNextJoinGame(tNet_game_details* pGame, int pIndex); 33 | 34 | void PDNetDisposeGameDetails(tNet_game_details* pDetails); 35 | 36 | int PDNetHostGame(tNet_game_details* pDetails, char* pHost_name, void** pHost_address); 37 | 38 | int PDNetJoinGame(tNet_game_details* pDetails, char* pPlayer_name); 39 | 40 | void PDNetLeaveGame(tNet_game_details* pDetails); 41 | 42 | void PDNetHostFinishGame(tNet_game_details* pDetails); 43 | 44 | tU32 PDNetExtractGameID(tNet_game_details* pDetails); 45 | 46 | tPlayer_ID PDNetExtractPlayerID(tNet_game_details* pDetails); 47 | 48 | void PDNetObtainSystemUserName(char* pName, int pMax_length); 49 | 50 | int PDNetSendMessageToPlayer(tNet_game_details* pDetails, tNet_message* pMessage, tPlayer_ID pPlayer); 51 | 52 | int PDNetSendMessageToAllPlayers(tNet_game_details* pDetails, tNet_message* pMessage); 53 | 54 | tNet_message* PDNetGetNextMessage(tNet_game_details* pDetails, void** pSender_address); 55 | 56 | tNet_message* PDNetAllocateMessage(tU32 pSize, tS32 pSize_decider); 57 | 58 | void PDNetDisposeMessage(tNet_game_details* pDetails, tNet_message* pMessage); 59 | 60 | void PDNetSetPlayerSystemInfo(tNet_game_player_info* pPlayer, void* pSender_address); 61 | 62 | void PDNetDisposePlayer(tNet_game_player_info* pPlayer); 63 | 64 | int PDNetSendMessageToAddress(tNet_game_details* pDetails, tNet_message* pMessage, void* pAddress); 65 | 66 | int PDNetInitClient(tNet_game_details* pDetails); 67 | 68 | int PDNetGetHeaderSize(void); 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /docs/RENDERING_PIPELINE.md: -------------------------------------------------------------------------------- 1 | # Rendering pipeline 2 | 3 | The original game renders both 2d and 3d elements to the same memory buffer, called `gBack_screen`. 4 | 5 | Another variable, `gRender_screen`, points into that memory buffer and is where the 3d scene is drawn on top of any existing 2d pixels. 6 | 7 | Rendering is done in a (standard for the time) 8 bit paletted mode. 8 | 9 | ``` 10 | +-----------------------------------------+ 11 | |gBack_screen | 12 | | +------------------------+ | 13 | | | gRender_screen | | 14 | | | | | 15 | | | | | 16 | | | | | 17 | | | | | 18 | | +------------------------+ | 19 | | | 20 | +-----------------------------------------+ 21 | ``` 22 | 23 | The `RenderAFrame` function does the following: 24 | 25 | 1. Render 2d background content (horizon, map, etc) to `gBack_screen` 26 | 2. Start 3d scene rendering 27 | 3. Render 3d environment to `gRender_screen` 28 | 4. End 3d scene rendering 29 | 5. Render 2d foreground content into `gBack_screen` (HUD, messages, etc) 30 | 6. Swap buffers 31 | 32 | If the rearview mirror is rendered, steps 3-4 are repeated, this time rendering into `gRearview_screen` 33 | 34 | ## Palette manipulation 35 | 36 | The game palette is updated frequently: 37 | 1. Fade screen to black 38 | 2. Fade screen back up to normal brightness 39 | 3. Different palettes for the menu interface and for game play 40 | 4. The "On drugs" powerup 41 | 42 | Palette animations run in a tight loop, assuming they are writing to the system color palette, so do not re-render the 3d scene etc. We handle this by hooking the palette functions and reusing the last-rendered scene from our framebuffer. 43 | 44 | ## OpenGL implementation 45 | 46 | ### Start 3d rendering hook 47 | - Capture the current `gBack_screen` and convert it to a 32 bit OpenGL texture, and render it as a full-screen quad. 48 | - Configure OpenGL framebuffer to do render-to-texture 49 | - Clear `gBack_screen` 50 | 51 | ### Render model hook 52 | - Render the model as an OpenGL VBO, convert referenced materials to OpenGL textures. 53 | 54 | ### End 3d rendering hook 55 | Render the framebuffer from above as a full-screen quad. 56 | 57 | ### Swap buffers hook 58 | - Again capture `gBack_screen` to pick up HUD elements rendered after the 3d scene, convert it to 32 bit, and render it as a full-screen quad. 59 | - Generate a palette-manipulation image which is blended over the top of everything as a full-screen quad to handle palette animations. 60 | -------------------------------------------------------------------------------- /src/DETHRACE/common/drfile.c: -------------------------------------------------------------------------------- 1 | #include "drfile.h" 2 | #include "brender.h" 3 | #include "harness/trace.h" 4 | #include "loading.h" 5 | #include 6 | 7 | // GLOBAL: CARM95 0x000050f020 8 | br_filesystem gFilesystem = { 9 | "Carmageddon", 10 | NULL, 11 | &DRStdioOpenRead, 12 | &DRStdioOpenWrite, 13 | &DRStdioClose, 14 | NULL, 15 | NULL, 16 | NULL, 17 | &DRStdioRead, 18 | &DRStdioWrite, 19 | NULL, 20 | NULL, 21 | NULL 22 | }; 23 | 24 | // GLOBAL: CARM95 0x00536298 25 | br_filesystem* gOld_file_system; 26 | 27 | // IDA: void* __cdecl DRStdioOpenRead(char *name, br_size_t n_magics, br_mode_test_cbfn *identify, int *mode_result) 28 | // FUNCTION: CARM95 0x0044cf30 29 | void* DRStdioOpenRead(char* name, br_size_t n_magics, br_mode_test_cbfn* identify, int* mode_result) { 30 | if (mode_result != NULL) { 31 | *mode_result = 0; 32 | } 33 | return DRfopen(name, "rb"); 34 | } 35 | 36 | // IDA: void* __cdecl DRStdioOpenWrite(char *name, int mode) 37 | // FUNCTION: CARM95 0x0044cf64 38 | void* DRStdioOpenWrite(char* name, int mode) { 39 | return gOld_file_system->open_write(name, mode); 40 | } 41 | 42 | // IDA: void __cdecl DRStdioClose(void *f) 43 | // FUNCTION: CARM95 0x0044cf87 44 | void DRStdioClose(void* f) { 45 | gOld_file_system->close(f); 46 | } 47 | 48 | // IDA: br_size_t __cdecl DRStdioRead(void *buf, br_size_t size, unsigned int n, void *f) 49 | // FUNCTION: CARM95 0x0044cfa1 50 | br_size_t DRStdioRead(void* buf, br_size_t size, unsigned int n, void* f) { 51 | br_size_t result; 52 | return gOld_file_system->read(buf, size, n, f); 53 | } 54 | 55 | // IDA: br_size_t __cdecl DRStdioWrite(void *buf, br_size_t size, unsigned int n, void *f) 56 | // FUNCTION: CARM95 0x0044cfd5 57 | br_size_t DRStdioWrite(void* buf, br_size_t size, unsigned int n, void* f) { 58 | br_size_t result; 59 | return gOld_file_system->write(buf, size, n, f); 60 | } 61 | 62 | // IDA: void __cdecl InstallDRFileCalls() 63 | // FUNCTION: CARM95 0x0044d009 64 | void InstallDRFileCalls(void) { 65 | br_filesystem* temp_system; 66 | temp_system = BrMemAllocate(sizeof(br_filesystem), kMem_temp_fs); 67 | gOld_file_system = BrFilesystemSet(temp_system); 68 | gFilesystem.attributes = gOld_file_system->attributes; 69 | gFilesystem.eof = gOld_file_system->eof; 70 | gFilesystem.getchr = gOld_file_system->getchr; 71 | gFilesystem.putchr = gOld_file_system->putchr; 72 | gFilesystem.getline = gOld_file_system->getline; 73 | gFilesystem.putline = gOld_file_system->putline; 74 | gFilesystem.advance = gOld_file_system->advance; 75 | BrFilesystemSet(&gFilesystem); 76 | BrMemFree(temp_system); 77 | } 78 | -------------------------------------------------------------------------------- /docs/PORTING.md: -------------------------------------------------------------------------------- 1 | # Porting Dethrace to other systems 2 | 3 | ## Operating Systems 4 | 5 | Assuming an operating system called _foo_, follow the steps to add support for it. 6 | 7 | 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): 8 | - `OS_InstallSignalHandler` 9 | - `OS_fopen` 10 | - `OS_ConsoleReadPassword` 11 | 12 | 2. Update `src/harness/CMakeLists.h` and add a new conditional section for "os/foo.h", based on existing conditions for Windows, MacOS etc. 13 | 14 | For example: 15 | 16 | ``` 17 | ... 18 | elseif( _FOO_ ) 19 | target_sources(harness PRIVATE 20 | os/foo.c 21 | ) 22 | ... 23 | ``` 24 | 25 | ## Platform (windowing / input) 26 | 27 | A `Platform` in _dethrace_ implements windowing and input handling. 28 | 29 | The default platform is `SDL2`, which uses SDL2 for windowing and input. See [platforms/sdl_opengl.c](https://github.com/dethrace-labs/dethrace/blob/main/src/harness/platforms/sdl2.c). 30 | 31 | To add a new `Platform`: 32 | 33 | 1. Create a `src/harness/my_platform.c` file where you'll implement your platform-specific callbacks. 34 | Define a public fully-initialized `const tPlatform_bootstrap MYPLATFORM_bootstrap ` variable in this file. 35 | 36 | 2. Add the the following code fragments to appropriate locations in `src/harness/harness.c`: 37 | ```c 38 | extern const tPlatform_bootstrap MYPLATFORM_bootstrap; 39 | ``` 40 | ```c 41 | #ifdef DETHRACE_PLATFORM_MYPLATFORM 42 | &MYPLATFORM_bootstrap, 43 | #endif 44 | ``` 45 | 46 | 3. Add new conditionals to `CMakeLists.txt` and `src/harness/CMakeLists.txt` for your new platform 47 | 48 | For example: 49 | ```cmake 50 | # CMakeLists.txt 51 | option(DETHRACE_PLATFORM_MYPLATFORM "Enable my platform" OFF) 52 | if(DETHRACE_PLATFORM_MYPLATFORM) 53 | find_package(MyPlatform REQUIRED) 54 | endif() 55 | ``` 56 | ```cmake 57 | # src/harness/CMakeLists.txt 58 | if(DETHRACE_PLATFORM_MYPLATFORM) 59 | target_sources(harness PRIVATE 60 | my_platform.c 61 | ) 62 | target_compile_definitions(harness PRIVATE DETHRACE_PLATFORM_MYPLATFORM) 63 | target_link_libraries(harness PRIVATE MyPlatform::MyPlatform) 64 | endif() 65 | ``` 66 | 67 | 4. Hook up all the function pointers using the [sdl2 platform](https://github.com/dethrace-labs/dethrace/blob/main/src/harness/platforms/sdl2.c) as a guide. 68 | 69 | 5. Run cmake to update your build with the new platform 70 | ```sh 71 | cd build 72 | cmake -DDETHRACE_PLATFORM_MYPLATFORM=ON .. 73 | cmake --build . 74 | ``` 75 | 76 | 6. Build 77 | ``` 78 | -cmake --build . 79 | ``` 80 | -------------------------------------------------------------------------------- /src/DETHRACE/common/crush.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRUSH_H_ 2 | #define _CRUSH_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern float gWobble_spam_y[8]; 7 | extern float gWobble_spam_z[8]; 8 | extern br_scalar gWheel_circ_to_width; 9 | extern tU8 gSmoke_damage_step[12]; 10 | extern int gSteal_ranks[5]; 11 | 12 | int ReadCrushData(FILE* pF, tCrush_data* pCrush_data); 13 | 14 | float SkipCrushData(FILE* pF); 15 | 16 | int WriteCrushData(FILE* pF, tCrush_data* pCrush_data); 17 | 18 | void DisposeCrushData(tCrush_data* pCrush_data); 19 | 20 | void CrushModelPoint(tCar_spec* pCar, int pModel_index, br_model* pModel, int pCrush_point_index, br_vector3* pEnergy_vector, br_scalar total_energy, tCrush_data* pCrush_data); 21 | 22 | void CrushModel(tCar_spec* pCar, int pModel_index, br_actor* pActor, br_vector3* pImpact_point, br_vector3* pEnergy_vector, tCrush_data* pCrush_data); 23 | 24 | void JitModelUpdate(br_actor* actor, br_model* model, br_material* material, void* render_data, br_uint_8 style, int on_screen); 25 | 26 | void SetModelForUpdate(br_model* pModel, tCar_spec* pCar, int crush_only); 27 | 28 | void TotallySpamTheModel(tCar_spec* pCar, int pModel_index, br_actor* pActor, tCrush_data* pCrush_data, br_scalar pMagnitude); 29 | 30 | br_scalar RepairModel(tCar_spec* pCar, int pModel_index, br_actor* pActor, br_vertex* pUndamaged_vertices, br_scalar pAmount, br_scalar* pTotal_deflection); 31 | 32 | float RepairCar2(tCar_spec* pCar, tU32 pFrame_period, br_scalar* pTotal_deflection); 33 | 34 | float RepairCar(tU16 pCar_ID, tU32 pFrame_period, br_scalar* pTotal_deflection); 35 | 36 | void TotallyRepairACar(tCar_spec* pCar); 37 | 38 | void TotallyRepairCar(void); 39 | 40 | void CheckLastCar(void); 41 | 42 | void KnackerThisCar(tCar_spec* pCar); 43 | 44 | void SetKnackeredFlag(tCar_spec* pCar); 45 | 46 | void DamageUnit2(tCar_spec* pCar, int pUnit_type, int pDamage_amount); 47 | 48 | void RecordLastDamage(tCar_spec* pCar); 49 | 50 | void DoDamage(tCar_spec* pCar, tDamage_type pDamage_type, float pMagnitude, float pNastiness); 51 | 52 | void CheckPiledriverBonus(tCar_spec* pCar, br_vector3* pImpact_point, br_vector3* pEnergy); 53 | 54 | tImpact_location CalcModifiedLocation(tCar_spec* pCar); 55 | 56 | void DoPratcamHit(br_vector3* pHit_vector); 57 | 58 | void DamageSystems(tCar_spec* pCar, br_vector3* pImpact_point, br_vector3* pEnergy_vector, int pWas_hitting_a_car); 59 | 60 | tImpact_location GetDirection(br_vector3* pVelocity); 61 | 62 | void SetSmokeLastDamageLevel(tCar_spec* pCar); 63 | 64 | void SortOutSmoke(tCar_spec* pCar); 65 | 66 | void StealCar(tCar_spec* pCar); 67 | 68 | int DoCrashEarnings(tCar_spec* pCar1, tCar_spec* pCar2); 69 | 70 | void DoWheelDamage(tU32 pFrame_period); 71 | 72 | void CrashEarnings(tCar_spec* pCar1, tCar_spec* pCar2); 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /lib/miniaudio/LICENSE: -------------------------------------------------------------------------------- 1 | This software is available as a choice of the following licenses. Choose 2 | whichever you prefer. 3 | 4 | =============================================================================== 5 | ALTERNATIVE 1 - Public Domain (www.unlicense.org) 6 | =============================================================================== 7 | This is free and unencumbered software released into the public domain. 8 | 9 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 10 | software, either in source code form or as a compiled binary, for any purpose, 11 | commercial or non-commercial, and by any means. 12 | 13 | In jurisdictions that recognize copyright laws, the author or authors of this 14 | software dedicate any and all copyright interest in the software to the public 15 | domain. We make this dedication for the benefit of the public at large and to 16 | the detriment of our heirs and successors. We intend this dedication to be an 17 | overt act of relinquishment in perpetuity of all present and future rights to 18 | this software under copyright law. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 24 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | 27 | For more information, please refer to 28 | 29 | =============================================================================== 30 | ALTERNATIVE 2 - MIT No Attribution 31 | =============================================================================== 32 | Copyright 2020 David Reid 33 | 34 | Permission is hereby granted, free of charge, to any person obtaining a copy of 35 | this software and associated documentation files (the "Software"), to deal in 36 | the Software without restriction, including without limitation the rights to 37 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 38 | of the Software, and to permit persons to whom the Software is furnished to do 39 | so. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 47 | SOFTWARE. -------------------------------------------------------------------------------- /src/S3/include/s3/s3.h: -------------------------------------------------------------------------------- 1 | #ifndef S3_SOUND_H 2 | #define S3_SOUND_H 3 | 4 | // External typedefs 5 | 6 | typedef float tF32; 7 | typedef struct tS3_sound_source tS3_sound_source; 8 | typedef tS3_sound_source* tS3_sound_source_ptr; 9 | typedef int tS3_sound_tag; 10 | typedef int tS3_sound_id; 11 | typedef int tS3_type; 12 | typedef int tS3_repeats; 13 | typedef int tS3_volume; 14 | typedef int tS3_effect_tag; 15 | typedef long tS3_priority; 16 | typedef long tS3_pitch; 17 | typedef long tS3_speed; 18 | typedef struct tS3_outlet tS3_outlet; 19 | typedef tS3_outlet* tS3_outlet_ptr; 20 | 21 | typedef void tS3_sample_filter(tS3_effect_tag, tS3_sound_tag); 22 | 23 | typedef struct tS3_vector3 { 24 | tF32 x; 25 | tF32 y; 26 | tF32 z; 27 | } tS3_vector3; 28 | 29 | int S3Init(char* path, int low_memory_mode); 30 | void S3Shutdown(void); 31 | 32 | void S3Disable(void); 33 | void S3Enable(void); 34 | 35 | void S3Set3DSoundEnvironment(float a1, float a2, float a3); 36 | int S3BindAmbientSoundToOutlet(tS3_outlet_ptr pOutlet, int pSound, tS3_sound_source* source, float pMax_distance, int pPeriod, int pRepeats, int pVolume, int pPitch, int pSpeed); 37 | 38 | tS3_sound_tag S3StartSound3D(tS3_outlet_ptr pOutlet, tS3_sound_id pSound, tS3_vector3* pInitial_position, tS3_vector3* pInitial_velocity, tS3_repeats pRepeats, tS3_volume pVolume, tS3_pitch pPitch, tS3_speed pSpeed); 39 | 40 | tS3_outlet_ptr S3CreateOutlet(int unk1, int pChannel_count); 41 | void S3ReleaseOutlet(tS3_outlet_ptr outlet); 42 | int S3ReleaseSound(tS3_sound_id id); 43 | int S3ReleaseSoundSource(tS3_sound_source_ptr src); 44 | 45 | int S3ChangeVolume(tS3_sound_tag pTag, tS3_volume pVolume); 46 | 47 | void S3Service(int inside_cockpit, int unk1); 48 | 49 | int S3LoadSample(tS3_sound_id id); 50 | tS3_sound_tag S3StartSound(tS3_outlet_ptr pOutlet, tS3_sound_id pSound); 51 | tS3_sound_tag S3StartSound2(tS3_outlet_ptr pOutlet, tS3_sound_id pSound, tS3_repeats pRepeats, tS3_volume pLVolume, tS3_volume pRVolume, tS3_pitch pPitch, tS3_speed pSpeed); 52 | void S3StopAllOutletSounds(void); 53 | int S3SoundStillPlaying(tS3_sound_tag pSound); 54 | int S3ChangePitchSpeed(tS3_sound_tag pTag, tS3_pitch pNew_pitch); 55 | int S3StopSound(tS3_sound_tag pSound_tag); 56 | int S3StopOutletSound(tS3_outlet_ptr pOutlet); 57 | int S3SetOutletVolume(tS3_outlet_ptr pOutlet, tS3_volume pVolume); 58 | void S3UpdateSoundSource(tS3_outlet_ptr outlet, tS3_sound_tag tag, tS3_sound_source_ptr src, float pMax_distance_squared, int pPeriod, tS3_repeats pAmbient_repeats, tS3_volume pVolume, int pPitch, tS3_speed pSpeed); 59 | 60 | int S3SetEffects(tS3_sample_filter* filter1, tS3_sample_filter* filter2); 61 | 62 | // CDA 63 | int S3CDAEnabled(void); 64 | int S3IsCDAPlaying(void); 65 | void S3EnableCDA(void); 66 | void S3DisableCDA(void); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/harness/include/harness/hooks.h: -------------------------------------------------------------------------------- 1 | #ifndef HARNESS_HOOKS_H 2 | #define HARNESS_HOOKS_H 3 | 4 | #include "brender.h" 5 | #include 6 | 7 | typedef enum tHarness_window_type { 8 | eWindow_type_software = 0, 9 | eWindow_type_opengl = 1, 10 | } tHarness_window_type; 11 | 12 | // Platform implementation functions 13 | typedef struct tHarness_platform { 14 | // Render a fullscreen quad using the specified pixel data 15 | void (*Renderer_Present)(br_pixelmap* src); 16 | // Set the 256 color palette to use (BGRA format) 17 | void (*Renderer_SetPalette)(br_colour* palette); 18 | // Get mouse button state 19 | int (*GetMouseButtons)(int* button_1, int* button_2); 20 | // Get mouse position 21 | int (*GetMousePosition)(int* pX, int* pY); 22 | // Close specified window 23 | void (*DestroyWindow)(void); 24 | // Process window messages, return any WM_QUIT message 25 | void (*ProcessWindowMessages)(void); 26 | // Set position of a window 27 | int (*SetWindowPos)(void* hWnd, int x, int y, int nWidth, int nHeight); 28 | // Show/hide the cursor 29 | int (*ShowCursor)(int show); 30 | // invoked when key is set up or down 31 | void (*SetKeyHandler)(void (*handler_func)(void)); 32 | // Get keyboard state. Argument expected to point to 32 byte buffer - 1 bit per key 33 | void (*GetKeyboardState)(br_uint_32* buffer); 34 | 35 | // Sleep 36 | void (*Sleep)(br_uint_32 dwMilliseconds); 37 | // Get ticks 38 | br_uint_32 (*GetTicks)(void); 39 | // Show error message 40 | int (*ShowErrorMessage)(char* title, char* message); 41 | 42 | // Create a window. Uses an underscore to avoid name collisions with windows.h `CreateWindow` macro 43 | void (*CreateWindow_)(const char* title, int nWidth, int nHeight, tHarness_window_type window_type); 44 | void (*Swap)(br_pixelmap* back_buffer); 45 | void (*PaletteChanged)(br_colour entries[256]); 46 | // If this platform supports OpenGL 47 | void* (*GL_GetProcAddress)(const char* name); 48 | void (*GetViewport)(int* x, int* y, float* width_multiplier, float* height_multiplier); 49 | 50 | void (*GetPrefPath)(char* path, char* app_name); 51 | 52 | } tHarness_platform; 53 | 54 | enum { 55 | ePlatform_cap_software = 0x1, 56 | ePlatform_cap_opengl = 0x2, 57 | ePlatform_cap_video_mask = ePlatform_cap_software | ePlatform_cap_opengl, 58 | }; 59 | 60 | typedef struct tPlatform_bootstrap { 61 | const char* name; 62 | const char* description; 63 | int capabilities; 64 | int (*init)(tHarness_platform* platform); 65 | } tPlatform_bootstrap; 66 | 67 | extern tHarness_platform gHarness_platform; 68 | 69 | int Harness_Init(int* argc, char* argv[]); 70 | 71 | // Hooks are called from original game code. 72 | 73 | // Filesystem hooks 74 | FILE* Harness_Hook_fopen(const char* pathname, const char* mode); 75 | 76 | // Localization 77 | int Harness_Hook_isalnum(int c); 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /src/S3/s3.h: -------------------------------------------------------------------------------- 1 | #ifndef _DOSAUDIO_H_ 2 | #define _DOSAUDIO_H_ 3 | 4 | #include "brender.h" 5 | #include "s3_defs.h" 6 | 7 | extern tS3_outlet* gS3_outlets; 8 | extern int gS3_enabled; 9 | extern int gS3_last_error; 10 | extern tS3_channel gS3_channel_template; 11 | extern tS3_sound_source* gS3_sound_sources; 12 | extern int gS3_service_time_delta; 13 | extern int gS3_inside_cockpit; 14 | 15 | int S3Init(char* path, int low_memory_mode); 16 | 17 | void S3Enable(void); 18 | void S3Disable(void); 19 | 20 | int S3OpenOutputDevices(void); 21 | int S3OpenSampleDevice(void); 22 | int S3OpenCDADevice(void); 23 | 24 | int S3OpenSampleDevice(void); 25 | void S3CloseDevices(void); 26 | tS3_outlet* S3CreateOutlet(int unk1, int pChannel_count); 27 | int S3CreateOutletChannels(tS3_outlet* outlet, int pChannel_count); 28 | void S3ReleaseOutlet(tS3_outlet* outlet); 29 | int S3UnbindChannels(tS3_outlet* outlet); 30 | void S3ReleaseUnboundChannels(void); 31 | tS3_channel* S3AllocateChannel(tS3_outlet* outlet, int priority); 32 | int S3StopChannel(tS3_channel* chan); 33 | 34 | void S3ReleaseOutlet(tS3_outlet* outlet); 35 | int S3StopOutletSound(tS3_outlet* pOutlet); 36 | void S3StopAllOutletSounds(void); 37 | 38 | int S3ReleaseSound(tS3_sound_id id); 39 | 40 | char* S3LoadSoundBankFile(char* pThe_path); 41 | int S3LoadSoundbank(const char* pSoundbank_filename, int pLow_memory_mode); 42 | 43 | void S3SoundBankReaderNextLine(tS3_soundbank_read_ctx* ctx); 44 | void S3SoundBankReaderSkipWhitespace(tS3_soundbank_read_ctx* ctx); 45 | void S3SoundBankReaderSkipToNewline(tS3_soundbank_read_ctx* ctx); 46 | void S3SoundBankReaderAdvance(tS3_soundbank_read_ctx* buffer, int bytes_read); 47 | int S3SoundBankReaderReadFilename(char** filename, tS3_soundbank_read_ctx* ctx, const char* dir_name); 48 | int S3SoundBankReadEntry(tS3_soundbank_read_ctx* ctx, char* dir_name, int low_memory_mode); 49 | 50 | tS3_descriptor* S3CreateDescriptor(void); 51 | tS3_descriptor* S3GetDescriptorByID(tS3_sound_id id); 52 | 53 | char* S3GetCurrentDir(void); 54 | 55 | void S3CalculateRandomizedFields(tS3_channel* chan, tS3_descriptor* desc); 56 | int S3IRandomBetween(int pMin, int pMax, int pDefault); 57 | int S3IRandomBetweenLog(int pMin, int pMax, int pDefault); 58 | double S3FRandomBetween(double pMin, double pMax); 59 | 60 | int S3GenerateTag(tS3_outlet* outlet); 61 | int S3ReleaseSound(tS3_sound_id id); 62 | int S3SetOutletVolume(tS3_outlet* pOutlet, tS3_volume pVolume); 63 | tS3_channel* S3GetChannelForTag(tS3_sound_tag tag); 64 | int S3ChangeVolume(tS3_sound_tag pTag, tS3_volume pVolume); 65 | 66 | void S3ServiceOutlets(void); 67 | int S3ServiceChannel(tS3_channel* chan); 68 | void S3Service(int inside_cockpit, int unk1); 69 | 70 | int S3SoundStillPlaying(tS3_sound_tag pSound); 71 | 72 | tS3_sound_source* S3CreateSoundSourceBR(br_vector3* pPosition, br_vector3* pVelocity, tS3_outlet* pBound_outlet); 73 | tS3_sound_source* S3CreateSoundSource(void* pPosition, void* pVelocity, tS3_outlet* pBound_outlet); 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/DETHRACE/common/raycast.h: -------------------------------------------------------------------------------- 1 | #ifndef _RAYCAST_H_ 2 | #define _RAYCAST_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern br_matrix34 gPick_model_to_view__raycast; // suffix added to avoid duplicate symbol 7 | extern int gBelow_face_index; 8 | extern br_scalar gCurrent_y; 9 | extern int gAbove_face_index; 10 | extern br_model* gAbove_model; 11 | extern br_model* gBelow_model; 12 | extern br_scalar gHighest_y_below; 13 | extern br_actor* gY_picking_camera; 14 | extern br_scalar gLowest_y_above; 15 | 16 | // Added, probably can be replaced with NULL 17 | extern br_model* model_unk1; 18 | extern br_material* material_unk1; 19 | 20 | int DRActorToRoot(br_actor* a, br_actor* world, br_matrix34* m); 21 | 22 | void InitRayCasting(void); 23 | 24 | // Suffix added to avoid duplicate symbol 25 | int BadDiv__raycast(br_scalar a, br_scalar b); 26 | 27 | // Suffix added to avoid duplicate symbol 28 | void DRVector2AccumulateScale__raycast(br_vector2* a, br_vector2* b, br_scalar s); 29 | 30 | // Suffix added to avoid duplicate symbol 31 | int PickBoundsTestRay__raycast(br_bounds* b, br_vector3* rp, br_vector3* rd, br_scalar t_near, br_scalar t_far, br_scalar* new_t_near, br_scalar* new_t_far); 32 | 33 | int ActorPick2D(br_actor* ap, br_model* model, br_material* material, dr_pick2d_cbfn* callback, void* arg); 34 | 35 | int DRScenePick2DXY(br_actor* world, br_actor* camera, br_pixelmap* viewport, int pick_x, int pick_y, dr_pick2d_cbfn* callback, void* arg); 36 | 37 | int DRScenePick2D(br_actor* world, br_actor* camera, dr_pick2d_cbfn* callback, void* arg); 38 | 39 | int DRModelPick2D__raycast(br_model* model, br_material* material, br_vector3* ray_pos, br_vector3* ray_dir, br_scalar t_near, br_scalar t_far, dr_modelpick2d_cbfn* callback, void* arg); 40 | 41 | // Suffix added to avoid duplicate symbol 42 | int FindHighestPolyCallBack__raycast(br_model* pModel, br_material* pMaterial, br_vector3* pRay_pos, br_vector3* pRay_dir, br_scalar pT, int pF, int pE, int pV, br_vector3* pPoint, br_vector2* pMap, void* pArg); 43 | 44 | // Suffix added to avoid duplicate symbol 45 | int FindHighestCallBack__raycast(br_actor* pActor, br_model* pModel, br_material* pMaterial, br_vector3* pRay_pos, br_vector3* pRay_dir, br_scalar pT_near, br_scalar pT_far, void* pArg); 46 | 47 | void FindBestY(br_vector3* pPosition, br_actor* gWorld, br_scalar pStarting_height, br_scalar* pNearest_y_above, br_scalar* pNearest_y_below, br_model** pNearest_above_model, br_model** pNearest_below_model, int* pNearest_above_face_index, int* pNearest_below_face_index); 48 | 49 | int FindYVerticallyBelowPolyCallBack(br_model* pModel, br_material* pMaterial, br_vector3* pRay_pos, br_vector3* pRay_dir, br_scalar pT, int pF, int pE, int pV, br_vector3* pPoint, br_vector2* pMap, void* pArg); 50 | 51 | int FindYVerticallyBelowCallBack(br_actor* pActor, br_model* pModel, br_material* pMaterial, br_vector3* pRay_pos, br_vector3* pRay_dir, br_scalar pT_near, br_scalar pT_far, void* pArg); 52 | 53 | br_scalar FindYVerticallyBelow(br_vector3* pPosition); 54 | 55 | br_scalar FindYVerticallyBelow2(br_vector3* pCast_point); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /lib/libsmacker/smk_bitstream.c: -------------------------------------------------------------------------------- 1 | /** 2 | libsmacker - A C library for decoding .smk Smacker Video files 3 | Copyright (C) 2012-2017 Greg Kennedy 4 | 5 | See smacker.h for more information. 6 | 7 | smk_bitstream.c 8 | Implements a bitstream structure, which can extract and 9 | return a bit at a time from a raw block of bytes. 10 | */ 11 | 12 | #include "smk_bitstream.h" 13 | 14 | /* malloc and friends */ 15 | #include "smk_malloc.h" 16 | 17 | /* 18 | Bitstream structure 19 | Pointer to raw block of data and a size limit. 20 | Maintains internal pointers to byte_num and bit_number. 21 | */ 22 | struct smk_bit_t 23 | { 24 | const unsigned char* buffer; 25 | unsigned long size; 26 | 27 | unsigned long byte_num; 28 | char bit_num; 29 | }; 30 | 31 | /* BITSTREAM Functions */ 32 | struct smk_bit_t* smk_bs_init(const unsigned char* b, const unsigned long size) 33 | { 34 | struct smk_bit_t* ret = NULL; 35 | 36 | /* sanity check */ 37 | smk_assert(b); 38 | 39 | /* allocate a bitstream struct */ 40 | smk_malloc(ret, sizeof(struct smk_bit_t)); 41 | 42 | /* set up the pointer to bitstream, and the size counter */ 43 | ret->buffer = b; 44 | ret->size = size; 45 | 46 | /* point to initial byte: note, smk_malloc already sets these to 0 */ 47 | /* ret->byte_num = 0; 48 | ret->bit_num = 0; */ 49 | 50 | /* return ret or NULL if error : ) */ 51 | error: 52 | return ret; 53 | } 54 | 55 | /* Reads a bit 56 | Returns -1 if error encountered */ 57 | char _smk_bs_read_1(struct smk_bit_t* bs) 58 | { 59 | unsigned char ret = -1; 60 | 61 | /* sanity check */ 62 | smk_assert(bs); 63 | 64 | /* don't die when running out of bits, but signal */ 65 | if (bs->byte_num >= bs->size) 66 | { 67 | fprintf(stderr, "libsmacker::_smk_bs_read_1(bs): ERROR: bitstream (length=%lu) exhausted.\n", bs->size); 68 | goto error; 69 | } 70 | 71 | /* get next bit and return */ 72 | ret = (((bs->buffer[bs->byte_num]) & (1 << bs->bit_num)) != 0); 73 | 74 | /* advance to next bit */ 75 | bs->bit_num ++; 76 | 77 | /* Out of bits in this byte: next! */ 78 | if (bs->bit_num > 7) 79 | { 80 | bs->byte_num ++; 81 | bs->bit_num = 0; 82 | } 83 | 84 | /* return ret, or (default) -1 if error */ 85 | error: 86 | return ret; 87 | } 88 | 89 | /* Reads a byte 90 | Returns -1 if error. */ 91 | short _smk_bs_read_8(struct smk_bit_t* bs) 92 | { 93 | unsigned char ret = -1; 94 | 95 | /* sanity check */ 96 | smk_assert(bs); 97 | 98 | /* don't die when running out of bits, but signal */ 99 | if (bs->byte_num + (bs->bit_num > 0) >= bs->size) 100 | { 101 | fprintf(stderr, "libsmacker::_smk_bs_read_8(bs): ERROR: bitstream (length=%lu) exhausted.\n", bs->size); 102 | goto error; 103 | } 104 | 105 | if (bs->bit_num) 106 | { 107 | /* unaligned read */ 108 | ret = bs->buffer[bs->byte_num] >> bs->bit_num; 109 | bs->byte_num ++; 110 | ret |= (bs->buffer[bs->byte_num] << (8 - bs->bit_num)); 111 | } else { 112 | /* aligned read */ 113 | ret = bs->buffer[bs->byte_num ++]; 114 | } 115 | 116 | /* return ret, or (default) -1 if error */ 117 | error: 118 | return ret; 119 | } 120 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: WebKit 4 | AccessModifierOffset: -4 5 | AlignAfterOpenBracket: DontAlign 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlinesLeft: false 9 | AlignOperands: false 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | AllowShortBlocksOnASingleLine: false 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: All 15 | AllowShortIfStatementsOnASingleLine: false 16 | AllowShortLoopsOnASingleLine: false 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakAfterReturnType: None 19 | AlwaysBreakBeforeMultilineStrings: false 20 | AlwaysBreakTemplateDeclarations: false 21 | BinPackArguments: true 22 | BinPackParameters: true 23 | BraceWrapping: 24 | AfterClass: false 25 | AfterControlStatement: false 26 | AfterEnum: false 27 | AfterFunction: false 28 | AfterNamespace: false 29 | AfterObjCDeclaration: false 30 | AfterStruct: false 31 | AfterUnion: false 32 | BeforeCatch: false 33 | BeforeElse: false 34 | IndentBraces: false 35 | BreakBeforeBinaryOperators: All 36 | BreakBeforeBraces: Custom 37 | BreakBeforeTernaryOperators: true 38 | BreakConstructorInitializersBeforeComma: true 39 | BreakAfterJavaFieldAnnotations: false 40 | BreakStringLiterals: true 41 | ColumnLimit: 0 42 | CommentPragmas: '^ IWYU pragma:' 43 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 44 | ConstructorInitializerIndentWidth: 4 45 | ContinuationIndentWidth: 4 46 | Cpp11BracedListStyle: false 47 | DerivePointerAlignment: false 48 | DisableFormat: false 49 | ExperimentalAutoDetectBinPacking: false 50 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 51 | IncludeCategories: 52 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 53 | Priority: 2 54 | - Regex: '^(<|"(gtest|isl|json)/)' 55 | Priority: 3 56 | - Regex: '.*' 57 | Priority: 1 58 | IncludeIsMainRegex: '$' 59 | IndentCaseLabels: false 60 | IndentWidth: 4 61 | IndentWrappedFunctionNames: false 62 | JavaScriptQuotes: Leave 63 | JavaScriptWrapImports: true 64 | KeepEmptyLinesAtTheStartOfBlocks: true 65 | MacroBlockBegin: '' 66 | MacroBlockEnd: '' 67 | MaxEmptyLinesToKeep: 1 68 | NamespaceIndentation: Inner 69 | ObjCBlockIndentWidth: 4 70 | ObjCSpaceAfterProperty: true 71 | ObjCSpaceBeforeProtocolList: true 72 | PenaltyBreakBeforeFirstCallParameter: 19 73 | PenaltyBreakComment: 300 74 | PenaltyBreakFirstLessLess: 120 75 | PenaltyBreakString: 1000 76 | PenaltyExcessCharacter: 1000000 77 | PenaltyReturnTypeOnItsOwnLine: 60 78 | PointerAlignment: Left 79 | ReflowComments: true 80 | SortIncludes: true 81 | SpaceAfterCStyleCast: false 82 | SpaceBeforeAssignmentOperators: true 83 | SpaceBeforeParens: ControlStatements 84 | SpaceInEmptyParentheses: false 85 | SpacesBeforeTrailingComments: 1 86 | SpacesInAngles: false 87 | SpacesInContainerLiterals: true 88 | SpacesInCStyleCastParentheses: false 89 | SpacesInParentheses: false 90 | SpacesInSquareBrackets: false 91 | Standard: Cpp03 92 | TabWidth: 8 93 | UseTab: Never 94 | ... 95 | 96 | -------------------------------------------------------------------------------- /src/DETHRACE/common/input.h: -------------------------------------------------------------------------------- 1 | #ifndef _INPUT_H_ 2 | #define _INPUT_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | // Variable leading zero 7 | #ifdef DETHRACE_FIX_BUGS 8 | #define VARLZEROINT "%0*d" 9 | #else 10 | #define VARLZEROINT "%0.*d" 11 | #endif 12 | 13 | extern int gEdge_trigger_mode; 14 | extern tU32 gLast_poll_keys; 15 | extern int gInsert_mode; 16 | extern int gGo_ahead_keys[3]; 17 | extern tJoy_array gJoy_array; 18 | extern tKey_array gKey_array; 19 | extern int gKey_poll_counter; 20 | extern tRolling_letter* gRolling_letters; 21 | extern int gCurrent_cursor; 22 | extern int gCurrent_position; 23 | extern int gLetter_x_coords[15]; 24 | extern int gVisible_length; 25 | extern int gLetter_y_coords[15]; 26 | extern int gThe_key; 27 | extern tU32 gLast_key_down_time; 28 | extern int gThe_length; 29 | extern tU32 gLast_roll; 30 | extern int gLast_key_down; 31 | extern int gKey_mapping[67]; 32 | extern char gCurrent_typing[110]; 33 | 34 | void SetJoystickArrays(int* pKeys, int pMark); 35 | 36 | void PollKeys(void); 37 | 38 | void CyclePollKeys(void); 39 | 40 | void ResetPollKeys(void); 41 | 42 | void CheckKeysForMouldiness(void); 43 | 44 | int EitherMouseButtonDown(void); 45 | 46 | tKey_down_result PDKeyDown2(int pKey_index); 47 | 48 | int PDKeyDown(int pKey_index); 49 | 50 | int PDKeyDown3(int pKey_index); 51 | 52 | int PDAnyKeyDown(void); 53 | 54 | int AnyKeyDown(void); 55 | 56 | tU32* KevKeyService(void); 57 | 58 | int OldKeyIsDown(int pKey_index); 59 | 60 | int KeyIsDown(int pKey_index); 61 | 62 | void WaitForNoKeys(void); 63 | 64 | void WaitForAKey(void); 65 | 66 | int CmdKeyDown(int pFKey_ID, int pCmd_key_ID); 67 | 68 | void GetMousePosition(int* pX_coord, int* pY_coord); 69 | 70 | void InitRollingLetters(void); 71 | 72 | void EndRollingLetters(void); 73 | 74 | int AddRollingLetter(char pChar, int pX, int pY, tRolling_type rolling_type); 75 | 76 | void AddRollingString(char* pStr, int pX, int pY, tRolling_type rolling_type); 77 | 78 | void AddRollingNumber(tU32 pNumber, int pWidth, int pX, int pY); 79 | 80 | void RollLettersIn(void); 81 | 82 | int ChangeCharTo(int pSlot_index, int pChar_index, char pNew_char); 83 | 84 | void ChangeTextTo(int pXcoord, int pYcoord, char* pNew_str, char* pOld_str); 85 | 86 | void SetRollingCursor(int pSlot_index); 87 | 88 | void BlankSlot(int pIndex, int pName_length, int pVisible_length); 89 | 90 | void DoRLBackspace(int pSlot_index); 91 | 92 | void DoRLDelete(int pSlot_index); 93 | 94 | void DoRLInsert(int pSlot_index); 95 | 96 | void DoRLCursorLeft(int pSlot_index); 97 | 98 | void DoRLCursorRight(int pSlot_index); 99 | 100 | void DoRLTypeLetter(int pChar, int pSlot_index); 101 | 102 | void StopTyping(int pSlot_index); 103 | 104 | void RevertTyping(int pSlot_index, char* pRevert_str); 105 | 106 | void StartTyping(int pSlot_index, char* pText, int pVisible_length); 107 | 108 | void TypeKey(int pSlot_index, char pKey); 109 | 110 | void SetSlotXY(int pSlot_index, int pX_coord, int pY_coord); 111 | 112 | void GetTypedName(char* pDestn, int pMax_length); 113 | 114 | void KillCursor(int pSlot_index); 115 | 116 | void EdgeTriggerModeOn(void); 117 | 118 | void EdgeTriggerModeOff(void); 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /lib/libsmacker/smk_hufftree.h: -------------------------------------------------------------------------------- 1 | /** 2 | libsmacker - A C library for decoding .smk Smacker Video files 3 | Copyright (C) 2012-2017 Greg Kennedy 4 | 5 | See smacker.h for more information. 6 | 7 | smk_hufftree.h 8 | SMK huffmann trees. There are two types: 9 | - a basic 8-bit tree, and 10 | - a "big" 16-bit tree which includes a cache for recently 11 | searched values. 12 | */ 13 | 14 | #ifndef SMK_HUFFTREE_H 15 | #define SMK_HUFFTREE_H 16 | 17 | #include "smk_bitstream.h" 18 | 19 | /** Tree node structures - Forward declaration */ 20 | struct smk_huff8_t; 21 | struct smk_huff16_t; 22 | 23 | /*********************** 8-BIT HUFF-TREE FUNCTIONS ***********************/ 24 | /** This macro checks return code from _smk_huff8_build and 25 | jumps to error label if problems occur. */ 26 | #define smk_huff8_build(bs,t) \ 27 | { \ 28 | if (!(t = _smk_huff8_build(bs))) \ 29 | { \ 30 | fprintf(stderr, "libsmacker::smk_huff8_build(" #bs ", " #t ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \ 31 | goto error; \ 32 | } \ 33 | } 34 | /** Build an 8-bit tree from a bitstream */ 35 | struct smk_huff8_t* _smk_huff8_build(struct smk_bit_t* bs); 36 | 37 | /** This macro checks return code from _smk_huff8_lookup and 38 | jumps to error label if problems occur. */ 39 | #define smk_huff8_lookup(bs,t,s) \ 40 | { \ 41 | if ((short)(s = _smk_huff8_lookup(bs, t)) < 0) \ 42 | { \ 43 | fprintf(stderr, "libsmacker::smk_huff8_lookup(" #bs ", " #t ", " #s ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \ 44 | goto error; \ 45 | } \ 46 | } 47 | /** Look up an 8-bit value in the referenced tree by following a bitstream 48 | returns -1 on error */ 49 | short _smk_huff8_lookup(struct smk_bit_t* bs, const struct smk_huff8_t* t); 50 | 51 | /** function to recursively delete an 8-bit huffman tree */ 52 | void smk_huff8_free(struct smk_huff8_t* t); 53 | 54 | /************************ 16-BIT HUFF-TREE FUNCTIONS ************************/ 55 | /** This macro checks return code from _smk_huff16_build and 56 | jumps to error label if problems occur. */ 57 | #define smk_huff16_build(bs,t) \ 58 | { \ 59 | if (!(t = _smk_huff16_build(bs))) \ 60 | { \ 61 | fprintf(stderr, "libsmacker::smk_huff16_build(" #bs ", " #t ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \ 62 | goto error; \ 63 | } \ 64 | } 65 | /** Build a 16-bit tree from a bitstream */ 66 | struct smk_huff16_t* _smk_huff16_build(struct smk_bit_t* bs); 67 | 68 | /** This macro checks return code from smk_huff16_lookup and 69 | jumps to error label if problems occur. */ 70 | #define smk_huff16_lookup(bs,t,s) \ 71 | { \ 72 | if ((s = _smk_huff16_lookup(bs, t)) < 0) \ 73 | { \ 74 | fprintf(stderr, "libsmacker::smk_huff16_lookup(" #bs ", " #t ", " #s ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \ 75 | goto error; \ 76 | } \ 77 | } 78 | /** Look up a 16-bit value in the bigtree by following a bitstream 79 | returns -1 on error */ 80 | long _smk_huff16_lookup(struct smk_bit_t* bs, struct smk_huff16_t* big); 81 | 82 | /** Reset the cache in a 16-bit tree */ 83 | void smk_huff16_reset(struct smk_huff16_t* big); 84 | 85 | /** function to recursively delete a 16-bit huffman tree */ 86 | void smk_huff16_free(struct smk_huff16_t* big); 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /src/harness/cameras/debug_camera.c: -------------------------------------------------------------------------------- 1 | #include "cameras/debug_camera.h" 2 | #include 3 | 4 | mat4 view, projection; 5 | vec3 cam_pos = { 0, 0, 0 }; 6 | vec3 cam_front = { 0, 0, -1 }; 7 | vec3 cam_up = { 0, 1, 0 }; 8 | float cam_speed = 0.5f; 9 | 10 | float vc[4][4] = { 11 | { 0.45397636, 0.0, 0.89101368, 0 }, { 0.1117821, 0.99209929, -0.056953594, 0 }, { -0.88397402, 0.12545498, 0.45038962, 0 }, { -69.239441, 20.735441, -52.417336, 1 } 12 | }; 13 | 14 | float lastX = 400, lastY = 300; 15 | int firstMouse = 1; 16 | float yaw = 0, pitch = 0; 17 | 18 | int gDebugCamera_active = 0; 19 | 20 | void DebugCamera_Update(void) { 21 | const Uint8* state = SDL_GetKeyboardState(NULL); 22 | if (state[SDL_SCANCODE_UP]) { 23 | vec3 s; 24 | glm_vec3_scale(cam_front, cam_speed, s); 25 | glm_vec3_add(cam_pos, s, cam_pos); 26 | } 27 | if (state[SDL_SCANCODE_DOWN]) { 28 | vec3 s; 29 | glm_vec3_scale(cam_front, -cam_speed, s); 30 | glm_vec3_add(cam_pos, s, cam_pos); 31 | } 32 | if (state[SDL_SCANCODE_LEFT]) { 33 | vec3 cr; 34 | glm_cross(cam_front, cam_up, cr); 35 | glm_normalize(cr); 36 | glm_vec3_scale(cr, cam_speed, cr); 37 | glm_vec3_add(cam_pos, cr, cam_pos); 38 | } 39 | if (state[SDL_SCANCODE_RIGHT]) { 40 | vec3 cr; 41 | glm_cross(cam_front, cam_up, cr); 42 | glm_normalize(cr); 43 | glm_vec3_scale(cr, -cam_speed, cr); 44 | glm_vec3_add(cam_pos, cr, cam_pos); 45 | } 46 | if (state[SDL_SCANCODE_F12]) { 47 | gDebugCamera_active = !gDebugCamera_active; 48 | // if (!gDebugCamera_active) { 49 | // printf("DEBUGCAMERAACTIVE\n"); 50 | // gDebugCamera_active = 1; 51 | // } 52 | } 53 | 54 | int xpos, ypos; 55 | SDL_GetMouseState(&xpos, &ypos); 56 | 57 | if (firstMouse) { 58 | lastX = xpos; 59 | lastY = ypos; 60 | firstMouse = false; 61 | } 62 | 63 | float xoffset = xpos - lastX; 64 | float yoffset = lastY - ypos; 65 | lastX = xpos; 66 | lastY = ypos; 67 | 68 | float sensitivity = 0.7f; 69 | xoffset *= sensitivity; 70 | yoffset *= sensitivity; 71 | 72 | yaw += xoffset; 73 | pitch += yoffset; 74 | 75 | if (pitch > 89.0f) 76 | pitch = 89.0f; 77 | if (pitch < -89.0f) 78 | pitch = -89.0f; 79 | 80 | vec3 direction; 81 | direction[0] = cos(glm_rad(yaw)) * cos(glm_rad(pitch)); 82 | direction[1] = sin(glm_rad(pitch)); 83 | direction[2] = sin(glm_rad(yaw)) * cos(glm_rad(pitch)); 84 | glm_normalize_to(direction, cam_front); 85 | } 86 | 87 | extern float gCamera_hither; 88 | extern float gCamera_yon; 89 | 90 | float* DebugCamera_Projection(void) { 91 | glm_perspective(glm_rad(55.55), 320.0f / 200.0f /*4.0f / 3.0f*/, gCamera_hither, gCamera_yon, projection); 92 | return (float*)&projection; 93 | } 94 | 95 | float* DebugCamera_View(void) { 96 | vec3 look; 97 | glm_vec3_add(cam_pos, cam_front, look); 98 | glm_lookat(cam_pos, look, cam_up, view); 99 | return (float*)&view; 100 | } 101 | 102 | void DebugCamera_SetPosition(float x, float y, float z) { 103 | if (cam_pos[0] == 0) { 104 | cam_pos[0] = x; 105 | cam_pos[1] = y; 106 | cam_pos[2] = z; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/DETHRACE/common/netgame.h: -------------------------------------------------------------------------------- 1 | #ifndef _NETGAME_H_ 2 | #define _NETGAME_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern int gPowerup_cost[4]; 7 | extern int gGame_scores[6]; 8 | extern int gPed_target; 9 | extern int gNot_shown_race_type_headup; 10 | extern tU32 gLast_it_change; 11 | extern tU32 gTime_for_punishment; 12 | extern tNet_game_player_info* gLast_lepper; 13 | extern int gInitialised_grid; 14 | extern int gIt_or_fox; 15 | 16 | void SendCarData(tU32 pNext_frame_time); 17 | 18 | void ReceivedRecover(tNet_contents* pContents); 19 | 20 | void CopyMechanics(tCar_spec* pCar, tNet_contents* pContents); 21 | 22 | void ReceivedMechanics(tNet_contents* pContents); 23 | 24 | void ReceivedCopInfo(tNet_contents* pContents); 25 | 26 | void SendAllNonCarPositions(void); 27 | 28 | void ReceivedNonCarPosition(tNet_contents* pContents); 29 | 30 | void ReceivedNonCar(tNet_contents* pContents); 31 | 32 | void SignalToStartRace2(int pIndex); 33 | 34 | void SignalToStartRace(void); 35 | 36 | void SetUpNetCarPositions(void); 37 | 38 | void ReinitialiseCar(tCar_spec* pCar); 39 | 40 | void RepositionPlayer(int pIndex); 41 | 42 | void DisableCar(tCar_spec* pCar); 43 | 44 | void EnableCar(tCar_spec* pCar); 45 | 46 | void DoNetworkHeadups(int pCredits); 47 | 48 | int SortNetHeadAscending(void* pFirst_one, void* pSecond_one); 49 | 50 | int SortNetHeadDescending(void* pFirst_one, void* pSecond_one); 51 | 52 | void ClipName(char* pName, tDR_font* pFont, int pMax_width); 53 | 54 | void DoNetScores2(int pOnly_sort_scores); 55 | 56 | void DoNetScores(void); 57 | 58 | void InitNetHeadups(void); 59 | 60 | void DisposeNetHeadups(void); 61 | 62 | void EverybodysLost(void); 63 | 64 | void DeclareWinner(int pWinner_index); 65 | 66 | void PlayerIsIt(tNet_game_player_info* pPlayer); 67 | 68 | int FarEnoughAway(tNet_game_player_info* pPlayer_1, tNet_game_player_info* pPlayer_2); 69 | 70 | void CarInContactWithItOrFox(tNet_game_player_info* pPlayer); 71 | 72 | void SelectRandomItOrFox(int pNot_this_one); 73 | 74 | void CalcPlayerScores(void); 75 | 76 | void SendPlayerScores(void); 77 | 78 | void DoNetGameManagement(void); 79 | 80 | void InitialisePlayerScore(tNet_game_player_info* pPlayer); 81 | 82 | void InitPlayers(void); 83 | 84 | void BuyPSPowerup(int pIndex); 85 | 86 | void BuyArmour(void); 87 | 88 | void BuyPower(void); 89 | 90 | void BuyOffense(void); 91 | 92 | void UseGeneralScore(int pScore); 93 | 94 | void NetSendEnvironmentChanges(tNet_game_player_info* pPlayer); 95 | 96 | void UpdateEnvironments(void); 97 | 98 | void ReceivedGameplay(tNet_contents* pContents, tNet_message* pMessage, tU32 pReceive_time); 99 | 100 | void SendGameplay(tPlayer_ID pPlayer, tNet_gameplay_mess pMess, int pParam_1, int pParam_2, int pParam_3, int pParam_4); 101 | 102 | void SendGameplayToAllPlayers(tNet_gameplay_mess pMess, int pParam_1, int pParam_2, int pParam_3, int pParam_4); 103 | 104 | void SendGameplayToHost(tNet_gameplay_mess pMess, int pParam_1, int pParam_2, int pParam_3, int pParam_4); 105 | 106 | void InitNetGameplayStuff(void); 107 | 108 | void DefaultNetName(void); 109 | 110 | void NetSendPointCrush(tCar_spec* pCar, tU16 pCrush_point_index, br_vector3* pEnergy_vector); 111 | 112 | void RecievedCrushPoint(tNet_contents* pContents); 113 | 114 | void GetReducedMatrix(tReduced_matrix* m1, br_matrix34* m2); 115 | 116 | void GetExpandedMatrix(br_matrix34* m1, tReduced_matrix* m2); 117 | 118 | void NetEarnCredits(tNet_game_player_info* pPlayer, tS32 pCredits); 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | ### July 2024 5 | - Support for CD audio added [PR](https://github.com/dethrace-labs/dethrace/pull/393) 6 | 7 | ### June 2024 8 | - Reverse engineered BRender code replaced with now-open-sourced [BRender-v1.3.2](https://github.com/dethrace-labs/BRender-v1.3.2) 9 | - Replaced home-made OpenGL renderer with BRender software renderer 10 | - [PR](https://github.com/dethrace-labs/dethrace/pull/363) 11 | 12 | ### July 2023 13 | - First cut of network code 14 | 15 | ### May 2023 16 | - Fixed multi-channel audio which worked in the original DOS code, but was broken in the original win95 code [PR](https://github.com/dethrace-labs/dethrace/pull/329) 17 | 18 | ### November 2022 19 | - Action Replay mode added. [PR](https://github.com/dethrace-labs/dethrace/pull/230) 20 | 21 | ### October 2022 22 | - "hires" SVGA 640x480 mode added. [PR](https://github.com/dethrace-labs/dethrace/pull/217) 23 | ### June 2022 24 | - Audio added, thanks to [miniaudio](https://miniaud.io/). [PR](https://github.com/dethrace-labs/dethrace/pull/130) 25 | 26 | ### May 2022 27 | - Pedestrians added! [PR](https://github.com/dethrace-labs/dethrace/pull/118) 28 | 29 | ### April 2022 30 | - Vehicle damage added. [PR](https://github.com/dethrace-labs/dethrace/pull/116) 31 | 32 | ### March 2022 33 | - Fog depth effects added. This really gives a boost to looking like the original game now. [PR](https://github.com/dethrace-labs/dethrace/pull/95) 34 | 35 | ### January 2022 36 | - Texturing implemented, no more ghostly shades of grey for everything! [PR](https://github.com/dethrace-labs/dethrace/pull/69) 37 | 38 | ### September 2021 39 | - Vehicle physics are implemented enough to drive around parts of the tracks [PR](https://github.com/dethrace-labs/dethrace/pull/57) 40 | 41 | ### July 17 2021 42 | - 3d rendering somewhat implemented. Flat shaded, no textures, but camera, cars and track are visible in the right place! 43 | 44 | ### April 21 2021 45 | - Actual game main loop running! Rendering, phyiscs, sound etc commented out, so all we can see is a black screen with the 2d rendering. 46 | 47 | ### March 24 2021 48 | - Menu screens up to and including race and car selection implemented 49 | - Fixed OpenGL crashes by moving back to single thread 50 | 51 | ### September 3 2020 52 | - Cutscenes displayed on startup. 53 | - Main menu renders and responds to key up and down events. Hitting "enter" on any option causes a crash 54 | 55 | ### July 6 2020 56 | - OpenGL renderer added. Shows nothing but a black screen then exits. 57 | 58 | ### November 25, 2019 59 | - First unit tests added and hooked up to the CI build pipeline 60 | 61 | ### November 18, 2019 62 | - c skeleton compiles for the first time on OSX and Linux! 63 | 64 | ### November 14, 2019 65 | - First [commit](https://github.com/jeff-1amstudios/dethrace/pull/9) of the correct generated c skeleton. It does not compile. 66 | 67 | ### November 12, 2019 68 | - A [bug fix](https://github.com/jeff-1amstudios/open-watcom-v2/commit/1a00368a6c5d8dddb1d27f972ef21e399dd48b60) in Watcom `exedump` finally allowed fully correct function args to be identified 69 | 70 | ### October 27, 2018 71 | - crayzkirk has been working with IDA to match up the symbols by hand from an older build to the released binary 72 | 73 | ### March 18, 2017 74 | - crayzkirk finds richer debug information by using Watcom `exedump` tool 75 | 76 | ### December 14, 2014 77 | - Carmageddon Watcom debug symbols [discovered and dumped](http://1amstudios.com/2014/12/02/carma1-symbols-dumped/) 78 | -------------------------------------------------------------------------------- /src/DETHRACE/pc-dos/scancodes.h: -------------------------------------------------------------------------------- 1 | #ifndef SCANCODES_H 2 | #define SCANCODES_H 3 | 4 | #define SCANCODE_ESCAPE 0x01 5 | #define SCANCODE_1 0x02 6 | #define SCANCODE_2 0x03 7 | #define SCANCODE_3 0x04 8 | #define SCANCODE_4 0x05 9 | #define SCANCODE_5 0x06 10 | #define SCANCODE_6 0x07 11 | #define SCANCODE_7 0x08 12 | #define SCANCODE_8 0x09 13 | #define SCANCODE_9 0x0A 14 | #define SCANCODE_0 0x0B 15 | #define SCANCODE_MINUS 0x0C /* - on main keyboard */ 16 | #define SCANCODE_EQUALS 0x0D 17 | #define SCANCODE_BACK 0x0E /* backspace */ 18 | #define SCANCODE_TAB 0x0F 19 | #define SCANCODE_Q 0x10 20 | #define SCANCODE_W 0x11 21 | #define SCANCODE_E 0x12 22 | #define SCANCODE_R 0x13 23 | #define SCANCODE_T 0x14 24 | #define SCANCODE_Y 0x15 25 | #define SCANCODE_U 0x16 26 | #define SCANCODE_I 0x17 27 | #define SCANCODE_O 0x18 28 | #define SCANCODE_P 0x19 29 | #define SCANCODE_LBRACKET 0x1A 30 | #define SCANCODE_RBRACKET 0x1B 31 | #define SCANCODE_RETURN 0x1C /* Enter on main keyboard */ 32 | #define SCANCODE_LCONTROL 0x1D 33 | #define SCANCODE_A 0x1E 34 | #define SCANCODE_S 0x1F 35 | #define SCANCODE_D 0x20 36 | #define SCANCODE_F 0x21 37 | #define SCANCODE_G 0x22 38 | #define SCANCODE_H 0x23 39 | #define SCANCODE_J 0x24 40 | #define SCANCODE_K 0x25 41 | #define SCANCODE_L 0x26 42 | #define SCANCODE_SEMICOLON 0x27 43 | #define SCANCODE_APOSTROPHE 0x28 44 | #define SCANCODE_GRAVE 0x29 45 | #define SCANCODE_LSHIFT 0x2A 46 | #define SCANCODE_BACKSLASH 0x2B 47 | #define SCANCODE_Z 0x2C 48 | #define SCANCODE_X 0x2D 49 | #define SCANCODE_C 0x2E 50 | #define SCANCODE_V 0x2F 51 | #define SCANCODE_B 0x30 52 | #define SCANCODE_N 0x31 53 | #define SCANCODE_M 0x32 54 | #define SCANCODE_COMMA 0x33 55 | #define SCANCODE_PERIOD 0x34 56 | #define SCANCODE_SLASH 0x35 57 | #define SCANCODE_RSHIFT 0x36 58 | #define SCANCODE_MULTIPLY 0x37 /* * on numeric keypad */ 59 | #define SCANCODE_LALT 0x38 60 | #define SCANCODE_SPACE 0x39 61 | #define SCANCODE_CAPITAL 0x3A 62 | #define SCANCODE_F1 0x3B 63 | #define SCANCODE_F2 0x3C 64 | #define SCANCODE_F3 0x3D 65 | #define SCANCODE_F4 0x3E 66 | #define SCANCODE_F5 0x3F 67 | #define SCANCODE_F6 0x40 68 | #define SCANCODE_F7 0x41 69 | #define SCANCODE_F8 0x42 70 | #define SCANCODE_F9 0x43 71 | #define SCANCODE_F10 0x44 72 | #define SCANCODE_NUMLOCK 0x45 73 | #define SCANCODE_SCROLL 0x46 74 | #define SCANCODE_NUMPAD7 0x47 75 | #define SCANCODE_NUMPAD8 0x48 76 | #define SCANCODE_NUMPAD9 0x49 77 | #define SCANCODE_SUBTRACT 0x4A /* - on numeric keypad */ 78 | #define SCANCODE_NUMPAD4 0x4B 79 | #define SCANCODE_NUMPAD5 0x4C 80 | #define SCANCODE_NUMPAD6 0x4D 81 | #define SCANCODE_ADD 0x4E /* + on numeric keypad */ 82 | #define SCANCODE_NUMPAD1 0x4F 83 | #define SCANCODE_NUMPAD2 0x50 84 | #define SCANCODE_NUMPAD3 0x51 85 | #define SCANCODE_NUMPAD0 0x52 86 | #define SCANCODE_DECIMAL 0x53 /* . on numeric keypad */ 87 | #define SCANCODE_OEM_102 0x56 /* <> or \| on RT 102-key keyboard (Non-U.S.) */ 88 | #define SCANCODE_F11 0x57 89 | #define SCANCODE_F12 0x58 90 | #define SCANCODE_NUMPADENTER 0x9C /* Enter on numeric keypad */ 91 | #define SCANCODE_RCONTROL 0x9D 92 | #define SCANCODE_DIVIDE 0xB5 /* / on numeric keypad */ 93 | #define SCANCODE_RALT 0xB8 94 | #define SCANCODE_PAUSE 0xC5 95 | #define SCANCODE_HOME 0xC7 96 | #define SCANCODE_UP 0xC8 97 | #define SCANCODE_PGUP 0xC9 98 | #define SCANCODE_LEFT 0xCB 99 | #define SCANCODE_RIGHT 0xCD 100 | #define SCANCODE_END 0xCF 101 | #define SCANCODE_DOWN 0xD0 102 | #define SCANCODE_PGDN 0xD1 103 | #define SCANCODE_INSERT 0xD2 104 | #define SCANCODE_DELETE 0xD3 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /src/harness/platforms/sdl2_syms.h: -------------------------------------------------------------------------------- 1 | #ifndef sdl2_syms_h 2 | #define sdl2_syms_h 3 | 4 | #include 5 | 6 | #define FOREACH_SDL2_SYM(X) \ 7 | X(Init, int, (Uint32)) \ 8 | X(Quit, void, (void)) \ 9 | X(Delay, void, (Uint32)) \ 10 | X(GetTicks, Uint32, (void)) \ 11 | X(GetError, const char*, (void)) \ 12 | X(PollEvent, int, (SDL_Event*)) \ 13 | X(ShowSimpleMessageBox, int, (Uint32, const char*, const char*, SDL_Window*)) \ 14 | X(CreateWindow, SDL_Window*, (const char*, int, int, int, int, Uint32)) \ 15 | X(DestroyWindow, void, (SDL_Window*)) \ 16 | X(GetWindowFlags, Uint32, (SDL_Window*)) \ 17 | X(GetWindowID, Uint32, (SDL_Window*)) \ 18 | X(GetWindowSize, void, (SDL_Window*, int*, int*)) \ 19 | X(SetWindowFullscreen, int, (SDL_Window*, Uint32)) \ 20 | X(SetWindowSize, void, (SDL_Window*, int, int)) \ 21 | X(CreateRenderer, SDL_Renderer*, (SDL_Window*, int, Uint32)) \ 22 | X(RenderClear, int, (SDL_Renderer*)) \ 23 | X(RenderCopy, int, (SDL_Renderer*, SDL_Texture*, const SDL_Rect*, const SDL_Rect*)) \ 24 | X(RenderPresent, void, (SDL_Renderer*)) \ 25 | X(RenderWindowToLogical, void, (SDL_Renderer*, int, int, float*, float*)) \ 26 | X(GetRendererInfo, int, (SDL_Renderer*, SDL_RendererInfo*)) \ 27 | X(RenderSetLogicalSize, int, (SDL_Renderer*, int, int)) \ 28 | X(SetRenderDrawBlendMode, int, (SDL_Renderer*, SDL_BlendMode)) \ 29 | X(CreateTexture, SDL_Texture*, (SDL_Renderer*, Uint32, int, int, int)) \ 30 | X(LockTexture, int, (SDL_Texture*, const SDL_Rect*, void**, int*)) \ 31 | X(UnlockTexture, void, (SDL_Texture*)) \ 32 | X(GetMouseFocus, SDL_Window*, (void)) \ 33 | X(GetMouseState, Uint32, (int*, int*)) \ 34 | X(ShowCursor, int, (int)) \ 35 | X(GetPixelFormatName, const char*, (Uint32)) \ 36 | X(GetScancodeName, const char*, (SDL_Scancode)) \ 37 | X(GL_CreateContext, SDL_GLContext, (SDL_Window*)) \ 38 | X(GL_GetProcAddress, void*, (const char*)) \ 39 | X(GL_SetAttribute, int, (SDL_GLattr, int)) \ 40 | X(GL_SetSwapInterval, int, (int)) \ 41 | X(GL_SwapWindow, void, (SDL_Window*)) \ 42 | X(GetPrefPath, char*, (const char* org, const char* app)) \ 43 | X(free, void, (void*)) 44 | 45 | #undef SDL2_SYM 46 | 47 | #endif /* sdl2_syms_h */ 48 | -------------------------------------------------------------------------------- /src/harness/dethrace_scancodes.h: -------------------------------------------------------------------------------- 1 | #ifndef DETHRACE_SCANCODES_H 2 | #define DETHRACE_SCANCODES_H 3 | 4 | // These are copied from `KeyBegin` 5 | // todo: remove duplication 6 | 7 | #define SCANCODE_ESCAPE 0x01 8 | #define SCANCODE_1 0x02 9 | #define SCANCODE_2 0x03 10 | #define SCANCODE_3 0x04 11 | #define SCANCODE_4 0x05 12 | #define SCANCODE_5 0x06 13 | #define SCANCODE_6 0x07 14 | #define SCANCODE_7 0x08 15 | #define SCANCODE_8 0x09 16 | #define SCANCODE_9 0x0A 17 | #define SCANCODE_0 0x0B 18 | #define SCANCODE_MINUS 0x0C /* - on main keyboard */ 19 | #define SCANCODE_EQUALS 0x0D 20 | #define SCANCODE_BACK 0x0E /* backspace */ 21 | #define SCANCODE_TAB 0x0F 22 | #define SCANCODE_Q 0x10 23 | #define SCANCODE_W 0x11 24 | #define SCANCODE_E 0x12 25 | #define SCANCODE_R 0x13 26 | #define SCANCODE_T 0x14 27 | #define SCANCODE_Y 0x15 28 | #define SCANCODE_U 0x16 29 | #define SCANCODE_I 0x17 30 | #define SCANCODE_O 0x18 31 | #define SCANCODE_P 0x19 32 | #define SCANCODE_LBRACKET 0x1A 33 | #define SCANCODE_RBRACKET 0x1B 34 | #define SCANCODE_RETURN 0x1C /* Enter on main keyboard */ 35 | #define SCANCODE_LCONTROL 0x1D 36 | #define SCANCODE_A 0x1E 37 | #define SCANCODE_S 0x1F 38 | #define SCANCODE_D 0x20 39 | #define SCANCODE_F 0x21 40 | #define SCANCODE_G 0x22 41 | #define SCANCODE_H 0x23 42 | #define SCANCODE_J 0x24 43 | #define SCANCODE_K 0x25 44 | #define SCANCODE_L 0x26 45 | #define SCANCODE_SEMICOLON 0x27 46 | #define SCANCODE_APOSTROPHE 0x28 47 | #define SCANCODE_GRAVE 0x29 48 | #define SCANCODE_LSHIFT 0x2A 49 | #define SCANCODE_BACKSLASH 0x2B 50 | #define SCANCODE_Z 0x2C 51 | #define SCANCODE_X 0x2D 52 | #define SCANCODE_C 0x2E 53 | #define SCANCODE_V 0x2F 54 | #define SCANCODE_B 0x30 55 | #define SCANCODE_N 0x31 56 | #define SCANCODE_M 0x32 57 | #define SCANCODE_COMMA 0x33 58 | #define SCANCODE_PERIOD 0x34 59 | #define SCANCODE_SLASH 0x35 60 | #define SCANCODE_RSHIFT 0x36 61 | #define SCANCODE_MULTIPLY 0x37 /* * on numeric keypad */ 62 | #define SCANCODE_LALT 0x38 63 | #define SCANCODE_SPACE 0x39 64 | #define SCANCODE_CAPITAL 0x3A 65 | #define SCANCODE_F1 0x3B 66 | #define SCANCODE_F2 0x3C 67 | #define SCANCODE_F3 0x3D 68 | #define SCANCODE_F4 0x3E 69 | #define SCANCODE_F5 0x3F 70 | #define SCANCODE_F6 0x40 71 | #define SCANCODE_F7 0x41 72 | #define SCANCODE_F8 0x42 73 | #define SCANCODE_F9 0x43 74 | #define SCANCODE_F10 0x44 75 | #define SCANCODE_NUMLOCK 0x45 76 | #define SCANCODE_SCROLL 0x46 77 | #define SCANCODE_NUMPAD7 0x47 78 | #define SCANCODE_NUMPAD8 0x48 79 | #define SCANCODE_NUMPAD9 0x49 80 | #define SCANCODE_SUBTRACT 0x4A /* - on numeric keypad */ 81 | #define SCANCODE_NUMPAD4 0x4B 82 | #define SCANCODE_NUMPAD5 0x4C 83 | #define SCANCODE_NUMPAD6 0x4D 84 | #define SCANCODE_ADD 0x4E /* + on numeric keypad */ 85 | #define SCANCODE_NUMPAD1 0x4F 86 | #define SCANCODE_NUMPAD2 0x50 87 | #define SCANCODE_NUMPAD3 0x51 88 | #define SCANCODE_NUMPAD0 0x52 89 | #define SCANCODE_DECIMAL 0x53 /* . on numeric keypad */ 90 | #define SCANCODE_OEM_102 0x56 /* <> or \| on RT 102-key keyboard (Non-U.S.) */ 91 | #define SCANCODE_F11 0x57 92 | #define SCANCODE_F12 0x58 93 | #define SCANCODE_NUMPADENTER 0x9C /* Enter on numeric keypad */ 94 | #define SCANCODE_RCONTROL 0x9D 95 | #define SCANCODE_DIVIDE 0xB5 /* / on numeric keypad */ 96 | #define SCANCODE_RALT 0xB8 97 | #define SCANCODE_PAUSE 0xC5 98 | #define SCANCODE_HOME 0xC7 99 | #define SCANCODE_UP 0xC8 100 | #define SCANCODE_PGUP 0xC9 101 | #define SCANCODE_LEFT 0xCB 102 | #define SCANCODE_RIGHT 0xCD 103 | #define SCANCODE_END 0xCF 104 | #define SCANCODE_DOWN 0xD0 105 | #define SCANCODE_PGDN 0xD1 106 | #define SCANCODE_INSERT 0xD2 107 | #define SCANCODE_DELETE 0xD3 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /src/DETHRACE/common/sound.h: -------------------------------------------------------------------------------- 1 | #ifndef _SOUND_H_ 2 | #define _SOUND_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern int gSound_detail_level; 7 | extern int gVirgin_pass; 8 | extern int gOld_sound_detail_level; 9 | extern int gLast_tune; 10 | extern int gRandom_MIDI_tunes[3]; 11 | extern int gRandom_Rockin_MIDI_tunes[3]; 12 | extern int gRandom_CDA_tunes[8]; 13 | extern int gCDA_is_playing; 14 | extern int gServicing_sound; 15 | extern int gSong_repeat_count; 16 | extern int gSound_sources_inited; 17 | extern int gMusic_available; 18 | extern tS3_sound_tag gCDA_tag; 19 | extern int gCD_fully_installed; 20 | extern tS3_outlet_ptr gEffects_outlet; 21 | extern tS3_outlet_ptr gCar_outlet; 22 | extern tS3_outlet_ptr gEngine_outlet; 23 | extern tS3_outlet_ptr gDriver_outlet; 24 | extern tS3_outlet_ptr gPedestrians_outlet; 25 | extern tS3_outlet_ptr gMusic_outlet; 26 | extern tS3_sound_id gMIDI_id; 27 | extern tS3_outlet_ptr gIndexed_outlets[6]; 28 | extern tU32 gLast_sound_service; 29 | extern int gCD_is_disabled; 30 | extern br_vector3 gCamera_left; 31 | extern br_vector3 gCamera_position; 32 | extern br_vector3 gOld_camera_position; 33 | extern br_vector3 gCamera_velocity; 34 | 35 | void UsePathFileToDetermineIfFullInstallation(void); 36 | 37 | void InitSound(void); 38 | 39 | tS3_sound_tag DRS3StartSound(tS3_outlet_ptr pOutlet, tS3_sound_id pSound); 40 | 41 | tS3_sound_tag DRS3StartSoundNoPiping(tS3_outlet_ptr pOutlet, tS3_sound_id pSound); 42 | 43 | tS3_sound_tag DRS3StartSound2(tS3_outlet_ptr pOutlet, tS3_sound_id pSound, tS3_repeats pRepeats, tS3_volume pLVolume, tS3_volume pRVolume, tS3_pitch pPitch, tS3_speed pSpeed); 44 | 45 | int DRS3ChangeVolume(tS3_sound_tag pSound_tag, tS3_volume pNew_volume); 46 | 47 | int DRS3ChangeLRVolume(tS3_sound_tag pSound_tag, tS3_volume pNew_Lvolume, tS3_volume pNew_Rvolume); 48 | 49 | int DRS3ChangePitch(tS3_sound_tag pTag, tS3_pitch pNew_pitch); 50 | 51 | int DRS3ChangeSpeed(tS3_sound_tag pTag, tS3_pitch pNew_speed); 52 | 53 | int DRS3ChangePitchSpeed(tS3_sound_tag pTag, tS3_pitch pNew_pitch); 54 | 55 | int DRS3StopSound(tS3_sound_tag pSound_tag); 56 | 57 | int DRS3LoadSound(tS3_sound_id pThe_sound); 58 | 59 | int DRS3ReleaseSound(tS3_sound_id pThe_sound); 60 | 61 | void DRS3Service(void); 62 | 63 | int DRS3OutletSoundsPlaying(tS3_outlet_ptr pOutlet); 64 | 65 | int DRS3SoundStillPlaying(tS3_sound_tag pSound_tag); 66 | 67 | void DRS3ShutDown(void); 68 | 69 | int DRS3SetOutletVolume(tS3_outlet_ptr pOutlet, tS3_volume pVolume); 70 | 71 | int DRS3OverallVolume(tS3_volume pVolume); 72 | 73 | int DRS3StopOutletSound(tS3_outlet_ptr pOutlet); 74 | 75 | int DRS3StopAllOutletSounds(void); 76 | 77 | void ToggleSoundEnable(void); 78 | 79 | void SoundService(void); 80 | 81 | void InitSoundSources(void); 82 | 83 | void DisposeSoundSources(void); 84 | 85 | tS3_sound_tag DRS3StartSound3D(tS3_outlet_ptr pOutlet, tS3_sound_id pSound, br_vector3* pInitial_position, br_vector3* pInitial_velocity, tS3_repeats pRepeats, tS3_volume pVolume, tS3_pitch pPitch, tS3_speed pSpeed); 86 | 87 | tS3_sound_tag DRS3StartSoundFromSource3(tS3_sound_source_ptr pSource, tS3_sound_id pSound, tS3_repeats pRepeats, tS3_volume pVolume, tS3_pitch pPitch, tS3_speed pSpeed); 88 | 89 | tS3_sound_tag DRS3StartSoundFromSource(tS3_sound_source_ptr pSource, tS3_sound_id pSound); 90 | 91 | void MungeEngineNoise(void); 92 | 93 | void SetSoundVolumes(void); 94 | 95 | tS3_outlet_ptr GetOutletFromIndex(int pIndex); 96 | 97 | int GetIndexFromOutlet(tS3_outlet_ptr pOutlet); 98 | 99 | int DRS3StartCDA(tS3_sound_id pCDA_id); 100 | 101 | int DRS3StopCDA(void); 102 | 103 | void StartMusic(void); 104 | 105 | void StopMusic(void); 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /src/harness/include/harness/trace.h: -------------------------------------------------------------------------------- 1 | #ifndef HARNESS_TRACE_H 2 | #define HARNESS_TRACE_H 3 | 4 | #include "brender.h" 5 | #include 6 | 7 | extern int harness_debug_level; 8 | 9 | void debug_printf(const char* fmt, const char* fn, const char* fmt2, ...); 10 | void panic_printf(const char* fmt, const char* fn, const char* fmt2, ...); 11 | void debug_print_vector3(const char* fmt, const char* fn, char* msg, br_vector3* v); 12 | void debug_print_matrix34(const char* fmt, const char* fn, char* name, br_matrix34* m); 13 | void debug_print_matrix4(const char* fmt, const char* fn, char* name, br_matrix4* m); 14 | 15 | #define BLUE 16 | 17 | #if 1 // _MSC_VER == 1020 18 | 19 | #define LOG_TRACE() 20 | #define LOG_TRACE8() 21 | #define LOG_TRACE9() 22 | #define LOG_TRACE10() 23 | #define LOG_DEBUG(a) 24 | #define LOG_DEBUG2(a, b) 25 | #define LOG_DEBUG3(a, b, c) 26 | #define LOG_INFO(a) 27 | #define LOG_INFO2(a, b) 28 | #define LOG_INFO3(a, b, c) 29 | #define LOG_WARN(a) 30 | #define LOG_WARN2(a, b) 31 | #define LOG_WARN3(a, b, c) 32 | #define LOG_PANIC(a) abort() 33 | #define LOG_PANIC2(a, b) 34 | #define LOG_WARN_ONCE() 35 | #define NOT_IMPLEMENTED() abort() 36 | #define TELL_ME_IF_WE_PASS_THIS_WAY() abort() 37 | #define STUB_ONCE() 38 | 39 | #else 40 | 41 | #define LOG_TRACE(...) \ 42 | if (harness_debug_level >= 5) { \ 43 | debug_printf("[TRACE] %s", __FUNCTION__, __VA_ARGS__); \ 44 | } 45 | 46 | #define LOG_TRACE10(...) \ 47 | if (harness_debug_level >= 10) { \ 48 | debug_printf("[TRACE] %s", __FUNCTION__, __VA_ARGS__); \ 49 | } 50 | #define LOG_TRACE9(...) \ 51 | if (harness_debug_level >= 9) { \ 52 | debug_printf("[TRACE] %s", __FUNCTION__, __VA_ARGS__); \ 53 | } 54 | 55 | #define LOG_TRACE8(...) \ 56 | if (harness_debug_level >= 8) { \ 57 | debug_printf("[TRACE] %s", __FUNCTION__, __VA_ARGS__); \ 58 | } 59 | 60 | #define LOG_DEBUG(...) debug_printf("\033[0;34m[DEBUG] %s ", __FUNCTION__, __VA_ARGS__) 61 | #define LOG_INFO(...) debug_printf("[INFO] %s ", __FUNCTION__, __VA_ARGS__) 62 | #define LOG_WARN(...) debug_printf("\033[0;33m[WARN] %s ", __FUNCTION__, __VA_ARGS__) 63 | #define LOG_PANIC(...) \ 64 | do { \ 65 | panic_printf("[PANIC] %s ", __FUNCTION__, __VA_ARGS__); \ 66 | abort(); \ 67 | } while (0) 68 | 69 | #define LOG_WARN_ONCE(...) \ 70 | static int warn_printed = 0; \ 71 | if (!warn_printed) { \ 72 | debug_printf("\033[0;33m[WARN] %s ", __FUNCTION__, __VA_ARGS__); \ 73 | warn_printed = 1; \ 74 | } 75 | 76 | #define NOT_IMPLEMENTED() \ 77 | LOG_PANIC("not implemented") 78 | 79 | #define TELL_ME_IF_WE_PASS_THIS_WAY() \ 80 | LOG_PANIC("code path not expected") 81 | 82 | #define STUB_ONCE() \ 83 | static int stub_printed = 0; \ 84 | if (!stub_printed) { \ 85 | debug_printf("\033[0;31m[WARN] %s ", __FUNCTION__, "%s", "stubbed"); \ 86 | stub_printed = 1; \ 87 | } 88 | 89 | #endif 90 | 91 | #endif // ifdef 92 | -------------------------------------------------------------------------------- /src/DETHRACE/common/options.h: -------------------------------------------------------------------------------- 1 | #ifndef _OPTIONS_H_ 2 | #define _OPTIONS_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern int gKey_defns[18]; 7 | extern tRadio_bastards gRadio_bastards__options[13]; // suffix added to avoid duplicate symbol 8 | extern int gKey_count; 9 | extern int gLast_graph_sel__options; // suffix added to avoid duplicate symbol 10 | extern char* gKey_names[125]; 11 | extern int gPending_entry; 12 | extern tInterface_spec* gThe_interface_spec__options; // suffix added to avoid duplicate symbol 13 | extern int gOrig_key_mapping[67]; 14 | extern br_pixelmap* gDials_pix; 15 | extern int gCurrent_key; 16 | 17 | void DrawDial(int pWhich_one, int pWhich_stage); 18 | 19 | void MoveDialFromTo(int pWhich_one, int pOld_stage, int pNew_stage); 20 | 21 | void SoundOptionsStart(void); 22 | 23 | int SoundOptionsDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out); 24 | 25 | int SoundOptionsLeft(int* pCurrent_choice, int* pCurrent_mode); 26 | 27 | int SoundOptionsRight(int* pCurrent_choice, int* pCurrent_mode); 28 | 29 | int SoundClick(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset); 30 | 31 | void DoSoundOptions(void); 32 | 33 | void GetGraphicsOptions(void); 34 | 35 | void SetGraphicsOptions(void); 36 | 37 | void PlayRadioOn2(int pIndex, int pValue); 38 | 39 | void PlayRadioOff2(int pIndex, int pValue); 40 | 41 | void PlayRadioOn__options(int pIndex, int pValue); 42 | 43 | void PlayRadioOff__options(int pIndex, int pValue); 44 | 45 | void DrawInitialRadios(void); 46 | 47 | void RadioChanged(int pIndex, int pNew_value); 48 | 49 | int GraphOptLeft(int* pCurrent_choice, int* pCurrent_mode); 50 | 51 | int GraphOptRight(int* pCurrent_choice, int* pCurrent_mode); 52 | 53 | int GraphOptUp(int* pCurrent_choice, int* pCurrent_mode); 54 | 55 | int GraphOptDown(int* pCurrent_choice, int* pCurrent_mode); 56 | 57 | int RadioClick(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset); 58 | 59 | int GraphOptGoAhead(int* pCurrent_choice, int* pCurrent_mode); 60 | 61 | // Suffix added to avoid duplicate symbol 62 | void PlotAGraphBox__options(int pIndex, int pColour_value); 63 | 64 | // Suffix added to avoid duplicate symbol 65 | void DrawAGraphBox__options(int pIndex); 66 | 67 | // Suffix added to avoid duplicate symbol 68 | void EraseAGraphBox__options(int pIndex); 69 | 70 | void DrawGraphBox(int pCurrent_choice, int pCurrent_mode); 71 | 72 | void DoGraphicsOptions(void); 73 | 74 | void CalibrateJoysticks(void); 75 | 76 | void StripControls(unsigned char* pStr); 77 | 78 | void LoadKeyNames(void); 79 | 80 | void DisposeKeyNames(void); 81 | 82 | void SaveOrigKeyMapping(void); 83 | 84 | void GetKeyCoords(int pIndex, int* pY, int* pName_x, int* pKey_x, int* pEnd_box); 85 | 86 | void SetKeysToDefault(void); 87 | 88 | void SaveKeyMapping(void); 89 | 90 | void ChangeKeyMapIndex(int pNew_one); 91 | 92 | void DrawKeyAssignments(int pCurrent_choice, int pCurrent_mode); 93 | 94 | int KeyAssignLeft(int* pCurrent_choice, int* pCurrent_mode); 95 | 96 | int KeyAssignRight(int* pCurrent_choice, int* pCurrent_mode); 97 | 98 | int KeyAssignUp(int* pCurrent_choice, int* pCurrent_mode); 99 | 100 | int KeyAssignDown(int* pCurrent_choice, int* pCurrent_mode); 101 | 102 | int KeyAssignGoAhead(int* pCurrent_choice, int* pCurrent_mode); 103 | 104 | int MouseyClickBastard(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset); 105 | 106 | void DrawInitialKMRadios(void); 107 | 108 | void DoControlOptions(void); 109 | 110 | void LoadSoundOptionsData(void); 111 | 112 | void FreeSoundOptionsData(void); 113 | 114 | void DrawDisabledOptions(void); 115 | 116 | void DoOptions(void); 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /src/DETHRACE/macros.h: -------------------------------------------------------------------------------- 1 | #ifndef MACROS_H 2 | #define MACROS_H 3 | 4 | #define DR_JOIN2(A, B) A##B 5 | #define DR_JOIN(A, B) DR_JOIN2(A, B) 6 | #define DR_STATIC_ASSERT(V) typedef int DR_JOIN(dr_static_assert_, __COUNTER__)[(V) ? 1 : -1] 7 | 8 | #define VEHICLE_TYPE_FROM_ID(id) ((tVehicle_type)(id >> 8)) 9 | #define VEHICLE_INDEX_FROM_ID(id) ((id) & 0x00ff) 10 | 11 | // #define VEC3_TRANSLATE(mat) (*(br_vector3*)(&mat->m[3][0])) 12 | 13 | #define SLOBYTE(x) (*((signed char*)&(x))) 14 | 15 | #define STR_STARTS_WITH(haystack, needle) strncmp(haystack, needle, strlen(needle)) 16 | 17 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) 18 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) 19 | #define CONSTRAIN_BETWEEN(lowerbound, upperbound, val) (MIN((upperbound), MAX((lowerbound), (val)))) 20 | 21 | #define COUNT_OF(array) (int)(sizeof((array)) / sizeof((array)[0])) 22 | #define LEN(array) (sizeof((array)) / sizeof((array)[0])) 23 | 24 | #define DEG_TO_RAD(degrees) ((degrees) * 3.141592653589793 / 180.0) 25 | 26 | #define V11MODEL(model) (((struct v11model*)model->prepared)) 27 | #define CAR(c) ((tCar_spec*)c) 28 | 29 | #define Vector3Div(v1, v2, v3) \ 30 | do { \ 31 | (v1)->v[0] = (v2)->v[0] / (v3)->v[0]; \ 32 | (v1)->v[1] = (v2)->v[1] / (v3)->v[1]; \ 33 | (v1)->v[2] = (v2)->v[2] / (v3)->v[2]; \ 34 | } while (0) 35 | 36 | #define Vector3DistanceSquared(V1, V2) \ 37 | ((((V1)->v[0] - (V2)->v[0])) * (((V1)->v[0] - (V2)->v[0])) + (((V1)->v[1] - (V2)->v[1])) * (((V1)->v[1] - (V2)->v[1])) + (((V1)->v[2] - (V2)->v[2])) * (((V1)->v[2] - (V2)->v[2]))) 38 | 39 | #define Vector3Distance(V1, V2) sqrt(Vector3DistanceSquared((V1), (V2))) 40 | #define Vector3AreEqual(V1, V2) \ 41 | ((V1)->v[0] == (V2)->v[0] && (V1)->v[1] == (V2)->v[1] && (V1)->v[2] == (V2)->v[2]) 42 | #define Vector3EqualElements(V, A, B, C) \ 43 | ((V)->v[0] == (A) && (V)->v[1] == (B) && (V)->v[2] == (C)) 44 | #define Vector3IsZero(V) Vector3EqualElements((V), 0.f, 0.f, 0.f) 45 | #define Vector3AddFloats(V1, V2, X, Y, Z) \ 46 | do { \ 47 | (V1)->v[0] = (V2)->v[0] + (X); \ 48 | (V1)->v[1] = (V2)->v[1] + (Y); \ 49 | (V1)->v[2] = (V2)->v[2] + (Z); \ 50 | } while (0) 51 | #define SwapValuesUsingTemporary(V1, V2, T) \ 52 | do { \ 53 | (T) = (V1); \ 54 | (V1) = (V2); \ 55 | (V2) = (T); \ 56 | } while (0) 57 | 58 | #define ReadVector3(pF, a, b, c) \ 59 | do { \ 60 | float x[3]; \ 61 | GetThreeFloats(pF, &x[2], &x[1], &x[0]); \ 62 | a = x[2]; \ 63 | b = x[1]; \ 64 | c = x[0]; \ 65 | \ 66 | } while (0) 67 | 68 | #define ReadVector32(pF, a, b, c) \ 69 | do { \ 70 | float x[3]; \ 71 | GetThreeFloats(pF, &x[2], &x[1], &x[0]); \ 72 | b = x[2]; \ 73 | c = x[1]; \ 74 | a = x[0]; \ 75 | } while (0) 76 | 77 | #define ReadPairOfFloats(pF, a, b) \ 78 | do { \ 79 | float x[2]; \ 80 | GetPairOfFloats(pF, &x[1], &x[0]); \ 81 | a = x[1]; \ 82 | b = x[0]; \ 83 | } while (0) 84 | 85 | #define DRVector3Scale(v1, v2, s) \ 86 | do { \ 87 | (v1)->v[0] = BR_MUL((v2)->v[0], s); \ 88 | (v1)->v[1] = BR_MUL((v2)->v[1], s); \ 89 | (v1)->v[2] = BR_MUL((v2)->v[2], s); \ 90 | } while (0) 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /lib/libsmacker/smacker.h: -------------------------------------------------------------------------------- 1 | /** 2 | libsmacker - A C library for decoding .smk Smacker Video files 3 | Copyright (C) 2012-2020 Greg Kennedy 4 | 5 | libsmacker is a cross-platform C library which can be used for 6 | decoding Smacker Video files produced by RAD Game Tools. 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU Lesser General Public License as published by 10 | the Free Software Foundation, either version 2.1 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with this program. If not, see . 20 | */ 21 | 22 | #ifndef SMACKER_H 23 | #define SMACKER_H 24 | 25 | /* includes - needed for FILE* here */ 26 | #include 27 | 28 | /** forward-declaration for an struct */ 29 | typedef struct smk_t* smk; 30 | 31 | /** a few defines as return codes from smk_next() */ 32 | #define SMK_DONE 0x00 33 | #define SMK_MORE 0x01 34 | #define SMK_LAST 0x02 35 | #define SMK_ERROR -1 36 | 37 | /** file-processing mode, pass to smk_open_file */ 38 | #define SMK_MODE_DISK 0x00 39 | #define SMK_MODE_MEMORY 0x01 40 | 41 | /** Y-scale meanings */ 42 | #define SMK_FLAG_Y_NONE 0x00 43 | #define SMK_FLAG_Y_INTERLACE 0x01 44 | #define SMK_FLAG_Y_DOUBLE 0x02 45 | 46 | /** track mask and enable bits */ 47 | #define SMK_AUDIO_TRACK_0 0x01 48 | #define SMK_AUDIO_TRACK_1 0x02 49 | #define SMK_AUDIO_TRACK_2 0x04 50 | #define SMK_AUDIO_TRACK_3 0x08 51 | #define SMK_AUDIO_TRACK_4 0x10 52 | #define SMK_AUDIO_TRACK_5 0x20 53 | #define SMK_AUDIO_TRACK_6 0x40 54 | #define SMK_VIDEO_TRACK 0x80 55 | 56 | /* PUBLIC FUNCTIONS */ 57 | #ifdef __cplusplus 58 | extern "C" { 59 | #endif 60 | 61 | /* OPEN OPERATIONS */ 62 | /** open an smk (from a file) */ 63 | smk smk_open_file(const char* filename, unsigned char mode); 64 | /** open an smk (from a file pointer) */ 65 | smk smk_open_filepointer(FILE* file, unsigned char mode); 66 | /** read an smk (from a memory buffer) */ 67 | smk smk_open_memory(const unsigned char* buffer, unsigned long size); 68 | 69 | /* CLOSE OPERATIONS */ 70 | /** close out an smk file and clean up memory */ 71 | void smk_close(smk object); 72 | 73 | /* GET FILE INFO OPERATIONS */ 74 | char smk_info_all(const smk object, unsigned long* frame, unsigned long* frame_count, double* usf); 75 | char smk_info_video(const smk object, unsigned long* w, unsigned long* h, unsigned char* y_scale_mode); 76 | char smk_info_audio(const smk object, unsigned char* track_mask, unsigned char channels[7], unsigned char bitdepth[7], unsigned long audio_rate[7]); 77 | 78 | /* ENABLE/DISABLE Switches */ 79 | char smk_enable_all(smk object, unsigned char mask); 80 | char smk_enable_video(smk object, unsigned char enable); 81 | char smk_enable_audio(smk object, unsigned char track, unsigned char enable); 82 | 83 | /** Retrieve palette */ 84 | const unsigned char* smk_get_palette(const smk object); 85 | /** Retrieve video frame, as a buffer of size w*h */ 86 | const unsigned char* smk_get_video(const smk object); 87 | /** Retrieve decoded audio chunk, track N */ 88 | const unsigned char* smk_get_audio(const smk object, unsigned char track); 89 | /** Get size of currently pointed decoded audio chunk, track N */ 90 | unsigned long smk_get_audio_size(const smk object, unsigned char track); 91 | 92 | /** rewind to first frame and unpack */ 93 | char smk_first(smk object); 94 | /** advance to next frame and unpack */ 95 | char smk_next(smk object); 96 | /** seek to first keyframe before/at N in an smk */ 97 | char smk_seek_keyframe(smk object, unsigned long frame); 98 | 99 | #ifdef __cplusplus 100 | } 101 | #endif 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /tools/progress.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | __help__ = """Print stats of overall project progress 4 | 5 | # Usage: find src/ -name "*.c" | xargs ./tools/progress.py 6 | """ 7 | 8 | import argparse 9 | import sys 10 | 11 | 12 | def main(): 13 | parser = argparse.ArgumentParser(description=__help__, allow_abbrev=False) 14 | parser.add_argument("files", metavar="FILE", nargs="+", help="sources") 15 | parser.add_argument("--sort", dest="sortkey", choices=["name", "percent", "completed", "total", "missing_contribution"], default="missing_contribution", help="key to sort on") 16 | parser.add_argument("-r", "--reverse", action="store_true", help="sort reverse") 17 | args = parser.parse_args() 18 | 19 | files = [] 20 | 21 | total_funcs = 0 22 | stubbed_funcs = 0 23 | unimplemented_funcs = 0 24 | 25 | for file_name in args.files: 26 | 27 | # we don't care about harness code 28 | if 'harness' in file_name: 29 | continue 30 | 31 | f = open(file_name, 'r') 32 | 33 | in_function = False 34 | 35 | file_total = 0 36 | file_stubbed = 0 37 | file_unimplemented = 0 38 | 39 | while True: 40 | line = f.readline() 41 | if line == '': 42 | break 43 | 44 | if line[0].isalpha() and '(' in line and line[-2] == '{': 45 | in_function = True 46 | file_total = file_total + 1 47 | if line[0] == '}' and in_function == True: 48 | # leaving function 49 | in_function = False 50 | 51 | if in_function: 52 | if line.strip() == 'NOT_IMPLEMENTED();': 53 | file_unimplemented = file_unimplemented + 1 54 | elif line.strip() == 'STUB();': 55 | file_stubbed = file_stubbed + 1 56 | elif line.strip() == 'STUB_ONCE();': 57 | file_stubbed = file_stubbed + 1 58 | 59 | 60 | if file_total > 0: 61 | completed = file_total - (file_stubbed + file_unimplemented) 62 | file = { 63 | 'name': file_name, 64 | 'percent': round((completed / file_total) * 100), 65 | 'completed': completed, 66 | 'total': file_total, 67 | } 68 | files.append(file) 69 | 70 | total_nb_functions = sum(f['total'] for f in files) 71 | total_implemented_functions = sum(f['completed'] for f in files) 72 | total_missing_functions = total_nb_functions - total_implemented_functions 73 | for f in files: 74 | f['missing_contribution'] = 100 * (f['total'] - f['completed']) / total_missing_functions 75 | 76 | print('{0:45} {1:>7} {2:>9} / {3:>5} {4:>7}'.format('name', 'percent', 'completed', 'total', 'missing')) 77 | print("=======================================") 78 | 79 | completed_funcs = 0 80 | total_funcs = 0 81 | for f in sorted(files, key=lambda x: x[args.sortkey], reverse=not args.reverse): 82 | print('{0:45} {1:>6}% {2:>9} / {3:>5} {4:>6.2f}%'.format(f['name'], f['percent'], f['completed'], f['total'], f['missing_contribution'])) 83 | 84 | total_funcs = total_funcs + f['total'] 85 | completed_funcs = completed_funcs + f['completed'] 86 | 87 | 88 | print('{0:45} {1:>7} {2:>9} / {3:>5} {4:>7}'.format('name', 'percent', 'completed', 'total', 'missing')) 89 | print("=======================================") 90 | percent_completed = round((completed_funcs / total_funcs) * 100) 91 | print('{0:45} {1:5}% {2:>9} / {3:>4}'.format('total', percent_completed, completed_funcs, total_funcs)) 92 | 93 | print() 94 | print('Overall progress:') 95 | print('{0}% of all functions implemented. ({1} completed / {2} total)'.format(percent_completed, completed_funcs, total_funcs)) 96 | 97 | return 0 98 | 99 | if __name__ == "__main__": 100 | raise SystemExit(main()) 101 | -------------------------------------------------------------------------------- /src/DETHRACE/common/racesumm.h: -------------------------------------------------------------------------------- 1 | #ifndef _RACESUMM_H_ 2 | #define _RACESUMM_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern int gPlayer_lookup[6]; 7 | extern tMouse_area gOld_back_button; 8 | extern tWreck_info gWreck_array[30]; 9 | extern br_actor* gWreck_root; 10 | extern br_actor* gWreck_camera; 11 | extern tU32 gWreck_start_zoom; 12 | extern tU32 gWreck_gallery_start; 13 | extern float gTemp_rank_increase; 14 | extern float gRank_per_ms; 15 | extern tU32 gLast_wreck_draw; 16 | extern tS3_sound_tag gSumm_sound; 17 | extern float gCredits_per_ms; 18 | extern tMouse_area* gBack_button_ptr; 19 | extern tU32 gSummary_start; 20 | extern br_pixelmap* gWreck_z_buffer; 21 | extern br_pixelmap* gWreck_render_area; 22 | extern int gWreck_selected; 23 | extern int gWreck_zoom_out; 24 | extern br_pixelmap* gChrome_font; 25 | extern int gWreck_zoom_in; 26 | extern int gTemp_credits; 27 | extern int gUser_interacted; 28 | extern int gWreck_count; 29 | extern int gRank_etc_munged; 30 | extern int gRank_increase; 31 | extern int gTemp_earned; 32 | extern int gTemp_rank; 33 | extern int gWreck_zoomed_in; 34 | extern int gDone_initial; 35 | extern int gTemp_lost; 36 | 37 | void MungeRankEtc(tProgram_state* pThe_state); 38 | 39 | void CalcRankIncrease(void); 40 | 41 | int RaceSummaryDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out); 42 | 43 | void DrawInBox(int pBox_left, int pText_left, int pTop, int pRight, int pBottom, int pColour, int pAmount); 44 | 45 | void DrawChromeNumber(int pLeft_1, int pLeft_2, int pPitch, int pTop, int pAmount); 46 | 47 | void DrawSummaryItems(void); 48 | 49 | void RampUpRate(float* pRate, tU32 pTime); 50 | 51 | void DrawSummary(int pCurrent_choice, int pCurrent_mode); 52 | 53 | void StartSummary(void); 54 | 55 | void SetUpTemps(void); 56 | 57 | int Summ1GoAhead(int* pCurrent_choice, int* pCurrent_mode); 58 | 59 | int SummCheckGameOver(int* pCurrent_choice, int* pCurrent_mode); 60 | 61 | tSO_result DoEndRaceSummary1(void); 62 | 63 | // Suffix added to avoid duplicate symbol 64 | void PrepareBoundingRadius__racesumm(br_model* model); 65 | 66 | void BuildWrecks(void); 67 | 68 | void DisposeWrecks(void); 69 | 70 | int MatrixIsIdentity(br_matrix34* pMat); 71 | 72 | void SpinWrecks(tU32 pFrame_period); 73 | 74 | void ZoomInTo(int pIndex, int* pCurrent_choice, int* pCurrent_mode); 75 | 76 | void ZoomOutTo(int pIndex, int* pCurrent_choice, int* pCurrent_mode); 77 | 78 | int WreckPick(br_actor* pActor, br_model* pModel, br_material* pMaterial, br_vector3* pRay_pos, br_vector3* pRay_dir, br_scalar pNear, br_scalar pFar, void* pArg); 79 | 80 | int CastSelectionRay(int* pCurrent_choice, int* pCurrent_mode); 81 | 82 | int DamageScrnExit(int* pCurrent_choice, int* pCurrent_mode); 83 | 84 | void DamageScrnDraw(int pCurrent_choice, int pCurrent_mode); 85 | 86 | int DamageScrnLeft(int* pCurrent_choice, int* pCurrent_mode); 87 | 88 | int DamageScrnRight(int* pCurrent_choice, int* pCurrent_mode); 89 | 90 | int DamageScrnUp(int* pCurrent_choice, int* pCurrent_mode); 91 | 92 | int DamageScrnDown(int* pCurrent_choice, int* pCurrent_mode); 93 | 94 | int DamageScrnGoHead(int* pCurrent_choice, int* pCurrent_mode); 95 | 96 | int ClickDamage(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset); 97 | 98 | int DamageScrnDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out); 99 | 100 | tSO_result DoEndRaceSummary2(void); 101 | 102 | // Suffix added to avoid duplicate symbol 103 | void DrawAnItem__racesumm(int pX, int pY_index, int pFont_index, char* pText); 104 | 105 | // Suffix added to avoid duplicate symbol 106 | void DrawColumnHeading__racesumm(int pStr_index, int pX); 107 | 108 | int SortScores(const void* pFirst_one, const void* pSecond_one); 109 | 110 | void SortGameScores(void); 111 | 112 | void NetSumDraw(int pCurrent_choice, int pCurrent_mode); 113 | 114 | void DoNetRaceSummary(void); 115 | 116 | tSO_result DoEndRaceSummary(int* pFirst_summary_done, tRace_result pRace_result); 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /src/DETHRACE/common/depth.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEPTH_H_ 2 | #define _DEPTH_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern tDepth_effect gDistance_depth_effects[4]; 7 | extern int gSky_on; 8 | extern int gDepth_cueing_on; 9 | extern tDepth_effect_type gSwap_depth_effect_type; 10 | extern br_scalar gSky_height; 11 | extern br_scalar gSky_x_multiplier; 12 | extern br_scalar gSky_width; 13 | extern br_scalar gSky_y_multiplier; 14 | extern tU32 gLast_depth_change; 15 | extern br_scalar gOld_yon; 16 | extern br_pixelmap* gWater_shade_table; 17 | extern br_material* gHorizon_material; 18 | extern br_model* gRearview_sky_model; 19 | extern int gFog_shade_table_power; 20 | extern br_actor* gRearview_sky_actor; 21 | extern int gAcid_shade_table_power; 22 | extern int gWater_shade_table_power; 23 | extern br_model* gForward_sky_model; 24 | extern br_actor* gForward_sky_actor; 25 | extern int gDepth_shade_table_power; 26 | extern br_pixelmap* gFog_shade_table; 27 | extern int gSwap_depth_effect_start; 28 | extern br_pixelmap* gDepth_shade_table; 29 | extern tSpecial_volume* gLast_camera_special_volume; 30 | extern br_pixelmap* gAcid_shade_table; 31 | extern int gSwap_depth_effect_end; 32 | extern br_pixelmap* gSwap_sky_texture; 33 | extern br_angle gOld_fov; 34 | extern br_angle gSky_image_width; 35 | extern br_angle gSky_image_height; 36 | extern br_angle gSky_image_underground; 37 | 38 | int Log2(int pNumber); 39 | 40 | br_scalar CalculateWrappingMultiplier(br_scalar pValue, br_scalar pYon); 41 | 42 | br_scalar DepthCueingShiftToDistance(int pShift); 43 | 44 | void FogAccordingToGPSCDE(br_material* pMaterial); 45 | 46 | void FrobFog(void); 47 | 48 | void InstantDepthChange(tDepth_effect_type pType, br_pixelmap* pSky_texture, int pStart, int pEnd); 49 | 50 | br_scalar Tan(br_scalar pAngle); 51 | 52 | br_scalar EdgeU(br_angle pSky, br_angle pView, br_angle pPerfect); 53 | 54 | void MungeSkyModel(br_actor* pCamera, br_model* pModel); 55 | 56 | br_model* CreateHorizonModel(br_actor* pCamera); 57 | 58 | void LoadDepthTable(char* pName, br_pixelmap** pTable, int* pPower); 59 | 60 | void InitDepthEffects(void); 61 | 62 | void DoDepthByShadeTable(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_pixelmap* pShade_table, int pShade_table_power, int pStart, int pEnd); 63 | 64 | void ExternalSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world); 65 | 66 | void DoHorizon(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world); 67 | 68 | void DoDepthCue(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer); 69 | 70 | void DoFog(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer); 71 | 72 | void DepthEffect(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world); 73 | 74 | void DepthEffectSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world); 75 | 76 | void DoWobbleCamera(br_actor* pCamera); 77 | 78 | void DoDrugWobbleCamera(br_actor* pCamera); 79 | 80 | void DoSpecialCameraEffect(br_actor* pCamera, br_matrix34* pCamera_to_world); 81 | 82 | void LessDepthFactor(void); 83 | 84 | void MoreDepthFactor(void); 85 | 86 | void LessDepthFactor2(void); 87 | 88 | void MoreDepthFactor2(void); 89 | 90 | void AssertYons(void); 91 | 92 | void IncreaseYon(void); 93 | 94 | void DecreaseYon(void); 95 | 96 | void SetYon(br_scalar pYon); 97 | 98 | br_scalar GetYon(void); 99 | 100 | void IncreaseAngle(void); 101 | 102 | void DecreaseAngle(void); 103 | 104 | void ToggleDepthMode(void); 105 | 106 | int GetSkyTextureOn(void); 107 | 108 | void SetSkyTextureOn(int pOn); 109 | 110 | void ToggleSkyQuietly(void); 111 | 112 | void ToggleSky(void); 113 | 114 | int GetDepthCueingOn(void); 115 | 116 | void SetDepthCueingOn(int pOn); 117 | 118 | void ToggleDepthCueingQuietly(void); 119 | 120 | void ToggleDepthCueing(void); 121 | 122 | void ChangeDepthEffect(void); 123 | 124 | void MungeForwardSky(void); 125 | 126 | void MungeRearviewSky(void); 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /src/DETHRACE/common/finteray.h: -------------------------------------------------------------------------------- 1 | #ifndef _FINTERAY_H_ 2 | #define _FINTERAY_H_ 3 | 4 | #include "dr_types.h" 5 | 6 | extern int gPling_materials; 7 | extern br_material* gSub_material; 8 | extern br_material* gReal_material; 9 | extern int gNfaces; 10 | extern br_matrix34 gPick_model_to_view__finteray; // suffix added to avoid duplicate symbol 11 | extern int gTemp_group; 12 | extern br_model* gNearest_model; 13 | extern br_model* gSelected_model; 14 | extern int gNearest_face_group; 15 | extern int gNearest_face; 16 | extern br_scalar gNearest_T; 17 | extern tFace_ref* gPling_face; 18 | 19 | // Suffix added to avoid duplicate symbol 20 | int BadDiv__finteray(br_scalar a, br_scalar b); 21 | 22 | // Suffix added to avoid duplicate symbol 23 | void DRVector2AccumulateScale__finteray(br_vector2* a, br_vector2* b, br_scalar s); 24 | 25 | // Suffix added to avoid duplicate symbol 26 | int PickBoundsTestRay__finteray(br_bounds* b, br_vector3* rp, br_vector3* rd, br_scalar t_near, br_scalar t_far, br_scalar* new_t_near, br_scalar* new_t_far); 27 | 28 | int ActorRayPick2D(br_actor* ap, br_vector3* pPosition, br_vector3* pDir, br_model* model, br_material* material, dr_pick2d_cbfn* callback); 29 | 30 | int DRSceneRayPick2D(br_actor* world, br_vector3* pPosition, br_vector3* pDir, dr_pick2d_cbfn* callback); 31 | 32 | // Suffix added to avoid duplicate symbol 33 | int DRModelPick2D__finteray(br_model* model, br_material* material, br_vector3* ray_pos, br_vector3* ray_dir, br_scalar t_near, br_scalar t_far, dr_modelpick2d_cbfn* callback, void* arg); 34 | 35 | // Suffix added to avoid duplicate symbol 36 | int FindHighestPolyCallBack__finteray(br_model* pModel, br_material* pMaterial, br_vector3* pRay_pos, br_vector3* pRay_dir, br_scalar pT, int pF, int pE, int pV, br_vector3* pPoint, br_vector2* pMap, void* pArg); 37 | 38 | // Suffix added to avoid duplicate symbol 39 | int FindHighestCallBack__finteray(br_actor* pActor, br_model* pModel, br_material* pMaterial, br_vector3* pRay_pos, br_vector3* pRay_dir, br_scalar pT_near, br_scalar pT_far, void* pArg); 40 | 41 | void FindFace(br_vector3* pPosition, br_vector3* pDir, br_vector3* nor, br_scalar* t, br_material** material); 42 | 43 | void EnablePlingMaterials(void); 44 | 45 | void DisablePlingMaterials(void); 46 | 47 | void CheckSingleFace(tFace_ref* pFace, br_vector3* ray_pos, br_vector3* ray_dir, br_vector3* normal, br_scalar* rt); 48 | 49 | void MultiRayCheckSingleFace(int pNum_rays, tFace_ref* pFace, br_vector3* ray_pos, br_vector3* ray_dir, br_vector3* normal, br_scalar* rt); 50 | 51 | void GetNewBoundingBox(br_bounds* b2, br_bounds* b1, br_matrix34* m); 52 | 53 | int FindFacesInBox(tBounds* bnds, tFace_ref* face_list, int max_face); 54 | 55 | int FindFacesInBox2(tBounds* bnds, tFace_ref* face_list, int max_face); 56 | 57 | int ActorBoxPick(tBounds* bnds, br_actor* ap, br_model* model, br_material* material, tFace_ref* face_list, int max_face, br_matrix34* pMat); 58 | 59 | int ModelPickBox(br_actor* actor, tBounds* bnds, br_model* model, br_material* model_material, tFace_ref* face_list, int max_face, br_matrix34* pMat); 60 | 61 | void ClipToPlaneGE(br_vector3* p, int* nv, int i, br_scalar limit); 62 | 63 | void ClipToPlaneLE(br_vector3* p, int* nv, int i, br_scalar limit); 64 | 65 | // Suffix added to avoid duplicate symbol 66 | int BoundsOverlapTest__finteray(br_bounds* b1, br_bounds* b2); 67 | 68 | int BoundsTransformTest(br_bounds* b1, br_bounds* b2, br_matrix34* M); 69 | 70 | int LineBoxColl(br_vector3* o, br_vector3* p, br_bounds* pB, br_vector3* pHit_point); 71 | 72 | int SphereBoxIntersection(br_bounds* pB, br_vector3* pC, br_scalar pR_squared, br_vector3* pHit_point); 73 | 74 | int LineBoxCollWithSphere(br_vector3* o, br_vector3* p, br_bounds* pB, br_vector3* pHit_point); 75 | 76 | int CompVert(int v1, int v2); 77 | 78 | void SetFacesGroup(int pFace); 79 | 80 | void SelectFace(br_vector3* pDir); 81 | 82 | void GetTilingLimits(br_vector2* min, br_vector2* max); 83 | 84 | void Scale(int pD, int factor); 85 | 86 | void ScaleUpX(void); 87 | 88 | void ScaleDnX(void); 89 | 90 | void ScaleUpY(void); 91 | 92 | void ScaleDnY(void); 93 | 94 | void SelectFaceForward(void); 95 | 96 | void SelectFaceDown(void); 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /src/DETHRACE/common/main.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include 3 | 4 | #include "controls.h" 5 | #include "cutscene.h" 6 | #include "drmem.h" 7 | #include "errors.h" 8 | #include "globvars.h" 9 | #include "globvrpb.h" 10 | #include "graphics.h" 11 | #include "harness/config.h" 12 | #include "harness/trace.h" 13 | #include "init.h" 14 | #include "input.h" 15 | #include "loading.h" 16 | #include "loadsave.h" 17 | #include "network.h" 18 | #include "pd/sys.h" 19 | #include "s3/s3.h" 20 | #include "sound.h" 21 | #include "structur.h" 22 | #include "utility.h" 23 | 24 | // IDA: void __cdecl QuitGame() 25 | // FUNCTION: CARM95 0x004a9ea0 26 | void QuitGame(void) { 27 | 28 | if (harness_game_info.mode == eGame_carmageddon_demo || harness_game_info.mode == eGame_splatpack_demo || harness_game_info.mode == eGame_splatpack_xmas_demo) { 29 | DoDemoGoodbye(); 30 | } 31 | 32 | gProgram_state.racing = 0; 33 | SaveOptions(); 34 | if (gNet_mode != eNet_mode_none) { 35 | NetLeaveGame(gCurrent_net_game); 36 | } 37 | ShutdownNetIfRequired(); 38 | if (gSound_available) { 39 | DRS3ShutDown(); 40 | } 41 | if (gBr_initialized) { 42 | #ifdef DETHRACE_FIX_BUGS 43 | // In 3dfx mode, we need direct pixel access before calling `ClearEntireScreen` 44 | if (harness_game_config.opengl_3dfx_mode) { 45 | PDLockRealBackScreen(1); 46 | } 47 | #endif 48 | ClearEntireScreen(); 49 | } 50 | PDRevertPalette(); 51 | StopMusic(); 52 | if (gBrZb_initialized) { 53 | BrZbEnd(); 54 | } 55 | 56 | if (gBr_initialized) { 57 | BrV1dbEndWrapper(); 58 | } 59 | 60 | #ifdef DETHRACE_FIX_BUGS 61 | // Hack: not sure if this is a bug in the original code or if its something caused by dethrace. 62 | // Avoids the device screen pixelmap being double-freed 63 | gDOSGfx_initialized = 0; 64 | #endif 65 | 66 | PDShutdownSystem(); 67 | } 68 | 69 | // IDA: tU32 __cdecl TrackCount(br_actor *pActor, tU32 *pCount) 70 | tU32 TrackCount(br_actor* pActor, tU32* pCount) { 71 | unsigned int x; 72 | unsigned int z; 73 | int ad; 74 | float e; 75 | NOT_IMPLEMENTED(); 76 | } 77 | 78 | // IDA: void __cdecl CheckNumberOfTracks() 79 | void CheckNumberOfTracks(void) { 80 | tU32 track_count; 81 | NOT_IMPLEMENTED(); 82 | } 83 | 84 | // IDA: void __usercall ServiceTheGame(int pRacing@) 85 | // FUNCTION: CARM95 0x004a9f29 86 | void ServiceTheGame(int pRacing) { 87 | 88 | CheckMemory(); 89 | if (!pRacing) { 90 | CyclePollKeys(); 91 | } 92 | PollKeys(); 93 | rand(); 94 | if (PDServiceSystem(gFrame_period)) { 95 | QuitGame(); 96 | } 97 | if (!pRacing) { 98 | CheckSystemKeys(0); 99 | } 100 | if (!pRacing && gSound_enabled) { 101 | if (gProgram_state.cockpit_on && gProgram_state.cockpit_image_index >= 0) { 102 | S3Service(1, 2); 103 | } else { 104 | S3Service(0, 2); 105 | } 106 | } 107 | NetService(pRacing); 108 | } 109 | 110 | // IDA: void __cdecl ServiceGame() 111 | // FUNCTION: CARM95 0x004a9fe4 112 | void ServiceGame(void) { 113 | ServiceTheGame(0); 114 | } 115 | 116 | // IDA: void __cdecl ServiceGameInRace() 117 | // FUNCTION: CARM95 0x004a9ff9 118 | void ServiceGameInRace(void) { 119 | 120 | ServiceTheGame(1); 121 | CheckKevKeys(); 122 | } 123 | 124 | // IDA: void __usercall GameMain(int pArgc@, char **pArgv@) 125 | // FUNCTION: CARM95 0x004aa013 126 | void GameMain(int pArgc, char** pArgv) { 127 | tPath_name CD_dir; 128 | 129 | PDSetFileVariables(); 130 | PDBuildAppPath(gApplication_path); 131 | OpenDiagnostics(); 132 | 133 | strcat(gApplication_path, "DATA"); 134 | 135 | UsePathFileToDetermineIfFullInstallation(); 136 | if (!gCD_fully_installed && GetCDPathFromPathsTxtFile(CD_dir) && !PDCheckDriveExists(CD_dir)) { 137 | PDInitialiseSystem(); 138 | PDFatalError("Can't find the Carmageddon CD\n"); 139 | } 140 | InitialiseDeathRace(pArgc, pArgv); 141 | DoProgram(); 142 | QuitGame(); 143 | } 144 | --------------------------------------------------------------------------------