mirror of
https://github.com/OpenDriver2/REDRIVER2.git
synced 2024-11-22 10:22:48 +01:00
Merge branch 'develop-Fireboyd78' of github.com:OpenDriver2/REDRIVER2 into develop-Fireboyd78
This commit is contained in:
commit
0287aa6722
@ -162,13 +162,12 @@ void DrawDebugOverlays()
|
|||||||
|
|
||||||
int lane = GetLaneByPositionOnRoad(&roadInfo, carPos);
|
int lane = GetLaneByPositionOnRoad(&roadInfo, carPos);
|
||||||
|
|
||||||
sprintf(tempBuf, "%s %d flg %d%d%d spd %d len %d",
|
sprintf(tempBuf, "%s %d PRK(%d-%d) SPD(%d) LEN(%d)",
|
||||||
roadInfo.straight ? "STR" : "CRV",
|
roadInfo.straight ? "STR" : "CRV",
|
||||||
roadInfo.surfId,
|
roadInfo.surfId,
|
||||||
(roadInfo.NumLanes & 0x20) > 0, // flag 0 - first lane?
|
ROAD_IS_LEFTMOST_LANE_PARKING(&roadInfo),
|
||||||
(roadInfo.NumLanes & 0x40) > 0, // flag 1 - leftmost park
|
ROAD_IS_RIGHTMOST_LANE_PARKING(&roadInfo),
|
||||||
(roadInfo.NumLanes & 0x80) > 0, // flag 2 - rightmost park
|
ROAD_SPEED_LIMIT(&roadInfo),
|
||||||
ROAD_SPEED_LIMIT(&roadInfo), // speed limit id
|
|
||||||
segLen
|
segLen
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -185,7 +184,7 @@ void DrawDebugOverlays()
|
|||||||
PrintString(tempBuf, 10, 195);
|
PrintString(tempBuf, 10, 195);
|
||||||
|
|
||||||
sprintf(tempBuf, "c %d %d %d %d",
|
sprintf(tempBuf, "c %d %d %d %d",
|
||||||
(int)(*roadInfo.ConnectIdx)[0], (int)(*roadInfo.ConnectIdx)[1], (int)(*roadInfo.ConnectIdx)[2], (int)(*roadInfo.ConnectIdx)[3]);
|
(int)roadInfo.ConnectIdx[0], (int)roadInfo.ConnectIdx[1], (int)roadInfo.ConnectIdx[2], (int)roadInfo.ConnectIdx[3]);
|
||||||
|
|
||||||
PrintString(tempBuf, 10, 205);
|
PrintString(tempBuf, 10, 205);
|
||||||
}
|
}
|
||||||
@ -193,10 +192,16 @@ void DrawDebugOverlays()
|
|||||||
{
|
{
|
||||||
DRIVER2_JUNCTION* junc = GET_JUNCTION(roadInfo.surfId);
|
DRIVER2_JUNCTION* junc = GET_JUNCTION(roadInfo.surfId);
|
||||||
|
|
||||||
sprintf(tempBuf, "JUN %d flg %d - c %d %d %d %d",roadInfo.surfId, junc->flags,
|
sprintf(tempBuf, "JUN %d TL(%d) YLD(%d)",
|
||||||
(int)(*roadInfo.ConnectIdx)[0], (int)(*roadInfo.ConnectIdx)[1], (int)(*roadInfo.ConnectIdx)[2], (int)(*roadInfo.ConnectIdx)[3]);
|
roadInfo.surfId,
|
||||||
|
(junc->flags & 1), (junc->flags & 2));
|
||||||
|
|
||||||
PrintString(tempBuf, 10, 180);
|
PrintString(tempBuf, 10, 180);
|
||||||
|
|
||||||
|
sprintf(tempBuf, "c %d %d %d %d",
|
||||||
|
(int)roadInfo.ConnectIdx[0], (int)roadInfo.ConnectIdx[1], (int)roadInfo.ConnectIdx[2], (int)roadInfo.ConnectIdx[3]);
|
||||||
|
|
||||||
|
PrintString(tempBuf, 10, 205);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,8 +111,10 @@ int FrustrumCheck16(PACKED_CELL_OBJECT* pcop, int bounding_sphere)
|
|||||||
|
|
||||||
ang = FRUSTUM_THRESHOLD - bounding_sphere;
|
ang = FRUSTUM_THRESHOLD - bounding_sphere;
|
||||||
|
|
||||||
if (ang <= MIN(result.vx, result.vz))
|
if (ang <= result.vx && ang <= result.vy && ang <= result.vz)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -132,8 +134,10 @@ int FrustrumCheck(VECTOR* pos, int bounding_sphere)
|
|||||||
|
|
||||||
ang = FRUSTUM_THRESHOLD - bounding_sphere;
|
ang = FRUSTUM_THRESHOLD - bounding_sphere;
|
||||||
|
|
||||||
if (ang <= MIN(result.vx, result.vz))
|
if (ang <= result.vx && ang <= result.vy && ang <= result.vz)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,8 @@ char UglyLowCarLODs[4][10] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int GetNodePos(DRIVER2_STRAIGHT* straight, DRIVER2_JUNCTION* junction, DRIVER2_CURVE* curve, int distAlongPath, CAR_DATA* cp, int* x, int* z, int laneNo);
|
||||||
|
|
||||||
// [D] [T]
|
// [D] [T]
|
||||||
int InitCar(CAR_DATA* cp, int direction, LONGVECTOR4* startPos, unsigned char control, int model, int palette, char* extraData)
|
int InitCar(CAR_DATA* cp, int direction, LONGVECTOR4* startPos, unsigned char control, int model, int palette, char* extraData)
|
||||||
{
|
{
|
||||||
@ -265,6 +267,66 @@ void CivCarFX(CAR_DATA* cp)
|
|||||||
AddBrakeLight(cp);
|
AddBrakeLight(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetLeftBoundLane(DRIVER2_ROAD_INFO& roadInfo, int oppDir)
|
||||||
|
{
|
||||||
|
int i, laneCount, laneNo;
|
||||||
|
|
||||||
|
laneCount = ROAD_WIDTH_IN_LANES(&roadInfo);
|
||||||
|
laneNo = laneCount;
|
||||||
|
|
||||||
|
for (i = laneNo - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (ROAD_IS_AI_LANE(&roadInfo, i) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, i))
|
||||||
|
{
|
||||||
|
test42 = ROAD_LANE_DIR(&roadInfo, i) ^ 1;
|
||||||
|
laneNo = i;
|
||||||
|
|
||||||
|
if (test42 == 0)
|
||||||
|
{
|
||||||
|
if (oppDir != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (oppDir == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return laneNo;
|
||||||
|
};
|
||||||
|
|
||||||
|
int GetRightBoundLane(DRIVER2_ROAD_INFO& roadInfo, int oppDir)
|
||||||
|
{
|
||||||
|
int i, laneCount, laneNo;
|
||||||
|
|
||||||
|
laneCount = ROAD_WIDTH_IN_LANES(&roadInfo);
|
||||||
|
laneNo = ROAD_IS_LEFTMOST_LANE_PARKING(&roadInfo);
|
||||||
|
|
||||||
|
for (i = laneNo; i < laneCount; i++)
|
||||||
|
{
|
||||||
|
if (ROAD_IS_AI_LANE(&roadInfo, i) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, i))
|
||||||
|
{
|
||||||
|
test555 = ROAD_LANE_DIR(&roadInfo, i) ^ 1;
|
||||||
|
laneNo = i;
|
||||||
|
|
||||||
|
if (test555 == 0)
|
||||||
|
{
|
||||||
|
if (oppDir != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (oppDir == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return laneNo;
|
||||||
|
}
|
||||||
|
|
||||||
// [D] [T]
|
// [D] [T]
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -274,34 +336,22 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
DRIVER2_ROAD_INFO currentRoadInfo;
|
DRIVER2_ROAD_INFO currentRoadInfo;
|
||||||
DRIVER2_ROAD_INFO roadInfo;
|
DRIVER2_ROAD_INFO roadInfo;
|
||||||
|
|
||||||
int currentRoadId = 0;
|
|
||||||
int tmpNewRoad[2];
|
int tmpNewRoad[2];
|
||||||
int newExit = 0;
|
|
||||||
int tmpNewLane[2];
|
int tmpNewLane[2];
|
||||||
int laneFit[2];
|
int laneFit[2];
|
||||||
short validExitIdx[4];
|
short validExitIdx[4];
|
||||||
|
|
||||||
int newLane;
|
int newRoad, newLane, newExit, numExits;
|
||||||
int newRoad;
|
int currentRoadId, leftLane, rightLane;
|
||||||
|
|
||||||
int numExits;
|
int oppDir, oldOppDir;
|
||||||
int leftLane;
|
int turnDir, currentLaneDir;
|
||||||
int rightLane;
|
|
||||||
|
|
||||||
int oldOppDir;
|
|
||||||
int oppDir;
|
|
||||||
int turnDir;
|
|
||||||
int currentLaneDir;
|
|
||||||
|
|
||||||
currentRoadId = cp->ai.c.currentRoad;
|
currentRoadId = cp->ai.c.currentRoad;
|
||||||
|
|
||||||
if (GetSurfaceRoadInfo(¤tRoadInfo, currentRoadId))
|
if (GetSurfaceRoadInfo(¤tRoadInfo, currentRoadId))
|
||||||
{
|
{
|
||||||
int widthInLanes;
|
|
||||||
int laneNo;
|
int laneNo;
|
||||||
int count;
|
|
||||||
|
|
||||||
widthInLanes = ROAD_WIDTH_IN_LANES(¤tRoadInfo);
|
|
||||||
|
|
||||||
currentLaneDir = ROAD_LANE_DIR(¤tRoadInfo, cp->ai.c.currentLane);
|
currentLaneDir = ROAD_LANE_DIR(¤tRoadInfo, cp->ai.c.currentLane);
|
||||||
|
|
||||||
@ -315,76 +365,36 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
dx = oldNode->x - currentRoadInfo.curve->Midx;
|
dx = oldNode->x - currentRoadInfo.curve->Midx;
|
||||||
dz = oldNode->z - currentRoadInfo.curve->Midz;
|
dz = oldNode->z - currentRoadInfo.curve->Midz;
|
||||||
|
|
||||||
oldOppDir = DIFF_ANGLES(ratan2(dx, dz), oldNode->dir); // (((oldNode->dir - ratan2(dx, dz)) + 2048U & 0xfff) - 2048);
|
oldOppDir = DIFF_ANGLES(ratan2(dx, dz), oldNode->dir);
|
||||||
oldOppDir = (oldOppDir < 1) * 2048;
|
oldOppDir = (oldOppDir < 1) * 2048;
|
||||||
}
|
}
|
||||||
|
|
||||||
// first road is picked from road direction
|
// first road is picked from road direction
|
||||||
tmpNewRoad[0] = ((short*)currentRoadInfo.ConnectIdx)[(oldOppDir > 0) * 2];
|
tmpNewRoad[0] = currentRoadInfo.ConnectIdx[(oldOppDir > 0) * 2];
|
||||||
|
|
||||||
// and second picked from lane direction
|
// and second picked from lane direction
|
||||||
tmpNewRoad[1] = ((short*)currentRoadInfo.ConnectIdx)[(currentLaneDir > 0) ? 3 : 1];
|
tmpNewRoad[1] = currentRoadInfo.ConnectIdx[(currentLaneDir > 0) ? 3 : 1];
|
||||||
|
laneNo = GetLeftBoundLane(currentRoadInfo, currentLaneDir);
|
||||||
|
|
||||||
count = widthInLanes; // counter
|
if (oldOppDir == 0)
|
||||||
laneNo = widthInLanes; // bestLane
|
leftLane = laneNo;
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
count--;
|
|
||||||
if (ROAD_IS_AI_LANE(¤tRoadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(¤tRoadInfo, count))
|
|
||||||
{
|
|
||||||
test42 = ROAD_LANE_DIR(¤tRoadInfo, count);
|
|
||||||
laneNo = count;
|
|
||||||
}
|
|
||||||
} while (count >= 0);
|
|
||||||
|
|
||||||
if (currentLaneDir == 0)
|
|
||||||
leftLane = laneNo & 0xff;
|
|
||||||
else
|
else
|
||||||
rightLane = laneNo & 0xff;
|
rightLane = laneNo;
|
||||||
|
|
||||||
// ifhas fast lane, use second lane
|
laneNo = GetRightBoundLane(currentRoadInfo, currentLaneDir);
|
||||||
count = ROAD_HAS_FAST_LANES(¤tRoadInfo);
|
|
||||||
laneNo = widthInLanes;
|
|
||||||
|
|
||||||
while (count < widthInLanes)
|
if (oldOppDir != 0)
|
||||||
{
|
leftLane = laneNo;
|
||||||
if (ROAD_IS_AI_LANE(¤tRoadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(¤tRoadInfo, count))
|
|
||||||
{
|
|
||||||
test555 = ROAD_LANE_DIR(¤tRoadInfo, count) ^ 1;
|
|
||||||
laneNo = count;
|
|
||||||
|
|
||||||
if (test555 == 0)
|
|
||||||
{
|
|
||||||
if (currentLaneDir != 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (currentLaneDir == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
laneNo = widthInLanes;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentLaneDir != 0)
|
|
||||||
leftLane = laneNo & 0xff;
|
|
||||||
else
|
else
|
||||||
rightLane = laneNo & 0xff;
|
rightLane = laneNo;
|
||||||
}
|
}
|
||||||
|
|
||||||
newLane = -1;
|
newLane = -1;
|
||||||
|
|
||||||
if (IS_JUNCTION_SURFACE(tmpNewRoad[0]))
|
if (IS_JUNCTION_SURFACE(tmpNewRoad[0]))
|
||||||
{
|
{
|
||||||
int bestExit;
|
int exitFrom, exitCnt, bestExit;
|
||||||
|
|
||||||
int exitFrom;
|
|
||||||
int exitCnt;
|
|
||||||
int rnd;
|
int rnd;
|
||||||
numExits = 0;
|
|
||||||
|
|
||||||
cp->ai.c.changeLaneCount = 0;
|
cp->ai.c.changeLaneCount = 0;
|
||||||
jn = GET_JUNCTION(tmpNewRoad[0]);
|
jn = GET_JUNCTION(tmpNewRoad[0]);
|
||||||
@ -393,15 +403,13 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
|
|
||||||
// check if road is valid for this junction
|
// check if road is valid for this junction
|
||||||
// by determining connection with junction
|
// by determining connection with junction
|
||||||
exitCnt = 0;
|
for(exitCnt = 0; exitCnt < 4; exitCnt++)
|
||||||
while(exitCnt < 4)
|
|
||||||
{
|
{
|
||||||
if(jn->ExitIdx[exitCnt] == currentRoadId)
|
if(jn->ExitIdx[exitCnt] == currentRoadId)
|
||||||
{
|
{
|
||||||
exitFrom = exitCnt;
|
exitFrom = exitCnt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
exitCnt++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exitFrom == -1)
|
if (exitFrom == -1)
|
||||||
@ -411,45 +419,46 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check directions of exits
|
// check directions of exits
|
||||||
//printWarning("Checking directions, exitFrom: %d, \n", exitFrom);
|
numExits = 0;
|
||||||
exitCnt = 0;
|
|
||||||
do {
|
// only need 3 cycles because we don't want make U-turns
|
||||||
int exitSurfId;
|
for (exitCnt = 0; exitCnt < 3; exitCnt++)
|
||||||
int exitIdx = (exitFrom + exitCnt + 1) % 4;
|
{
|
||||||
int valid;
|
int exitSurfId, exitIdx, valid;
|
||||||
|
|
||||||
|
exitIdx = (exitFrom + exitCnt + 1) % 4;
|
||||||
|
|
||||||
valid = 0;
|
valid = 0;
|
||||||
exitSurfId = jn->ExitIdx[exitIdx];
|
exitSurfId = jn->ExitIdx[exitIdx];
|
||||||
|
|
||||||
if (exitSurfId != -1)
|
if (exitSurfId != -1)
|
||||||
{
|
{
|
||||||
|
int turnAng;
|
||||||
int exitDir;
|
int exitDir;
|
||||||
exitDir = ((exitIdx + 4) - exitFrom) % 4;
|
exitDir = ((exitIdx + 4) - exitFrom) % 4;
|
||||||
//exitDir = exitDir - (exitDir / 4) * 4;
|
|
||||||
|
|
||||||
if (exitDir == 1)
|
if (exitDir == 1)
|
||||||
*turnAngle = -1024; // left
|
turnAng = -1024; // left
|
||||||
else if (exitDir == 2)
|
else if (exitDir == 2)
|
||||||
*turnAngle = 0; // forward
|
turnAng = 0; // forward
|
||||||
else if (exitDir == 3)
|
else if (exitDir == 3)
|
||||||
*turnAngle = 1024; // right
|
turnAng = 1024; // right
|
||||||
else
|
else
|
||||||
*turnAngle = 0; // forward again?
|
turnAng = 0; // forward again?
|
||||||
|
|
||||||
test123 = 666;
|
test123 = 666;
|
||||||
test555 = 666;
|
test555 = 666;
|
||||||
test42 = 666;
|
test42 = 666;
|
||||||
|
|
||||||
// current node direction and new direction
|
// current node direction and new direction
|
||||||
turnDir = oldNode->dir + *turnAngle;
|
turnDir = oldNode->dir + turnAng;
|
||||||
|
|
||||||
if (GetSurfaceRoadInfo(&roadInfo, exitSurfId))
|
if (GetSurfaceRoadInfo(&roadInfo, exitSurfId))
|
||||||
{
|
{
|
||||||
int turnAng;
|
|
||||||
int dx, dz;
|
int dx, dz;
|
||||||
int laneCount;
|
int numLanes;
|
||||||
|
|
||||||
laneCount = ROAD_WIDTH_IN_LANES(&roadInfo);
|
numLanes = ROAD_WIDTH_IN_LANES(&roadInfo);
|
||||||
|
|
||||||
if(roadInfo.straight)
|
if(roadInfo.straight)
|
||||||
{
|
{
|
||||||
@ -460,94 +469,42 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
dx = oldNode->x - roadInfo.curve->Midx;
|
dx = oldNode->x - roadInfo.curve->Midx;
|
||||||
dz = oldNode->z - roadInfo.curve->Midz;
|
dz = oldNode->z - roadInfo.curve->Midz;
|
||||||
|
|
||||||
oppDir = DIFF_ANGLES(ratan2(dx, dz), turnDir);// ((turnDir - ratan2(dx, dz)) + 2048U & 0xfff) - 2048; // [A]
|
oppDir = DIFF_ANGLES(ratan2(dx, dz), turnDir);
|
||||||
oppDir = (oppDir < 1) * 2048;
|
oppDir = (oppDir < 1) * 2048;
|
||||||
}
|
}
|
||||||
|
|
||||||
turnAng = *turnAngle;
|
|
||||||
|
|
||||||
if (oppDir == 0)
|
|
||||||
turnAng = -turnAng;
|
|
||||||
|
|
||||||
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 = laneCount - (cp->ai.c.currentLane + 1);
|
newLane = numLanes - (cp->ai.c.currentLane + 1);
|
||||||
else
|
else
|
||||||
newLane = cp->ai.c.currentLane;
|
newLane = cp->ai.c.currentLane;
|
||||||
|
|
||||||
// goes on invalid lane?
|
|
||||||
// [A] bug fix with exitDir == 0
|
|
||||||
if (oppDir == 0 && exitDir == 0 || !ROAD_IS_AI_LANE(&roadInfo, newLane))
|
|
||||||
newLane = -1;
|
|
||||||
}
|
}
|
||||||
else if (turnAng == -1024) // going left
|
else if (turnAng == -1024) // going left
|
||||||
{
|
{
|
||||||
int count;
|
newLane = GetRightBoundLane(roadInfo, oppDir);
|
||||||
|
|
||||||
//printInfo("check left\n");
|
|
||||||
|
|
||||||
count = ROAD_HAS_FAST_LANES(&roadInfo); // lane counter
|
|
||||||
newLane = laneCount;
|
|
||||||
|
|
||||||
// check if allowed to go on any of lanes
|
|
||||||
while (count < laneCount)
|
|
||||||
{
|
|
||||||
if (ROAD_IS_AI_LANE(&roadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, count))
|
|
||||||
{
|
|
||||||
test555 = (ROAD_LANE_DIR(&roadInfo, count) ^ 1) & 1;
|
|
||||||
newLane = count;
|
|
||||||
|
|
||||||
if (test555 == 0)
|
|
||||||
{
|
|
||||||
if (oppDir != 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (oppDir == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
count++;
|
|
||||||
newLane = laneCount;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (turnAng == 1024)
|
else if (turnAng == 1024)
|
||||||
{
|
{
|
||||||
int count;
|
newLane = GetLeftBoundLane(roadInfo, oppDir);
|
||||||
|
|
||||||
count = laneCount; // lane counter
|
|
||||||
newLane = laneCount;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (ROAD_IS_AI_LANE(&roadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, count))
|
|
||||||
{
|
|
||||||
test42 = (ROAD_LANE_DIR(&roadInfo, count) ^ 1) & 1;
|
|
||||||
|
|
||||||
if (test42 == 0)
|
|
||||||
{
|
|
||||||
if (oppDir != 0)
|
|
||||||
newLane = count;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (oppDir == 0)
|
|
||||||
newLane = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
count--;
|
|
||||||
} while (count >= 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate lane
|
// validate lane
|
||||||
if (turnAng == 0 || newLane >= 0 && newLane < laneCount)
|
if (newLane >= 0 && newLane < numLanes)
|
||||||
{
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oppDir != oldOppDir)
|
||||||
|
{
|
||||||
|
if (currentLaneDir == ROAD_LANE_DIR(&roadInfo, newLane))
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (currentLaneDir != ROAD_LANE_DIR(&roadInfo, newLane))
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,10 +517,7 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
{
|
{
|
||||||
validExitIdx[exitCnt] = 42;
|
validExitIdx[exitCnt] = 42;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// only need 3 cycles because we don't want make U-turns
|
|
||||||
exitCnt++;
|
|
||||||
} while (exitCnt < 3);
|
|
||||||
|
|
||||||
if (leftLane != rightLane && numExits != 1 && ROAD_LANES_COUNT(¤tRoadInfo) > 1)
|
if (leftLane != rightLane && numExits != 1 && ROAD_LANES_COUNT(¤tRoadInfo) > 1)
|
||||||
{
|
{
|
||||||
@ -611,11 +565,9 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
|
|
||||||
newRoad = jn->ExitIdx[bestExit];
|
newRoad = jn->ExitIdx[bestExit];
|
||||||
|
|
||||||
if (turnAngle != NULL)
|
|
||||||
{
|
{
|
||||||
int invExit;
|
int invExit;
|
||||||
invExit = (bestExit + 4 - exitFrom) % 4;
|
invExit = (bestExit + 4 - exitFrom) % 4;
|
||||||
//invExit = invExit - (invExit / 4) * 4;
|
|
||||||
|
|
||||||
if (invExit == 1)
|
if (invExit == 1)
|
||||||
*turnAngle = -1024;
|
*turnAngle = -1024;
|
||||||
@ -691,9 +643,9 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
|
|
||||||
turnDir = oldNode->dir + *turnAngle;
|
turnDir = oldNode->dir + *turnAngle;
|
||||||
|
|
||||||
|
// determine the new lane on the new road
|
||||||
{
|
{
|
||||||
int numLanes;
|
int numLanes, turnAng;
|
||||||
int turnAng;
|
|
||||||
|
|
||||||
numLanes = ROAD_WIDTH_IN_LANES(&roadInfo);
|
numLanes = ROAD_WIDTH_IN_LANES(&roadInfo);
|
||||||
turnAng = *turnAngle;
|
turnAng = *turnAngle;
|
||||||
@ -708,7 +660,7 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
dx = oldNode->x - roadInfo.curve->Midx;
|
dx = oldNode->x - roadInfo.curve->Midx;
|
||||||
dz = oldNode->z - roadInfo.curve->Midz;
|
dz = oldNode->z - roadInfo.curve->Midz;
|
||||||
|
|
||||||
oppDir = DIFF_ANGLES(ratan2(dx, dz), turnDir); // (((turnDir - ratan2(dx, dz)) + 2048U & 0xfff) - 2048);
|
oppDir = DIFF_ANGLES(ratan2(dx, dz), turnDir);
|
||||||
oppDir = (oppDir < 1) * 2048;
|
oppDir = (oppDir < 1) * 2048;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,68 +689,14 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
}
|
}
|
||||||
else if (turnAng == -1024)
|
else if (turnAng == -1024)
|
||||||
{
|
{
|
||||||
int count;
|
newLane = GetRightBoundLane(roadInfo, oppDir);
|
||||||
|
|
||||||
count = ROAD_HAS_FAST_LANES(&roadInfo);
|
|
||||||
newLane = numLanes;
|
|
||||||
|
|
||||||
// check if allowed to go on any of lanes
|
|
||||||
while (count < numLanes)
|
|
||||||
{
|
|
||||||
if (ROAD_IS_AI_LANE(&roadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, count))
|
|
||||||
{
|
|
||||||
test555 = (ROAD_LANE_DIR(&roadInfo, count) ^ 1) & 1;
|
|
||||||
newLane = count;
|
|
||||||
|
|
||||||
if (test555 == 0)
|
|
||||||
{
|
|
||||||
if (oppDir != 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (oppDir == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
count++;
|
|
||||||
newLane = numLanes;
|
|
||||||
}
|
|
||||||
|
|
||||||
//printWarning("car %d check left lane, chosen %d\n", cp->id, newLane);
|
|
||||||
}
|
}
|
||||||
else if (turnAng == 1024)
|
else if (turnAng == 1024)
|
||||||
{
|
{
|
||||||
int count;
|
newLane = GetLeftBoundLane(roadInfo, oppDir);
|
||||||
|
|
||||||
count = numLanes;
|
|
||||||
newLane = numLanes;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (ROAD_IS_AI_LANE(&roadInfo, count) && !ROAD_IS_PARKING_ALLOWED_AT(&roadInfo, count))
|
|
||||||
{
|
|
||||||
test42 = (ROAD_LANE_DIR(&roadInfo, count) ^ 1) & 1;
|
|
||||||
|
|
||||||
if (test42 == 0)
|
|
||||||
{
|
|
||||||
if (oppDir != 0)
|
|
||||||
newLane = count;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (oppDir == 0)
|
|
||||||
newLane = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
count--;
|
|
||||||
} while (count >= 0);
|
|
||||||
|
|
||||||
//printWarning("car %d check right lane, chosen %d\n", cp->id, newLane);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (*turnAngle != 0)
|
if (*turnAngle != 0)
|
||||||
{
|
{
|
||||||
if (numLanes - 1 == newLane)
|
if (numLanes - 1 == newLane)
|
||||||
@ -843,11 +741,23 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
{
|
{
|
||||||
if (tmpNewRoad[roadCnt] != -1)
|
if (tmpNewRoad[roadCnt] != -1)
|
||||||
{
|
{
|
||||||
|
int px, pz;
|
||||||
int dx, dz;
|
int dx, dz;
|
||||||
int numLanes;
|
int numLanes;
|
||||||
|
|
||||||
numLanes = 0;
|
numLanes = 0;
|
||||||
|
|
||||||
|
// [A] fix lane changingg issues
|
||||||
|
if(cp->ai.c.changeLaneCount > 0)
|
||||||
|
{
|
||||||
|
GetNodePos(currentRoadInfo.straight, NULL, currentRoadInfo.curve, oldNode->distAlongSegment, NULL, &px, &pz, cp->ai.c.currentLane);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
px = oldNode->x;
|
||||||
|
pz = oldNode->z;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetSurfaceRoadInfo(&roadInfo, tmpNewRoad[roadCnt]))
|
if (GetSurfaceRoadInfo(&roadInfo, tmpNewRoad[roadCnt]))
|
||||||
{
|
{
|
||||||
numLanes = ROAD_WIDTH_IN_LANES(&roadInfo);
|
numLanes = ROAD_WIDTH_IN_LANES(&roadInfo);
|
||||||
@ -855,8 +765,8 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
// determine new lane by old node position
|
// determine new lane by old node position
|
||||||
if(roadInfo.straight)
|
if(roadInfo.straight)
|
||||||
{
|
{
|
||||||
dx = (oldNode->x - roadInfo.straight->Midx);
|
dx = (px - roadInfo.straight->Midx);
|
||||||
dz = (oldNode->z - roadInfo.straight->Midz);
|
dz = (pz - roadInfo.straight->Midz);
|
||||||
|
|
||||||
tmpNewLane[roadCnt] = ROAD_LANES_COUNT(&roadInfo)
|
tmpNewLane[roadCnt] = ROAD_LANES_COUNT(&roadInfo)
|
||||||
- (FIXEDH(dx * RCOS(roadInfo.straight->angle) - dz * RSIN(roadInfo.straight->angle)) + 512 >> 9);
|
- (FIXEDH(dx * RCOS(roadInfo.straight->angle) - dz * RSIN(roadInfo.straight->angle)) + 512 >> 9);
|
||||||
@ -864,8 +774,8 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dx = oldNode->x - roadInfo.curve->Midx;
|
dx = px - roadInfo.curve->Midx;
|
||||||
dz = oldNode->z - roadInfo.curve->Midz;
|
dz = pz - roadInfo.curve->Midz;
|
||||||
|
|
||||||
tmpNewLane[roadCnt] = (SquareRoot0(dx * dx + dz * dz) >> 9) - roadInfo.curve->inside * 2;
|
tmpNewLane[roadCnt] = (SquareRoot0(dx * dx + dz * dz) >> 9) - roadInfo.curve->inside * 2;
|
||||||
}
|
}
|
||||||
@ -882,7 +792,6 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// fit new lane
|
// fit new lane
|
||||||
newLane = tmpNewLane[roadCnt];
|
newLane = tmpNewLane[roadCnt];
|
||||||
|
|
||||||
@ -1055,11 +964,44 @@ void InitNodeList(CAR_DATA* cp, EXTRA_CIV_DATA* extraData)
|
|||||||
cr->distAlongSegment = extraData->distAlongSegment;
|
cr->distAlongSegment = extraData->distAlongSegment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [A] bug fixes the incorrect lane changes
|
||||||
|
void RemapLaneChange(CAR_DATA* cp)
|
||||||
|
{
|
||||||
|
CIV_ROUTE_ENTRY* currentNode;
|
||||||
|
DRIVER2_ROAD_INFO roadInfo;
|
||||||
|
int numLanes, dx, dz;
|
||||||
|
int newLane;
|
||||||
|
|
||||||
|
if (!GetSurfaceRoadInfo(&roadInfo, cp->ai.c.currentRoad))
|
||||||
|
return;
|
||||||
|
|
||||||
|
currentNode = &cp->ai.c.targetRoute[cp->ai.c.currentNode];
|
||||||
|
numLanes = ROAD_WIDTH_IN_LANES(&roadInfo);
|
||||||
|
|
||||||
|
// determine lane on new road by old node position
|
||||||
|
if (roadInfo.straight)
|
||||||
|
{
|
||||||
|
dx = (currentNode->x - roadInfo.straight->Midx);
|
||||||
|
dz = (currentNode->z - roadInfo.straight->Midz);
|
||||||
|
|
||||||
|
newLane = ROAD_LANES_COUNT(&roadInfo)
|
||||||
|
- (FIXEDH(dx * RCOS(roadInfo.straight->angle) - dz * RSIN(roadInfo.straight->angle)) + 512 >> 9);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dx = currentNode->x - roadInfo.curve->Midx;
|
||||||
|
dz = currentNode->z - roadInfo.curve->Midz;
|
||||||
|
|
||||||
|
newLane = (SquareRoot0(dx * dx + dz * dz) >> 9) - roadInfo.curve->inside * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
cp->ai.c.currentLane = newLane;
|
||||||
|
}
|
||||||
|
|
||||||
// [D] [T]
|
// [D] [T]
|
||||||
int GetNodePos(DRIVER2_STRAIGHT* straight, DRIVER2_JUNCTION* junction, DRIVER2_CURVE* curve, int distAlongPath, CAR_DATA* cp, int* x, int* z, int laneNo)
|
int GetNodePos(DRIVER2_STRAIGHT* straight, DRIVER2_JUNCTION* junction, DRIVER2_CURVE* curve, int distAlongPath, CAR_DATA* cp, int* x, int* z, int laneNo)
|
||||||
{
|
{
|
||||||
unsigned char oldLane;
|
u_char oldLane, changeLaneCount;
|
||||||
unsigned char changeLaneCount;
|
|
||||||
int angle;
|
int angle;
|
||||||
int distFromCentre;
|
int distFromCentre;
|
||||||
int sideShift;
|
int sideShift;
|
||||||
@ -1135,13 +1077,10 @@ int GetNodePos(DRIVER2_STRAIGHT* straight, DRIVER2_JUNCTION* junction, DRIVER2_C
|
|||||||
// [D] [T]
|
// [D] [T]
|
||||||
int CheckChangeLanes(DRIVER2_STRAIGHT* straight, DRIVER2_CURVE* curve, int distAlongSegment, CAR_DATA* cp, int tryToPark)
|
int CheckChangeLanes(DRIVER2_STRAIGHT* straight, DRIVER2_CURVE* curve, int distAlongSegment, CAR_DATA* cp, int tryToPark)
|
||||||
{
|
{
|
||||||
int oldLane;
|
int oldLane, newLane, currentLane;
|
||||||
int currentLane;
|
|
||||||
int newLane;
|
|
||||||
int trials;
|
int trials;
|
||||||
CAR_COSMETICS* car_cos;
|
CAR_COSMETICS* car_cos;
|
||||||
int dx;
|
int dx, dz;
|
||||||
int dz;
|
|
||||||
u_int theta;
|
u_int theta;
|
||||||
int length;
|
int length;
|
||||||
CAR_DATA* lcp;
|
CAR_DATA* lcp;
|
||||||
@ -2244,7 +2183,7 @@ int PingInCivCar(int minPingInDist)
|
|||||||
// this is closest to OG decompiled. Works different!
|
// this is closest to OG decompiled. Works different!
|
||||||
//if ((
|
//if ((
|
||||||
// ((tryPingInParkedCars && allowedToPark))) ||
|
// ((tryPingInParkedCars && allowedToPark))) ||
|
||||||
// ((ROAD_IS_AI_LANE(straight, i) && (((i != 0 || ((straight->NumLanes & 0x40U) == 0)) && (((straight->NumLanes & 0xffffff0f) * 2 - 1 != i || ((straight->NumLanes & 0x80U) == 0))))))))
|
// ((ROAD_IS_AI_LANE(&roadInfo, i) && (((i != 0 || ((roadInfo.NumLanes & 0x40U) == 0)) && (((roadInfo.NumLanes & 0xffffff0f) * 2 - 1 != i || ((roadInfo.NumLanes & 0x80U) == 0))))))))
|
||||||
|
|
||||||
// pick only non-parkable driveable lanes if parked cars not requested
|
// pick only non-parkable driveable lanes if parked cars not requested
|
||||||
if (tryPingInParkedCars && allowedToPark || ROAD_IS_AI_LANE(&roadInfo, i) && !allowedToPark)
|
if (tryPingInParkedCars && allowedToPark || ROAD_IS_AI_LANE(&roadInfo, i) && !allowedToPark)
|
||||||
@ -2943,7 +2882,7 @@ void SetUpCivCollFlags(void)
|
|||||||
|
|
||||||
if (ABS(cd[0].x.vx - cd[1].x.vx) >= dist ||
|
if (ABS(cd[0].x.vx - cd[1].x.vx) >= dist ||
|
||||||
ABS(cd[0].x.vz - cd[1].x.vz) >= dist ||
|
ABS(cd[0].x.vz - cd[1].x.vz) >= dist ||
|
||||||
isTanner && ABS(cd[0].x.vy - cd[1].x.vy) >= 500)
|
ABS(cd[0].x.vy - cd[1].x.vy) >= 500)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -3251,10 +3190,8 @@ int CivFindPointOnPath(CAR_DATA * cp, int station, VECTOR * ppoint)
|
|||||||
CIV_ROUTE_ENTRY* start;
|
CIV_ROUTE_ENTRY* start;
|
||||||
CIV_ROUTE_ENTRY* currentNode;
|
CIV_ROUTE_ENTRY* currentNode;
|
||||||
CIV_ROUTE_ENTRY* retNode;
|
CIV_ROUTE_ENTRY* retNode;
|
||||||
int dx;
|
int dx, dz;
|
||||||
int dz;
|
int sx, sz;
|
||||||
int sx;
|
|
||||||
int sz;
|
|
||||||
|
|
||||||
start = cp->ai.c.pnode;
|
start = cp->ai.c.pnode;
|
||||||
|
|
||||||
@ -3741,8 +3678,8 @@ int CivControl(CAR_DATA* cp)
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
//maxCivCars = 2;
|
//maxCivCars = 2;
|
||||||
//maxCopCars = 0;
|
//maxCopCars = 0;
|
||||||
|
|
||||||
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);
|
||||||
|
@ -25,6 +25,22 @@ CAR_COSMETICS car_cosmetics[MAX_CAR_MODELS];
|
|||||||
CAR_COSMETICS levelSpecCosmetics[5];
|
CAR_COSMETICS levelSpecCosmetics[5];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PSX
|
||||||
|
// [A] loads car cosmetics from file
|
||||||
|
void LoadCustomCarCosmetics(CAR_COSMETICS* dest, int modelNumber)
|
||||||
|
{
|
||||||
|
char filename[64];
|
||||||
|
|
||||||
|
sprintf(filename, "LEVELS\\%s\\CARMODEL_%d.COS", LevelNames[GameLevel], modelNumber);
|
||||||
|
if (!FileExists(filename))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadfileSeg(filename, (char*)dest, 0, sizeof(CAR_COSMETICS));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// [D] [T]
|
// [D] [T]
|
||||||
void ProcessCosmeticsLump(char *lump_ptr, int lump_size)
|
void ProcessCosmeticsLump(char *lump_ptr, int lump_size)
|
||||||
{
|
{
|
||||||
@ -51,6 +67,9 @@ void ProcessCosmeticsLump(char *lump_ptr, int lump_size)
|
|||||||
offset = *(int*)(lump_ptr + model * sizeof(int));
|
offset = *(int*)(lump_ptr + model * sizeof(int));
|
||||||
car_cosmetics[i] = *(CAR_COSMETICS*)((u_char*)lump_ptr + offset);
|
car_cosmetics[i] = *(CAR_COSMETICS*)((u_char*)lump_ptr + offset);
|
||||||
|
|
||||||
|
#ifndef PSX
|
||||||
|
LoadCustomCarCosmetics(&car_cosmetics[i], model);
|
||||||
|
#endif
|
||||||
FixCarCos(&car_cosmetics[i], model);
|
FixCarCos(&car_cosmetics[i], model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,55 +86,6 @@ void FreeCutsceneBuffer();
|
|||||||
int IsCutsceneResident(int cutscene);
|
int IsCutsceneResident(int cutscene);
|
||||||
|
|
||||||
|
|
||||||
#ifndef PSX
|
|
||||||
char gUserReplayFolderList[MAX_USER_REPLAYS][48];
|
|
||||||
int gNumUserChases = 0;
|
|
||||||
int gUserChaseLoaded = -1;
|
|
||||||
|
|
||||||
// [A] user replay folders initialization
|
|
||||||
void InitUserReplays(const char* str)
|
|
||||||
{
|
|
||||||
int quit;
|
|
||||||
char* ptr;
|
|
||||||
char* strStart;
|
|
||||||
gNumUserChases = 0;
|
|
||||||
|
|
||||||
if (!str)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ptr = (char*)str;
|
|
||||||
strStart = NULL;
|
|
||||||
memset(gUserReplayFolderList, 0, sizeof(gUserReplayFolderList));
|
|
||||||
|
|
||||||
quit = 0;
|
|
||||||
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
if (strStart == NULL)
|
|
||||||
strStart = ptr;
|
|
||||||
|
|
||||||
// if we're encountered string end go on
|
|
||||||
if(*ptr == ',' || *ptr == ' ' || *ptr == '\0')
|
|
||||||
{
|
|
||||||
if (*ptr == '\0')
|
|
||||||
quit = 1;
|
|
||||||
|
|
||||||
*ptr = '\0';
|
|
||||||
strcpy(gUserReplayFolderList[gNumUserChases++], strStart);
|
|
||||||
strStart = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr++;
|
|
||||||
|
|
||||||
if (quit)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// [D] [T]
|
// [D] [T]
|
||||||
void InitInGameCutsceneVariables(void)
|
void InitInGameCutsceneVariables(void)
|
||||||
{
|
{
|
||||||
@ -159,10 +110,6 @@ void InitInGameCutsceneVariables(void)
|
|||||||
|
|
||||||
gSkipInGameCutscene = 0;
|
gSkipInGameCutscene = 0;
|
||||||
|
|
||||||
#ifndef PSX
|
|
||||||
gUserChaseLoaded = -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FreeCutsceneBuffer();
|
FreeCutsceneBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,18 +183,6 @@ void DrawInGameCutscene(void)
|
|||||||
|
|
||||||
if (gInGameCutsceneActive == 0 && gInGameCutsceneDelay == 0)
|
if (gInGameCutsceneActive == 0 && gInGameCutsceneDelay == 0)
|
||||||
{
|
{
|
||||||
#ifndef PSX
|
|
||||||
if(gInGameChaseActive && gUserChaseLoaded != -1 && (CameraCnt - frameStart) < 200)
|
|
||||||
{
|
|
||||||
// [A] print user chaser name on screen
|
|
||||||
char tempStr[80];
|
|
||||||
|
|
||||||
sprintf(tempStr, "%s %s", G_LTXT(GTXT_GetawayIs), gUserReplayFolderList[gUserChaseLoaded]);
|
|
||||||
|
|
||||||
SetTextColour(128, 128, 64);
|
|
||||||
PrintString(tempStr, gOverlayXPos, 230);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,34 +327,8 @@ int SelectCutsceneFile(char* filename, int init, int subindex)
|
|||||||
if (init)
|
if (init)
|
||||||
{
|
{
|
||||||
// try load replacement bundle
|
// try load replacement bundle
|
||||||
#ifndef PSX
|
sprintf(filename, "REPLAYS\\ReChases\\CUT%d_N.R", gCurrentMissionNumber);
|
||||||
int userId = -1;
|
gReChaseAvailable = FileExists(filename);
|
||||||
|
|
||||||
// [A] REDRIVER2 PC - custom user chases
|
|
||||||
if (gNumUserChases)
|
|
||||||
{
|
|
||||||
userId = rand() % (gNumUserChases + 1);
|
|
||||||
|
|
||||||
// if random decides to have no user chase - get og or replacement one
|
|
||||||
if (userId == gNumUserChases)
|
|
||||||
userId = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try loading user chase
|
|
||||||
if (userId != -1)
|
|
||||||
sprintf(filename, "REPLAYS\\UserChases\\%s\\CUT%d_N.R", (char*)gUserReplayFolderList[userId], gCurrentMissionNumber);
|
|
||||||
|
|
||||||
if (FileExists(filename))
|
|
||||||
{
|
|
||||||
gUserChaseLoaded = userId;
|
|
||||||
gReChaseAvailable = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
sprintf(filename, "REPLAYS\\ReChases\\CUT%d_N.R", gCurrentMissionNumber);
|
|
||||||
gReChaseAvailable = FileExists(filename);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subindex >= 2)
|
if (subindex >= 2)
|
||||||
@ -427,21 +336,14 @@ int SelectCutsceneFile(char* filename, int init, int subindex)
|
|||||||
if (gReChaseAvailable == 1)
|
if (gReChaseAvailable == 1)
|
||||||
{
|
{
|
||||||
sprintf(filename, "REPLAYS\\ReChases\\CUT%d_N.R", gCurrentMissionNumber);
|
sprintf(filename, "REPLAYS\\ReChases\\CUT%d_N.R", gCurrentMissionNumber);
|
||||||
|
return FileExists(filename);
|
||||||
}
|
}
|
||||||
#ifndef PSX
|
|
||||||
else if (gUserChaseLoaded != -1)
|
|
||||||
{
|
|
||||||
sprintf(filename, "REPLAYS\\UserChases\\%s\\CUT%d_N.R", (char*)gUserReplayFolderList[gUserChaseLoaded], gCurrentMissionNumber);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gCurrentMissionNumber < 21)
|
||||||
|
sprintf(filename, "REPLAYS\\CUT%d.R", gCurrentMissionNumber);
|
||||||
else
|
else
|
||||||
{
|
sprintf(filename, "REPLAYS\\A\\CUT%d.R", gCurrentMissionNumber);
|
||||||
if (gCurrentMissionNumber < 21)
|
|
||||||
sprintf(filename, "REPLAYS\\CUT%d.R", gCurrentMissionNumber);
|
|
||||||
else
|
|
||||||
sprintf(filename, "REPLAYS\\A\\CUT%d.R", gCurrentMissionNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FileExists(filename);
|
return FileExists(filename);
|
||||||
}
|
}
|
||||||
@ -462,7 +364,7 @@ int CalcInGameCutsceneSize(void)
|
|||||||
LoadfileSeg(filename, (char*)&CutsceneHeader, 0, sizeof(CUTSCENE_HEADER));
|
LoadfileSeg(filename, (char*)&CutsceneHeader, 0, sizeof(CUTSCENE_HEADER));
|
||||||
|
|
||||||
// load re-chase file header
|
// load re-chase file header
|
||||||
if(SelectCutsceneFile(filename, 0, 2))
|
if (SelectCutsceneFile(filename, 0, 2))
|
||||||
LoadfileSeg(filename, (char*)&ChaseHeader, 0, sizeof(CUTSCENE_HEADER));
|
LoadfileSeg(filename, (char*)&ChaseHeader, 0, sizeof(CUTSCENE_HEADER));
|
||||||
|
|
||||||
maxSize = 0;
|
maxSize = 0;
|
||||||
|
@ -13,16 +13,6 @@ struct CUTSCENE_HEADER
|
|||||||
CUTSCENE_INFO data[15];
|
CUTSCENE_INFO data[15];
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef PSX
|
|
||||||
#define MAX_USER_REPLAYS 16
|
|
||||||
|
|
||||||
extern char gUserReplayFolderList[MAX_USER_REPLAYS][48];
|
|
||||||
extern int gNumUserChases;
|
|
||||||
|
|
||||||
extern void InitUserReplays(const char* str);
|
|
||||||
|
|
||||||
#endif // PSX
|
|
||||||
|
|
||||||
extern int NumCutsceneStreams;
|
extern int NumCutsceneStreams;
|
||||||
extern int gSkipInGameCutscene;
|
extern int gSkipInGameCutscene;
|
||||||
extern int gInGameCutsceneID;
|
extern int gInGameCutsceneID;
|
||||||
|
@ -2054,18 +2054,17 @@ void ShowLight(VECTOR *v1, CVECTOR *col, short size, TEXTURE_DETAILS *texture)
|
|||||||
if (z < 0)
|
if (z < 0)
|
||||||
z = 0;
|
z = 0;
|
||||||
|
|
||||||
if (z < 10000)
|
|
||||||
tail_width = (10000 - z) >> 0xd;
|
|
||||||
else
|
|
||||||
tail_width = 0;
|
|
||||||
|
|
||||||
addPrim(current->ot + z, poly);
|
addPrim(current->ot + z, poly);
|
||||||
current->primptr += sizeof(POLY_FT4);
|
current->primptr += sizeof(POLY_FT4);
|
||||||
|
|
||||||
|
|
||||||
if (CameraCnt <= 4 || NumPlayers > 1) // [A] don't draw trails in multiplayer
|
if (CameraCnt <= 4 || NumPlayers > 1) // [A] don't draw trails in multiplayer
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (z < 10000)
|
||||||
|
tail_width = (10000 - z) >> 13;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
if ((col->cd & 0x20) && gLightsOn)
|
if ((col->cd & 0x20) && gLightsOn)
|
||||||
{
|
{
|
||||||
trails = Known_Lamps[LightIndex].light_trails;
|
trails = Known_Lamps[LightIndex].light_trails;
|
||||||
@ -2093,15 +2092,15 @@ void ShowLight(VECTOR *v1, CVECTOR *col, short size, TEXTURE_DETAILS *texture)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PSX
|
#ifndef PSX
|
||||||
x = (poly->x0 + poly->x3) / 2.0f;
|
x = (poly->x0 + poly->x3) * 0.5f;
|
||||||
y = (poly->y0 + poly->y3) / 2.0f;
|
y = (poly->y0 + poly->y3) * 0.5f;
|
||||||
#else
|
#else
|
||||||
x = (poly->x0 + poly->x3) / 2;
|
x = (poly->x0 + poly->x3) / 2;
|
||||||
y = (poly->y0 + poly->y3) / 2;
|
y = (poly->y0 + poly->y3) / 2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// unified drawing both for car and lamps
|
// unified drawing both for car and lamps
|
||||||
if (CameraChanged == 0 && *clock == (FrameCnt & 0xffffU)-1)
|
if (CameraChanged == 0 && *clock == (FrameCnt & 0xffffU) - 1)
|
||||||
{
|
{
|
||||||
int old_x, old_y;
|
int old_x, old_y;
|
||||||
|
|
||||||
@ -2114,7 +2113,11 @@ void ShowLight(VECTOR *v1, CVECTOR *col, short size, TEXTURE_DETAILS *texture)
|
|||||||
if (size > 1 && ABS(old_x - x) + ABS(old_y - y) > 1)
|
if (size > 1 && ABS(old_x - x) + ABS(old_y - y) > 1)
|
||||||
{
|
{
|
||||||
int angle, width;
|
int angle, width;
|
||||||
VERTTYPE dx, dy;
|
#ifdef PSX
|
||||||
|
int dx, dy;
|
||||||
|
#else
|
||||||
|
float dx, dy;
|
||||||
|
#endif
|
||||||
|
|
||||||
trail = (POLY_G4 *)current->primptr;
|
trail = (POLY_G4 *)current->primptr;
|
||||||
|
|
||||||
@ -2124,21 +2127,20 @@ void ShowLight(VECTOR *v1, CVECTOR *col, short size, TEXTURE_DETAILS *texture)
|
|||||||
angle = -ratan2(old_x - x,old_y - y) & 0xfff;
|
angle = -ratan2(old_x - x,old_y - y) & 0xfff;
|
||||||
width = ABS(poly->x0 - poly->x3);
|
width = ABS(poly->x0 - poly->x3);
|
||||||
|
|
||||||
#ifdef PSX
|
|
||||||
dx = RCOS(angle) * width * 3;
|
dx = RCOS(angle) * width * 3;
|
||||||
dy = RSIN(angle) * width * 3;
|
dy = RSIN(angle) * width * 3;
|
||||||
|
|
||||||
if (col->cd & 0x40)
|
if (col->cd & 0x40)
|
||||||
{
|
{
|
||||||
dx >>= 0x10;
|
dx /= 1 << 16;
|
||||||
dy >>= 0x10;
|
dy /= 1 << 16;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dx >>= 0xf;
|
dx /= 1 << 15;
|
||||||
dy >>= 0xf;
|
dy /= 1 << 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
trail->x0 = x + dx * tail_width;
|
trail->x0 = x + dx * tail_width;
|
||||||
trail->y0 = y + dy * tail_width;
|
trail->y0 = y + dy * tail_width;
|
||||||
|
|
||||||
@ -2150,34 +2152,6 @@ void ShowLight(VECTOR *v1, CVECTOR *col, short size, TEXTURE_DETAILS *texture)
|
|||||||
|
|
||||||
trail->x3 = old_x - dx;
|
trail->x3 = old_x - dx;
|
||||||
trail->y3 = old_y - dy;
|
trail->y3 = old_y - dy;
|
||||||
#else
|
|
||||||
// [A] slightly bigger light trail
|
|
||||||
dx = RCOS(angle);
|
|
||||||
dy = RSIN(angle);
|
|
||||||
|
|
||||||
if (col->cd & 0x40)
|
|
||||||
{
|
|
||||||
dx = dx / 40000.0f;
|
|
||||||
dy = dy / 40000.0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dx = dx / 32768.0f;
|
|
||||||
dy = dy / 32768.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
trail->x0 = x + dx * width * 3 * tail_width;
|
|
||||||
trail->y0 = y + dy * width * 3 * tail_width;
|
|
||||||
|
|
||||||
trail->x1 = x - dx * width * 3 * tail_width;
|
|
||||||
trail->y1 = y - dy * width * 3 * tail_width;
|
|
||||||
|
|
||||||
trail->x2 = old_x + dx * width * 3;
|
|
||||||
trail->y2 = old_y + dy * width * 3;
|
|
||||||
|
|
||||||
trail->x3 = old_x - dx * width * 3;
|
|
||||||
trail->y3 = old_y - dy * width * 3;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (col->cd & 0x18)
|
if (col->cd & 0x18)
|
||||||
{
|
{
|
||||||
@ -2212,8 +2186,8 @@ void ShowLight(VECTOR *v1, CVECTOR *col, short size, TEXTURE_DETAILS *texture)
|
|||||||
|
|
||||||
addPrim(current->ot + z, null);
|
addPrim(current->ot + z, null);
|
||||||
current->primptr += sizeof(POLY_FT3);
|
current->primptr += sizeof(POLY_FT3);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
|
@ -101,7 +101,7 @@ int GetSurfaceRoadInfo(DRIVER2_ROAD_INFO* outRoadInfo, int surfId)
|
|||||||
if(IS_CURVED_SURFACE(surfId))
|
if(IS_CURVED_SURFACE(surfId))
|
||||||
{
|
{
|
||||||
outRoadInfo->curve = curve = GET_CURVE(surfId);
|
outRoadInfo->curve = curve = GET_CURVE(surfId);
|
||||||
outRoadInfo->ConnectIdx = &curve->ConnectIdx;
|
outRoadInfo->ConnectIdx = curve->ConnectIdx;
|
||||||
outRoadInfo->NumLanes = curve->NumLanes;
|
outRoadInfo->NumLanes = curve->NumLanes;
|
||||||
outRoadInfo->LaneDirs = curve->LaneDirs;
|
outRoadInfo->LaneDirs = curve->LaneDirs;
|
||||||
outRoadInfo->AILanes = curve->AILanes;
|
outRoadInfo->AILanes = curve->AILanes;
|
||||||
@ -110,7 +110,7 @@ int GetSurfaceRoadInfo(DRIVER2_ROAD_INFO* outRoadInfo, int surfId)
|
|||||||
else if (IS_STRAIGHT_SURFACE(surfId))
|
else if (IS_STRAIGHT_SURFACE(surfId))
|
||||||
{
|
{
|
||||||
outRoadInfo->straight = straight = GET_STRAIGHT(surfId);
|
outRoadInfo->straight = straight = GET_STRAIGHT(surfId);
|
||||||
outRoadInfo->ConnectIdx = &straight->ConnectIdx;
|
outRoadInfo->ConnectIdx = straight->ConnectIdx;
|
||||||
outRoadInfo->NumLanes = straight->NumLanes;
|
outRoadInfo->NumLanes = straight->NumLanes;
|
||||||
outRoadInfo->LaneDirs = straight->LaneDirs;
|
outRoadInfo->LaneDirs = straight->LaneDirs;
|
||||||
outRoadInfo->AILanes = straight->AILanes;
|
outRoadInfo->AILanes = straight->AILanes;
|
||||||
@ -119,7 +119,7 @@ int GetSurfaceRoadInfo(DRIVER2_ROAD_INFO* outRoadInfo, int surfId)
|
|||||||
else if (IS_JUNCTION_SURFACE(surfId))
|
else if (IS_JUNCTION_SURFACE(surfId))
|
||||||
{
|
{
|
||||||
junction = GET_JUNCTION(surfId);
|
junction = GET_JUNCTION(surfId);
|
||||||
outRoadInfo->ConnectIdx = &junction->ExitIdx;
|
outRoadInfo->ConnectIdx = junction->ExitIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -12,20 +12,25 @@
|
|||||||
#define GET_CURVE(surfid) (Driver2CurvesPtr + ((surfid) & 0x1FFF))
|
#define GET_CURVE(surfid) (Driver2CurvesPtr + ((surfid) & 0x1FFF))
|
||||||
#define GET_JUNCTION(surfid) (Driver2JunctionsPtr + ((surfid) & 0x1FFF))
|
#define GET_JUNCTION(surfid) (Driver2JunctionsPtr + ((surfid) & 0x1FFF))
|
||||||
|
|
||||||
|
// AI lanes - each bit represents lane being enabled for Civ AI to be driven
|
||||||
|
// Lane dirs - each bit represents lane direction invertion
|
||||||
|
// NumLanes - | Lane count (4 bits - max 15) | speed limit id (2 bits - max 3) | Leftmost Lane parking | Rightmost Lane parking
|
||||||
|
|
||||||
// $DEPRECATED: as it's used to detect lane direction, use ROAD_LANE_DIR instead
|
// $DEPRECATED: as it's used to detect lane direction, use ROAD_LANE_DIR instead
|
||||||
#define IS_NARROW_ROAD(rd) \
|
#define IS_NARROW_ROAD(rd) \
|
||||||
((*(ushort*)&(rd)->NumLanes & 0xFFFF) == 0xFF01)
|
((*(ushort*)&(rd)->NumLanes & 0xFFFF) == 0xFF01)
|
||||||
|
|
||||||
// those macros can be applied to straights and junctions
|
// those macros can be applied to straights and junctions
|
||||||
#define ROAD_LANES_COUNT(rd) ((u_int)(rd)->NumLanes & 0xF) // lane count
|
#define ROAD_IS_AI_LANE(rd, lane) ((u_char)(rd)->AILanes >> ((lane) / 2) & 1U) // lane AI driveable flag
|
||||||
#define ROAD_WIDTH_IN_LANES(rd) (ROAD_LANES_COUNT(rd) * 2) // width in lanes
|
#define ROAD_LANE_DIRECTION_BIT(rd, lane) ((u_char)(rd)->LaneDirs >> ((lane) / 2) & 1U) // direction bit
|
||||||
#define ROAD_IS_AI_LANE(rd, lane) ((u_char)(rd)->AILanes >> ((lane) / 2) & 1U) // lane AI driveable flag
|
|
||||||
#define ROAD_IS_LEFTMOST_LANE_PARKING(rd) (((u_char)(rd)->NumLanes & 0x40) != 0) // allows parking on leftmost lane
|
|
||||||
#define ROAD_IS_RIGHTMOST_LANE_PARKING(rd) (((u_char)(rd)->NumLanes & 0x80) != 0) // allows parking on rightmost lane
|
|
||||||
#define ROAD_LANE_DIRECTION_BIT(rd, lane) ((u_char)(rd)->LaneDirs >> ((lane) / 2) & 1U) // direction bit
|
|
||||||
#define ROAD_SPEED_LIMIT(rd) (((u_char)(rd)->NumLanes >> 4) & 3) // speed limit id
|
|
||||||
#define ROAD_HAS_FAST_LANES(rd) (((u_char)(rd)->NumLanes >> 6) & 1) // & 0x20; in fact speed limit check too
|
|
||||||
|
|
||||||
|
#define ROAD_LANES_COUNT(rd) ((u_int)(rd)->NumLanes & 15) // lane count
|
||||||
|
#define ROAD_WIDTH_IN_LANES(rd) (ROAD_LANES_COUNT(rd) * 2) // width in lanes
|
||||||
|
|
||||||
|
#define ROAD_IS_LEFTMOST_LANE_PARKING(rd) (((u_char)(rd)->NumLanes & 0x40) != 0) // bit 7 allows parking on leftmost lane
|
||||||
|
#define ROAD_IS_RIGHTMOST_LANE_PARKING(rd) (((u_char)(rd)->NumLanes & 0x80) != 0) // bit 8 allows parking on rightmost lane
|
||||||
|
|
||||||
|
#define ROAD_SPEED_LIMIT(rd) (((u_char)(rd)->NumLanes >> 4) & 3) // speed limit id
|
||||||
|
|
||||||
#define ROAD_LANE_DIR(rd, lane) \
|
#define ROAD_LANE_DIR(rd, lane) \
|
||||||
(((u_char)(rd)->LaneDirs == 0xFF && (rd)->NumLanes == 1) ? ((lane) & 1) : ROAD_LANE_DIRECTION_BIT(rd, lane))
|
(((u_char)(rd)->LaneDirs == 0xFF && (rd)->NumLanes == 1) ? ((lane) & 1) : ROAD_LANE_DIRECTION_BIT(rd, lane))
|
||||||
@ -38,7 +43,7 @@ struct DRIVER2_ROAD_INFO
|
|||||||
{
|
{
|
||||||
int surfId;
|
int surfId;
|
||||||
|
|
||||||
short (*ConnectIdx)[4];
|
short* ConnectIdx; // [4]
|
||||||
char NumLanes;
|
char NumLanes;
|
||||||
char LaneDirs;
|
char LaneDirs;
|
||||||
char AILanes;
|
char AILanes;
|
||||||
|
@ -4324,8 +4324,8 @@ int StopUserMissionEvents(MR_THREAD *thread)
|
|||||||
|
|
||||||
int RunUserMissionEvents(MR_THREAD *thread)
|
int RunUserMissionEvents(MR_THREAD *thread)
|
||||||
{
|
{
|
||||||
if (gCurrentMissionNumber >= 50 && gCurrentMissionNumber <= 65)
|
//if (gCurrentMissionNumber >= 50 && gCurrentMissionNumber <= 65)
|
||||||
maxCopCars = 32;
|
// maxCopCars = 32;
|
||||||
|
|
||||||
return (*fnMissionEventHandlers)[GameLevel](thread, 0);
|
return (*fnMissionEventHandlers)[GameLevel](thread, 0);
|
||||||
}
|
}
|
||||||
|
@ -262,10 +262,11 @@ void FixCarCos(CAR_COSMETICS* carCos, int externalModelNumber)
|
|||||||
car_cosmetics[2].mass *= 3;
|
car_cosmetics[2].mass *= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [A] vegas box truck
|
// [A] wibbly wobbly fuckery hacks...
|
||||||
if (GameLevel == 2 && externalModelNumber == 10)
|
// flag certain cars that have a tendency to go CRAZY at a stand-still
|
||||||
|
if (GameLevel == 2 && externalModelNumber == 10) // vegas box truck
|
||||||
{
|
{
|
||||||
carCos->extraInfo |= 4; // wibbly wobbly fuckery hack...
|
carCos->extraInfo |= 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,6 +335,22 @@ void GlobalTimeStep(void)
|
|||||||
|
|
||||||
st = &cp->st;
|
st = &cp->st;
|
||||||
|
|
||||||
|
// [A] bugfix: wibbly wobbly cars
|
||||||
|
// (see end of FixCarCos for cars that have this flag)
|
||||||
|
if (car_cosmetics[cp->ap.model].extraInfo & 4)
|
||||||
|
{
|
||||||
|
if (cp->handbrake && cp->wasOnGround && cp->hd.speed < 3)
|
||||||
|
{
|
||||||
|
cp->hd.aacc[0] >>= 1;
|
||||||
|
cp->hd.aacc[1] >>= 1;
|
||||||
|
cp->hd.aacc[2] >>= 1;
|
||||||
|
|
||||||
|
cp->hd.acc[0] >>= 1;
|
||||||
|
cp->hd.acc[1] >>= 1;
|
||||||
|
cp->hd.acc[2] >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
st->n.linearVelocity[0] += cp->hd.acc[0];
|
st->n.linearVelocity[0] += cp->hd.acc[0];
|
||||||
st->n.linearVelocity[1] += cp->hd.acc[1];
|
st->n.linearVelocity[1] += cp->hd.acc[1];
|
||||||
st->n.linearVelocity[2] += cp->hd.acc[2];
|
st->n.linearVelocity[2] += cp->hd.acc[2];
|
||||||
|
@ -383,7 +383,7 @@ void SetupResidentModels()
|
|||||||
// force palette
|
// force palette
|
||||||
if (singlePal)
|
if (singlePal)
|
||||||
PlayerStartInfo[i]->palette = 0;
|
PlayerStartInfo[i]->palette = 0;
|
||||||
else
|
else if (wantedColour[i] != -1)
|
||||||
PlayerStartInfo[i]->palette = wantedColour[i];
|
PlayerStartInfo[i]->palette = wantedColour[i];
|
||||||
|
|
||||||
// store for replay if necessary
|
// store for replay if necessary
|
||||||
@ -1280,7 +1280,7 @@ void HandleTimer(MR_TIMER *timer)
|
|||||||
// [D] [T]
|
// [D] [T]
|
||||||
void RegisterChaseHit(int car1, int car2)
|
void RegisterChaseHit(int car1, int car2)
|
||||||
{
|
{
|
||||||
if (!Mission.ChaseTarget || Mission.ChaseHitDelay == 0)
|
if (!Mission.ChaseTarget || Mission.ChaseHitDelay != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int player_id;
|
int player_id;
|
||||||
|
@ -1719,7 +1719,7 @@ int DrawCharacter(LPPEDESTRIAN pPed)
|
|||||||
if (pUsedPeds->pNext == NULL && pPed->pedType == TANNER_MODEL)
|
if (pUsedPeds->pNext == NULL && pPed->pedType == TANNER_MODEL)
|
||||||
#else
|
#else
|
||||||
// draw a nice shadow for non-civilian peds :)
|
// draw a nice shadow for non-civilian peds :)
|
||||||
if (pPed->pedType != CIVILIAN)
|
if (pPed->pedType == TANNER_MODEL || pPed->pedType == OTHER_MODEL)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
v.vx = (pPed->position.vx - camera_position.vx) + Skel[ROOT].pvOrigPos->vx;
|
v.vx = (pPed->position.vx - camera_position.vx) + Skel[ROOT].pvOrigPos->vx;
|
||||||
|
@ -1001,7 +1001,12 @@ void DrawMultiplayerMap(void)
|
|||||||
map_z_offset = 0;
|
map_z_offset = 0;
|
||||||
|
|
||||||
xPos = gMapXOffset;
|
xPos = gMapXOffset;
|
||||||
|
#ifndef PSX
|
||||||
|
// [A] add room for speedometer
|
||||||
|
yPos = gMapYOffset - 4;
|
||||||
|
#else
|
||||||
yPos = gMapYOffset;
|
yPos = gMapYOffset;
|
||||||
|
#endif
|
||||||
|
|
||||||
DrawMultiplayerTargets();
|
DrawMultiplayerTargets();
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ struct XZDIR
|
|||||||
short dx, dz;
|
short dx, dz;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Fast Marching method
|
||||||
ushort distanceCache[16384];
|
ushort distanceCache[16384];
|
||||||
char omap[128][16]; // obstacle map 128x128 (bit field)
|
char omap[128][16]; // obstacle map 128x128 (bit field)
|
||||||
int dunyet[32][2]; // scanned cell map (32x32, multi-level bitfield)
|
int dunyet[32][2]; // scanned cell map (32x32, multi-level bitfield)
|
||||||
@ -147,7 +148,7 @@ void DebugDisplayObstacleMap()
|
|||||||
n.vx = player[0].pos[0];
|
n.vx = player[0].pos[0];
|
||||||
n.vz = player[0].pos[2];
|
n.vz = player[0].pos[2];
|
||||||
n.vy = pos_y;
|
n.vy = pos_y;
|
||||||
n.vy = MapHeight((VECTOR*)&n);
|
//n.vy = MapHeight((VECTOR*)&n);
|
||||||
|
|
||||||
for (int i = 0; i < 128; i++)
|
for (int i = 0; i < 128; i++)
|
||||||
{
|
{
|
||||||
@ -179,7 +180,7 @@ void DebugDisplayObstacleMap()
|
|||||||
|
|
||||||
n.vx = px << 8;
|
n.vx = px << 8;
|
||||||
n.vz = pz << 8;
|
n.vz = pz << 8;
|
||||||
n.vy = MapHeight((VECTOR*)&n);
|
n.vy = 0;// MapHeight((VECTOR*)&n);
|
||||||
|
|
||||||
int dist = distanceCache[(n.vx >> 2 & 0x3f80U | n.vz >> 9 & 0x7fU) ^ (n.vy & 1U) * 0x2040 ^ (n.vy & 2U) << 0xc];// distanceCache[((pos_x+i & 127) * 128) + (j + pos_z & 127)];
|
int dist = distanceCache[(n.vx >> 2 & 0x3f80U | n.vz >> 9 & 0x7fU) ^ (n.vy & 1U) * 0x2040 ^ (n.vy & 2U) << 0xc];// distanceCache[((pos_x+i & 127) * 128) + (j + pos_z & 127)];
|
||||||
|
|
||||||
@ -270,9 +271,9 @@ void WunCell(VECTOR* pbase)
|
|||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
#if ENABLE_GAME_FIXES
|
#if ENABLE_GAME_FIXES
|
||||||
// [A] hack with height map (fixes some bits in Havana)
|
// start with the base (player) height
|
||||||
height1 = MapHeight(pbase);
|
height1 = pbase->vy;
|
||||||
|
|
||||||
pbase->vx += 512;
|
pbase->vx += 512;
|
||||||
pbase->vz += 512;
|
pbase->vz += 512;
|
||||||
|
|
||||||
@ -281,7 +282,9 @@ void WunCell(VECTOR* pbase)
|
|||||||
pbase->vx -= 512;
|
pbase->vx -= 512;
|
||||||
pbase->vz -= 512;
|
pbase->vz -= 512;
|
||||||
|
|
||||||
if (height1 - v[0].vy > 100)
|
// if base height differs from map height too much (we are on bridge etc)
|
||||||
|
// we then use base height to ensure that obstacles are locally correct
|
||||||
|
if (ABS(height1 - v[0].vy) > 100)
|
||||||
v[0].vy = height1;
|
v[0].vy = height1;
|
||||||
|
|
||||||
v[0].vy += 32;
|
v[0].vy += 32;
|
||||||
@ -300,6 +303,17 @@ void WunCell(VECTOR* pbase)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
pbase->vx = pbase->vx + 512;
|
||||||
|
pbase->vz = pbase->vz + 512;
|
||||||
|
|
||||||
|
height1 = MapHeight(pbase);
|
||||||
|
|
||||||
|
v[0].vy = height1 + 60;
|
||||||
|
|
||||||
|
pbase->vx = pbase->vx - 512;
|
||||||
|
pbase->vz = pbase->vz - 512;
|
||||||
|
v[1].vy = v[0].vy;
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
@ -321,14 +335,10 @@ void WunCell(VECTOR* pbase)
|
|||||||
dz = v[0].vz + v[1].vz >> 1;
|
dz = v[0].vz + v[1].vz >> 1;
|
||||||
|
|
||||||
OMapSet(dx >> 8, dz >> 8, lineClear(&v[0], &v[1]) == 0);
|
OMapSet(dx >> 8, dz >> 8, lineClear(&v[0], &v[1]) == 0);
|
||||||
|
|
||||||
j++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
pbase->vx -= 512;
|
pbase->vx -= 512;
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -501,9 +511,15 @@ int blocked(tNode* v1, tNode* v2)
|
|||||||
if (slowWallTests != 0)
|
if (slowWallTests != 0)
|
||||||
return lineClear((VECTOR*)v1, (VECTOR*)v2) == 0;
|
return lineClear((VECTOR*)v1, (VECTOR*)v2) == 0;
|
||||||
|
|
||||||
x = v1->vx + v1->vx >> 9;
|
x = v1->vx + v2->vx >> 9;
|
||||||
z = v1->vz + v2->vz >> 9;
|
z = v1->vz + v2->vz >> 9;
|
||||||
|
|
||||||
|
int prev = DONEMAP_V(x >> 2, z >> 2);
|
||||||
|
int val = DONEMAP_GETVALUE(x >> 2, z >> 2, prev, 0);
|
||||||
|
|
||||||
|
if (val != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
return OMAP_GETVALUE(x, z);
|
return OMAP_GETVALUE(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,10 +532,10 @@ void setDistance(tNode* n, ushort dist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [A]
|
// [A]
|
||||||
void SetNodeDistanceWithParents(tNode* startNode, ushort dist);
|
void pushNode(tNode* startNode, ushort dist);
|
||||||
|
|
||||||
// [D] [T]
|
// [D] [T]
|
||||||
void iterate(void)
|
int iterate(void)
|
||||||
{
|
{
|
||||||
tNode pathNodes[8];
|
tNode pathNodes[8];
|
||||||
|
|
||||||
@ -536,16 +552,14 @@ void iterate(void)
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (numHeapEntries == 0)
|
if (numHeapEntries == 0)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
popNode(&itHere);
|
popNode(&itHere);
|
||||||
nbr = pathNodes;
|
nbr = pathNodes;
|
||||||
|
|
||||||
// check directions
|
// check directions
|
||||||
for(dir = 0; dir < 6; dir++)
|
for(dir = 0; dir < 6; dir++, nbr++)
|
||||||
{
|
{
|
||||||
nbr++;
|
|
||||||
|
|
||||||
nbr->vx = itHere.vx + dirs[dir].dx;
|
nbr->vx = itHere.vx + dirs[dir].dx;
|
||||||
nbr->vy = itHere.vy;
|
nbr->vy = itHere.vy;
|
||||||
nbr->vz = itHere.vz + dirs[dir].dz;
|
nbr->vz = itHere.vz + dirs[dir].dz;
|
||||||
@ -560,9 +574,7 @@ void iterate(void)
|
|||||||
{
|
{
|
||||||
if (ABS(nbr->vy - itHere.vy) < 201)
|
if (ABS(nbr->vy - itHere.vy) < 201)
|
||||||
{
|
{
|
||||||
if ((dist & 1) == 0)
|
nbr->dist = 0;
|
||||||
nbr->dist = 0;
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -581,18 +593,18 @@ void iterate(void)
|
|||||||
// now we have distance let's compute the rest of the map
|
// now we have distance let's compute the rest of the map
|
||||||
for(dir = 0; dir < 6; dir++)
|
for(dir = 0; dir < 6; dir++)
|
||||||
{
|
{
|
||||||
if (pathNodes[dir + 1].dist != 0)
|
if (pathNodes[dir].dist != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (dir != 5)
|
if (dir != 5)
|
||||||
nr = pathNodes[dir + 2].dist;
|
nr = pathNodes[dir + 1].dist;
|
||||||
else
|
else
|
||||||
nr = pathNodes[1].dist;
|
nr = pathNodes[0].dist;
|
||||||
|
|
||||||
if (dir != 0)
|
if (dir != 0)
|
||||||
nl = pathNodes[dir].dist;
|
nl = pathNodes[dir - 1].dist;
|
||||||
else
|
else
|
||||||
nl = pathNodes[6].dist;
|
nl = pathNodes[5].dist;
|
||||||
|
|
||||||
// uhhmm... distance function selection?
|
// uhhmm... distance function selection?
|
||||||
if (nl < 2)
|
if (nl < 2)
|
||||||
@ -627,8 +639,10 @@ void iterate(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetNodeDistanceWithParents(&pathNodes[dir + 1], dist);
|
pushNode(&pathNodes[dir], dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return numHeapEntries > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [D] [T]
|
// [D] [T]
|
||||||
@ -853,7 +867,7 @@ void addCivs(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [A]
|
// [A]
|
||||||
void SetNodeDistanceWithParents(tNode* startNode, ushort dist)
|
void pushNode(tNode* startNode, ushort dist)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u_int pnode, parent;
|
u_int pnode, parent;
|
||||||
@ -863,6 +877,7 @@ void SetNodeDistanceWithParents(tNode* startNode, ushort dist)
|
|||||||
|
|
||||||
setDistance(startNode, dist);
|
setDistance(startNode, dist);
|
||||||
|
|
||||||
|
// up heap
|
||||||
i = numHeapEntries + 1;
|
i = numHeapEntries + 1;
|
||||||
|
|
||||||
pnode = i;
|
pnode = i;
|
||||||
@ -881,7 +896,7 @@ void SetNodeDistanceWithParents(tNode* startNode, ushort dist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [A]
|
// [A]
|
||||||
void ComputeDistanceFromSearchTarget(tNode* startNode)
|
void pushSeedNode(tNode* startNode)
|
||||||
{
|
{
|
||||||
u_short dist;
|
u_short dist;
|
||||||
int i, dx, dz;
|
int i, dx, dz;
|
||||||
@ -894,7 +909,7 @@ void ComputeDistanceFromSearchTarget(tNode* startNode)
|
|||||||
|
|
||||||
dist = SquareRoot0( dx * dx + dz * dz ) >> 1;
|
dist = SquareRoot0( dx * dx + dz * dz ) >> 1;
|
||||||
|
|
||||||
SetNodeDistanceWithParents(startNode, dist);
|
pushNode(startNode, dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
// [D] [T]
|
// [D] [T]
|
||||||
@ -939,14 +954,21 @@ void UpdateCopMap(void)
|
|||||||
i = 36;
|
i = 36;
|
||||||
|
|
||||||
while (--i >= 0)
|
while (--i >= 0)
|
||||||
iterate();
|
{
|
||||||
|
if (!iterate())
|
||||||
|
{
|
||||||
|
pathFrames = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DebugDisplayObstacleMap();
|
DebugDisplayObstacleMap();
|
||||||
|
|
||||||
// remove cars
|
// remove cars
|
||||||
addCivs();
|
addCivs();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if(pathFrames == 0)
|
||||||
{
|
{
|
||||||
// restart from new search target position
|
// restart from new search target position
|
||||||
if (player[0].playerType == 1 && (CopsCanSeePlayer != 0 || numActiveCops == 0))
|
if (player[0].playerType == 1 && (CopsCanSeePlayer != 0 || numActiveCops == 0))
|
||||||
@ -1001,30 +1023,30 @@ void UpdateCopMap(void)
|
|||||||
|
|
||||||
if (dz < dx + dz / 2)
|
if (dz < dx + dz / 2)
|
||||||
{
|
{
|
||||||
ComputeDistanceFromSearchTarget(&startNode);
|
pushSeedNode(&startNode);
|
||||||
|
|
||||||
startNode.vx += 256;
|
startNode.vx += 256;
|
||||||
startNode.vz += 512;
|
startNode.vz += 512;
|
||||||
|
|
||||||
ComputeDistanceFromSearchTarget(&startNode);
|
pushSeedNode(&startNode);
|
||||||
|
|
||||||
startNode.vx += 256;
|
startNode.vx += 256;
|
||||||
startNode.vz -= 512;
|
startNode.vz -= 512;
|
||||||
|
|
||||||
ComputeDistanceFromSearchTarget(&startNode);
|
pushSeedNode(&startNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ComputeDistanceFromSearchTarget(&startNode);
|
pushSeedNode(&startNode);
|
||||||
|
|
||||||
startNode.vx += 256;
|
startNode.vx += 256;
|
||||||
startNode.vz += 512;
|
startNode.vz += 512;
|
||||||
|
|
||||||
ComputeDistanceFromSearchTarget(&startNode);
|
pushSeedNode(&startNode);
|
||||||
|
|
||||||
startNode.vx -= 512;
|
startNode.vx -= 512;
|
||||||
|
|
||||||
ComputeDistanceFromSearchTarget(&startNode);
|
pushSeedNode(&startNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1282,7 +1282,7 @@ void SetupGetInCar(LPPEDESTRIAN pPed)
|
|||||||
|
|
||||||
// HEY!
|
// HEY!
|
||||||
CreatePedAtLocation(&pos, 8);
|
CreatePedAtLocation(&pos, 8);
|
||||||
Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, sample, pos[0], pos[1], pos[2], 0, 4096);
|
Start3DSoundVolPitch(-1, SOUND_BANK_TANNER, 5, pos[0], pos[1], pos[2], 0, 4096);
|
||||||
|
|
||||||
carToGetIn->controlFlags |= CONTROL_FLAG_WAS_PARKED;
|
carToGetIn->controlFlags |= CONTROL_FLAG_WAS_PARKED;
|
||||||
}
|
}
|
||||||
|
@ -285,50 +285,11 @@ int LoadReplayFromBuffer(char *buffer)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PSX
|
|
||||||
int LoadUserAttractReplay(int mission, int userId)
|
|
||||||
{
|
|
||||||
char customFilename[64];
|
|
||||||
|
|
||||||
if (userId >= 0 && userId < gNumUserChases)
|
|
||||||
{
|
|
||||||
sprintf(customFilename, "REPLAYS\\User\\%s\\ATTRACT.%d", gUserReplayFolderList[userId], mission);
|
|
||||||
|
|
||||||
if (FileExists(customFilename))
|
|
||||||
{
|
|
||||||
if (Loadfile(customFilename, (char*)_other_buffer))
|
|
||||||
return LoadReplayFromBuffer((char*)_other_buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// [D] [T]
|
// [D] [T]
|
||||||
int LoadAttractReplay(int mission)
|
int LoadAttractReplay(int mission)
|
||||||
{
|
{
|
||||||
char filename[32];
|
char filename[32];
|
||||||
|
|
||||||
#ifndef PSX
|
|
||||||
int userId = -1;
|
|
||||||
|
|
||||||
// [A] REDRIVER2 PC - custom attract replays
|
|
||||||
if (gNumUserChases)
|
|
||||||
{
|
|
||||||
userId = rand() % (gNumUserChases + 1);
|
|
||||||
|
|
||||||
if (userId == gNumUserChases)
|
|
||||||
userId = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LoadUserAttractReplay(mission, userId))
|
|
||||||
{
|
|
||||||
printInfo("Loaded custom attract replay (%d) by %s\n", mission, gUserReplayFolderList[userId]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sprintf(filename, "REPLAYS\\ATTRACT.%d", mission);
|
sprintf(filename, "REPLAYS\\ATTRACT.%d", mission);
|
||||||
|
|
||||||
if (!FileExists(filename))
|
if (!FileExists(filename))
|
||||||
|
@ -213,12 +213,15 @@ void AddWheelForcesDriver1(CAR_DATA* cp, CAR_LOCALS* cl)
|
|||||||
int player_id;
|
int player_id;
|
||||||
int oldCutRoughness;
|
int oldCutRoughness;
|
||||||
|
|
||||||
oldSpeed = cp->hd.speed * 3 >> 1;
|
// NB: skips precision every 3rd increment or so
|
||||||
|
int speed = cp->hd.speed * 3 >> 1;
|
||||||
|
|
||||||
if (oldSpeed < 32)
|
if (speed < 32)
|
||||||
oldSpeed = oldSpeed * -72 + 3696;
|
oldSpeed = 4096 - (72 * speed);
|
||||||
else
|
else
|
||||||
oldSpeed = 1424 - oldSpeed;
|
oldSpeed = 1824 - speed;
|
||||||
|
|
||||||
|
oldSpeed -= 400;
|
||||||
|
|
||||||
dir = cp->hd.direction;
|
dir = cp->hd.direction;
|
||||||
cdx = RSIN(dir);
|
cdx = RSIN(dir);
|
||||||
@ -528,32 +531,6 @@ void AddWheelForcesDriver1(CAR_DATA* cp, CAR_LOCALS* cl)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
cp->hd.wheel_speed = cdz / 64 * (cl->vel[2] / 64) + cdx / 64 * (cl->vel[0] / 64);
|
cp->hd.wheel_speed = cdz / 64 * (cl->vel[2] / 64) + cdx / 64 * (cl->vel[0] / 64);
|
||||||
|
|
||||||
// [A] wibbly wobbly fuckery hack...
|
|
||||||
if (car_cos->extraInfo & 4)
|
|
||||||
{
|
|
||||||
if (cp->thrust == 0 && cp->handbrake && (cp->hd.speed > 0 && cp->hd.speed < 4))
|
|
||||||
{
|
|
||||||
cp->hd.speed--;
|
|
||||||
cp->hd.wheel_speed >>= 1;
|
|
||||||
|
|
||||||
cp->hd.acc[0] >>= 1;
|
|
||||||
cp->hd.acc[1] >>= 1;
|
|
||||||
cp->hd.acc[2] >>= 1;
|
|
||||||
|
|
||||||
cp->hd.aacc[0] >>= 2;
|
|
||||||
cp->hd.aacc[1] >>= 2;
|
|
||||||
cp->hd.aacc[2] >>= 2;
|
|
||||||
|
|
||||||
//cp->st.n.linearVelocity[0] >>= 1;
|
|
||||||
//cp->st.n.linearVelocity[1] >>= 1;
|
|
||||||
//cp->st.n.linearVelocity[2] >>= 1;
|
|
||||||
|
|
||||||
cp->st.n.angularVelocity[0] >>= 2;
|
|
||||||
cp->st.n.angularVelocity[1] >>= 2;
|
|
||||||
cp->st.n.angularVelocity[2] >>= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
#define M_BIT(x) (1 << (x))
|
#define M_BIT(x) (1 << (x))
|
||||||
|
|
||||||
|
// makes RGB int out of three bytes
|
||||||
|
#define M_INT_RGB(r,g,b) (((r) << 16) | ((g) << 8) | (b))
|
||||||
|
|
||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
|
|
||||||
#if !defined( __TYPEINFOGEN__ ) && !defined( _lint ) && defined(_WIN32) // pcLint has problems with assert_offsetof()
|
#if !defined( __TYPEINFOGEN__ ) && !defined( _lint ) && defined(_WIN32) // pcLint has problems with assert_offsetof()
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 8fa92c7fba6685c0e9f41804c2f5b68dee4b87e7
|
Subproject commit a04825ea2c1c5c5eecac83ed97cb637d3cab8928
|
@ -565,12 +565,9 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
int newScrZ = gCameraDefaultScrZ;
|
int newScrZ = gCameraDefaultScrZ;
|
||||||
const char* dataFolderStr = ini_get(config, "fs", "dataFolder");
|
const char* dataFolderStr = ini_get(config, "fs", "dataFolder");
|
||||||
const char* userReplaysStr = ini_get(config, "game", "userChases");
|
|
||||||
|
|
||||||
if(!cdImageFileName)
|
if(!cdImageFileName)
|
||||||
cdImageFileName = ini_get(config, "cdfs", "image");
|
cdImageFileName = ini_get(config, "cdfs", "image");
|
||||||
|
|
||||||
InitUserReplays(userReplaysStr);
|
|
||||||
|
|
||||||
// configure Psy-X pads
|
// configure Psy-X pads
|
||||||
ini_sget(config, "pad", "pad1device", "%d", &g_cfg_controllerToSlotMapping[0]);
|
ini_sget(config, "pad", "pad1device", "%d", &g_cfg_controllerToSlotMapping[0]);
|
||||||
|
Loading…
Reference in New Issue
Block a user