Merge pull request #38 from SoapyMan/develop-SoapyMan

Develop soapy man
This commit is contained in:
Ilya 2020-10-14 01:24:36 +06:00 committed by GitHub
commit cef59a8ae4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 4732 additions and 5223 deletions

View File

@ -58,12 +58,12 @@ before_build:
- cmd: premake5 vs2019 - cmd: premake5 vs2019
- cmd: ren "%JPEG_DIR%\jconfig.vc" "jconfig.h" - cmd: ren "%JPEG_DIR%\jconfig.vc" "jconfig.h"
#artifacts: artifacts:
# - path: src_rebuild\bin\%configuration%\*.zip - path: src_rebuild\bin\%configuration%\*.zip
# name: Binaries name: Binaries
#after_build: after_build:
# - cmd: cd %project_folder%\bin\%configuration% - cmd: cd %project_folder%\bin\%configuration%
# - 7z a REDRIVER2.zip ".\*" - 7z a REDRIVER2.zip ".\*"
#build: off #build: off

View File

@ -3,17 +3,17 @@
#include "LIBGTE.H" #include "LIBGTE.H"
#include "LIBGPU.H" #include "LIBGPU.H"
#include "INLINE_C.H" #include "INLINE_C.H"
#include "GTEREG.H" #include "C/MISSION.H"
#include "GAME/ASM/ASMTEST.H" #include "C/CONVERT.H"
#include "GAME/C/CONVERT.H" #include "C/CAMERA.H"
#include "GAME/C/CAMERA.H" #include "C/DRAW.H"
#include "GAME/C/DRAW.H" #include "C/SYSTEM.H"
#include "GAME/C/SYSTEM.H" #include "C/PRES.H"
#include "GAME/C/PRES.H" #include "C/SPOOL.H"
#include "GAME/C/SPOOL.H" #include "C/CARS.H"
#include "GAME/C/CARS.H" #include "C/PLAYERS.H"
#include "GAME/C/PLAYERS.H" #include "C/GLAUNCH.H"
int gDisplayDrawStats = 0; int gDisplayDrawStats = 0;
@ -112,6 +112,9 @@ void DrawDebugOverlays()
sprintf(tempBuf, "Car speed: %d", speed); sprintf(tempBuf, "Car speed: %d", speed);
PrintString(tempBuf, 10, 60); PrintString(tempBuf, 10, 60);
sprintf(tempBuf, "Mission %d Chase: %d", gCurrentMissionNumber, gRandomChase);
PrintString(tempBuf, 10, 70);
} }
} }

View File

@ -142,6 +142,10 @@ extern int docop2(int op);
#define gte_ldrgb( r0 ) \ #define gte_ldrgb( r0 ) \
MTC2(*(uint*)((char*)r0), 6); MTC2(*(uint*)((char*)r0), 6);
// mtc2 8
#define gte_lddp( r0 ) \
MTC2(*(uint*)r0, 8);
#if defined(PGXP) #if defined(PGXP)
// swc2 14 // swc2 14
@ -298,6 +302,15 @@ extern int docop2(int op);
gte_rtir(); \ gte_rtir(); \
gte_stclmv((char*)r3+4); } gte_stclmv((char*)r3+4); }
#define gte_LoadAverage12(r1,r2,r3,r4,r5) \
{ gte_lddp(r3); \
gte_ldlvl(r1); \
gte_gpf12(); \
gte_lddp(r4); \
gte_ldlvl(r2); \
gte_gpl12(); \
gte_stlvl(r5); }
// FIXME: there is lack of some macros // FIXME: there is lack of some macros
// please refer to official Psy-Q PSX SDK headers // please refer to official Psy-Q PSX SDK headers
// and this: https://github.com/ogamespec/pops-gte/blob/master/docs/gte.txt // and this: https://github.com/ogamespec/pops-gte/blob/master/docs/gte.txt

View File

@ -1226,7 +1226,7 @@ long RotAverageNclip4(struct SVECTOR* v0, struct SVECTOR* v1, struct SVECTOR* v2
MATRIX* MulMatrix0(MATRIX* m0, MATRIX* m1, MATRIX* m2) MATRIX* MulMatrix0(MATRIX* m0, MATRIX* m1, MATRIX* m2)
{ {
#if 0 #if 1
gte_MulMatrix0(m0, m1, m2); gte_MulMatrix0(m0, m1, m2);
#else #else
/* ±êÅàm0==m2ÌŽžƒ„ƒoƒC */ /* ±êÅàm0==m2ÌŽžƒ„ƒoƒC */
@ -1311,42 +1311,142 @@ void SetFarColor(long rfc, long gfc, long bfc)
VECTOR* ApplyMatrix(MATRIX* m, SVECTOR* v0, VECTOR* v1) VECTOR* ApplyMatrix(MATRIX* m, SVECTOR* v0, VECTOR* v1)
{ {
APPLYMATRIX(m, v0, v1) #if 0
return v1; gte_SetRotMatrix(m);
gte_ldv0(v0);
gte_rtv0();
gte_stlvnl(v1);
#else
APPLYMATRIX(m, v0, v1);
#endif
return v1;
} }
VECTOR* ApplyRotMatrix(SVECTOR* v0, VECTOR* v1) VECTOR* ApplyRotMatrix(SVECTOR* v0, VECTOR* v1)
{ {
#if 0
gte_ldv0(v0);
gte_rtv0();
gte_stsv(v1);
#else
MATRIX temp; MATRIX temp;
gte_ReadRotMatrix(&temp); gte_ReadRotMatrix(&temp);
MATRIX* m = &temp; MATRIX* m = &temp;
APPLYMATRIX(m, v0, v1); APPLYMATRIX(m, v0, v1);
#endif
return v1; return v1;
} }
VECTOR* ApplyRotMatrixLV(VECTOR* v0, VECTOR* v1) VECTOR* ApplyRotMatrixLV(VECTOR* v0, VECTOR* v1)
{ {
#if 1
// correct Psy-Q implementation
VECTOR tmpHI;
VECTOR tmpLO;
tmpHI.vx = v0->vx;
tmpHI.vy = v0->vy;
tmpHI.vz = v0->vz;
if (tmpHI.vx < 0)
{
tmpLO.vx = -(-tmpHI.vx >> 0xf);
tmpHI.vx = -(-tmpHI.vx & 0x7fff);
}
else
{
tmpLO.vx = tmpHI.vx >> 0xf;
tmpHI.vx = tmpHI.vx & 0x7fff;
}
if (tmpHI.vy < 0)
{
tmpLO.vy = -(-tmpHI.vy >> 0xf);
tmpHI.vy = -(-tmpHI.vy & 0x7fff);
}
else
{
tmpLO.vy = tmpHI.vy >> 0xf;
tmpHI.vy = tmpHI.vy & 0x7fff;
}
if (tmpHI.vz < 0)
{
tmpLO.vz = -(-tmpHI.vz >> 0xf);
tmpHI.vz = -(-tmpHI.vz & 0x7fff);
}
else
{
tmpLO.vz = tmpHI.vz >> 0xf;
tmpHI.vz = tmpHI.vz & 0x7fff;
}
gte_ldlvl(&tmpLO);
docop2(0x41E012); // gte_rtir_sf0 ?
gte_stlvnl(&tmpLO);
gte_ldlvl(&tmpHI);
gte_rtir();
if (tmpLO.vx < 0)
tmpLO.vx = tmpLO.vx * 8;
else
tmpLO.vx = tmpLO.vx << 3;
if (tmpLO.vy < 0)
tmpLO.vy = tmpLO.vy * 8;
else
tmpLO.vy = tmpLO.vy << 3;
if (tmpLO.vz < 0)
tmpLO.vz = tmpLO.vz * 8;
else
tmpLO.vz = tmpLO.vz << 3;
gte_stlvnl(&tmpHI);
v1->vx = tmpHI.vx + tmpLO.vx;
v1->vy = tmpHI.vy + tmpLO.vy;
v1->vz = tmpHI.vz + tmpLO.vz;
#else
MATRIX temp; MATRIX temp;
gte_ReadRotMatrix(&temp); gte_ReadRotMatrix(&temp);
MATRIX* m = &temp; MATRIX* m = &temp;
APPLYMATRIX(m, v0, v1); APPLYMATRIX(m, v0, v1);
#endif
return v1; return v1;
} }
SVECTOR* ApplyMatrixSV(MATRIX* m, SVECTOR* v0, SVECTOR* v1) SVECTOR* ApplyMatrixSV(MATRIX* m, SVECTOR* v0, SVECTOR* v1)
{ {
APPLYMATRIX(m, v0, v1) #if 1
return v1; // correct Psy-Q implementation
gte_SetRotMatrix(m);
gte_ldv0(v0);
gte_rtv0();
gte_stsv(v1);
#else
APPLYMATRIX(m, v0, v1);
#endif
return v1;
} }
VECTOR* ApplyMatrixLV(MATRIX* m, VECTOR* v0, VECTOR* v1) VECTOR* ApplyMatrixLV(MATRIX* m, VECTOR* v0, VECTOR* v1)
{ {
APPLYMATRIX(m, v0, v1) #if 0
return v1; gte_SetRotMatrix(m);
gte_ldv0(v0);
gte_rtv0();
gte_stlvnl(v1);
#else
APPLYMATRIX(m, v0, v1);
#endif
return v1;
} }
MATRIX* RotMatrix(struct SVECTOR* r, MATRIX* m) MATRIX* RotMatrix(struct SVECTOR* r, MATRIX* m)
@ -1389,7 +1489,7 @@ MATRIX* RotMatrixYXZ(struct SVECTOR* r, MATRIX* m)
int iVar1; int iVar1;
int iVar2; int iVar2;
short sVar3; short sVar3;
uint uVar4; int uVar4;
int iVar5; int iVar5;
int iVar6; int iVar6;
int iVar7; int iVar7;
@ -1397,31 +1497,31 @@ MATRIX* RotMatrixYXZ(struct SVECTOR* r, MATRIX* m)
uVar4 = (r->vx); uVar4 = (r->vx);
if ((int)uVar4 < 0) if (uVar4 < 0)
{ {
iVar6 = *(int*)(rcossin_tbl + (-uVar4 & 0xfff) * 2); iVar6 = *(int*)(rcossin_tbl + (-uVar4 & 0xfff) * 2);
sVar3 = (short)iVar6; sVar3 = iVar6;
iVar5 = -(int)sVar3; iVar5 = -sVar3;
} }
else else
{ {
iVar6 = *(int*)(rcossin_tbl + (uVar4 & 0xfff) * 2); iVar6 = *(int*)(rcossin_tbl + (uVar4 & 0xfff) * 2);
iVar5 = (int)(short)iVar6; iVar5 = iVar6;
sVar3 = -(short)iVar6; sVar3 = -iVar6;
} }
iVar6 = iVar6 >> 0x10; iVar6 = iVar6 >> 0x10;
uVar4 = (r->vy); uVar4 = (r->vy);
if ((int)uVar4 < 0) if (uVar4 < 0)
{ {
iVar7 = *(int*)(rcossin_tbl + (-uVar4 & 0xfff) * 2); iVar7 = *(int*)(rcossin_tbl + (-uVar4 & 0xfff) * 2);
iVar1 = -(int)(short)iVar7; iVar1 = -iVar7;
} }
else else
{ {
iVar7 = *(int*)(rcossin_tbl + (uVar4 & 0xfff) * 2); iVar7 = *(int*)(rcossin_tbl + (uVar4 & 0xfff) * 2);
iVar1 = (int)(short)iVar7; iVar1 = iVar7;
} }
iVar7 = iVar7 >> 0x10; iVar7 = iVar7 >> 0x10;
@ -1431,17 +1531,17 @@ MATRIX* RotMatrixYXZ(struct SVECTOR* r, MATRIX* m)
m->m[0][2] = FIXED(iVar1 * iVar6); m->m[0][2] = FIXED(iVar1 * iVar6);
sVar3 = FIXED(iVar7 * iVar6); sVar3 = FIXED(iVar7 * iVar6);
if ((int)uVar4 < 0) if (uVar4 < 0)
{ {
m->m[2][2] = sVar3; m->m[2][2] = sVar3;
iVar8 = *(int*)(rcossin_tbl + (-uVar4 & 0xfff) * 2); iVar8 = *(int*)(rcossin_tbl + (-uVar4 & 0xfff) * 2);
iVar2 = -(int)(short)iVar8; iVar2 = -iVar8;
} }
else else
{ {
m->m[2][2] = sVar3; m->m[2][2] = sVar3;
iVar8 = *(int*)(rcossin_tbl + (uVar4 & 0xfff) * 2); iVar8 = *(int*)(rcossin_tbl + (uVar4 & 0xfff) * 2);
iVar2 = (int)(short)iVar8; iVar2 = iVar8;
} }
iVar8 = iVar8 >> 0x10; iVar8 = iVar8 >> 0x10;
@ -1523,6 +1623,9 @@ MATRIX* RotMatrixZ(long r, MATRIX* m)
MATRIX* RotMatrixZYX_gte(SVECTOR* r, MATRIX* m) MATRIX* RotMatrixZYX_gte(SVECTOR* r, MATRIX* m)
{ {
#if 0
// TODO:...
#else
// FIXME: make a proper function // FIXME: make a proper function
m->m[0][0] = 0x1000; m->m[0][0] = 0x1000;
m->m[0][1] = 0; m->m[0][1] = 0;
@ -1539,6 +1642,7 @@ MATRIX* RotMatrixZYX_gte(SVECTOR* r, MATRIX* m)
RotMatrixX(r->vx, m); RotMatrixX(r->vx, m);
RotMatrixY(r->vy, m); RotMatrixY(r->vy, m);
RotMatrixZ(r->vz, m); RotMatrixZ(r->vz, m);
#endif
return m; return m;
} }
@ -1584,52 +1688,20 @@ void SetFogNear(long a, long h)
SetDQB(20971520); SetDQB(20971520);
} }
int isin(int x)
{
#define qN 10
#define qA 12
#define B 19900
#define C 3516
int c, x2, y;
c = x << (30 - qN); // Semi-circle info into carry.
x -= 1 << qN; // sine -> cosine calc
x = x << (31 - qN); // Mask with PI
x = x >> (31 - qN); // Note: SIGNED shift! (to qN)
x = x * x >> (2 * qN - 14); // x=x^2 To Q14
y = B - (x * C >> 14); // B - x^2*C
y = (1 << qA) - (x * y >> 16); // A - x^2*(B-x^2*C)
return c >= 0 ? y : -y;
}
int rsin(int a) int rsin(int a)
{ {
#if 0
return isin(a);
#else
if (a < 0) if (a < 0)
return -rcossin_tbl[(-a & 0xfffU) * 2]; return -rcossin_tbl[(-a & 0xfffU) * 2];
return rcossin_tbl[(a & 0xfffU) * 2]; return rcossin_tbl[(a & 0xfffU) * 2];
#endif
} }
int rcos(int a) int rcos(int a)
{ {
#if 0
return isin(a + 1024);
#else
if (a < 0) if (a < 0)
return rcossin_tbl[(-a & 0xfffU) * 2 + 1]; return rcossin_tbl[(-a & 0xfffU) * 2 + 1];
return rcossin_tbl[(a & 0xfffU) * 2 + 1]; return rcossin_tbl[(a & 0xfffU) * 2 + 1];
#endif
} }
long ratan2(long y, long x) long ratan2(long y, long x)

View File

@ -71,33 +71,24 @@ void StoreGameFlags(void)
// [D] [T] // [D] [T]
int TannerCanEnterCar(_CAR_DATA *cp, int distToCarSq) int TannerCanEnterCar(_CAR_DATA *cp, int distToCarSq)
{ {
int speed;
int carRange; int carRange;
if ((cp->controlFlags & 1) != 0) if (cp->controlFlags & CONTROL_FLAG_COP)
gCopCarTheftAttempted = 1; gCopCarTheftAttempted = 1;
if ((cp->controlType == CONTROL_TYPE_CIV_AI || cp->controlType == CONTROL_TYPE_CUTSCENE) && if ((cp->controlType == CONTROL_TYPE_CIV_AI || cp->controlType == CONTROL_TYPE_CUTSCENE) &&
(cp->controlFlags & 1) == 0 && (cp->controlFlags & CONTROL_FLAG_COP) == 0 &&
(cp->controlFlags & 2) == 0 && (cp->controlFlags & CONTROL_FLAG_COP_SLEEPING) == 0 &&
cp->hd.where.m[1][1] > 99) // not flipped over cp->hd.where.m[1][1] > 99) // not flipped over
{ {
speed = FIXEDH(cp->hd.wheel_speed); if (ABS(FIXEDH(cp->hd.wheel_speed)) < 3)
if (speed < 0)
speed = -speed;
if (speed < 3)
{ {
carRange = car_cosmetics[cp->ap.model].colBox.vx * 2; carRange = car_cosmetics[cp->ap.model].colBox.vx * 2;
if (carRange > 5000) if (carRange > 5000)
carRange = 5000; carRange = 5000;
carRange *= carRange; return (carRange*carRange < distToCarSq) ^ 1;
return (carRange < distToCarSq) ^ 1;
} }
} }
@ -132,9 +123,8 @@ int TannerCanEnterCar(_CAR_DATA *cp, int distToCarSq)
// [D] // [D]
int TannerStuckInCar(int doSpeedCheck, int player_id) int TannerStuckInCar(int doSpeedCheck, int player_id)
{ {
short *psVar1; short *playerFelony;
int speed; int speed;
int iVar3;
_CAR_DATA *cp; _CAR_DATA *cp;
_PLAYER* lp; _PLAYER* lp;
@ -146,15 +136,15 @@ int TannerStuckInCar(int doSpeedCheck, int player_id)
{ {
if (lp->playerCarId < 0) if (lp->playerCarId < 0)
{ {
psVar1 = &pedestrianFelony; playerFelony = &pedestrianFelony;
} }
else else
{ {
cp = &car_data[lp->playerCarId]; cp = &car_data[lp->playerCarId];
psVar1 = &cp->felonyRating; playerFelony = &cp->felonyRating;
} }
if ((*psVar1 < 0x293 || player_position_known < 1) && if ((*playerFelony < 0x293 || player_position_known < 1) &&
cp && cp &&
(cp->hd.wheel[1].surface & 7) != 1 && (cp->hd.wheel[1].surface & 7) != 1 &&
(cp->hd.wheel[3].surface & 7) != 1) (cp->hd.wheel[3].surface & 7) != 1)

View File

@ -981,23 +981,15 @@ int CarBuildingCollision(_CAR_DATA *cp, BUILDING_BOX *building, CELL_OBJECT *cop
tempwhere.vz = cp->hd.where.t[2]; tempwhere.vz = cp->hd.where.t[2];
debris_colour = GetDebrisColour(cp); debris_colour = GetDebrisColour(cp);
gte_SetRotMatrix(&cp->hd.where);
gte_SetTransMatrix(&cp->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[0].x);
cd[0].theta = cp->hd.direction; cd[0].theta = cp->hd.direction;
if (cp->controlType == CONTROL_TYPE_TANNERCOLLIDER) if (cp->controlType == CONTROL_TYPE_TANNERCOLLIDER)
{ {
cd[0].x.vx = cp->hd.where.t[0];
cd[0].x.vy = cp->hd.where.t[1];
cd[0].x.vz = cp->hd.where.t[2];
cd[0].vel.vx = FIXEDH(cp->st.n.linearVelocity[0]); cd[0].vel.vx = FIXEDH(cp->st.n.linearVelocity[0]);
cd[0].vel.vz = FIXEDH(cp->st.n.linearVelocity[2]); cd[0].vel.vz = FIXEDH(cp->st.n.linearVelocity[2]);
@ -1009,6 +1001,10 @@ int CarBuildingCollision(_CAR_DATA *cp, BUILDING_BOX *building, CELL_OBJECT *cop
} }
else if (cp->controlType == CONTROL_TYPE_CAMERACOLLIDER) else if (cp->controlType == CONTROL_TYPE_CAMERACOLLIDER)
{ {
cd[0].x.vx = cp->hd.where.t[0];
cd[0].x.vy = cp->hd.where.t[1];
cd[0].x.vz = cp->hd.where.t[2];
cd[0].vel.vx = 0; cd[0].vel.vx = 0;
cd[0].vel.vz = 0; cd[0].vel.vz = 0;
cd[0].length[1] = 5; cd[0].length[1] = 5;
@ -1016,6 +1012,19 @@ int CarBuildingCollision(_CAR_DATA *cp, BUILDING_BOX *building, CELL_OBJECT *cop
} }
else else
{ {
gte_SetRotMatrix(&cp->hd.where);
gte_SetTransMatrix(&cp->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[0].x);
cd[0].vel.vx = FIXEDH(cp->st.n.linearVelocity[0]); cd[0].vel.vx = FIXEDH(cp->st.n.linearVelocity[0]);
cd[0].vel.vz = FIXEDH(cp->st.n.linearVelocity[2]); cd[0].vel.vz = FIXEDH(cp->st.n.linearVelocity[2]);
@ -1226,7 +1235,7 @@ int CarBuildingCollision(_CAR_DATA *cp, BUILDING_BOX *building, CELL_OBJECT *cop
while (sip->name != NULL) while (sip->name != NULL)
{ {
if (modelpointers[sip->modelIdx] == model) if (sip->modelIdx == cop->type)
{ {
match = sip; match = sip;
break; break;

View File

@ -23,8 +23,9 @@
#include "RAND.H" #include "RAND.H"
MODEL* gBombModel; MODEL* gBombModel;
_ExOBJECT explosion[5];
static BOMB ThrownBombs[5]; static BOMB ThrownBombs[MAX_THROWN_BOMBS];
static int ThrownBombDelay = 0; static int ThrownBombDelay = 0;
static int CurrentBomb = 0; static int CurrentBomb = 0;
static int gWantFlash = 0; static int gWantFlash = 0;
@ -71,7 +72,7 @@ void InitThrownBombs(void)
{ {
int i; int i;
for (i = 0; i < 5; i++) for (i = 0; i < MAX_THROWN_BOMBS; i++)
ThrownBombs[i].flags = 0; ThrownBombs[i].flags = 0;
ThrownBombDelay = Random2(0) % 45 + 8; ThrownBombDelay = Random2(0) % 45 + 8;
@ -153,7 +154,7 @@ void HandleThrownBombs(void)
ThrownBombDelay = Random2(0) % 45 + 8; ThrownBombDelay = Random2(0) % 45 + 8;
bomb = &ThrownBombs[CurrentBomb++]; bomb = &ThrownBombs[CurrentBomb++];
CurrentBomb = CurrentBomb % 5; CurrentBomb = CurrentBomb % MAX_THROWN_BOMBS;
bomb->flags = 1; bomb->flags = 1;
bomb->active = 1; bomb->active = 1;
@ -182,7 +183,7 @@ void HandleThrownBombs(void)
bomb = ThrownBombs; bomb = ThrownBombs;
i = 0; i = 0;
while (i < 5) while (i < MAX_THROWN_BOMBS)
{ {
if ((bomb->flags & 1) != 0) if ((bomb->flags & 1) != 0)
{ {
@ -303,7 +304,7 @@ void DrawThrownBombs(void)
bomb = ThrownBombs; bomb = ThrownBombs;
i = 0; i = 0;
while (i < 5) while (i < MAX_THROWN_BOMBS)
{ {
if ((bomb->flags & 1) != 0) if ((bomb->flags & 1) != 0)
{ {
@ -406,7 +407,7 @@ void BombThePlayerToHellAndBack(int car)
gBombTargetVehicle = &car_data[(car + 1) % maxCivCars]; gBombTargetVehicle = &car_data[(car + 1) % maxCivCars];
bomb = &ThrownBombs[CurrentBomb++]; bomb = &ThrownBombs[CurrentBomb++];
CurrentBomb = CurrentBomb % 5; CurrentBomb = CurrentBomb % MAX_THROWN_BOMBS;
bomb->flags = 1; bomb->flags = 1;
bomb->active = 1; bomb->active = 1;
@ -420,7 +421,7 @@ void BombThePlayerToHellAndBack(int car)
bomb->velocity.vz = 0; bomb->velocity.vz = 0;
bomb = &ThrownBombs[CurrentBomb++]; bomb = &ThrownBombs[CurrentBomb++];
CurrentBomb = CurrentBomb % 5; CurrentBomb = CurrentBomb % MAX_THROWN_BOMBS;
bomb->flags = 1; bomb->flags = 1;
bomb->active = 1; bomb->active = 1;
@ -434,7 +435,7 @@ void BombThePlayerToHellAndBack(int car)
bomb->velocity.vz = 0; bomb->velocity.vz = 0;
bomb = &ThrownBombs[CurrentBomb++]; bomb = &ThrownBombs[CurrentBomb++];
CurrentBomb = CurrentBomb % 5; CurrentBomb = CurrentBomb % MAX_THROWN_BOMBS;
bomb->flags = 1; bomb->flags = 1;
bomb->active = 1; bomb->active = 1;
@ -769,13 +770,13 @@ void ExplosionCollisionCheck(_CAR_DATA *cp, _ExOBJECT *pE)
pointVel[1] = denom * (collisionResult.surfNormal.vy >> 6); pointVel[1] = denom * (collisionResult.surfNormal.vy >> 6);
pointVel[2] = denom * (collisionResult.surfNormal.vz >> 6); pointVel[2] = denom * (collisionResult.surfNormal.vz >> 6);
cp->st.n.linearVelocity[0] = cp->st.n.linearVelocity[0] + pointVel[0]; cp->st.n.linearVelocity[0] += pointVel[0];
cp->st.n.linearVelocity[1] = cp->st.n.linearVelocity[1] + pointVel[1]; cp->st.n.linearVelocity[1] += pointVel[1];
cp->st.n.linearVelocity[2] = cp->st.n.linearVelocity[2] + pointVel[2]; cp->st.n.linearVelocity[2] += pointVel[2];
cp->hd.aacc[0] = (cp->hd.aacc[0] + FIXEDH(lever[1] * pointVel[2])) - FIXEDH(lever[2] * pointVel[1]); cp->hd.aacc[0] += FIXEDH(lever[1] * pointVel[2]) - FIXEDH(lever[2] * pointVel[1]);
cp->hd.aacc[1] = (cp->hd.aacc[1] + FIXEDH(lever[2] * pointVel[0])) - FIXEDH(lever[0] * pointVel[2]); cp->hd.aacc[1] += FIXEDH(lever[2] * pointVel[0]) - FIXEDH(lever[0] * pointVel[2]);
cp->hd.aacc[2] = (cp->hd.aacc[2] + FIXEDH(lever[0] * pointVel[1])) - FIXEDH(lever[1] * pointVel[0]); cp->hd.aacc[2] += FIXEDH(lever[0] * pointVel[1]) - FIXEDH(lever[1] * pointVel[0]);
} }
} }

View File

@ -2,7 +2,6 @@
#define BOMBERMAN_H #define BOMBERMAN_H
extern MODEL* gBombModel; extern MODEL* gBombModel;
extern _ExOBJECT explosion[5];
extern _CAR_DATA *gBombTargetVehicle; extern _CAR_DATA *gBombTargetVehicle;
extern void InitThrownBombs(); // 0x0001F570 extern void InitThrownBombs(); // 0x0001F570

View File

@ -630,8 +630,8 @@ void TurnHead(_PLAYER *lp)
// End Line: 1744 // End Line: 1744
int maxCameraDist; int maxCameraDist;
short gCameraDistance = 0x3e8; short gCameraDistance = 1000;
short gCameraMaxDistance = 0x3e8; short gCameraMaxDistance = 1000;
_CAR_DATA *jcam = NULL; _CAR_DATA *jcam = NULL;
int switch_detail_distance = 10000; int switch_detail_distance = 10000;
@ -649,13 +649,11 @@ void PlaceCameraFollowCar(_PLAYER *lp)
int cammapht; int cammapht;
int camPosVy; int camPosVy;
if (lp->cameraCarId < 0) maxCameraDist = 850;
{ carheight = -220;
maxCameraDist = 850; camExpandSpeed = 10;
carheight = -220;
camExpandSpeed = 10; if (lp->cameraCarId >= 0)
}
else
{ {
_CAR_DATA* camCar; _CAR_DATA* camCar;
int carSpeed; int carSpeed;
@ -665,7 +663,7 @@ void PlaceCameraFollowCar(_PLAYER *lp)
if(car_cos) if(car_cos)
{ {
carheight = car_cos->colBox.vy * -3 + 0x55; carheight = car_cos->colBox.vy * -3 + 85;
maxCameraDist = car_cos->colBox.vz * 2 + car_cos->colBox.vy + 248; maxCameraDist = car_cos->colBox.vz * 2 + car_cos->colBox.vy + 248;
carSpeed = FIXEDH(camCar->hd.wheel_speed); carSpeed = FIXEDH(camCar->hd.wheel_speed);
@ -673,17 +671,9 @@ void PlaceCameraFollowCar(_PLAYER *lp)
if (carSpeed < 0) if (carSpeed < 0)
carSpeed = -carSpeed; carSpeed = -carSpeed;
camExpandSpeed = 10;
if (carSpeed > 9 && (gCameraDistance + 30 <= maxCameraDist)) if (carSpeed > 9 && (gCameraDistance + 30 <= maxCameraDist))
camExpandSpeed = 20; camExpandSpeed = 20;
} }
else
{
maxCameraDist = 850;
carheight = -220;
camExpandSpeed = 10;
}
} }
if (pauseflag == 0) if (pauseflag == 0)
@ -700,7 +690,7 @@ void PlaceCameraFollowCar(_PLAYER *lp)
} }
else else
{ {
angleDelta = (((baseDir + gCameraAngle) - lp->cameraAngle) + 0x800U & 0xfff) - 0x800; angleDelta = (((baseDir + gCameraAngle) - lp->cameraAngle) + 2048U & 0xfff) - 2048;
lp->cameraAngle += (angleDelta >> 3) & 0xfff; lp->cameraAngle += (angleDelta >> 3) & 0xfff;
} }
} }
@ -738,9 +728,7 @@ void PlaceCameraFollowCar(_PLAYER *lp)
gCameraDistance = maxCameraDist; gCameraDistance = maxCameraDist;
if (lp->cameraCarId < 0) if (lp->cameraCarId >= 0)
jcam->ap.carCos = &dummyCosmetics;
else
jcam->ap.carCos = car_data[lp->cameraCarId].ap.carCos; jcam->ap.carCos = car_data[lp->cameraCarId].ap.carCos;
jcam->hd.direction = camAngle; jcam->hd.direction = camAngle;
@ -748,9 +736,9 @@ void PlaceCameraFollowCar(_PLAYER *lp)
sdist = maxCameraDist * rcossin_tbl[camAngle * 2] + 0x800; sdist = maxCameraDist * rcossin_tbl[camAngle * 2] + 0x800;
cdist = maxCameraDist * rcossin_tbl[camAngle * 2 + 1] + 0x800; cdist = maxCameraDist * rcossin_tbl[camAngle * 2 + 1] + 0x800;
jcam->hd.oBox.location.vx = jcam->hd.where.t[0] = basePos[0] + ((sdist >> 0xc) - (sdist >> 0x1f) >> 1); jcam->hd.oBox.location.vx = jcam->hd.where.t[0] = basePos[0] + (sdist >> 13);
jcam->hd.oBox.location.vy = jcam->hd.where.t[1] = -lp->cameraPos.vy; jcam->hd.oBox.location.vy = jcam->hd.where.t[1] = -lp->cameraPos.vy;
jcam->hd.oBox.location.vz = jcam->hd.where.t[2] = basePos[2] + ((cdist >> 0xc) - (cdist >> 0x1f) >> 1); jcam->hd.oBox.location.vz = jcam->hd.where.t[2] = basePos[2] + (cdist >> 13);
CheckScenaryCollisions(jcam); CheckScenaryCollisions(jcam);
@ -759,17 +747,19 @@ void PlaceCameraFollowCar(_PLAYER *lp)
if (lp->cameraDist > gCameraDistance) if (lp->cameraDist > gCameraDistance)
lp->cameraDist = gCameraDistance; lp->cameraDist = gCameraDistance;
jcam->hd.direction = jcam->hd.direction & 0xfff;
lp->cameraPos.vy = -jcam->hd.where.t[1]; lp->cameraPos.vy = -jcam->hd.where.t[1];
lp->cameraPos.vx = basePos[0] + FIXEDH(lp->cameraDist * rcossin_tbl[jcam->hd.direction * 2]); lp->cameraPos.vx = basePos[0] + FIXEDH(lp->cameraDist * rcossin_tbl[(jcam->hd.direction & 0xfff) * 2]);
lp->cameraPos.vz = basePos[2] + FIXEDH(lp->cameraDist * rcossin_tbl[jcam->hd.direction * 2 + 1]); lp->cameraPos.vz = basePos[2] + FIXEDH(lp->cameraDist * rcossin_tbl[(jcam->hd.direction & 0xfff) * 2 + 1]);
camera_angle.vy = -ratan2(basePos[0] - lp->cameraPos.vx, basePos[2] - lp->cameraPos.vz) & 0xfff; if (lp->cameraCarId < 0)
camera_angle.vy = -(jcam->hd.direction + 2048);
else
camera_angle.vy = -ratan2(basePos[0] - lp->cameraPos.vx, basePos[2] - lp->cameraPos.vz) & 0xfff;
camera_angle.vz = 0; camera_angle.vz = 0;
SetGeomScreen(0x100); SetGeomScreen(256);
scr_z = 0x100; scr_z = 256;
switch_detail_distance = 10000; switch_detail_distance = 10000;
BuildWorldMatrix(); BuildWorldMatrix();
@ -996,7 +986,7 @@ void PlaceCameraInCar(_PLAYER *lp, int BumperCam)
{ {
ClearMem((char *)&inv_camera_matrix, sizeof(MATRIX)); ClearMem((char *)&inv_camera_matrix, sizeof(MATRIX));
angle = 0x800U - baseDir & 0xfff; angle = 2048U - baseDir & 0xfff;
inv_camera_matrix.m[0][0] = rcossin_tbl[angle * 2 + 1]; inv_camera_matrix.m[0][0] = rcossin_tbl[angle * 2 + 1];
inv_camera_matrix.m[0][2] = rcossin_tbl[angle * 2]; inv_camera_matrix.m[0][2] = rcossin_tbl[angle * 2];

View File

@ -23,6 +23,11 @@
#include "INLINE_C.H" #include "INLINE_C.H"
#include "LIBAPI.H" #include "LIBAPI.H"
#ifndef PSX
const int CAR_LOD_SWITCH_DISTANCE = 12500;
#else
const int CAR_LOD_SWITCH_DISTANCE = 5500;
#endif
MATRIX light_matrix = MATRIX light_matrix =
{ { { 4096, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, { 0, 0, 0 } }; { { { 4096, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, { 0, 0, 0 } };
@ -862,7 +867,7 @@ void DrawCar(_CAR_DATA *cp, int view)
} }
// LOD switching // LOD switching
if (pos.vz < 5501 && gForceLowDetailCars == 0 || cp->controlType == CONTROL_TYPE_PLAYER) if (pos.vz <= CAR_LOD_SWITCH_DISTANCE && gForceLowDetailCars == 0 || cp->controlType == CONTROL_TYPE_PLAYER)
{ {
int blackSmoke = 0; int blackSmoke = 0;

View File

@ -24,6 +24,7 @@
#include "OBJCOLL.H" #include "OBJCOLL.H"
#include "INLINE_C.H" #include "INLINE_C.H"
#include "OVERLAY.H"
unsigned char speedLimits[3] = { 56, 97, 138 }; unsigned char speedLimits[3] = { 56, 97, 138 };
@ -61,8 +62,15 @@ int test555 = 0;
#define GET_NODE_ID(cp, node) int((node) - cp->ai.c.targetRoute) #define GET_NODE_ID(cp, node) int((node) - cp->ai.c.targetRoute)
#ifdef _DEBUG
#define CIV_STATE_SET_CONFUSED(cp) \
printInfo("CIV confused: at %s, %d\n", __FUNCTION__, __LINE__);\
cp->ai.c.thrustState = 3; cp->ai.c.ctrlState = 7;
#else
#define CIV_STATE_SET_CONFUSED(cp) \ #define CIV_STATE_SET_CONFUSED(cp) \
cp->ai.c.thrustState = 3; cp->ai.c.ctrlState = 7; cp->ai.c.thrustState = 3; cp->ai.c.ctrlState = 7;
#endif
// decompiled code // decompiled code
// original method signature: // original method signature:
@ -534,15 +542,6 @@ void CivCarFX(_CAR_DATA* cp)
/* WARNING: Type propagation algorithm not settling */ /* WARNING: Type propagation algorithm not settling */
int currentRoadId = 0;
int tmpNewRoad[2];
int newExit = 0;
int tmpNewLane[2];
int laneFit[2];
DRIVER2_STRAIGHT* tmpStr[2];
DRIVER2_CURVE* tmpCrv[2];
short validExitIdx[4];
// [D] [T] // [D] [T]
// BUGS: sometimes not getting right lane when road direction switched // BUGS: sometimes not getting right lane when road direction switched
int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist, CIV_ROUTE_ENTRY* oldNode) int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist, CIV_ROUTE_ENTRY* oldNode)
@ -550,8 +549,18 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
unsigned long junctionFlags; unsigned long junctionFlags;
DRIVER2_JUNCTION* jn; DRIVER2_JUNCTION* jn;
DRIVER2_ROAD_INFO currentRoadInfo;
DRIVER2_ROAD_INFO roadInfo; DRIVER2_ROAD_INFO roadInfo;
int currentRoadId = 0;
int tmpNewRoad[2];
int newExit = 0;
int tmpNewLane[2];
int laneFit[2];
DRIVER2_STRAIGHT* tmpStr[2];
DRIVER2_CURVE* tmpCrv[2];
short validExitIdx[4];
int newLane; int newLane;
int newRoad; int newRoad;
@ -562,15 +571,12 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
int oldOppDir; int oldOppDir;
int oppDir; int oppDir;
int turnDir; int turnDir;
int currentLaneDir;
currentRoadId = cp->ai.c.currentRoad; currentRoadId = cp->ai.c.currentRoad;
//straight = NULL;
//curve = NULL;
if (GetSurfaceRoadInfo(&roadInfo, currentRoadId)) if (GetSurfaceRoadInfo(&currentRoadInfo, currentRoadId))
{ {
int currentLaneDir;
int widthInLanes; int widthInLanes;
int laneNo; int laneNo;
int count; int count;
@ -578,27 +584,29 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
junctionIdx = -1; junctionIdx = -1;
widthInLanes = ROAD_WIDTH_IN_LANES(&roadInfo); widthInLanes = ROAD_WIDTH_IN_LANES(&currentRoadInfo);
currentLaneDir = ROAD_LANE_DIR(&roadInfo, cp->ai.c.currentLane); currentLaneDir = ROAD_LANE_DIR(&currentRoadInfo, cp->ai.c.currentLane);
oldOppDir = currentLaneDir << 0xb;
tmpNewRoad[0] = ((short*)roadInfo.ConnectIdx)[currentLaneDir * 2]; if (currentRoadInfo.straight)
if (currentLaneDir != 0)
tmpNewRoad[1] = ((short*)roadInfo.ConnectIdx)[3];
else
tmpNewRoad[1] = ((short*)roadInfo.ConnectIdx)[1];
/*
// [A] strict check for junction first
if (!IS_JUNCTION_SURFACE(tmpNewRoad[0]) && IS_JUNCTION_SURFACE(_st->ConnectIdx[currentLaneDir * 2 - 1]))
{ {
junctionIdx = _st->ConnectIdx[currentLaneDir * 2 - 1]; oldOppDir = (currentRoadInfo.straight->angle - oldNode->dir) + 0x400U & 0x800;
}
else
{
int dx, dz;
dx = oldNode->x - currentRoadInfo.curve->Midx;
dz = oldNode->z - currentRoadInfo.curve->Midz;
if (junctionIdx != -1 && tmpNewRoad[0] != junctionIdx) oldOppDir = (((oldNode->dir - ratan2(dx, dz)) + 0x800U & 0xfff) - 0x800);
tmpNewRoad[0] = junctionIdx; oldOppDir = (oldOppDir < 1) << 0xb;
}*/ }
// first road is picked from road direction
tmpNewRoad[0] = ((short*)currentRoadInfo.ConnectIdx)[(oldOppDir > 0) * 2];
// and second picked from lane direction
tmpNewRoad[1] = ((short*)currentRoadInfo.ConnectIdx)[(currentLaneDir > 0) ? 3 : 1];
count = widthInLanes; // counter count = widthInLanes; // counter
laneNo = widthInLanes; // bestLane laneNo = widthInLanes; // bestLane
@ -606,9 +614,9 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
do do
{ {
count--; count--;
if (ROAD_IS_AI_LANE(&roadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, count)) if (ROAD_IS_AI_LANE(&currentRoadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(&currentRoadInfo, count))
{ {
test42 = ROAD_LANE_DIR(&roadInfo, count); test42 = ROAD_LANE_DIR(&currentRoadInfo, count);
laneNo = count; laneNo = count;
} }
} while (count >= 0); } while (count >= 0);
@ -618,15 +626,15 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
else else
rightLane = laneNo & 0xff; rightLane = laneNo & 0xff;
// if speed lane, use other first lane. WTF idk why // ifhas fast lane, use second lane
count = ROAD_HAS_FAST_LANES(&roadInfo); // counter count = ROAD_HAS_FAST_LANES(&currentRoadInfo);
laneNo = widthInLanes; // bestLane laneNo = widthInLanes;
while (count < widthInLanes) while (count < widthInLanes)
{ {
if (ROAD_IS_AI_LANE(&roadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, count)) if (ROAD_IS_AI_LANE(&currentRoadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(&currentRoadInfo, count))
{ {
test555 = ROAD_LANE_DIR(&roadInfo, count) ^ 1; test555 = ROAD_LANE_DIR(&currentRoadInfo, count) ^ 1;
laneNo = count; laneNo = count;
if (test555 == 0) if (test555 == 0)
@ -728,7 +736,7 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
if(roadInfo.straight) if(roadInfo.straight)
{ {
oppDir = (turnDir - roadInfo.straight->angle) + 1024U & 0x800; oppDir = (roadInfo.straight->angle - turnDir) + 1024U & 0x800;
} }
else else
{ {
@ -747,16 +755,9 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
if (turnAng == 0) // going forward if (turnAng == 0) // going forward
{ {
if (oppDir != oldOppDir) // next road is flipped if (oppDir != oldOppDir) // next road is flipped
{
newLane = ROAD_WIDTH_IN_LANES(&roadInfo) - (cp->ai.c.currentLane + 1); newLane = ROAD_WIDTH_IN_LANES(&roadInfo) - (cp->ai.c.currentLane + 1);
//if (newLane == 0) // [A] temporary hack
// newLane++;
}
else else
{
newLane = cp->ai.c.currentLane; newLane = cp->ai.c.currentLane;
}
// goes on invalid lane? // goes on invalid lane?
// [A] bug fix with exitDir == 0 // [A] bug fix with exitDir == 0
@ -818,11 +819,7 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
if (newLane > -1 && newLane < laneCount) if (newLane > -1 && newLane < laneCount)
{ {
valid = ROAD_IS_AI_LANE(&roadInfo, newLane) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, newLane); valid = ROAD_IS_AI_LANE(&roadInfo, newLane) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, newLane);
//printInfo("Valid exit: %d, dir: %d vs %d, turnDir: %d, oppDir: %d (%d), turnAng: %d\n", exitIdx, tmpSt->angle, oldNode->dir, turnDir, oppDir, (turnDir - tmpSt->angle) + 1024, turnAng);
} }
//printInfo("car %d check %s, valid: %d\n", cp->id, (turnAng == 1024) ? "right" : (turnAng == -1024 ? "left" : "forward"), valid);
} }
} }
@ -996,7 +993,7 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
} }
else else
{ {
newLane = numLanes - cp->ai.c.currentLane + 1; newLane = numLanes - (cp->ai.c.currentLane + 1);
//if (newLane == 0)// [A] temporary hack //if (newLane == 0)// [A] temporary hack
// newLane++; // newLane++;
@ -1099,6 +1096,7 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
} }
else else
{ {
// road continuation using connections
int roadCnt; int roadCnt;
if (turnAngle == NULL) if (turnAngle == NULL)
@ -1110,15 +1108,11 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
*turnAngle = 0; *turnAngle = 0;
newExit = -1; newExit = -1;
roadCnt = 0; // check the connections
// determine new lanes on possible new roads based on the old node position
for (roadCnt = 0; roadCnt < 2; roadCnt++) for (roadCnt = 0; roadCnt < 2; roadCnt++)
{ {
if (tmpNewRoad[roadCnt] == -1) if (tmpNewRoad[roadCnt] != -1)
{
laneFit[roadCnt] = 666;
}
else
{ {
int dx, dz; int dx, dz;
int numLanes; int numLanes;
@ -1128,7 +1122,8 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
if (GetSurfaceRoadInfo(&roadInfo, tmpNewRoad[roadCnt])) if (GetSurfaceRoadInfo(&roadInfo, tmpNewRoad[roadCnt]))
{ {
numLanes = ROAD_WIDTH_IN_LANES(&roadInfo); numLanes = ROAD_WIDTH_IN_LANES(&roadInfo);
// determine new lane by old node position
if(roadInfo.straight) if(roadInfo.straight)
{ {
int laneNo; int laneNo;
@ -1137,11 +1132,13 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
dx = (oldNode->x - roadInfo.straight->Midx); dx = (oldNode->x - roadInfo.straight->Midx);
dz = (oldNode->z - roadInfo.straight->Midz); dz = (oldNode->z - roadInfo.straight->Midz);
test555 = dx * rcossin_tbl[(roadInfo.straight->angle & 0xfff) * 2 + 1] - dz * rcossin_tbl[(roadInfo.straight->angle & 0xfff) * 2]; //test555 = dx * rcossin_tbl[(roadInfo.straight->angle & 0xfff) * 2 + 1] - dz * rcossin_tbl[(roadInfo.straight->angle & 0xfff) * 2];
test42 = ROAD_LANES_COUNT(&roadInfo) - (FIXEDH(test555) + 512 >> 9); //test42 = ROAD_LANES_COUNT(&roadInfo) - (FIXEDH(test555) + 512 >> 9);
tmpStr[roadCnt] = roadInfo.straight; tmpStr[roadCnt] = roadInfo.straight;
tmpNewLane[roadCnt] = test42; tmpNewLane[roadCnt] = ROAD_LANES_COUNT(&roadInfo) - (FIXEDH(dx * rcossin_tbl[(roadInfo.straight->angle & 0xfff) * 2 + 1] - dz * rcossin_tbl[(roadInfo.straight->angle & 0xfff) * 2]) + 512 >> 9);
// [A] I don't think that is needed
count = numLanes; count = numLanes;
laneNo = numLanes; laneNo = numLanes;
@ -1149,20 +1146,19 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
{ {
if (ROAD_IS_AI_LANE(&roadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, count)) if (ROAD_IS_AI_LANE(&roadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, count))
{ {
// this line below needed because fucking compiler seem to be omitting it completely
test42 = (ROAD_LANE_DIR(&roadInfo, count) ^ 1) & 1; test42 = (ROAD_LANE_DIR(&roadInfo, count) ^ 1) & 1;
laneNo = count; laneNo = count;
} }
count--; count--;
} while (count >= 0); } while (count >= 0);
//if (laneNo == 0) // [A] temporary dirty hack. Still needed here, idk why if (laneNo < 0 || laneNo >= numLanes)
// laneNo++;
if (laneNo < 0 || laneNo >= numLanes) // [A] and here. Was laneNo > numLanes
{ {
laneFit[roadCnt] = 666; laneFit[roadCnt] = 666;
continue; continue;
} }
} }
else else
{ {
@ -1174,22 +1170,29 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
} }
} }
test123 = tmpNewLane[roadCnt]; // fit new lane
newLane = tmpNewLane[roadCnt];
if (test123 < 0) if (newLane < 0)
laneFit[roadCnt] = test123; laneFit[roadCnt] = newLane;
else if (test123 <= numLanes - 1) else if (newLane <= numLanes - 1)
laneFit[roadCnt] = 0; laneFit[roadCnt] = 0;
else else
laneFit[roadCnt] = test123 - numLanes - 1; laneFit[roadCnt] = newLane - numLanes - 1;
// clamp lane
if (tmpNewLane[roadCnt] >= numLanes - 1) if (tmpNewLane[roadCnt] >= numLanes - 1)
tmpNewLane[roadCnt] = numLanes - 1; tmpNewLane[roadCnt] = numLanes - 1;
newExit = roadCnt;
if (tmpNewLane[roadCnt] < 0) if (tmpNewLane[roadCnt] < 0)
tmpNewLane[roadCnt] = 0; tmpNewLane[roadCnt] = 0;
// set this a s correct exit
newExit = roadCnt;
}
else
{
laneFit[roadCnt] = 666;
} }
} }
@ -1219,8 +1222,7 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
if(roadInfo.straight) if(roadInfo.straight)
{ {
oppDir = (oldNode->dir - roadInfo.straight->angle) + 0x400U & 0x800; oppDir = (oldNode->dir - roadInfo.straight->angle) + 0x400U & 0x800 > 0;
test123 = oppDir;
} }
else else
{ {
@ -1231,11 +1233,13 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
oppDir = (((oldNode->dir - ratan2(dx, dz)) + 0x800U & 0xfff) - 0x800) < 1; oppDir = (((oldNode->dir - ratan2(dx, dz)) + 0x800U & 0xfff) - 0x800) < 1;
} }
if (laneDirCorrect && oppDir == 0 || !laneDirCorrect && oppDir != 0) // road width might be changed too, so we have to clamp it
if (laneDirCorrect != oppDir) // && ROAD_WIDTH_IN_LANES(&currentRoadInfo) != numLanes)
{ {
// find drivable leftmost and rightmost lane
laneFromLeft = numLanes; laneFromLeft = numLanes;
laneFromRight = 0; laneFromRight = -1;
count = numLanes; count = numLanes;
do do
@ -1284,7 +1288,7 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
if (laneFromLeft < 0) if (laneFromLeft < 0)
laneFromLeft = 42; laneFromLeft = 42;
if (laneFromRight >= numLanes) if (laneFromRight >= numLanes)
laneFromRight = 42; laneFromRight = 42;
@ -1294,12 +1298,15 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
return 0; return 0;
} }
// swap
// [A] this is bugged still if (ABS(laneFromRight - newLane) >= ABS(laneFromLeft - newLane))
if (ABS(laneFromRight - newLane) < ABS(laneFromLeft - newLane)) {
int tmp = laneFromRight;
laneFromRight = laneFromLeft; laneFromRight = laneFromLeft;
laneFromLeft = tmp;
}
/*
// it doesn't work well
laneFit[newExit] = laneFromRight; laneFit[newExit] = laneFromRight;
if (laneFromRight > -1) if (laneFromRight > -1)
@ -1310,8 +1317,10 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
laneFit[newExit] = 0; laneFit[newExit] = 0;
} }
// [A] IDK... this is bugged. Might get back to it any time
int oldLane = newLane; int oldLane = newLane;
if (laneFromRight >= numLanes - 1) if (laneFromRight >= numLanes - 1)
newLane = numLanes - 1; newLane = numLanes - 1;
//else //else
@ -1319,25 +1328,15 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
if (newLane < 0) if (newLane < 0)
newLane = 0; newLane = 0;
*/
} }
} }
if (laneFit[newExit] != 0) if (laneFit[newExit] != 0)
{ {
cp->ai.c.turnNode = GET_NODE_ID(cp, GET_NEXT_NODE(cp, oldNode)); cp->ai.c.turnNode = GET_NODE_ID(cp, GET_NEXT_NODE(cp, oldNode));
cp->ai.c.turnDir = ROAD_LANE_DIR(&roadInfo, laneFit[newExit]);
if (IS_STRAIGHT_SURFACE(newRoad))
{
cp->ai.c.turnDir = (ROAD_LANE_DIR(tmpStr[newExit], laneFit[newExit]) ^ 1) & 1;
}
else
{
cp->ai.c.turnDir = (ROAD_LANE_DIR(tmpCrv[newExit], laneFit[newExit]) ^ 1) & 1;
}
//printWarning("new turn dir: %d\n", cp->ai.c.turnDir);
//cp->ai.c.turnDir = bVar6;
} }
} }
} }
@ -1351,9 +1350,6 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
// determine distance and speed limit // determine distance and speed limit
if (startDist != NULL) if (startDist != NULL)
{ {
//DRIVER2_CURVE* curve;
//DRIVER2_STRAIGHT* straight;
if (GetSurfaceRoadInfo(&roadInfo, newRoad)) if (GetSurfaceRoadInfo(&roadInfo, newRoad))
{ {
if(roadInfo.straight) if(roadInfo.straight)
@ -1375,14 +1371,15 @@ int GetNextRoadInfo(_CAR_DATA* cp, int randomExit, int* turnAngle, int* startDis
} }
} }
if (newRoad < 0)
{
CIV_STATE_SET_CONFUSED(cp);
return 0;
}
cp->ai.c.currentLane = newLane; cp->ai.c.currentLane = newLane;
if (newRoad > -1) return newRoad;
return newRoad;
CIV_STATE_SET_CONFUSED(cp);
return 0;
} }
@ -3861,7 +3858,7 @@ int PingInCivCar(int minPingInDist)
carCnt++; carCnt++;
} }
if (retDistSq != 56) // [A] This was decompiled wrong. Can't get the meaning for it //if (retDistSq != 56) // [A] This was decompiled wrong. Can't get the meaning for it
distSq = retDistSq; distSq = retDistSq;
if (distSq < (lbody * lbody * 8 * 8)) if (distSq < (lbody * lbody * 8 * 8))
@ -4106,10 +4103,7 @@ int CivControl(_CAR_DATA * cp)
Debug_AddLineOfs(_zero, ofs, b1p, rrcv); Debug_AddLineOfs(_zero, ofs, b1p, rrcv);
} }
pn++; pn = GET_NEXT_NODE(cp, pn);
if (pn > cp->ai.c.targetRoute + 13)
pn -= 12;
} }
} }
@ -4816,8 +4810,8 @@ void SetUpCivCollFlags(void)
// do horns // do horns
// horn to player and chased cars (except Steal the Ambulance) // horn to player and chased cars (except Steal the Ambulance)
if (cp0->ai.c.thrustState != 3 && if (cp0->ai.c.thrustState != 3 &&
(cp1->controlType == CONTROL_TYPE_PLAYER || (cp1->controlType == CONTROL_TYPE_CUTSCENE && gCurrentMissionNumber != 26) || (cp1->controlType == CONTROL_TYPE_PLAYER || cp1->controlType == CONTROL_TYPE_CUTSCENE && gCurrentMissionNumber != 26 && ProxyBar.active == 0 ||
CAR_INDEX(cp1) == 20)) CAR_INDEX(cp1) == 20))
{ {
int dont; int dont;
int rnd; int rnd;
@ -6008,15 +6002,14 @@ void CreateRoadblock(void)
GetNodePos(str, NULL, crv, distAlongSegment, NULL, (int*)&startPos.vx, (int*)&startPos.vz, 0); GetNodePos(str, NULL, crv, distAlongSegment, NULL, (int*)&startPos.vx, (int*)&startPos.vz, 0);
laneNo = numLanes - 1; GetNodePos(str, NULL, crv, distAlongSegment, NULL, (int*)&endPos, (int*)&endPos.vz, numLanes - 1);
GetNodePos(str, NULL, crv, distAlongSegment, NULL, (int*)&endPos, (int*)&endPos.vz, laneNo);
dir2NextRow = ratan2(endPos.vx - startPos.vx, endPos.vz - startPos.vz); dir2NextRow = ratan2(endPos.vx - startPos.vx, endPos.vz - startPos.vz);
delta = 256; delta = 256;
while (delta < (numLanes-1) * 512) while (delta < numLanes * 512)
{ {
laneNo = (delta >> 10); laneNo = (delta >> 9);
currentPos.vx = startPos.vx + FIXEDH(delta * rcossin_tbl[(dir2NextRow & 0xfff) * 2]); currentPos.vx = startPos.vx + FIXEDH(delta * rcossin_tbl[(dir2NextRow & 0xfff) * 2]);
currentPos.vz = startPos.vz + FIXEDH(delta * rcossin_tbl[(dir2NextRow & 0xfff) * 2 + 1]); currentPos.vz = startPos.vz + FIXEDH(delta * rcossin_tbl[(dir2NextRow & 0xfff) * 2 + 1]);
@ -6024,7 +6017,7 @@ void CreateRoadblock(void)
if((str && ROAD_IS_AI_LANE(str, laneNo) || crv && ROAD_IS_AI_LANE(crv, laneNo)) && if((str && ROAD_IS_AI_LANE(str, laneNo) || crv && ROAD_IS_AI_LANE(crv, laneNo)) &&
CellEmpty(&currentPos, lbody)) CellEmpty(&currentPos, lbody))
{ {
newSlot = CreateStationaryCivCar(dir2NextRow + (Random2(0) * 0x10001 >> (delta >> 9 & 0x1fU) & 0x3ffU) - 512, 0, 0, (long(*)[4]) & currentPos, externalCopModel, 0, 2); newSlot = CreateStationaryCivCar(dir2NextRow + (Random2(0) * 0x10001 >> (laneNo) & 0x3ffU) - 512, 0, 0, (long(*)[4]) & currentPos, externalCopModel, 0, 2);
if (newSlot == -1) if (newSlot == -1)
break; break;

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,9 @@ char* CosmeticFiles[] = {
}; };
CAR_COSMETICS car_cosmetics[MAX_CAR_MODELS]; CAR_COSMETICS car_cosmetics[MAX_CAR_MODELS];
CAR_COSMETICS dummyCosmetics = { 0 };
// [A] temporary hardcoded bug fix
CAR_COSMETICS gVegasLimoCosmetic;
// decompiled code // decompiled code
// original method signature: // original method signature:
@ -130,6 +132,17 @@ void ProcessCosmeticsLump(char *lump_ptr, int lump_size)
i++; i++;
} while (i < MAX_CAR_MODELS); } while (i < MAX_CAR_MODELS);
// [A] fix vegas limo cosmetic bug in advance
if(GameLevel == 2)
{
offset = *(int*)(lump_ptr + 8 * 4);
ptr = (lump_ptr + offset);
memcpy(&gVegasLimoCosmetic, ptr, sizeof(CAR_COSMETICS));
FixCarCos(&gVegasLimoCosmetic, model);
}
} }
@ -229,6 +242,12 @@ void AddReverseLight(_CAR_DATA *cp)
void SetupSpecCosmetics(char *loadbuffer) void SetupSpecCosmetics(char *loadbuffer)
{ {
// [A] this is better // [A] this is better
if(GameLevel == 2 && MissionHeader->residentModels[4] == 8)
{
memcpy(&car_cosmetics[4], &gVegasLimoCosmetic, sizeof(CAR_COSMETICS));
return;
}
memcpy(&car_cosmetics[4], loadbuffer, sizeof(CAR_COSMETICS)); memcpy(&car_cosmetics[4], loadbuffer, sizeof(CAR_COSMETICS));
} }

View File

@ -54,6 +54,10 @@ PLAYBACKCAMERA *CutsceneCamera = NULL;
static int CutsceneCameraOffset = 0; static int CutsceneCameraOffset = 0;
#ifndef PSX
char* gCustomCutsceneBuffer;
#endif
// decompiled code // decompiled code
// original method signature: // original method signature:
// void /*$ra*/ InitInGameCutsceneVariables() // void /*$ra*/ InitInGameCutsceneVariables()
@ -242,6 +246,10 @@ void DrawInGameCutscene(void)
{ {
TILE *tile; TILE *tile;
#ifndef PSX
PrintXASubtitles();
#endif
if (gInGameCutsceneActive == 0 && gInGameCutsceneDelay == 0) if (gInGameCutsceneActive == 0 && gInGameCutsceneDelay == 0)
return; return;
@ -1318,6 +1326,20 @@ int LoadCutsceneToBuffer(int subindex)
#ifndef PSX #ifndef PSX
// [A] REDRIVER2 PC - custom cutcenes or chases for debugging // [A] REDRIVER2 PC - custom cutcenes or chases for debugging
sprintf(customFilename, "REPLAYS\\CUT%d\\%d.D2RP", gCurrentMissionNumber, subindex); sprintf(customFilename, "REPLAYS\\CUT%d\\%d.D2RP", gCurrentMissionNumber, subindex);
if (FileExists(customFilename))
{
printInfo("Custom cutscene replay file loaded\n");
size = LoadfileSeg(customFilename, gCustomCutsceneBuffer, 0, 0xffff);
// load into custom buffer
CutsceneBuffer.residentCutscenes[CutsceneBuffer.numResident] = subindex;
CutsceneBuffer.residentPointers[CutsceneBuffer.numResident] = gCustomCutsceneBuffer;
CutsceneBuffer.numResident++;
gCustomCutsceneBuffer += size;
return 1;
}
#endif #endif
if (CutsceneBuffer.bytesFree < size) if (CutsceneBuffer.bytesFree < size)
{ {
@ -1328,27 +1350,11 @@ int LoadCutsceneToBuffer(int subindex)
CutsceneBuffer.currentPointer = _other_buffer2; CutsceneBuffer.currentPointer = _other_buffer2;
CutsceneBuffer.bytesFree = 0xc000; CutsceneBuffer.bytesFree = 0xc000;
#ifndef PSX LoadfileSeg(filename, _other_buffer2, offset, size);
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 else
{ {
#ifndef PSX LoadfileSeg(filename, CutsceneBuffer.currentPointer, offset, size);
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; CutsceneBuffer.residentCutscenes[CutsceneBuffer.numResident] = subindex;
@ -1527,6 +1533,10 @@ void FreeCutsceneBuffer(void)
CutsceneBuffer.bytesFree = sizeof(CutsceneBuffer.buffer); CutsceneBuffer.bytesFree = sizeof(CutsceneBuffer.buffer);
ClearMem(CutsceneBuffer.buffer, sizeof(CutsceneBuffer.buffer)); ClearMem(CutsceneBuffer.buffer, sizeof(CutsceneBuffer.buffer));
#ifndef PSX
gCustomCutsceneBuffer = _other_buffer2;
#endif
} }

File diff suppressed because it is too large Load Diff

View File

@ -137,7 +137,7 @@ int gLoadedReplay = 0;
int gHaveStoredData = 0; int gHaveStoredData = 0;
int gLastChase = 0; int gLastChase = 0;
int gChaseNumber = -1; int gChaseNumber = 0;
int gRandomChase = 0; int gRandomChase = 0;
int gSubGameNumber = 0; int gSubGameNumber = 0;
@ -595,7 +595,7 @@ void RunMissionLadder(int newgame)
void GetRandomChase(void) void GetRandomChase(void)
{ {
// [A] debug // [A] debug
if (gChaseNumber != -1) if (gChaseNumber != 0)
{ {
gRandomChase = gChaseNumber; gRandomChase = gChaseNumber;
return; return;
@ -610,7 +610,7 @@ void GetRandomChase(void)
if (gRandomChase == gLastChase) if (gRandomChase == gLastChase)
{ {
do { do {
gRandomChase = (VSync(-1) + bump) % 0xd + 2; gRandomChase = (VSync(-1) + bump) % 13 + 2;
bump++; bump++;
} while (gRandomChase == gLastChase); } while (gRandomChase == gLastChase);
} }

View File

@ -956,7 +956,7 @@ void GlobalTimeStep(void)
if (c1->controlType == CONTROL_TYPE_PLAYER && IS_ROADBLOCK_CAR(cp)) if (c1->controlType == CONTROL_TYPE_PLAYER && IS_ROADBLOCK_CAR(cp))
{ {
InitCopState(cp, NULL); InitCopState(cp, NULL);
c1->ai.p.justPinged = 0; cp->ai.p.justPinged = 0;
} }
} }
@ -1414,45 +1414,48 @@ void LongQuaternion2Matrix(long(*qua)[4], MATRIX *m)
void initOBox(_CAR_DATA *cp) void initOBox(_CAR_DATA *cp)
{ {
SVECTOR boxDisp; SVECTOR boxDisp;
CAR_COSMETICS* car_cos;
short length; short length;
gte_SetRotMatrix(&cp->hd.where); gte_SetRotMatrix(&cp->hd.where);
gte_SetTransMatrix(&cp->hd.where); gte_SetTransMatrix(&cp->hd.where);
boxDisp.vx = -cp->ap.carCos->cog.vx; car_cos = &car_cosmetics[cp->ap.model];
boxDisp.vy = -cp->ap.carCos->cog.vy;
boxDisp.vz = -cp->ap.carCos->cog.vz; boxDisp.vx = -car_cos->cog.vx;
boxDisp.vy = -car_cos->cog.vy;
boxDisp.vz = -car_cos->cog.vz;
gte_ldv0(&boxDisp); gte_ldv0(&boxDisp);
gte_rtv0tr(); gte_rtv0tr();
if (cp->controlType == CONTROL_TYPE_PURSUER_AI) if (cp->controlType == CONTROL_TYPE_PURSUER_AI)
{ {
length = FixFloorSigned(cp->ap.carCos->colBox.vx * 14, 4); length = FixFloorSigned(car_cos->colBox.vx * 14, 4);
cp->hd.oBox.length[0] = length; cp->hd.oBox.length[0] = length;
} }
else else
{ {
length = cp->ap.carCos->colBox.vx; length = car_cos->colBox.vx;
cp->hd.oBox.length[0] = length; cp->hd.oBox.length[0] = length;
} }
gte_stlvnl(&cp->hd.oBox.location); gte_stlvnl(&cp->hd.oBox.location);
VECTOR svx = { length, 0 ,0 }; VECTOR svx = { length, 0 ,0 };
VECTOR svy = { 0, cp->ap.carCos->colBox.vy ,0 }; VECTOR svy = { 0, car_cos->colBox.vy ,0 };
VECTOR svz = { 0, 0 ,cp->ap.carCos->colBox.vz }; VECTOR svz = { 0, 0 ,car_cos->colBox.vz };
gte_ldlvl(&svx); gte_ldlvl(&svx);
gte_rtir(); gte_rtir();
cp->hd.oBox.length[1] = cp->ap.carCos->colBox.vy; cp->hd.oBox.length[1] = car_cos->colBox.vy;
gte_stsv(&cp->hd.oBox.radii[0]); gte_stsv(&cp->hd.oBox.radii[0]);
gte_ldlvl(&svy); gte_ldlvl(&svy);
gte_rtir(); gte_rtir();
cp->hd.oBox.length[2] = cp->ap.carCos->colBox.vz; cp->hd.oBox.length[2] = car_cos->colBox.vz;
gte_stsv(&cp->hd.oBox.radii[1]); gte_stsv(&cp->hd.oBox.radii[1]);
gte_ldlvl(&svz); gte_ldlvl(&svz);
@ -1990,14 +1993,18 @@ void ProcessCarPad(_CAR_DATA *cp, ulong pad, char PadSteer, char use_analogue)
cp->hd.autoBrake = 90; cp->hd.autoBrake = 90;
// handle burnouts or handbrake // handle burnouts or handbrake
if ((pad & 0x10) == 0) if (pad & 0x10)
{
cp->handbrake = 1;
}
else
{ {
cp->handbrake = 0; cp->handbrake = 0;
if ((pad & 0x20) == 0) if (pad & 0x20)
cp->wheelspin = 0;
else
cp->wheelspin = 1; cp->wheelspin = 1;
else
cp->wheelspin = 0;
// continue without burnout // continue without burnout
if (cp->wheelspin != 0 && cp->hd.wheel_speed > 0x6e958) if (cp->wheelspin != 0 && cp->hd.wheel_speed > 0x6e958)
@ -2006,37 +2013,14 @@ void ProcessCarPad(_CAR_DATA *cp, ulong pad, char PadSteer, char use_analogue)
pad |= 0x40; pad |= 0x40;
} }
} }
else
{
cp->handbrake = 1;
}
// handle steering // handle steering
if (use_analogue == 0) if (use_analogue == 0)
{ {
if ((pad & 4) == 0) if (pad & 0x4)
{
// regular steer
if((pad & 0x2000) != 0)
{
cp->wheel_angle += 32;
if (cp->wheel_angle > 352)
cp->wheel_angle = 352;
}
if ((pad & 0x8000) != 0)
{
cp->wheel_angle -= 32;
if (cp->wheel_angle < -352)
cp->wheel_angle = -352;
}
}
else
{ {
// fast steer // fast steer
if ((pad & 0x2000) != 0) if (pad & 0x2000)
{ {
cp->wheel_angle += 64; cp->wheel_angle += 64;
@ -2044,7 +2028,7 @@ void ProcessCarPad(_CAR_DATA *cp, ulong pad, char PadSteer, char use_analogue)
cp->wheel_angle = 511; cp->wheel_angle = 511;
} }
if ((pad & 0x8000) != 0) if (pad & 0x8000)
{ {
cp->wheel_angle -= 64; cp->wheel_angle -= 64;
@ -2052,24 +2036,43 @@ void ProcessCarPad(_CAR_DATA *cp, ulong pad, char PadSteer, char use_analogue)
cp->wheel_angle = -511; cp->wheel_angle = -511;
} }
} }
else
{
// regular steer
if(pad & 0x2000)
{
cp->wheel_angle += 32;
if ((pad & 0xa000) != 0) if (cp->wheel_angle > 352)
cp->wheel_angle = 352;
}
if (pad & 0x8000)
{
cp->wheel_angle -= 32;
if (cp->wheel_angle < -352)
cp->wheel_angle = -352;
}
}
if (pad & 0xa000)
cp->hd.autoBrake++; cp->hd.autoBrake++;
else else
cp->hd.autoBrake = 0; cp->hd.autoBrake = 0;
} }
else else
{ {
if ((pad & 4) == 0) if (pad & 0x4)
{
int_steer *= (int_steer * int_steer) / 80;
analog_angle = ((long long)int_steer * 0x66666667) >> 32; // int_steer * 0.4
}
else
{ {
int_steer *= (int_steer * int_steer) / 60; int_steer *= (int_steer * int_steer) / 60;
analog_angle = ((long long)int_steer * 0x88888889) >> 32; // int_steer * 0.6 analog_angle = ((long long)int_steer * 0x88888889) >> 32; // int_steer * 0.6
} }
else
{
int_steer *= (int_steer * int_steer) / 80;
analog_angle = ((long long)int_steer * 0x66666667) >> 32; // int_steer * 0.4
}
analog_angle = (analog_angle >> 5) - (int_steer >> 0x1f); analog_angle = (analog_angle >> 5) - (int_steer >> 0x1f);
@ -2096,7 +2099,7 @@ void ProcessCarPad(_CAR_DATA *cp, ulong pad, char PadSteer, char use_analogue)
if (gTimeInWater != 0) if (gTimeInWater != 0)
{ {
if ((pad & 0x80) != 0) if (pad & 0x80)
{ {
int rws; int rws;
@ -2110,7 +2113,7 @@ void ProcessCarPad(_CAR_DATA *cp, ulong pad, char PadSteer, char use_analogue)
cp->thrust = FIXEDH(cp->ap.carCos->powerRatio * rws); cp->thrust = FIXEDH(cp->ap.carCos->powerRatio * rws);
} }
else if ((pad & 0x40) != 0) else if (pad & 0x40)
{ {
if (cp->hndType == 5) if (cp->hndType == 5)
{ {
@ -2148,8 +2151,6 @@ void ProcessCarPad(_CAR_DATA *cp, ulong pad, char PadSteer, char use_analogue)
_CAR_DATA* tp; _CAR_DATA* tp;
int targetCarId, cx, cz, chase_square_dist; int targetCarId, cx, cz, chase_square_dist;
targetCarId = -1;
if (player[0].playerCarId == cp->id) if (player[0].playerCarId == cp->id)
targetCarId = player[0].targetCarId; targetCarId = player[0].targetCarId;
else if (player[1].playerCarId == cp->id) else if (player[1].playerCarId == cp->id)

View File

@ -12,6 +12,8 @@
#include "INLINE_C.H" #include "INLINE_C.H"
_ExOBJECT explosion[MAX_EXPLOSION_OBJECTS];
MATRIX SS = { 0 }; MATRIX SS = { 0 };
// decompiled code // decompiled code
@ -54,7 +56,7 @@ void InitExObjects(void)
{ {
int i; int i;
for (i = 0; i < 5; i++) for (i = 0; i < MAX_EXPLOSION_OBJECTS; i++)
explosion[i].time = -1; explosion[i].time = -1;
initExplosion(); initExplosion();
@ -186,7 +188,7 @@ void HandleExplosion(void)
i = 0; i = 0;
exp = explosion; exp = explosion;
while (i < 5) while (i < MAX_EXPLOSION_OBJECTS)
{ {
if (exp->time != -1 && exp->type != BANG_USED) if (exp->time != -1 && exp->type != BANG_USED)
{ {
@ -207,7 +209,7 @@ void HandleExplosion(void)
i = 0; i = 0;
exp = explosion; exp = explosion;
while (i < 5) while (i < MAX_EXPLOSION_OBJECTS)
{ {
if (exp->time != -1) if (exp->time != -1)
{ {
@ -277,7 +279,7 @@ void DrawAllExplosions(void)
{ {
int i; int i;
i = 0; i = 0;
while (i < 5) while (i < MAX_EXPLOSION_OBJECTS)
{ {
if (explosion[i].time != -1) if (explosion[i].time != -1)
DrawExplosion(explosion[i].time, explosion[i].pos, explosion[i].hscale, explosion[i].rscale); DrawExplosion(explosion[i].time, explosion[i].pos, explosion[i].hscale, explosion[i].rscale);

View File

@ -1,6 +1,7 @@
#ifndef JOB_FX_H #ifndef JOB_FX_H
#define JOB_FX_H #define JOB_FX_H
extern _ExOBJECT explosion[MAX_EXPLOSION_OBJECTS];
extern void InitExObjects(); // 0x00057B0C extern void InitExObjects(); // 0x00057B0C

View File

@ -106,6 +106,17 @@ void LoadCurrentProfile()
SetTextColour(128, 128, 64); SetTextColour(128, 128, 64);
ShowSavingWaitMessage("Loading configuration...", 0); ShowSavingWaitMessage("Loading configuration...", 0);
{
RECT16 rect;
rect.x = 0;
rect.y = 0;
rect.w = 320;
rect.h = 512;
ClearImage(&rect, 0, 0, 0);
DrawSync(0);
}
error = 1; error = 1;
// load config // load config
@ -126,6 +137,10 @@ void LoadCurrentProfile()
error = 0; error = 0;
} }
} }
else
{
ShowSavingWaitMessage("No saved data", 0);
}
if (error) if (error)
{ {

View File

@ -56,7 +56,8 @@ void ShowLoading(void)
{ {
POLY_G4 poly; POLY_G4 poly;
if ((NewLevel != 0) || (gInFrontend != 0)) { if (NewLevel != 0 || gInFrontend != 0)
{
int col = (VERTTYPE)(++loading_bar_pos * load_steps); int col = (VERTTYPE)(++loading_bar_pos * load_steps);
if (col > 120) if (col > 120)

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,8 @@
extern int game_over; extern int game_over;
extern XZPAIR gStartPos;
extern int xa_timeout; extern int xa_timeout;
extern int FrameCnt; extern int FrameCnt;
extern int CurrentPlayerView; extern int CurrentPlayerView;

View File

@ -35,49 +35,49 @@
char* MissionName[37] = char* MissionName[37] =
{ {
// Chicago // Chicago
"Surveillance Tip Off", "Surveillance tip off",
"Chase the Witness", "Chase the witness",
"Train Pursuit", "Train pursuit",
"Tailing the Drop", "Tailing the drop",
"Escape to the Safe House", "Escape to the safe house",
"Chase the Intruder", "Chase the intruder",
"Caine's Compound", "Caine's compound",
"Leaving Chicago", "Leaving Chicago",
// Havana // Havana
"Follow Up the Lead", "Follow up the lead",
"Hijack the Truck", "Hijack the truck",
"Stop the Truck", "Stop the truck",
"Find the Clue", "Find the clue",
"Escape to Ferry", "Escape to ferry",
"To the Docks", "To the docks",
"Back to Jones", "Back to Jones",
"Tail Jericho", "Tail Jericho",
"Pursue Jericho", "Pursue Jericho",
"Escape the Brazilians", "Escape the Brazilians",
// Vegas // Vegas
"Casino Getaway", "Casino getaway",
"Beat the Train", "Beat the train",
"Car Bomb", "Car bomb",
"Car Bomb Getaway", "Car bomb getaway",
"Bank Job", "Bank job",
"Steal the Ambulance", "Steal the ambulance",
"Stake Out", "Stake Out",
"Steal the Keys", "Steal the keys",
"C4 Deal", "C4 deal",
"Destroy the Yard", "Destroy the yard",
// Rio // Rio
"Bus Crash", "Bus crash",
"Steal the Cop Car", "Steal the cop car",
"Caine's Cash", "Caine's cash",
"Save Jones", "Save Jones",
"Boat Jump", "Boat jump",
"Jones in Trouble", "Jones in trouble",
"Chase the Gunman", "Chase the Gun Man",
"Lenny Escaping", "Lenny escaping",
"Pink Lenny Gets Caught", "Lenny gets caught",
}; };
// decompiled code // decompiled code
@ -484,9 +484,20 @@ void LoadMission(int missionnum)
if (gCutsceneAsReplay == 0) if (gCutsceneAsReplay == 0)
#endif #endif
{ {
PlayerStartInfo[0]->position.vx = MissionHeader->playerStartPosition.x;
PlayerStartInfo[0]->rotation = MissionHeader->playerStartRotation; PlayerStartInfo[0]->rotation = MissionHeader->playerStartRotation;
PlayerStartInfo[0]->position.vx = MissionHeader->playerStartPosition.x;
PlayerStartInfo[0]->position.vz = MissionHeader->playerStartPosition.y; PlayerStartInfo[0]->position.vz = MissionHeader->playerStartPosition.y;
#ifdef DEBUG_OPTIONS
if(gStartPos.x != 0 && gStartPos.z != 0)
{
PlayerStartInfo[0]->rotation = 0;
PlayerStartInfo[0]->position.vx = gStartPos.x;
PlayerStartInfo[0]->position.vz = gStartPos.z;
}
#endif
PlayerStartInfo[0]->model = MissionHeader->playerCarModel; PlayerStartInfo[0]->model = MissionHeader->playerCarModel;
PlayerStartInfo[0]->palette = MissionHeader->playerCarColour; PlayerStartInfo[0]->palette = MissionHeader->playerCarColour;
} }
@ -921,7 +932,7 @@ void RegisterChaseHit(int car1, int car2)
Mission.ChaseHitDelay = 20; Mission.ChaseHitDelay = 20;
player[1 - player_id].targetCarId = gPlayerWithTheFlag; player[1 - player_id].targetCarId = gPlayerWithTheFlag;
SetPlayerMessage(player_id, "You got the flag!",2,1); SetPlayerMessage(player_id, "You've got the flag!",2,1);
} }
} }
} }

View File

@ -359,7 +359,7 @@ int vStored = 0;
// [D] // [D]
void ProcessMotionLump(char *lump_ptr, int lump_size) void ProcessMotionLump(char *lump_ptr, int lump_size)
{ {
if (ThisMotion < 24) if (ThisMotion < 24)
{ {
int size = (lump_size + 3U & 0xfffffffc); int size = (lump_size + 3U & 0xfffffffc);
@ -546,14 +546,16 @@ void DrawBodySprite(PEDESTRIAN *pDrawingPed, int boneId, VERTTYPE v1[2], VERTTYP
lVar2 = ratan2(y, x); lVar2 = ratan2(y, x);
if (bDoingShadow == 0) if (bDoingShadow == 0)
iVar5 = gCurrentZ + (scr_z / 2); iVar5 = gCurrentZ + (scr_z / 2);
else else
iVar5 = sz + (scr_z / 2); iVar5 = sz + (scr_z / 2);
iVar13 = (scr_z * 4096) / iVar5; iVar13 = (scr_z * 4096) / iVar5;
iVar13 = iVar13 * 25 >> 5;
if (bone == JOINT_1) if (bone == JOINT_1)
iVar13 = iVar13 + ((int)((uint)*(ushort *)((int)rcossin_tbl + (((int)(pDrawingPed->dir).vy + (int)camera_angle.vy) * 8 & 0x3ff8U) + 2) << 0x10) >> 0x16); iVar13 = iVar13 + ((int)((uint)*(ushort *)((int)rcossin_tbl + (((int)(pDrawingPed->dir).vy + (int)camera_angle.vy) * 8 & 0x3ff8U) + 2) << 0x10) >> 0x16);
if (pDrawingPed->type == PED_ACTION_JUMP) if (pDrawingPed->type == PED_ACTION_JUMP)
{ {
@ -709,6 +711,10 @@ void DrawBodySprite(PEDESTRIAN *pDrawingPed, int boneId, VERTTYPE v1[2], VERTTYP
prims->b0 = combointensity & 0xFF; prims->b0 = combointensity & 0xFF;
} }
#ifndef PSX
prims->pgxp_index = 0xFFFF;
#endif
if (bDoingShadow == 0) if (bDoingShadow == 0)
{ {
x = sz + sy >> 4; x = sz + sy >> 4;
@ -792,7 +798,7 @@ void StoreVertexLists(void)
{ {
cTannerVNumbers[pBVar2->id] = -1; cTannerVNumbers[pBVar2->id] = -1;
} }
else if(*pBVar2->pModel != NULL) else if (*pBVar2->pModel != NULL)
{ {
pMVar5 = *pBVar2->pModel; pMVar5 = *pBVar2->pModel;
local_a2_76 = (SVECTOR *)pMVar5->vertices; local_a2_76 = (SVECTOR *)pMVar5->vertices;
@ -827,7 +833,7 @@ void StoreVertexLists(void)
do { do {
local_t0_256 = pmJerichoModels[iVar7]; local_t0_256 = pmJerichoModels[iVar7];
if (local_t0_256 != NULL) if (local_t0_256 != NULL)
{ {
local_a2_308 = (SVECTOR *)local_t0_256->vertices; local_a2_308 = (SVECTOR *)local_t0_256->vertices;
@ -959,7 +965,7 @@ void SetupTannerSkeleton(PEDESTRIAN *pDrawingPed)
local_t0_244->vy = pBone[1].pParent->pvOrigPos->vy - pBone[1].pvOrigPos->vy; local_t0_244->vy = pBone[1].pParent->pvOrigPos->vy - pBone[1].pvOrigPos->vy;
local_t0_244->vz = pBone[1].pParent->pvOrigPos->vz - pBone[1].pvOrigPos->vz; local_t0_244->vz = pBone[1].pParent->pvOrigPos->vz - pBone[1].pvOrigPos->vz;
if (pBone[1].id == JOINT_1) if (pBone[1].id == JOINT_1)
local_t0_244->vy -= bodyShiftValue; local_t0_244->vy -= bodyShiftValue;
i--; i--;
@ -986,7 +992,7 @@ void SetupTannerSkeleton(PEDESTRIAN *pDrawingPed)
} while (-1 < i); } while (-1 < i);
#if 0 #if 0
// Draw T POSE // Draw T POSE
{ {
extern void Debug_AddLine(VECTOR& pointA, VECTOR& pointB, CVECTOR& color); extern void Debug_AddLine(VECTOR& pointA, VECTOR& pointB, CVECTOR& color);
extern void Debug_AddLineOfs(VECTOR& pointA, VECTOR& pointB, VECTOR& ofs, CVECTOR& color); extern void Debug_AddLineOfs(VECTOR& pointA, VECTOR& pointB, VECTOR& ofs, CVECTOR& color);
@ -1237,19 +1243,19 @@ void newShowTanner(PEDESTRIAN *pDrawingPed)
LVar1 = lRoutes[vvar1][1]; LVar1 = lRoutes[vvar1][1];
iVar5 = 1; iVar5 = 1;
while (LVar1 != ROOT) while (LVar1 != ROOT)
{ {
LVar1 = lRoutes[vvar1][iVar5]; LVar1 = lRoutes[vvar1][iVar5];
uVar4 = (uint)LVar1; uVar4 = (uint)LVar1;
pBone = Skel + uVar4; pBone = Skel + uVar4;
if (pBone->id < 0x7f) if (pBone->id < 0x7f)
{ {
uVar6 = lRoutes[vvar1][iVar5-1];// (uint)*(byte *)((int)MissionName37 + iVar5 + sy + 0x93); uVar6 = lRoutes[vvar1][iVar5 - 1];// (uint)*(byte *)((int)MissionName37 + iVar5 + sy + 0x93);
VECTOR_ARRAY_1f800020[pBone->id].vx = VECTOR_ARRAY_1f800020[uVar6].vx + Skel[uVar4].vCurrPos.vx; VECTOR_ARRAY_1f800020[pBone->id].vx = VECTOR_ARRAY_1f800020[uVar6].vx + Skel[uVar4].vCurrPos.vx;
VECTOR_ARRAY_1f800020[pBone->id].vy = VECTOR_ARRAY_1f800020[uVar6].vy + Skel[uVar4].vCurrPos.vy; VECTOR_ARRAY_1f800020[pBone->id].vy = VECTOR_ARRAY_1f800020[uVar6].vy + Skel[uVar4].vCurrPos.vy;
VECTOR_ARRAY_1f800020[pBone->id].vz = VECTOR_ARRAY_1f800020[uVar6].vz + Skel[uVar4].vCurrPos.vz; VECTOR_ARRAY_1f800020[pBone->id].vz = VECTOR_ARRAY_1f800020[uVar6].vz + Skel[uVar4].vCurrPos.vz;
if ((pDrawingPed->pedType == TANNER_MODEL) && (pBone->id == HEAD)) if ((pDrawingPed->pedType == TANNER_MODEL) && (pBone->id == HEAD))
{ {
iVar3 = VECTOR_ARRAY_1f800020[uVar6].vy - 94; iVar3 = VECTOR_ARRAY_1f800020[uVar6].vy - 94;
pDrawingPed->head_pos = iVar3 / 3; pDrawingPed->head_pos = iVar3 / 3;
@ -1261,7 +1267,7 @@ void newShowTanner(PEDESTRIAN *pDrawingPed)
mVerts = (SVECTOR *)model->vertices; mVerts = (SVECTOR *)model->vertices;
iVar3 = 0; iVar3 = 0;
if (model->num_vertices != 0) if (model->num_vertices != 0)
{ {
do { do {
iVar3 = iVar3 + 1; iVar3 = iVar3 + 1;
@ -1275,7 +1281,7 @@ void newShowTanner(PEDESTRIAN *pDrawingPed)
pBone->id = (LIMBS)(pBone->id | 0x80); pBone->id = (LIMBS)(pBone->id | 0x80);
} }
iVar5++; iVar5++;
} }
vvar1++; vvar1++;
sy = vvar1 * 8; sy = vvar1 * 8;
@ -1290,7 +1296,7 @@ void newShowTanner(PEDESTRIAN *pDrawingPed)
sy = 20; sy = 20;
do { do {
uVar4 = (uint)pBone->id & 0x7f; uVar4 = (uint)pBone->id & 0x7f;
if (bDoingShadow == 0) if (bDoingShadow == 0)
{ {
if (pBone->pModel != NULL) if (pBone->pModel != NULL)
{ {
@ -1302,12 +1308,12 @@ void newShowTanner(PEDESTRIAN *pDrawingPed)
RenderModel(*pBone->pModel, NULL, &v, vvar1, 0, 0); RenderModel(*pBone->pModel, NULL, &v, vvar1, 0, 0);
} }
} }
else else
{ {
if (((uVar4 != 5) && (uVar4 != 9)) && if (((uVar4 != 5) && (uVar4 != 9)) &&
((uVar4 != 0xd && ((uVar4 != 0xd &&
((((uVar4 != 1 && ((pBone->id & 0x7f) != 0)) && (uVar4 != 0x16)) && ((((uVar4 != 1 && ((pBone->id & 0x7f) != 0)) && (uVar4 != 0x16)) &&
((uVar4 != 0xe && (uVar4 != 0x12)))))))) ((uVar4 != 0xe && (uVar4 != 0x12))))))))
{ {
uVar6 = pBone->pParent->id & 0x7f; uVar6 = pBone->pParent->id & 0x7f;
@ -1371,7 +1377,7 @@ void newShowTanner(PEDESTRIAN *pDrawingPed)
} while (-1 < sy); } while (-1 < sy);
} }
} }
else else
{ {
sy = 21; sy = 21;
do { do {
@ -1406,7 +1412,7 @@ void newShowTanner(PEDESTRIAN *pDrawingPed)
pBone = pBone + 1; pBone = pBone + 1;
} while (-1 < sy); } while (-1 < sy);
if (switch_detail_distance >> 2 < gCurrentZ) if (switch_detail_distance >> 2 < gCurrentZ)
{ {
uVar4 = (uint)Skel[4].id & 0x7f; uVar4 = (uint)Skel[4].id & 0x7f;
uVar6 = (uint)(Skel[4].pParent)->id & 0x7f; uVar6 = (uint)(Skel[4].pParent)->id & 0x7f;
@ -1432,7 +1438,7 @@ void newShowTanner(PEDESTRIAN *pDrawingPed)
DrawBodySprite(pDrawingPed, Skel[4].id, v1_00, v2_00, z, z1); DrawBodySprite(pDrawingPed, Skel[4].id, v1_00, v2_00, z, z1);
} }
else else
{ {
v1.vx = *(short *)&VECTOR_ARRAY_1f800020[(uint)Skel[4].id & 0x7f].vx; v1.vx = *(short *)&VECTOR_ARRAY_1f800020[(uint)Skel[4].id & 0x7f].vx;
v1.vy = *(short *)&VECTOR_ARRAY_1f800020[(uint)Skel[4].id & 0x7f].vy; v1.vy = *(short *)&VECTOR_ARRAY_1f800020[(uint)Skel[4].id & 0x7f].vy;
@ -1491,25 +1497,25 @@ SVECTOR* GetModelVertPtr(PEDESTRIAN *pDrawingPed, int boneId, int modelType)
switch (boneId) switch (boneId)
{ {
case 2: case 2:
startVertex = cJerichoVNumbers[0]; startVertex = cJerichoVNumbers[0];
break; break;
case 4: case 4:
startVertex = cJerichoVNumbers[1]; startVertex = cJerichoVNumbers[1];
break; break;
case 6: case 6:
startVertex = cJerichoVNumbers[2]; startVertex = cJerichoVNumbers[2];
break; break;
case 7: case 7:
startVertex = cJerichoVNumbers[3]; startVertex = cJerichoVNumbers[3];
break; break;
case 10: case 10:
startVertex = cJerichoVNumbers[4]; startVertex = cJerichoVNumbers[4];
break; break;
case 11: case 11:
startVertex = cJerichoVNumbers[5]; startVertex = cJerichoVNumbers[5];
default: default:
return vTannerList + cTannerVNumbers[boneId & 0x7f]; return vTannerList + cTannerVNumbers[boneId & 0x7f];
} }
return vJerichoList + startVertex; return vJerichoList + startVertex;
@ -1614,7 +1620,7 @@ void newRotateBones(PEDESTRIAN *pDrawingPed, BONE *poBone)
MATRIX MATRIX_1f800000; MATRIX MATRIX_1f800000;
MATRIX MATRIX_1f800020; MATRIX MATRIX_1f800020;
MATRIX MATRIX_1f800040; MATRIX MATRIX_1f800040;
SVECTOR SVECTOR_ARRAY_1f800060[2]; SVECTOR SVECTOR_ARRAY_1f800060[2];
SVECTOR SVECTOR_ARRAY_1f800080[80]; SVECTOR SVECTOR_ARRAY_1f800080[80];
VECTOR VECTOR_1f800070; VECTOR VECTOR_1f800070;
@ -1671,27 +1677,27 @@ void newRotateBones(PEDESTRIAN *pDrawingPed, BONE *poBone)
iVar6 = 1; iVar6 = 1;
LVar2 = lRoutes[local_30][iVar6]; LVar2 = lRoutes[local_30][iVar6];
while (LVar2 != ROOT) while (LVar2 != ROOT)
{ {
uVar4 = (uint)LVar2; uVar4 = (uint)LVar2;
SVECTOR_ARRAY_1f800060[0].vx = Skel[uVar4].vOffset.vx; SVECTOR_ARRAY_1f800060[0].vx = Skel[uVar4].vOffset.vx;
SVECTOR_ARRAY_1f800060[0].vy = Skel[uVar4].vOffset.vy; SVECTOR_ARRAY_1f800060[0].vy = Skel[uVar4].vOffset.vy;
SVECTOR_ARRAY_1f800060[0].vz = Skel[uVar4].vOffset.vz; SVECTOR_ARRAY_1f800060[0].vz = Skel[uVar4].vOffset.vz;
if (bReverseYRotation == 0 || Skel[uVar4].pParent->id != ROOT) if (bReverseYRotation == 0 || Skel[uVar4].pParent->id != ROOT)
{ {
SVECTOR_ARRAY_1f800060[1].vx = -Skel[uVar4].pParent->pvRotation->vx; SVECTOR_ARRAY_1f800060[1].vx = -Skel[uVar4].pParent->pvRotation->vx;
SVECTOR_ARRAY_1f800060[1].vy = Skel[uVar4].pParent->pvRotation->vy; SVECTOR_ARRAY_1f800060[1].vy = Skel[uVar4].pParent->pvRotation->vy;
SVECTOR_ARRAY_1f800060[1].vz = Skel[uVar4].pParent->pvRotation->vz; SVECTOR_ARRAY_1f800060[1].vz = Skel[uVar4].pParent->pvRotation->vz;
} }
else else
{ {
SVECTOR_ARRAY_1f800060[1].vx = Skel[uVar4].pParent->pvRotation->vx; SVECTOR_ARRAY_1f800060[1].vx = Skel[uVar4].pParent->pvRotation->vx;
SVECTOR_ARRAY_1f800060[1].vy = -Skel[uVar4].pParent->pvRotation->vy; SVECTOR_ARRAY_1f800060[1].vy = -Skel[uVar4].pParent->pvRotation->vy;
SVECTOR_ARRAY_1f800060[1].vz = Skel[uVar4].pParent->pvRotation->vz; SVECTOR_ARRAY_1f800060[1].vz = Skel[uVar4].pParent->pvRotation->vz;
} }
if (LVar2 == HEAD) if (LVar2 == HEAD)
{ {
SVECTOR_ARRAY_1f800060[1].vy -= pDrawingPed->head_rot; SVECTOR_ARRAY_1f800060[1].vy -= pDrawingPed->head_rot;
} }
@ -1728,51 +1734,51 @@ void newRotateBones(PEDESTRIAN *pDrawingPed, BONE *poBone)
LVar2 = Skel[uVar4].id; LVar2 = Skel[uVar4].id;
/**/ /**/
if (((((LVar2 & 0x7f) == 4) || (pDrawingPed->pedType < OTHER_SPRITE)) && if (((((LVar2 & 0x7f) == 4) || (pDrawingPed->pedType < OTHER_SPRITE)) &&
(-1 < (int)((uint)LVar2 << 0x18))) && (-1 < (int)((uint)LVar2 << 0x18))) &&
((Skel[uVar4].pModel != NULL && (verts != NULL)))) ((Skel[uVar4].pModel != NULL && (verts != NULL))))
{ {
pMVar5 = *Skel[uVar4].pModel; pMVar5 = *Skel[uVar4].pModel;
uVar9 = pMVar5->num_vertices; uVar9 = pMVar5->num_vertices;
uVar11 = (uint)uVar9; uVar11 = (uint)uVar9;
local_s0_2092 = (SVECTOR *)pMVar5->vertices; local_s0_2092 = (SVECTOR *)pMVar5->vertices;
pSVar8 = SVECTOR_ARRAY_1f800080; pSVar8 = SVECTOR_ARRAY_1f800080;
uVar10 = uVar11; uVar10 = uVar11;
if (uVar9 != 0) if (uVar9 != 0)
{ {
do { do {
pSVar8->vx = verts->vx + SVECTOR_ARRAY_1f800060[0].vx; pSVar8->vx = verts->vx + SVECTOR_ARRAY_1f800060[0].vx;
pSVar8->vy = verts->vy + SVECTOR_ARRAY_1f800060[0].vy; pSVar8->vy = verts->vy + SVECTOR_ARRAY_1f800060[0].vy;
pSVar8->vz = verts->vz + SVECTOR_ARRAY_1f800060[0].vz; pSVar8->vz = verts->vz + SVECTOR_ARRAY_1f800060[0].vz;
verts = verts + 1; verts = verts + 1;
uVar10 = uVar10 - 1; uVar10 = uVar10 - 1;
pSVar8 = pSVar8 + 1; pSVar8 = pSVar8 + 1;
} while (uVar10 != 0); } while (uVar10 != 0);
} }
verts = SVECTOR_ARRAY_1f800080; verts = SVECTOR_ARRAY_1f800080;
if (uVar9 != 0) if (uVar9 != 0)
{ {
do { do {
gte_ldv0(verts); gte_ldv0(verts);
gte_rtv0(); gte_rtv0();
gte_stlvnl(&VECTOR_1f800070); gte_stlvnl(&VECTOR_1f800070);
local_s0_2092->vx = VECTOR_1f800070.vx; local_s0_2092->vx = VECTOR_1f800070.vx;
local_s0_2092->vy = VECTOR_1f800070.vy; local_s0_2092->vy = VECTOR_1f800070.vy;
local_s0_2092->vz = VECTOR_1f800070.vz; local_s0_2092->vz = VECTOR_1f800070.vz;
local_s0_2092 = local_s0_2092 + 1; local_s0_2092 = local_s0_2092 + 1;
verts = verts + 1; verts = verts + 1;
uVar11 = uVar11 - 1; uVar11 = uVar11 - 1;
} while (uVar11 != 0); } while (uVar11 != 0);
} }
} }
iVar6 = iVar6 + 1; iVar6 = iVar6 + 1;
LVar2 = lRoutes[local_30][iVar6]; LVar2 = lRoutes[local_30][iVar6];
@ -1928,7 +1934,7 @@ void DrawCiv(PEDESTRIAN *pPed)
iVar26 = 0; iVar26 = 0;
boneId = (uint)(pPed->frame1 >> 1); boneId = (uint)(pPed->frame1 >> 1);
vert2 = vert1 + boneId * 0x1e; vert2 = vert1 + boneId * 0x1e;
uVar15 = pPed->head_pos;// (uint)(*(char *)((int)&pPed->flags + 1) >> 7); // [A] scale? height offset? uVar15 = (uint)(*(char *)((int)&pPed->flags + 1) >> 7); // [A] scale? height offset?
if ((pPed->frame1 & 1U) == 0) if ((pPed->frame1 & 1U) == 0)
{ {
@ -1943,11 +1949,11 @@ void DrawCiv(PEDESTRIAN *pPed)
vert2++; vert2++;
} while (0 < iVar13); } while (0 < iVar13);
} }
else else
{ {
if (pPed->frame1 < 30) if (pPed->frame1 < 30)
vert1 += (boneId + 1) * 30; vert1 += (boneId + 1) * 30;
iVar13 = 30; iVar13 = 30;
do { do {
// WTF? // WTF?
@ -1959,7 +1965,7 @@ void DrawCiv(PEDESTRIAN *pPed)
temp1.vz = vert1->vz; temp1.vz = vert1->vz;
temp2.vz = vert2->vz; temp2.vz = vert2->vz;
psrLerpData->vx = (temp1.vx + temp2.vx >> 1); psrLerpData->vx = (temp1.vx + temp2.vx >> 1);
psrLerpData->vy = (temp1.vy + temp2.vy >> uVar15 + 1); psrLerpData->vy = (temp1.vy + temp2.vy >> uVar15 + 1);
psrLerpData->vz = (temp1.vz + temp2.vz >> 1); psrLerpData->vz = (temp1.vz + temp2.vz >> 1);
@ -2043,7 +2049,7 @@ void DrawCiv(PEDESTRIAN *pPed)
iVar13 = 0xe; iVar13 = 0xe;
do { do {
if (iVar26 < 30) if (iVar26 < 30)
{ {
gte_stsxy3(&plVar22[0], &plVar22[1], &plVar22[2]); gte_stsxy3(&plVar22[0], &plVar22[1], &plVar22[2]);
gte_stsz3(&plVar23[0], &plVar23[1], &plVar23[2]); gte_stsz3(&plVar23[0], &plVar23[1], &plVar23[2]);
@ -2093,7 +2099,7 @@ void DrawCiv(PEDESTRIAN *pPed)
boneId = *piVar25; boneId = *piVar25;
if ((boneId == 4) && if ((boneId == 4) &&
(v1 = 1, lVar9 = LONG_ARRAY_1f800210[0], (v1 = 1, lVar9 = LONG_ARRAY_1f800210[0],
LONG_ARRAY_1f800210[0] <= switch_detail_distance >> 1)) LONG_ARRAY_1f800210[0] <= switch_detail_distance >> 1))
{ {
local_38 = 1; local_38 = 1;
} }
@ -2108,7 +2114,7 @@ void DrawCiv(PEDESTRIAN *pPed)
piVar25++; piVar25++;
} while (-1 < iVar13); } while (-1 < iVar13);
if (local_38 != 0) if (local_38 != 0)
{ {
bAllreadyRotated = 0; bAllreadyRotated = 0;
DoCivHead(pPed, SVECTOR_ARRAY_1f800090 + 5, SVECTOR_ARRAY_1f800090 + 4); DoCivHead(pPed, SVECTOR_ARRAY_1f800090 + 5, SVECTOR_ARRAY_1f800090 + 4);
@ -2163,7 +2169,7 @@ void DrawCiv(PEDESTRIAN *pPed)
// [D] // [D]
void SetSkelModelPointers(int type) void SetSkelModelPointers(int type)
{ {
if (type == OTHER_MODEL) if (type == OTHER_MODEL)
{ {
Skel[2].pModel = &pmJerichoModels[0]; Skel[2].pModel = &pmJerichoModels[0];
Skel[4].pModel = &pmJerichoModels[1]; Skel[4].pModel = &pmJerichoModels[1];
@ -2260,7 +2266,7 @@ void DrawTanner(PEDESTRIAN *pPed)
bDoingShadow = 1; bDoingShadow = 1;
v.vy = -camera_position.vy - MapHeight((VECTOR *)&pPed->position); v.vy = -camera_position.vy - MapHeight((VECTOR *)&pPed->position);
if (pPed->padId == 0) if (pPed->padId == 0)
{ {
if (gTimeOfDay == 3) if (gTimeOfDay == 3)
{ {
@ -2269,7 +2275,7 @@ void DrawTanner(PEDESTRIAN *pPed)
cV.r = 12; cV.r = 12;
TannerShadow(pPed, &v, moon_position + GameLevel, &cV, pPed->dir.vy); TannerShadow(pPed, &v, moon_position + GameLevel, &cV, pPed->dir.vy);
} }
else else
{ {
cV.b = 32; cV.b = 32;
cV.g = 32; cV.g = 32;
@ -2372,7 +2378,7 @@ int DrawCharacter(PEDESTRIAN *pPed)
cV.r = 12; cV.r = 12;
TannerShadow(pPed, &v, moon_position + GameLevel, &cV, (pPed->dir).vy); TannerShadow(pPed, &v, moon_position + GameLevel, &cV, (pPed->dir).vy);
} }
else else
{ {
cV.b = 32; cV.b = 32;
cV.g = 32; cV.g = 32;
@ -2398,7 +2404,7 @@ int DrawCharacter(PEDESTRIAN *pPed)
pos.vy = (0x1e - MapHeight(&pos)) - camera_position.vy; pos.vy = (0x1e - MapHeight(&pos)) - camera_position.vy;
pos.vz = pos.vz - camera_position.vz; pos.vz = pos.vz - camera_position.vz;
if (uVar8 < 8) if (uVar8 < 8)
size = uVar8 | 0x50; size = uVar8 | 0x50;
else else
size = uVar2 * -2 + 0x60; size = uVar2 * -2 + 0x60;
@ -2485,7 +2491,7 @@ void InitTannerShadow(void)
uVar2 = (ushort)uVar5; uVar2 = (ushort)uVar5;
do { do {
rectTannerWindow.w = 64; rectTannerWindow.w = 64;
rectTannerWindow.h = 128; rectTannerWindow.h = 128;
rectTannerWindow.x = uVar1; rectTannerWindow.x = uVar1;
@ -2613,7 +2619,7 @@ void TannerShadow(PEDESTRIAN* pDrawingPed, VECTOR *pPedPos, SVECTOR *pLightPos,
dr_env = (DR_ENV*)current->primptr; dr_env = (DR_ENV*)current->primptr;
SetDrawEnv(dr_env, &drEnv); SetDrawEnv(dr_env, &drEnv);
addPrim(current->ot + 0x107f, dr_env); addPrim(current->ot + 0x107f, dr_env);
current->primptr += sizeof(DR_ENV); current->primptr += sizeof(DR_ENV);
@ -2739,12 +2745,12 @@ void TannerShadow(PEDESTRIAN* pDrawingPed, VECTOR *pPedPos, SVECTOR *pLightPos,
InitCamera(&player[0]); InitCamera(&player[0]);
gte_SetGeomOffset(160, 128); gte_SetGeomOffset(160, 128);
SetDefDrawEnv(&drEnv, rectTannerWindow.x, rectTannerWindow.y, rectTannerWindow.w, rectTannerWindow.h); SetDefDrawEnv(&drEnv, rectTannerWindow.x, rectTannerWindow.y, rectTannerWindow.w, rectTannerWindow.h);
dr_env = (DR_ENV*)current->primptr; dr_env = (DR_ENV*)current->primptr;
SetDrawEnv(dr_env, &drEnv); SetDrawEnv(dr_env, &drEnv);
addPrim(current->ot + 0x107f, dr_env); addPrim(current->ot + 0x107f, dr_env);
current->primptr += sizeof(DR_ENV); current->primptr += sizeof(DR_ENV);
#endif #endif
@ -2878,7 +2884,7 @@ void DoCivHead(PEDESTRIAN *pPed, SVECTOR *vert1, SVECTOR *vert2)
flags = 0x10; // set custom palette flag flags = 0x10; // set custom palette flag
plotContext.clut = civ_clut[0][texturePedHead.texture_number][pPed->pallet & 0xf] << 0x10; plotContext.clut = civ_clut[0][texturePedHead.texture_number][pPed->pallet & 0xf] << 0x10;
} }
oldcombointensity = combointensity; oldcombointensity = combointensity;
if (gNight != 0) if (gNight != 0)

View File

@ -81,30 +81,29 @@ char CellEmpty(VECTOR *pPosition, int radius)
int num_cb; int num_cb;
int box_loop; int box_loop;
int sphere_sq; int sphere_sq;
int iVar1; int zd;
int iVar2; int iVar2;
int iVar3; int iVar3;
uint uVar4; uint theta;
int iVar5; int sn;
int* piVar6; int* piVar6;
int iVar7; int ypos;
int iVar8; int cs;
COLLISION_PACKET* collide; COLLISION_PACKET* collide;
int iVar9; int xs;
int iVar10; int zs;
int iVar11; int xd;
int cell_x, cell_z;
CELL_ITERATOR ci; CELL_ITERATOR ci;
iVar3 = pPosition->vx + units_across_halved; cell_x = (pPosition->vx + units_across_halved) / 2048;
iVar1 = pPosition->vz + units_down_halved; cell_z = (pPosition->vz + units_down_halved) / 2048;
ppco = GetFirstPackedCop(FixFloorSigned(iVar3, 11), FixFloorSigned(iVar1, 11), &ci, 0); ppco = GetFirstPackedCop(cell_x, cell_z, &ci, 0);
pCellObject = UnpackCellObject(ppco, &ci.nearCell); pCellObject = UnpackCellObject(ppco, &ci.nearCell);
do { while(pCellObject)
if (!pCellObject) {
return 1;
pModel = modelpointers[pCellObject->type]; pModel = modelpointers[pCellObject->type];
piVar6 = (int*)pModel->collision_block; piVar6 = (int*)pModel->collision_block;
@ -113,38 +112,143 @@ char CellEmpty(VECTOR *pPosition, int radius)
{ {
num_cb = *piVar6; num_cb = *piVar6;
iVar11 = ((pCellObject->pos.vx - pPosition->vx) * 0x10000) >> 0x10; xd = (pCellObject->pos.vx - pPosition->vx);
iVar1 = ((pCellObject->pos.vz - pPosition->vz) * 0x10000) >> 0x10; zd = (pCellObject->pos.vz - pPosition->vz);
sphere_sq = pModel->bounding_sphere + 580; sphere_sq = pModel->bounding_sphere + 580;
sphere_sq = (sphere_sq * sphere_sq); sphere_sq = (sphere_sq * sphere_sq);
collide = (COLLISION_PACKET*)(piVar6 + 1); collide = (COLLISION_PACKET*)(piVar6 + 1);
if (iVar11 * iVar11 + iVar1 * iVar1 < sphere_sq) if (xd * xd + zd * zd < sphere_sq)
{ {
box_loop = 0; box_loop = 0;
while (box_loop < num_cb) while (box_loop < num_cb)
{ {
iVar10 = collide->zsize * 0x800 + radius * 0x1000; // ORIGINAL
iVar9 = collide->xsize * 0x800 + radius * 0x1000; /*
uVar4 = (pCellObject->yang + collide->yang) * 0x100 & 0x3f00; zs = collide->zsize * 0x800 + radius * 0x1000;
iVar7 = pPosition->vy + ((int)(((uint) * (ushort*)&(pCellObject->pos).vy + (uint)(ushort)collide->ypos) * 0x10000) >> 0x10) + 0x50; xs = collide->xsize * 0x800 + radius * 0x1000;
if (iVar7 < 0) theta = (pCellObject->yang + collide->yang) * 64 & 0xfff;
iVar7 = -iVar7; ypos = pPosition->vy + (pCellObject->pos.vy + collide->ypos) + 80;
iVar8 = (int)*(short*)((int)rcossin_tbl + uVar4 + 2); cs = rcossin_tbl[theta * 2 + 1];
iVar5 = (int)*(short*)((int)rcossin_tbl + uVar4); sn = rcossin_tbl[theta * 2];
iVar2 = (uint)(ushort)collide->ysize << 0x10; */
if (((iVar7 < ((iVar2 >> 0x10) - (iVar2 >> 0x1f) >> 1) + 0x3c) && // NEW
((uint)((iVar11 * iVar8 - iVar1 * iVar5) + iVar9) < (uint)(iVar9 * 2))) && int xxd, zzd;
((uint)(iVar1 * iVar8 + iVar11 * iVar5 + iVar10) < (uint)(iVar10 * 2))) int yang;
int theta;
MATRIX2* mat;
yang = -pCellObject->yang & 0x3f;
theta = (pCellObject->yang + collide->yang) * 64 & 0xfff;
mat = &matrixtable[yang];
cs = rcossin_tbl[theta * 2 + 1];
sn = rcossin_tbl[theta * 2];
xxd = FIXEDH(collide->xpos * mat->m[0][0] + collide->zpos * mat->m[2][0]);
zzd = FIXEDH(collide->xpos * mat->m[0][2] + collide->zpos * mat->m[2][2]);
xd = (pCellObject->pos.vx - pPosition->vx) + xxd;
zd = (pCellObject->pos.vz - pPosition->vz) + zzd;
zs = (collide->zsize * 2048 + radius * 4096);
xs = (collide->xsize * 2048 + radius * 4096);
ypos = pPosition->vy + (pCellObject->pos.vy + collide->ypos) + 80;
#ifdef COLLISION_DEBUG
int result = 0;
if (collide->ysize / 2 + 60 > ABS(ypos) &&
xs * 2 > ABS(xd * cs - zd * sn) + xs &&
zs * 2 > ABS(zd * cs + xd * sn) + zs)
{
result = 1;
}
extern int gShowCollisionDebug;
if (gShowCollisionDebug == 3)
{
CDATA2D cd[1];
cd[0].x.vx = (pCellObject->pos.vx + xxd);//FIXEDH(collide->xpos * mat->m[0][0] + collide->zpos * mat->m[2][0]));
cd[0].x.vz = (pCellObject->pos.vz + zzd);//FIXEDH(collide->xpos * mat->m[0][2] + collide->zpos * mat->m[2][2]));
cd[0].x.vy = pPosition->vy;
cd[0].theta = theta; // (pCellObject->yang + collide->yang) * 64 & 0xfff;
cd[0].length[0] = collide->zsize / 2;
cd[0].length[1] = collide->xsize / 2;
// calc axes of box
int dtheta = cd[0].theta & 0xfff;
cd[0].axis[0].vx = rcossin_tbl[dtheta * 2];
cd[0].axis[0].vz = rcossin_tbl[dtheta * 2 + 1];
cd[0].axis[1].vz = -rcossin_tbl[dtheta * 2];
cd[0].axis[1].vx = rcossin_tbl[dtheta * 2 + 1];
extern void Debug_AddLine(VECTOR & pointA, VECTOR & pointB, CVECTOR & color);
extern void Debug_AddLineOfs(VECTOR & pointA, VECTOR & pointB, VECTOR & ofs, CVECTOR & color);
CVECTOR ggcv = { 0, 250, 0 };
CVECTOR rrcv = { 250, 0, 0 };
CVECTOR yycv = { 250, 250, 0 };
// show both box axes
{
VECTOR _zero = { 0 };
VECTOR b1p = cd[0].x;
// show position to position
//Debug_AddLine(b1p1, b2p1, yycv);
VECTOR b1ax[2] = { {0} , {0} };
b1ax[0].vx = FIXEDH(cd[0].axis[0].vx * cd[0].length[0]);
b1ax[0].vz = FIXEDH(cd[0].axis[0].vz * cd[0].length[0]);
b1ax[1].vx = FIXEDH(cd[0].axis[1].vx * cd[0].length[1]);
b1ax[1].vz = FIXEDH(cd[0].axis[1].vz * cd[0].length[1]);
// show axis of body 1
Debug_AddLineOfs(_zero, b1ax[0], b1p, rrcv);
Debug_AddLineOfs(_zero, b1ax[1], b1p, yycv);
// display 2D box 1
{
int h = b1ax[0].vy;
VECTOR box_points[4] = {
{b1ax[0].vx - b1ax[1].vx, h, b1ax[0].vz - b1ax[1].vz, 0}, // front left
{b1ax[0].vx + b1ax[1].vx, h, b1ax[0].vz + b1ax[1].vz, 0}, // front right
{-b1ax[0].vx + b1ax[1].vx, h, -b1ax[0].vz + b1ax[1].vz, 0}, // back right
{-b1ax[0].vx - b1ax[1].vx, h, -b1ax[0].vz - b1ax[1].vz, 0} // back left
};
Debug_AddLineOfs(box_points[0], box_points[1], b1p, result ? rrcv : ggcv);
Debug_AddLineOfs(box_points[1], box_points[2], b1p, result ? rrcv : ggcv);
Debug_AddLineOfs(box_points[2], box_points[3], b1p, result ? rrcv : ggcv);
Debug_AddLineOfs(box_points[3], box_points[0], b1p, result ? rrcv : ggcv);
}
}
}
if (result)
return 0;
#else
if (collide->ysize / 2 + 60 > ABS(ypos) &&
xs * 2 > ABS(xd * cs - zd * sn) + xs &&
zs * 2 > ABS(zd * cs + xd * sn) + zs)
{ {
return 0; return 0;
} }
#endif
box_loop++; box_loop++;
collide++; collide++;
@ -154,10 +258,9 @@ char CellEmpty(VECTOR *pPosition, int radius)
ppco = GetNextPackedCop(&ci); ppco = GetNextPackedCop(&ci);
pCellObject = UnpackCellObject(ppco, &ci.nearCell); pCellObject = UnpackCellObject(ppco, &ci.nearCell);
}
} while (true); return 1;
return 0;
} }
@ -941,7 +1044,7 @@ void CheckScenaryCollisions(_CAR_DATA *cp)
int lbody; int lbody;
int extraDist; int extraDist;
if (cp->controlType == CONTROL_TYPE_CAMERACOLLIDER && cp->ap.carCos == NULL) if (cp->controlType == CONTROL_TYPE_CAMERACOLLIDER || cp->ap.carCos == NULL)
lbody = 360; lbody = 360;
else else
lbody = cp->ap.carCos->colBox.vz; lbody = cp->ap.carCos->colBox.vz;

View File

@ -188,7 +188,7 @@ MENU_HEADER DebugTimeOfDayHeader =
MENU_ITEM DebugJustForFunItems[] = MENU_ITEM DebugJustForFunItems[] =
{ {
{ "Secret Car Fun", 3, 2, ToggleSecretCarFun, MENU_QUIT_RESTART, NULL }, { "Secret Car Fun", 3, 2, ToggleSecretCarFun, MENU_QUIT_RESTART, NULL },
{ "Mini cars", 3, 2, ToggleMiniCars, MENU_QUIT_NONE, NULL }, { "Mini Cars", 3, 2, ToggleMiniCars, MENU_QUIT_NONE, NULL },
{ "Jericho Mode", 3, 2, ToggleJerichoMode, MENU_QUIT_NONE, NULL }, { "Jericho Mode", 3, 2, ToggleJerichoMode, MENU_QUIT_NONE, NULL },
{ NULL, 128u, 0u, NULL, MENU_QUIT_NONE, NULL } { NULL, 128u, 0u, NULL, MENU_QUIT_NONE, NULL }
}; };
@ -199,16 +199,20 @@ MENU_HEADER DebugJustForFunHeader =
#ifdef CUTSCENE_RECORDER #ifdef CUTSCENE_RECORDER
extern void NextCutsceneRecorderPlayer(int dir); extern void NextCutsceneRecorderPlayer(int dir);
extern char gCutsceneRecorderPauseText[64]; extern char gCutsceneRecorderPauseText[64];
extern void NextChase(int dir);
extern char gCurrentChasePauseText[64];
#endif #endif
MENU_ITEM DebugOptionsItems[] = MENU_ITEM DebugOptionsItems[] =
{ {
#if 0 // TODO: enable #ifdef CUTSCENE_RECORDER
{ gCutsceneRecorderPauseText, 5u, 2u, (pauseFunc)&NextCutsceneRecorderPlayer, MENU_QUIT_NONE, NULL }, //{ gCutsceneRecorderPauseText, 5u, 2u, (pauseFunc)&NextCutsceneRecorderPlayer, MENU_QUIT_NONE, NULL },
{ gCurrentChasePauseText, 5u, 2u, (pauseFunc)&NextChase, MENU_QUIT_NONE, NULL },
#endif #endif
{ "Back on Wheels", 3, 2, SetRightWayUp, MENU_QUIT_NONE, NULL}, { "Back on Wheels", 3, 2, SetRightWayUp, MENU_QUIT_NONE, NULL},
{ "Time of Day", 65, 2, NULL, MENU_QUIT_NONE, &DebugTimeOfDayHeader }, { "Time of Day", 65, 2, NULL, MENU_QUIT_NONE, &DebugTimeOfDayHeader },
{ "Fun cheats", 65, 2, NULL, MENU_QUIT_NONE, &DebugJustForFunHeader }, { "Fun Cheats", 65, 2, NULL, MENU_QUIT_NONE, &DebugJustForFunHeader },
{ "Invincibility", 3, 2, ToggleInvincibility,MENU_QUIT_NONE, NULL}, { "Invincibility", 3, 2, ToggleInvincibility,MENU_QUIT_NONE, NULL},
{ "Immunity", 3, 2, ToggleImmunity, MENU_QUIT_NONE, NULL}, { "Immunity", 3, 2, ToggleImmunity, MENU_QUIT_NONE, NULL},
{ "Puppy Dog Cops", 3, 2, TogglePuppyDogCops, MENU_QUIT_NONE, NULL }, { "Puppy Dog Cops", 3, 2, TogglePuppyDogCops, MENU_QUIT_NONE, NULL },
@ -406,7 +410,7 @@ MENU_HEADER ChaseGameFinishedHeader =
MENU_HEADER NoPadHeader = MENU_HEADER NoPadHeader =
{ {
"Insert controller in slot 1", "Insert a Controller in port 1",
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
0u, 0u,
NoPadItems NoPadItems
@ -414,7 +418,7 @@ MENU_HEADER NoPadHeader =
MENU_HEADER NoMultiPadHeader = MENU_HEADER NoMultiPadHeader =
{ {
"Insert controller in slot 1", "Insert a Controller in port 2",
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
0u, 0u,
NoMultiPadItems NoMultiPadItems
@ -422,7 +426,7 @@ MENU_HEADER NoMultiPadHeader =
MENU_HEADER InvalidPadHeader = MENU_HEADER InvalidPadHeader =
{ {
"Incompatible controller in port 1", "Unsupported controller in port 1",
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
0u, 0u,
InvalidPadItems InvalidPadItems
@ -430,7 +434,7 @@ MENU_HEADER InvalidPadHeader =
MENU_HEADER InvalidMultiPadHeader = MENU_HEADER InvalidMultiPadHeader =
{ {
"Incompatible controller in port 1", "Unsupported controller in port 2",
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
0u, 0u,
InvalidMultiPadItems InvalidMultiPadItems
@ -679,7 +683,7 @@ void SaveReplay(int direction)
CallMemoryCard(0x10, 1); CallMemoryCard(0x10, 1);
#else #else
int size = SaveReplayToBuffer(_other_buffer); int size = SaveReplayToBuffer(_other_buffer);
FILE* fp = fopen("chase.d2rp", "wb"); FILE* fp = fopen("chase.d2rp", "wb");
if (fp) if (fp)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@
PEDESTRIAN *pPlayerPed = NULL; PEDESTRIAN *pPlayerPed = NULL;
_PLAYER player[8]; _PLAYER player[8];
// [D] // [D] [T]
void InitPlayer(_PLAYER *locPlayer, _CAR_DATA *cp, char carCtrlType, int direction, long(*startPos)[4], int externModel, int palette, char *padid) void InitPlayer(_PLAYER *locPlayer, _CAR_DATA *cp, char carCtrlType, int direction, long(*startPos)[4], int externModel, int palette, char *padid)
{ {
int model; int model;
@ -63,7 +63,8 @@ void InitPlayer(_PLAYER *locPlayer, _CAR_DATA *cp, char carCtrlType, int directi
InitCar(cp, direction, startPos, carCtrlType, model, palette & 0xff, &locPlayer->padid); InitCar(cp, direction, startPos, carCtrlType, model, palette & 0xff, &locPlayer->padid);
cp->controlFlags |= 4; cp->controlFlags |= CONTROL_FLAG_WAS_PARKED;
locPlayer->worldCentreCarId = cp->id; locPlayer->worldCentreCarId = cp->id;
locPlayer->cameraView = 0;// (NumPlayers == 2) << 1; // [A] locPlayer->cameraView = 0;// (NumPlayers == 2) << 1; // [A]
locPlayer->playerCarId = cp->id; locPlayer->playerCarId = cp->id;
@ -71,6 +72,7 @@ void InitPlayer(_PLAYER *locPlayer, _CAR_DATA *cp, char carCtrlType, int directi
locPlayer->spoolXZ = (VECTOR *)cp->hd.where.t; locPlayer->spoolXZ = (VECTOR *)cp->hd.where.t;
locPlayer->cameraCarId = cp->id; locPlayer->cameraCarId = cp->id;
locPlayer->car_is_sounding = 0; locPlayer->car_is_sounding = 0;
locPlayer->pos[1] = cp->hd.where.t[1]; locPlayer->pos[1] = cp->hd.where.t[1];
} }
else else
@ -82,6 +84,7 @@ void InitPlayer(_PLAYER *locPlayer, _CAR_DATA *cp, char carCtrlType, int directi
locPlayer->playerCarId = -1; locPlayer->playerCarId = -1;
locPlayer->car_is_sounding = 2; locPlayer->car_is_sounding = 2;
locPlayer->cameraView = 0; locPlayer->cameraView = 0;
locPlayer->pos[1] = -pPlayerPed->position.vy; locPlayer->pos[1] = -pPlayerPed->position.vy;
} }
@ -122,7 +125,7 @@ void InitPlayer(_PLAYER *locPlayer, _CAR_DATA *cp, char carCtrlType, int directi
/* end block 2 */ /* end block 2 */
// End Line: 261 // End Line: 261
// [D] // [D] [T]
void ChangeCarPlayerToPed(int playerID) void ChangeCarPlayerToPed(int playerID)
{ {
_CAR_DATA *lcp = &car_data[player[playerID].playerCarId]; _CAR_DATA *lcp = &car_data[player[playerID].playerCarId];
@ -205,25 +208,29 @@ void ChangeCarPlayerToPed(int playerID)
extern int lastCarCameraView; extern int lastCarCameraView;
// [D] [T]
void ChangePedPlayerToCar(int playerID, _CAR_DATA *newCar) void ChangePedPlayerToCar(int playerID, _CAR_DATA *newCar)
{ {
bool bVar1; int carParked;
char cVar2; int siren;
char bVar3;
bool bVar4;
uint uVar5;
int channel; int channel;
uint uVar6; int carSampleId;
int channel_00;
_PLAYER *lPlayer = &player[playerID]; _PLAYER* lPlayer;
bVar4 = false; lPlayer = &player[playerID];
uVar5 = CarHasSiren(newCar->ap.model);
if (((newCar->controlType != CONTROL_TYPE_CIV_AI && newCar->controlType != CONTROL_TYPE_CUTSCENE) || newCar->ai.c.thrustState != 3) || (newCar->ai.c.ctrlState != 7 && newCar->ai.c.ctrlState != 5)) siren = CarHasSiren(newCar->ap.model);
if (newCar->controlType == CONTROL_TYPE_CIV_AI &&
newCar->ai.c.thrustState == 3 && (newCar->ai.c.ctrlState == 7 || newCar->ai.c.ctrlState == 5) ||
newCar->controlType == CONTROL_TYPE_CUTSCENE)
{ {
bVar4 = true; carParked = 1;
}
else
{
carParked = 0;
} }
lPlayer->playerType = 1; lPlayer->playerType = 1;
@ -232,38 +239,32 @@ void ChangePedPlayerToCar(int playerID, _CAR_DATA *newCar)
if (gInGameCutsceneActive == 0 && gInGameChaseActive == 0) if (gInGameCutsceneActive == 0 && gInGameChaseActive == 0)
{ {
cVar2 = newCar->id;
lPlayer->spoolXZ = (VECTOR *)newCar->hd.where.t; lPlayer->spoolXZ = (VECTOR *)newCar->hd.where.t;
lPlayer->worldCentreCarId = cVar2; lPlayer->worldCentreCarId = newCar->id;
} }
lPlayer->cameraView = lastCarCameraView; lPlayer->cameraView = lastCarCameraView;
channel = 0x1000;
if (NoPlayerControl == 0) if (NoPlayerControl == 0)
{ lPlayer->cameraAngle = newCar->hd.direction + 1536;
channel = newCar->hd.direction + 0x600; else
} lPlayer->cameraAngle = 4096;
lPlayer->cameraAngle = channel;
lPlayer->headPos = 0; lPlayer->headPos = 0;
lPlayer->headTarget = 0; lPlayer->headTarget = 0;
lPlayer->headTimer = 0; lPlayer->headTimer = 0;
//lPlayer->padid = 0;
lPlayer->pPed = NULL; lPlayer->pPed = NULL;
{
newCar->controlType = CONTROL_TYPE_PLAYER;
newCar->ai.padid = &lPlayer->padid;
newCar->hndType = 0;
if (playerID == 0) newCar->controlType = CONTROL_TYPE_PLAYER;
newCar->ai.padid = &lPlayer->padid;
newCar->hndType = 0;
if (playerID == 0)
{
if (gCurrentMissionNumber != 32 && MissionHeader->residentModels[newCar->ap.model] == 0)
{ {
if (gCurrentMissionNumber != 32 && MissionHeader->residentModels[newCar->ap.model] == 0) NoteFelony(&felonyData, 11, 4096);
{
NoteFelony(&felonyData, 11, 4096);
}
} }
} }
@ -274,61 +275,32 @@ void ChangePedPlayerToCar(int playerID, _CAR_DATA *newCar)
// door close sound // door close sound
Start3DSoundVolPitch(-1, 6, 3, newCar->hd.where.t[0], newCar->hd.where.t[1], newCar->hd.where.t[2], 0, 0x1000); Start3DSoundVolPitch(-1, 6, 3, newCar->hd.where.t[0], newCar->hd.where.t[1], newCar->hd.where.t[2], 0, 0x1000);
bVar3 = newCar->ap.model;
if (bVar3 == 4) if (newCar->ap.model == 4)
uVar6 = ResidentModelsBodge(); carSampleId = ResidentModelsBodge();
else if (bVar3 < 3) else if (newCar->ap.model < 3)
uVar6 = newCar->ap.model; carSampleId = newCar->ap.model;
else else
uVar6 = newCar->ap.model - 1; carSampleId = newCar->ap.model - 1;
channel = 1; // start idle sound
if (playerID != 0) channel = playerID == 0 ? 1 : 4;
channel = 4; Start3DSoundVolPitch(channel, 3, carSampleId * 3 + 1, newCar->hd.where.t[0], newCar->hd.where.t[1], newCar->hd.where.t[2], -10000, 0x1000);
// idle sound // rev sound
Start3DSoundVolPitch(channel, 3, uVar6 * 3 + 1, newCar->hd.where.t[0], newCar->hd.where.t[1], newCar->hd.where.t[2], -10000, 0x1000); channel = playerID == 0 ? 0 : 3;
bVar3 = newCar->ap.model; Start3DSoundVolPitch(channel, 3, carSampleId * 3, newCar->hd.where.t[0], newCar->hd.where.t[1], newCar->hd.where.t[2], -10000, 0x1000);
if (bVar3 == 4) if (siren != 0)
{ {
channel_00 = ResidentModelsBodge(); channel = playerID == 0 ? 2 : 5;
channel = channel_00 << 1; Start3DSoundVolPitch(channel, (siren & 0xff00) >> 8, siren & 0xff, newCar->hd.where.t[0], newCar->hd.where.t[1], newCar->hd.where.t[2], -10000, 129);
}
else {
if (bVar3 < 3)
{
channel = newCar->ap.model * 3;
goto LAB_000737d4;
}
channel_00 = newCar->ap.model - 1;
channel = channel_00 * 2;
} }
channel = channel + channel_00; if (carParked)
LAB_000737d4:
channel_00 = 0;
if (playerID != 0)
channel_00 = 3;
Start3DSoundVolPitch(channel_00, 3, channel, newCar->hd.where.t[0], newCar->hd.where.t[1], newCar->hd.where.t[2], -10000, 0x1000);
if (uVar5 != 0)
{
channel = 2;
if (playerID != 0)
channel = 5;
Start3DSoundVolPitch(channel, (uVar5 & 0xff00) >> 8, uVar5 & 0xff, newCar->hd.where.t[0], newCar->hd.where.t[1], newCar->hd.where.t[2], -10000, 0x81);
}
if (bVar4)
HaveCarSoundStraightAway(playerID);
else
RequestSlightPauseBeforeCarSoundStarts(playerID); RequestSlightPauseBeforeCarSoundStarts(playerID);
else
HaveCarSoundStraightAway(playerID);
} }
@ -369,18 +341,18 @@ LAB_000737d4:
/* WARNING: Unknown calling convention yet parameter storage is locked */ /* WARNING: Unknown calling convention yet parameter storage is locked */
// [D] // [D] [T]
void UpdatePlayers(void) void UpdatePlayers(void)
{ {
int carId; int carId;
PEDESTRIAN *ped; PEDESTRIAN *ped;
_PLAYER *locPlayer; _PLAYER *locPlayer;
_CAR_DATA* cp;
pedestrianFelony = 0; pedestrianFelony = 0;
locPlayer = player; locPlayer = player;
// [A] cycle might be wrong
do { do {
if (gInGameCutsceneActive == 0) if (gInGameCutsceneActive == 0)
locPlayer->playerType = (locPlayer->pPed != NULL) ? 2 : 1; locPlayer->playerType = (locPlayer->pPed != NULL) ? 2 : 1;
@ -389,19 +361,23 @@ void UpdatePlayers(void)
{ {
carId = locPlayer->playerCarId; carId = locPlayer->playerCarId;
locPlayer->spoolXZ = (VECTOR *)car_data[locPlayer->worldCentreCarId].hd.where.t; if(locPlayer->worldCentreCarId >= 0)
locPlayer->spoolXZ = (VECTOR *)car_data[locPlayer->worldCentreCarId].hd.where.t;
if (carId >= 0) if (carId >= 0)
{ {
locPlayer->pos[0] = car_data[carId].hd.where.t[0]; cp = &car_data[carId];
locPlayer->pos[1] = car_data[carId].hd.where.t[1];
locPlayer->pos[2] = car_data[carId].hd.where.t[2]; locPlayer->pos[0] = cp->hd.where.t[0];
locPlayer->dir = car_data[carId].hd.direction; locPlayer->pos[1] = cp->hd.where.t[1];
locPlayer->pos[2] = cp->hd.where.t[2];
locPlayer->dir = cp->hd.direction;
} }
} }
else if (locPlayer->playerType == 2) else if (locPlayer->playerType == 2)
{ {
ped = locPlayer->pPed; ped = locPlayer->pPed;
locPlayer->pos[0] = ped->position.vx; locPlayer->pos[0] = ped->position.vx;
locPlayer->pos[1] = -ped->position.vy; locPlayer->pos[1] = -ped->position.vy;
locPlayer->pos[2] = ped->position.vz; locPlayer->pos[2] = ped->position.vz;
@ -428,7 +404,7 @@ void UpdatePlayers(void)
/* end block 2 */ /* end block 2 */
// End Line: 944 // End Line: 944
// [D] // [D] [T]
void RequestSlightPauseBeforeCarSoundStarts(char player_id) void RequestSlightPauseBeforeCarSoundStarts(char player_id)
{ {
player[player_id].car_is_sounding = 2; player[player_id].car_is_sounding = 2;
@ -448,7 +424,7 @@ void RequestSlightPauseBeforeCarSoundStarts(char player_id)
/* end block 1 */ /* end block 1 */
// End Line: 961 // End Line: 961
// [D] // [D] [T]
void HaveCarSoundStraightAway(char player_id) void HaveCarSoundStraightAway(char player_id)
{ {
player[player_id].car_is_sounding = 0; player[player_id].car_is_sounding = 0;
@ -466,7 +442,7 @@ void HaveCarSoundStraightAway(char player_id)
/* end block 1 */ /* end block 1 */
// End Line: 972 // End Line: 972
// [D] // [D] [T]
void MakeTheCarShutUp(char player_id) void MakeTheCarShutUp(char player_id)
{ {
player[player_id].car_is_sounding = 1; player[player_id].car_is_sounding = 1;

View File

@ -65,7 +65,7 @@ OUT_FONTINFO fontinfo[128];
/* end block 3 */ /* end block 3 */
// End Line: 1310 // End Line: 1310
// [D] // [D] [T]
void SetTextColour(unsigned char Red, unsigned char Green, unsigned char Blue) void SetTextColour(unsigned char Red, unsigned char Green, unsigned char Blue)
{ {
gFontColour.r = Red; gFontColour.r = Red;
@ -108,34 +108,29 @@ void SetTextColour(unsigned char Red, unsigned char Green, unsigned char Blue)
/* end block 3 */ /* end block 3 */
// End Line: 1344 // End Line: 1344
// [D] // [D] [T]
int StringWidth(char *pString) int StringWidth(char *pString)
{ {
char bVar1; char let;
char *pbVar2; int w;
int iVar3;
iVar3 = 0; w = 0;
bVar1 = *pString;
pbVar2 = (pString + 1); while (true)
while (bVar1 != 0) { {
if (bVar1 == 0x20) { let = *pString++;
iVar3 = iVar3 + 4; if (!let)
} break;
else {
if (((uint)bVar1 + 0x80 & 0xff) < 0xb) { if (let == 32)
iVar3 = iVar3 + 0x18; w += 4;
} else if ((let + 128 & 0xff) < 11)
else { w += 24;
if (AsciiTable[(uint)bVar1] != 0xff) { else if (AsciiTable[let] != 0xff)
iVar3 = iVar3 + (uint)fontinfo[AsciiTable[(uint)bVar1]].width; w += fontinfo[AsciiTable[let]].width;
}
}
}
bVar1 = *pbVar2;
pbVar2 = pbVar2 + 1;
} }
return iVar3;
return w;
} }
@ -175,29 +170,26 @@ int StringWidth(char *pString)
/* end block 4 */ /* end block 4 */
// End Line: 1424 // End Line: 1424
// [D] // [D] [T]
int OutputString(char *pString, int formatting, int x, int y, int xw, int r, int g, int b) int OutputString(char *pString, int formatting, int x, int y, int xw, int r, int g, int b)
{ {
int iVar1; int xpos;
SetTextColour((unsigned char)r, (unsigned char)g, (unsigned char)b); SetTextColour(r, g, b);
if ((formatting & 1U) == 0) { if (formatting & 1)
if ((formatting & 2U) == 0) { {
if ((formatting & 4U) != 0) {
iVar1 = StringWidth(pString);
PrintString(pString, x - iVar1, y);
}
}
else {
iVar1 = StringWidth(pString);
x = (x + (xw - iVar1 >> 1)) * 0x10000 >> 0x10;
PrintString(pString, x, y);
}
}
else {
PrintString(pString, x, y); PrintString(pString, x, y);
} }
else if (formatting & 2)
{
xpos = (xw - StringWidth(pString)) / 2;
PrintString(pString, x + xpos, y);
}
else if (formatting & 4)
{
PrintString(pString, x - StringWidth(pString), y);
}
return x; return x;
} }
@ -218,13 +210,10 @@ int OutputString(char *pString, int formatting, int x, int y, int xw, int r, int
/* end block 2 */ /* end block 2 */
// End Line: 1526 // End Line: 1526
// [D] // [D] [T]
void PrintStringRightAligned(char *pString, int x, int y) void PrintStringRightAligned(char *pString, int x, int y)
{ {
int iVar1; PrintString(pString, x - StringWidth(pString), y);
iVar1 = StringWidth(pString);
PrintString(pString, x - iVar1, y);
} }
@ -245,13 +234,10 @@ void PrintStringRightAligned(char *pString, int x, int y)
/* end block 2 */ /* end block 2 */
// End Line: 1554 // End Line: 1554
// [D] // [D] [T
void PrintStringCentred(char *pString, short y) void PrintStringCentred(char *pString, short y)
{ {
int iVar1; PrintString(pString, (320 - StringWidth(pString)) / 2, y);
iVar1 = StringWidth(pString);
PrintString(pString, (0x140 - iVar1) * 0x8000 >> 0x10, y);
} }
@ -282,54 +268,56 @@ void PrintStringCentred(char *pString, short y)
/* end block 3 */ /* end block 3 */
// End Line: 723 // End Line: 723
// [D] // [D] [T]
void LoadFont(char *buffer) void LoadFont(char *buffer)
{ {
int *piVar1; int i;
char *pcVar2; ushort *clut;
u_long *puVar3; int nchars;
int iVar4; char *file;
int iVar5; RECT16 dest;
int iVar6;
int *addr;
RECT16 rect;
fontclutpos.x = 976; fontclutpos.x = 976;
fontclutpos.y = 256; fontclutpos.y = 256;
fontclutpos.w = 16; fontclutpos.w = 16;
fontclutpos.h = 1; fontclutpos.h = 1;
//addr = (int *)&DAT_0011b400; // [A] FIXME: this font address might be used somewhere else
addr = (int*)_frontend_buffer; if (buffer != NULL)
if (buffer != NULL) { file = buffer;
addr = (int *)buffer; else
} file = _frontend_buffer; // 0x11b400; // [A] FIXME: this font address might be used somewhere else
Loadfile("GFX\\FONT2.FNT", (char *)addr);
iVar6 = *addr;
memcpy(fontinfo, addr + 1, iVar6 * 8);
addr = addr + 1 + iVar6 * 2;
pcVar2 = AsciiTable;
memcpy(AsciiTable, addr, 256); Loadfile("GFX\\FONT2.FNT",file);
nchars = *(int *)file;
fontclutid = GetClut((int)fontclutpos.x, (int)fontclutpos.y); // copy character info
iVar6 = 0xf; memcpy(fontinfo,file + 4,nchars * 8);
puVar3 = (u_long *)(addr + 0x40);
file += sizeof(int) + nchars * 8;
memcpy(AsciiTable, file, 256);
fontclutid = GetClut(fontclutpos.x,fontclutpos.y);
i = 0;
clut = (ushort*)(file + 0x100);
do { do {
iVar6 = iVar6 + -1; *clut++ &= 0x7fff;
*(ushort *)puVar3 = *(ushort *)puVar3 & 0x7fff; i++;
puVar3 = (u_long *)((int)puVar3 + 2); } while(i < 16);
} while (-1 < iVar6);
*(ushort *)((int)addr + 0x102) = *(ushort *)((int)addr + 0x102) | 0x8000; clut[1] |= 0x8000;
*(ushort *)(addr + 0x41) = *(ushort *)(addr + 0x41) | 0x8000; clut[2] |= 0x8000;
LoadImage(&fontclutpos, (u_long *)(addr + 0x40));
rect.x = 960; dest.x = 960;
rect.y = 466; dest.y = 466;
rect.w = 64; dest.w = 64;
rect.h = 46; dest.h = 46;
fonttpage = GetTPage(0, 0, 960, 466);
LoadImage(&rect, (u_long *)(addr + 0x48)); fonttpage = GetTPage(0,0,0x3c0,0x1d2);
LoadImage(&fontclutpos, (u_long *)(file + 0x100));
LoadImage(&dest, (u_long *)(file + 0x120));
DrawSync(0); DrawSync(0);
return;
} }
@ -362,16 +350,17 @@ void LoadFont(char *buffer)
/* end block 4 */ /* end block 4 */
// End Line: 1697 // End Line: 1697
// [D] // [D] [T]
void StoreClut2(ulong *pDest, int x, int y) void StoreClut2(ulong *pDest, int x, int y)
{ {
RECT16 local_10; RECT16 rect;
local_10.x = (short)x; rect.x = x;
local_10.y = (short)y; rect.y = y;
local_10.w = 0x10; rect.w = 16;
local_10.h = 1; rect.h = 1;
StoreImage2(&local_10, pDest);
StoreImage2(&rect, pDest);
} }
@ -403,42 +392,36 @@ void StoreClut2(ulong *pDest, int x, int y)
/* end block 3 */ /* end block 3 */
// End Line: 1741 // End Line: 1741
// [D] // [D] [T]
void SetCLUT16Flags(ushort clutID, ushort mask, char transparent) void SetCLUT16Flags(ushort clutID, ushort mask, char transparent)
{ {
#ifdef PSX
ushort uVar1;
ushort *puVar2;
uint uVar3;
ushort *pCurrent; ushort *pCurrent;
int x; int ctr;
int x, y;
ushort buffer[16]; ushort buffer[16];
x = ((uint)clutID & 0x3f) << 4; x = (clutID & 0x3f) << 4;
y = (clutID >> 6);
StoreClut2((ulong *)buffer, x, (uint)(clutID >> 6)); StoreClut2((ulong *)buffer,x,y);
pCurrent = buffer + transparent; pCurrent = buffer;
uVar3 = 1; ctr = 1;
// [A] while (pCurrent < &buffer[16])
while ((pCurrent - buffer) < 16)
{ {
if (((int)(uint)mask >> (uVar3 & 0x1f) & 1U) == 0) if (mask >> (ctr & 1U) == 0)
{ *pCurrent &= 0x7fff;
uVar1 = *pCurrent & 0x7fff; else
} *pCurrent |= 0x8000;
else
{
uVar1 = *pCurrent | 0x8000;
}
*pCurrent++ = uVar1; buffer[transparent] = 0;
uVar3 = uVar3 + 1 & 0xff;
pCurrent++;
ctr++;
} }
LoadClut2((u_long*)buffer, x, (uint)(clutID >> 6)); LoadClut2((u_long*)buffer, x,y);
#endif // PSX
} }
@ -478,110 +461,94 @@ void SetCLUT16Flags(ushort clutID, ushort mask, char transparent)
// MAP.C ???? // MAP.C ????
extern int gShowMap; extern int gShowMap;
// [D] // [D] [T]
int PrintString(char *string, int x, int y) int PrintString(char *string, int x, int y)
{ {
u_char chr; u_char chr;
char bVar1; int width;
unsigned char uVar2; uint index;
int iVar3;
short sVar4;
DB *pDVar5;
int x_00;
char *pcVar6;
uint uVar7;
SPRT *font; SPRT *font;
char *pbVar8;
int showMap = gShowMap; int showMap = gShowMap;
x_00 = -1; if (current == NULL)
if (current != NULL) return -1;
font = (SPRT *)current->primptr;
if (showMap != 0)
font = (SPRT *)SetFontTPage(font);
chr = *string++;
width = x;
while (chr != 0)
{ {
font = (SPRT *)current->primptr; if (chr == 32)
if (showMap != 0)
font = (SPRT *)SetFontTPage(font);
chr = *string;
pbVar8 = (string + 1);
x_00 = x;
while (chr != 0)
{ {
if (chr == 0x20) width += 4;
{ }
x_00 = x_00 + 4; else if (chr < 32 || chr > 138 || chr < 128)
} {
if (AsciiTable[chr] == 0xff)
index = AsciiTable[63];
else else
{ index = AsciiTable[chr];
if (chr < 0x20 || 0x8a < chr || chr < 0x80)
{
bVar1 = AsciiTable[chr];
if (AsciiTable[chr] == 0xff)
bVar1 = AsciiTable[63];
uVar7 = (uint)bVar1; chr = fontinfo[index].width;
chr = fontinfo[uVar7].width;
setSprt(font); setSprt(font);
#ifdef PSX #ifdef PSX
setSemiTrans(font, 1); setSemiTrans(font, 1);
#endif #endif
//*(undefined *)((int)&font->tag + 3) = 4; font->r0 = gFontColour.r;
//font->code = 'f'; font->g0 = gFontColour.g;
font->b0 = gFontColour.b;
font->x0 = width;
font->y0 = fontinfo[index].offy + y;
font->u0 = fontinfo[index].x;
font->v0 = fontinfo[index].y - 46;
font->w = chr;
font->h = fontinfo[index].height;
font->clut = fontclutid;
font->r0 = gFontColour.r; if (showMap == 0)
font->g0 = gFontColour.g; {
uVar2 = gFontColour.b; addPrim(current->ot, font);
font->x0 = (short)x_00;
font->b0 = uVar2;
font->y0 = (short)fontinfo[uVar7].offy + (short)y;
font->u0 = fontinfo[uVar7].x;
uVar2 = fontinfo[uVar7].y;
font->w = (ushort)chr;
font->v0 = uVar2 - 46;
sVar4 = fontclutid;
font->h = (ushort)fontinfo[uVar7].height;
font->clut = sVar4;
pDVar5 = current;
if (showMap == 0)
{
addPrim(current->ot, font);
}
else
{
DrawPrim(font);
}
font = font + 1;
x_00 = x_00 + (uint)chr;
}
else
{
if (showMap == 0)
font = (SPRT *)SetFontTPage(font);
font = (SPRT *)DrawButton(chr, font, x_00, y);
x_00 = x_00 + 0x18;
if (showMap != 0)
font = (SPRT *)SetFontTPage(font);
}
} }
chr = *pbVar8; else
pbVar8 = pbVar8 + 1; {
DrawPrim(font);
}
font++;
width += chr;
}
else
{
if (showMap == 0)
font = (SPRT *)SetFontTPage(font);
font = (SPRT *)DrawButton(chr, font, width, y);
width += 24;
if (showMap != 0)
font = (SPRT *)SetFontTPage(font);
} }
if (showMap == 0) chr = *string++;
current->primptr = (char *)SetFontTPage(font);
else
DrawSync(0);
} }
return x_00; if (showMap == 0)
current->primptr = (char *)SetFontTPage(font);
else
DrawSync(0);
return width;
} }
@ -624,64 +591,49 @@ int PrintString(char *string, int x, int y)
/* end block 3 */ /* end block 3 */
// End Line: 1130 // End Line: 1130
// [D] // [D] [T]
short PrintDigit(int x, int y, char *string) short PrintDigit(int x, int y, char *string)
{ {
char bVar1; FONT_DIGIT* pDigit;
char bVar2; char chr;
unsigned char uVar3; short width;
DB *pDVar4; int index;
short sVar5;
uint uVar6;
ulong *puVar7;
SPRT *font; SPRT *font;
int iVar8; int fixedWidth;
char cVar9; char vOff, h;
sVar5 = (short)x; width = x;
bVar1 = *string; chr = *string++;
while (bVar1 != 0) font = (SPRT *)current->primptr;
while (chr != 0)
{ {
bVar1 = *string; if (chr == 58)
string++; index = 11;
else if (chr == 47)
index = 10;
else
index = chr - 48 & 0xff;
if (bVar1 == 0x3a) pDigit = &fontDigit[index];
if (chr == 58)
fixedWidth = 8;
else
fixedWidth = 16;
if (index < 6)
{ {
uVar6 = 0xb; vOff = 0;
} h = 28;
else if (bVar1 == 0x2f)
{
uVar6 = 10;
} }
else else
{ {
uVar6 = (uint)bVar1 - 0x30 & 0xff; vOff = 28;
h = 31;
} }
bVar2 = fontDigit[uVar6].width;
iVar8 = 0x10;
if (bVar1 == 0x3a)
{
iVar8 = 8;
}
cVar9 = '\0';
if (uVar6 < 6)
{
sVar5 = 0x1c;
}
else
{
cVar9 = '\x1c';
sVar5 = 0x1f;
}
font = (SPRT *)current->primptr;
current->primptr += sizeof(SPRT);
setSprt(font); setSprt(font);
#ifdef PSX #ifdef PSX
setSemiTrans(font, 1); setSemiTrans(font, 1);
@ -691,27 +643,28 @@ short PrintDigit(int x, int y, char *string)
font->g0 = gFontColour.g; font->g0 = gFontColour.g;
font->b0 = gFontColour.b; font->b0 = gFontColour.b;
font->x0 = (short)x + (short)((int)(iVar8 - (uint)bVar2) >> 1); font->x0 = width + (fixedWidth - pDigit->width) / 2;
font->y0 = (short)y; font->y0 = y;
font->u0 = digit_texture.coords.u0 + fontDigit[uVar6].xOffset; font->u0 = digit_texture.coords.u0 + pDigit->xOffset;
font->v0 = cVar9 + digit_texture.coords.v0; font->v0 = vOff + digit_texture.coords.v0;
font->w = pDigit->width;
font->h = h;
font->w = (ushort)bVar2;
font->h = sVar5;
pDVar4 = current;
font->clut = digit_texture.clutid; font->clut = digit_texture.clutid;
addPrim(current->ot, font); addPrim(current->ot, font);
x = x + iVar8; width += fixedWidth;
sVar5 = (short)x;
bVar1 = *string; font++;
font = font + 1;
chr = *string++;
} }
current->primptr = (char*)font;
POLY_FT3* null = (POLY_FT3*)current->primptr; POLY_FT3* null = (POLY_FT3*)current->primptr;
setPolyFT3(null); setPolyFT3(null);
#ifdef PSX #ifdef PSX
@ -729,9 +682,7 @@ short PrintDigit(int x, int y, char *string)
addPrim(current->ot, null); addPrim(current->ot, null);
current->primptr += sizeof(POLY_FT3); current->primptr += sizeof(POLY_FT3);
pDVar4 = current; return width;
return sVar5;
} }
@ -755,13 +706,10 @@ short PrintDigit(int x, int y, char *string)
/* end block 3 */ /* end block 3 */
// End Line: 2128 // End Line: 2128
// [D] // [D] [T]
int PrintStringFeature(char *string, int x, int y, int w, int h, int transparent) int PrintStringFeature(char *string, int x, int y, int w, int h, int transparent)
{ {
int iVar1; return PrintString(string, x, y);
iVar1 = PrintString(string, x, y);
return iVar1;
} }
@ -802,7 +750,7 @@ int PrintStringFeature(char *string, int x, int y, int w, int h, int transparent
/* end block 4 */ /* end block 4 */
// End Line: 1388 // End Line: 1388
// [D] [A] // [D] [T]
void PrintStringBoxed(char *string, int ix, int iy) void PrintStringBoxed(char *string, int ix, int iy)
{ {
SPRT *font; SPRT *font;
@ -815,60 +763,57 @@ void PrintStringBoxed(char *string, int ix, int iy)
font = (SPRT *)current->primptr; font = (SPRT *)current->primptr;
if (*string != 0) wordcount = 1;
x = ix;
y = iy;
while (*string)
{ {
wordcount = 1; string = GetNextWord(string, word);
x = ix;
y = iy;
do if (x + StringWidth(word) > 308 && (wordcount != 1 || *string != 0))
{ {
string = GetNextWord(string, word); x = ix;
y += 14;
}
if ((x + StringWidth(word)) > 308 && (wordcount != 1 || (*string != 0))) wpt = word;
char c = 0;
while ((c = *wpt++) != 0)
{
if (c == ' ')
{ {
x = ix; x += 4;
y += 14;
} }
else
wpt = word;
char c = 0;
while ((c = *wpt++) != 0)
{ {
if (c == ' ') index = AsciiTable[c];
if (index != -1)
{ {
x += 4; OUT_FONTINFO *pFontInfo = &fontinfo[index];
}
else
{
index = AsciiTable[c];
if (index != -1) setSprt(font);
{
OUT_FONTINFO *pFontInfo = &fontinfo[index];
setSprt(font); setRGB0(font, gFontColour.r, gFontColour.g, gFontColour.b);
setXY0(font, x, y + pFontInfo->offy);
setUV0(font, pFontInfo->x, pFontInfo->y - 46);
setWH(font, pFontInfo->width, pFontInfo->height);
font->clut = fontclutid;
setRGB0(font, gFontColour.r, gFontColour.g, gFontColour.b); addPrim(current->ot, font);
setXY0(font, x, y + pFontInfo->offy); font++;
setUV0(font, pFontInfo->x, pFontInfo->y - 46);
setWH(font, pFontInfo->width, pFontInfo->height);
font->clut = fontclutid;
addPrim(current->ot, font); x += pFontInfo->width;
font++;
x += pFontInfo->width;
}
} }
} }
}
wordcount++; wordcount++;
} while (*string != 0);
} }
POLY_FT3* null = (POLY_FT3*)font; POLY_FT3* null = (POLY_FT3*)font;
@ -929,7 +874,7 @@ void PrintStringBoxed(char *string, int ix, int iy)
/* WARNING: Unknown calling convention yet parameter storage is locked */ /* WARNING: Unknown calling convention yet parameter storage is locked */
// [D] // [D] [T]
void InitButtonTextures(void) void InitButtonTextures(void)
{ {
int i; int i;
@ -1003,7 +948,7 @@ int PrintScaledString(int y, char *string, int scale)
{ {
c = *string - '0'; c = *string - '0';
if (*string == 0x20) // space if (*string == 32) // space
{ {
width = (scale / 4); width = (scale / 4);
} }
@ -1091,7 +1036,7 @@ int PrintScaledString(int y, char *string, int scale)
/* end block 4 */ /* end block 4 */
// End Line: 2506 // End Line: 2506
// [D] // [D] [T]
char * GetNextWord(char *string, char *word) char * GetNextWord(char *string, char *word)
{ {
char c = *string; char c = *string;
@ -1138,7 +1083,7 @@ char * GetNextWord(char *string, char *word)
/* end block 3 */ /* end block 3 */
// End Line: 1834 // End Line: 1834
// [D] // [D] [T]
void* DrawButton(unsigned char button, void *prim, int x, int y) void* DrawButton(unsigned char button, void *prim, int x, int y)
{ {
TEXTURE_DETAILS *btn; TEXTURE_DETAILS *btn;
@ -1212,7 +1157,7 @@ void* DrawButton(unsigned char button, void *prim, int x, int y)
/* end block 3 */ /* end block 3 */
// End Line: 2621 // End Line: 2621
// [D] // [D] [T]
void* SetFontTPage(void *prim) void* SetFontTPage(void *prim)
{ {
POLY_FT3* null = (POLY_FT3*)prim; POLY_FT3* null = (POLY_FT3*)prim;

View File

@ -72,14 +72,13 @@ int way_distance = 0;
/* WARNING: Unknown calling convention yet parameter storage is locked */ /* WARNING: Unknown calling convention yet parameter storage is locked */
// [D] // [D] [T]
void InitPadRecording(void) void InitPadRecording(void)
{ {
char *pcVar1; char *bufferEnd;
char *pcVar2;
int remain;
int i; int i;
REPLAY_STREAM *stream;
gOutOfTape = 0; gOutOfTape = 0;
@ -99,14 +98,13 @@ void InitPadRecording(void)
replayptr = (char*)(PingBuffer + 400); replayptr = (char*)(PingBuffer + 400);
pcVar1 = ReplayStart; // FIXME: is that correct?
pcVar2 = replayptr-0x3444; bufferEnd = replayptr-13380;
remain = (uint)ReplayStart - (uint)bufferEnd - CalcInGameCutsceneSize();
int cutsceneSize = CalcInGameCutsceneSize();
for (i = 0; i < NumPlayers; i++) for (i = 0; i < NumPlayers; i++)
{ {
AllocateReplayStream(&ReplayStreams[i], ((int)(pcVar1 + (-cutsceneSize - (int)pcVar2)) / sizeof(PADRECORD)) / NumPlayers); AllocateReplayStream(&ReplayStreams[i], remain / sizeof(PADRECORD) / NumPlayers);
NumReplayStreams++; NumReplayStreams++;
} }
@ -156,7 +154,8 @@ void InitPadRecording(void)
// Start line: 1348 // Start line: 1348
/* end block 3 */ /* end block 3 */
// End Line: 1349 // End Line: 1349
// [D]
// [D] [T]
int SaveReplayToBuffer(char *buffer) int SaveReplayToBuffer(char *buffer)
{ {
REPLAY_STREAM_HEADER *sheader; REPLAY_STREAM_HEADER *sheader;
@ -294,6 +293,23 @@ int gCutsceneAsReplay = 0;
int gCutsceneAsReplay_PlayerId = 0; int gCutsceneAsReplay_PlayerId = 0;
int gCutsceneAsReplay_PlayerChanged = 0; int gCutsceneAsReplay_PlayerChanged = 0;
char gCutsceneRecorderPauseText[64] = { 0 }; char gCutsceneRecorderPauseText[64] = { 0 };
char gCurrentChasePauseText[64] = { 0 };
void NextChase(int dir)
{
if(dir > 0)
gChaseNumber++;
else if(dir < 0)
gChaseNumber--;
if (gChaseNumber < 0)
gChaseNumber = 0;
if (gChaseNumber > 15)
gChaseNumber = 15;
sprintf(gCurrentChasePauseText, "Chase ID: %d", gChaseNumber);
}
void NextCutsceneRecorderPlayer(int dir) void NextCutsceneRecorderPlayer(int dir)
{ {
@ -358,7 +374,7 @@ int LoadCutsceneAsReplay(int subindex)
} }
#endif // CUTSCENE_RECORDER #endif // CUTSCENE_RECORDER
// [D] // [D] [T]
int LoadReplayFromBuffer(char *buffer) int LoadReplayFromBuffer(char *buffer)
{ {
REPLAY_SAVE_HEADER *header; REPLAY_SAVE_HEADER *header;
@ -513,7 +529,7 @@ int LoadReplayFromBuffer(char *buffer)
/* end block 3 */ /* end block 3 */
// End Line: 2119 // End Line: 2119
// [D] // [D] [T]
int LoadAttractReplay(int mission) int LoadAttractReplay(int mission)
{ {
char filename[32]; char filename[32];
@ -555,7 +571,7 @@ int LoadAttractReplay(int mission)
/* end block 3 */ /* end block 3 */
// End Line: 2365 // End Line: 2365
// [D] // [D] [T]
char GetPingInfo(char *cookieCount) char GetPingInfo(char *cookieCount)
{ {
char retCarId; char retCarId;
@ -620,41 +636,36 @@ char GetPingInfo(char *cookieCount)
/* end block 5 */ /* end block 5 */
// End Line: 2833 // End Line: 2833
// [D] // [D] [T]
int valid_region(int x, int z) int valid_region(int x, int z)
{ {
int iVar1; XYPAIR region_coords;
int iVar2;
iVar1 = (x >> 0x10) + regions_across / 2; int region;
iVar2 = (z >> 0x10) + regions_down / 2;
if (-1 < iVar1) { region_coords.x = (x >> 16) + regions_across / 2;
if (regions_across < iVar1) region_coords.y = (z >> 16) + regions_down / 2;
return 0;
if (-1 < iVar2) if (region_coords.x >= 0 && region_coords.x <= regions_across &&
region_coords.y >= 0 && region_coords.y <= regions_down)
{
region = region_coords.x + region_coords.y * regions_across;
if (region != regions_unpacked[0])
{ {
if (regions_down < iVar2) if (region == regions_unpacked[1])
return region + 1;
if (region == regions_unpacked[2])
return region + 1;
if (region != regions_unpacked[3])
return 0; return 0;
iVar1 = iVar1 + iVar2 * regions_across;
if (iVar1 != regions_unpacked[0])
{
if (iVar1 == regions_unpacked[1])
return iVar1 + 1;
if (iVar1 == regions_unpacked[2])
return iVar1 + 1;
if (iVar1 != regions_unpacked[3])
return 0;
}
return iVar1 + 1;
} }
return region + 1;
} }
return 0; return 0;
} }
@ -685,7 +696,7 @@ int valid_region(int x, int z)
/* end block 3 */ /* end block 3 */
// End Line: 2932 // End Line: 2932
// [D] // [D] [T]
int cjpPlay(int stream, ulong *ppad, char *psteer, char *ptype) int cjpPlay(int stream, ulong *ppad, char *psteer, char *ptype)
{ {
int ret; int ret;
@ -745,18 +756,15 @@ int cjpPlay(int stream, ulong *ppad, char *psteer, char *ptype)
char ReplayMode = 0; char ReplayMode = 0;
// [D] // [D] [T]
void cjpRecord(int stream, ulong *ppad, char *psteer, char *ptype) void cjpRecord(int stream, ulong *ppad, char *psteer, char *ptype)
{ {
int iVar2; int tmp;
int iVar3;
int t1; int t1;
ulong t0; ulong t0;
if (stream > -1 && stream < NumReplayStreams) if (stream > -1 && stream < NumReplayStreams)
{ {
iVar3 = (int)*psteer;
RecordWaypoint(); RecordWaypoint();
if ((*ptype & 4U) == 0) if ((*ptype & 4U) == 0)
@ -765,19 +773,19 @@ void cjpRecord(int stream, ulong *ppad, char *psteer, char *ptype)
} }
else else
{ {
if (iVar3 < -45) if (*psteer < -45)
{ {
iVar2 = -45 - iVar3 >> 0x1f; tmp = -45 - *psteer >> 0x1f; // [A] still need to figure out this
t1 = (((-45 - iVar3) / 6 + iVar2 >> 1) - iVar2) + 1; t1 = (((-45 - *psteer) / 6 + tmp >> 1) - tmp) + 1;
} }
else if (iVar3 < 46) else if (*psteer < 46)
{ {
t1 = 8; t1 = 8;
} }
else else
{ {
iVar2 = iVar3 - 45 >> 0x1f; tmp = *psteer - 45 >> 0x1f; // [A] still need to figure out this
t1 = (((iVar3 - 45) / 6 + iVar2 >> 1) - iVar2) + 9; t1 = (((*psteer - 45) / 6 + tmp >> 1) - tmp) + 9;
} }
} }
@ -841,14 +849,14 @@ void cjpRecord(int stream, ulong *ppad, char *psteer, char *ptype)
/* end block 4 */ /* end block 4 */
// End Line: 3418 // End Line: 3418
// [D] // [D] [T]
void AllocateReplayStream(REPLAY_STREAM *stream, int maxpad) void AllocateReplayStream(REPLAY_STREAM *stream, int maxpad)
{ {
stream->playbackrun = 0; stream->playbackrun = 0;
stream->length = 0; stream->length = 0;
if(CurrentGameMode != GAMEMODE_DIRECTOR && CurrentGameMode != GAMEMODE_REPLAY) if(CurrentGameMode != GAMEMODE_DIRECTOR && CurrentGameMode != GAMEMODE_REPLAY)
stream->padCount = 0; stream->padCount = 0;
stream->InitialPadRecordBuffer = (PADRECORD*)replayptr; stream->InitialPadRecordBuffer = (PADRECORD*)replayptr;
stream->PadRecordBuffer = (PADRECORD*)replayptr; stream->PadRecordBuffer = (PADRECORD*)replayptr;
@ -892,7 +900,7 @@ void AllocateReplayStream(REPLAY_STREAM *stream, int maxpad)
/* end block 3 */ /* end block 3 */
// End Line: 3467 // End Line: 3467
// [D] // [D] [T]
int Get(int stream, ulong *pt0) int Get(int stream, ulong *pt0)
{ {
REPLAY_STREAM* rstream; REPLAY_STREAM* rstream;
@ -962,7 +970,7 @@ int Get(int stream, ulong *pt0)
/* end block 5 */ /* end block 5 */
// End Line: 3545 // End Line: 3545
// [D] // [D] [T]
int Put(int stream, ulong *pt0) int Put(int stream, ulong *pt0)
{ {
REPLAY_STREAM *rstream; REPLAY_STREAM *rstream;
@ -1029,25 +1037,23 @@ int Put(int stream, ulong *pt0)
/* WARNING: Unknown calling convention yet parameter storage is locked */ /* WARNING: Unknown calling convention yet parameter storage is locked */
// [D] // [D] [T]
void RecordWaypoint(void) void RecordWaypoint(void)
{ {
if (TimeToWay == 0) if (TimeToWay > 0)
{ {
if (PlayerWaypoints < 150) TimeToWay--;
{
PlayerWaypoints++;
TimeToWay = way_distance;
PlayerWayRecordPtr->x = (player[0].pos[0] >> 10);
PlayerWayRecordPtr->y = (player[0].pos[2] >> 10);
PlayerWayRecordPtr++;
}
return; return;
} }
TimeToWay--; if (PlayerWaypoints < 150)
{
TimeToWay = way_distance;
PlayerWayRecordPtr->x = (player[0].pos[0] >> 10);
PlayerWayRecordPtr->y = (player[0].pos[2] >> 10);
PlayerWayRecordPtr++;
PlayerWaypoints++;
}
} }

View File

@ -39,7 +39,7 @@
SCORE_TABLES ScoreTables; SCORE_TABLES ScoreTables;
PLAYER_SCORE gPlayerScore; PLAYER_SCORE gPlayerScore;
// [D] // [D] [T]
void InitialiseScoreTables(void) void InitialiseScoreTables(void)
{ {
int i, j; int i, j;
@ -100,7 +100,7 @@ void InitialiseScoreTables(void)
/* end block 4 */ /* end block 4 */
// End Line: 204 // End Line: 204
// [D] // [D] [T]
int OnScoreTable(SCORE_ENTRY **tablept) int OnScoreTable(SCORE_ENTRY **tablept)
{ {
int position; int position;
@ -168,7 +168,7 @@ int OnScoreTable(SCORE_ENTRY **tablept)
/* end block 4 */ /* end block 4 */
// End Line: 302 // End Line: 302
// [D] // [D] [T]
void AddScoreToTable(SCORE_ENTRY *table, int entry) void AddScoreToTable(SCORE_ENTRY *table, int entry)
{ {
int i; int i;
@ -218,7 +218,7 @@ void AddScoreToTable(SCORE_ENTRY *table, int entry)
/* end block 4 */ /* end block 4 */
// End Line: 365 // End Line: 365
// [D] // [D] [T]
int CheckGetawayPlacing(SCORE_ENTRY *table) int CheckGetawayPlacing(SCORE_ENTRY *table)
{ {
int i; int i;
@ -266,7 +266,7 @@ int CheckGetawayPlacing(SCORE_ENTRY *table)
/* end block 4 */ /* end block 4 */
// End Line: 422 // End Line: 422
// [D] // [D] [T]
int CheckTrailblazerPlacing(SCORE_ENTRY *table) int CheckTrailblazerPlacing(SCORE_ENTRY *table)
{ {
int i; int i;
@ -286,7 +286,7 @@ int CheckTrailblazerPlacing(SCORE_ENTRY *table)
} }
} }
else if ((table->items == -1) || (table->items < gPlayerScore.items)) else if (table->items == -1 || table->items < gPlayerScore.items)
{ {
return i; return i;
} }
@ -330,7 +330,7 @@ int CheckTrailblazerPlacing(SCORE_ENTRY *table)
/* end block 4 */ /* end block 4 */
// End Line: 491 // End Line: 491
// [D] // [D] [T]
int CheckCheckpointPlacing(SCORE_ENTRY *table) int CheckCheckpointPlacing(SCORE_ENTRY *table)
{ {
int i; int i;
@ -377,7 +377,7 @@ int CheckCheckpointPlacing(SCORE_ENTRY *table)
/* end block 4 */ /* end block 4 */
// End Line: 546 // End Line: 546
// [D] // [D] [T]
int CheckSurvivalPlacing(SCORE_ENTRY *table) int CheckSurvivalPlacing(SCORE_ENTRY *table)
{ {
int i; int i;
@ -423,7 +423,7 @@ int CheckSurvivalPlacing(SCORE_ENTRY *table)
/* end block 4 */ /* end block 4 */
// End Line: 587 // End Line: 587
// [D] // [D] [T]
void ResetTable(SCORE_ENTRY *table) void ResetTable(SCORE_ENTRY *table)
{ {
int i; int i;

View File

@ -1,8 +1,12 @@
#include "DRIVER2.H" #include "DRIVER2.H"
#include "XAPLAY.H" #include "XAPLAY.H"
#include "MAIN.H"
#include "CAMERA.H"
#include "FMVPLAY.H"
#include "PAUSE.H"
#include "SOUND.H" #include "SOUND.H"
#include "SPOOL.H" #include "PRES.H"
#ifndef PSX #ifndef PSX
@ -11,9 +15,13 @@
#include "../utils/audio_source/snd_wav_cache.h" #include "../utils/audio_source/snd_wav_cache.h"
#include "AL/al.h" #include "AL/al.h"
#include "AL/alext.h"
#include "LIBETC.H"
const char* XANameFormat = "DRIVER2\\XA\\XABNK0%d.XA[%d].wav"; const char* XANameFormat = "DRIVER2\\XA\\XABNK0%d.XA[%d].wav";
ALuint g_XASource = AL_NONE; ALuint g_XASource = AL_NONE;
CSoundSource_WaveCache* g_wavData = NULL;
CSoundSource_OpenALCache* g_XAWave = NULL; CSoundSource_OpenALCache* g_XAWave = NULL;
#else #else
@ -39,6 +47,38 @@ static CdlLOC pause_loc;
static unsigned long buffer[8]; static unsigned long buffer[8];
XA_TRACK XAMissionMessages[4]; XA_TRACK XAMissionMessages[4];
#ifndef PSX
int gXASubtitleTime = 0;
int gXASubtitlePauseTime = 0;
void PrintXASubtitles()
{
if (gSubtitles == 0 || pauseflag)
return;
if (gPlaying == 0 || g_wavData == NULL)
return;
int curTime = (VSync(-1) - gXASubtitleTime) * 17;
// find subtitles
for(int i = 0; i < g_wavData->m_numSubtitles; i++)
{
CUESubtitle_t* sub = &g_wavData->m_subtitles[i];
int subStartFrame = sub->sampleStart;
int subEndFrame = sub->sampleStart + sub->sampleLength;
if(curTime >= subStartFrame && curTime <= subEndFrame)
{
SetTextColour(120, 120, 120);
PrintStringCentred(sub->text, 200);
}
}
}
#endif
// decompiled code // decompiled code
// original method signature: // original method signature:
// void /*$ra*/ GetMissionXAData(int number /*$s0*/) // void /*$ra*/ GetMissionXAData(int number /*$s0*/)
@ -227,6 +267,8 @@ void PrepareXA(void)
{ {
alGenSources(1, &g_XASource); alGenSources(1, &g_XASource);
alSourcei(g_XASource, AL_LOOPING, 0); alSourcei(g_XASource, AL_LOOPING, 0);
alSourcei(g_XASource, AL_SOURCE_RESAMPLER_SOFT, 2); // Use cubic resampler
alSourcei(g_XASource, AL_SOURCE_RELATIVE, AL_TRUE);
if (g_XAWave) if (g_XAWave)
{ {
@ -297,10 +339,11 @@ void PlayXA(int num, int index)
char fileName[250]; char fileName[250];
sprintf(fileName, XANameFormat, num+1, index); sprintf(fileName, XANameFormat, num+1, index);
CSoundSource_WaveCache wavData; g_wavData = new CSoundSource_WaveCache();
if (wavData.Load(fileName))
if (g_wavData->Load(fileName))
{ {
g_XAWave = new CSoundSource_OpenALCache(&wavData); g_XAWave = new CSoundSource_OpenALCache(g_wavData);
alSourcei(g_XASource, AL_BUFFER, g_XAWave->m_alBuffer); alSourcei(g_XASource, AL_BUFFER, g_XAWave->m_alBuffer);
@ -312,6 +355,8 @@ void PlayXA(int num, int index)
gPlaying = 1; gPlaying = 1;
xa_prepared = 2; xa_prepared = 2;
gXASubtitleTime = VSync(-1);
} }
#endif #endif
} }
@ -400,6 +445,9 @@ void UnprepareXA(void)
if (g_XAWave) if (g_XAWave)
{ {
delete g_wavData;
g_wavData = NULL;
delete g_XAWave; delete g_XAWave;
g_XAWave = NULL; g_XAWave = NULL;
} }
@ -550,6 +598,8 @@ void ResumeXA(void)
alSourcef(g_XASource, AL_GAIN, float(vol) / 128.0f); alSourcef(g_XASource, AL_GAIN, float(vol) / 128.0f);
alSourcePlay(g_XASource); alSourcePlay(g_XASource);
gXASubtitleTime += VSync(-1) - gXASubtitlePauseTime;
} }
#endif #endif
} }
@ -603,6 +653,7 @@ void PauseXA(void)
if (xa_prepared && gPlaying) if (xa_prepared && gPlaying)
{ {
alSourcePause(g_XASource); alSourcePause(g_XASource);
gXASubtitlePauseTime = VSync(-1);
} }
#endif #endif
} }

View File

@ -1,6 +1,7 @@
#ifndef XAPLAY_H #ifndef XAPLAY_H
#define XAPLAY_H #define XAPLAY_H
extern void PrintXASubtitles();
extern void GetMissionXAData(int number); // 0x00082EC0 extern void GetMissionXAData(int number); // 0x00082EC0

View File

@ -4,9 +4,12 @@
// DRIVER 2 game engine limits // DRIVER 2 game engine limits
// please populate this file only with engine limits during refactoring // please populate this file only with engine limits during refactoring
#define MAX_CARS 20 #define MAX_CARS 20
#define MAX_CAR_MODELS 5 #define MAX_CAR_MODELS 5
#define MAX_PEDESTRIANS 28 #define MAX_PEDESTRIANS 28
#define MAX_TRAFFIC_CARS 19 #define MAX_PLACED_PEDS 15
#define MAX_TRAFFIC_CARS 19
#define MAX_EXPLOSION_OBJECTS 5
#define MAX_THROWN_BOMBS 5
#endif // DRLIMITS_H #endif // DRLIMITS_H

View File

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

View File

@ -1,12 +1,22 @@
#include "snd_wav_source.h" #include "snd_wav_source.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
//--------------------------------------------------------------------- //---------------------------------------------------------------------
CSoundSource_Wave::CSoundSource_Wave() : m_loopStart(0), m_loopEnd(0), m_numSamples(0) CSoundSource_Wave::CSoundSource_Wave() : m_loopStart(0), m_loopEnd(0), m_numSamples(0)
{ {
m_numSubtitles = 0;
}
CSoundSource_Wave::~CSoundSource_Wave()
{
for(int i = 0; i < m_numSubtitles; i++)
{
free(m_subtitles[i].text);
}
} }
void CSoundSource_Wave::ParseChunk(CRIFF_Parser &chunk) void CSoundSource_Wave::ParseChunk(CRIFF_Parser &chunk)
@ -19,6 +29,8 @@ void CSoundSource_Wave::ParseChunk(CRIFF_Parser &chunk)
memcpy(namestr, name, 4); memcpy(namestr, name, 4);
namestr[4] = 0; namestr[4] = 0;
//printf("chunk ID %s\n", namestr);
switch ( chunk.GetName() ) switch ( chunk.GetName() )
{ {
case CHUNK_FMT: case CHUNK_FMT:
@ -27,6 +39,9 @@ void CSoundSource_Wave::ParseChunk(CRIFF_Parser &chunk)
case CHUNK_CUE: case CHUNK_CUE:
ParseCue( chunk ); ParseCue( chunk );
break; break;
case CHUNK_LIST:
ParseList( chunk );
break;
case CHUNK_DATA: case CHUNK_DATA:
ParseData( chunk ); ParseData( chunk );
break; break;
@ -50,14 +65,93 @@ void CSoundSource_Wave::ParseFormat(CRIFF_Parser &chunk)
void CSoundSource_Wave::ParseCue(CRIFF_Parser &chunk) void CSoundSource_Wave::ParseCue(CRIFF_Parser &chunk)
{ {
wavcuehdr_t cue; int count;
chunk.ReadChunk(&count, sizeof(int));
chunk.ReadChunk( (u_char *)&cue, sizeof(wavcuehdr_t) ); // now read all CUEs
m_loopStart = cue.SampleOffset; for(int i = 0; i < count; i++)
{
wavcuehdr_t cue;
chunk.ReadChunk( (u_char *)&cue, sizeof(wavcuehdr_t) );
m_loopStart = cue.SampleOffset;
//printf("CUE %d time: %d ms (%d)\n", i+1, sampleTimeMilliseconds, cue.SampleOffset);
CUESubtitle_t& sub = m_subtitles[m_numSubtitles];
sub.sampleStart = float(cue.SampleOffset) / float(m_format.frequency) * 1000.0f;
sub.sampleLength = 0;
sub.text = NULL;
m_numSubtitles++;
}
// dont care about the rest // dont care about the rest
} }
struct wavltxthdr_t
{
uint CueId;
uint SampleLen;
uint PurposeId;
ushort Country;
ushort Language;
ushort Dialect;
ushort CodePage;
};
void CSoundSource_Wave::ParseList(CRIFF_Parser &chunk)
{
int adtl;
chunk.ReadChunk(&adtl, sizeof(int));
if(adtl == CHUNK_ADTLLIST)
{
int remainingSize = chunk.GetSize() -4;
while(remainingSize > 0)
{
RIFFchunk_t listChunk;
int read = chunk.ReadChunk(&listChunk, sizeof(listChunk));
remainingSize -= read;
char* name = (char*)&listChunk.Id;
char namestr[5];
memcpy(namestr, name, 4);
namestr[4] = 0;
if(listChunk.Id == CHUNK_LTXT)
{
wavltxthdr_t ltxt;
int read = chunk.ReadChunk(&ltxt, sizeof(wavltxthdr_t));
remainingSize -= read;
m_subtitles[ltxt.CueId-1].sampleLength = float(ltxt.SampleLen) / float(m_format.frequency) * 1000.0f;
}
else if(listChunk.Id == CHUNK_LABEL)
{
char labelString[128];
int cueId;
int stringSize = listChunk.Size - 4 + (listChunk.Size & 1);
int read = chunk.ReadChunk( &cueId, sizeof(int) );
remainingSize -= read;
m_subtitles[cueId - 1].text = (char*)malloc(stringSize);
read = chunk.ReadChunk( m_subtitles[cueId - 1].text, stringSize );
remainingSize -= read;
//printf("Label cue = %d, size: %d, '%s'\n", cueId, stringSize, labelString);
}
}
}
}
void CSoundSource_Wave::ParseSample(CRIFF_Parser &chunk) void CSoundSource_Wave::ParseSample(CRIFF_Parser &chunk)
{ {
wavsamplehdr_t wsx; wavsamplehdr_t wsx;

View File

@ -7,14 +7,26 @@
//--------------------------------------------------------------------- //---------------------------------------------------------------------
struct CUESubtitle_t
{
int sampleStart;
int sampleLength;
char* text;
};
class CSoundSource_Wave : public ISoundSource class CSoundSource_Wave : public ISoundSource
{ {
public: public:
CSoundSource_Wave(); CSoundSource_Wave();
virtual ~CSoundSource_Wave();
virtual soundFormat_t* GetFormat() { return &m_format; } virtual soundFormat_t* GetFormat() { return &m_format; }
virtual float GetLoopPosition(float flPosition); virtual float GetLoopPosition(float flPosition);
virtual int GetSampleCount() const { return m_numSamples; } virtual int GetSampleCount() const { return m_numSamples; }
CUESubtitle_t m_subtitles[128];
int m_numSubtitles;
protected: protected:
void ParseChunk(CRIFF_Parser &chunk); void ParseChunk(CRIFF_Parser &chunk);
@ -22,6 +34,7 @@ protected:
virtual void ParseFormat(CRIFF_Parser &chunk); virtual void ParseFormat(CRIFF_Parser &chunk);
virtual void ParseCue(CRIFF_Parser &chunk); virtual void ParseCue(CRIFF_Parser &chunk);
virtual void ParseSample(CRIFF_Parser &chunk); virtual void ParseSample(CRIFF_Parser &chunk);
virtual void ParseList(CRIFF_Parser &chunk);
virtual void ParseData(CRIFF_Parser &chunk) = 0; virtual void ParseData(CRIFF_Parser &chunk) = 0;
soundFormat_t m_format; soundFormat_t m_format;

View File

@ -94,12 +94,15 @@ int CRIFF_Parser::ReadChunk( void* pOutput, int maxLen )
int readCount = ReadData( pOutput, numToRead); int readCount = ReadData( pOutput, numToRead);
numToRead -= readCount;
/*
if (numToRead < m_curChunk.Size) if (numToRead < m_curChunk.Size)
{ {
m_pos += m_curChunk.Size - numToRead; m_pos += m_curChunk.Size - numToRead;
if (m_riff) if (m_riff)
fseek(m_riff, m_curChunk.Size - numToRead, SEEK_CUR); fseek(m_riff, m_curChunk.Size - numToRead, SEEK_CUR);
} }*/
return readCount; return readCount;
} }

View File

@ -13,6 +13,10 @@
#define CHUNK_CUE ((' ' << 24) | ('e' << 16) | ('u' << 8) | 'c' ) #define CHUNK_CUE ((' ' << 24) | ('e' << 16) | ('u' << 8) | 'c' )
#define CHUNK_DATA (('a' << 24) | ('t' << 16) | ('a' << 8) | 'd' ) #define CHUNK_DATA (('a' << 24) | ('t' << 16) | ('a' << 8) | 'd' )
#define CHUNK_SAMPLE (('l' << 24) | ('p' << 16) | ('m' << 8) | 's' ) #define CHUNK_SAMPLE (('l' << 24) | ('p' << 16) | ('m' << 8) | 's' )
#define CHUNK_LTXT (('t' << 24) | ('x' << 16) | ('t' << 8) | 'l' )
#define CHUNK_LABEL (('l' << 24) | ('b' << 16) | ('a' << 8) | 'l' )
#define CHUNK_LIST (('T' << 24) | ('S' << 16) | ('I' << 8) | 'L' )
#define CHUNK_ADTLLIST (('l' << 24) | ('t' << 16) | ('d' << 8) | 'a' )
// RIFF WAVE FILE HEADERS // RIFF WAVE FILE HEADERS
typedef struct typedef struct