Subversion Repositories Games.Carmageddon

Rev

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

  1. #include "init.h"
  2.  
  3. #include <stdlib.h>
  4. #include <time.h>
  5.  
  6. #include "car.h"
  7. #include "controls.h"
  8. #include "depth.h"
  9. #include "displays.h"
  10. #include "drfile.h"
  11. #include "drmem.h"
  12. #include "errors.h"
  13. #include "flicplay.h"
  14. #include "globvars.h"
  15. #include "globvrkm.h"
  16. #include "globvrpb.h"
  17. #include "grafdata.h"
  18. #include "graphics.h"
  19. #include "harness/config.h"
  20. #include "harness/trace.h"
  21. #include "loading.h"
  22. #include "loadsave.h"
  23. #include "netgame.h"
  24. #include "network.h"
  25. #include "oil.h"
  26. #include "opponent.h"
  27. #include "pd/sys.h"
  28. #include "pedestrn.h"
  29. #include "piping.h"
  30. #include "powerup.h"
  31. #include "pratcam.h"
  32. #include "raycast.h"
  33. #include "replay.h"
  34. #include "skidmark.h"
  35. #include "sound.h"
  36. #include "spark.h"
  37. #include "trig.h"
  38. #include "utility.h"
  39. #include "world.h"
  40.  
  41. #include "brender/brender.h"
  42.  
  43. int gGame_initialized;
  44. int gBr_initialized;
  45. int gBrZb_initialized;
  46. int gInitialisation_finished;
  47. int gRender_indent;
  48. tU32 gAustere_time;
  49. int gInitial_rank;
  50. int gCredits_per_rank[3];
  51. int gInitial_credits[3];
  52. int gNet_mode_of_last_game;
  53. br_material* gDefault_track_material;
  54.  
  55. // IDA: void __cdecl AllocateSelf()
  56. void AllocateSelf(void) {
  57.     LOG_TRACE("()");
  58.  
  59.     gSelf = BrActorAllocate(BR_ACTOR_NONE, NULL);
  60.     if (gSelf == NULL) {
  61.         FatalError(kFatalError_AllocateSelf);
  62.     }
  63.     gSelf = BrActorAdd(gNon_track_actor, gSelf);
  64.     if (gSelf == NULL) {
  65.         FatalError(kFatalError_AllocateSelf);
  66.     }
  67. }
  68.  
  69. // IDA: void __cdecl AllocateCamera()
  70. void AllocateCamera(void) {
  71.     br_camera* camera_ptr;
  72.     int i;
  73.     LOG_TRACE("()");
  74.  
  75.     for (i = 0; i < COUNT_OF(gCamera_list); i++) {
  76.         gCamera_list[i] = BrActorAllocate(BR_ACTOR_CAMERA, NULL);
  77.         if (gCamera_list[i] == NULL) {
  78.             FatalError(kFatalError_AllocateCamera);
  79.         }
  80.  
  81.         camera_ptr = gCamera_list[i]->type_data;
  82.         camera_ptr->type = BR_CAMERA_PERSPECTIVE_FOV;
  83.         camera_ptr->field_of_view = BrDegreeToAngle(gCamera_angle);
  84.         camera_ptr->hither_z = gCamera_hither;
  85.         camera_ptr->yon_z = gCamera_yon;
  86.         camera_ptr->aspect = (double)gWidth / (double)gHeight;
  87.     }
  88.  
  89.     gCamera_list[0] = BrActorAdd(gSelf, gCamera_list[0]);
  90.     if (gCamera_list[0] == NULL) {
  91.         FatalError(kFatalError_AllocateCamera);
  92.     }
  93.     gCamera_list[1] = BrActorAdd(gUniverse_actor, gCamera_list[1]);
  94.     if (gCamera_list[1] == NULL) {
  95.         FatalError(kFatalError_AllocateCamera);
  96.     }
  97.     gCamera = gCamera_list[0];
  98.     gRearview_camera = BrActorAllocate(BR_ACTOR_CAMERA, NULL);
  99.     if (gRearview_camera == NULL) {
  100.         FatalError(kFatalError_AllocateCamera);
  101.     }
  102.  
  103.     gRearview_camera->t.t.mat.m[2][2] = -1.0f;
  104.     camera_ptr = (br_camera*)gRearview_camera->type_data;
  105.     camera_ptr->hither_z = gCamera_hither;
  106.     camera_ptr->type = BR_CAMERA_PERSPECTIVE_FOV;
  107.     camera_ptr->yon_z = gCamera_yon;
  108.     camera_ptr->field_of_view = BrDegreeToAngle(gCamera_angle);
  109.     camera_ptr->aspect = (double)gWidth / (double)gHeight;
  110.     gRearview_camera = BrActorAdd(gSelf, gRearview_camera);
  111.     if (gRearview_camera == NULL) {
  112.         FatalError(kFatalError_AllocateCamera);
  113.     }
  114.     SetSightDistance(camera_ptr->yon_z);
  115. }
  116.  
  117. // IDA: void __cdecl ReinitialiseForwardCamera()
  118. void ReinitialiseForwardCamera(void) {
  119.     br_camera* camera_ptr;
  120.     float the_angle;
  121.     float d;
  122.     float w;
  123.     LOG_TRACE("()");
  124.  
  125.     camera_ptr = (br_camera*)gCamera->type_data;
  126.     if (gProgram_state.cockpit_on) {
  127.         the_angle = gCamera_angle / 2.0;
  128.  
  129.         d = atan(
  130.                 tandeg(the_angle)
  131.                 * (double)gRender_screen->height
  132.                 / (double)(gProgram_state.current_car.render_bottom[0] - gProgram_state.current_car.render_top[0]))
  133.             * 114.5915590261646;
  134.         camera_ptr->field_of_view = BrDegreeToAngle(d);
  135.         BrMatrix34Identity(&gCamera->t.t.mat);
  136.         gCamera->t.t.mat.m[3][0] = gProgram_state.current_car.driver_x_offset;
  137.         gCamera->t.t.mat.m[3][1] = gProgram_state.current_car.driver_y_offset;
  138.         gCamera->t.t.mat.m[3][2] = gProgram_state.current_car.driver_z_offset;
  139.         w = (float)(gRender_screen->base_y
  140.             + (gRender_screen->height / 2)
  141.             - (gProgram_state.current_car.render_bottom[0] + gProgram_state.current_car.render_top[0]) / 2);
  142.  
  143.         gCamera->t.t.mat.m[2][1] = tandeg(d / 2.0) * w * 2.0 / (float)gRender_screen->height;
  144.         camera_ptr->aspect = (float)gWidth / gHeight;
  145.         camera_ptr->yon_z = gYon_multiplier * gCamera_yon;
  146.         if (gProgram_state.which_view == eView_left) {
  147.             DRMatrix34PostRotateY(
  148.                 &gCamera->t.t.mat,
  149.                 BrDegreeToAngle(gProgram_state.current_car.head_left_angle));
  150.         } else if (gProgram_state.which_view == eView_right) {
  151.             DRMatrix34PostRotateY(
  152.                 &gCamera->t.t.mat,
  153.                 BrDegreeToAngle(gProgram_state.current_car.head_right_angle));
  154.         }
  155.         gCamera->t.t.mat.m[3][0] = gProgram_state.current_car.driver_x_offset;
  156.         gCamera->t.t.mat.m[3][1] = gProgram_state.current_car.driver_y_offset;
  157.         gCamera->t.t.mat.m[3][2] = gProgram_state.current_car.driver_z_offset;
  158.         SetSightDistance(camera_ptr->yon_z);
  159.         MungeForwardSky();
  160.     }
  161.     AssertYons();
  162. }
  163.  
  164. // IDA: void __cdecl AllocateRearviewPixelmap()
  165. void AllocateRearviewPixelmap(void) {
  166.     char* rear_screen_pixels;
  167.     LOG_TRACE("()");
  168.  
  169.     if (gRearview_screen) {
  170.         BrMemFree(gRearview_screen->pixels);
  171.         BrPixelmapFree(gRearview_screen);
  172.         BrPixelmapFree(gRearview_depth_buffer);
  173.         gRearview_screen = NULL;
  174.     }
  175.     if (gProgram_state.mirror_on) {
  176.         rear_screen_pixels = BrMemAllocate(
  177.             (gProgram_state.current_car.mirror_bottom - gProgram_state.current_car.mirror_top + 1)
  178.                 * (gProgram_state.current_car.mirror_right - gProgram_state.current_car.mirror_left + 4)
  179.                 * gGraf_specs[gGraf_spec_index].depth_bytes,
  180.             kMem_rear_screen_pixels);
  181.         if (gScreen->row_bytes < 0) {
  182.             BrFatal("..\\..\\source\\common\\init.c", 260, "Bruce bug at line %d, file ..\\..\\source\\common\\init.c", 4);
  183.         }
  184.         gRearview_screen = DRPixelmapAllocate(
  185.             gScreen->type,
  186.             gProgram_state.current_car.mirror_right - gProgram_state.current_car.mirror_left,
  187.             gProgram_state.current_car.mirror_bottom - gProgram_state.current_car.mirror_top,
  188.             rear_screen_pixels,
  189.             0);
  190.  
  191.         gRearview_screen->origin_x = gRearview_screen->width / 2;
  192.         gRearview_screen->origin_y = gRearview_screen->height / 2;
  193.         gRearview_depth_buffer = BrPixelmapMatch(gRearview_screen, BR_PMMATCH_DEPTH_16);
  194.     }
  195. }
  196.  
  197. // IDA: void __cdecl ReinitialiseRearviewCamera()
  198. void ReinitialiseRearviewCamera(void) {
  199.     br_camera* camera_ptr;
  200.     LOG_TRACE("()");
  201.  
  202.     camera_ptr = gRearview_camera->type_data;
  203.     camera_ptr->field_of_view = BrDegreeToAngle(gProgram_state.current_car.rearview_camera_angle);
  204.     camera_ptr->aspect = (gProgram_state.current_car.mirror_right - gProgram_state.current_car.mirror_left) / (float)(gProgram_state.current_car.mirror_bottom - gProgram_state.current_car.mirror_top);
  205.     gRearview_camera->t.t.translate.t.v[0] = gProgram_state.current_car.mirror_x_offset;
  206.     gRearview_camera->t.t.translate.t.v[1] = gProgram_state.current_car.mirror_y_offset;
  207.     gRearview_camera->t.t.translate.t.v[2] = gProgram_state.current_car.mirror_z_offset;
  208.     AllocateRearviewPixelmap();
  209.     MungeRearviewSky();
  210. }
  211.  
  212. // IDA: void __cdecl ReinitialiseRenderStuff()
  213. void ReinitialiseRenderStuff(void) {
  214.     int x_diff;
  215.     int y_diff;
  216.     LOG_TRACE("()");
  217.  
  218.     if (gProgram_state.cockpit_on) {
  219.         gProgram_state.current_render_left = gProgram_state.current_car.render_left[gProgram_state.cockpit_image_index];
  220.         gProgram_state.current_render_top = gProgram_state.current_car.render_top[gProgram_state.cockpit_image_index];
  221.         gProgram_state.current_render_right = gProgram_state.current_car.render_right[gProgram_state.cockpit_image_index];
  222.         gProgram_state.current_render_bottom = gProgram_state.current_car.render_bottom[gProgram_state.cockpit_image_index];
  223.     } else {
  224.         gProgram_state.current_render_top = (gGraf_specs[gGraf_spec_index].total_height / 18 & ~1) * gRender_indent;
  225.         gProgram_state.current_render_left = (gGraf_specs[gGraf_spec_index].total_width / 18 & ~3) * gRender_indent;
  226.         x_diff = gGraf_specs[gGraf_spec_index].total_width - gProgram_state.current_render_left;
  227.         y_diff = gGraf_specs[gGraf_spec_index].total_height - gProgram_state.current_render_top;
  228.         gProgram_state.current_render_right = x_diff;
  229.         gProgram_state.current_render_bottom = y_diff;
  230.     }
  231. }
  232.  
  233. // IDA: void __cdecl InstallFindFailedHooks()
  234. void InstallFindFailedHooks(void) {
  235.     LOG_TRACE("()");
  236.     NOT_IMPLEMENTED();
  237. }
  238.  
  239. // IDA: void __cdecl AllocateStandardLamp()
  240. void AllocateStandardLamp(void) {
  241.     //br_actor* lamp; // Pierre-Marie Baty -- unused variable
  242.     //int i; // Pierre-Marie Baty -- unused variable
  243.     STUB();
  244. }
  245.  
  246. // IDA: void __cdecl InitializeBRenderEnvironment()
  247. void InitializeBRenderEnvironment(void) {
  248.     br_model* arrow_model;
  249.     LOG_TRACE("()");
  250.  
  251.     gBr_initialized = 1;
  252.     InstallDRMemCalls();
  253.     InstallDRFileCalls();
  254.     SetBRenderScreenAndBuffers(0, 0, 0, 0);
  255.     gUniverse_actor = BrActorAllocate(BR_ACTOR_NONE, NULL);
  256.     if (gUniverse_actor == NULL) {
  257.         FatalError(kFatalError_AllocateRootActor);
  258.     }
  259.     gUniverse_actor->identifier = BrResStrDup(gUniverse_actor, "Root");
  260.     BrEnvironmentSet(gUniverse_actor);
  261.     gNon_track_actor = BrActorAllocate(BR_ACTOR_NONE, NULL);
  262.     if (gNon_track_actor == NULL) {
  263.         FatalError(kFatalError_AllocateRootActor);
  264.     }
  265.     BrActorAdd(gUniverse_actor, gNon_track_actor);
  266.     gDont_render_actor = BrActorAllocate(BR_ACTOR_NONE, 0);
  267.     if (gDont_render_actor == NULL) {
  268.         FatalError(kFatalError_AllocateRootActor);
  269.     }
  270.     gDont_render_actor->render_style = BR_RSTYLE_NONE;
  271.     BrActorAdd(gUniverse_actor, gDont_render_actor);
  272.     AllocateSelf();
  273.     AllocateCamera();
  274.     arrow_model = LoadModel("CPOINT.DAT");
  275.     BrModelAdd(arrow_model);
  276.     gArrow_actor = LoadActor("CPOINT.ACT");
  277.     gArrow_actor->model = arrow_model;
  278. }
  279.  
  280. // IDA: void __cdecl InitBRFonts()
  281. void InitBRFonts(void) {
  282.     LOG_TRACE("()");
  283.     gBig_font = LoadBRFont("BIGFONT.FNT");
  284.     gFont_7 = LoadBRFont("FONT7.FNT");
  285.     gHeadup_font = LoadBRFont("HEADUP.FNT");
  286. }
  287.  
  288. // IDA: void __cdecl AustereWarning()
  289. void AustereWarning(void) {
  290.     LOG_TRACE("()");
  291.  
  292.     ClearEntireScreen();
  293.  
  294.     if (gAusterity_mode) {
  295.         LoadFont(FONT_GRNLIT);
  296.         TransDRPixelmapText(gBack_screen,
  297.             (gBack_screen->width - DRTextWidth(&gFonts[FONT_GRNLIT], GetMiscString(kMiscString_LOW_MEMORY_MODE_INVOKED))) / 2,
  298.             0,
  299.             &gFonts[FONT_GRNLIT],
  300.             GetMiscString(kMiscString_LOW_MEMORY_MODE_INVOKED),
  301.             gBack_screen->width);
  302.         PDScreenBufferSwap(0);
  303.         gAustere_time = PDGetTotalTime();
  304.         DisposeFont(FONT_GRNLIT);
  305.     } else {
  306.         gAustere_time = gAusterity_mode;
  307.     }
  308. }
  309.  
  310. // IDA: void __cdecl InitLineStuff()
  311. void InitLineStuff(void) {
  312.     LOG_TRACE("()");
  313.     NOT_IMPLEMENTED();
  314. }
  315.  
  316. // IDA: void __cdecl InitSmokeStuff()
  317. void InitSmokeStuff(void) {
  318.     //static br_token_value fadealpha[3]; // Pierre-Marie Baty -- unused variable
  319.     //tPath_name path; // Pierre-Marie Baty -- unused variable
  320.     LOG_TRACE("()");
  321.     NOT_IMPLEMENTED();
  322. }
  323.  
  324. // IDA: void __cdecl Init2DStuff()
  325. void Init2DStuff(void) {
  326.     //br_camera* camera; // Pierre-Marie Baty -- unused variable
  327.     //static br_token_value fadealpha[3]; // Pierre-Marie Baty -- unused variable
  328.     //tPath_name path; // Pierre-Marie Baty -- unused variable
  329.     //br_scalar prat_u; // Pierre-Marie Baty -- unused variable
  330.     //br_scalar prat_v; // Pierre-Marie Baty -- unused variable
  331.     LOG_TRACE("()");
  332.     NOT_IMPLEMENTED();
  333. }
  334.  
  335. // IDA: void __usercall InitialiseApplication(int pArgc@<EAX>, char **pArgv@<EDX>)
  336. void InitialiseApplication(int pArgc, char** pArgv) {
  337.  
  338.     if (harness_game_config.gore_check) {
  339.         gProgram_state.sausage_eater_mode = gSausage_override ? 1 : (PDGetGorePassword() ? 0 : 1);
  340.         PDDisplayGoreworthiness(!gProgram_state.sausage_eater_mode);
  341.     } else {
  342.         gProgram_state.sausage_eater_mode = gSausage_override;
  343.     }
  344.  
  345.     MAMSInitMem();
  346.     PrintMemoryDump(gSausage_override, *pArgv);
  347.     if (gAustere_override || PDDoWeLeadAnAustereExistance() != 0) {
  348.         gAusterity_mode = 1;
  349.     }
  350.  
  351.     srand(time(NULL));
  352.     BrV1dbBeginWrapper_Float();
  353.     CreateStainlessClasses();
  354.     InitWobbleStuff();
  355.     LoadGeneralParameters();
  356.     DefaultNetName();
  357.     strcpy(gProgram_state.player_name[0], "MAX DAMAGE");
  358.     strcpy(gProgram_state.player_name[1], "DIE ANNA");
  359.     RestoreOptions();
  360.     LoadKeyMapping();
  361.     if (!PDInitScreenVars(pArgc, pArgv)) {
  362.         FatalError(kFatalError_UnsupportedScreenDepth);
  363.     }
  364.     CalcGrafDataIndex();
  365.     PDInitScreen();
  366.     InitializeBRenderEnvironment();
  367.     InitDRFonts();
  368.     InitBRFonts();
  369.     LoadMiscStrings();
  370.     LoadInRegistees();
  371.     FinishLoadingGeneral();
  372.     InitializePalettes();
  373.     AustereWarning();
  374.     LoadInterfaceStrings();
  375.     InitializeActionReplay();
  376.     FlicPaletteAllocate();
  377.     InitInterfaceLoadState();
  378.     InitTransientBitmaps();
  379.     InitSound();
  380.     InitHeadups();
  381.     gDefault_track_material = BrMaterialAllocate("gDefault_track_material");
  382.     gDefault_track_material->index_base = 227;
  383.     gDefault_track_material->index_range = 1;
  384.     BrMaterialAdd(gDefault_track_material);
  385.     InitShadow();
  386.     InitFlics();
  387.     AllocateStandardLamp();
  388.     InitAmbience();
  389.     LoadOpponents();
  390.     LoadPowerups();
  391.     LoadRaces(gRace_list, &gNumber_of_races, -1);
  392.     InitPaletteAnimate();
  393.     InitRayCasting();
  394.     InitDepthEffects();
  395.     InitialiseStorageSpace(&gOur_car_storage_space, 40, 2, 40, 30);
  396.     InitialiseStorageSpace(&gTheir_cars_storage_space, 300, 50, 500, 200);
  397.     InitialiseStorageSpace(&gPedestrians_storage_space, 500, 10, 0, 0);
  398.     InitialiseStorageSpace(&gTrack_storage_space, 400, 50, 400, 1000);
  399.     InitOilSpills();
  400.     if (gAustere_time) {
  401.         while (PDGetTotalTime() - gAustere_time < 2000) {
  402.         }
  403.     }
  404.     ClearEntireScreen();
  405.     InitSkids();
  406.     InitPeds();
  407.     gProgram_state.track_spec.the_actor = NULL;
  408.     gCD_is_in_drive = TestForOriginalCarmaCDinDrive();
  409.     SwitchToLoresMode();
  410.     PrintMemoryDump(0, "AFTER APPLICATION INITIALISATION");
  411. }
  412.  
  413. // IDA: void __usercall InitialiseDeathRace(int pArgc@<EAX>, char **pArgv@<EDX>)
  414. void InitialiseDeathRace(int pArgc, char** pArgv) {
  415.     PDInitialiseSystem();
  416.  
  417.     InitialiseApplication(pArgc, pArgv);
  418.     // dword_112DF8 = 1;  // never checked by game
  419. }
  420.  
  421. // IDA: void __usercall InitGame(int pStart_race@<EAX>)
  422. void InitGame(int pStart_race) {
  423.     int i;
  424.     LOG_TRACE("(%d)", pStart_race);
  425.  
  426.     gWaiting_for_unpause = 1;
  427.     gWait_for_it = 1;
  428.     if (gNet_mode != eNet_mode_none) {
  429.         gCredit_period = gCredit_period_network[gCurrent_net_game->type];
  430.     } else {
  431.         gCredit_period = gCredit_period_single[gProgram_state.skill_level];
  432.     }
  433.     SwitchToRealResolution();
  434.     gGame_to_load = -1;
  435.     gCurrent_race.number_of_racers = 0;
  436.     LoadHeadupImages();
  437.     gGame_initialized = 1;
  438.     gNet_mode_of_last_game = gNet_mode;
  439.     gNo_races_yet = 1;
  440.     NetPlayerStatusChanged(ePlayer_status_loading);
  441.     gProgram_state.current_race_index = pStart_race;
  442.     if (harness_game_info.mode == eGame_carmageddon_demo || harness_game_info.mode == eGame_splatpack_demo || harness_game_info.mode == eGame_splatpack_xmas_demo) {
  443.         gProgram_state.current_car.power_up_levels[0] = gDemo_armour;
  444.         gProgram_state.current_car.power_up_levels[1] = gDemo_power;
  445.         gProgram_state.current_car.power_up_levels[2] = gDemo_offensive;
  446.     } else {
  447.         for (i = 0; i < COUNT_OF(gProgram_state.current_car.power_up_levels); i++) {
  448.             gProgram_state.current_car.power_up_levels[i] = 0;
  449.         }
  450.     }
  451.     for (i = 0; i < gNumber_of_races; i++) {
  452.         gRace_list[i].been_there_done_that = 0;
  453.     }
  454.     for (i = 0; i < gNumber_of_racers; i++) {
  455.         gOpponents[i].dead = 0;
  456.     }
  457.     gProgram_state.rank = gInitial_rank;
  458.     gProgram_state.credits = gInitial_credits[gProgram_state.skill_level];
  459.     gProgram_state.credits_per_rank = gCredits_per_rank[gProgram_state.skill_level];
  460.     gProgram_state.number_of_cars = 1;
  461.     gProgram_state.cars_available[0] = gProgram_state.frank_or_anniness;
  462.     gProgram_state.game_completed = 0;
  463.     gProgram_state.redo_race_index = -1;
  464.     gWait_for_it = 0;
  465.     SwitchToLoresMode();
  466. }
  467.  
  468. // IDA: void __cdecl DisposeGameIfNecessary()
  469. void DisposeGameIfNecessary(void) {
  470.     int i;
  471.     LOG_TRACE("()");
  472.  
  473.     if (gNet_mode != eNet_mode_none) {
  474.         NetLeaveGame(gCurrent_net_game);
  475.     }
  476.     if (gGame_initialized) {
  477.         DisposeHeadupImages();
  478.         gGame_initialized = 0;
  479.         if (gNet_mode_of_last_game) {
  480.             for (i = 0; i < gNumber_of_net_players; i++) {
  481.                 DisposeCar(gNet_players[i].car, gNet_players[i].car_index);
  482.             }
  483.             PossibleService();
  484.             LoadRaces(gRace_list, &gNumber_of_races, -1);
  485.             DisposeStorageSpace(&gNet_cars_storage_space);
  486.         }
  487.     }
  488.     ShutdownNetIfRequired();
  489. }
  490.  
  491. // IDA: void __cdecl LoadInTrack()
  492. void LoadInTrack(void) {
  493.     LOG_TRACE("()");
  494.  
  495.     LoadTrack(gProgram_state.track_file_name, &gProgram_state.track_spec, &gCurrent_race);
  496. }
  497.  
  498. // IDA: void __cdecl DisposeTrack()
  499. void DisposeTrack(void) {
  500.     LOG_TRACE("()");
  501.  
  502.     FreeTrack(&gProgram_state.track_spec);
  503. }
  504.  
  505. // IDA: void __usercall CopyMaterialColourFromIndex(br_material *pMaterial@<EAX>)
  506. void CopyMaterialColourFromIndex(br_material* pMaterial) {
  507.     LOG_TRACE("(%p)", pMaterial);
  508.     NOT_IMPLEMENTED();
  509. }
  510.  
  511. // IDA: void __cdecl InitRace()
  512. void InitRace(void) {
  513.     LOG_TRACE("()");
  514.  
  515.     SwitchToRealResolution();
  516.     // TODO: dword_5454C4 = 0;
  517.     ClearConcussion();
  518.     ClearWobbles();
  519.     ClearHeadups();
  520.     ResetOilSpills();
  521.     HideSkids();
  522.     PossibleService();
  523.     BuildColourTable(gRender_palette);
  524.     PossibleService();
  525.     // TODO: dword_55142C = 0;
  526.     gStart_race_sent = 0;
  527.     gProgram_state.frame_rate_headup = NewTextHeadupSlot(0, 0, 0, -1, "");
  528.     if (TranslationMode()) {
  529.         if (gAusterity_mode) {
  530.             FlushInterfaceFonts();
  531.         }
  532.     } else {
  533.         LoadFont(kFont_ORANGHED);
  534.         LoadFont(kFont_BLUEHEAD);
  535.         LoadFont(kFont_GREENHED);
  536.     }
  537.     LoadFont(kFont_MEDIUMHD);
  538.     LoadFont(kFont_TIMER);
  539.     PossibleService();
  540.     LoadFont(kFont_NEWHITE);
  541.     LoadFont(kFont_NEWRED);
  542.     LoadFont(kFont_NEWBIGGR);
  543.     PossibleService();
  544.     ResetRecoveryVouchers();
  545.     gMap_mode = 0;
  546.     gProgram_state.cockpit_image_index = 0;
  547.     if (gNet_mode != eNet_mode_none) {
  548.         gNet_cash_headup = NewTextHeadupSlot(13, 0, 0, -6, "");
  549.         gNet_ped_headup = NewTextHeadupSlot(14, 0, 0, -6, "");
  550.     } else {
  551.         gCredits_won_headup = NewTextHeadupSlot(1, 0, 0, -6, "");
  552.         gPed_kill_count_headup = NewTextHeadupSlot(2, 0, 0, -6, "");
  553.         gCar_kill_count_headup = NewTextHeadupSlot(12, 0, 0, -6, "");
  554.         gTimer_headup = NewTextHeadupSlot(7, 0, 0, -5, "");
  555.         gTime_awarded_headup = NewTextHeadupSlot(11, 0, 0, -2, "");
  556.         gLaps_headup = NewTextHeadupSlot(8, 0, 0, -6, "");
  557.     }
  558.     PossibleService();
  559.     gProgram_state.which_view = eView_forward;
  560.     gProgram_state.new_view = eView_undefined;
  561.     gProgram_state.pratcam_move_start = 0;
  562.     gAction_replay_mode = 0;
  563.     SwitchToRealResolution();
  564.     InitPratcam();
  565.     SwitchToLoresMode();
  566.     gProgram_state.credits_earned = 0;
  567.     gProgram_state.credits_lost = 0;
  568.     gProgram_state.peds_killed = 0;
  569.     gProgram_state.revs = 2000;
  570.     gProgram_state.current_car.speed = 0.0;
  571.     gProgram_state.current_car.steering_angle = 0.0;
  572.     gProgram_state.current_car.lf_sus_position = 0.0;
  573.     gProgram_state.current_car.rf_sus_position = 0.0;
  574.     gProgram_state.current_car.lr_sus_position = 0.0;
  575.     gProgram_state.current_car.rr_sus_position = 0.0;
  576.     PossibleService();
  577.     gAuto_repair = 0;
  578.     SetIntegerMapRenders();
  579.     AdjustRenderScreenSize();
  580.     PrintMemoryDump(0, "DIRECTLY BEFORE LOADING IN TRACK");
  581.     LoadInTrack();
  582.     if (gYon_multiplier != 1.0) {
  583.         AdjustRenderScreenSize();
  584.     }
  585.     PrintMemoryDump(0, "DIRECTLY AFTER LOADING IN TRACK");
  586.     LoadCopCars();
  587.     PrintMemoryDump(0, "AFTER LOADING IN COPS");
  588.     SaveShadeTables();
  589.     gCountdown = 7;
  590.     gTimer = 1000 * gCurrent_race.initial_timer[gProgram_state.skill_level];
  591.     gLap = 1;
  592.     gTotal_laps = gCurrent_race.total_laps;
  593.     gCheckpoint = 1;
  594.     gCheckpoint_count = gCurrent_race.check_point_count;
  595.     gFreeze_timer = 0;
  596.     gFree_repairs = 0;
  597.     if (gNet_mode) {
  598.         gShow_opponents = gCurrent_net_game->options.show_players_on_map;
  599.     } else {
  600.         gShow_opponents = 1;
  601.     }
  602.     gOn_drugs = 0;
  603.     gRace_finished = 0;
  604.     gOpponent_speed_factor = 1.0f;
  605.     gCop_speed_factor = 1.0f;
  606.     gGravity_multiplier = gDefault_gravity;
  607.     gPinball_factor = 0;
  608.     gInstant_handbrake = 0;
  609.     if (gNet_mode) {
  610.         gShow_peds_on_map = gCurrent_net_game->options.show_peds_on_map;
  611.     } else {
  612.         gShow_peds_on_map = 0;
  613.     }
  614.     PossibleService();
  615.     SetCarSuspGiveAndHeight(&gProgram_state.current_car, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f);
  616.     InitPowerups();
  617.     PossibleService();
  618.     ResetSparks();
  619.     PossibleService();
  620.     MakeSavedGame(&gPre_race_saved_game);
  621.     PossibleService();
  622.     InitPlayers();
  623.     if (gNet_mode) {
  624.         gProgram_state.credits_earned = gInitial_net_credits[gCurrent_net_game->options.starting_money_index];
  625.         InitNetGameplayStuff();
  626.     }
  627.     gInitialised_grid = 0;
  628.     SwitchToLoresMode();
  629. }
  630.  
  631. // IDA: void __cdecl DisposeRace()
  632. void DisposeRace(void) {
  633.     LOG_TRACE("()");
  634.  
  635.     PossibleService();
  636.     DisposePiping();
  637.     PossibleService();
  638.     CloseDownPowerUps();
  639.     PossibleService();
  640.     if (!TranslationMode()) {
  641.         DisposeFont(1);
  642.         DisposeFont(2);
  643.         DisposeFont(3);
  644.     }
  645.     PossibleService();
  646.     DisposeFont(6);
  647.     DisposeFont(7);
  648.     DisposeFont(8);
  649.     DisposeFont(4);
  650.     DisposeFont(5);
  651.     PossibleService();
  652.     DisposeSavedShadeTables();
  653.     PossibleService();
  654.     DisposeSoundSources();
  655.     PossibleService();
  656.     DisposeOpponents();
  657.     PossibleService();
  658.     DisposePedestrians();
  659.     PossibleService();
  660.     DisposePratcam();
  661.     PossibleService();
  662. }
  663.  
  664. // IDA: int __cdecl GetScreenSize()
  665. int GetScreenSize(void) {
  666.     LOG_TRACE("()");
  667.  
  668.     return gRender_indent;
  669. }
  670.  
  671. // IDA: void __usercall SetScreenSize(int pNew_size@<EAX>)
  672. void SetScreenSize(int pNew_size) {
  673.     LOG_TRACE("(%d)", pNew_size);
  674.  
  675.     gRender_indent = pNew_size;
  676. }
  677.