REDRIVER2/src_rebuild/GAME/C/MAIN.C
2020-04-20 12:34:37 +06:00

3321 lines
64 KiB
C

#include "THISDUST.H"
#include "MAIN.H"
#include "LIBETC.H"
#include "LIBSPU.H"
#include "LIBGPU.H"
#include "LIBAPI.H"
#include "LIBMCRD.H"
#include "../ASM/ASMTEST.H"
#include "SYSTEM.H"
#include "PAD.H"
#include "SOUND.H"
#include "FMVPLAY.H"
#include "E3STUFF.H"
#include "GAMESND.H"
#include "SCORES.H"
#include "GLAUNCH.H"
#include "LOADVIEW.H"
#include "REPLAYS.H"
#include "EVENT.H"
#include "MISSION.H"
#include "CUTSCENE.H"
#include "TEXTURE.H"
#include "SKY.H"
#include "PRES.H"
#include "DRAW.H"
#include "DENTING.H"
#include "COSMETIC.H"
#include "PEDEST.H"
#include "SPOOL.H"
#include "MAP.H"
#include "OBJANIM.H"
#include "HANDLING.H"
#include "DRIVINGGAMES.H"
#include "BOMBERMAN.H"
#include "PLAYERS.H"
#include "AI.H"
#include "CIV_AI.H"
#include "COP_AI.H"
#include "CAMERA.H"
#include "EVENT.H"
#include "OVERLAY.H"
#include "DEBRIS.H"
#include "JOB_FX.H"
#include "DIRECTOR.H"
#include "CONVERT.H"
#include "TILE.H"
#include "OVERMAP.H"
#include "MOTION_C.H"
#include "DR2ROADS.H"
#include "MODELS.H"
#include "CARS.H"
#include "COP_AI.H"
#include "GLAUNCH.H"
#include "OBJCOLL.H"
#include "MC_SND.H"
#include "FELONY.H"
#include "XAPLAY.H"
#include "SHADOW.H"
#include "PAUSE.H"
#include <stdlib.h>
#include "../FRONTEND/FEMAIN.H"
int scr_z = 0;
int levelstartpos[8][4] = {
{ 0x12B1, 0xFFFFFC00, 0xFFFC9794, 0},
{ 0xFFFC74AC, 0x800, 0xFFFC6961, 0},
{ 0x383CB, 0xFFFFFC00, 0xABE1E, 0},
{ 0x165EF, 0xFFFFFC00, 0xFFFAB3D9, 0},
{ 0x24548, 0x1813, 0xFFFE4A80, 0},
{ 0xFFFD67F0, 0x1813, 0x58228, 0},
{ 0xFFFFD6FC, 0xFFFFE7ED, 0xFFFFA980, 0},
{ 0xFFFFDCDD, 0xFFFFE7ED, 0xF8A7, 0},
};
enum LevLumpType
{
// known lumps indexes
LUMP_MODELS = 1, // level models
LUMP_MAP = 2, // map info
LUMP_TEXTURENAMES = 5, // texture name strings
LUMP_ROADMAP = 7, // unused lump in Driver 2
LUMP_ROADS = 8, // unused lump in Driver 2
LUMP_JUNCTIONS = 9, // unused lump in Driver 2
LUMP_ROADSURF = 10, // unused lump in Driver 2
LUMP_MODELNAMES = 12, // model name strings
LUMP_ROADBOUNDS = 16, // unused lump in Driver 2
LUMP_JUNCBOUNDS = 17, // unused lump in Driver 2
LUMP_SUBDIVISION = 20,
LUMP_LOWDETAILTABLE = 21, // LOD tables for models
LUMP_MOTIONCAPTURE = 22, // motion capture/animation data for peds and Tanner
LUMP_OVERLAYMAP = 24, // overlay map
LUMP_PALLET = 25, // car palettes
LUMP_SPOOLINFO = 26, // level region spooling
LUMP_CAR_MODELS = 28, // car models
LUMP_CHAIR = 33,
LUMP_TEXTUREINFO = 34, // texture page info and details (atlases)
LUMP_LEVELDESC = 35,
LUMP_LEVELDATA = 36,
LUMP_LUMPDESC = 37,
LUMP_STRAIGHTS2 = 40, // road straights (AI)
LUMP_CURVES2 = 41,
LUMP_JUNCTIONS2 = 42, // previously LUMP_JUNCTIONS2
LUMP_JUNCTIONS2_NEW = 43, // Only appear in release Driver2
};
REPLAY_STREAM ReplayStreams[8];
int HitLeadCar = 0;
int game_over = 0;
int saved_counter = 0;
int saved_leadcar_pos = 0;
int gStopPadReads = 0;
int DawnCount = 0;
int variable_weather = 0;
int current_camera_angle = 0x800;
int gDieWithFade = 0;
int FrameCnt = 0;
unsigned char defaultPlayerModel[2] = { 0 }; // offset 0xAA604
unsigned char defaultPlayerPalette = 0; // offset 0xAA606
// decompiled code
// original method signature:
// void /*$ra*/ ProcessLumps(char *lump_ptr /*$s1*/, int lump_size /*$a1*/)
// line 2672, offset 0x00058c08
/* begin block 1 */
// Start line: 2673
// Start offset: 0x00058C08
// Variables:
// int quit; // $s3
// int lump_type; // $v1
// int seg_size; // $s0
/* begin block 1.1 */
// Start line: 2686
// Start offset: 0x00058D94
/* begin block 1.1.1 */
// Start line: 2845
// Start offset: 0x00058F7C
// Variables:
// struct DRIVER2_JUNCTION *dst; // $a0
// unsigned long *src; // $a2
// int i; // $v1
/* end block 1.1.1 */
// End offset: 0x00058FC4
// End Line: 2858
/* begin block 1.1.2 */
// Start line: 2865
// Start offset: 0x00058FCC
// Variables:
// struct DRIVER2_JUNCTION *dst; // $a0
// unsigned long *src; // $a2
// int i; // $v1
/* end block 1.1.2 */
// End offset: 0x00059018
// End Line: 2878
/* end block 1.1 */
// End offset: 0x00059024
// End Line: 2890
/* end block 1 */
// End offset: 0x00059050
// End Line: 2894
/* begin block 2 */
// Start line: 5344
/* end block 2 */
// End Line: 5345
void ProcessLumps(char *lump_ptr, int lump_size)
{
int quit;
int lump_type;
DRIVER2_JUNCTION *pDVar8;
ulong *puVar9;
int size;
int *ptr;
quit = false;
do {
lump_type = *(int *)lump_ptr;
size = *(int *)(lump_ptr + 4);
ptr = (int *)(lump_ptr + 8);
if (lump_type == LUMP_LOWDETAILTABLE)
{
printf("LUMP_LOWDETAILTABLE: size: %d\n", size);
ProcessLowDetailTable((char *)ptr, size);
}
else if (lump_type == LUMP_CHAIR)
{
printf("LUMP_CHAIR: size: %d\n", size);
ProcessChairLump((char *)ptr, size);
}
else if (lump_type == LUMP_MOTIONCAPTURE)
{
printf("LUMP_MOTIONCAPTURE: size: %d\n", size);
ProcessMotionLump((char *)ptr, size);
gLoadedMotionCapture = 1;
}
else if (lump_type == LUMP_OVERLAYMAP)
{
printf("LUMP_OVERLAYMAP: size: %d\n", size);
ProcessOverlayLump((char *)ptr, size);
gLoadedOverlay = 1;
}
else if (lump_type == LUMP_MAP)
{
map_lump = (char *)ptr;
}
else if (lump_type == LUMP_SPOOLINFO)
{
printf("LUMP_SPOOLINFO: size: %d\n", size);
ProcessSpoolInfoLump((char *)ptr, lump_size);
ProcessMapLump(map_lump, 0);
// [A] I don't think it's used anymore
//region_buffer_xor =
// (cells_down >> 5 & 2U | cells_across >> 6 & 1U) << 2;
//sdSelfModifyingCode =
// sdSelfModifyingCode ^
// (sdSelfModifyingCode ^ region_buffer_xor) & 0xc;
}
else if (lump_type == LUMP_CURVES2)
{
printf("LUMP_CURVES2: size: %d\n", size);
ProcessCurvesDriver2Lump((char *)ptr, size);
}
else if (lump_type == LUMP_TEXTURENAMES)
{
printf("LUMP_TEXTURENAMES: size: %d\n", size);
texturename_buffer = (char*)ptr;
}
else if (lump_type == LUMP_PALLET)
{
printf("LUMP_PALLET: size: %d\n", size);
palette_lump = (char*)ptr;
}
else if (lump_type == LUMP_TEXTUREINFO)
{
printf("LUMP_TEXTUREINFO: size: %d\n", size);
ProcessTextureInfo((char *)ptr);
}
else if (lump_type == LUMP_STRAIGHTS2)
{
printf("LUMP_STRAIGHTS2: size: %d\n", size);
ProcessStraightsDriver2Lump((char *)ptr, size);
}
else if (lump_type == LUMP_JUNCTIONS2_NEW)
{
printf("LUMP_JUNCTIONS2_NEW: size: %d\n", size);
ProcessJunctionsDriver2Lump((char *)ptr, size, 0);
lump_type = NumTempJunctions;
pDVar8 = Driver2JunctionsPtr;
puVar9 = Driver2TempJunctionsPtr;
if (0 < NumTempJunctions)
{
do {
lump_type = lump_type + -1;
pDVar8->flags = *puVar9;
pDVar8 = pDVar8 + 1;
puVar9 = puVar9 + 1;
} while (lump_type != 0);
}
}
else if (lump_type == LUMP_JUNCTIONS2)
{
printf("LUMP_JUNCTIONS2: size: %d\n", size);
ProcessJunctionsDriver2Lump
((char *)ptr, size, 1);
lump_type = NumTempJunctions;
pDVar8 = Driver2JunctionsPtr;
puVar9 = Driver2TempJunctionsPtr;
if (0 < NumTempJunctions) {
do {
lump_type = lump_type + -1;
pDVar8->flags = *puVar9;
pDVar8 = pDVar8 + 1;
puVar9 = puVar9 + 1;
} while (lump_type != 0);
}
}
else if (lump_type == LUMP_JUNCTIONS)
{
printf("LUMP_JUNCTIONS: size: %d\n", size);
ProcessJunctionsLump((char *)ptr, size);
}
else if (lump_type == LUMP_CAR_MODELS)
{
printf("LUMP_CAR_MODELS: size: %d\n", size);
car_models_lump = (char*)ptr;
}
else if (lump_type == LUMP_MODELS)
{
printf("LUMP_MODELS: size: %d\n", size);
ProcessMDSLump((char *)ptr, size);
ProcessCarModelLump(car_models_lump, 0);
InitModelNames();
SetUpEvents(1);
}
else if (lump_type == LUMP_ROADMAP)
{
printf("LUMP_ROADMAP: size: %d\n", size);
NewProcessRoadMapLump(&roadMapLumpData, (char *)ptr);
}
else if (lump_type == LUMP_ROADS)
{
printf("LUMP_ROADS: size: %d\n", size);
ProcessRoadsLump((char *)ptr, size);
}
if (lump_type == LUMP_ROADBOUNDS)
{
printf("LUMP_ROADBOUNDS: size: %d\n", size);
ProcessRoadBoundsLump((char *)ptr, size);
}
else if (lump_type == LUMP_JUNCBOUNDS)
{
printf("LUMP_JUNCBOUNDS: size: %d\n", size);
ProcessJuncBoundsLump((char *)ptr, size);
}
else if (lump_type == LUMP_SUBDIVISION)
{
printf("LUMP_SUBDIVISION: size: %d\n", size);
ProcessSubDivisionLump((char *)ptr, size);
}
else if (lump_type == LUMP_ROADSURF)
{
printf("LUMP_ROADSURF: size: %d\n", size);
}
else if (lump_type == LUMP_MODELNAMES)
{
printf("LUMP_MODELNAMES: size: %d\n", size);
modelname_buffer = (char *)ptr;
}
else if (lump_type == 0xff)
{
quit = true;
}
lump_size = size + 3;
lump_ptr = (char*)ptr + (lump_size & ~0x3); // aligned to 4-byte boundary
if (quit)
return;
} while (true);
}
// decompiled code
// original method signature:
// void /*$ra*/ LoadGameLevel()
// line 2896, offset 0x00059050
/* begin block 1 */
// Start line: 2898
// Start offset: 0x00059050
// Variables:
// int sector; // stack offset -32
// int nsectors; // $s1
// char name[64]; // stack offset -96
// char *malloc_lump; // $s2
/* end block 1 */
// End offset: 0x00059238
// End Line: 2967
/* begin block 2 */
// Start line: 5806
/* end block 2 */
// End Line: 5807
/* begin block 3 */
// Start line: 5809
/* end block 3 */
// End Line: 5810
/* begin block 4 */
// Start line: 5810
/* end block 4 */
// End Line: 5811
/* begin block 5 */
// Start line: 5818
/* end block 5 */
// End Line: 5819
/* WARNING: Unknown calling convention yet parameter storage is locked */
int SpoolLumpOffset;
SEATED_PEDESTRIANS* seated_pedestrian = NULL;
// [D]
void LoadGameLevel(void)
{
char *malloc_lump;
int nsectors;
int sector;
seated_pedestrian = NULL;
LoadCosmetics(GameLevel);
if (gMultiplayerLevels == 0)
{
if (gTimeOfDay == 3) {
SetCityType(CITYTYPE_NIGHT);
}
else {
SetCityType(CITYTYPE_DAY);
}
}
else {
if (gTimeOfDay == 3) {
SetCityType(CITYTYPE_MULTI_NIGHT);
}
else {
SetCityType(CITYTYPE_MULTI_DAY);
}
}
ReportMode(0);
sector = citylumps[GameLevel][0].x;
if (sector < 0) {
sector = sector + 2047;
}
nsectors = citylumps[GameLevel][0].y;
sector = sector / CDSECTOR_SIZE;
if (nsectors < 0) {
nsectors = nsectors + (CDSECTOR_SIZE-1);
}
nsectors = nsectors / CDSECTOR_SIZE;
#ifdef PSX
loadsectors(_frontend_buffer, sector, nsectors);
#else
extern char g_CurrentLevelFileName[64];
loadsectorsPC(g_CurrentLevelFileName, _frontend_buffer, sector, nsectors);
#endif // PSX
sector += nsectors;
// CITYLUMP_DATA1
ProcessLumps(_frontend_buffer+8, nsectors * CDSECTOR_SIZE);
// CITYLUMP_TPAGE is right next after DATA1
LoadPermanentTPages(&sector);
malloc_lump = mallocptr;
sector = citylumps[GameLevel][CITYLUMP_DATA2].x;
if (sector < 0) {
sector = sector + (CDSECTOR_SIZE-1);
}
nsectors = citylumps[GameLevel][CITYLUMP_DATA2].y;
sector = sector / CDSECTOR_SIZE;
if (nsectors < 0) {
nsectors = nsectors + (CDSECTOR_SIZE-1);
}
nsectors = nsectors / CDSECTOR_SIZE;
mallocptr = mallocptr + (nsectors * CDSECTOR_SIZE);
#ifdef PSX
loadsectors(malloc_lump, sector, nsectors);
#else
extern char g_CurrentLevelFileName[64];
loadsectorsPC(g_CurrentLevelFileName, malloc_lump, sector, nsectors);
#endif // PSX
sector += nsectors;
ProcessLumps(malloc_lump + 8, (nsectors * CDSECTOR_SIZE));
SpoolLumpOffset = citylumps[GameLevel][CITYLUMP_SPOOL].x;
//Init_Reflection_Mapping(); // [A] I know that this is obsolete and used NOWHERE
InitDebrisNames();
InitShadow();
//InitTextureNames(); // [A] I know that this is obsolete and used NOWHERE
ReportMode(1);
}
// decompiled code
// original method signature:
// int /*$ra*/ ReplayLog_Fnarr_He_Said_Log(int val /*$a0*/)
// line 2973, offset 0x0005c81c
/* begin block 1 */
// Start line: 5946
/* end block 1 */
// End Line: 5947
/* begin block 2 */
// Start line: 9921
/* end block 2 */
// End Line: 9922
int ReplayLog_Fnarr_He_Said_Log(int val)
{
return 0;
}
// decompiled code
// original method signature:
// void /*$ra*/ InitModelNames()
// line 3003, offset 0x00059238
/* begin block 1 */
// Start line: 3005
// Start offset: 0x00059238
/* end block 1 */
// End offset: 0x00059330
// End Line: 3067
/* begin block 2 */
// Start line: 6005
/* end block 2 */
// End Line: 6006
/* begin block 3 */
// Start line: 6042
/* end block 3 */
// End Line: 6043
/* begin block 4 */
// Start line: 6043
/* end block 4 */
// End Line: 6044
/* begin block 5 */
// Start line: 6050
/* end block 5 */
// End Line: 6051
/* WARNING: Unknown calling convention yet parameter storage is locked */
void InitModelNames(void)
{
UNIMPLEMENTED();
/*
gHubcapModelPtr = FindModelPtrWithName(s_HUBCAP1_000aa648);
gCleanWheelModelPtr = FindModelPtrWithName(s_CLEANWHEEL_00010cd0);
gFastWheelModelPtr = FindModelPtrWithName(s_FASTWHEEL_00010cdc);
gDamWheelModelPtr = FindModelPtrWithName(s_DAMWHEEL_00010ce8);
gPed1HeadModelPtr = FindModelPtrWithName(s_PEDHEAD1_00010cf4);
gPed2HeadModelPtr = FindModelPtrWithName(&DAT_000aa650);
gPed3HeadModelPtr = FindModelPtrWithName(&DAT_000aa650);
gPed4HeadModelPtr = FindModelPtrWithName(&DAT_000aa650);
gBoxModelPtr = FindModelPtrWithName(s_CRATE_000aa658);
gRotorPtr = FindModelPtrWithName(s_ROTOR_000aa660);
gTrailblazerConeModel = FindModelPtrWithName(s_GREENCONE_00010d00);
gBombModel = FindModelPtrWithName(&DAT_000aa668);
MangleWheelModels();
InitTanner();
InitAnimatingObjects();
return;
*/
}
// decompiled code
// original method signature:
// void /*$ra*/ GameInit()
// line 3114, offset 0x00059330
/* begin block 1 */
// Start line: 3122
// Start offset: 0x00059330
/* begin block 1.1 */
// Start line: 3226
// Start offset: 0x000594C0
/* end block 1.1 */
// End offset: 0x000594D4
// End Line: 3228
/* begin block 1.2 */
// Start line: 3263
// Start offset: 0x000595B4
/* end block 1.2 */
// End offset: 0x000595B4
// End Line: 3263
/* begin block 1.3 */
// Start line: 3271
// Start offset: 0x000595DC
/* end block 1.3 */
// End offset: 0x00059604
// End Line: 3277
/* begin block 1.4 */
// Start line: 3305
// Start offset: 0x000596B0
// Variables:
// struct STREAM_SOURCE *pinfo; // $s0
// char padid; // stack offset -48
// int i; // $s2
/* end block 1.4 */
// End offset: 0x0005980C
// End Line: 3359
/* begin block 1.5 */
// Start line: 3442
// Start offset: 0x00059944
// Variables:
// int loop; // $s0
/* begin block 1.5.1 */
// Start line: 3445
// Start offset: 0x0005994C
/* end block 1.5.1 */
// End offset: 0x0005994C
// End Line: 3445
/* end block 1.5 */
// End offset: 0x0005996C
// End Line: 3447
/* begin block 1.6 */
// Start line: 3455
// Start offset: 0x0005998C
// Variables:
// int i; // $v1
/* end block 1.6 */
// End offset: 0x000599B8
// End Line: 3460
/* begin block 1.7 */
// Start line: 3464
// Start offset: 0x000599B8
/* end block 1.7 */
// End offset: 0x000599B8
// End Line: 3475
/* begin block 1.8 */
// Start line: 3504
// Start offset: 0x00059A0C
/* end block 1.8 */
// End offset: 0x00059A14
// End Line: 3506
/* end block 1 */
// End offset: 0x00059A44
// End Line: 3509
/* begin block 2 */
// Start line: 6262
/* end block 2 */
// End Line: 6263
/* begin block 3 */
// Start line: 6310
/* end block 3 */
// End Line: 6311
/* begin block 4 */
// Start line: 6317
/* end block 4 */
// End Line: 6318
/* WARNING: Unknown calling convention yet parameter storage is locked */
// TODO: SPOOL?
PACKED_CELL_OBJECT** pcoplist;
CELL_OBJECT** coplist;
ulong* transparent_buffer;
// system?
int gameinit = 0;
int gMusicType = 0;
int xa_timeout = 0;
int ThisMotion = 0;
int IconsLoaded = 0;
// TODO: AI.C?
SPEECH_QUEUE gSpeechQueue;
// OVERLAY
int gLoadedOverlay = 0;
// MOTION_C
int gLoadedMotionCapture = 0;
// DRAWGAME.C ???
int FrAng = 0;
int wetness = 0;
extern char* mallocptr_start; // SYSTEM.C
extern char* mallocDebugMark;
// [D]
void GameInit(void)
{
long lVar1;
_PLAYER *p_Var2;
STREAM_SOURCE *pSVar3;
int i;
int iVar5;
int iVar6;
char padid;
short totaldam;
if (NewLevel == 0) {
SetPleaseWait(NULL);
}
else {
#ifdef PSX
mallocptr = 0x137400;
#else
mallocptr = mallocptr_start;
*((int*)mallocDebugMark) = 0x1f100ded;
*((int*)mallocDebugMark+1) = 0x12345678;
#endif // PSX
packed_cell_pointers = D_MALLOC(0x1000);
}
gameinit = 1;
InitGameVariables();
InitEvents();
InitPadRecording();
InitSpeechQueue(&gSpeechQueue);
if (NewLevel != 0) {
leadAIRequired = 0;
leadAILoaded = 0;
pathAILoaded = 0;
}
LoadMission(gCurrentMissionNumber);
if (gCurrentMissionNumber == 0x26) {
MissionHeader->residentModels[4] = 9;
}
if (GameType == GAME_MISSION) {
SetupFadePolys();
}
if (NewLevel != 0) {
ShowLoadingScreen(LoadingScreenNames[GameLevel], 1, 36);
}
if (AttractMode != 0) {
TriggerInGameCutscene(0);
NoPlayerControl = 1;
}
ResetSound();
LockChannel(0);
LockChannel(1);
LockChannel(2);
if (NumPlayers == 2) {
LockChannel(3);
LockChannel(4);
LockChannel(5);
}
if (NewLevel != 0) {
ShowLoading();
LoadLevelSFX(gCurrentMissionNumber);
}
PauseSound();
ThisMotion = 0;
if (GameLevel == 1)
{
gMusicType = 1;
if ((gCurrentMissionNumber & 1U) != 0)
gMusicType = 5;
}
else if (GameLevel == 0)
{
gMusicType = 6;
if ((gCurrentMissionNumber & 1U) != 0)
gMusicType = 6;
}
else if (GameLevel == 2)
{
gMusicType = 0;
if ((gCurrentMissionNumber & 1U) == 0)
gMusicType = 3;
}
else if(GameLevel == 3)
{
gMusicType = 4;
if((gCurrentMissionNumber & 1U) != 0)
gMusicType = 7;
}
InitMusic(gMusicType);
if (NewLevel == 0)
{
if (IconsLoaded == 0)
ReloadIcons();
IconsLoaded = 1;
SetUpEvents(0);
}
else {
LoadGameLevel();
IconsLoaded = 1;
LoadSky();
LoadFont(NULL);
}
ClearMem((char *)car_data, sizeof(car_data));
player[0].spoolXZ = (VECTOR *)car_data[0].hd.where.t;
car_data[0].hd.where.t[0] = PlayerStartInfo[0]->position.vx;
car_data[0].hd.where.t[2] = PlayerStartInfo[0]->position.vz;
CalcObjectRotationMatrices();
InitialiseDenting();
cameraview = 0;
if (gLoadedMotionCapture != 0)
InitPedestrians();
InitSpooling();
InitMap();
InitSpecSpool();
if (NewLevel == 0 && allowSpecSpooling == 1)
{
QuickSpoolSpecial();
}
int_garage_door();
SpoolSYNC();
Emulator_SaveVRAM("VRAM_AFTER_LOAD.TGA", 0, 0, VRAM_WIDTH, VRAM_HEIGHT, TRUE);
InitialiseCarHandling();
ClearMem((char *)&player, 0x3a0);
InitDrivingGames();
InitThrownBombs();
i = 0;
if (0 < numPlayersToCreate)
{
do {
pSVar3 = PlayerStartInfo[i];
padid = -(char)i;
if (i < (int)(uint)NumPlayers)
padid = (char)i;
gStartOnFoot = (pSVar3->type == 2);
InitPlayer(&player[i], &car_data[i], pSVar3->controlType, pSVar3->rotation, (long(*)[4])&pSVar3->position, pSVar3->model, pSVar3->palette, &padid);
if (gStartOnFoot == 0)
{
car_data[i].ap.damage[0] = pSVar3->damage[0];
car_data[i].ap.damage[1] = pSVar3->damage[1];
car_data[i].ap.damage[2] = pSVar3->damage[2];
car_data[i].ap.damage[3] = pSVar3->damage[3];
car_data[i].ap.damage[4] = pSVar3->damage[4];
car_data[i].ap.damage[5] = pSVar3->damage[5];
car_data[i].totalDamage = pSVar3->totaldamage;
car_data[i].ap.needsDenting = 1;
}
i++;
} while (i < numPlayersToCreate);
}
if (pathAILoaded != 0)
InitCops();
InitCamera(&player[0]);
if (gLoadedOverlay != 0 && NoPlayerControl == 0) {
InitOverlays();
IconsLoaded = 0;
}
gSinkingTimer = 100;
gTimeInWater = 0x19;
InWater = 0;
gBobIndex = 0;
SetupRain();
InitExObjects();
if (NewLevel != 0)
{
pcoplist = (PACKED_CELL_OBJECT **)(mallocptr + 1024);
transparent_buffer = (ulong *)(mallocptr + 2048);
tile_overflow_buffer = (ulong *)mallocptr;
coplist = (CELL_OBJECT **)mallocptr;
mallocptr = mallocptr + 0x900;
}
if (NoPlayerControl == 0)
{
DeleteAllCameras();
}
else
{
FindNextChange(CameraCnt);
}
FrAng = 0x200;
if (gWeather == 1)
wetness = 0x1b58;
else
wetness = 0;
if (gTimeOfDay == 2)
{
i = 0;
do {
lightsOnDelay[i] = Random2(0);
i++;
} while (i < 20);
}
tracking_car = 1;
if (NoPlayerControl == 0)
StoreGameFlags();
SetReverbState(0);
for(i = 0; i < 2; i++)
{
player[i].horn.request = 0;
player[i].horn.time = 0;
player[i].horn.on = 0;
}
gShowPlayerDamage = 1;
InitThunder();
GetXAData(-1);
SetXAVolume(0);
switch (gCurrentMissionNumber)
{
case 2:
case 3:
case 6:
case 11:
case 13:
case 14:
case 19:
case 26:
case 28:
case 34:
case 38:
FunkUpDaBGMTunez(1);
}
xa_timeout = 0;
}
// decompiled code
// original method signature:
// void /*$ra*/ StepSim()
// line 3555, offset 0x00059a44
/* begin block 1 */
// Start line: 3557
// Start offset: 0x00059A44
// Variables:
// static unsigned long t0; // offset 0x0
// static char t1; // offset 0x4
// static char t2; // offset 0x5
// static int oldsp; // offset 0x8
// struct _CAR_DATA *lcp; // $s0
// int i; // $s2
/* begin block 1.1 */
// Start line: 3633
// Start offset: 0x00059C70
// Variables:
// int eekTimer; // $s0
/* begin block 1.1.1 */
// Start line: 3639
// Start offset: 0x00059CC4
/* end block 1.1.1 */
// End offset: 0x00059CC4
// End Line: 3641
/* end block 1.1 */
// End offset: 0x00059D20
// End Line: 3645
/* begin block 1.2 */
// Start line: 3649
// Start offset: 0x00059D6C
/* end block 1.2 */
// End offset: 0x00059D6C
// End Line: 3653
/* begin block 1.3 */
// Start line: 3556
// Start offset: 0x00059FD8
/* end block 1.3 */
// End offset: 0x00059FD8
// End Line: 3556
/* begin block 1.4 */
// Start line: 3838
// Start offset: 0x0005A220
// Variables:
// int padsteer; // $a1
/* begin block 1.4.1 */
// Start line: 3868
// Start offset: 0x0005A320
/* end block 1.4.1 */
// End offset: 0x0005A33C
// End Line: 3872
/* begin block 1.4.2 */
// Start line: 3879
// Start offset: 0x0005A374
/* end block 1.4.2 */
// End offset: 0x0005A374
// End Line: 3879
/* end block 1.4 */
// End offset: 0x0005A374
// End Line: 3879
/* begin block 1.5 */
// Start line: 3886
// Start offset: 0x0005A394
/* end block 1.5 */
// End offset: 0x0005A3C8
// End Line: 3888
/* begin block 1.6 */
// Start line: 3983
// Start offset: 0x0005A650
// Variables:
// int i; // $s1
// int j; // $s0
// static int stupid_logic[4]; // offset 0x0
/* begin block 1.6.1 */
// Start line: 4003
// Start offset: 0x0005A744
/* end block 1.6.1 */
// End offset: 0x0005A794
// End Line: 4005
/* end block 1.6 */
// End offset: 0x0005A7B0
// End Line: 4006
/* begin block 1.7 */
// Start line: 4033
// Start offset: 0x0005A894
/* end block 1.7 */
// End offset: 0x0005A8AC
// End Line: 4036
/* end block 1 */
// End offset: 0x0005A8DC
// End Line: 4039
/* begin block 2 */
// Start line: 7193
/* end block 2 */
// End Line: 7194
/* begin block 3 */
// Start line: 7240
/* end block 3 */
// End Line: 7241
/* begin block 4 */
// Start line: 7241
/* end block 4 */
// End Line: 7242
/* begin block 5 */
// Start line: 7263
/* end block 5 */
// End Line: 7264
/* WARNING: Unknown calling convention yet parameter storage is locked */
extern short paddp;
extern short padd;
unsigned short controller_bits = 0;
VECTOR lis_pos;
int gLightsOn = 0;
int NightAmbient = 0;
char CameraChanged = 0;
char CamerasSaved = 0;
char paused = 0;
char gRightWayUp = 0; // cheat
int num_active_cars = 0;
unsigned long lead_pad = 0;
int distFurthestCivCarSq = 0;
int numInactiveCars = 0;
int numActiveCops = 0;
char furthestCivID = 0;
int leadCarId = 0;
VECTOR leadcar_pos;
unsigned long PingBufferPos = 0;
_PING_PACKET *PingBuffer = NULL;
int frameStart = 0;
void StepSim(void)
{
static unsigned long t0; // offset 0x0
static char t1; // offset 0x4
static char t2; // offset 0x5
static int oldsp; // offset 0x8
char cVar1;
ushort uVar2;
short *psVar3;
int *piVar4;
//undefined3 extraout_var;
int stream;
uint uVar5;
int *piVar6;
uint uVar7;
_CAR_DATA *cp;
_PLAYER *pPVar8;
int i;
int car;
if ((gTimeOfDay == 0) || (gTimeOfDay == 2)) {
DawnCount = DawnCount + 1;
}
SetUpTrafficLightPhase();
MoveSmashable_object();
animate_garage_door();
StepEvents();
HandleMission();
HandleInGameCutscene();
HandleDrivingGames();
num_active_cars = 0;
if ((NoPlayerControl != 0) && (ReplayParameterPtr->RecordingEnd + -2 < CameraCnt))
{
ReleaseInGameCutscene();
pauseflag = 1;
}
oldsp = SetSp(0x1f8003e8); // i don't know what this does
lead_pad = (ulong)controller_bits;
if ((int)player[0].playerCarId < 0)
{
psVar3 = &pedestrianFelony;
}
else
{
psVar3 = &car_data[(int)player[0].playerCarId].felonyRating;
}
// control cop roadblocks
if ((*psVar3 < 0x527) || (numRoadblockCars != 0))
{
LAB_00059c00:
if (roadblockCount == 0)
goto LAB_00059c1c;
}
else
{
if (roadblockCount == 0)
{
if (((copsAreInPursuit != 0) && (MissionHeader->residentModels[3] == 0)) && (gCurrentMissionNumber != 0x1a))
requestRoadblock = 1;
goto LAB_00059c00;
}
}
roadblockCount = roadblockCount + -1;
LAB_00059c1c:
// control civcars pingin/pingout
if ((requestStationaryCivCar == 1) || (requestRoadblock != 0))
{
distFurthestCivCarSq = 0;
}
else
{
i = 0;
if (gInGameChaseActive == 0)
{
if ((numCivCars < maxCivCars) && (NumPlayers == 1)) {
i = 0;
while ((i < 5 && (car = PingInCivCar(15900), car == 0)))
{
i = i + 1;
}
}
}
else
{
if ((PingBufferPos < 400) && ((uint)PingBuffer[PingBufferPos].frame <= (CameraCnt - frameStart & 0xffffU)))
{
while (true)
{
PingInCivCar(15900);
i = i + 1;
if (399 < PingBufferPos)
break;
if (((CameraCnt - frameStart & 0xffffU) < (uint)PingBuffer[PingBufferPos].frame)
|| (10 < i)) break;
}
}
}
SetUpCivCollFlags();
}
uVar7 = 0xd43fc;
numRoadblockCars = 0;
numInactiveCars = 0;
numParkedCars = 0;
numActiveCops = 0;
numCopCars = 0;
numCivCars = 0;
if (true)
{
cp = car_data;
do {
cVar1 = cp->controlType;
if (cVar1 == '\x02')
{
numCivCars = numCivCars + 1;
if ((cp->controlFlags & 1) != 0)
{
numCopCars = numCopCars + 1;
}
if (((cp->controlFlags & 2) != 0) && (cp->ai.c.thrustState == 3))
{
if (cp->ai.c.ctrlState == 5)
{
numParkedCars = numParkedCars + 1;
}
if ((cp->controlFlags & 2) != 0)
{
numRoadblockCars = numRoadblockCars + 1;
}
}
}
else
{
if (cVar1 == '\x03')
{
numCopCars = numCopCars + 1;
if (cp->ai.p.dying == 0)
{
numActiveCops = numActiveCops + 1;
}
}
else {
if (cVar1 == '\0')
{
numInactiveCars = numInactiveCars + 1;
}
}
}
cp++;
} while (cp <= &car_data[21]);
}
if (numRoadblockCars != 0)
roadblockCount = roadblockDelay;
if ((((requestStationaryCivCar == 0) && (requestRoadblock != 0)) && (numRoadblockCars == 0)) && (4 < maxCivCars - numCivCars))
{
CreateRoadblock();
}
cp = car_data;
if (gInGameCutsceneActive == 0)
{
CheckSpecialSpool();
}
while (cp <= &car_data[0x13])
{
if (true) {
switch (cp->controlType)
{
case 1:
t0 = (ulong)Pads[(int)cp->ai.padid].mapped; // [A] padid might be wrong
t1 = Pads[(int)cp->ai.padid].mapanalog[2];
t2 = Pads[(int)cp->ai.padid].type & 4;
if (NoPlayerControl == 0)
{
if (gStopPadReads != 0)
{
t0 = 0x80;
if ((cp->hd).wheel_speed < 0x9001)
t0 = 0x10;
t1 = '\0';
t2 = 1;
}
cjpRecord((int)cp->ai.padid, &t0, &t1, &t2);
}
else
{
cjpPlay((int)cp->ai.padid, &t0, &t1, &t2);
}
ProcessCarPad(cp, t0, t1, t2);
break;
case 2:
CivControl(cp);
break;
case 3:
CopControl(cp);
break;
case 4:
UNIMPLEMENTED();
/*
t2 = 0;
t1 = '\0';
t0 = 0;
t0 = FreeRoamer(cp); // [A]
if (t0_18 == 0) {
cp->handbrake = '\x01';
cp->wheel_angle = 0;
}
else {
ProcessCarPad(cp, t0_18, t1_19, t2_20);
}*/
break;
case 7:
cjpPlay((int)cp->ai.padid, &t0, &t1, &t2);
ProcessCarPad(cp, t0, t1, t2);
}
}
StepCarPhysics(cp);
cp++;
}
i = 0;
pPVar8 = player;
car = 7;
do {
if (pPVar8->playerType == '\x02')
{
stream = pPVar8->padid;
if (stream < 0)
{
stream = cjpPlay(stream, &t0, &t1, &t2);
if (stream != 0) {
ProcessTannerPad(player[i].pPed, t0, t1, t2);
}
}
else
{
if (Pads[stream].type == '\x04')
{
cVar1 = Pads[stream].mapanalog[3];
if ((cVar1 < -0x40) && (-100 < cVar1))
{
Pads[stream].mapped = Pads[stream].mapped | 0x1008;
}
else
{
if ((cVar1 < -100) && ('\x7f' < cVar1))
{
stream = (int)pPVar8->padid;
uVar2 = Pads[stream].mapped | 0x1000;
}
else
{
if (cVar1 < '!') goto LAB_0005a2dc;
stream = (int)pPVar8->padid;
uVar2 = Pads[stream].mapped | 0x4000;
}
Pads[stream].mapped = uVar2;
}
}
LAB_0005a2dc:
stream = player[i].padid;
t0 = (ulong)Pads[stream].mapped;
t1 = Pads[stream].mapanalog[2];
t2 = Pads[stream].type & 4;
if (NoPlayerControl == 0)
{
if (gStopPadReads != 0)
{
t2 = 0;
t1 = '\0';
t0 = 0;
}
cjpRecord(stream, &t0, &t1, &t2);
}
else
{
stream = cjpPlay(stream, &t0, &t1, &t2);
if (stream == 0) goto LAB_0005a3d0;
}
ProcessTannerPad(player[i].pPed, t0, t1, t2);
}
}
LAB_0005a3d0:
i = i + 0x74;
pPVar8 = pPVar8 + 1;
car = car + -1;
} while (-1 < car);
if ((requestStationaryCivCar == 1) &&
((numCivCars < maxCivCars ||
(PingOutCar(car_data + furthestCivID), numCivCars < maxCivCars)))) {
requestStationaryCivCar = 0;
}
if ((game_over == 0) && (ControlCops(), gLoadedMotionCapture != 0)) {
HandlePedestrians();
}
i = 0;
GlobalTimeStep();
UpdatePlayers();
DoScenaryCollisions();
CheckPlayerMiscFelonies();
SetSp(oldsp);
CameraCnt = CameraCnt + 1;
gBobIndex = gBobIndex + 0x3cU & 0xfff;
if (NumPlayers != 0)
{
car = 0;
pPVar8 = player;
do {
if ((pPVar8->horn).on == '\0')
{
LAB_0005a5b8:
stream = CarHasSiren(car_data[player[car].playerCarId].ap.model);
if ((stream == 0) && (pPVar8->pPed == NULL))
{
stream = 2;
if (i != 0)
stream = 5;
StopChannel(stream);
player[car].horn.request = '\0';
player[car].horn.time = '\0';
}
}
else {
uVar5 = 4;
if (i != 0)
uVar5 = 0x20;
stream = SpuGetKeyStatus(uVar5);
if (stream == 0)
{
stream = CarHasSiren(car_data[pPVar8->playerCarId].ap.model);
if (((stream == 0) && (pPVar8->pPed == NULL)) && (pPVar8->horn.request == '\0'))
pPVar8->horn.request = '\x01';
pPVar8->horn.time = '\v';
}
else
{
if ((pPVar8->horn).on == '\0')
goto LAB_0005a5b8;
}
}
DealWithHorn(&player[car].horn.request, i);
car++;
i = i + 1;
pPVar8 = pPVar8 + 1;
} while (i < (int)(uint)NumPlayers);
}
SoundTasks();
static int stupid_logic[4];
if (((gInGameCutsceneActive == 0) || (gCurrentMissionNumber != 0x17)) || (gInGameCutsceneID != 0))
stupid_logic[0] = player[0].playerCarId;
else
stupid_logic[0] = 2;
i = 0;
piVar4 = stupid_logic;
stupid_logic[1] = player[1].playerCarId;
stupid_logic[2] = gThePlayerCar;
stupid_logic[3] = leadCarId;
do {
car = i + 1;
if (car < 4) {
piVar6 = stupid_logic + car;
do {
if (*piVar4 == *piVar6) {
*piVar6 = -1;
}
car = car + 1;
piVar6 = piVar6 + 1;
} while (car < 4);
}
i = i + 1;
piVar4 = piVar4 + 1;
} while (i < 3);
car = 0;
piVar4 = stupid_logic;
i = 0;
do {
stream = i;
if ((*piVar4 != -1) && (cVar1 = SilenceThisCar(car), cVar1 == 0))
{
stream = i + 1;
CheckCarEffects(car_data + *piVar4, i);
}
car = car + 1;
piVar4 = piVar4 + 1;
} while ((car < 4) && (i = stream, stream < 2));
SwirlLeaves(car_data);
if ((gStopPadReads == 1) && (((lead_car != 0 && (saved_counter = saved_counter + 1, 0x14 < saved_counter)) && (saved_leadcar_pos == 0))))
{
saved_leadcar_pos = gStopPadReads;
leadcar_pos.vx = car_data[lead_car].hd.where.t[0];
leadcar_pos.vy = car_data[lead_car].hd.where.t[1];
leadcar_pos.vz = car_data[lead_car].hd.where.t[2];
}
if ((gInGameCutsceneActive == 0) &&
(((car = XAPrepared(), i = xa_timeout, car != 0 && (i = xa_timeout + -1, xa_timeout == 0)) ||
(xa_timeout = i, xa_timeout == 0))))
{
StopXA();
UnprepareXA();
StartSpooling();
}
}
// decompiled code
// original method signature:
// void /*$ra*/ GameLoop()
// line 4046, offset 0x0005a8dc
/* begin block 1 */
// Start line: 4048
// Start offset: 0x0005A8DC
// Variables:
// int i; // $s0
// struct RECT dest; // stack offset -24
/* begin block 1.1 */
// Start line: 4125
// Start offset: 0x0005AA2C
// Variables:
// static struct POLY_FT3 buffer[2]; // offset 0x10
// static struct POLY_FT3 *null; // offset 0xc
/* end block 1.1 */
// End offset: 0x0005AA98
// End Line: 4140
/* end block 1 */
// End offset: 0x0005AB28
// End Line: 4188
/* begin block 2 */
// Start line: 8546
/* end block 2 */
// End Line: 8547
/* begin block 3 */
// Start line: 8554
/* end block 3 */
// End Line: 8555
/* begin block 4 */
// Start line: 8555
/* end block 4 */
// End Line: 8556
/* begin block 5 */
// Start line: 8575
/* end block 5 */
// End Line: 8576
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
void GameLoop(void)
{
uint uVar1;
int iVar2;
static POLY_FT3 buffer[2];
static POLY_FT3 *null;
if (NewLevel != 0) {
CloseShutters(2, 0x140, 0x200);
}
DisableDisplay();
SetupDrawBuffers();
EnableDisplay();
srand(0x1234);
cameraview = 0;
FrameCnt = 0;
NoTextureMemory = 0;
SpoolSYNC();
if (CurrentGameMode != GAMEMODE_DIRECTOR) {
UnPauseSound();
}
iVar2 = 4;
StartGameSounds();
SetMasterVolume(gMasterVolume);
SetXMVolume(gMusicVolume);
CloseControllers();
InitControllers();
VSync(0);
do {
iVar2 = iVar2 + -1;
ReadControllers();
VSync(0);
} while (-1 < iVar2);
while (game_over == 0) {
StepGame();
if ((FastForward == 0) || (FrameCnt == (FrameCnt / 7) * 7))
{
DrawGame();
}
else
{
FrameCnt = FrameCnt + 1;
uVar1 = FrameCnt & 1;
null = buffer + uVar1;
setPolyFT3(null);
null->code = '$';
null->x0 = -1;
null->y0 = -1;
null->x1 = -1;
null->y1 = -1;
null->x2 = -1;
null->y2 = -1;
null->tpage = 0x20;
DrawPrim(null);
DrawSync(0);
}
CheckForPause();
}
if (NoPlayerControl == 0)
{
UNIMPLEMENTED(); // [A]
//ReplayParameterPtr->RecordingEnd = CameraCnt;
}
StopPadVibration(0);
StopPadVibration(1);
StopAllChannels();
FreeXM();
iVar2 = XAPrepared();
if (iVar2 != 0) {
StopXA();
UnprepareXA();
}
}
// decompiled code
// original method signature:
// void /*$ra*/ StepGame()
// line 4196, offset 0x0005ab28
/* begin block 1 */
// Start line: 4198
// Start offset: 0x0005AB28
/* begin block 1.1 */
// Start line: 4238
// Start offset: 0x0005AB60
/* end block 1.1 */
// End offset: 0x0005AB70
// End Line: 4240
/* begin block 1.2 */
// Start line: 4252
// Start offset: 0x0005ABD8
// Variables:
// int i; // $a1
/* end block 1.2 */
// End offset: 0x0005AC3C
// End Line: 4262
/* begin block 1.3 */
// Start line: 4336
// Start offset: 0x0005AE20
/* end block 1.3 */
// End offset: 0x0005AE50
// End Line: 4345
/* begin block 1.4 */
// Start line: 4361
// Start offset: 0x0005AEC0
/* end block 1.4 */
// End offset: 0x0005AED0
// End Line: 4368
/* begin block 1.5 */
// Start line: 4395
// Start offset: 0x0005AF6C
// Variables:
// int strobe; // $v0
/* end block 1.5 */
// End offset: 0x0005AFB8
// End Line: 4398
/* begin block 1.6 */
// Start line: 4536
// Start offset: 0x0005B2E4
/* end block 1.6 */
// End offset: 0x0005B31C
// End Line: 4538
/* end block 1 */
// End offset: 0x0005B384
// End Line: 4547
/* begin block 2 */
// Start line: 8865
/* end block 2 */
// End Line: 8866
/* begin block 3 */
// Start line: 8874
/* end block 3 */
// End Line: 8875
/* begin block 4 */
// Start line: 8875
/* end block 4 */
// End Line: 8876
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
void StepGame(void)
{
char cVar1;
int iVar2;
uint uVar3;
unsigned char *puVar4;
_PLAYER *pPVar5;
if (CameraCnt == 3)
{
StartXM(0);
}
if (doSpooling != 0)
{
CheckValidSpoolData();
ControlMap();
}
if (gTimeOfDay == 3)
PreLampStreak();
UpdatePadData();
if (FrameCnt == 5)
SetDispMask(1);
if (((padd & 0x2000U) != 0) && ((padd & 0x8000U) != 0))
padd = padd & 0x5fff;
uVar3 = (uint)NumPlayers;
controller_bits = padd;
if (NumPlayers != 0)
{
pPVar5 = player;
do {
cVar1 = (pPVar5->horn).time;
if ((cVar1 == '\0') || ((pPVar5->horn).on == '\0'))
(pPVar5->horn).time = '\0';
else
(pPVar5->horn).time = cVar1 + -1;
uVar3 = uVar3 - 1;
pPVar5 = pPVar5 + 1;
} while (uVar3 != 0);
}
ModifyCamera();
lis_pos.vx = camera_position.vx;
lis_pos.vy = camera_position.vy;
lis_pos.vz = camera_position.vz;
lis_pos.pad = camera_position.pad;
FrAng = ratan2(160, scr_z);
if ((gTimeInWater == 0) || (gSinkingTimer < 100))
{
gStopPadReads = 1;
TargetCar = 0;
cameraview = 0;
gSinkingTimer = gSinkingTimer + -1;
gCameraAngle = gCameraAngle - 0x16U & 0xfff;
if (gCameraDistance < 1000)
{
gCameraMaxDistance = gCameraMaxDistance + 8;
gCameraDistance = gCameraDistance + 8;
}
if (-1000 < CameraPos.vy) {
CameraPos.vy = CameraPos.vy + -8;
}
if (gSinkingTimer < 0) {
EnablePause(PAUSEMODE_GAMEOVER);
}
}
if (gTimeOfDay == 1)
{
gLightsOn = 0;
iVar2 = 0x4e;
if (1 < gWeather - 1U)
iVar2 = 0x80;
goto LAB_0005aea0;
}
if (gTimeOfDay < 2)
{
if (gTimeOfDay == 0)
{
NightAmbient = (DawnCount >> 7) + 0x1a;
gLightsOn = (DawnCount < 4000);
iVar2 = 0x60;
if (0x60 < NightAmbient) goto LAB_0005aea0;
}
}
else
{
if (gTimeOfDay == 2)
{
if (DawnCount < 3000)
{
gLightsOn = 0;
}
else
{
gLightsOn = 1;
puVar4 = lightsOnDelay;
do {
if (*puVar4 != '\0') {
*puVar4 = *puVar4 + -1;
}
puVar4 = puVar4 + 1;
} while ((int)puVar4 < 0xd56e4);
}
NightAmbient = 0x4e;
if (gWeather - 1U < 2)
{
iVar2 = DawnCount >> 7;
}
else
{
NightAmbient = 0x60;
iVar2 = DawnCount >> 5;
}
NightAmbient = NightAmbient - iVar2;
iVar2 = 0x2d;
if (NightAmbient < 0x2d)
goto LAB_0005aea0;
}
else
{
if (gTimeOfDay == 3)
{
gLightsOn = 1;
iVar2 = 0x80;
LAB_0005aea0:
NightAmbient = iVar2;
}
}
}
if ((gWeather != 0) && (gWeather == 1))
{
DoLightning();
DoThunder();
}
HandleExplosion();
if (FastForward == 0)
ColourCycle();
combointensity = NightAmbient | NightAmbient << 8 | NightAmbient << 0x10;
if ((NoPlayerControl != 0) && (AttractMode == 0))
ShowReplayOptions();
if ((FastForward != 0) && (uVar3 = CameraCnt & 0x1f, CameraCnt < ReplayParameterPtr->RecordingEnd + -1))
{
if (0xf < uVar3)
uVar3 = 0x20 - uVar3;
SetTextColour((uVar3 & 0x1f) << 3, '\0', '\0');
PrintStringFeature("Fast forward", 100, 0x1e, 0x1000, 0x1000, 0);
}
if ((AttractMode == 0) && (pauseflag == 0))
{
if (NoPlayerControl == 0)
{
if (2 < FrameCnt)
{
if (NumPlayers == 1)
{
if (((paddp == 0x800) && (bMissionTitleFade == 0)) && (gInGameCutsceneActive == 0))
{
EnablePause(PAUSEMODE_PAUSE);
}
}
else if (paddp == 0x800)
{
EnablePause(PAUSEMODE_PAUSEP1);
}
else if ((NumPlayers == 2) && ((Pads[1].dirnew & 0x800) != 0))
{
EnablePause(PAUSEMODE_PAUSEP2);
}
}
goto LAB_0005b0a8;
}
}
else
{
LAB_0005b0a8:
if (NoPlayerControl == 0)
{
if (((pad_connected < 1) && (2 < FrameCnt)) && ((bMissionTitleFade == 0 && (gInGameCutsceneActive == 0))))
{
pauseflag = 1;
PauseSound();
}
if ((NoPlayerControl == 0) && (NoTextureMemory != 0))
{
NoTextureMemory = NoTextureMemory + -1;
}
}
}
CameraChanged = '\0';
old_camera_change = camera_change;
if ((pauseflag == 0) && (NoPlayerControl != 0))
{
if (gInGameCutsceneActive == 0)
{
iVar2 = CheckCameraChange(CameraCnt);
camera_change = (char)iVar2;
goto LAB_0005b1e0;
}
}
else {
if (gInGameCutsceneActive == 0)
{
camera_change = '\0';
goto LAB_0005b1e0;
}
}
iVar2 = CutsceneCameraChange(CameraCnt);
camera_change = (char)iVar2;
LAB_0005b1e0:
if (pauseflag == 0)
{
StepSim();
if (gDieWithFade != 0) {
gDieWithFade = gDieWithFade + 1;
}
if (paused != 0) {
CamerasSaved = 1;
paused = 0;
}
}
else
{
if (((NoPlayerControl == 0) && (AttractMode == 0)) && (game_over == 0))
{
if (pad_connected < 1)
EnablePause(PAUSEMODE_PADERROR);
else
EnablePause(PAUSEMODE_PAUSE);
}
paused = 1;
}
if ((NoPlayerControl != 0) && (AttractMode == 0))
ControlReplay();
if (gRightWayUp != 0)
{
TempBuildHandlingMatrix(car_data + player[0].playerCarId, 0);
gRightWayUp = 0;
}
if ((AttractMode != 0) && ((paddp != 0 || (ReplayParameterPtr->RecordingEnd <= CameraCnt))))
EndGame(GAMEMODE_QUIT);
UpdatePlayerInformation();
}
// decompiled code
// original method signature:
// void /*$ra*/ DrawGame()
// line 4549, offset 0x0005c458
/* begin block 1 */
// Start line: 4551
// Start offset: 0x0005C458
// Variables:
// static unsigned long frame; // offset 0xc8
/* begin block 1.1 */
// Start line: 4555
// Start offset: 0x0005C480
/* end block 1.1 */
// End offset: 0x0005C4D0
// End Line: 4561
/* begin block 1.2 */
// Start line: 4567
// Start offset: 0x0005C4EC
/* end block 1.2 */
// End offset: 0x0005C554
// End Line: 4577
/* end block 1 */
// End offset: 0x0005C574
// End Line: 4583
/* begin block 2 */
// Start line: 10753
/* end block 2 */
// End Line: 10754
/* begin block 3 */
// Start line: 9098
/* end block 3 */
// End Line: 9099
/* begin block 4 */
// Start line: 10754
/* end block 4 */
// End Line: 10755
/* begin block 5 */
// Start line: 10756
/* end block 5 */
// End Line: 10757
/* WARNING: Unknown calling convention yet parameter storage is locked */
// TODO: DRAW.C?
int ObjectDrawnValue = 0;
int ObjectDrawnCounter = 0;
void DrawGame(void)
{
static unsigned long frame = 0;
if ((NumPlayers == 1) || (NoPlayerControl != 0)) {
ObjectDrawnValue = FrameCnt;
DrawPauseMenus();
RenderGame2(0);
ObjectDrawnCounter++;
while ((VSync(-1) - frame) < 2);
frame = VSync(-1);
SwapDrawBuffers();
}
else {
ObjectDrawnValue = FrameCnt;
RenderGame2(0);
ObjectDrawnCounter++;
SwapDrawBuffers2(0);
ObjectDrawnValue += 16;
DrawPauseMenus();
RenderGame2(1);
ObjectDrawnCounter++;
SwapDrawBuffers2(1);
}
FrameCnt++;
}
// decompiled code
// original method signature:
// void /*$ra*/ EndGame(enum GAMEMODE mode /*$a0*/)
// line 4586, offset 0x0005c574
/* begin block 1 */
// Start line: 10823
/* end block 1 */
// End Line: 10824
/* begin block 2 */
// Start line: 10827
/* end block 2 */
// End Line: 10828
/* begin block 3 */
// Start line: 10829
/* end block 3 */
// End Line: 10830
static int WantPause = 0;
static PAUSEMODE PauseMode = PAUSEMODE_PAUSE;
// [D]
void EndGame(GAMEMODE mode)
{
WantedGameMode = mode;
pauseflag = 0;
game_over = 1;
}
// decompiled code
// original method signature:
// void /*$ra*/ EnablePause(enum PAUSEMODE mode /*$a0*/)
// line 4593, offset 0x0005c590
/* begin block 1 */
// Start line: 10842
/* end block 1 */
// End Line: 10843
/* begin block 2 */
// Start line: 10843
/* end block 2 */
// End Line: 10844
// [D]
void EnablePause(PAUSEMODE mode)
{
if (((quick_replay != 0) || (NoPlayerControl == 0)) || (mode != PAUSEMODE_GAMEOVER))
{
WantPause = 1;
PauseMode = mode;
}
}
// decompiled code
// original method signature:
// void /*$ra*/ CheckForPause()
// line 4602, offset 0x0005c5d0
/* begin block 1 */
// Start line: 4604
// Start offset: 0x0005C5D0
/* begin block 1.1 */
// Start line: 4603
// Start offset: 0x0005C5E4
/* end block 1.1 */
// End offset: 0x0005C614
// End Line: 4603
/* end block 1 */
// End offset: 0x0005C668
// End Line: 4618
/* begin block 2 */
// Start line: 10861
/* end block 2 */
// End Line: 10862
/* begin block 3 */
// Start line: 10862
/* end block 3 */
// End Line: 10863
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
void CheckForPause(void)
{
if ((gDieWithFade > 15) && ((quick_replay != 0 || (NoPlayerControl == 0))))
{
PauseMode = PAUSEMODE_GAMEOVER;
WantPause = 1;
}
if (WantPause != 0)
{
WantPause = 0;
pauseflag = 1;
PauseSound();
ShowPauseMenu(PauseMode);
if (game_over == 0)
{
UnPauseSound();
}
}
}
// decompiled code
// original method signature:
// int /*$ra*/ main()
// line 4767, offset 0x0005b384
/* begin block 1 */
// Start line: 4768
// Start offset: 0x0005B384
/* begin block 1.1 */
// Start line: 4768
// Start offset: 0x0005B384
/* begin block 1.1.1 */
// Start line: 4768
// Start offset: 0x0005B384
// Variables:
// char (*PALScreenNames[4]); // stack offset -24
// char (*NTSCScreenNames[4]); // stack offset -40
// char (*OPMScreenNames[4]); // stack offset -56
/* end block 1.1.1 */
// End offset: 0x0005B384
// End Line: 4768
/* end block 1.1 */
// End offset: 0x0005B384
// End Line: 4768
/* end block 1 */
// End offset: 0x0005B54C
// End Line: 4868
/* begin block 2 */
// Start line: 9845
/* end block 2 */
// End Line: 9846
/* begin block 3 */
// Start line: 10066
/* end block 3 */
// End Line: 10067
/* WARNING: Unknown calling convention yet parameter storage is locked */
// decompiled code
// original method signature:
// void SsSetSerialVol(char param_1,short param_2,short param_3);
// line -1, offset 0x00092b3c
// function 'SsSetSerialVol' @0x00092B3C was found in the decompiled code exported from Ghidra, but not the original debug symbol data.
void SsSetSerialVol(char param_1, short param_2, short param_3)
{
UNIMPLEMENTED();
/*
undefined4 local_30[4];
short local_20;
short local_1e;
short local_14;
short local_12;
if (param_1 == '\0') {
local_30[0] = 0xc0;
if (0x7f < param_2) {
param_2 = 0x7f;
}
if (0x7f < param_3) {
param_3 = 0x7f;
}
local_20 = param_2 * 0x102;
local_1e = param_3 * 0x102;
}
if (param_1 == '\x01') {
local_30[0] = 0xc00;
if (0x7f < param_2) {
param_2 = 0x7f;
}
if (0x7f < param_3) {
param_3 = 0x7f;
}
local_14 = param_2 * 0x102;
local_12 = param_3 * 0x102;
}
SpuSetCommonAttr(local_30);
return;
*/
}
// [D]
#ifdef PSX
int main(void)
#else
int redriver2_main(void)
#endif // PSX
{
char *PALScreenNames[4] = { // [A] don't show publisher logo
// "GFX\\SPLASH2.TIM",
// "GFX\\SPLASH3.TIM",
"GFX\\SPLASH1P.TIM",
NULL
};
char *NTSCScreenNames[4] = { // [A] don't show publisher logo
// "GFX\\SPLASH2.TIM",
// "GFX\\SPLASH3.TIM",
"GFX\\SPLASH1N.TIM",
NULL
};
char *OPMScreenNames[4] = { // [A] don't show publisher logo
//"GFX\\OPM1.TIM",
"GFX\\OPM2.TIM",
"GFX\\OPM3.TIM",
NULL
};
//_stacksize = 0x4000;
//_ramsize = 0x200000;
SetDispMask(0);
StopCallback();
ResetCallback();
ResetGraph(0);
SsSetSerialVol(0, 0, 0);
SetDispMask(0);
SetGraphDebug(0);
SetVideoMode(video_mode);
CdInit();
SsSetSerialVol(0, 0, 0);
SpuInit();
InitGeom();
SetGeomOffset(160, 128);
scr_z = 256;
SetGeomScreen(256);
MemCardInit(1);
InitControllers();
Init_FileSystem();
InitSound();
//PlayFMV(99); // [A] don't show publisher logo
ShowHiresScreens(OPMScreenNames, 300, 0); // [A]
PlayFMV(0); // play intro movie
CheckForCorrectDisc(0);
// Init frontend
#ifdef PSX
Loadfile("FRONTEND.BIN", &DAT_001c0000);
#endif // PSX
SpuSetMute(0);
// initializes sound system
LoadSoundBankDynamic(NULL, 0, 0);
// load frontend bank
LoadBankFromLump(1, 0);
InitialiseScoreTables();
// now run the frontend
DoFrontEnd();
return 1;
}
// decompiled code
// original method signature:
// void /*$ra*/ FadeScreen(int end_value /*$a1*/)
// line 4870, offset 0x0005c668
/* begin block 1 */
// Start line: 4871
// Start offset: 0x0005C668
// Variables:
// int tmp2; // $s1
/* end block 1 */
// End offset: 0x0005C6E0
// End Line: 4888
/* begin block 2 */
// Start line: 11280
/* end block 2 */
// End Line: 11281
/* begin block 3 */
// Start line: 11397
/* end block 3 */
// End Line: 11398
// [D]
void FadeScreen(int end_value)
{
int tmp2 = pauseflag;
pauseflag = 1;
SetupScreenFade(-0x20, end_value, 1);
FadingScreen = 1;
do {
RenderGame();
} while (FadingScreen != 0);
DrawSync(0);
SetDispMask(0);
pauseflag = tmp2;
return;
}
// decompiled code
// original method signature:
// void /*$ra*/ UpdatePlayerInformation()
// line 4893, offset 0x0005b54c
/* begin block 1 */
// Start line: 4895
// Start offset: 0x0005B54C
// Variables:
// struct _CAR_DATA *cp; // $s1
// int count; // $s0
// int scale; // $v1
// int wheel; // $t1
// int wheelsonwater; // $t2
/* end block 1 */
// End offset: 0x0005B888
// End Line: 4972
/* begin block 2 */
// Start line: 10293
/* end block 2 */
// End Line: 10294
/* begin block 3 */
// Start line: 10319
/* end block 3 */
// End Line: 10320
/* begin block 4 */
// Start line: 10320
/* end block 4 */
// End Line: 10321
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
void UpdatePlayerInformation(void)
{
short *psVar1;
int iVar2;
unsigned char *pbVar3;
WHEEL *pWVar4;
int iVar5;
int iVar6;
int iVar7;
int iVar8;
_CAR_DATA *p_Var9;
p_Var9 = NULL;
PlayerDamageBar.max = (ushort)MaxPlayerDamage[0];
Player2DamageBar.max = (ushort)MaxPlayerDamage[1];
if (gPlayerImmune != 0)
{
if ((int)player[0].playerCarId < 0)
psVar1 = &pedestrianFelony;
else
psVar1 = &car_data[(int)player[0].playerCarId].felonyRating;
*psVar1 = 0;
}
if ((int)player[0].playerCarId < 0)
psVar1 = &pedestrianFelony;
else
psVar1 = &car_data[(int)player[0].playerCarId].felonyRating;
FelonyBar.position = *psVar1;
if (NumPlayers != 0)
{
iVar2 = 0;
iVar8 = 0;
do {
iVar2 = (iVar2 * 4 + iVar8 * -3) * 4;
if ((&player[0].playerType)[iVar2] == '\x01')
{
iVar2 = (int)(&player[0].playerCarId)[iVar2];
p_Var9 = car_data + iVar2;
if (gInvincibleCar != 0)
{
car_data[iVar2].totalDamage = 0;
ClearMem((char *)car_data[iVar2].ap.damage, 0xc);
}
iVar6 = 0;
iVar7 = iVar8 + 1;
pWVar4 = car_data[iVar2].hd.wheel;
pbVar3 = &car_data[iVar2].hd.wheel[0].surface;
iVar5 = 3;
do {
if (((uint)*pbVar3 & 7) == 1)
{
if (pWVar4->susCompression == 9)
{
if ((car_data[iVar2].hd.where.t[1] < -1000) && (gDieWithFade == 0))
{
gDieWithFade = (uint)*pbVar3 & 7;
}
}
else
{
iVar6 = iVar6 + 1;
}
}
pWVar4 = pWVar4 + 1;
iVar5 = iVar5 + -1;
pbVar3 = pbVar3 + 4;
} while (-1 < iVar5);
if (iVar6 == 4)
{
car_data[iVar2].totalDamage =
car_data[iVar2].totalDamage + (short)(MaxPlayerDamage[iVar8] / 0x50);
}
if (MaxPlayerDamage[iVar8] < (int)(uint)car_data[iVar2].totalDamage)
{
car_data[iVar2].totalDamage = *(ushort *)(MaxPlayerDamage + iVar8);
}
if (iVar8 == 0) {
PlayerDamageBar.position = car_data[iVar2].totalDamage;
}
else
{
Player2DamageBar.position = car_data[iVar2].totalDamage;
}
}
else {
iVar7 = iVar8 + 1;
if (iVar8 == 0)
{
PlayerDamageBar.position = 0;
iVar7 = 1;
}
else
{
Player2DamageBar.position = 0;
}
}
if (((0x1df < gCurrentMissionNumber) &&
(((gCurrentMissionNumber < 0x1e2 ||
((gCurrentMissionNumber < 0x1e6 && (0x1e3 < gCurrentMissionNumber)))) &&
((p_Var9->hd).where.t[1] < -750)))) && (gDieWithFade == 0))
{
gDieWithFade = 1;
}
iVar2 = iVar7 << 3;
iVar8 = iVar7;
} while (iVar7 < (int)(uint)NumPlayers);
}
}
// decompiled code
// original method signature:
// void /*$ra*/ RenderGame2(int view /*$s3*/)
// line 5021, offset 0x0005b888
/* begin block 1 */
// Start line: 5022
// Start offset: 0x0005B888
// Variables:
// int spaceFree; // $a1
// int notInDreaAndStevesEvilLair; // $s0
/* begin block 1.1 */
// Start line: 5067
// Start offset: 0x0005B9A4
// Variables:
// int strobe; // $v0
/* end block 1.1 */
// End offset: 0x0005B9EC
// End Line: 5070
/* begin block 1.2 */
// Start line: 5073
// Start offset: 0x0005B9EC
// Variables:
// int i; // $s1
/* end block 1.2 */
// End offset: 0x0005BA84
// End Line: 5077
/* begin block 1.3 */
// Start line: 5090
// Start offset: 0x0005BAE4
// Variables:
// struct POLY_F4 *poly; // $v1
// int col; // $a1
/* end block 1.3 */
// End offset: 0x0005BC20
// End Line: 5113
/* begin block 1.4 */
// Start line: 5121
// Start offset: 0x0005BC40
/* end block 1.4 */
// End offset: 0x0005BC88
// End Line: 5125
/* end block 1 */
// End offset: 0x0005BCE4
// End Line: 5132
/* begin block 2 */
// Start line: 10644
/* end block 2 */
// End Line: 10645
/* begin block 3 */
// Start line: 10654
/* end block 3 */
// End Line: 10655
int CurrentPlayerView = 0;
// [D]
void RenderGame2(int view)
{
DB *pDVar1;
int iVar2;
POLY_F4 *poly;
uint uVar3;
unsigned char uVar4;
char *pcVar5;
_PLAYER *pPVar6;
int iVar7;
CurrentPlayerView = view;
InitCamera((_PLAYER *)(player + view));
Set_Inv_CameraMatrix();
SetCameraVector();
SetupDrawMapPSX();
if (gLoadedMotionCapture != 0)
DrawAllPedestrians();
DisplayMissionTitle();
DrawInGameCutscene();
DrawEvents(1);
Set_Inv_CameraMatrix();
SetCameraVector();
SetupDrawMapPSX();
DrawDrivingGames();
DrawThrownBombs();
AddGroundDebris();
DrawEvents(0);
current->ot = current->ot + 10;
DrawSmashable_sprites();
HandleDebris();
current->ot = current->ot + -10;
DrawAllExplosions();
if (AttractMode != 0)
{
uVar3 = CameraCnt & 0x1f;
if (0xf < uVar3) {
uVar3 = 0x20 - uVar3;
}
SetTextColour(((uVar3 & 0x1f) << 3), '\0', '\0');
PrintString("DEMO", 0x23, 0xf);
}
pPVar6 = player;
iVar7 = 2;
do {
iVar2 = CarHasSiren((uint)(char)car_data[pPVar6->playerCarId].ap.model);
if ((iVar2 != 0) && ((pPVar6->horn).on != '\0'))
AddCopCarLight(car_data + pPVar6->playerCarId);
iVar7 = iVar7 + -1;
pPVar6 = pPVar6 + 1;
} while (-1 < iVar7);
if (gLoadedOverlay != 0)
{
DisplayOverlays();
}
DrawMission();
if ((FastForward == 0) && (NumPlayers == 1))
{
DrawLensFlare();
}
uVar4 = (unsigned char)(gDieWithFade << 4);
if (gDieWithFade != 0)
{
if (0xff < gDieWithFade << 4)
{
uVar4 = -1;
}
poly = (POLY_F4 *)current->primptr;
setPolyF4(poly);
setSemiTrans(poly, 1);
poly->r0 = uVar4;
poly->g0 = uVar4;
poly->b0 = uVar4;
pDVar1 = current;
poly->x0 = 0;
poly->y0 = 0;
poly->x1 = 0x140;
poly->y1 = 0;
poly->x2 = 0;
poly->y2 = 0x100;
poly->x3 = 0x140;
poly->y3 = 0x100;
addPrim(pDVar1->ot + 8, poly);
pDVar1->primptr += sizeof(POLY_F4);
POLY_FT3* null = (POLY_FT3*)pDVar1->primptr;
setPolyFT3(null);
null->x0 = -1;
null->y0 = -1;
null->x1 = -1;
null->y1 = -1;
null->x2 = -1;
null->y2 = -1;
null->tpage = 0x40;
addPrim(pDVar1->ot + 8, null);
pDVar1->primptr += sizeof(POLY_FT3);
}
iVar7 = Havana3DOcclusion(DrawMapPSX, (int *)&ObjectDrawnValue);
ScaleCamera();
if ((iVar7 != 0) && (DrawSkyDome(), 40000 < (int)(current->primtab + -(int)(current->primptr + -0x1e000))))
{
DoWeather(gWeather);
}
if (37000 < (int)(current->primtab + -(int)(current->primptr + -0x1e000)))
{
DrawTyreTracks();
}
DrawAllTheCars(view);
}
// decompiled code
// original method signature:
// void /*$ra*/ RenderGame()
// line 5260, offset 0x0005c6e0
/* begin block 1 */
// Start line: 5262
// Start offset: 0x0005C6E0
/* begin block 1.1 */
// Start line: 5262
// Start offset: 0x0005C6E0
/* begin block 1.1.1 */
// Start line: 5262
// Start offset: 0x0005C6E0
// Variables:
// static unsigned long frame; // offset 0xc8
/* begin block 1.1.1.1 */
// Start line: 5261
// Start offset: 0x0005C714
/* end block 1.1.1.1 */
// End offset: 0x0005C764
// End Line: 5261
/* begin block 1.1.1.2 */
// Start line: 5261
// Start offset: 0x0005C780
/* end block 1.1.1.2 */
// End offset: 0x0005C7E8
// End Line: 5261
/* end block 1.1.1 */
// End offset: 0x0005C7E8
// End Line: 5261
/* end block 1.1 */
// End offset: 0x0005C7E8
// End Line: 5261
/* end block 1 */
// End offset: 0x0005C81C
// End Line: 5269
/* begin block 2 */
// Start line: 11914
/* end block 2 */
// End Line: 11915
/* begin block 3 */
// Start line: 12188
/* end block 3 */
// End Line: 12189
/* begin block 4 */
// Start line: 12189
/* end block 4 */
// End Line: 12190
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
void RenderGame(void)
{
UpdatePadData();
DrawGame();
FadeGameScreen(0, 8);
}
// decompiled code
// original method signature:
// void /*$ra*/ InitGameVariables()
// line 5272, offset 0x0005bce4
/* begin block 1 */
// Start line: 5274
// Start offset: 0x0005BCE4
/* end block 1 */
// End offset: 0x0005BF74
// End Line: 5341
/* begin block 2 */
// Start line: 11050
/* end block 2 */
// End Line: 11051
/* begin block 3 */
// Start line: 11191
/* end block 3 */
// End Line: 11192
/* begin block 4 */
// Start line: 11192
/* end block 4 */
// End Line: 11193
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
void InitGameVariables(void)
{
InitDebris();
InitTyreTracks();
TargetCar = 0;
if (NewLevel != 0) {
gLoadedOverlay = 0;
gLoadedMotionCapture = 0;
}
gRainCount = '\0';
if ((NoPlayerControl == 0) || (AttractMode != 0)) {
pauseflag = 0;
}
else {
pauseflag = 1;
}
HitLeadCar = 0;
FastForward = 0;
game_over = 0;
saved_counter = 0;
saved_leadcar_pos = 0;
gStopPadReads = 0;
DawnCount = 0;
variable_weather = 0;
current_camera_angle = 0x800;
gDieWithFade = 0;
srand(0x1234);
RandomInit(0xd431, 0x350b1);
FrameCnt = 0;
CameraCnt = 0;
ClearMem((char *)&lightsOnDelay, 0x14);
PlayerStartInfo[0] = &ReplayStreams[0].SourceType;
ClearMem((char *)PlayerStartInfo[0], sizeof(STREAM_SOURCE));
PlayerStartInfo[0]->type = 1;
PlayerStartInfo[0]->model = defaultPlayerModel[0];
PlayerStartInfo[0]->palette = defaultPlayerPalette;
PlayerStartInfo[0]->controlType = 1;
PlayerStartInfo[0]->flags = 0;
PlayerStartInfo[0]->rotation = levelstartpos[GameLevel][1];
PlayerStartInfo[0]->position.vx = levelstartpos[GameLevel][0];
PlayerStartInfo[0]->position.vy = 0;
PlayerStartInfo[0]->position.vz = levelstartpos[GameLevel][2];
numPlayersToCreate = 1;
if (NumPlayers == 2) {
PlayerStartInfo[1] = &ReplayStreams[1].SourceType;
ClearMem((char *)PlayerStartInfo[1], sizeof(STREAM_SOURCE));
PlayerStartInfo[1]->type = 1;
PlayerStartInfo[1]->model = defaultPlayerModel[1];
PlayerStartInfo[1]->palette = defaultPlayerPalette;
PlayerStartInfo[1]->controlType = 1;
PlayerStartInfo[1]->flags = 0;
PlayerStartInfo[1]->rotation = levelstartpos[GameLevel][1];
PlayerStartInfo[1]->position.vx = levelstartpos[GameLevel][0] + 600;
PlayerStartInfo[1]->position.vy = 0;
PlayerStartInfo[1]->position.vz = levelstartpos[GameLevel][2];
numPlayersToCreate = NumPlayers;
}
InitCivCars();
return;
}
// decompiled code
// original method signature:
// void /*$ra*/ DealWithHorn(char *hr /*$s2*/, int i /*$s1*/)
// line 5345, offset 0x0005bf74
/* begin block 1 */
// Start line: 5346
// Start offset: 0x0005BF74
// Variables:
// struct _CAR_DATA *car; // $s0
/* begin block 1.1 */
// Start line: 5348
// Start offset: 0x0005C014
/* end block 1.1 */
// End offset: 0x0005C124
// End Line: 5363
/* end block 1 */
// End offset: 0x0005C154
// End Line: 5365
/* begin block 2 */
// Start line: 11377
/* end block 2 */
// End Line: 11378
/* begin block 3 */
// Start line: 11382
/* end block 3 */
// End Line: 11383
void DealWithHorn(char *hr, int i)
{
UNIMPLEMENTED();
/*
byte bVar1;
int channel;
int channel_00;
uint uVar2;
channel = (int)(&player)[i].playerCarId;
bVar1 = *hr;
if (bVar1 == 1) {
channel = 2;
if (i != 0) {
channel = 5;
}
StopChannel(channel);
}
else {
if (bVar1 < 2) {
if (bVar1 == 0) {
return;
}
}
else {
if (bVar1 == 2) {
bVar1 = car_data[channel].ap.model;
if (bVar1 == 4) {
uVar2 = ResidentModelsBodge();
}
else {
if (bVar1 < 3) {
uVar2 = (uint)(byte)car_data[channel].ap.model;
}
else {
uVar2 = (uint)(byte)car_data[channel].ap.model - 1;
}
}
channel_00 = 2;
if (i != 0) {
channel_00 = 5;
}
Start3DSoundVolPitch
(channel_00, 3, uVar2 * 3 + 2, car_data[channel].hd.where.t[0],
car_data[channel].hd.where.t[1], car_data[channel].hd.where.t[2], -10000, 0x1000);
if ((1 < NumPlayers) && (NoPlayerControl == 0)) {
channel_00 = 2;
if (i != 0) {
channel_00 = 5;
}
SetPlayerOwnsChannel(channel_00, (char)i);
}
channel_00 = 2;
if (i != 0) {
channel_00 = 5;
}
SetChannelPosition3(channel_00, (VECTOR *)car_data[channel].hd.where.t,
(long *)(car_data[channel].st + 0x1c), -2000, i * 8 + 0x1000, 0);
}
}
}
uVar2 = (uint)(byte)*hr + 1 & 0xff;
*hr = (char)uVar2 - (((byte)((ulonglong)uVar2 * 0xaaaaaaab >> 0x20) & 0xfe) + (char)(uVar2 / 3));
return;
*/
}
// decompiled code
// original method signature:
// int /*$ra*/ Havana3DOcclusion(TDRFuncPtr_Havana3DOcclusion0func func /*$a3*/, int *param /*$fp*/)
// line 5367, offset 0x0005c16c
/* begin block 1 */
// Start line: 5368
// Start offset: 0x0005C16C
// Variables:
// int outside; // $s6
// int otAltered; // $s5
/* begin block 1.1 */
// Start line: 5379
// Start offset: 0x0005C208
// Variables:
// int draw; // $s2
// int loop; // $s0
/* end block 1.1 */
// End offset: 0x0005C414
// End Line: 5473
/* end block 1 */
// End offset: 0x0005C458
// End Line: 5480
/* begin block 2 */
// Start line: 11426
/* end block 2 */
// End Line: 11427
/* begin block 3 */
// Start line: 11430
/* end block 3 */
// End Line: 11431
// [D]
int Havana3DOcclusion(occlFunc func, int *param)
{
bool bVar1;
int iVar2;
int unaff_s2;
int iVar3;
int iVar4;
int iVar5;
iVar5 = 1;
if ((((GameLevel != 1) || (-0x68fdc < camera_position.vx)) || (camera_position.vx < -0x75416))
|| ((-0x1b8ae < camera_position.vz || (camera_position.vz < -0x20cb3))))
{
(*func)(param);
return 1;
}
if (camera_position.vy < 0x1bf)
{
unaff_s2 = 0x10;
if (-0x729fc < camera_position.vx)
unaff_s2 = 0x11;
}
else
{
iVar5 = 0;
if (((camera_position.vx < -0x6e9e5) && (-0x6fa01 < camera_position.vx)) &&
((camera_position.vz < -0x1e201 &&
((-0x1f205 < camera_position.vz && (camera_position.vy < 0xf73))))))
{
if (camera_position.vy < 0x4dd)
{
LAB_0005c2b4:
unaff_s2 = 0xf;
}
else
{
bVar1 = camera_position.vy < 0xc00;
if (camera_position.vy < 0x7d1)
{
unaff_s2 = 0xe;
}
else
{
LAB_0005c2d8:
if (bVar1)
{
unaff_s2 = 0xd;
}
}
}
}
else
{
if (camera_position.vy < 0x6c2)
goto LAB_0005c2b4;
unaff_s2 = 0xe;
if (camera_position.vy < 0x834)
{
bVar1 = camera_position.vx < -0x73609;
goto LAB_0005c2d8;
}
if ((((0xbff < camera_position.vy) && (-0x6fa01 < camera_position.vx)) ||
(unaff_s2 = 0xc, camera_position.vz < -0x1f9db)) &&
(unaff_s2 = 10, camera_position.vz < -0x1f9dc)) {
unaff_s2 = 0xb;
}
}
}
events.camera = 1;
iVar2 = unaff_s2 + -1;
if (iVar2 < 10) {
iVar2 = 10;
}
iVar3 = 0;
while (true)
{
if (unaff_s2 + 1 < iVar2)
{
events.camera = 0;
return iVar5;
}
if (iVar2 == 0x10)
break;
if (unaff_s2 != iVar2)
{
iVar3 = 200;
}
events.draw = iVar2;
current->ot = current->ot + iVar3;
(*func)(param);
iVar4 = iVar3;
if (iVar3 != 0)
{
iVar4 = 0;
current->ot = current->ot + iVar3 * 0x3fffffff;
}
iVar2 = iVar2 + 1;
iVar3 = iVar4;
}
events.camera = 0;
if ((unaff_s2 == 0xf) && (-0x6fd11 < camera_position.vx))
{
events.camera = 0;
return iVar5;
}
return 1;
}