Subversion Repositories Games.Carmageddon

Rev

Rev 15 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "brender.h"
  2. #include "car.h"
  3. #include "errors.h"
  4. #include "globvars.h"
  5. #include "grafdata.h"
  6. #include "graphics.h"
  7. #include "harness/config.h"
  8. #include "harness/hooks.h"
  9. #include "harness/os.h"
  10. #include "harness/trace.h"
  11. #include "input.h"
  12. #include "loadsave.h"
  13. #include "main.h"
  14. #include "pd/sys.h"
  15. #include "sound.h"
  16. #include "utility.h"
  17. #include <errno.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <sys/stat.h>
  22. #include <time.h>
  23.  
  24. #ifdef __DOS__
  25. #define GFX_INIT_STRING_32X20X8 "MCGA,W:320,H:200,B:8"
  26. #define GFX_INIT_STRING_64X48X8 "VESA,W:640,H:480,B:8"
  27.  
  28. int gDOSGfx_initialized;
  29.  
  30. tU32 gUpper_loop_limit;
  31. int gReal_back_screen_locked;
  32. void (*gPrev_keyboard_handler)();
  33.  
  34. char* _unittest_last_fatal_error;
  35.  
  36. // IDA: void __cdecl KeyboardHandler()
  37. void KeyboardHandler(void) {
  38.     tU8 scan_code;
  39.     tU8 up;
  40.     static tU8 extended;
  41.     LOG_TRACE("()");
  42.     NOT_IMPLEMENTED();
  43. }
  44.  
  45. // IDA: int __usercall KeyDown@<EAX>(tU8 pScan_code@<EAX>)
  46. int KeyDown(tU8 pScan_code) {
  47.     NOT_IMPLEMENTED();
  48. }
  49.  
  50. // IDA: void __usercall KeyTranslation(tU8 pKey_index@<EAX>, tU8 pScan_code_1@<EDX>, tU8 pScan_code_2@<EBX>)
  51. void KeyTranslation(tU8 pKey_index, tU8 pScan_code_1, tU8 pScan_code_2) {
  52.     LOG_TRACE("(%d, %d, %d)", pKey_index, pScan_code_1, pScan_code_2);
  53.     NOT_IMPLEMENTED();
  54. }
  55.  
  56. // IDA: void __cdecl KeyBegin()
  57. void KeyBegin(void) {
  58.     NOT_IMPLEMENTED();
  59. }
  60.  
  61. // IDA: void __cdecl KeyEnd()
  62. void KeyEnd(void) {
  63.     LOG_TRACE("()");
  64.     NOT_IMPLEMENTED();
  65. }
  66.  
  67. // IDA: int __usercall KeyDown22@<EAX>(int pKey_index@<EAX>)
  68. int KeyDown22(int pKey_index) {
  69.     LOG_TRACE("(%d)", pKey_index);
  70.     NOT_IMPLEMENTED();
  71. }
  72.  
  73. // IDA: void __usercall PDSetKeyArray(int *pKeys@<EAX>, int pMark@<EDX>)
  74. void PDSetKeyArray(int* pKeys, int pMark) {
  75.     int i;
  76.     tS32 joyX;
  77.     tS32 joyY;
  78.     LOG_TRACE10("(%p, %d)", pKeys, pMark);
  79. }
  80.  
  81. // IDA: void __usercall PDFatalError(char *pThe_str@<EAX>)
  82. void PDFatalError(char* pThe_str) {
  83.     static int been_here = 0;
  84.     LOG_TRACE("(\"%s\")", pThe_str);
  85.  
  86.     if (been_here) {
  87.         exit(1);
  88.     }
  89.     been_here = 1;
  90.  
  91.     dr_dprintf("FATAL ERROR: %s", pThe_str);
  92.  
  93.     _unittest_last_fatal_error = pThe_str;
  94.     fprintf(stderr, "FATAL ERROR: %s\n", pThe_str);
  95.  
  96.     // wait for keypress
  97.  
  98.     abort();
  99. }
  100.  
  101. // IDA: void __usercall PDNonFatalError(char *pThe_str@<EAX>)
  102. void PDNonFatalError(char* pThe_str) {
  103.     LOG_TRACE("(\"%s\")", pThe_str);
  104.     NOT_IMPLEMENTED();
  105. }
  106.  
  107. // IDA: void __cdecl PDInitialiseSystem()
  108. void PDInitialiseSystem(void) {
  109.     tPath_name the_path;
  110.     FILE* f;
  111.     int len;
  112.  
  113.     KeyBegin();
  114.  
  115.     // v4 = DOSMouseBegin();
  116.     gJoystick_deadzone = 8000;
  117.     // gUpper_loop_limit = sub_A1940(v4, v5, v3, v6) / 2;
  118.  
  119.     // Demo's do not ship with KEYBOARD.COK file
  120.     if (harness_game_info.defines.ascii_table == NULL) {
  121.         PathCat(the_path, gApplication_path, "KEYBOARD.COK");
  122.         f = fopen(the_path, "rb");
  123.         if (f == NULL) {
  124.             PDFatalError("This .exe must have KEYBOARD.COK in the DATA folder.");
  125.         }
  126.  
  127.         fseek(f, 0, SEEK_END);
  128.         len = ftell(f);
  129.         rewind(f);
  130.         fread(gASCII_table, len / 2, 1, f);
  131.         fread(gASCII_shift_table, len / 2, 1, f);
  132.         fclose(f);
  133.     } else {
  134.         memcpy(gASCII_table, harness_game_info.defines.ascii_table, sizeof(gASCII_table));
  135.         memcpy(gASCII_shift_table, harness_game_info.defines.ascii_shift_table, sizeof(gASCII_shift_table));
  136.     }
  137. }
  138.  
  139. // IDA: void __cdecl PDShutdownSystem()
  140. void PDShutdownSystem() {
  141.     static int been_here = 0; // Added by dethrace
  142.     LOG_TRACE("()");
  143.  
  144.     if (!been_here) {
  145.         Harness_Hook_PDShutdownSystem();
  146.     } else {
  147.         LOG_WARN("recursion detected => force exit");
  148.         exit(8);
  149.     }
  150. }
  151.  
  152. // IDA: void __cdecl PDSaveOriginalPalette()
  153. void PDSaveOriginalPalette(void) {
  154.     LOG_TRACE("()");
  155.     NOT_IMPLEMENTED();
  156. }
  157.  
  158. // IDA: void __cdecl PDRevertPalette()
  159. void PDRevertPalette(void) {
  160.     LOG_TRACE("()");
  161.  
  162.     // empty function
  163. }
  164.  
  165. // IDA: int __usercall PDInitScreenVars@<EAX>(int pArgc@<EAX>, char **pArgv@<EDX>)
  166. int PDInitScreenVars(int pArgc, char** pArgv) {
  167.     gGraf_specs[gGraf_spec_index].phys_width = gGraf_specs[gGraf_spec_index].total_width;
  168.     gGraf_specs[gGraf_spec_index].phys_height = gGraf_specs[gGraf_spec_index].total_height;
  169.     return 1;
  170. }
  171.  
  172. // IDA: void __cdecl PDInitScreen()
  173. void PDInitScreen(void) {
  174. }
  175.  
  176. // IDA: void __cdecl PDLockRealBackScreen()
  177. void PDLockRealBackScreen(void) {
  178.     LOG_TRACE("()");
  179.     NOT_IMPLEMENTED();
  180. }
  181.  
  182. // IDA: void __cdecl PDUnlockRealBackScreen()
  183. void PDUnlockRealBackScreen(void) {
  184.     LOG_TRACE("()");
  185.     NOT_IMPLEMENTED();
  186. }
  187.  
  188. // IDA: void __cdecl PDAllocateScreenAndBack()
  189. void PDAllocateScreenAndBack(void) {
  190.  
  191.     dr_dprintf("PDAllocateScreenAndBack() - START...");
  192.     BrMaterialFindHook(PDMissingMaterial);
  193.     BrTableFindHook(PDMissingTable);
  194.     BrModelFindHook(PDMissingModel);
  195.     BrMapFindHook(PDMissingMap);
  196.  
  197.     // This is a bit of a mix between the original DOS code and windows code...
  198.     // DOS:
  199.     // gScreen = DOSGfxBegin(gGraf_specs[gGraf_spec_index].gfx_init_string);
  200.     //
  201.     // Windows:
  202.     // SSDXInit(gGraf_specs[gGraf_spec_index].total_width, gGraf_specs[gGraf_spec_index].total_height)
  203.     // gScreen = BrPixelmapAllocate(BR_PMT_INDEX_8, ...)
  204.     //
  205.  
  206.     Harness_Hook_GraphicsInit(gGraf_specs[gGraf_spec_index].total_width, gGraf_specs[gGraf_spec_index].total_height);
  207.     gScreen = BrPixelmapAllocate(BR_PMT_INDEX_8, gGraf_specs[gGraf_spec_index].total_width, gGraf_specs[gGraf_spec_index].total_height, NULL, BR_PMAF_NORMAL);
  208.  
  209.     gScreen->origin_x = 0;
  210.     gDOSGfx_initialized = 1;
  211.     gScreen->origin_y = 0;
  212.     gBack_screen = BrPixelmapMatch(gScreen, BR_PMMATCH_OFFSCREEN);
  213.     gBack_screen->origin_x = 0;
  214.     gBack_screen->origin_y = 0;
  215.     gTemp_screen = BrPixelmapMatch(gScreen, BR_PMMATCH_OFFSCREEN);
  216.     gTemp_screen->origin_x = 0;
  217.     gTemp_screen->origin_y = 0;
  218.     dr_dprintf("PDAllocateScreenAndBack() - END.");
  219. }
  220.  
  221. // IDA: void __usercall Copy8BitTo16BitPixelmap(br_pixelmap *pDst@<EAX>, br_pixelmap *pSrc@<EDX>, br_pixelmap *pPalette@<EBX>)
  222. void Copy8BitTo16BitPixelmap(br_pixelmap* pDst, br_pixelmap* pSrc, br_pixelmap* pPalette) {
  223.     int x;
  224.     int y;
  225.     tU8* src;
  226.     tU8 value;
  227.     tU8 red;
  228.     tU8 green;
  229.     tU8 blue;
  230.     tU16* dst;
  231.     tU16* palette_entry;
  232.     LOG_TRACE("(%p, %p, %p)", pDst, pSrc, pPalette);
  233.     NOT_IMPLEMENTED();
  234. }
  235.  
  236. // IDA: void __usercall Double8BitTo16BitPixelmap(br_pixelmap *pDst@<EAX>, br_pixelmap *pSrc@<EDX>, br_pixelmap *pPalette@<EBX>, tU16 pOff@<ECX>, tU16 pSrc_width, tU16 pSrc_height)
  237. void Double8BitTo16BitPixelmap(br_pixelmap* pDst, br_pixelmap* pSrc, br_pixelmap* pPalette, tU16 pOff, tU16 pSrc_width, tU16 pSrc_height) {
  238.     int x;
  239.     int y;
  240.     tU8* src;
  241.     tU8 value;
  242.     tU8 red;
  243.     tU8 green;
  244.     tU8 blue;
  245.     tU16* dst0;
  246.     tU16* dst1;
  247.     tU16 sixteen;
  248.     tU16* palette_entry;
  249.     LOG_TRACE("(%p, %p, %p, %d, %d, %d)", pDst, pSrc, pPalette, pOff, pSrc_width, pSrc_height);
  250.     NOT_IMPLEMENTED();
  251. }
  252.  
  253. // IDA: br_pixelmap* __cdecl PDInterfacePixelmap()
  254. br_pixelmap* PDInterfacePixelmap(void) {
  255.     LOG_TRACE("()");
  256.     NOT_IMPLEMENTED();
  257. }
  258.  
  259. // IDA: void __cdecl SwapBackScreen()
  260. void SwapBackScreen(void) {
  261.     LOG_TRACE("()");
  262.     NOT_IMPLEMENTED();
  263. }
  264.  
  265. // IDA: void __usercall ReallyCopyBackScreen(int pRendering_area_only@<EAX>, int pClear_top_and_bottom@<EDX>)
  266. void ReallyCopyBackScreen(int pRendering_area_only, int pClear_top_and_bottom) {
  267.     LOG_TRACE("(%d, %d)", pRendering_area_only, pClear_top_and_bottom);
  268.     NOT_IMPLEMENTED();
  269. }
  270.  
  271. // IDA: void __usercall CopyBackScreen(int pRendering_area_only@<EAX>)
  272. void CopyBackScreen(int pRendering_area_only) {
  273.     LOG_TRACE("(%d)", pRendering_area_only);
  274.     NOT_IMPLEMENTED();
  275. }
  276.  
  277. // IDA: void __usercall PDScreenBufferSwap(int pRendering_area_only@<EAX>)
  278. void PDScreenBufferSwap(int pRendering_area_only) {
  279.     LOG_TRACE10("(%d)", pRendering_area_only);
  280.     if (pRendering_area_only) {
  281.         BrPixelmapRectangleCopy(gScreen, gY_offset, gX_offset, gRender_screen, 0, 0, gWidth, gHeight);
  282.     } else {
  283.         if (gReal_graf_data_index == gGraf_data_index) {
  284.             BrPixelmapDoubleBuffer(gScreen, gBack_screen);
  285.         } else {
  286.             DRPixelmapDoubledCopy(gTemp_screen, gBack_screen, 320, 200, 0, 40);
  287.             BrPixelmapDoubleBuffer(gScreen, gTemp_screen);
  288.         }
  289.     }
  290. }
  291.  
  292. // IDA: void __usercall PDPixelmapToScreenRectangleCopy(br_pixelmap *dst@<EAX>, br_int_16 dx@<EDX>, br_int_16 dy@<EBX>, br_pixelmap *src@<ECX>, br_int_16 sx, br_int_16 sy, br_uint_16 w, br_uint_16 h)
  293. void PDPixelmapToScreenRectangleCopy(br_pixelmap* dst, br_int_16 dx, br_int_16 dy, br_pixelmap* src, br_int_16 sx, br_int_16 sy, br_uint_16 w, br_uint_16 h) {
  294.     LOG_TRACE("(%p, %d, %d, %p, %d, %d, %d, %d)", dst, dx, dy, src, sx, sy, w, h);
  295.     NOT_IMPLEMENTED();
  296. }
  297.  
  298. // IDA: void __usercall PDPixelmapHLineOnScreen(br_pixelmap *dst@<EAX>, br_int_16 x1@<EDX>, br_int_16 y1@<EBX>, br_int_16 x2@<ECX>, br_int_16 y2, br_uint_32 colour)
  299. void PDPixelmapHLineOnScreen(br_pixelmap* dst, br_int_16 x1, br_int_16 y1, br_int_16 x2, br_int_16 y2, br_uint_32 colour) {
  300.     LOG_TRACE("(%p, %d, %d, %d, %d, %d)", dst, x1, y1, x2, y2, colour);
  301.     NOT_IMPLEMENTED();
  302. }
  303.  
  304. // IDA: void __usercall PDPixelmapVLineOnScreen(br_pixelmap *dst@<EAX>, br_int_16 x1@<EDX>, br_int_16 y1@<EBX>, br_int_16 x2@<ECX>, br_int_16 y2, br_uint_32 colour)
  305. void PDPixelmapVLineOnScreen(br_pixelmap* dst, br_int_16 x1, br_int_16 y1, br_int_16 x2, br_int_16 y2, br_uint_32 colour) {
  306.     LOG_TRACE("(%p, %d, %d, %d, %d, %d)", dst, x1, y1, x2, y2, colour);
  307.     NOT_IMPLEMENTED();
  308. }
  309.  
  310. // IDA: void __cdecl PDInstallErrorHandlers()
  311. void PDInstallErrorHandlers(void) {
  312.     LOG_TRACE("()");
  313.     NOT_IMPLEMENTED();
  314. }
  315.  
  316. // IDA: void __cdecl PDSetFileVariables()
  317. void PDSetFileVariables(void) {
  318.     gDir_separator[0] = '\\';
  319.  
  320.     // Added >>
  321.     gDir_separator[0] = '/';
  322.     gDir_separator[1] = '\0';
  323.     // <<
  324. }
  325.  
  326. // IDA: void __usercall PDBuildAppPath(char *pThe_path@<EAX>)
  327. void PDBuildAppPath(char* pThe_path) {
  328.     int pos;
  329.  
  330.     getcwd(pThe_path, 256);
  331.     strcat(pThe_path, "/"); // original: pThe_path[pos] = '\\';
  332.     strcpy(gNetwork_profile_fname, pThe_path);
  333.     strcat(gNetwork_profile_fname, "NETWORK.INI");
  334. }
  335.  
  336. // IDA: void __usercall PDForEveryFile(char *pThe_path@<EAX>, void (*pAction_routine)(char*)@<EDX>)
  337. void PDForEveryFile(char* pThe_path, void (*pAction_routine)(char*)) {
  338.     char find_path[256];
  339.     char found_path[256];
  340.  
  341.     char* found = OS_GetFirstFileInDirectory(pThe_path);
  342.     while (found != NULL) {
  343.         PathCat(found_path, pThe_path, found);
  344.         pAction_routine(found_path);
  345.         found = OS_GetNextFileInDirectory();
  346.     }
  347. }
  348.  
  349. // IDA: void __usercall PDSetPalette(br_pixelmap *pThe_palette@<EAX>)
  350. void PDSetPalette(br_pixelmap* pThe_palette) {
  351.     BrDevPaletteSetOld(pThe_palette);
  352. }
  353.  
  354. // IDA: void __usercall PDSetPaletteEntries(br_pixelmap *pPalette@<EAX>, int pFirst_colour@<EDX>, int pCount@<EBX>)
  355. void PDSetPaletteEntries(br_pixelmap* pPalette, int pFirst_colour, int pCount) {
  356.     int i;
  357.     tU8* p;
  358.     p = (tU8*)pPalette->pixels + 4 * pFirst_colour;
  359.     for (i = pFirst_colour; i < pFirst_colour + pCount; i++) {
  360. #if BR_ENDIAN_BIG
  361.         BrDevPaletteSetEntryOld(i, (p[1] << 16) | (p[2] << 8) | p[3]);
  362. #else
  363.         BrDevPaletteSetEntryOld(i, (p[2] << 16) | (p[1] << 8) | *p);
  364. #endif
  365.         p += 4;
  366.     }
  367. }
  368.  
  369. // IDA: void __cdecl PDSwitchToRealResolution()
  370. void PDSwitchToRealResolution(void) {
  371.     LOG_TRACE("()");
  372. }
  373.  
  374. // IDA: void __cdecl PDSwitchToLoresMode()
  375. void PDSwitchToLoresMode(void) {
  376.     LOG_TRACE("()");
  377. }
  378.  
  379. // IDA: void __usercall PDMouseButtons(int *pButton_1@<EAX>, int *pButton_2@<EDX>)
  380. void PDMouseButtons(int* pButton_1, int* pButton_2) {
  381.     br_uint_32 mouse_buttons;
  382.     br_int_32 mouse_x;
  383.     br_int_32 mouse_y;
  384.     LOG_TRACE("(%p, %p)", pButton_1, pButton_2);
  385.  
  386.     Harness_Hook_GetMouseButtons(pButton_1, pButton_2);
  387. }
  388.  
  389. // IDA: void __usercall PDGetMousePosition(int *pX_coord@<EAX>, int *pY_coord@<EDX>)
  390. void PDGetMousePosition(int* pX_coord, int* pY_coord) {
  391.     br_uint_32 mouse_buttons;
  392.     br_int_32 mouse_x2;
  393.     br_int_32 mouse_y2;
  394.     int delta_x;
  395.     int delta_y;
  396.     static br_int_32 mouse_x;
  397.     static br_int_32 mouse_y;
  398.     LOG_TRACE("(%p, %p)", pX_coord, pY_coord);
  399.  
  400.     Harness_Hook_GetMousePosition(pX_coord, pY_coord);
  401. }
  402.  
  403. // IDA: int __cdecl PDGetTotalTime()
  404. int PDGetTotalTime(void) {
  405.     return OS_GetTime();
  406. }
  407.  
  408. // IDA: int __usercall PDServiceSystem@<EAX>(tU32 pTime_since_last_call@<EAX>)
  409. int PDServiceSystem(tU32 pTime_since_last_call) {
  410.     Harness_Hook_PDServiceSystem();
  411.     return 0;
  412. }
  413.  
  414. // IDA: tU32 __cdecl LargestBlockAvail()
  415. tU32 LargestBlockAvail(void) {
  416.     SREGS sregs;
  417.     tMem_info mem_info;
  418.     size_t memmax;
  419.  
  420.     // Added >>
  421.     return 15000000;
  422.     // <<
  423. }
  424.  
  425. // IDA: void* __usercall PDGrabLargestMammaryWeCanPlayWith@<EAX>(tU32 pMaximum_required@<EAX>, tU32 *pAmount_allocated@<EDX>)
  426. void* PDGrabLargestMammaryWeCanPlayWith(tU32 pMaximum_required, tU32* pAmount_allocated) {
  427.     void* result;
  428.     LOG_TRACE("(%d, %p)", pMaximum_required, pAmount_allocated);
  429.     NOT_IMPLEMENTED();
  430. }
  431.  
  432. // IDA: void __usercall PDAllocateActionReplayBuffer(char **pBuffer@<EAX>, tU32 *pBuffer_size@<EDX>)
  433. void PDAllocateActionReplayBuffer(char** pBuffer, tU32* pBuffer_size) {
  434.     tU32 lba;
  435.     tU32 required;
  436.     LOG_TRACE("(%p, %p)", pBuffer, pBuffer_size);
  437.  
  438.     OS_AllocateActionReplayBuffer(pBuffer, pBuffer_size);
  439. }
  440.  
  441. // IDA: void __usercall PDDisposeActionReplayBuffer(char *pBuffer@<EAX>)
  442. void PDDisposeActionReplayBuffer(char* pBuffer) {
  443.     LOG_TRACE("(\"%s\")", pBuffer);
  444. }
  445.  
  446. // IDA: void __usercall Usage(char *pProgpath@<EAX>)
  447. void Usage(char* pProgpath) {
  448.     // char basename[9];
  449.     char basename[256]; // fix: changed from 9 to avoid overflow on longer filenames
  450.  
  451.     fprintf(stderr,
  452.         "Usage: %s [%s] [%s YonFactor] [%s CarSimplificationLevel] [%s SoundDetailLevel] [%s] [%s] [%s] [%s] [%s] [%s]\nWhere YonFactor is between 0 and 1,\nCarSimplificationLevel is a whole number between 0 and %d,\nand SoundDetailLevel is a whole number.\n",
  453.         basename,
  454.         "-hires",
  455.         "-yon",
  456.         "-simple",
  457.         "-sound",
  458.         "-robots",
  459.         "-lomem",
  460.         "-nosound",
  461.         "-spamfritter",
  462.         "-nocutscenes",
  463.         "-noreplay",
  464.         CAR_MAX_SIMPLIFICATION_LEVEL);
  465.     exit(1);
  466. }
  467.  
  468. // Renamed from "main" to "original_main" to allow for harness + unit testing
  469. int original_main(int pArgc, char** pArgv) {
  470.     int arg;
  471.     int i;
  472.     float f;
  473.  
  474.     for (i = 1; i < pArgc; i++) {
  475.         if (strcasecmp(pArgv[i], "-hires") == 0) {
  476.             gGraf_spec_index = 1;
  477.         } else if (strcasecmp(pArgv[i], "-yon") == 0 && i < pArgc - 1) {
  478.             i++;
  479.             sscanf(pArgv[i], "%f", &f);
  480.             if (f >= 0.0 && f <= 1.0f) {
  481.                 gYon_multiplier = f;
  482.             }
  483.         } else if (strcasecmp(pArgv[i], "-simple") == 0 && i < pArgc - 1) {
  484.             i++;
  485.             sscanf(pArgv[i], "%d", &arg);
  486.             if (arg >= 0 && arg < 5) {
  487.                 gCar_simplification_level = arg;
  488.             }
  489.         } else if (strcasecmp(pArgv[i], "-sound") == 0 && i < pArgc - 1) {
  490.             i++;
  491.             sscanf(pArgv[i], "%d", &arg);
  492.             gSound_detail_level = arg;
  493.  
  494.         } else if (strcasecmp(pArgv[i], "-robots") == 0 || strcasecmp(pArgv[i], "-german") == 0) {
  495.             gSausage_override = 1;
  496.         } else if (strcasecmp(pArgv[i], "-lomem") == 0) {
  497.             gAustere_override = 1;
  498.         } else if (strcasecmp(pArgv[i], "-nosound") == 0) {
  499.             gSound_override = 1;
  500.         } else if (strcasecmp(pArgv[i], "-spamfritter") == 0) {
  501.             gExtra_mem = 2000000;
  502.         } else if (strcasecmp(pArgv[i], "-nocutscenes") == 0) {
  503.             gCut_scene_override = 1;
  504.         } else if (strcasecmp(pArgv[i], "-noreplay") == 0) {
  505.             gReplay_override = 1;
  506.         } else {
  507.             Usage(pArgv[0]);
  508.         }
  509.     }
  510.  
  511.     GameMain(pArgc, pArgv);
  512.     return 0;
  513. }
  514.  
  515. // IDA: int __cdecl OurGetChar()
  516. int OurGetChar(void) {
  517.     int key;
  518.     LOG_TRACE("()");
  519.     NOT_IMPLEMENTED();
  520. }
  521.  
  522. // IDA: void __usercall PDEnterDebugger(char *pStr@<EAX>)
  523. void PDEnterDebugger(char* pStr) {
  524.     static unsigned char* save_it;
  525.     LOG_TRACE("(\"%s\")", pStr);
  526.  
  527.     // FIXME: uses __CrtDbgReport when using MSVC runtime
  528.     STUB_ONCE();
  529.  
  530.     dr_dprintf("PDEnterDebugger(): %s", pStr);
  531.     // ShowCursor(1);
  532.     abort();
  533.     // ShowCursor(0);
  534. }
  535.  
  536. // IDA: void __cdecl PDEndItAllAndReRunTheBastard()
  537. void PDEndItAllAndReRunTheBastard(void) {
  538.     LOG_TRACE("()");
  539.     NOT_IMPLEMENTED();
  540. }
  541.  
  542. // IDA: int __usercall LoopLimitTooLow@<EAX>(tU32 limit@<EAX>)
  543. int LoopLimitTooLow(tU32 limit) {
  544.     clock_t start;
  545.     tU32 count;
  546.     tU32 val;
  547.     LOG_TRACE("(%d)", limit);
  548.     NOT_IMPLEMENTED();
  549. }
  550.  
  551. // IDA: tS32 __cdecl UpperLoopLimit()
  552. tS32 UpperLoopLimit(void) {
  553.     tU32 limit;
  554.     LOG_TRACE("()");
  555.     NOT_IMPLEMENTED();
  556. }
  557.  
  558. // IDA: int __cdecl InitJoysticks()
  559. int InitJoysticks(void) {
  560.     LOG_TRACE("()");
  561.     NOT_IMPLEMENTED();
  562. }
  563.  
  564. // IDA: tU32 __usercall ReadJoystickAxis@<EAX>(int pBit@<EAX>)
  565. tU32 ReadJoystickAxis(int pBit) {
  566.     tU32 val;
  567.     tU32 count;
  568.     LOG_TRACE("(%d)", pBit);
  569.     NOT_IMPLEMENTED();
  570. }
  571.  
  572. // IDA: void __cdecl PDReadJoySticks()
  573. void PDReadJoySticks(void) {
  574.     tU32 temp1x;
  575.     tU32 temp1y;
  576.     tU32 temp2x;
  577.     tU32 temp2y;
  578.     LOG_TRACE("()");
  579.     NOT_IMPLEMENTED();
  580. }
  581.  
  582. // IDA: tS32 __cdecl PDGetJoy1X()
  583. tS32 PDGetJoy1X(void) {
  584.     tS32 joy;
  585.     LOG_TRACE("()");
  586.     NOT_IMPLEMENTED();
  587. }
  588.  
  589. // IDA: tS32 __cdecl PDGetJoy1Y()
  590. tS32 PDGetJoy1Y(void) {
  591.     tS32 joy;
  592.     LOG_TRACE("()");
  593.     NOT_IMPLEMENTED();
  594. }
  595.  
  596. // IDA: tS32 __cdecl PDGetJoy2X()
  597. tS32 PDGetJoy2X(void) {
  598.     tS32 joy;
  599.     LOG_TRACE("()");
  600.     NOT_IMPLEMENTED();
  601. }
  602.  
  603. // IDA: tS32 __cdecl PDGetJoy2Y()
  604. tS32 PDGetJoy2Y(void) {
  605.     tS32 joy;
  606.     LOG_TRACE("()");
  607.     NOT_IMPLEMENTED();
  608. }
  609.  
  610. // IDA: int __cdecl PDGetJoy1Button1()
  611. int PDGetJoy1Button1(void) {
  612.     LOG_TRACE("()");
  613.     NOT_IMPLEMENTED();
  614. }
  615.  
  616. // IDA: int __cdecl PDGetJoy1Button2()
  617. int PDGetJoy1Button2(void) {
  618.     LOG_TRACE("()");
  619.     NOT_IMPLEMENTED();
  620. }
  621.  
  622. // IDA: int __cdecl PDGetJoy1Button3()
  623. int PDGetJoy1Button3(void) {
  624.     LOG_TRACE("()");
  625.     NOT_IMPLEMENTED();
  626. }
  627.  
  628. // IDA: int __cdecl PDGetJoy1Button4()
  629. int PDGetJoy1Button4(void) {
  630.     LOG_TRACE("()");
  631.     NOT_IMPLEMENTED();
  632. }
  633.  
  634. // IDA: int __cdecl PDGetJoy2Button1()
  635. int PDGetJoy2Button1(void) {
  636.     LOG_TRACE("()");
  637.     NOT_IMPLEMENTED();
  638. }
  639.  
  640. // IDA: int __cdecl PDGetJoy2Button2()
  641. int PDGetJoy2Button2(void) {
  642.     LOG_TRACE("()");
  643.     NOT_IMPLEMENTED();
  644. }
  645.  
  646. // IDA: int __cdecl PDGetJoy2Button3()
  647. int PDGetJoy2Button3(void) {
  648.     LOG_TRACE("()");
  649.     NOT_IMPLEMENTED();
  650. }
  651.  
  652. // IDA: int __cdecl PDGetJoy2Button4()
  653. int PDGetJoy2Button4(void) {
  654.     LOG_TRACE("()");
  655.     NOT_IMPLEMENTED();
  656. }
  657.  
  658. // IDA: int __usercall PDFileUnlock@<EAX>(char *pThe_path@<EAX>)
  659. int PDFileUnlock(char* pThe_path) {
  660.     unsigned int attr;
  661.     LOG_TRACE("(\"%s\")", pThe_path);
  662.     // _dos_setfileattr_(pThe_path, 0);
  663.     return 0;
  664. }
  665.  
  666. // IDA: void __cdecl CriticalISR(INTPACK pRegs)
  667. void CriticalISR(INTPACK pRegs) {
  668.     LOG_TRACE("(%d)", pRegs);
  669.     NOT_IMPLEMENTED();
  670. }
  671.  
  672. // IDA: int __usercall PDCheckDriveExists2@<EAX>(char *pThe_path@<EAX>, char *pFile_name@<EDX>, tU32 pMin_size@<EBX>)
  673. int PDCheckDriveExists2(char* pThe_path, char* pFile_name, tU32 pMin_size) {
  674.     struct stat buf;
  675.     //void (*old_critical_isr)(); // Pierre-Marie Baty -- unused variable
  676.     int stat_failed;
  677.     //char slasher[4]; // Pierre-Marie Baty -- unused variable
  678.     char the_path[256];
  679.     LOG_TRACE("(\"%s\", \"%s\", %d)", pThe_path, pFile_name, pMin_size);
  680.  
  681.     //strcpy(slasher, "?:\\"); // Pierre-Marie Baty -- unused variable
  682.     if (pFile_name) {
  683.         PathCat(the_path, pThe_path, pFile_name);
  684.     } else {
  685.         strcpy(the_path, pThe_path);
  686.     }
  687.  
  688.     // Jeff: force unix dir separator >>
  689.     char* rep = the_path;
  690.     while ((rep = strchr(rep, '\\')) != NULL) {
  691.         *rep++ = '/';
  692.     }
  693.     // <<
  694.  
  695.     stat_failed = stat(the_path, &buf);
  696.     return stat_failed == 0 && buf.st_size >= pMin_size;
  697. }
  698.  
  699. // IDA: int __cdecl PDDoWeLeadAnAustereExistance()
  700. int PDDoWeLeadAnAustereExistance(void) {
  701.     tU32 block;
  702.  
  703.     block = LargestBlockAvail();
  704.  
  705.     dr_dprintf("PDDoWeLeadAnAustereExistance (sic): LargestBlockAvail=%d\n", block);
  706.  
  707.     if (gReal_graf_data_index == 0) {
  708.         return block < 13000000;
  709.     }
  710.     return block < 15000000;
  711. }
  712.  
  713. #endif
  714.  
  715. int CheckGorePasswordFile(char* pPassword) {
  716.     tPath_name path;
  717.     FILE* f;
  718.     char line[10];
  719.  
  720.     PathCat(path, "DATA", "PASS.TXT");
  721.     f = fopen(path, "rb");
  722.     if (f == NULL) {
  723.         return 0;
  724.     }
  725.     if (fgets(line, sizeof(line), f) == NULL) {
  726.         fclose(f);
  727.         return 0;
  728.     }
  729.     fclose(f);
  730. #if defined(DETHRACE_FIX_BUGS)
  731.     // Allow a final newline in DATA/PASS.TXT
  732.     while (strlen(line) > 0 && (line[strlen(line) - 1] == '\n' || line[strlen(line) - 1] == '\r')) {
  733.         line[strlen(line) - 1] = '\0';
  734.     }
  735. #endif
  736. #ifdef _WIN32
  737.     return _stricmp(line, pPassword) == 0; // Pierre-Marie Baty -- ISO C name compliance fix
  738. #else
  739.     return strcasecmp(line, pPassword) == 0;
  740. #endif
  741. }
  742.  
  743. // IDA: int __cdecl PDGetGorePassword()
  744. int PDGetGorePassword(void) {
  745.     //int ch; // Pierre-Marie Baty -- unused variable
  746.     //int len; // Pierre-Marie Baty -- unused variable
  747.     int chances;
  748.     char password[17];
  749.     LOG_TRACE("()");
  750.  
  751.     for (chances = 0; chances < 3; chances++) {
  752.         printf(chances == 0 ? "\n\n\n\n\nEnter password for uncut version...\n" : "\nIncorrect password, please try again...\n");
  753.         OS_ConsoleReadPassword(password, sizeof(password));
  754.         dr_dprintf("Password entered is '%s'", password);
  755.         if (CheckGorePasswordFile(password)) {
  756.             return 1;
  757.         }
  758.     }
  759.     return 0;
  760. }
  761.  
  762. // IDA: void __usercall PDDisplayGoreworthiness(int pGory@<EAX>)
  763. void PDDisplayGoreworthiness(int pGory) {
  764.     tU32 delay_start;
  765.     LOG_TRACE("(%d)", pGory);
  766.  
  767.     printf(pGory ? "\nPlaying full version...\n" : "\nPlaying zombie version...\n");
  768.     delay_start = 2;
  769.     gHarness_platform.Sleep(delay_start * 1000);
  770. }
  771.