Merge commit '1fc045ca0bc7154da905042f5acef0b7121d0507' into linux

This commit is contained in:
André Vicente Milack 2020-10-07 23:42:37 -03:00
commit ae85ecad2f
47 changed files with 3124 additions and 3668 deletions

1
.gitignore vendored
View File

@ -27,7 +27,6 @@ TDR/*
xmplayer/*
game_rebuild/*
src_rebuild/dependencies/*
# src_rebuild/EMULATOR/*
src_rebuild/.vs/*
src_rebuild/bin/*
src_rebuild/obj/*

View File

@ -498,7 +498,7 @@ void Emulator_GenerateLineArray(struct Vertex* vertex, VERTTYPE* p0, VERTTYPE* p
float ofsX = activeDrawEnv.ofs[0] % activeDispEnv.disp.w;
float ofsY = activeDrawEnv.ofs[1] % activeDispEnv.disp.h;
if (dx > abs(dy)) { // horizontal
if (dx > abs((short)dy)) { // horizontal
vertex[0].x = p0[0] + ofsX;
vertex[0].y = p0[1] + ofsY;

View File

@ -0,0 +1,6 @@
#ifndef RAND_H
#define RAND_H
#include <stdlib.h>
#endif

View File

@ -17,9 +17,9 @@
#include "CAMERA.H"
#include "OBJANIM.H"
#include "RAND.H"
#include "STRINGS.H"
#include "INLINE_C.H"
#include <stdlib.h>
// decompiled code
// original method signature:
@ -65,8 +65,6 @@ int boxOverlap = 0;
int bcollided2d(CDATA2D *body, int needOverlap)
{
int dtheta;
int absdist;
int abslim;
short ac;
short as;
int i; // $t7
@ -95,8 +93,8 @@ int bcollided2d(CDATA2D *body, int needOverlap)
i--;
} while (i != -1);
ac = rcossin_tbl[(dtheta + 0x400 & 0x7ff) * 2];
as = rcossin_tbl[(dtheta & 0x7ff) * 2];
ac = rcossin_tbl[(dtheta + 1024 & 0x7ff) * 2];
delta.vx = body[0].x.vx - body[1].x.vx;
delta.vz = body[0].x.vz - body[1].x.vz;
@ -111,14 +109,12 @@ int bcollided2d(CDATA2D *body, int needOverlap)
body[i].dist[j] = FIXEDH(body[i].axis[j].vx * delta.vx + body[i].axis[j].vz * delta.vz);
body[i].limit[j] = body[i].length[j] + FIXEDH(body[k].length[j] * ac + body[k].length[1-j] * as);
if (body[i].limit[j] < body[i].dist[j])
return 0;
if (body[i].dist[j] < -body[i].limit[j])
if (body[i].dist[j] < -body[i].limit[j] ||
body[i].dist[j] > body[i].limit[j])
return 0;
j--;
} while (j != -1);
} while (j >= 0);
k++;
i--;
@ -133,10 +129,10 @@ int bcollided2d(CDATA2D *body, int needOverlap)
tmp2 = FIXEDH(body->axis[0].vx * body[1].axis[0].vx + body->axis[0].vz * body[1].axis[0].vz);
tmp2 = ABS(tmp2);
if (tmp2 < 11)
xover = -1;
else
if (tmp2 > 10)
xover = (FE * ONE) / tmp2;
else
xover = -1;
FE = ABS(body[1].dist[1]) - ABS(body[1].limit[1]);
FE = ABS(FE);
@ -144,19 +140,17 @@ int bcollided2d(CDATA2D *body, int needOverlap)
tmp2 = FIXEDH(body->axis[0].vx * body[1].axis[1].vx + body->axis[0].vz * body[1].axis[1].vz);
tmp2 = ABS(tmp2);
zover = xover;
if (tmp2 > 10)
zover = (FE * ONE) / tmp2;
if (xover > -1)
{
if (zover < xover)
boxOverlap = zover;
else
boxOverlap = xover;
}
else
zover = xover;
if (xover <= -1)
boxOverlap = zover;
else if (zover < xover)
boxOverlap = zover;
else
boxOverlap = xover;
}
return 1;
@ -242,10 +236,10 @@ void bFindCollisionPoint(CDATA2D *body, CRET2D *collisionResult)
sign = 0;
carBarrierCollision = false;
smallest = body->limit[0] + 1;
if ((body[0].isCameraOrTanner == 0) && (body[1].isCameraOrTanner == 0) &&
(body[1].length[0] << 3 <= body[1].length[1]) || (body[1].length[1] << 3 <= body[1].length[0]))
smallest = body[0].limit[0] + 1;
if (!body[0].isCameraOrTanner && !body[1].isCameraOrTanner &&
(body[1].length[1] >= body[1].length[0] * 4 || body[1].length[0] >= body[1].length[1] * 4))
{
carBarrierCollision = true;
}
@ -289,14 +283,14 @@ void bFindCollisionPoint(CDATA2D *body, CRET2D *collisionResult)
upper = body[1].limit[k] - body[1].dist[k];
lower = body[1].dist[k] + body[1].limit[k];
if (upper < lower && (body[1].length[k] < body[1].length[1-k] << 2))
if (upper < lower && (body[1].length[k] < body[1].length[1-k] * 4))
{
besti = 1;
sign = 1;
bestk = k;
}
if (lower < upper && (body[1].length[k] < body[1].length[1 - k] << 2))
if (lower < upper && (body[1].length[k] < body[1].length[1 - k] * 4))
{
besti = 1;
sign = -1;
@ -309,15 +303,15 @@ void bFindCollisionPoint(CDATA2D *body, CRET2D *collisionResult)
cd = &body[(besti ^ 1)];
sign0 = sign;
if (cd->axis[0].vx * body[besti].axis[bestk].vx + cd->axis[0].vz * body[besti].axis[bestk].vz + 0x800 > -1)
if (cd->axis[0].vx * body[besti].axis[bestk].vx + cd->axis[0].vz * body[besti].axis[bestk].vz + 2048 > -1)
sign0 = -sign;
else
sign0 = sign;
sign1 = sign;
if (cd->axis[1].vx * body[besti].axis[bestk].vx + cd->axis[1].vz * body[besti].axis[bestk].vz + 0x800 > -1)
if (cd->axis[1].vx * body[besti].axis[bestk].vx + cd->axis[1].vz * body[besti].axis[bestk].vz + 2048 > -1)
sign1 = -sign;
else
sign1 = sign;
collisionResult->penetration = smallest;
@ -366,7 +360,6 @@ void bFindCollisionPoint(CDATA2D *body, CRET2D *collisionResult)
// [D] [T]
int bFindCollisionTime(CDATA2D *cd, CRET2D *collisionResult)
{
CDATA2D* coll;
int hit;
int q;
int time;
@ -377,8 +370,8 @@ int bFindCollisionTime(CDATA2D *cd, CRET2D *collisionResult)
hit = 1;
neverfree = 1;
time = 0x1000;
step = 0x800;
time = 4096;
step = 2048;
i = 1;
do {
@ -604,17 +597,17 @@ int DamageCar3D(_CAR_DATA *cp, long(*delta)[4], int strikeVel, _CAR_DATA *pOther
char region;
int value;
bool fakeDamage;
int lbody;
int player_id;
int kludge;
int door, nose;
strikeVel = strikeVel * 0x177;
strikeVel *= 375;
value = cp->ap.carCos->colBox.vz << 0x10;
value = (value >> 0x10) - (value >> 0x1f) >> 1;
lbody = cp->ap.carCos->colBox.vz / 2;
strikeVel = strikeVel >> 8;
strikeVel >>= 8;
if (strikeVel < 0xa000)
{
@ -629,25 +622,29 @@ int DamageCar3D(_CAR_DATA *cp, long(*delta)[4], int strikeVel, _CAR_DATA *pOther
if (door < 1)
{
region = 0;
if ((nose <= value) && (region = 4, -value < nose))
if(nose > lbody)
region = 0;
else if (-lbody < nose)
region = 5;
else
region = 4;
}
else
{
region = 1;
if ((nose <= value) && (region = 3, -value < nose))
if(nose > lbody)
region = 1;
else if (-lbody < nose)
region = 2;
else
region = 3;
}
if (cp->controlType == CONTROL_TYPE_PLAYER)
{
value = (strikeVel / 350 + 0x200) * 3;
value = value >> 3;
if (0x477 < value)
value >>= 3;
if (value > 0x477)
value = 0x477;
}
@ -657,9 +654,9 @@ int DamageCar3D(_CAR_DATA *cp, long(*delta)[4], int strikeVel, _CAR_DATA *pOther
{
value = (strikeVel / 350 + 0x200) * 3;
value = value >> 3;
value >>= 3;
if (0x477 < value)
if (value > 0x477)
value = 0x477;
cp->ai.l.takeDamage = 0x32;
@ -668,8 +665,8 @@ int DamageCar3D(_CAR_DATA *cp, long(*delta)[4], int strikeVel, _CAR_DATA *pOther
{
value = strikeVel / 350 + 0x200;
value = value >> 2;
if (0x2fa < value)
value >>= 3;
if (value > 0x2fa)
value = 0x2fa;
if (cp->ai.l.takeDamage == 0)
@ -681,7 +678,7 @@ int DamageCar3D(_CAR_DATA *cp, long(*delta)[4], int strikeVel, _CAR_DATA *pOther
value = ((strikeVel / 400 + 0x400) * 7) >> 3;
}
fakeDamage = cp->controlType == CONTROL_TYPE_PURSUER_AI && pOtherCar->controlType == CONTROL_TYPE_PURSUER_AI;
fakeDamage = (cp->controlType == CONTROL_TYPE_PURSUER_AI && pOtherCar->controlType == CONTROL_TYPE_PURSUER_AI);
ApplyDamage(cp, region, value, fakeDamage);
@ -748,15 +745,14 @@ void DamageCar(_CAR_DATA *cp, CDATA2D *cd, CRET2D *collisionResult, int strikeVe
int region;
int dz;
int dx;
int lbody;
player_id = GetPlayerId(cp);
value = cp->ap.carCos->colBox.vz << 0x10;
lbody = cp->ap.carCos->colBox.vz / 2;
impact = strikeVel / 600;
value = (value >> 0x10) - (value >> 0x1f) >> 1;
if (0x4fff < strikeVel && 9 < cp->hd.speed)
if (strikeVel > 0x4fff && cp->hd.speed > 9)
{
dx = collisionResult->hit.vx - cd->x.vx;
dz = collisionResult->hit.vz - cd->x.vz;
@ -766,21 +762,27 @@ void DamageCar(_CAR_DATA *cp, CDATA2D *cd, CRET2D *collisionResult, int strikeVe
if (door < 1)
{
region = 0;
if ((nose <= value) && (region = 4, -value < nose))
if (nose > lbody)
region = 0;
else if (-lbody < nose)
region = 5;
else
region = 4;
}
else
else
{
region = 1;
if ((nose <= value) && (region = 3, -value < nose))
if (nose > lbody)
region = 1;
else if (-lbody < nose)
region = 2;
else
region = 3;
}
if (0x1f4000 < strikeVel)
strikeVel = 0x1f4000;
value = ((strikeVel / 300) * 0x400) / 0x5dc;
value = ((strikeVel / 300) * 1024) / 1500;
if (0x800 < value)
value = 0x800;
@ -994,7 +996,7 @@ int CarBuildingCollision(_CAR_DATA *cp, BUILDING_BOX *building, CELL_OBJECT *cop
cd[0].theta = cp->hd.direction;
if (cp->controlType == 6)
if (cp->controlType == CONTROL_TYPE_TANNERCOLLIDER)
{
cd[0].vel.vx = FIXEDH(cp->st.n.linearVelocity[0]);
cd[0].vel.vz = FIXEDH(cp->st.n.linearVelocity[2]);
@ -1041,11 +1043,11 @@ int CarBuildingCollision(_CAR_DATA *cp, BUILDING_BOX *building, CELL_OBJECT *cop
if (cp->controlType == CONTROL_TYPE_CAMERACOLLIDER)
{
collided = (bcollided2d(cd, 1) != 0);
collided = bcollided2d(cd, 1);
}
else
{
collided = (bcollided2d(cd, 0) != 0);
collided = bcollided2d(cd, 0);
#if defined(COLLISION_DEBUG) && !defined(PSX)

View File

@ -20,7 +20,7 @@
#include "../ASM/ASMTEST.H"
#include "INLINE_C.H"
#include <stdlib.h>
#include "RAND.H"
MODEL* gBombModel;
_ExOBJECT explosion[5];

View File

@ -8,25 +8,22 @@
#include "DEBRIS.H"
#include "MAIN.H"
#include "CAMERA.H"
#include "DRAW.H"
#include "HANDLING.H"
#include "COSMETIC.H"
#include "DENTING.H"
#include "SHADOW.H"
#include "CIV_AI.H"
#include "COP_AI.H"
#include "MC_SND.H"
#include "GAMESND.H"
#include "PLAYERS.H"
#include "CUTSCENE.H"
#include "CONVERT.H"
#include "PAUSE.H"
#include "PLAYERS.H"
#include "GLAUNCH.H"
#include "../ASM/ASMTEST.H"
#include "INLINE_C.H"
#include "LIBAPI.H"
MATRIX light_matrix =
{ { { 4096, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, { 0, 0, 0 } };
@ -849,9 +846,21 @@ void DrawCar(_CAR_DATA *cp, int view)
num_cars_drawn++;
MulMatrix0(&inv_camera_matrix, &cp->hd.drawCarMat, &workmatrix);
// [A] there was mini cars cheat
// we need full blown mini cars with physics support
if (ActiveCheats.cheat13 != 0)
{
int i;
for (i = 0; i < 3; i++)
{
workmatrix.m[i][0] >>= 1;
workmatrix.m[i][1] >>= 1;
workmatrix.m[i][2] >>= 1;
}
}
// LOD switching
if (pos.vz < 5501 && gForceLowDetailCars == 0 || cp->controlType == CONTROL_TYPE_PLAYER)
{
@ -897,11 +906,15 @@ void DrawCar(_CAR_DATA *cp, int view)
CarModelPtr->vlist = gTempCarVertDump[cp->id];
CarModelPtr->nlist = gTempCarVertDump[cp->id];
MulMatrix0(&inv_camera_matrix, &cp->hd.drawCarMat, &workmatrix);
FindCarLightFade(&workmatrix);
DrawCarObject(CarModelPtr, &workmatrix, &pos, cp->ap.palette, cp, 1);
if (ActiveCheats.cheat13 != 0)
{
MulMatrix0(&inv_camera_matrix, &cp->hd.drawCarMat, &workmatrix);
}
DrawCarWheels(cp, &workmatrix, &pos, view);
}
else
@ -918,7 +931,7 @@ void DrawCar(_CAR_DATA *cp, int view)
}
ComputeCarLightingLevels(cp, 0);
MulMatrix0(&inv_camera_matrix, &cp->hd.drawCarMat, &workmatrix);
FindCarLightFade(&workmatrix);
DrawCarObject(CarModelPtr, &workmatrix, &pos, cp->ap.palette, cp, 0);

File diff suppressed because it is too large Load Diff

View File

@ -1556,80 +1556,76 @@ void ControlCopDetection(void)
while (car_data <= cp)
{
uVar1 = cp->controlType;
if (cp->controlType == 3 && cp->ai.p.dying == 0 || cp->controlFlags & CONTROL_FLAG_COP)
{
vec.vx = cp->hd.where.t[0];
vec.vz = cp->hd.where.t[2];
y = cp->hd.where.t[0];
x = y - player[0].pos[0];
if (uVar1 == 3)
{
if (cp->ai.p.dying == 0)
goto LAB_0002eed0;
}
else
{
if ((cp->controlFlags & 1) != 0)
if (x < 0)
x = player[0].pos[0] - y;
iVar7 = cp->hd.where.t[2];
y = iVar7 - player[0].pos[2];
if (y < 0)
y = player[0].pos[2] - iVar7;
lVar6 = SquareRoot0(x * x + y * y);
if (cp->controlType == 3)
{
LAB_0002eed0:
vec.vx = cp->hd.where.t[0];
vec.vz = cp->hd.where.t[2];
y = cp->hd.where.t[0];
x = y - player[0].pos[0];
if (x < 0)
x = player[0].pos[0] - y;
iVar7 = cp->hd.where.t[2];
y = iVar7 - player[0].pos[2];
if (y < 0)
y = player[0].pos[2] - iVar7;
lVar6 = SquareRoot0(x * x + y * y);
cp->ai.p.DistanceToPlayer = lVar6;
if ((uVar1 == 3) && cp->ai.p.close_pursuit != 0)
if(cp->ai.p.close_pursuit != 0)
{
LAB_0002f040:
CopsCanSeePlayer = 1;
break;
}
}
if (newPositionVisible(&vec, CopWorkMem, ccx, ccz) != 0)
if (newPositionVisible(&vec, CopWorkMem, ccx, ccz) != 0)
{
if (lVar6 < copSightData.surroundViewDistance)
{
if (lVar6 < copSightData.surroundViewDistance)
LAB_0002f030:
bVar2 = true;
}
else
{
bVar2 = false;
if (lVar6 < copSightData.frontViewDistance)
{
LAB_0002f030:
bVar2 = true;
}
else
{
bVar2 = false;
if (lVar6 < copSightData.frontViewDistance)
y = targetVehicle->hd.where.t[0] - cp->hd.where.t[0];
x = targetVehicle->hd.where.t[2] - cp->hd.where.t[2];
lVar6 = ratan2(y, x);
if (lVar6 - cp->hd.direction < 0)
{
y = targetVehicle->hd.where.t[0] - cp->hd.where.t[0];
x = targetVehicle->hd.where.t[2] - cp->hd.where.t[2];
lVar6 = ratan2(y, x);
if (lVar6 - cp->hd.direction < 0)
{
lVar6 = ratan2(y, x);
x = cp->hd.direction - lVar6;
}
else
{
lVar6 = ratan2(y, x);
x = lVar6 - cp->hd.direction;
}
if ((x < copSightData.frontViewAngle) || (bVar2 = false, x < copSightData.frontViewAngle + 0x200))
goto LAB_0002f030;
x = cp->hd.direction - lVar6;
}
else
{
lVar6 = ratan2(y, x);
x = lVar6 - cp->hd.direction;
}
if ((x < copSightData.frontViewAngle) || (bVar2 = false, x < copSightData.frontViewAngle + 0x200))
goto LAB_0002f030;
}
if (bVar2)
goto LAB_0002f040;
}
if (bVar2)
{
CopsCanSeePlayer = 1;
break;
}
}
}
cp = cp + -1;
cp--;
}
}
}

View File

@ -12,8 +12,8 @@
#include "INLINE_C.H"
#include <string.h>
#include <stdlib.h>
#include "RAND.H"
#include "STRINGS.H"
char* CosmeticFiles[] = {
"LEVELS\\CHICAGO.LCF",

View File

@ -1225,6 +1225,7 @@ int LoadCutsceneToReplayBuffer(int residentCutscene)
destStream->InitialPadRecordBuffer = (PADRECORD*)replayptr;
destStream->PadRecordBuffer = (PADRECORD*)replayptr;
destStream->PadRecordBufferEnd = (PADRECORD *)(replayptr + sheader->Size);
destStream->padCount = sheader->Size;
destStream->length = sheader->Length;
destStream->playbackrun = 0;
@ -1296,6 +1297,7 @@ int LoadCutsceneToBuffer(int subindex)
CUTSCENE_HEADER header;
char filename[64];
char customFilename[64];
if (gCurrentMissionNumber < 21)
sprintf(filename, "REPLAYS\\CUT%d.R", gCurrentMissionNumber);
@ -1313,6 +1315,10 @@ int LoadCutsceneToBuffer(int subindex)
offset = header.data[subindex].offset * 4;
size = header.data[subindex].size;
#ifndef PSX
// [A] REDRIVER2 PC - custom cutcenes or chases for debugging
sprintf(customFilename, "REPLAYS\\CUT%d\\%d.D2RP", gCurrentMissionNumber, subindex);
#endif
if (CutsceneBuffer.bytesFree < size)
{
// load into lead/path AI buffer
@ -1322,11 +1328,27 @@ int LoadCutsceneToBuffer(int subindex)
CutsceneBuffer.currentPointer = _other_buffer2;
CutsceneBuffer.bytesFree = 0xc000;
LoadfileSeg(filename, _other_buffer2, offset, size);
#ifndef PSX
if (FileExists(customFilename))
{
printInfo("Custom cutscene replay file loaded\n");
LoadfileSeg(customFilename, _other_buffer2, 0, size);
}
else
#endif
LoadfileSeg(filename, _other_buffer2, offset, size);
}
else
{
LoadfileSeg(filename, CutsceneBuffer.currentPointer, offset, size);
#ifndef PSX
if (FileExists(customFilename))
{
printInfo("Custom cutscene replay file loaded\n");
LoadfileSeg(customFilename, _other_buffer2, 0, size);
}
else
#endif
LoadfileSeg(filename, CutsceneBuffer.currentPointer, offset, size);
}
CutsceneBuffer.residentCutscenes[CutsceneBuffer.numResident] = subindex;

View File

@ -26,10 +26,9 @@
#include "../ASM/ASMTEST.H"
#include "INLINE_C.H"
#include "RAND.H"
#include "STRINGS.H"
#include <stdlib.h>
TEXTURE_DETAILS digit_texture;
TRI_POINT debris_rot1[32]; // offset 0xC0A60
@ -1614,11 +1613,6 @@ void DrawSmashable_sprites(void)
RotMatrixZ(dam->rot_speed * dam->damage & 0xfff, &object_matrix);
// [A]
#ifndef PSX
MulMatrix0(&aspect, &object_matrix, &object_matrix);
#endif
pos.vx = dam->vx - camera_position.vx;
pos.vy = dam->cop.pos.vy - camera_position.vy;
pos.vz = dam->cop.pos.vz - camera_position.vz;
@ -2066,7 +2060,7 @@ void AddLightEffect(CELL_OBJECT *cop, int x, int y, int z, int type, int colour)
Apply_Inv_CameraMatrix(&v1);
gte_SetRotMatrix(&aspect);
gte_SetRotMatrix(&identity);
gte_SetTransVector(&v1);
ShowLight1(&v1, &col, size, &light_texture);
@ -2882,7 +2876,7 @@ void ShowLight(VECTOR *v1, CVECTOR *col, short size, TEXTURE_DETAILS *texture)
Apply_Inv_CameraMatrix(v1);
gte_SetRotMatrix(&aspect);
gte_SetRotMatrix(&identity);
gte_SetTransVector(v1);
vert[0].vz = 0;
@ -3462,9 +3456,6 @@ void ShowFlare(VECTOR *v1, CVECTOR *col, short size, int rotation)
direction.vz = rotation;
RotMatrixXYZ(&temp_matrix, &direction);
#ifndef PSX
MulMatrix0(&aspect, &temp_matrix, &temp_matrix);
#endif
gte_SetRotMatrix(&temp_matrix);
@ -4881,7 +4872,7 @@ void DisplaySmoke(SMOKE *smoke)
Apply_Inv_CameraMatrix(&v);
gte_SetTransVector(&v);
gte_SetRotMatrix(&aspect);
gte_SetRotMatrix(&identity);
smokemesh[0].vx = -smoke->start_w;
smokemesh[0].vy = -smoke->start_w;
@ -5582,7 +5573,7 @@ void DisplaySplashes(void)
iVar4 = FIXEDH(uVar3 * FrAng * 3);
gte_SetRotMatrix(&aspect); // [A] norot
gte_SetRotMatrix(&identity); // [A] norot
CamGnd.vx = camera_position.vx;
CamGnd.vz = camera_position.vz;

View File

@ -20,8 +20,8 @@
#include "SYSTEM.H"
#include "../MEMCARD/MAIN.H"
#include "RAND.H"
#include "STRINGS.H"
#include <stdlib.h>
TEXTURE_DETAILS delcam; // address 0xC0EE0
TEXTURE_DETAILS incar; // address 0xBF950

View File

@ -27,6 +27,37 @@ int NumDriver2Curves = 0;
int NumDriver2Straights = 0;
DRIVER2_STRAIGHT *Driver2StraightsPtr = NULL;
// [A] custom function for working with roads in very optimized way
int GetSurfaceRoadInfo(DRIVER2_ROAD_INFO* outRoadInfo, int surfId)
{
DRIVER2_CURVE* curve;
DRIVER2_STRAIGHT* straight;
ClearMem((char*)outRoadInfo, sizeof(DRIVER2_ROAD_INFO));
outRoadInfo->surfId = surfId;
if(IS_CURVED_SURFACE(surfId))
{
outRoadInfo->curve = curve = GET_CURVE(surfId);
outRoadInfo->ConnectIdx = (short(*)[4])curve->ConnectIdx;
outRoadInfo->NumLanes = curve->NumLanes;
outRoadInfo->LaneDirs = curve->LaneDirs;
outRoadInfo->AILanes = curve->AILanes;
return 1;
}
else if (IS_STRAIGHT_SURFACE(surfId))
{
outRoadInfo->straight = straight = GET_STRAIGHT(surfId);
outRoadInfo->ConnectIdx = (short(*)[4])straight->ConnectIdx;
outRoadInfo->NumLanes = straight->NumLanes;
outRoadInfo->LaneDirs = straight->LaneDirs;
outRoadInfo->AILanes = straight->AILanes;
return 1;
}
return 0;
}
// decompiled code
// original method signature:
// void /*$ra*/ ProcessStraightsDriver2Lump(char *lump_file /*$s0*/, int lump_size /*$a1*/)

View File

@ -1,34 +1,51 @@
#ifndef DR2ROADS_H
#define DR2ROADS_H
#define IS_ROAD_SURFACE(surfid) (((surfid) & 0xFFFFE000) != 0xFFFFE000) // is any road surface
#define IS_STRAIGHT_SURFACE(surfid) (((surfid) > -1) && ((surfid) & 0xFFFFE000) == 0 && ((surfid) & 0x1FFF) < NumDriver2Straights)
#define IS_CURVED_SURFACE(surfid) (((surfid) > -1) && ((surfid) & 0xFFFFE000) == 0x4000 && ((surfid) & 0x1FFF) < NumDriver2Curves)
#define IS_JUNCTION_SURFACE(surfid) (((surfid) > -1) && ((surfid) & 0xFFFFE000) == 0x2000 && ((surfid) & 0x1FFF) < NumDriver2Junctions)
#define IS_STRAIGHT_SURFACE(surfid) (((surfid) > -1) && ((surfid) & 0xFFFFE000) == 0 && (surfid & 0x1FFF) < NumDriver2Straights)
#define IS_CURVED_SURFACE(surfid) (((surfid) > -1) && ((surfid) & 0xFFFFE000) == 0x4000 && (surfid & 0x1FFF) < NumDriver2Curves)
#define IS_JUNCTION_SURFACE(surfid) (((surfid) > -1) && ((surfid) & 0xFFFFE000) == 0x2000 && (surfid & 0x1FFF) < NumDriver2Junctions)
#define IS_DRIVEABLE_SURFACE(surfid) (((surfid) & 0xFFFFE000) != 0xFFFFE000) // is any road surface
#define IS_ROAD_SURFACE(surfid) (IS_STRAIGHT_SURFACE(surfid) || IS_CURVED_SURFACE(surfid))
#define GET_STRAIGHT(surfid) (Driver2StraightsPtr + (surfid & 0x1FFF))
#define GET_CURVE(surfid) (Driver2CurvesPtr + (surfid & 0x1FFF))
#define GET_JUNCTION(surfid) (Driver2JunctionsPtr + (surfid & 0x1FFF))
#define GET_STRAIGHT(surfid) (Driver2StraightsPtr + ((surfid) & 0x1FFF))
#define GET_CURVE(surfid) (Driver2CurvesPtr + ((surfid) & 0x1FFF))
#define GET_JUNCTION(surfid) (Driver2JunctionsPtr + ((surfid) & 0x1FFF))
// $DEPRECATED: as it's used to detect lane direction, use ROAD_LANE_DIR instead
#define IS_NARROW_ROAD(rd) \
((*(ushort*)&(rd)->NumLanes & 0xFFFF) == 0xFF01)
// those macros can be applied to straights and junctions
#define ROAD_LANES_COUNT(rd) ((uint)rd->NumLanes & 0xF) // lane count
#define ROAD_LANES_COUNT(rd) ((uint)(rd)->NumLanes & 0xF) // lane count
#define ROAD_WIDTH_IN_LANES(rd) (ROAD_LANES_COUNT(rd) * 2) // width in lanes
#define ROAD_IS_AI_LANE(rd, lane) ((u_char)rd->AILanes >> (lane / 2) & 1U) // lane AI driveable flag
#define ROAD_IS_LEFTMOST_LANE_PARKING(rd) ((rd->NumLanes & 0x40) != 0) // allows parking on leftmost lane
#define ROAD_IS_RIGHTMOST_LANE_PARKING(rd) ((rd->NumLanes & 0x80) != 0) // allows parking on rightmost lane
#define ROAD_LANE_DIRECTION_BIT(rd, lane) ((u_char)rd->LaneDirs >> (lane / 2) & 1U) // direction bit
#define ROAD_SPEED_LIMIT(rd) (((u_char)rd->NumLanes >> 4) & 3) // speed limit id
#define ROAD_IS_AI_LANE(rd, lane) ((u_char)(rd)->AILanes >> ((lane) / 2) & 1U) // lane AI driveable flag
#define ROAD_IS_LEFTMOST_LANE_PARKING(rd) (((u_char)(rd)->NumLanes & 0x40) != 0) // allows parking on leftmost lane
#define ROAD_IS_RIGHTMOST_LANE_PARKING(rd) (((u_char)(rd)->NumLanes & 0x80) != 0) // allows parking on rightmost lane
#define ROAD_LANE_DIRECTION_BIT(rd, lane) ((u_char)(rd)->LaneDirs >> ((lane) / 2) & 1U) // direction bit
#define ROAD_SPEED_LIMIT(rd) (((u_char)(rd)->NumLanes >> 4) & 3) // speed limit id
#define ROAD_HAS_FAST_LANES(rd) (((u_char)(rd)->NumLanes >> 6) & 1) // & 0x20; in fact speed limit check too
#define ROAD_LANE_DIR(rd, lane) \
(((u_char)rd->LaneDirs == 0xFF && rd->NumLanes == 1) ? (lane & 1) : ROAD_LANE_DIRECTION_BIT(rd, lane))
(((u_char)(rd)->LaneDirs == 0xFF && (rd)->NumLanes == 1) ? ((lane) & 1) : ROAD_LANE_DIRECTION_BIT(rd, lane))
#define ROAD_IS_PARKING_ALLOWED_AT(rd, lane)\
((ROAD_IS_LEFTMOST_LANE_PARKING(rd) && lane == 0) || (ROAD_IS_RIGHTMOST_LANE_PARKING(rd) && lane == ROAD_WIDTH_IN_LANES(rd) - 1))
((ROAD_IS_LEFTMOST_LANE_PARKING(rd) && (lane) == 0) || (ROAD_IS_RIGHTMOST_LANE_PARKING(rd) && (lane) == ROAD_WIDTH_IN_LANES(rd) - 1))
// Driver 2 road data.
struct DRIVER2_ROAD_INFO
{
int surfId;
short (*ConnectIdx)[4];
char NumLanes;
char LaneDirs;
char AILanes;
DRIVER2_STRAIGHT* straight;
DRIVER2_CURVE* curve;
};
extern ROAD_MAP_LUMP_DATA roadMapLumpData;
@ -45,6 +62,8 @@ extern int NumDriver2Curves;
extern short* RoadMapDataRegions[4];
extern int GetSurfaceRoadInfo(DRIVER2_ROAD_INFO* outRoadInfo, int surfId);
extern void ProcessStraightsDriver2Lump(char *lump_file, int lump_size); // 0x000136C0
extern void ProcessCurvesDriver2Lump(char *lump_file, int lump_size); // 0x000136F4

View File

@ -29,6 +29,16 @@ MATRIX aspect =
{ 0, 0, 0 }
};
MATRIX identity =
{
{
{ 4096, 0, 0 },
{ 0, 4096, 0 },
{ 0, 0, 4096 }
},
{ 0, 0, 0 }
};
int PolySizes[56] = {
8, 12, 16, 24,
20, 20, 28, 32,

View File

@ -7,6 +7,7 @@ extern SVECTOR day_colours[4];
extern SVECTOR night_colours[4];
extern MATRIX aspect;
extern MATRIX identity;
extern MATRIX inv_camera_matrix;
extern MATRIX face_camera;

View File

@ -19,7 +19,7 @@
#include "../ASM/ASMTEST.H"
#include "INLINE_C.H"
#include <stdlib.h>
#include "RAND.H"
MODEL* gTrailblazerConeModel;
SMASHED_CONE smashed_cones[6];
@ -915,11 +915,6 @@ void DrawSmashedCone(SMASHED_CONE *sc, VECTOR *wpos)
pos.vy = wpos->vy - camera_position.vy;
pos.vz = wpos->vz - camera_position.vz;
// [A]
#ifndef PSX
MulMatrix0(&aspect, &object_matrix, &object_matrix);
#endif
Apply_Inv_CameraMatrix(&pos);
SetRotMatrix(&object_matrix);

View File

@ -24,9 +24,7 @@
#include "../ASM/ASMTEST.H"
#include "INLINE_C.H"
#include <stdlib.h>
#include "RAND.H"
int ElTrainData[83] = {
6, 80, 130, 32768, 336284, -220364, 283420, -2147483646,
@ -2576,6 +2574,14 @@ int GetBridgeRotation(int timer)
if (debugRotation != -1)
return debugRotation;
#ifdef CUTSCENE_RECORDER
extern int gCutsceneAsReplay;
if (gCutsceneAsReplay != 0)
{
return 0;
}
#endif
if (2600 < timer)
{
return 0;

View File

@ -569,14 +569,10 @@ void CheckPlayerMiscFelonies(void)
int exitId;
int _exitId;
VECTOR *carPos;
DRIVER2_CURVE *cv;
DRIVER2_STRAIGHT *st;
DRIVER2_ROAD_INFO roadInfo;
DRIVER2_JUNCTION *jn;
_CAR_DATA* cp;
cv = NULL;
st = NULL;
if (player[0].playerType == 2 || player[0].playerCarId < 0 || FelonyBar.active == 0)
return;
@ -613,36 +609,50 @@ void CheckPlayerMiscFelonies(void)
playerLastRoad = surfInd;
goingWrongWay = false;
// straight or curve
if (IS_STRAIGHT_SURFACE(surfInd))
if(GetSurfaceRoadInfo(&roadInfo, surfInd))
{
int lane_count;
int lane; // $s0
int dx; // $v1
int dz; // $a0
int lane;
int dx;
int dz;
int crd;
st = GET_STRAIGHT(surfInd);
lane_count = ROAD_WIDTH_IN_LANES(&roadInfo);
dx = carPos->vx - st->Midx;
dz = carPos->vz - st->Midz;
lane = ROAD_LANES_COUNT(st) - (FIXEDH(dx * rcossin_tbl[(st->angle & 0xfff) * 2 + 1] - dz * rcossin_tbl[(st->angle & 0xfff) * 2]) + 512 >> 9);
lane_count = ROAD_WIDTH_IN_LANES(st);
if (lane < 0)
lane = 0;
if (lane_count <= lane)
lane = lane_count - 1;
// check if on correct lane
if (ROAD_IS_AI_LANE(st, lane))
if(roadInfo.straight)
{
int crd;
crd = (st->angle - cp->hd.direction) + 0x400U >> 0xb & 1;
dx = carPos->vx - roadInfo.straight->Midx;
dz = carPos->vz - roadInfo.straight->Midz;
if (ROAD_LANE_DIR(st, lane) == 0)
lane = ROAD_LANES_COUNT(&roadInfo) - (FIXEDH(dx * rcossin_tbl[(roadInfo.straight->angle & 0xfff) * 2 + 1] - dz * rcossin_tbl[(roadInfo.straight->angle & 0xfff) * 2]) + 512 >> 9);
if (lane < 0)
lane = 0;
if (lane_count <= lane)
lane = lane_count - 1;
crd = (roadInfo.straight->angle - cp->hd.direction) + 0x400U >> 0xb & 1;
}
else
{
dx = carPos->vx - roadInfo.curve->Midx;
dz = carPos->vz - roadInfo.curve->Midz;
lane = (SquareRoot0(dx * dx + dz * dz) >> 9) - roadInfo.curve->inside * 2;
if (lane < 0)
lane = 0;
if (lane >= lane_count)
lane = lane_count - 1;
crd = NotTravellingAlongCurve(carPos->vx, carPos->vz, cp->hd.direction, roadInfo.curve);
}
// check if on correct lane
if (ROAD_IS_AI_LANE(&roadInfo, lane))
{
if (ROAD_LANE_DIR(&roadInfo, lane) == 0)
{
if (crd == 1)
goingWrongWay = true;
@ -655,69 +665,25 @@ void CheckPlayerMiscFelonies(void)
}
#if 0
printInfo("str lane: %d / %d (%d). AI drive: %d, flg: %d%d, dir: %d, spd: %d (wrong way: %d)\n",
printInfo("ROAD lane: %d / %d, (%d). AI drive: %d, flg: %d%d%d, dir: %d, spd: %d (wrong way: %d)\n",
lane + 1,
((u_char)st->NumLanes & 0xF) * 2, // lane count. * 2 for both sides as roads are symmetric
IS_NARROW_ROAD(st),
((u_char)st->AILanes >> (lane / 2) & 1U), // lane AI driveable flag
(st->NumLanes & 0x40) > 0, // flag 1 - parking allowed?
(st->NumLanes & 0x80) > 0, // flag 2 - spawning allowed?
((u_char)st->LaneDirs >> (lane / 2) & 1U), // direction bit
((u_char)st->NumLanes >> 4) & 3, // speed limit id
((u_char)roadInfo.NumLanes & 0xF) * 2, // lane count. * 2 for both sides as roads are symmetric
IS_NARROW_ROAD(&roadInfo),
((u_char)roadInfo.AILanes >> (lane / 2) & 1U), // lane AI driveable flag
(roadInfo.NumLanes & 0x20) > 0, // flag 0 - first lane?
(roadInfo.NumLanes & 0x40) > 0, // flag 1 - leftmost park
(roadInfo.NumLanes & 0x80) > 0, // flag 2 - rightmost park
((u_char)roadInfo.LaneDirs >> (lane / 2) & 1U), // direction bit
((u_char)roadInfo.NumLanes >> 4) & 3, // speed limit id
goingWrongWay);
#endif
// get road speed limit
maxSpeed = speedLimits[ROAD_SPEED_LIMIT(&roadInfo)];
}
else if(IS_CURVED_SURFACE(surfInd))
else
{
int lane_count;
int lane; // $s0
int dx; // $v1
int dz; // $a0
cv = GET_CURVE(surfInd);
dx = carPos->vx - cv->Midx;
dz = carPos->vz - cv->Midz;
lane = (SquareRoot0(dx * dx + dz * dz) >> 9) - cv->inside * 2;
if (lane < 0)
lane = 0;
lane_count = ROAD_WIDTH_IN_LANES(cv);
if (lane >= lane_count)
lane = lane_count - 1;
// check if on correct lane
if (ROAD_IS_AI_LANE(cv, lane))
{
int crd;
crd = NotTravellingAlongCurve(carPos->vx, carPos->vz, cp->hd.direction, cv);
if (ROAD_LANE_DIR(cv, lane) == 0)
{
if (crd != 0)
goingWrongWay = true;
}
else
{
if (crd == 0)
goingWrongWay = true;
}
}
#if 0
printInfo("crv lane: %d / %d, (%d). AI drive: %d, flg: %d%d, dir: %d, spd: %d (wrong way: %d)\n",
lane + 1,
((u_char)cv->NumLanes & 0xF) * 2, // lane count. * 2 for both sides as roads are symmetric
IS_NARROW_ROAD(cv),
((u_char)cv->AILanes >> (lane / 2) & 1U), // lane AI driveable flag
(cv->NumLanes & 0x40) > 0, // flag 1 - parking allowed?
(cv->NumLanes & 0x80) > 0, // flag 2 - spawning allowed?
((u_char)cv->LaneDirs >> (lane / 2) & 1U), // direction bit
((u_char)cv->NumLanes >> 4) & 3, // speed limit id
goingWrongWay);
#endif
maxSpeed = speedLimits[2];
}
// wrong way
@ -749,13 +715,6 @@ void CheckPlayerMiscFelonies(void)
NoteFelony(&felonyData, 10, 0x1000);
// check the speed limit
if (st != NULL)
maxSpeed = speedLimits[ROAD_SPEED_LIMIT(st)];
else if (cv != NULL)
maxSpeed = speedLimits[ROAD_SPEED_LIMIT(cv)];
else
maxSpeed = speedLimits[2];
if (speedLimits[2] == maxSpeed)
limit = (maxSpeed * 19) >> 4;
else

View File

@ -342,12 +342,13 @@ int MapCarIndexToBank(int index)
{8, 7, 13, 9, 2, 17, 17, 11, 16},
};
int iVar1;
int iVar2;
iVar1 = MissionHeader->residentModels[index];
if (gCurrentMissionNumber - 39 < 2 && iVar1 == 13)
if (gCurrentMissionNumber - 39 < 2 && MissionHeader->residentModels[index] == 13)
{
iVar2 = 10 - (MissionHeader->residentModels[0] + MissionHeader->residentModels[1] + MissionHeader->residentModels[2]);
iVar1 = iVar2;
@ -446,14 +447,13 @@ void LoadLevelSFX(int missionNum)
LoadBankFromLump(2, uVar1 + 69);
if (((((3 < missionNum - 1U) && (missionNum != 6)) && (missionNum != 7)) &&
(((missionNum != 9 && (missionNum != 10)) &&
((missionNum != 0xb && ((missionNum != 0xd && (missionNum != 0xe)))))))) &&
(((missionNum != 0x12 &&
((((missionNum != 0x13 && (missionNum != 0x14)) && (missionNum != 0x16)) &&
((missionNum != 0x1a && (missionNum != 0x1c)))))) &&
((((missionNum != 0x1f && ((missionNum != 0x21 && (missionNum != 0x22)))) &&
(missionNum != 0x26)) && (missionNum != 0x28))))))
if (missionNum - 1U > 3 && missionNum != 6 && missionNum != 7 &&
missionNum != 9 && missionNum != 10 && missionNum != 0xb &&
missionNum != 0xd && missionNum != 0xe && missionNum != 0x12 &&
missionNum != 0x13 && missionNum != 0x14 && missionNum != 0x16 &&
missionNum != 0x1a && missionNum != 0x1c && missionNum != 0x1f &&
missionNum != 0x21 && missionNum != 0x22 && missionNum != 0x26 &&
missionNum != 0x28)
{
if ((GameLevel & 2U) == 0)
{
@ -3085,93 +3085,66 @@ void Tunnels(__tunnelinfo *T)
// [D]
void AddTunnels(int level)
{
long z2;
long x1;
long z1;
long x2;
long local_18;
if (level == 0)
{
InitTunnels(29);
if (level == 1)
AddTunnel(-0x13178, 0, -0x1e848, -0xab18, -500, -0x26f0c);
AddTunnel(-65000, 0, -0x1df4c, -68000, -500, -0x1e848);
AddTunnel(-0xbdd8, 0, -0x39dc8, -0xc4ae, -500, -0x3997c);
AddTunnel(-0x35af7, 0, 0xa4cfb, -0x32f07, -2000, 0xa3507);
AddTunnel(-0x47ef4, 0, 0x4e1e5, -0x466fc, -500, 0x4d5f5);
AddTunnel(-0x44df9, 0, 0x4e8ee, -0x43611, -500, 0x4d0f6);
AddTunnel(-0x418f6, 0, 0x4e2f4, -0x4010a, -500, 0x4cb40);
AddTunnel(-0x47bfe, 0, 0x4b5f8, -0x46c0e, -500, 0x4a9f8);
AddTunnel(-0x43f02, 0, 0x4b5f8, -0x43afe, -500, 0x4aa00);
AddTunnel(-0x48cfe, 0, 0x49a00, -0x468fa, -500, 0x48e00);
AddTunnel(-0x47506, 0, 0x48e00, -0x468fa, -500, 0x481f8);
AddTunnel(-0x452fa, 0, 0x489f4, -0x446fa, -500, 0x47dfc);
AddTunnel(-0x452fe, 0, 0x47dfc, -0x42f06, -500, 0x47200);
AddTunnel(-0x46e8b, 0, 0x43eec, -0x44e7f, -500, 0x432f8);
AddTunnel(-0x44afa, 0, 0x439f0, -0x43ede, -500, 0x42e00);
AddTunnel(-0x466f6, 0, 0x41af8, -0x45afa, -500, 0x40f00);
AddTunnel(-0x46a83, 0, 0x3f6e6, -0x4668b, -500, 0x3eafa);
AddTunnel(-0x488fa, 0, 0x3dafa, -0x47112, -500, 0x3cef6);
AddTunnel(-0x456fe, 0, 0x3dafa, -0x43f0e, -500, 0x3cef6);
AddTunnel(-0x418fa, 0, 0x3dafa, -0x400fe, -500, 0x3cef6);
AddTunnel(-0x48e02, 0, 0x3acf9, -0x46e06, -500, 0x3a101);
AddTunnel(-0x410fa, 0, 0x3b5f5, -0x3f906, -500, 0x3aa05);
AddTunnel(-0x44cf6, 0, 0x390f7, -0x448fe, -500, 0x384ff);
AddTunnel(-0x448fe, 0, 0x384ff, -0x43102, -500, 0x37903);
AddTunnel(-0x45afe, 0, 0x329f9, -0x45706, -500, 0x31dfd);
AddTunnel(-0x47701, 0, 0x30df8, -0x42f05, -500, 0x2f604);
AddTunnel(-0x41501, 0, 0x305f8, -0x40905, -500, 0x2ee00);
AddTunnel(-0x418fe, 0, 0x2ee00, -0x40d05, -500, 0x2d608);
AddTunnel(-0x351f1, 0, -0x55f12, -0x30a1d, -500, -0x57702);
}
else if (level == 1)
{
InitTunnels(4);
AddTunnel(-0x6153a, 0, -0x274e8, -0x5314c, 2000, -0x19258);
AddTunnel(0x429a0, 0, 0xa0f0, 0x3e418, 2000, 0x29298);
AddTunnel(-0x749a0, 0, -0x1b83c, -0x60ec8, 0x1f40, -0x206c0);
z2 = -0xae38;
x1 = -0x2d613;
z1 = -0xa1ea;
x2 = -0x2bdc2;
local_18 = -1000;
AddTunnel(-0x2d613, 0, -0xa1ea, -0x2bdc2, -1000, -0xae38);
}
else
else if (level == 2)
{
if (level < 2)
{
if (level != 0)
return;
InitTunnels(29);
AddTunnel(-0x13178, 0, -0x1e848, -0xab18, -500, -0x26f0c);
AddTunnel(-65000, 0, -0x1df4c, -68000, -500, -0x1e848);
AddTunnel(-0xbdd8, 0, -0x39dc8, -0xc4ae, -500, -0x3997c);
AddTunnel(-0x35af7, 0, 0xa4cfb, -0x32f07, -2000, 0xa3507);
AddTunnel(-0x47ef4, 0, 0x4e1e5, -0x466fc, -500, 0x4d5f5);
AddTunnel(-0x44df9, 0, 0x4e8ee, -0x43611, -500, 0x4d0f6);
AddTunnel(-0x418f6, 0, 0x4e2f4, -0x4010a, -500, 0x4cb40);
AddTunnel(-0x47bfe, 0, 0x4b5f8, -0x46c0e, -500, 0x4a9f8);
AddTunnel(-0x43f02, 0, 0x4b5f8, -0x43afe, -500, 0x4aa00);
AddTunnel(-0x48cfe, 0, 0x49a00, -0x468fa, -500, 0x48e00);
AddTunnel(-0x47506, 0, 0x48e00, -0x468fa, -500, 0x481f8);
AddTunnel(-0x452fa, 0, 0x489f4, -0x446fa, -500, 0x47dfc);
AddTunnel(-0x452fe, 0, 0x47dfc, -0x42f06, -500, 0x47200);
AddTunnel(-0x46e8b, 0, 0x43eec, -0x44e7f, -500, 0x432f8);
AddTunnel(-0x44afa, 0, 0x439f0, -0x43ede, -500, 0x42e00);
AddTunnel(-0x466f6, 0, 0x41af8, -0x45afa, -500, 0x40f00);
AddTunnel(-0x46a83, 0, 0x3f6e6, -0x4668b, -500, 0x3eafa);
AddTunnel(-0x488fa, 0, 0x3dafa, -0x47112, -500, 0x3cef6);
AddTunnel(-0x456fe, 0, 0x3dafa, -0x43f0e, -500, 0x3cef6);
AddTunnel(-0x418fa, 0, 0x3dafa, -0x400fe, -500, 0x3cef6);
AddTunnel(-0x48e02, 0, 0x3acf9, -0x46e06, -500, 0x3a101);
AddTunnel(-0x410fa, 0, 0x3b5f5, -0x3f906, -500, 0x3aa05);
AddTunnel(-0x44cf6, 0, 0x390f7, -0x448fe, -500, 0x384ff);
AddTunnel(-0x448fe, 0, 0x384ff, -0x43102, -500, 0x37903);
AddTunnel(-0x45afe, 0, 0x329f9, -0x45706, -500, 0x31dfd);
AddTunnel(-0x47701, 0, 0x30df8, -0x42f05, -500, 0x2f604);
AddTunnel(-0x41501, 0, 0x305f8, -0x40905, -500, 0x2ee00);
AddTunnel(-0x418fe, 0, 0x2ee00, -0x40d05, -500, 0x2d608);
z2 = -0x57702;
x1 = -0x351f1;
z1 = -0x55f12;
x2 = -0x30a1d;
local_18 = -500;
}
else
{
if (level != 2)
{
if (level != 3)
return;
InitTunnels(5);
AddTunnel(0x24f68, 0, -0x3d374, 0x25cb0, -400, -0x398e6);
AddTunnel(-0x1c19c, 0, -0x2f2b0, -0x1ba94, -400, -0x20594);
AddTunnel(-0x118dc, 0, -0x3f7a, -0x11fb2, -400, -0x6f54);
AddTunnel(0x131dc, 0, -0x28fdc, 0x14212, -500, -0x297de);
AddTunnel(0x2a5ee, 0, 0x3c668, 0x2b624, -500, 0x3be34);
return;
}
InitTunnels(2);
AddTunnel(0x2678a, 0, 0xb4b9a, 0x2918a, -2000, 0xb139b);
z2 = 0xb06da;
x1 = 0x28550;
z1 = 0xb139b;
x2 = 0x2918a;
local_18 = -2000;
}
InitTunnels(2);
AddTunnel(0x2678a, 0, 0xb4b9a, 0x2918a, -2000, 0xb139b);
AddTunnel(0x28550, 0, 0xb139b, 0x2918a, -2000, 0xb06da);
}
else if (level == 3)
{
InitTunnels(5);
AddTunnel(0x24f68, 0, -0x3d374, 0x25cb0, -400, -0x398e6);
AddTunnel(-0x1c19c, 0, -0x2f2b0, -0x1ba94, -400, -0x20594);
AddTunnel(-0x118dc, 0, -0x3f7a, -0x11fb2, -400, -0x6f54);
AddTunnel(0x131dc, 0, -0x28fdc, 0x14212, -500, -0x297de);
AddTunnel(0x2a5ee, 0, 0x3c668, 0x2b624, -500, 0x3be34);
}
AddTunnel(x1, 0, z1, x2, local_18, z2);
}

View File

@ -137,7 +137,7 @@ int gLoadedReplay = 0;
int gHaveStoredData = 0;
int gLastChase = 0;
int gChaseNumber = 0;
int gChaseNumber = -1;
int gRandomChase = 0;
int gSubGameNumber = 0;
@ -594,6 +594,13 @@ void RunMissionLadder(int newgame)
// [D]
void GetRandomChase(void)
{
// [A] debug
if (gChaseNumber != -1)
{
gRandomChase = gChaseNumber;
return;
}
int bump = 0;
if (gLoadedReplay == 0)

View File

@ -3,7 +3,6 @@
#include "COSMETIC.H"
#include "MISSION.H"
#include "DR2ROADS.H"
#include "TEXTURE.H"
#include "CARS.H"
#include "MAIN.H"
#include "WHEELFORCES.H"
@ -11,7 +10,6 @@
#include "DENTING.H"
#include "CAMERA.H"
#include "FELONY.H"
#include "MISSION.H"
#include "DEBRIS.H"
#include "PAD.H"
#include "COP_AI.H"
@ -24,12 +22,10 @@
#include "GLAUNCH.H"
#include "SHADOW.H"
#include "PLAYERS.H"
#include "DR2ROADS.H"
#include "INLINE_C.H"
#include "STRINGS.H"
#include <stdlib.h>
#include "RAND.H"
// decompiled code
// original method signature:
@ -292,18 +288,18 @@ void UpdateCarPoints(CAR_COSMETICS *carCos)
// [D] [T]
void FixCarCos(CAR_COSMETICS *carCos, int externalModelNumber)
{
{
delta.vx = 0;
delta.vy = 0;
delta.vz = -(carCos->wheelDisp[0].vz + carCos->wheelDisp[1].vz - 14) / 2;
doWheels = 1;
UpdateCarPoints(carCos);
if (ActiveCheats.cheat10) // [A] cheat for secret car - Fireboyd78
{
if ((carCos == &car_cosmetics[4]) && (externalModelNumber == 12))
if (carCos == &car_cosmetics[4] && externalModelNumber == 12)
{
carCos->powerRatio += (carCos->powerRatio / 2);
carCos->mass *= 3;
@ -313,6 +309,76 @@ void FixCarCos(CAR_COSMETICS *carCos, int externalModelNumber)
}
}
// Super mini cars
if (ActiveCheats.cheat13)
{
int i;
carCos->wheelSize >>= 1;
carCos->headLight.vx >>= 1;
carCos->headLight.vy >>= 1;
carCos->headLight.vz >>= 1;
carCos->colBox.vx >>= 1;
carCos->colBox.vy >>= 1;
carCos->colBox.vz >>= 1;
carCos->cog.vx >>= 1;
carCos->cog.vy >>= 1;
carCos->cog.vz >>= 1;
carCos->brakeLight.vx >>= 1;
carCos->brakeLight.vy >>= 1;
carCos->brakeLight.vz >>= 1;
carCos->revLight.vx >>= 1;
carCos->revLight.vy >>= 1;
carCos->revLight.vz >>= 1;
carCos->backInd.vx >>= 1;
carCos->backInd.vy >>= 1;
carCos->backInd.vz >>= 1;
carCos->frontInd.vx >>= 1;
carCos->frontInd.vy >>= 1;
carCos->frontInd.vz >>= 1;
carCos->policeLight.vx >>= 1;
carCos->policeLight.vy >>= 1;
carCos->policeLight.vz >>= 1;
carCos->exhaust.vx >>= 1;
carCos->exhaust.vy >>= 1;
carCos->exhaust.vz >>= 1;
carCos->smoke.vx >>= 1;
carCos->smoke.vy >>= 1;
carCos->smoke.vz >>= 1;
carCos->fire.vx >>= 1;
carCos->fire.vy >>= 1;
carCos->fire.vz >>= 1;
carCos->twistRateX <<= 1;
carCos->twistRateY <<= 1;
carCos->twistRateZ <<= 1;
for (i = 0; i < 4; i++)
{
carCos->wheelDisp[i].vx >>= 1;
carCos->wheelDisp[i].vy >>= 1;
carCos->wheelDisp[i].vz >>= 1;
carCos->wheelDisp[i].vy -= 10;
}
for (i = 0; i < 12; i++)
{
carCos->cPoints[i].vx >>= 1;
carCos->cPoints[i].vy >>= 1;
carCos->cPoints[i].vz >>= 1;
}
}
// Caine's compound heavy Vans
if (carCos == &car_cosmetics[2] && gCurrentMissionNumber == 7)
{
@ -637,7 +703,6 @@ void GlobalTimeStep(void)
RigidBodyState* tp;
RigidBodyState* d0;
RigidBodyState* d1;
int iVar28;
long AV[4];
long delta_orientation[4];
long normal[4];
@ -646,7 +711,6 @@ void GlobalTimeStep(void)
long lever1[4];
long torque[4];
long pointVel0[4];
long pointVel1[4];
VECTOR velocity;
int depth;
int RKstep;
@ -770,6 +834,7 @@ void GlobalTimeStep(void)
CheckScenaryCollisions(cp);
}
// check collisions with vehicles
if (cp->hd.mayBeColliding != 0)
{
@ -829,6 +894,9 @@ void GlobalTimeStep(void)
bb1->z0 < bb2->z1 && bb2->y0 < bb1->y1 && bb1->y0 < bb2->y1 &&
CarCarCollision3(cp, c1, &depth, (VECTOR*)collisionpoint, (VECTOR*)normal))
{
int c1InfiniteMass;
int c2InfiniteMass;
collisionpoint[1] -= 0;
lever0[0] = collisionpoint[0] - cp->hd.where.t[0];
@ -936,17 +1004,25 @@ void GlobalTimeStep(void)
if (m2 < m1)
{
do1 = (m2 << 0xc) / m1;
do2 = 0x1000;
do1 = (m2 * 4096) / m1;
do2 = 4096;
}
else
{
do2 = (m1 << 0xc) / m2;
do1 = 0x1000;
do2 = (m1 * 4096) / m2;
do1 = 4096;
}
c1InfiniteMass = cp->controlType == CONTROL_TYPE_CUTSCENE || m1 == 0x7fff;
c2InfiniteMass = c1->controlType == CONTROL_TYPE_CUTSCENE || m2 == 0x7fff;
// [A] if any checked cars has infinite mass, reduce bouncing
// TODO: very easy difficulty
if (c1InfiniteMass ||c2InfiniteMass)
strikeVel = strikeVel * 10 >> 2;
// apply force to car 0
if (cp->controlType != CONTROL_TYPE_CUTSCENE && m1 != 0x7fff)
if (!c1InfiniteMass)
{
int twistY, strength1;
@ -985,7 +1061,7 @@ void GlobalTimeStep(void)
}
// apply force to car 1
if (c1->controlType != CONTROL_TYPE_CUTSCENE && m2 != 0x7fff)
if (!c2InfiniteMass)
{
int twistY, strength2;
@ -1854,12 +1930,6 @@ void CheckCarToCarCollisions(void)
// [D] [T]
void ProcessCarPad(_CAR_DATA *cp, ulong pad, char PadSteer, char use_analogue)
{
char cVar1;
short sVar2;
int iVar3;
int iVar4;
int iVar7;
int player_id;
int int_steer;
int analog_angle;

View File

@ -69,7 +69,7 @@
#include "PAUSE.H"
#include <stdlib.h>
#include "RAND.H"
#include "STRINGS.H"
#include <PLATFORM.H>
@ -303,39 +303,36 @@ void ProcessLumps(char *lump_ptr, int lump_size)
}
else if (lump_type == LUMP_JUNCTIONS2_NEW)
{
int cnt;
printf("LUMP_JUNCTIONS2_NEW: size: %d\n", size);
ProcessJunctionsDriver2Lump((char *)ptr, size, 0);
lump_type = NumTempJunctions;
pDVar8 = Driver2JunctionsPtr;
puVar9 = Driver2TempJunctionsPtr;
if (0 < NumTempJunctions)
// put junction flags if any
cnt = 0;
while (cnt < NumTempJunctions)
{
do {
lump_type = lump_type + -1;
pDVar8->flags = *puVar9;
pDVar8 = pDVar8 + 1;
puVar9 = puVar9 + 1;
} while (lump_type != 0);
Driver2JunctionsPtr[cnt].flags = Driver2TempJunctionsPtr[cnt];
cnt++;
}
gDemoLevel = false; // [A]
}
else if (lump_type == LUMP_JUNCTIONS2)
{
int cnt;
printf("LUMP_JUNCTIONS2: size: %d\n", size);
ProcessJunctionsDriver2Lump((char *)ptr, size, 1);
lump_type = NumTempJunctions;
pDVar8 = Driver2JunctionsPtr;
puVar9 = Driver2TempJunctionsPtr;
// put junction flags if any
cnt = 0;
if (0 < NumTempJunctions) {
do {
lump_type = lump_type + -1;
pDVar8->flags = *puVar9;
pDVar8 = pDVar8 + 1;
puVar9 = puVar9 + 1;
} while (lump_type != 0);
while (cnt < NumTempJunctions)
{
Driver2JunctionsPtr[cnt].flags = Driver2TempJunctionsPtr[cnt];
cnt++;
}
gDemoLevel = true; // [A]
@ -2400,13 +2397,16 @@ void SsSetSerialVol(short s_num, short voll, short volr)
void PrintCommandLineArguments()
{
const char* argumentsMessage =
"Example: REDRIVER2 <command> [arguments]\n\n"\
" -players <count> : Set player count (1 or 2)\n"\
" -playercar <number>, -player2car <number> : set player wanted car\n"\
" -mission <number> : starts specified mission\n"\
" -replay <filename> : starts replay from file\n"\
" -recordcutscene <mission_number> <subindex> <base_mission> : starts cutscene recorder session\n"\
" -nointro : disable intro screens\n"\
"Example: REDRIVER2 <command> [arguments]\n\n"
" -players <count> : Set player count (1 or 2)\n"
" -playercar <number>, -player2car <number> : set player wanted car\n"
" -mission <number> : starts specified mission\n"
" -chase <number> : using specified chase number for mission\n"
" -replay <filename> : starts replay from file\n"
#ifdef CUTSCENE_RECORDER
" -recordcutscene <mission_number> <subindex> <base_mission> : starts cutscene recorder session\n"
#endif
" -nointro : disable intro screens\n"
" -nofmv : disable all FMVs\n";
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "REDRIVER 2 command line arguments", argumentsMessage, NULL);
@ -2500,7 +2500,10 @@ int redriver2_main(int argc, char** argv)
LoadCurrentProfile();
#ifndef PSX
#ifndef PSX
int commandLinePropsShown;
commandLinePropsShown = 0;
for (int i = 1; i < argc; i++)
{
if (!_stricmp(argv[i], "-playercar"))
@ -2533,6 +2536,17 @@ int redriver2_main(int argc, char** argv)
i++;
NumPlayers = atoi(argv[i + 1]);
}
else if (!_stricmp(argv[i], "-chase"))
{
if (argc - i < 2)
{
printError("-chase missing number argument!");
return -1;
}
gChaseNumber = atoi(argv[i + 1]);
i++;
}
else if (!_stricmp(argv[i], "-mission"))
{
if (argc - i < 2)
@ -2645,7 +2659,9 @@ int redriver2_main(int argc, char** argv)
#endif
else
{
PrintCommandLineArguments();
if(!commandLinePropsShown)
PrintCommandLineArguments();
commandLinePropsShown = 1;
}
}
#endif // PSX

View File

@ -834,36 +834,35 @@ void DoMissionSound(void)
bodgevar += 4;
}
else if (bodgevar == 5)
else if (bodgevar >= 4)
{
x = (int)(((long long)Mission.timer[0].count * 0x57619f1) >> 0x20);
if ((Mission.timer[0].count / 3000) * 3000 != Mission.timer[0].count + 100)
return;
if (Mission.timer[0].count / 3000 * 3000 == Mission.timer[0].count + 100)
{
cVar1 = GetMissionSound(29);
Start3DSoundVolPitch(-1, 5, cVar1, -0x382c, -0x114, 0xcd383, -0x5dc, 0x1000 - ((x >> 4) - (Mission.timer[0].count >> 0x1f)));
}
cVar1 = GetMissionSound(29);
Start3DSoundVolPitch(-1, 5, cVar1, -0x382c, -0x114, 0xcd383, -0x5dc, 0x1000 - ((x >> 4) - (Mission.timer[0].count >> 0x1f)));
}
else if (bodgevar < 8) // [A] capture 6 and 7
{
if (bodgevar == 7)
if (bodgevar >= 5)
{
if ((Mission.timer[0].count / 3000) * 3000 == Mission.timer[0].count + -0x514)
{
cVar1 = GetMissionSound(20);
Start3DSoundVolPitch(-1, 5, cVar1, -0x2ffb, -0x113, 0xcd61b, -0x5dc, 0x1000 - Mission.timer[0].count / 0x2ee);
}
}
// bodgevar 6 & 7 (is this a bug?)
if (bodgevar >= 6)
{
if ((Mission.timer[0].count / 3000) * 3000 == Mission.timer[0].count + -800)
{
cVar1 = GetMissionSound(20);
Start3DSoundVolPitch(-1, 5, cVar1, -0x34aa, -0xfa, 0xcd5e0, -0x5dc, 0x1000 - Mission.timer[0].count / 0x2ee);
}
}
}
break;
case 32:
if (holdall == -1)
@ -914,7 +913,7 @@ void DoMissionSound(void)
bodgevar += 4;
}
else if (bodgevar == 5)
else if (bodgevar >= 5)
{
x = (int)(((long long)Mission.timer[0].count * 0x57619f1) >> 0x20);
@ -922,10 +921,17 @@ void DoMissionSound(void)
cVar1 = GetMissionSound(20);
Start3DSoundVolPitch(-1, 5, cVar1, 0x31330, -0xb1, 0x5e0e0, -0x5dc, 0x1000 - ((x >> 4) - (Mission.timer[0].count >> 0x1f)));
}
}
else if (bodgevar < 8) // [A] capture 6 and 7
{
if (bodgevar == 7)
if (bodgevar >= 6)
{
if ((Mission.timer[0].count / 3000) * 3000 == Mission.timer[0].count + -800)
{
cVar1 = GetMissionSound(20);
Start3DSoundVolPitch(-1, 5, cVar1, 0x312b0, -0xb1, 0x5f050, -0x5dc, 0x1000 - Mission.timer[0].count / 0x2ee);
}
}
if (bodgevar >= 7)
{
if ((Mission.timer[0].count / 3000) * 3000 == Mission.timer[0].count + -0x514)
{
@ -933,13 +939,6 @@ void DoMissionSound(void)
Start3DSoundVolPitch(-1, 5, cVar1, 0x30ad0, -0xb1, 0x5f050, -0x5dc, 0x1000 - Mission.timer[0].count / 0x2ee);
}
}
// bodgevar 6 & 7 (is this a bug?)
if ((Mission.timer[0].count / 3000) * 3000 == Mission.timer[0].count + -800)
{
cVar1 = GetMissionSound(20);
Start3DSoundVolPitch(-1, 5, cVar1, 0x312b0, -0xb1, 0x5f050, -0x5dc, 0x1000 - Mission.timer[0].count / 0x2ee);
}
}
break;
case 39:

File diff suppressed because it is too large Load Diff

View File

@ -1402,15 +1402,16 @@ void DoScenaryCollisions(void)
{
_CAR_DATA *cp;
cp = car_data + 19;
cp = car_data + MAX_CARS - 1;
do {
if (cp->controlType != CONTROL_TYPE_NONE)
{
// civ AI and dead cop cars perform less collision detection frames
if (cp->controlType == CONTROL_TYPE_CIV_AI || cp->controlType == CONTROL_TYPE_PURSUER_AI && cp->ai.p.dying > 85)
if (cp->controlType == CONTROL_TYPE_CIV_AI ||
cp->controlType == CONTROL_TYPE_PURSUER_AI && cp->ai.p.dying > 85)
{
if (cp->totalDamage != 0 && (10 < cp->hd.speed || (cp->id + CameraCnt & 3) == 0))
if (cp->totalDamage != 0 && (cp->hd.speed > 10 || (cp->id + CameraCnt & 3) == 0))
{
CheckScenaryCollisions(cp);
}

View File

@ -1165,7 +1165,7 @@ LAB_00016fac:
direction.vy = player[0].dir & 0xfff;
RotMatrixXYZ(&map_matrix, &direction);
MulMatrix0(&aspect, &map_matrix, &map_matrix);
MulMatrix0(&identity, &map_matrix, &map_matrix);
gte_SetRotMatrix(&map_matrix);
gte_SetTransVector(&translate);
@ -3196,7 +3196,7 @@ void SetFullscreenMapMatrix(void)
direction.vz = 0;
RotMatrixXYZ(&map_matrix, &direction); // Why, Reflections? Why? You could have used RotMatrixY
MulMatrix0(&aspect, &map_matrix, &map_matrix);
MulMatrix0(&identity, &map_matrix, &map_matrix);
gte_SetRotMatrix(&map_matrix);
gte_SetTransVector(&translate);

View File

@ -113,6 +113,11 @@ void ToggleSecretCarFun(int direction)
FixCarCos(&car_cosmetics[4], 12);
}
void ToggleMiniCars(int direction)
{
ActiveCheats.cheat13 ^= 1;
}
void ToggleJerichoMode(int direction)
{
ActiveCheats.cheat12 ^= 1;
@ -183,6 +188,7 @@ MENU_HEADER DebugTimeOfDayHeader =
MENU_ITEM DebugJustForFunItems[] =
{
{ "Secret Car Fun", 3, 2, ToggleSecretCarFun, MENU_QUIT_RESTART, NULL },
{ "Mini cars", 3, 2, ToggleMiniCars, MENU_QUIT_NONE, NULL },
{ "Jericho Mode", 3, 2, ToggleJerichoMode, MENU_QUIT_NONE, NULL },
{ NULL, 128u, 0u, NULL, MENU_QUIT_NONE, NULL }
};
@ -190,8 +196,16 @@ MENU_ITEM DebugJustForFunItems[] =
MENU_HEADER DebugJustForFunHeader =
{ "Just for fun", { 0, 0, 0, 0 }, 0u, DebugJustForFunItems };
#ifdef CUTSCENE_RECORDER
extern void NextCutsceneRecorderPlayer(int dir);
extern char gCutsceneRecorderPauseText[64];
#endif
MENU_ITEM DebugOptionsItems[] =
{
#if 0 // TODO: enable
{ gCutsceneRecorderPauseText, 5u, 2u, (pauseFunc)&NextCutsceneRecorderPlayer, MENU_QUIT_NONE, NULL },
#endif
{ "Back on Wheels", 3, 2, SetRightWayUp, MENU_QUIT_NONE, NULL},
{ "Time of Day", 65, 2, NULL, MENU_QUIT_NONE, &DebugTimeOfDayHeader },
{ "Fun cheats", 65, 2, NULL, MENU_QUIT_NONE, &DebugJustForFunHeader },
@ -228,18 +242,10 @@ MENU_HEADER YesNoRestartHeader =
MENU_HEADER YesNoQuitHeader =
{ "Are You Sure?", { 0, 0, 0, 0 }, 0u, YesNoQuitItems };
#ifdef CUTSCENE_RECORDER
extern void NextCutsceneRecorderPlayer(int dir);
extern char gCutsceneRecorderPauseText[64];
#endif
MENU_ITEM MainPauseItems[] =
{
{ "Continue", 1u, 2u, NULL, MENU_QUIT_CONTINUE, NULL },
{ "Show Map", 3u, 2u, (pauseFunc)&PauseMap, MENU_QUIT_NONE, NULL },
#ifdef CUTSCENE_RECORDER
{ gCutsceneRecorderPauseText, 5u, 2u, (pauseFunc)&NextCutsceneRecorderPlayer, MENU_QUIT_NONE, NULL },
#endif
{ "Restart", 65u, 2u, NULL, MENU_QUIT_NONE, &YesNoRestartHeader },
{ "Sfx Volume", 13u, 2u, (pauseFunc)&SfxVolume, MENU_QUIT_NONE, NULL },
{ "Music Volume", 21u, 2u, (pauseFunc)&MusicVolume, MENU_QUIT_NONE, NULL },
@ -310,9 +316,6 @@ MENU_ITEM MissionFailedItems[6] =
MENU_ITEM TakeARideFinishedItems[] =
{
#ifdef CUTSCENE_RECORDER
{ gCutsceneRecorderPauseText, 5u, 2u, (pauseFunc)&NextCutsceneRecorderPlayer, MENU_QUIT_NONE, NULL },
#endif
{ "Restart", 65u, 2u, NULL, MENU_QUIT_NONE, &YesNoRestartHeader },
{ "Film Director",1u,2u,NULL,MENU_QUIT_DIRECTOR,NULL},
{ "Quick Replay",1u,2u,NULL,MENU_QUIT_QUICKREPLAY,NULL},
@ -680,7 +683,7 @@ void SaveReplay(int direction)
FILE* fp = fopen("chase.d2rp", "wb");
if (fp)
{
fwrite(_other_buffer, size, 1, fp);
fwrite(_other_buffer, 1, size, fp);
fclose(fp);
}
#endif

View File

@ -3669,35 +3669,45 @@ int TannerCarCollisionCheck(VECTOR *pPos, int dir, int bQuick)
long pointVel[4];
long reaction[4];
long lever[4];
SVECTOR boxDisp;
CAR_COSMETICS* car_cos;
static struct CRET2D collisionResult; // offset 0x30
CRET2D collisionResult; // offset 0x30
CDATA2D cd[2];
cd[0].length[0] = 0x3c;
cd[0].length[1] = 0x3c;
cd[0].x.vx = pPos->vx;
cd[0].x.vz = pPos->vz;
cp1 = car_data + 0x13;
cd[0].theta = dir;
do {
uVar2 = cp1->ap.model;
cp1 = car_data + MAX_CARS - 1;
cd[1].x.vx = cp1->hd.where.t[0];
cd[1].length[0] = car_cosmetics[uVar2].colBox.vz;
cd[1].length[1] = car_cosmetics[uVar2].colBox.vx;
do {
car_cos = &car_cosmetics[cp1->ap.model];
cd[1].length[0] = car_cos->colBox.vz;
cd[1].length[1] = car_cos->colBox.vx;
cd[1].theta = cp1->hd.direction;
cd[1].x.vz = cp1->hd.where.t[2];
// [A] fix bug with offset box collision
gte_SetRotMatrix(&cp1->hd.where);
gte_SetTransMatrix(&cp1->hd.where);
boxDisp.vx = -car_cos->cog.vx;
boxDisp.vy = -car_cos->cog.vy;
boxDisp.vz = -car_cos->cog.vz;
gte_ldv0(&boxDisp);
gte_rtv0tr();
gte_stlvnl(&cd[1].x);
if (cp1->controlType != CONTROL_TYPE_NONE)
{
iVar3 = cp1->hd.where.t[1] + pPos->vy;
if (iVar3 < 0) {
iVar3 = -iVar3;
}
if (iVar3 < 500 && bcollided2d(cd, 1) != 0)
if (ABS(cp1->hd.where.t[1] + pPos->vy) < 500 &&
bcollided2d(cd, 1))
{
if (bQuick != 0)
return 1;
@ -3706,14 +3716,17 @@ int TannerCarCollisionCheck(VECTOR *pPos, int dir, int bQuick)
return 1;
bFindCollisionPoint(cd, &collisionResult);
iVar3 = -collisionResult.surfNormal.vz;
iVar1 = -collisionResult.surfNormal.vx;
iVar10 = pcdTanner->hd.where.t[2] + FIXEDH(collisionResult.penetration * iVar3);
iVar12 = collisionResult.hit.vz - iVar10;
collisionResult.hit.vy = pcdTanner->hd.where.t[1] + 0x3c;
iVar9 = collisionResult.hit.vy - pcdTanner->hd.where.t[1];
iVar8 = pcdTanner->hd.where.t[0] + FIXEDH(collisionResult.penetration * iVar1);
iVar11 = collisionResult.hit.vx - iVar8;
collisionResult.surfNormal.vy = 0;
iVar7 = FIXEDH(pcdTanner->st.n.angularVelocity[1] * iVar12 - pcdTanner->st.n.angularVelocity[2] * iVar9) + pcdTanner->st.n.linearVelocity[0];

View File

@ -156,7 +156,6 @@ void InitPadRecording(void)
// Start line: 1348
/* end block 3 */
// End Line: 1349
// [D]
int SaveReplayToBuffer(char *buffer)
{
@ -205,7 +204,7 @@ int SaveReplayToBuffer(char *buffer)
// copy source type
memcpy(&sheader->SourceType, &srcStream->SourceType, sizeof(STREAM_SOURCE));
sheader->Size = srcStream->PadRecordBufferEnd - srcStream->InitialPadRecordBuffer;
sheader->Size = srcStream->padCount; // srcStream->PadRecordBufferEnd - srcStream->InitialPadRecordBuffer;
sheader->Length = srcStream->length;
int size = (sheader->Size + sizeof(PADRECORD)) & -4;
@ -245,7 +244,11 @@ int SaveReplayToBuffer(char *buffer)
memcpy(pt, &MissionStartData, sizeof(MISSION_DATA));
}
#ifdef PSX
return 0x3644; // size?
#else
return pt - buffer;
#endif
}
@ -339,6 +342,8 @@ int LoadCutsceneAsReplay(int subindex)
offset = header.data[subindex].offset * 4;
size = header.data[subindex].size;
printWarning("cutscene size: %d\n", size);
LoadfileSeg(filename, _other_buffer, offset, size);
int result = LoadReplayFromBuffer(_other_buffer);
@ -397,27 +402,41 @@ int LoadReplayFromBuffer(char *buffer)
pt += sizeof(REPLAY_STREAM_HEADER);
REPLAY_STREAM* destStream = &ReplayStreams[i];
// copy source type
memcpy(&destStream->SourceType, &sheader->SourceType, sizeof(STREAM_SOURCE));
int size = (sheader->Size + sizeof(PADRECORD)) & -4;
// init buffers
destStream->InitialPadRecordBuffer = (PADRECORD*)replayptr;
destStream->PadRecordBuffer = (PADRECORD*)replayptr;
destStream->PadRecordBufferEnd = (PADRECORD *)(replayptr + sheader->Size);
#ifdef CUTSCENE_RECORDER
if (gCutsceneAsReplay)
{
AllocateReplayStream(destStream, 4000);
// copy pad data and advance buffer
memcpy(destStream->PadRecordBuffer, pt, size);
}
else
#endif
{
destStream->InitialPadRecordBuffer = (PADRECORD*)replayptr;
destStream->PadRecordBuffer = (PADRECORD*)replayptr;
destStream->PadRecordBufferEnd = (PADRECORD*)(replayptr + sheader->Size);
destStream->playbackrun = 0;
destStream->padCount = sheader->Size;
// copy pad data and advance buffer
memcpy(replayptr, pt, size);
replayptr += size;
}
pt += size;
destStream->length = sheader->Length;
destStream->playbackrun = 0;
if (sheader->Length > maxLength)
maxLength = sheader->Length;
int size = (sheader->Size + sizeof(PADRECORD)) & -4;
// copy pad data and advance buffer
memcpy(replayptr, pt, size);
replayptr += size;
pt += size;
}
ReplayParameterPtr = (REPLAY_PARAMETER_BLOCK *)replayptr;
@ -828,6 +847,9 @@ void AllocateReplayStream(REPLAY_STREAM *stream, int maxpad)
stream->playbackrun = 0;
stream->length = 0;
if(CurrentGameMode != GAMEMODE_DIRECTOR && CurrentGameMode != GAMEMODE_REPLAY)
stream->padCount = 0;
stream->InitialPadRecordBuffer = (PADRECORD*)replayptr;
stream->PadRecordBuffer = (PADRECORD*)replayptr;
@ -972,7 +994,8 @@ int Put(int stream, ulong *pt0)
padbuf->run = 0;
rstream->PadRecordBuffer = padbuf;
rstream->padCount++;
return 1;
}

View File

@ -15,8 +15,8 @@
#include "XAPLAY.H"
#include "PLAYERS.H"
#include <string.h>
#include <stdlib.h>
#include "RAND.H"
#include "STRINGS.H"
long dummylong[4] = { 0, 0, 0, 0 };

View File

@ -1407,80 +1407,62 @@ void LoadInAreaTSets(int area)
loadaddr = model_spool_buffer + 0xA000;
navailable = 0;
if (slotsused < 19)
slot = slotsused;
while (slot < 19)
{
slot = slotsused;
offset = 0;
do {
offset = 0;
if (tpageslots[slot] == 0xff) // [A]
{
availableslots[navailable++] = slot;
}
else
{
i = 0;
while (tpageslots[slot] != tpages[i]) // [A]
{
if (ntpages_to_load <= i)
break;
if (tpageslots[slot] == 0xff) // [A]
i++;
};
if (i == ntpages_to_load)
{
availableslots[navailable++] = slot;
}
else
{
i = 0;
while (tpageslots[slot] != tpages[i]) // [A]
{
if (ntpages_to_load <= i)
break;
}
i++;
};
if (i == ntpages_to_load)
{
availableslots[navailable++] = slot;
}
}
slot++;
} while (slot < 19);
slot++;
}
offset = AreaData[area].gfx_offset;
if (!ntpages_to_load)
return;
i = 0;
if (ntpages_to_load != 0)
while (--navailable >= 0)
{
if (tpageloaded[*tpages] != 0) // weird goto lol
tsetinfo[tsetcounter * 2 + 1] = availableslots[navailable];
while (i < ntpages_to_load)
{
goto LAB_0007bc94;
}
RequestSpool(1, 0, offset, 17, loadaddr, SendTPage);
offset += 17;
if (navailable-- > 0)
{
while (true)
{
tsetinfo[tsetcounter*2 + 1] = availableslots[navailable];
i++;
tsetinfo[tsetcounter * 2] = *tpages;
while (true)
{
RequestSpool(1, 0, offset, 17, loadaddr, SendTPage);
offset += 17;
tsetcounter++;
tpages++;
i++;
tsetinfo[tsetcounter * 2] = *tpages;
if (tpageloaded[*tpages] == 0)
break;
tsetcounter++;
tpages++;
if (ntpages_to_load <= i)
return;
if (tpageloaded[*tpages] == 0)
break;
LAB_0007bc94:
tsetinfo[tsetcounter * 2 + 1] = tpageloaded[*tpages] - 1;
}
if (navailable < 1)
break;
navailable--;
}
tsetinfo[tsetcounter * 2 + 1] = tpageloaded[*tpages] - 1;
}
}
}

View File

@ -34,11 +34,19 @@ extern void sys_freeall();
#define MALLOC_BEGIN() \
{ \
char* _oldmalloc = mallocptr;
const char* _oldmalloc = mallocptr;
#ifdef __GNUC__
#define MALLOC_END() \
if(mallocptr > _oldmalloc) printWarning("malloc(%d) in %s, line %d. Malloc usage: %d\n", mallocptr-_oldmalloc, __FUNCTION__, __LINE__, (mallocptr-mallocptr_start));\
}
if(mallocptr > _oldmalloc)\
printWarning("malloc(%d) in %s, line %d. Malloc usage: %d\n", mallocptr-_oldmalloc, __FUNCTION__, __LINE__, (mallocptr-mallocptr_start));\
} // MALLOC_BEGIN block
#else
#define MALLOC_END() \
if(mallocptr > _oldmalloc)\
printWarning("malloc(%d) in " __FUNCTION__ ", line %d. Malloc usage: %d\n", mallocptr-_oldmalloc, __LINE__, (mallocptr-mallocptr_start));\
} // MALLOC_BEGIN block
#endif
extern int leadAIRequired;
extern int leadAILoaded;

View File

@ -236,7 +236,7 @@ void DrawTargetArrowModel(TARGET_ARROW_MODEL *pTargetArrowModel, VECTOR *pPositi
pSVar10 = pTargetArrowModel->pVerts;
WorldToCameraPositions(pPosition, cameraPos, 1);
gte_SetRotMatrix(&aspect);
gte_SetRotMatrix(&identity);
gte_SetTransVector(&tempVec);
pVVar7 = &tempVec;
@ -376,7 +376,7 @@ void DrawStopZone(VECTOR *pPosition)
pPoly = (POLY_FT4*)current->primptr;
pOut = (long*)&pPoly->x0;
gte_SetRotMatrix(&aspect);
gte_SetRotMatrix(&identity);
gte_SetTransVector(&dummy);
setPolyFT4(pPoly);

View File

@ -100,12 +100,13 @@ short specialSlot;
/* end block 3 */
// End Line: 1165
// [D]
// [D] [T]
void IncrementClutNum(RECT16 *clut)
{
clut->x += 16;
if (clut->x == 1024) {
if (clut->x == 1024)
{
clut->x = 960;
clut->y += 1;
}
@ -144,7 +145,8 @@ void IncrementTPageNum(RECT16 *tpage)
while (++i)
{
// proper tpage position?
if ((tpage->x == tpagepos[i - 1].x) && (tpage->y == tpagepos[i - 1].y))
if ((tpage->x == tpagepos[i - 1].x) &&
(tpage->y == tpagepos[i - 1].y))
{
if (tpagepos[i].x == -1)
{
@ -193,7 +195,7 @@ void IncrementTPageNum(RECT16 *tpage)
// [D] [T]
// Originally ASM function
char * unpackTexture(char *dest, char *src)
char* unpackTexture(char *dest, char *src)
{
char *ptr = dest + 0x7fff;
@ -217,13 +219,17 @@ char * unpackTexture(char *dest, char *src)
return src;
}
// [D] [A]
// [D] [T]
int LoadTPageAndCluts(RECT16 *tpage, RECT16 *cluts, int tpage2send, char *tpageaddress)
{
int npalettes = *(int *)tpageaddress;
int npalettes;
int i;
RECT16 temptpage;
npalettes = *(int *)tpageaddress;
tpageaddress += 4;
for (int i = 0; i < npalettes; i++)
for (i = 0; i < npalettes; i++)
{
LoadImage(cluts, (u_long *)tpageaddress);
tpageaddress += 32;
@ -232,8 +238,6 @@ int LoadTPageAndCluts(RECT16 *tpage, RECT16 *cluts, int tpage2send, char *tpagea
IncrementClutNum(cluts);
}
RECT16 temptpage;
temptpage.x = tpage->x;
temptpage.y = tpage->y;
temptpage.w = tpage->w;
@ -330,23 +334,26 @@ int LoadTPageAndCluts(RECT16 *tpage, RECT16 *cluts, int tpage2send, char *tpagea
/* end block 3 */
// End Line: 396
// UNUSED
int Find_TexID(MODEL *model, int t_id)
{
char *polylist = (char *)model->poly_block;
char *polylist;
polylist = (char *)model->poly_block;
for (int i = 0; i < model->num_polys; i++)
{
switch (*polylist & 0x1F) {
case 4:
case 5:
case 6:
case 7:
case 20:
case 21:
case 22:
case 23:
if (polylist[2] == t_id)
return 1;
switch (*polylist & 0x1F)
{
case 4:
case 5:
case 6:
case 7:
case 20:
case 21:
case 22:
case 23:
if (polylist[2] == t_id)
return 1;
}
polylist += PolySizes[*polylist];
@ -390,16 +397,18 @@ int Find_TexID(MODEL *model, int t_id)
// End Line: 1491
// [D] [T]
TEXINF * GetTEXINFName(char *name, int *tpagenum, int *texturenum)
TEXINF* GetTEXINFName(char *name, int *tpagenum, int *texturenum)
{
char *nametable = texturename_buffer;
char *nametable;
int i, j;
nametable = texturename_buffer;
for (int i = 0; i < tpage_amount; i++)
for (i = 0; i < tpage_amount; i++)
{
int texamt = tpage_texamts[i];
TEXINF *texinf = tpage_ids[i];
for (int j = 0; j < texamt; j++)
for (j = 0; j < texamt; j++)
{
if (!strcmp(nametable + texinf->nameoffset, name))
{
@ -437,8 +446,8 @@ TEXINF * GetTEXINFName(char *name, int *tpagenum, int *texturenum)
/* end block 2 */
// End Line: 581
// [D]
TEXINF * GetTextureInfoName(char *name, TPAN *result)
// [D] [T]
TEXINF* GetTextureInfoName(char *name, TPAN *result)
{
TEXINF *tex;
int tpagenum;
@ -473,7 +482,7 @@ TEXINF * GetTextureInfoName(char *name, TPAN *result)
/* end block 3 */
// End Line: 1656
// [D]
// [D] [T]
void update_slotinfo(int tpage, int slot, RECT16 *pos)
{
tpageslots[slot] = tpage;
@ -502,26 +511,26 @@ void update_slotinfo(int tpage, int slot, RECT16 *pos)
/* end block 2 */
// End Line: 1687
// [D]
// [D] [T]
void ProcessTextureInfo(char *lump_ptr)
{
int i;
char* ptr;
tpage_amount = *(int *)lump_ptr;
texamount = *(int *)(lump_ptr + 4);
tpage_position = (TP *)(lump_ptr + 8);
char *ptr = (char *)&tpage_position[tpage_amount + 1];
ptr = (char *)&tpage_position[tpage_amount + 1];
if (tpage_amount > 0) {
for (int i = 0; i < tpage_amount; i++)
{
texamount = *(int *)ptr;
ptr += 4;
for (i = 0; i < tpage_amount; i++)
{
texamount = *(int *)ptr;
ptr += 4;
tpage_ids[i] = (TEXINF *)ptr;
ptr += (texamount * sizeof(TEXINF));
tpage_ids[i] = (TEXINF *)ptr;
ptr += (texamount * sizeof(TEXINF));
tpage_texamts[i] = texamount;
}
tpage_texamts[i] = texamount;
}
nperms = *(int *)ptr;
@ -593,16 +602,19 @@ void LoadPermanentTPages(int *sector)
{
int nsectors;
char *tpagebuffer;
int tloop, tset, i;
int specmodel;
int page1, page2;
// init tpage and cluts
MaxSpecCluts = 0;
for (int tloop = 0; tloop < 128; tloop++)
for (tloop = 0; tloop < 128; tloop++)
texture_pages[tloop] = GetTPage(0, 0, 960, 0);
for (int tloop = 0; tloop < 128; tloop++)
for (tloop = 0; tloop < 128; tloop++)
{
for (int tset = 0; tset < 32; tset++)
for (tset = 0; tset < 32; tset++)
texture_cluts[tloop][tset] = GetClut(960, 16);
}
@ -635,7 +647,7 @@ void LoadPermanentTPages(int *sector)
tpagebuffer = mallocptr;
nsectors = 0;
for (int i = 0; i < nperms; i++)
for (i = 0; i < nperms; i++)
nsectors += (permlist[i].y + 2047) / CDSECTOR_SIZE;
#ifdef PSX
@ -646,7 +658,7 @@ void LoadPermanentTPages(int *sector)
*sector += nsectors;
for (int i = 0; i < nperms; i++)
for (i = 0; i < nperms; i++)
{
int tp = permlist[i].x;
@ -663,23 +675,27 @@ void LoadPermanentTPages(int *sector)
slot_clutpos[slotsused].vx = clutpos.x;
slot_clutpos[slotsused].vy = clutpos.y;
int specmodel = (MissionHeader->residentModels[4] - 8) * 2;
// init special slot texture
specmodel = (MissionHeader->residentModels[4] - 8) * 2;
specialSlot = (short)slotsused;
int page1 = specTpages[GameLevel][specmodel];
int page2 = specTpages[GameLevel][specmodel + 1];
// get special slot tpage
page1 = specTpages[GameLevel][specmodel];
page2 = specTpages[GameLevel][specmodel + 1];
carTpages[GameLevel][6] = page1;
carTpages[GameLevel][7] = page2;
if (nspecpages != 0)
{
int temp = 0;
int clutsloaded = 0;
int temp, clutsloaded;
temp = 0;
clutsloaded = 0;
nsectors = 0;
for (int i = 0; i < nspecpages; i++)
for (i = 0; i < nspecpages; i++)
nsectors += (speclist[i].y + 2047) / CDSECTOR_SIZE;
#ifdef PSX
@ -691,9 +707,10 @@ void LoadPermanentTPages(int *sector)
*sector += nsectors;
for (int i = 0; i < nspecpages; i++)
for (i = 0; i < nspecpages; i++)
{
int npalettes = *(int *)tpagebuffer;
int tp, npalettes;
npalettes = *(int *)tpagebuffer;
temp += npalettes;
@ -705,7 +722,7 @@ void LoadPermanentTPages(int *sector)
temp = 0;
}
int tp = speclist[i].x;
tp = speclist[i].x;
// find a special car TPAGEs
if (page1 == tp || page2 == tp)
@ -733,7 +750,8 @@ void LoadPermanentTPages(int *sector)
clutpos.y++;
}
for (int i = slotsused; i < 19; i++)
// init all slots
for (i = slotsused; i < 19; i++)
{
tpageslots[i] = 0xFF;
@ -789,7 +807,7 @@ void LoadPermanentTPages(int *sector)
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
// [D] [T]
void ReloadIcons(void)
{
ReportMode(0);
@ -835,29 +853,32 @@ int environmenttpage = 0;
// [D] [T]
void GetTextureDetails(char *name, TEXTURE_DETAILS *info)
{
char *nametable = texturename_buffer;
int i, j;
int texamt;
char *nametable;
TEXINF *texinf;
nametable = texturename_buffer;
for (int i = 0; i < tpage_amount; i++)
for (i = 0; i < tpage_amount; i++)
{
int texamt = tpage_texamts[i];
TEXINF *texinf = tpage_ids[i];
texamt = tpage_texamts[i];
texinf = tpage_ids[i];
for (int j = 0; j < texamt; j++)
for (j = 0; j < texamt; j++)
{
if (!strcmp(nametable + texinf->nameoffset, name))
if (!strcmp(nametable + texinf->nameoffset, name) &&
(!texture_is_icon || i == environmenttpage))
{
if (!texture_is_icon || (i == environmenttpage))
{
info->tpageid = texture_pages[i];
info->clutid = texture_cluts[i][j];
info->texture_number = (char)j;
info->texture_page = (char)i;
info->tpageid = texture_pages[i];
info->clutid = texture_cluts[i][j];
info->texture_number = j;
info->texture_page = i;
setUVWH(&info->coords, texinf->x, texinf->y, texinf->width - 1, texinf->height - 1);
setUVWH(&info->coords, texinf->x, texinf->y, texinf->width - 1, texinf->height - 1);
// bust 'outta here, real fly
return;
}
// bust 'outta here, real fly
return;
}
texinf++;

View File

@ -21,7 +21,7 @@
#else
#define FixHalfRound(x, bits) ((x) + (1 << (bits-1)) >> bits)
#define FixHalfRound(x, bits) (((x) + (1 << (bits-1))) >> bits)
#define FixFloorSigned(x, bits) ((x) / (1 << bits)) // in disassembly: ((int(x) < 0 ? int(x) + (1 << bits)-1 : int(x)) >> bits)
#define FIXEDH(a) FixHalfRound(a, ONE_BITS) // Fixed Half Round number

View File

@ -1139,6 +1139,7 @@ struct REPLAY_STREAM // hashcode: 0xC894D541 (dec: -929770175)
struct PADRECORD* PadRecordBufferEnd; // size=3, offset=56
unsigned char playbackrun; // size=0, offset=60
int length; // size=0, offset=64
int padCount;
};
struct _PING_PACKET // hashcode: 0x9E8E7C27 (dec: -1634829273)

View File

@ -49,6 +49,7 @@ screenFunc fpUserFunctions[] = {
GamePlayScreen,
GameNameScreen,
CheatNumlayerSelect,
BonusGalleryScreen
};
char* gfxNames[4] = {
@ -75,34 +76,37 @@ int CutAmountsTotal[5] = {
char* CutSceneNames[28] =
{
"Il fiume rosso",
"L'obitorio",
"Il testimone",
"L'appartamento di Lenny",
"La setta cubana",
"L'intruso",
"L'incontro con Caine",
"Partenza dalla citt",
"In cerca di indizi",
"Partenza",
"Osservando l'autocarro",
"L'indizio nella Rosanna Soto",
"Il cantiere navale",
"Il colpo",
"L'arresto di Jericho",
"Vasquez in Las Vegas",
"Lo scambio di Jericho",
"Rapina nella banca",
"La sala da biliardo",
"Il sentiero di guerra di Caine",
"Caine a Rio",
"Avviso a Jones",
"La sparatoria",
"La fuga di Lenny",
"Lenny takedown",
"Back to chicago",
"Vasquez and Caine",
"Credits"
"Red River",
"The morgue",
"The Witness",
"Lenny's apartment",
"The Cuba Connection",
"The Intruder",
"Meeting Caine",
"Leaving Town",
"Looking for a lead",
"Moving out",
"Watching the truck",
"Rosanna Soto Clue",
"The Dockyard",
"The Hit",
"Seizing Jericho",
"Vasquez in Vegas",
"Trading Jericho",
"Bank job",
"The Pool Hall",
"Caine's Warpath",
"Caine in Rio",
"Warning Jones",
"The Shootout",
"Lenny's getaway",
"Lenny gets it",
"Back in Chicago",
"Vasquez meets Caine",
"Credits",
};
@ -501,6 +505,7 @@ void LoadFrontendScreens(void)
rect.x = 960;
rect.y = 256;
// load font
LoadImage(&rect, (u_long *)_frontend_buffer);
DrawSync(0);
@ -4208,161 +4213,255 @@ int MainScreen(int bSetup)
/* end block 4 */
// End Line: 10088
static char* cheatText[5] =
static char* cheatText[] =
{
"Sorry, no secrets",
"Mountain track",
"Circuit",
"Invincibility",
"Immunity"
"Immunity",
"Bonus Gallery"
};
// [D] [T] [A] adding bonus gallery
int CheatScreen(int bSetup)
{
PSXSCREEN *pPVar1;
PSXSCREEN *pPVar2;
int iVar3;
int iVar4;
int *piVar5;
int iVar6;
unsigned char bVar7;
int iVar8;
int iVar9;
int i;
int numOpen;
int k;
unsigned char cheatOn[12];
int evilRuss[4];
int evilRuss[5];
int hackLookup1[4] = {
0x121, 0x121, 0x11E, 0x11F
int hackLookup1[5] = {
0x121,
0x121,
0x11E,
0x11F,
(40 & 0xFF) | (1 << 8)
};
int hackLookup2[4] = {
0xC01, 0xC00, -1, -1
int hackLookup2[5] = {
0xC01, 0xC00, -1, -1, -1
};
if (bSetup == 0) {
if (bSetup == 0)
return 0;
}
if (gFurthestMission == 0x28)
{
bVar7 = 4;
}
else
{
bVar7 = AvailableCheats.cheat1 + AvailableCheats.cheat2 + AvailableCheats.cheat3 + AvailableCheats.cheat4;
}
if (bVar7 == 0)
if (gFurthestMission == 40)
numOpen = 5;
else
numOpen = AvailableCheats.cheat1 + AvailableCheats.cheat2 + AvailableCheats.cheat3 + AvailableCheats.cheat4;
// "Sorry no secrets"
if (numOpen == 0)
{
pCurrScreen->numButtons = 1;
pCurrScreen->buttons[0].u = 1;
pCurrScreen->buttons[0].d = 1;
pCurrScreen->numButtons = 1;
pPVar1 = pCurrScreen;
pCurrScreen->buttons[0].action = 0x400;
sprintf(pPVar1->buttons[0].Name, cheatText[0]);
sprintf(pCurrScreen->buttons[0].Name, cheatText[0]);
return 0;
}
piVar5 = evilRuss;
iVar4 = 0;
pCurrScreen->numButtons = bVar7;
pCurrScreen->numButtons = numOpen;
evilRuss[0] = AvailableCheats.cheat1;
evilRuss[1] = AvailableCheats.cheat2;
evilRuss[2] = AvailableCheats.cheat3;
evilRuss[3] = AvailableCheats.cheat4;
iVar3 = 4;
iVar8 = 0;
if (numOpen >= 5)
pCurrScreen->buttons[4] = pCurrScreen->buttons[3];
k = 0;
i = 0;
do {
if ((*piVar5 == 1) || (iVar6 = iVar3, iVar9 = iVar8, gFurthestMission == 0x28)) {
iVar6 = iVar3 + 0x3c;
sprintf((char *)((int)&pCurrScreen->buttons[0].var + iVar3), cheatText[iVar4 + 1]);
iVar9 = iVar8 + 1;
cheatOn[iVar8] = (unsigned char)iVar4;
if (evilRuss[i] || gFurthestMission == 40)
{
sprintf(pCurrScreen->buttons[i].Name, cheatText[i + 1]);
cheatOn[k++] = i;
}
pPVar1 = pCurrScreen;
iVar4 = iVar4 + 1;
piVar5 = piVar5 + 1;
iVar3 = iVar6;
iVar8 = iVar9;
} while (iVar4 < 4);
i++;
} while (i < 5);
if (bVar7 == 2) {
if (numOpen == 2)
{
pCurrScreen->buttons[0].action = hackLookup1[cheatOn[0]];
pPVar1->buttons[1].action = hackLookup1[cheatOn[1]];
pPVar1->buttons[0].var = hackLookup2[cheatOn[0]];
iVar3 = hackLookup2[cheatOn[1]];
pPVar1->buttons[0].d = '\x02';
pPVar2 = pCurrScreen;
pPVar1->buttons[1].var = iVar3;
pPVar2->buttons[0].u = '\x02';
pCurrScreen->buttons[1].d = '\x01';
pCurrScreen->buttons[1].u = '\x01';
pCurrScreen->buttons[1].action = hackLookup1[cheatOn[1]];
pCurrScreen->buttons[0].var = hackLookup2[cheatOn[0]];
pCurrScreen->buttons[1].var = hackLookup2[cheatOn[1]];
pCurrScreen->buttons[0].d = 2;
pCurrScreen->buttons[0].u = 2;
pCurrScreen->buttons[1].d = 1;
pCurrScreen->buttons[1].u = 1;
currSelIndex = 0;
return 0;
}
if (numOpen == 1)
{
pCurrScreen->buttons[0].action = hackLookup1[cheatOn[0]];
pCurrScreen->buttons[0].var = hackLookup2[cheatOn[0]];
pCurrScreen->buttons[0].d = 1;
pCurrScreen->buttons[0].u = 1;
currSelIndex = 0;
return 0;
}
if (numOpen == 3)
{
pCurrScreen->buttons[0].action = hackLookup1[cheatOn[0]];
pCurrScreen->buttons[1].action = hackLookup1[cheatOn[1]];
pCurrScreen->buttons[2].action = hackLookup1[cheatOn[2]];
pCurrScreen->buttons[0].var = hackLookup2[cheatOn[0]];
pCurrScreen->buttons[1].var = hackLookup2[cheatOn[1]];
pCurrScreen->buttons[2].var = hackLookup2[cheatOn[2]];
pCurrScreen->buttons[0].d = 2;
pCurrScreen->buttons[0].u = 3;
pCurrScreen->buttons[1].d = 3;
pCurrScreen->buttons[1].u = 1;
pCurrScreen->buttons[2].d = 1;
pCurrScreen->buttons[2].u = 2;
currSelIndex = 0;
return 0;
}
if (bVar7 == 1) {
if (numOpen >= 4)
{
pCurrScreen->buttons[0].action = hackLookup1[cheatOn[0]];
iVar3 = hackLookup2[cheatOn[0]];
pPVar1->buttons[0].d = '\x01';
pPVar2 = pCurrScreen;
pPVar1->buttons[0].var = iVar3;
pPVar2->buttons[0].u = '\x01';
pCurrScreen->buttons[1].action = hackLookup1[cheatOn[1]];
pCurrScreen->buttons[2].action = hackLookup1[cheatOn[2]];
pCurrScreen->buttons[3].action = hackLookup1[cheatOn[3]];
pCurrScreen->buttons[0].var = hackLookup2[cheatOn[0]];
pCurrScreen->buttons[1].var = hackLookup2[cheatOn[1]];
pCurrScreen->buttons[2].var = hackLookup2[cheatOn[2]];
pCurrScreen->buttons[3].var = hackLookup2[cheatOn[3]];
pCurrScreen->buttons[0].d = 2;
pCurrScreen->buttons[0].u = 4;
pCurrScreen->buttons[1].d = 3;
pCurrScreen->buttons[1].u = 1;
pCurrScreen->buttons[2].d = 4;
pCurrScreen->buttons[2].u = 2;
pCurrScreen->buttons[3].d = 1;
pCurrScreen->buttons[3].u = 3;
if(numOpen >= 5)
{
pCurrScreen->buttons[4].action = hackLookup1[cheatOn[4]];
pCurrScreen->buttons[4].var = hackLookup2[cheatOn[4]];
pCurrScreen->buttons[4].y += 40;
pCurrScreen->buttons[4].s_y += 40;
PsxScreens[40].userFunctionNum = 21;
pCurrScreen->buttons[0].u = 5;
pCurrScreen->buttons[3].d = 5;
pCurrScreen->buttons[4].d = 1;
pCurrScreen->buttons[4].u = 4;
}
currSelIndex = 0;
return 0;
}
if (bVar7 == 3) {
pCurrScreen->buttons[0].action = hackLookup1[cheatOn[0]];
pPVar1->buttons[1].action = hackLookup1[cheatOn[1]];
pPVar1->buttons[2].action = hackLookup1[cheatOn[2]];
pPVar1->buttons[0].var = hackLookup2[cheatOn[0]];
pPVar1->buttons[1].var = hackLookup2[cheatOn[1]];
iVar3 = hackLookup2[cheatOn[2]];
pPVar1->buttons[0].d = '\x02';
pPVar2 = pCurrScreen;
pPVar1->buttons[2].var = iVar3;
pPVar2->buttons[0].u = '\x03';
pCurrScreen->buttons[1].d = '\x03';
pCurrScreen->buttons[1].u = '\x01';
pCurrScreen->buttons[2].d = '\x01';
pCurrScreen->buttons[2].u = '\x02';
currSelIndex = 0;
return 0;
}
if (bVar7 == 4) {
pCurrScreen->buttons[0].action = hackLookup1[cheatOn[0]];
pPVar1->buttons[1].action = hackLookup1[cheatOn[1]];
pPVar1->buttons[2].action = hackLookup1[cheatOn[2]];
pPVar1->buttons[3].action = hackLookup1[cheatOn[3]];
pPVar1->buttons[0].var = hackLookup2[cheatOn[0]];
pPVar1->buttons[1].var = hackLookup2[cheatOn[1]];
pPVar1->buttons[2].var = hackLookup2[cheatOn[2]];
iVar3 = hackLookup2[cheatOn[3]];
pPVar1->buttons[0].d = '\x02';
pPVar2 = pCurrScreen;
pPVar1->buttons[3].var = iVar3;
pPVar2->buttons[0].u = '\x04';
pCurrScreen->buttons[1].d = '\x03';
pCurrScreen->buttons[1].u = '\x01';
pCurrScreen->buttons[2].d = '\x04';
pCurrScreen->buttons[2].u = '\x02';
pCurrScreen->buttons[3].d = '\x01';
pCurrScreen->buttons[3].u = '\x03';
currSelIndex = 0;
return 0;
}
pCurrScreen->numButtons = '\0';
pCurrScreen->numButtons = 0;
currSelIndex = 0;
return 0;
}
int g_GalleryImage = 0;
char* GalleryImageNames[] = {
"GFX\\GAL\\IMG1.TIM",
"GFX\\GAL\\IMG2.TIM",
"GFX\\GAL\\IMG3.TIM"
};
// [A]
int BonusGalleryScreen(int bSetup)
{
char tmpStr[64];
int imageChanged;
RECT16 rect;
imageChanged = 0;
if(bSetup)
{
bDoingScores = 1;
g_GalleryImage = 0;
imageChanged = 1;
}
if (fePad & 0x10)
{
// goint back
bDoingScores = 0;
LoadFrontendScreens();
//LoadBackgroundFile("DATA\\GFX.RAW");
}
else if(fePad & 0x8000)
{
imageChanged = 1;
g_GalleryImage--;
if (g_GalleryImage < 0)
g_GalleryImage = 2;
FESound(3);
}
else if(fePad & 0x2000)
{
imageChanged = 1;
g_GalleryImage++;
if (g_GalleryImage > 2)
g_GalleryImage = 0;
FESound(3);
}
if(imageChanged)
{
FEDrawCDicon();
LoadfileSeg(GalleryImageNames[g_GalleryImage], _overlay_buffer, 20, 0x4ff80);
LoadClut((u_long*)_overlay_buffer, 640, 511);
DrawSync(0);
setRECT16(&rect, 640, 0, 320, 511);
LoadImage(&rect, (u_long*)&_overlay_buffer[512]);
DrawSync(0);
}
//sprintf(tmpStr, "Gallery %d of %d", g_GalleryImage + 1, 3);
//FEPrintStringSized(tmpStr, 10, 10, 4, 0, 128, 64, 0 );
return 0;
}
// decompiled code

View File

@ -86,5 +86,6 @@ extern void FEDrawCDicon(); // 0x001C62F8
extern int CheatNumlayerSelect(int bSetup); // 0x001C6724
extern int BonusGalleryScreen(int bSetup);
#endif

View File

@ -1,7 +1,7 @@
#ifndef VERSION_H
#define VERSION_H
#define GAME_VERSION_N "1.0 alpha"
#define GAME_VERSION_N "2.0 alpha"
#define GAME_TITLE "REDRIVER2"
#define GAME_VERSION GAME_TITLE " " GAME_VERSION_N

2
src_rebuild/gen_psx.bat Normal file
View File

@ -0,0 +1,2 @@
premake5 --os=psx gmake2
pause

View File

@ -1,19 +1,23 @@
-- premake5.lua
require "premake_modules/psx"
-- you can redefine dependencies
SDL2_DIR = os.getenv("SDL2_DIR") or "dependencies/SDL2"
GLEW_DIR = os.getenv("GLEW_DIR") or "dependencies/glew"
OPENAL_DIR = os.getenv("OPENAL_DIR") or "dependencies/openal-soft"
JPEG_DIR = os.getenv("JPEG_DIR") or "dependencies/jpeg"
PSYQ_DIR = os.getenv("PSYQ_DIR") or "PSY-Q"
GAME_REGION = os.getenv("GAME_REGION") or "NTSC_VERSION" -- or PAL_VERSION
if not (GAME_REGION == "NTSC_VERSION" or GAME_REGION == "PAL_VERSION") then
error("'GAME_REGION' should be 'NTSC_VERSION' or 'PAL_VERSION'")
end
workspace "REDRIVER2"
configurations { "Debug", "Release" }
configurations { "Debug", "Release", "Release Dev" }
defines { VERSION }
@ -31,72 +35,15 @@ workspace "REDRIVER2"
"NDEBUG",
}
if _TARGET_OS == "windows" then
dofile("premake_libjpeg.lua")
end
-- EMULATOR layer
project "PSX"
kind "StaticLib"
language "C++"
compileas "C++"
targetdir "bin/%{cfg.buildcfg}"
includedirs {
"EMULATOR"
}
defines { GAME_REGION }
files {
"EMULATOR/**.h",
"EMULATOR/**.H",
"EMULATOR/**.c",
"EMULATOR/**.C",
"EMULATOR/**.cpp",
"EMULATOR/**.CPP",
}
defines { "OGL", "GLEW" }
includedirs {
SDL2_DIR.."/include",
GLEW_DIR.."/include",
OPENAL_DIR.."/include",
}
filter "system:Windows"
links {
"opengl32",
"glew32",
"SDL2",
"OpenAL32"
}
libdirs {
SDL2_DIR.."/lib/x86",
GLEW_DIR.."/lib/Release/Win32",
OPENAL_DIR.."/libs/Win32",
}
filter "system:linux"
buildoptions { "-Wno-narrowing", "-m32" }
includedirs {
"/usr/include/SDL2"
}
links {
"GL",
"GLEW",
"openal",
"SDL2",
}
linkoptions { "-m32" }
filter "configurations:Release"
optimize "Full"
if os.target() == "windows" then
dofile("premake_libjpeg.lua")
end
if os.target() ~= "psx" then
dofile("premake_emulator.lua")
end
-- TODO: overlays
-- game iteslf
project "REDRIVER2"
@ -107,7 +54,6 @@ project "REDRIVER2"
includedirs {
"GAME",
"EMULATOR"
}
defines { GAME_REGION }
@ -115,18 +61,38 @@ project "REDRIVER2"
files {
"GAME/**.H",
"GAME/**.C",
"utils/**.h",
"utils/**.cpp",
"redriver2_psxpc.cpp",
"DebugOverlay.cpp",
}
-- exclude sources which belong to overlays
if os.target() == "psx" then
excludes {
"GAME/MEMCARD/**.C",
"GAME/MEMCARD/**.H",
"GAME/FRONTEND/**.C",
"GAME/FRONTEND/**.H",
"GAME/C/LEADAI.C",
"GAME/C/PATHFIND.C",
}
end
filter "system:Windows or linux"
defines { "OGL", "GLEW" }
defines { "OGL", "GLEW", "SIMPLE_SPOOL" }
dependson { "PSX" }
links { "PSX", "jpeg" }
includedirs {
"EMULATOR"
}
files {
"utils/**.h",
"utils/**.cpp",
"redriver2_psxpc.cpp",
"DebugOverlay.cpp",
}
filter "system:Windows"
files {
"Windows/resource.h",
"Windows/Resource.rc",
@ -145,7 +111,12 @@ project "REDRIVER2"
}
filter "system:linux"
buildoptions { "-Wno-narrowing", "-fpermissive", "-m32" }
buildoptions {
"-Wno-narrowing",
"-fpermissive",
"-m32"
}
cppdialect "C++11"
includedirs {
@ -159,17 +130,44 @@ project "REDRIVER2"
"SDL2",
}
linkoptions { "-z muldefs", "-m32" }
linkoptions {
"-z muldefs",
"-m32"
}
filter "system:psx"
defines { "PSX" }
includedirs {
PSYQ_DIR.."/include"
}
links {
PSYQ_DIR.."/lib/LIBETC",
PSYQ_DIR.."/lib/LIBPAD",
PSYQ_DIR.."/lib/LIBGTE",
PSYQ_DIR.."/lib/LIBMCRD",
PSYQ_DIR.."/lib/LIBCD",
PSYQ_DIR.."/lib/LIBSN",
PSYQ_DIR.."/lib/LIBSPU",
PSYQ_DIR.."/lib/LIBAPI"
}
filter "configurations:Debug"
targetsuffix "_dbg"
defines {
"DEBUG_OPTIONS",
"COLLISION_DEBUG"
"COLLISION_DEBUG",
"CUTSCENE_RECORDER"
}
symbols "On"
filter "configurations:Release"
optimize "Full"
filter "configurations:Release Dev"
targetsuffix "_dev"
defines {
--"DEBUG_OPTIONS",
--"COLLISION_DEBUG"
"DEBUG_OPTIONS",
"COLLISION_DEBUG",
"CUTSCENE_RECORDER"
}
optimize "Full"

View File

@ -0,0 +1,70 @@
-- EMULATOR layer
project "PSX"
kind "StaticLib"
language "C++"
compileas "C++"
targetdir "bin/%{cfg.buildcfg}"
removeplatforms "psx"
includedirs {
"EMULATOR"
}
defines { GAME_REGION }
files {
"EMULATOR/**.h",
"EMULATOR/**.H",
"EMULATOR/**.c",
"EMULATOR/**.C",
"EMULATOR/**.cpp",
"EMULATOR/**.CPP",
}
defines { "OGL", "GLEW" }
includedirs {
SDL2_DIR.."/include",
GLEW_DIR.."/include",
OPENAL_DIR.."/include",
}
filter "system:Windows"
defines { "_WINDOWS" }
links {
"opengl32",
"glew32",
"SDL2",
"OpenAL32"
}
libdirs {
SDL2_DIR.."/lib/x86",
GLEW_DIR.."/lib/Release/Win32",
OPENAL_DIR.."/libs/Win32",
}
filter "system:linux"
buildoptions {
"-Wno-narrowing",
"-m32",
}
includedirs {
"/usr/include/SDL2"
}
links {
"GL",
"GLEW",
"openal",
"SDL2",
}
linkoptions {
"-m32"
}
filter "configurations:Release"
optimize "Full"

View File

@ -0,0 +1,4 @@
return {
"_preload.lua",
"psx.lua",
}

View File

@ -0,0 +1,47 @@
-- Premake PSX module
-- By SoapyMan
local p = premake
local api = p.api
--
-- Register the PSX extension
--
p.PSX = "psx"
api.addAllowed("system", p.PSX)
api.addAllowed("architecture", { "mips32" })
local osoption = p.option.get("os")
if osoption ~= nil then
table.insert(osoption.allowed, { "psx", "PSX" })
end
-- add system tags for PSX
os.systemTags[p.PSX] = { "psx" }
filter { "system:psx", "kind:ConsoleApp or WindowedApp" }
targetextension ".exe"
-- overlays
filter { "system:psx", "kind:Overlay" }
targetprefix ""
targetextension ".bin"
implibextension ".lib"
filter { "system:psx", "kind:StaticLib" }
targetprefix ""
targetextension ".lib"
--
-- Register PSX properties
--
-- Compilation properties
-- TODO
return function(cfg)
return (cfg.system == p.PSX)
end

View File

@ -0,0 +1,19 @@
-- Premake PSX module
-- By SoapyMan
local p = premake
if not p.modules.psx then
include ( "_preload.lua" )
require ("gmake")
p.modules.psx = {}
if _ACTION == "gmake" or _ACTION == "gmake2" then
configuration { "psx" }
system "psx"
end
end
return p.modules.psx

View File

@ -5,7 +5,7 @@
#include "GAME/C/MAIN.H"
#include "GAME/C/SYSTEM.H"
#include "GAME/C/GLAUNCH.H"
#include "GAME/C/PLAYERS.H"
#include "EMULATOR.H"
#include "EMULATOR_PRIVATE.H"
@ -305,6 +305,29 @@ void GameDebugKeys(int nKey, bool down)
g_FreeCameraEnabled ^= 1;
printf("Free camera: %s\n", g_FreeCameraEnabled ? "ON" : "OFF");
}
else if (nKey == SDL_SCANCODE_BACKSPACE)
{
extern int FastForward;
FastForward = 1;
}
else if (nKey == SDL_SCANCODE_PAGEUP)
{
player[0].cameraCarId++;
if (player[0].cameraCarId > MAX_CARS - 1)
player[0].cameraCarId = MAX_CARS - 1;
printf("Car on camera: %d\n", player[0].cameraCarId);
}
else if (nKey == SDL_SCANCODE_PAGEDOWN)
{
player[0].cameraCarId--;
if (player[0].cameraCarId < 0)
player[0].cameraCarId = 0;
printf("Car on camera: %d\n", player[0].cameraCarId);
}
else if (nKey == SDL_SCANCODE_KP_DIVIDE)
{
FunkUpDaBGMTunez(0);