mirror of
https://github.com/OpenDriver2/REDRIVER2.git
synced 2024-11-23 19:02:35 +01:00
3484 lines
66 KiB
C
3484 lines
66 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 "LEADAI.H"
|
|
|
|
#include "XAPLAY.H"
|
|
#include "SHADOW.H"
|
|
|
|
#include "PAUSE.H"
|
|
|
|
#include <stdlib.h>
|
|
#include "STRINGS.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
|
|
};
|
|
|
|
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
|
|
|
|
bool gDriver1Level = false;
|
|
|
|
void ProcessLumps(char *lump_ptr, int lump_size)
|
|
{
|
|
int quit;
|
|
|
|
int lump_type;
|
|
DRIVER2_JUNCTION *pDVar8;
|
|
ulong *puVar9;
|
|
int size;
|
|
int *ptr;
|
|
|
|
int numLumps = -1;
|
|
gDriver1Level = false;
|
|
|
|
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);
|
|
}
|
|
else 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;
|
|
}
|
|
else
|
|
{
|
|
printf("ERROR - unknown lump type %d... assuming it's Driver 1 level\n", lump_type);
|
|
gDriver1Level = true;
|
|
numLumps = lump_type;
|
|
|
|
lump_ptr += 4;
|
|
continue;
|
|
}
|
|
|
|
lump_size = size + 3;
|
|
lump_ptr = (char*)ptr + (lump_size & ~0x3); // aligned to 4-byte boundary
|
|
|
|
if (quit)
|
|
return;
|
|
numLumps--;
|
|
} while (numLumps != 0);
|
|
}
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
// [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][CITYLUMP_DATA1].x / CDSECTOR_SIZE;
|
|
nsectors = citylumps[GameLevel][CITYLUMP_DATA1].y / 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 - load-time lump
|
|
ProcessLumps(_frontend_buffer+8, nsectors * CDSECTOR_SIZE);
|
|
|
|
// CITYLUMP_TPAGE is right next after DATA1
|
|
LoadPermanentTPages(§or);
|
|
|
|
sector = citylumps[GameLevel][CITYLUMP_DATA2].x / CDSECTOR_SIZE;
|
|
nsectors = citylumps[GameLevel][CITYLUMP_DATA2].y / CDSECTOR_SIZE;
|
|
|
|
MALLOC_BEGIN();
|
|
malloc_lump = D_MALLOC(nsectors * CDSECTOR_SIZE);
|
|
MALLOC_END();
|
|
|
|
#ifdef PSX
|
|
loadsectors(malloc_lump, sector, nsectors);
|
|
#else
|
|
extern char g_CurrentLevelFileName[64];
|
|
loadsectorsPC(g_CurrentLevelFileName, malloc_lump, sector, nsectors);
|
|
#endif // PSX
|
|
sector += nsectors;
|
|
|
|
// CITYLUMP_DATA2 - in-memory lump
|
|
ProcessLumps(malloc_lump + 8, (nsectors * CDSECTOR_SIZE));
|
|
|
|
SpoolLumpOffset = citylumps[GameLevel][CITYLUMP_SPOOL].x; // not used anyway
|
|
|
|
//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:
|
|
// 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 */
|
|
|
|
// [D]
|
|
void InitModelNames(void)
|
|
{
|
|
gHubcapModelPtr = FindModelPtrWithName("HUBCAP1");
|
|
gCleanWheelModelPtr = FindModelPtrWithName("CLEANWHEEL");
|
|
gFastWheelModelPtr = FindModelPtrWithName("FASTWHEEL");
|
|
gDamWheelModelPtr = FindModelPtrWithName("DAMWHEEL");
|
|
gPed1HeadModelPtr = FindModelPtrWithName("PEDHEAD1");
|
|
gPed2HeadModelPtr = FindModelPtrWithName("HEAD");
|
|
gPed3HeadModelPtr = FindModelPtrWithName("HEAD");
|
|
gPed4HeadModelPtr = FindModelPtrWithName("HEAD");
|
|
|
|
//gBoxModelPtr = FindModelPtrWithName("CRATE");
|
|
//gRotorPtr = FindModelPtrWithName("ROTOR");
|
|
gTrailblazerConeModel = FindModelPtrWithName("GREENCONE");
|
|
gBombModel = FindModelPtrWithName("BOMB");
|
|
|
|
MangleWheelModels();
|
|
InitTanner();
|
|
InitAnimatingObjects();
|
|
}
|
|
|
|
|
|
|
|
// 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 */
|
|
|
|
ulong* transparent_buffer;
|
|
|
|
// system?
|
|
int gameinit = 0;
|
|
int gMusicType = 0;
|
|
int xa_timeout = 0;
|
|
|
|
int IconsLoaded = 0;
|
|
|
|
// OVERLAY
|
|
int gLoadedOverlay = 0;
|
|
|
|
// MOTION_C
|
|
int gLoadedMotionCapture = 0;
|
|
|
|
// DRAWGAME.C ???
|
|
int FrAng = 0;
|
|
int wetness = 0;
|
|
|
|
extern SPEECH_QUEUE gSpeechQueue;
|
|
|
|
// [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
|
|
|
|
#ifdef USE_CRT_MALLOC
|
|
sys_freeall();
|
|
mallocptr_start = D_MALLOC(0x200000);
|
|
#else
|
|
|
|
#endif // USE_CRT_MALLOC
|
|
mallocptr = (char*)mallocptr_start;
|
|
#endif // PSX
|
|
|
|
MALLOC_BEGIN();
|
|
packed_cell_pointers = D_MALLOC(0x1000);
|
|
MALLOC_END();
|
|
}
|
|
|
|
gameinit = 1;
|
|
InitGameVariables();
|
|
InitEvents();
|
|
InitPadRecording();
|
|
InitSpeechQueue(&gSpeechQueue);
|
|
|
|
if (NewLevel != 0) {
|
|
leadAIRequired = 0;
|
|
leadAILoaded = 0;
|
|
pathAILoaded = 0;
|
|
}
|
|
|
|
LoadMission(gCurrentMissionNumber);
|
|
|
|
if (gCurrentMissionNumber == 38)
|
|
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 = 2;
|
|
|
|
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 || gCarCleanModelPtr[4] == NULL) && allowSpecSpooling == 1) // [A] to load even more secret truck from Chicago
|
|
{
|
|
QuickSpoolSpecial();
|
|
}
|
|
|
|
int_garage_door();
|
|
SpoolSYNC();
|
|
|
|
InitialiseCarHandling();
|
|
ClearMem((char *)player, sizeof(player));
|
|
|
|
InitDrivingGames();
|
|
InitThrownBombs();
|
|
|
|
i = 0;
|
|
if (0 < numPlayersToCreate)
|
|
{
|
|
do {
|
|
pSVar3 = PlayerStartInfo[i];
|
|
padid = -i;
|
|
|
|
if (i < NumPlayers)
|
|
padid = 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);
|
|
}
|
|
|
|
#ifdef CUTSCENE_RECORDER
|
|
extern int gCutsceneAsReplay;
|
|
extern int gCutsceneAsReplay_PlayerId;
|
|
if (gCutsceneAsReplay != 0)
|
|
{
|
|
player[0].playerCarId = gCutsceneAsReplay_PlayerId;
|
|
player[0].cameraCarId = gCutsceneAsReplay_PlayerId;
|
|
}
|
|
#endif
|
|
|
|
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)
|
|
{
|
|
MALLOC_BEGIN();
|
|
char* mem = D_MALLOC(1024);
|
|
tile_overflow_buffer = (ulong *)mem;
|
|
coplist = (CELL_OBJECT **)mem;
|
|
|
|
pcoplist = (PACKED_CELL_OBJECT **)D_MALLOC(1024 + 256);
|
|
//transparent_buffer = D_MALLOC(256); // [A] unused
|
|
MALLOC_END();
|
|
}
|
|
|
|
if (NoPlayerControl == 0)
|
|
{
|
|
#ifdef CUTSCENE_RECORDER
|
|
extern int gCutsceneAsReplay;
|
|
if(gCutsceneAsReplay == 0)
|
|
#endif
|
|
DeleteAllCameras();
|
|
}
|
|
else
|
|
{
|
|
FindNextChange(CameraCnt);
|
|
}
|
|
|
|
FrAng = 0x200;
|
|
|
|
if (gWeather == 1)
|
|
wetness = 7000;
|
|
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 numInactiveCars = 0;
|
|
int leadCarId = 0;
|
|
|
|
VECTOR leadcar_pos;
|
|
|
|
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;
|
|
_CAR_DATA *cp;
|
|
_PLAYER *pl;
|
|
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
|
|
{
|
|
if (gInGameChaseActive == 0)
|
|
{
|
|
if(numCivCars < maxCivCars && (NumPlayers == 1 || (NumPlayers == 2 && GameType == GAME_COPSANDROBBERS)))
|
|
{
|
|
// make 5 tries
|
|
for (i = 0; i < 5; i++)
|
|
{
|
|
if (PingInCivCar(15900))
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// ping buffer used to spawn civ cars
|
|
i = 0;
|
|
while (i < 10 && PingBufferPos < 400 && PingBuffer[PingBufferPos].frame <= (CameraCnt - frameStart & 0xffffU))
|
|
{
|
|
PingInCivCar(15900);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
SetUpCivCollFlags();
|
|
}
|
|
|
|
numRoadblockCars = 0;
|
|
numInactiveCars = 0;
|
|
numParkedCars = 0;
|
|
numActiveCops = 0;
|
|
numCopCars = 0;
|
|
numCivCars = 0;
|
|
|
|
if (true)
|
|
{
|
|
cp = car_data;
|
|
|
|
do {
|
|
cVar1 = cp->controlType;
|
|
|
|
if (cVar1 == 2)
|
|
{
|
|
numCivCars++;
|
|
|
|
if ((cp->controlFlags & 1) != 0)
|
|
{
|
|
numCopCars++;
|
|
}
|
|
|
|
if (((cp->controlFlags & 2) != 0) && (cp->ai.c.thrustState == 3))
|
|
{
|
|
if (cp->ai.c.ctrlState == 5)
|
|
{
|
|
numParkedCars++;
|
|
}
|
|
|
|
if ((cp->controlFlags & 2) != 0)
|
|
{
|
|
numRoadblockCars++;
|
|
}
|
|
}
|
|
}
|
|
else if (cVar1 == 3)
|
|
{
|
|
numCopCars++;
|
|
|
|
if (cp->ai.p.dying == 0)
|
|
{
|
|
numActiveCops++;
|
|
}
|
|
}
|
|
else if (cVar1 == 0)
|
|
{
|
|
numInactiveCars++;
|
|
}
|
|
|
|
cp++;
|
|
} while (cp <= &car_data[21]);
|
|
}
|
|
|
|
if (numRoadblockCars != 0)
|
|
roadblockCount = roadblockDelay;
|
|
|
|
if (requestStationaryCivCar == 0 && requestRoadblock != 0 && numRoadblockCars == 0 && maxCivCars - numCivCars > 4)
|
|
{
|
|
CreateRoadblock();
|
|
}
|
|
|
|
|
|
|
|
if (gInGameCutsceneActive == 0)
|
|
{
|
|
CheckSpecialSpool();
|
|
}
|
|
|
|
cp = car_data;
|
|
while (cp < &car_data[20])
|
|
{
|
|
switch (cp->controlType)
|
|
{
|
|
case 1:
|
|
t0 = Pads[*cp->ai.padid].mapped; // [A] padid might be wrong
|
|
t1 = Pads[*cp->ai.padid].mapanalog[2];
|
|
t2 = Pads[*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(*cp->ai.padid, &t0, &t1, &t2);
|
|
}
|
|
else
|
|
{
|
|
cjpPlay(*cp->ai.padid, &t0, &t1, &t2);
|
|
}
|
|
|
|
ProcessCarPad(cp, t0, t1, t2);
|
|
break;
|
|
case 2:
|
|
CivControl(cp);
|
|
break;
|
|
case 3:
|
|
CopControl(cp);
|
|
break;
|
|
case 4:
|
|
t2 = 0;
|
|
t1 = 0;
|
|
t0 = 0;
|
|
|
|
t0 = FreeRoamer(cp);
|
|
|
|
if (t0 == 0)
|
|
{
|
|
cp->handbrake = 1;
|
|
cp->wheel_angle = 0;
|
|
}
|
|
else
|
|
{
|
|
ProcessCarPad(cp, t0, t1, t2);
|
|
}
|
|
|
|
break;
|
|
case 7:
|
|
#ifdef CUTSCENE_RECORDER
|
|
extern int gCutsceneAsReplay;
|
|
extern int gCutsceneAsReplay_PlayerId;
|
|
|
|
if (gCutsceneAsReplay != 0 && NoPlayerControl == 0 && cp->id == gCutsceneAsReplay_PlayerId)
|
|
{
|
|
t0 = Pads[0].mapped; // [A] padid might be wrong
|
|
t1 = Pads[0].mapanalog[2];
|
|
t2 = Pads[0].type & 4;
|
|
|
|
if (gStopPadReads != 0)
|
|
{
|
|
t0 = 0x80;
|
|
|
|
if (cp->hd.wheel_speed < 0x9001)
|
|
t0 = 0x10;
|
|
|
|
t1 = 0;
|
|
t2 = 1;
|
|
}
|
|
|
|
cjpRecord(-*cp->ai.padid, &t0, &t1, &t2);
|
|
}
|
|
else
|
|
#endif
|
|
cjpPlay(-*cp->ai.padid, &t0, &t1, &t2);
|
|
ProcessCarPad(cp, t0, t1, t2);
|
|
}
|
|
|
|
StepCarPhysics(cp);
|
|
cp++;
|
|
}
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
pl = &player[i];
|
|
|
|
if (pl->playerType != 2)
|
|
continue;
|
|
|
|
stream = pl->padid;
|
|
|
|
if (stream < 0)
|
|
{
|
|
stream = cjpPlay(-stream, &t0, &t1, &t2);
|
|
|
|
if (stream != 0)
|
|
ProcessTannerPad(pl->pPed, t0, t1, t2);
|
|
}
|
|
else
|
|
{
|
|
if (Pads[stream].type == 4)
|
|
{
|
|
cVar1 = Pads[stream].mapanalog[3];
|
|
|
|
if ((cVar1 < -64) && (-100 < cVar1))
|
|
{
|
|
Pads[stream].mapped = Pads[stream].mapped | 0x1008;
|
|
}
|
|
else if ((cVar1 < -100) && (127 < cVar1))
|
|
{
|
|
stream = pl->padid;
|
|
Pads[stream].mapped = Pads[stream].mapped | 0x1000;
|
|
}
|
|
else if (cVar1 > 32)
|
|
{
|
|
stream = pl->padid;
|
|
Pads[stream].mapped = Pads[stream].mapped | 0x4000;
|
|
}
|
|
}
|
|
|
|
stream = pl->padid;
|
|
|
|
t0 = 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
|
|
{
|
|
if (cjpPlay(stream, &t0, &t1, &t2) == 0)
|
|
continue;
|
|
}
|
|
|
|
ProcessTannerPad(pl->pPed, t0, t1, t2);
|
|
}
|
|
}
|
|
|
|
if (requestStationaryCivCar == 1 && (numCivCars < maxCivCars || (PingOutCar(car_data + furthestCivID), numCivCars < maxCivCars)))
|
|
{
|
|
requestStationaryCivCar = 0;
|
|
}
|
|
|
|
if (game_over == 0)
|
|
{
|
|
ControlCops();
|
|
|
|
if(gLoadedMotionCapture)
|
|
HandlePedestrians();
|
|
}
|
|
|
|
i = 0;
|
|
|
|
GlobalTimeStep();
|
|
UpdatePlayers();
|
|
DoScenaryCollisions();
|
|
CheckPlayerMiscFelonies();
|
|
|
|
SetSp(oldsp);
|
|
|
|
CameraCnt++;
|
|
gBobIndex = gBobIndex + 0x3cU & 0xfff;
|
|
if (NumPlayers != 0)
|
|
{
|
|
car = 0;
|
|
pl = player;
|
|
do {
|
|
if (pl->horn.on == 0)
|
|
{
|
|
LAB_0005a5b8:
|
|
stream = CarHasSiren(car_data[player[car].playerCarId].ap.model);
|
|
|
|
if (stream == 0 && pl->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[pl->playerCarId].ap.model);
|
|
|
|
if (stream == 0 && pl->pPed == NULL && pl->horn.request == 0)
|
|
pl->horn.request = 1;
|
|
|
|
pl->horn.time = 11;
|
|
}
|
|
|
|
}
|
|
|
|
DealWithHorn(&player[car].horn.request, i);
|
|
|
|
car++;
|
|
i++;
|
|
pl++;
|
|
} while (i < NumPlayers);
|
|
}
|
|
|
|
SoundTasks();
|
|
|
|
static int stupid_logic[4];
|
|
|
|
if (gInGameCutsceneActive == 0 || gCurrentMissionNumber != 23 || 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++;
|
|
piVar6++;
|
|
} while (car < 4);
|
|
}
|
|
i = i + 1;
|
|
piVar4 = piVar4 + 1;
|
|
} while (i < 3);
|
|
|
|
car = 0;
|
|
i = 0;
|
|
|
|
do {
|
|
stream = i;
|
|
|
|
if ((stupid_logic[car] != -1) && SilenceThisCar(car) == 0)
|
|
{
|
|
stream = i + 1;
|
|
CheckCarEffects(&car_data[stupid_logic[car]], i);
|
|
}
|
|
|
|
car++;
|
|
} 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 &&
|
|
(((i = xa_timeout, XAPrepared() != 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)
|
|
{
|
|
#ifdef PSX
|
|
CloseShutters(2, 320, 512);
|
|
#else
|
|
CloseShutters(16, 320, 512);
|
|
#endif // PSX
|
|
}
|
|
|
|
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++;
|
|
null = buffer + (FrameCnt & 1);
|
|
|
|
setPolyFT3(null);
|
|
|
|
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)
|
|
{
|
|
ReplayParameterPtr->RecordingEnd = CameraCnt;
|
|
}
|
|
|
|
StopPadVibration(0);
|
|
StopPadVibration(1);
|
|
StopAllChannels();
|
|
FreeXM();
|
|
|
|
if (XAPrepared() != 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 = NumPlayers;
|
|
controller_bits = padd;
|
|
|
|
if (NumPlayers != 0)
|
|
{
|
|
pPVar5 = player;
|
|
do {
|
|
if (pPVar5->horn.time == 0 || pPVar5->horn.on == 0)
|
|
pPVar5->horn.time = 0;
|
|
else
|
|
pPVar5->horn.time--;
|
|
|
|
uVar3--;
|
|
pPVar5++;
|
|
} 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;
|
|
|
|
#ifndef PSX
|
|
int screenW, screenH;
|
|
Emulator_GetScreenSize(screenW, screenH);
|
|
|
|
float aspectVar = float(screenH) / float(screenW);
|
|
|
|
FrAng = ratan2(160, float(scr_z) * aspectVar* 1.35f);
|
|
|
|
aspect.m[0][0] = 5500 * aspectVar;
|
|
aspect.m[0][1] = 0;
|
|
aspect.m[0][2] = 0;
|
|
|
|
aspect.m[1][0] = 0;
|
|
aspect.m[1][1] = 4710;
|
|
aspect.m[1][2] = 0;
|
|
|
|
aspect.m[2][0] = 0;
|
|
aspect.m[2][1] = 0;
|
|
aspect.m[2][2] = 4096;
|
|
|
|
#else
|
|
FrAng = ratan2(160, scr_z);
|
|
#endif
|
|
|
|
if ((gTimeInWater == 0) || (gSinkingTimer < 100))
|
|
{
|
|
gStopPadReads = 1;
|
|
TargetCar = 0;
|
|
cameraview = 0;
|
|
gSinkingTimer--;
|
|
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++;
|
|
} while (puVar4 < lightsOnDelay + sizeof(lightsOnDelay));
|
|
}
|
|
|
|
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) // [A] && gInGameCutsceneActive == 0) // allow pausing during cutscene
|
|
{
|
|
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 && FrameCnt > 2 && bMissionTitleFade == 0 && gInGameCutsceneActive == 0)
|
|
{
|
|
pauseflag = 1;
|
|
PauseSound();
|
|
}
|
|
|
|
if (NoPlayerControl == 0 && NoTextureMemory != 0)
|
|
NoTextureMemory--;
|
|
}
|
|
}
|
|
|
|
CameraChanged = 0;
|
|
old_camera_change = camera_change;
|
|
|
|
if (pauseflag == 0 && NoPlayerControl != 0)
|
|
{
|
|
if (gInGameCutsceneActive == 0)
|
|
{
|
|
camera_change = CheckCameraChange(CameraCnt);
|
|
goto LAB_0005b1e0;
|
|
}
|
|
}
|
|
else {
|
|
if (gInGameCutsceneActive == 0)
|
|
{
|
|
camera_change = 0;
|
|
goto LAB_0005b1e0;
|
|
}
|
|
}
|
|
|
|
camera_change = CutsceneCameraChange(CameraCnt);
|
|
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++;
|
|
|
|
while ((VSync(-1) - frame) < 2);
|
|
frame = VSync(-1);
|
|
|
|
SwapDrawBuffers2(1);
|
|
}
|
|
|
|
#ifndef PSX
|
|
Emulator_EndScene();
|
|
#endif
|
|
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
|
|
// [D]
|
|
void SsSetSerialVol(short s_num, short voll, short volr)
|
|
{
|
|
SpuCommonAttr attr;
|
|
|
|
if ((s_num & 0xffU) == 0)
|
|
{
|
|
attr.mask = 0xc0;
|
|
if (0x7f < voll)
|
|
voll = 0x7f;
|
|
|
|
if (0x7f < volr)
|
|
volr = 0x7f;
|
|
|
|
attr.cd.volume.left = voll * 0x102;
|
|
attr.cd.volume.right = volr * 0x102;
|
|
}
|
|
|
|
if (s_num == 1)
|
|
{
|
|
attr.mask = 0xc00;
|
|
if (0x7f < voll)
|
|
voll = 0x7f;
|
|
|
|
if (0x7f < volr)
|
|
volr = 0x7f;
|
|
|
|
attr.ext.volume.left = voll * 0x102;
|
|
attr.ext.volume.right = volr * 0x102;
|
|
}
|
|
|
|
SpuSetCommonAttr(&attr);
|
|
}
|
|
|
|
// 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 */
|
|
|
|
// [D]
|
|
#ifdef PSX
|
|
int main(void)
|
|
#else
|
|
int redriver2_main(int argc, char** argv)
|
|
#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();
|
|
|
|
#ifndef PSX
|
|
if(argc <= 1)
|
|
#endif
|
|
{
|
|
//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();
|
|
|
|
#ifndef PSX
|
|
for (int i = 0; i < argc; i++)
|
|
{
|
|
if (!_stricmp(argv[i], "-players"))
|
|
{
|
|
if (argc - i < 2)
|
|
{
|
|
printError("-players missing number argument!");
|
|
return -1;
|
|
}
|
|
|
|
NumPlayers = atoi(argv[i + 1]);
|
|
}
|
|
else if (!_stricmp(argv[i], "-mission"))
|
|
{
|
|
if (argc - i < 2)
|
|
{
|
|
printError("-mission missing number argument!");
|
|
return -1;
|
|
}
|
|
|
|
SetFEDrawMode();
|
|
|
|
gInFrontend = 0;
|
|
AttractMode = 0;
|
|
|
|
gCurrentMissionNumber = atoi(argv[i + 1]);
|
|
|
|
LaunchGame();
|
|
}
|
|
else if (!_stricmp(argv[i], "-replay"))
|
|
{
|
|
if (argc-i < 2)
|
|
{
|
|
printError("-replay missing argument!");
|
|
return -1;
|
|
}
|
|
|
|
SetFEDrawMode();
|
|
|
|
gInFrontend = 0;
|
|
AttractMode = 0;
|
|
|
|
char nameStr[512];
|
|
sprintf(nameStr, "%s.d2rp", argv[i+1]);
|
|
|
|
FILE* fp = fopen(nameStr, "rb");
|
|
if (fp)
|
|
{
|
|
int replay_size = 0;
|
|
fseek(fp, 0, SEEK_END);
|
|
replay_size = ftell(fp);
|
|
fseek(fp, 0, SEEK_SET);
|
|
|
|
fread(_other_buffer, replay_size, 1, fp);
|
|
fclose(fp);
|
|
|
|
if (LoadReplayFromBuffer(_other_buffer))
|
|
{
|
|
CurrentGameMode = GAMEMODE_REPLAY;
|
|
gLoadedReplay = 1;
|
|
|
|
LaunchGame();
|
|
|
|
gLoadedReplay = 0;
|
|
}
|
|
else
|
|
{
|
|
printError("Error loading replay file '%s'!\n", nameStr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printError("Cannot open replay '%s'!\n", nameStr);
|
|
return -1;
|
|
}
|
|
}
|
|
#ifdef CUTSCENE_RECORDER
|
|
if (!_stricmp(argv[i], "-recordcutscene"))
|
|
{
|
|
if (argc-i < 3)
|
|
{
|
|
printWarning("Example: -recordcutscene <mission_number> <base_mission> <player_id>");
|
|
return 0;
|
|
}
|
|
|
|
SetFEDrawMode();
|
|
|
|
gInFrontend = 0;
|
|
AttractMode = 0;
|
|
|
|
int player_id = atoi(argv[i+3]);
|
|
|
|
extern int LoadCutsceneAsReplay(int subindex);
|
|
extern int gCutsceneAsReplay;
|
|
extern int gCutsceneAsReplay_PlayerId;
|
|
|
|
gCutsceneAsReplay = atoi(argv[i + 1]); // acts as cutscene mission
|
|
gCurrentMissionNumber = atoi(argv[i + 2]); // acts as base mission. Some mission requires other base
|
|
gCutsceneAsReplay_PlayerId = atoi(argv[i + 3]);
|
|
|
|
if (LoadCutsceneAsReplay(0))
|
|
{
|
|
CurrentGameMode = GAMEMODE_REPLAY;
|
|
gLoadedReplay = 1;
|
|
|
|
LaunchGame();
|
|
|
|
gLoadedReplay = 0;
|
|
}
|
|
gCutsceneAsReplay = 0;
|
|
return 1;
|
|
}
|
|
#endif
|
|
}
|
|
#endif // PSX
|
|
|
|
// 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(-32, end_value, 1);
|
|
FadingScreen = 1;
|
|
|
|
do {
|
|
RenderGame();
|
|
} while (FadingScreen != 0);
|
|
|
|
DrawSync(0);
|
|
SetDispMask(0);
|
|
|
|
pauseflag = tmp2;
|
|
}
|
|
|
|
|
|
|
|
// 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 *cp;
|
|
|
|
cp = NULL;
|
|
PlayerDamageBar.max = MaxPlayerDamage[0];
|
|
Player2DamageBar.max = MaxPlayerDamage[1];
|
|
|
|
if (player[0].playerCarId < 0)
|
|
psVar1 = &pedestrianFelony;
|
|
else
|
|
psVar1 = &car_data[player[0].playerCarId].felonyRating;
|
|
|
|
if (gPlayerImmune != 0)
|
|
*psVar1 = 0;
|
|
|
|
FelonyBar.position = *psVar1;
|
|
if (NumPlayers != 0)
|
|
{
|
|
iVar2 = 0;
|
|
iVar8 = 0;
|
|
do {
|
|
|
|
if (player[iVar8].playerType == 1)
|
|
{
|
|
iVar2 = player[iVar8].playerCarId;
|
|
cp = &car_data[iVar2];
|
|
|
|
if (gInvincibleCar != 0)
|
|
{
|
|
cp->totalDamage = 0;
|
|
ClearMem((char *)cp->ap.damage, 0xc);
|
|
}
|
|
|
|
iVar6 = 0;
|
|
iVar7 = iVar8 + 1;
|
|
pWVar4 = cp->hd.wheel;
|
|
iVar5 = 3;
|
|
|
|
do {
|
|
if ((pWVar4->surface & 7) == 1)
|
|
{
|
|
if (pWVar4->susCompression == 0)
|
|
{
|
|
if (cp->hd.where.t[1] < -1000 && gDieWithFade == 0)
|
|
{
|
|
gDieWithFade = pWVar4->surface & 7;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iVar6++;
|
|
}
|
|
}
|
|
|
|
pWVar4++;
|
|
iVar5--;
|
|
} while (-1 < iVar5);
|
|
|
|
if (iVar6 == 4) // apply water damage
|
|
cp->totalDamage += MaxPlayerDamage[iVar8] / 80;
|
|
|
|
if (MaxPlayerDamage[iVar8] < cp->totalDamage)
|
|
cp->totalDamage = MaxPlayerDamage[iVar8];
|
|
|
|
if (iVar8 == 0)
|
|
PlayerDamageBar.position = cp->totalDamage;
|
|
else
|
|
Player2DamageBar.position = cp->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)))) &&
|
|
(cp->hd.where.t[1] < -750)))) && (gDieWithFade == 0))
|
|
{
|
|
gDieWithFade = 1;
|
|
}
|
|
|
|
iVar2 = iVar7 << 3;
|
|
iVar8 = iVar7;
|
|
} while (iVar7 < NumPlayers);
|
|
}
|
|
|
|
|
|
// [A] - test
|
|
/*
|
|
int surface_index = GetSurfaceIndex((VECTOR*)player[0].pos);
|
|
|
|
if (IS_ROAD_SURFACE(surface_index))
|
|
printWarning("------- road idx: %d\n", (surface_index & 0x1fffU));
|
|
|
|
if (IS_CURVED_SURFACE(surface_index))
|
|
{
|
|
DRIVER2_CURVE* crv = GET_CURVE(surface_index);
|
|
|
|
printWarning("CURVE\nlanes: %d\n", crv->NumLanes, crv->NumLanes);
|
|
}
|
|
else if (IS_STRAIGHT_SURFACE(surface_index))
|
|
{
|
|
DRIVER2_STRAIGHT* str = GET_STRAIGHT(surface_index);
|
|
|
|
printWarning("STRAIGHT\nlanes: %d (s: %d s2: %d, ail: %d), conn: %d %d %d %d, lanedirs: %d, ailanes: %d\n",
|
|
str->NumLanes & 0xF, str->NumLanes & 0x40, str->NumLanes & 0x80, str->AILanes, str->ConnectIdx[0], str->ConnectIdx[1], str->ConnectIdx[2], str->ConnectIdx[3], str->LaneDirs);
|
|
str->NumLanes |= 0x80;
|
|
|
|
}
|
|
else if (IS_JUNCTION_SURFACE(surface_index))
|
|
{
|
|
DRIVER2_JUNCTION* junc = GET_JUNCTION(surface_index);
|
|
|
|
printWarning("JUNCTION\nexits: %d %d %d %d, flags: %d\n", junc->ExitIdx[0], junc->ExitIdx[1], junc->ExitIdx[2], junc->ExitIdx[3], junc->flags);
|
|
}
|
|
*/
|
|
}
|
|
|
|
// 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 {
|
|
if (pPVar6->playerCarId != -1 &&
|
|
CarHasSiren(car_data[pPVar6->playerCarId].ap.model) != 0 &&
|
|
pPVar6->horn.on != 0)
|
|
{
|
|
AddCopCarLight(car_data + pPVar6->playerCarId);
|
|
}
|
|
|
|
iVar7--;
|
|
pPVar6++;
|
|
} 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);
|
|
|
|
#ifndef PSX
|
|
extern void DrawDebugOverlays();
|
|
|
|
DrawDebugOverlays();
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
// 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, sizeof(lightsOnDelay));
|
|
|
|
PlayerStartInfo[0] = &ReplayStreams[0].SourceType;
|
|
|
|
#ifdef CUTSCENE_RECORDER
|
|
extern int gCutsceneAsReplay;
|
|
if (gCutsceneAsReplay == 0)
|
|
{
|
|
#endif
|
|
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;
|
|
}
|
|
#ifdef CUTSCENE_RECORDER
|
|
}
|
|
else
|
|
{
|
|
extern int gCutsceneAsReplay_PlayerId;
|
|
extern int gCutsceneAsReplay_PlayerChanged;
|
|
|
|
for (int i = 0; i < NumReplayStreams; i++)
|
|
{
|
|
PlayerStartInfo[i] = &ReplayStreams[i].SourceType;
|
|
}
|
|
|
|
numPlayersToCreate = NumReplayStreams;
|
|
}
|
|
#endif // CUTSCENE_RECORDER
|
|
|
|
|
|
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)
|
|
{
|
|
unsigned char bVar1;
|
|
int channel;
|
|
int modelId;
|
|
_CAR_DATA* car;
|
|
|
|
channel = player[i].playerCarId;
|
|
car = &car_data[player[i].playerCarId];
|
|
|
|
bVar1 = *hr;
|
|
|
|
if (bVar1 == 0)
|
|
{
|
|
return;
|
|
}
|
|
else if (bVar1 == 1)
|
|
{
|
|
channel = 2;
|
|
|
|
if (i != 0)
|
|
channel = 5;
|
|
|
|
StopChannel(channel);
|
|
}
|
|
else if (bVar1 == 2)
|
|
{
|
|
bVar1 = car->ap.model;
|
|
|
|
if (bVar1 == 4)
|
|
modelId = ResidentModelsBodge();
|
|
else if (bVar1 < 3)
|
|
modelId = car->ap.model;
|
|
else
|
|
modelId = car->ap.model - 1;
|
|
|
|
channel = 2;
|
|
|
|
if (i != 0)
|
|
channel = 5;
|
|
|
|
Start3DSoundVolPitch(channel, 3, modelId * 3 + 2,
|
|
car->hd.where.t[0],
|
|
car->hd.where.t[1],
|
|
car->hd.where.t[2], -10000,
|
|
0x1000);
|
|
|
|
if ((1 < NumPlayers) && (NoPlayerControl == 0))
|
|
{
|
|
channel = 2;
|
|
|
|
if (i != 0)
|
|
channel = 5;
|
|
|
|
SetPlayerOwnsChannel(channel, (char)i);
|
|
}
|
|
|
|
channel = 2;
|
|
if (i != 0)
|
|
channel = 5;
|
|
|
|
SetChannelPosition3(channel, (VECTOR *)car->hd.where.t, car->st.n.linearVelocity, -2000, i * 8 + 0x1000, 0);
|
|
}
|
|
|
|
*hr = (*hr+1) % 28; // [A]
|
|
}
|
|
|
|
|
|
|
|
// 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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|