mirror of
https://github.com/GTAmodding/re3.git
synced 2021-02-19 17:49:54 +01:00
Merge branch 'upstream/master'
This commit is contained in:
commit
0669df763c
@ -231,6 +231,7 @@ project "re3"
|
|||||||
files { addSrcFiles("src/audio") }
|
files { addSrcFiles("src/audio") }
|
||||||
files { addSrcFiles("src/audio/eax") }
|
files { addSrcFiles("src/audio/eax") }
|
||||||
files { addSrcFiles("src/audio/oal") }
|
files { addSrcFiles("src/audio/oal") }
|
||||||
|
files { addSrcFiles("src/collision") }
|
||||||
files { addSrcFiles("src/control") }
|
files { addSrcFiles("src/control") }
|
||||||
files { addSrcFiles("src/core") }
|
files { addSrcFiles("src/core") }
|
||||||
files { addSrcFiles("src/entities") }
|
files { addSrcFiles("src/entities") }
|
||||||
@ -253,6 +254,7 @@ project "re3"
|
|||||||
includedirs { "src/audio" }
|
includedirs { "src/audio" }
|
||||||
includedirs { "src/audio/eax" }
|
includedirs { "src/audio/eax" }
|
||||||
includedirs { "src/audio/oal" }
|
includedirs { "src/audio/oal" }
|
||||||
|
includedirs { "src/collision" }
|
||||||
includedirs { "src/control" }
|
includedirs { "src/control" }
|
||||||
includedirs { "src/core" }
|
includedirs { "src/core" }
|
||||||
includedirs { "src/entities" }
|
includedirs { "src/entities" }
|
||||||
|
@ -13,6 +13,7 @@ MACRO(HEADER_DIRECTORIES return_list)
|
|||||||
FILE(GLOB_RECURSE new_list *.cpp)
|
FILE(GLOB_RECURSE new_list *.cpp)
|
||||||
SET(dir_list "animation"
|
SET(dir_list "animation"
|
||||||
"audio"
|
"audio"
|
||||||
|
"collision"
|
||||||
"control"
|
"control"
|
||||||
"core"
|
"core"
|
||||||
"entities"
|
"entities"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -332,7 +332,7 @@ public:
|
|||||||
int8 GetMissionScriptPoliceAudioPlayingStatus() const;
|
int8 GetMissionScriptPoliceAudioPlayingStatus() const;
|
||||||
uint8 GetNum3DProvidersAvailable() const;
|
uint8 GetNum3DProvidersAvailable() const;
|
||||||
int32 GetPedCommentSfx(CPed *ped, int32 sound);
|
int32 GetPedCommentSfx(CPed *ped, int32 sound);
|
||||||
void GetPhrase(uint32 *phrase, uint32 *prevPhrase, uint32 sample, uint32 maxOffset) const;
|
void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const;
|
||||||
float GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
|
float GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
|
||||||
cTransmission *transmission, float velocityChange);
|
cTransmission *transmission, float velocityChange);
|
||||||
float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
|
float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
|
||||||
@ -362,29 +362,29 @@ public:
|
|||||||
void PreTerminateGameSpecificShutdown();
|
void PreTerminateGameSpecificShutdown();
|
||||||
/// processX - main logic of adding new sounds
|
/// processX - main logic of adding new sounds
|
||||||
void ProcessActiveQueues();
|
void ProcessActiveQueues();
|
||||||
bool ProcessAirBrakes(cVehicleParams *params);
|
bool ProcessAirBrakes(cVehicleParams& params);
|
||||||
void ProcessAirportScriptObject(uint8 sound);
|
void ProcessAirportScriptObject(uint8 sound);
|
||||||
bool ProcessBoatEngine(cVehicleParams *params);
|
bool ProcessBoatEngine(cVehicleParams& params);
|
||||||
bool ProcessBoatMovingOverWater(cVehicleParams *params);
|
bool ProcessBoatMovingOverWater(cVehicleParams& params);
|
||||||
void ProcessBridge();
|
void ProcessBridge();
|
||||||
void ProcessBridgeMotor();
|
void ProcessBridgeMotor();
|
||||||
void ProcessBridgeOneShots();
|
void ProcessBridgeOneShots();
|
||||||
void ProcessBridgeWarning();
|
void ProcessBridgeWarning();
|
||||||
bool ProcessCarBombTick(cVehicleParams *params);
|
bool ProcessCarBombTick(cVehicleParams& params);
|
||||||
void ProcessCesna(cVehicleParams *params);
|
void ProcessCesna(cVehicleParams& params);
|
||||||
void ProcessCinemaScriptObject(uint8 sound);
|
void ProcessCinemaScriptObject(uint8 sound);
|
||||||
void ProcessCrane();
|
void ProcessCrane();
|
||||||
void ProcessDocksScriptObject(uint8 sound);
|
void ProcessDocksScriptObject(uint8 sound);
|
||||||
bool ProcessEngineDamage(cVehicleParams *params);
|
bool ProcessEngineDamage(cVehicleParams& params);
|
||||||
void ProcessEntity(int32 sound);
|
void ProcessEntity(int32 sound);
|
||||||
void ProcessExplosions(int32 explosion);
|
void ProcessExplosions(int32 explosion);
|
||||||
void ProcessFireHydrant();
|
void ProcessFireHydrant();
|
||||||
void ProcessFires(int32 entity);
|
void ProcessFires(int32 entity);
|
||||||
void ProcessFrontEnd();
|
void ProcessFrontEnd();
|
||||||
void ProcessGarages();
|
void ProcessGarages();
|
||||||
bool ProcessHelicopter(cVehicleParams *params);
|
bool ProcessHelicopter(cVehicleParams& params);
|
||||||
void ProcessHomeScriptObject(uint8 sound);
|
void ProcessHomeScriptObject(uint8 sound);
|
||||||
void ProcessJumbo(cVehicleParams *);
|
void ProcessJumbo(cVehicleParams& params);
|
||||||
void ProcessJumboAccel(CPlane *plane);
|
void ProcessJumboAccel(CPlane *plane);
|
||||||
void ProcessJumboDecel(CPlane *plane);
|
void ProcessJumboDecel(CPlane *plane);
|
||||||
void ProcessJumboFlying();
|
void ProcessJumboFlying();
|
||||||
@ -394,37 +394,37 @@ public:
|
|||||||
void ProcessLaunderetteScriptObject(uint8 sound);
|
void ProcessLaunderetteScriptObject(uint8 sound);
|
||||||
void ProcessLoopingScriptObject(uint8 sound);
|
void ProcessLoopingScriptObject(uint8 sound);
|
||||||
void ProcessMissionAudio();
|
void ProcessMissionAudio();
|
||||||
void ProcessModelCarEngine(cVehicleParams *params);
|
void ProcessModelCarEngine(cVehicleParams& params);
|
||||||
void ProcessOneShotScriptObject(uint8 sound);
|
void ProcessOneShotScriptObject(uint8 sound);
|
||||||
void ProcessPed(CPhysical *ped);
|
void ProcessPed(CPhysical *ped);
|
||||||
void ProcessPedHeadphones(cPedParams *params);
|
void ProcessPedHeadphones(cPedParams *params);
|
||||||
void ProcessPedOneShots(cPedParams *params);
|
void ProcessPedOneShots(cPedParams *params);
|
||||||
void ProcessPhysical(int32 id);
|
void ProcessPhysical(int32 id);
|
||||||
void ProcessPlane(cVehicleParams *params);
|
void ProcessPlane(cVehicleParams& params);
|
||||||
void ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *automobile);
|
void ProcessPlayersVehicleEngine(cVehicleParams& params, CAutomobile *automobile);
|
||||||
void ProcessPoliceCellBeatingScriptObject(uint8 sound);
|
void ProcessPoliceCellBeatingScriptObject(uint8 sound);
|
||||||
void ProcessPornCinema(uint8 sound);
|
void ProcessPornCinema(uint8 sound);
|
||||||
void ProcessProjectiles();
|
void ProcessProjectiles();
|
||||||
void ProcessRainOnVehicle(cVehicleParams *params);
|
void ProcessRainOnVehicle(cVehicleParams& params);
|
||||||
void ProcessReverb() const;
|
void ProcessReverb() const;
|
||||||
bool ProcessReverseGear(cVehicleParams *params);
|
bool ProcessReverseGear(cVehicleParams& params);
|
||||||
void ProcessSawMillScriptObject(uint8 sound);
|
void ProcessSawMillScriptObject(uint8 sound);
|
||||||
void ProcessScriptObject(int32 id);
|
void ProcessScriptObject(int32 id);
|
||||||
void ProcessShopScriptObject(uint8 sound);
|
void ProcessShopScriptObject(uint8 sound);
|
||||||
void ProcessSpecial();
|
void ProcessSpecial();
|
||||||
bool ProcessTrainNoise(cVehicleParams *params);
|
bool ProcessTrainNoise(cVehicleParams& params);
|
||||||
void ProcessVehicle(CVehicle *vehicle);
|
void ProcessVehicle(CVehicle *vehicle);
|
||||||
bool ProcessVehicleDoors(cVehicleParams *params);
|
bool ProcessVehicleDoors(cVehicleParams& params);
|
||||||
void ProcessVehicleEngine(cVehicleParams *params);
|
void ProcessVehicleEngine(cVehicleParams& params);
|
||||||
void ProcessVehicleHorn(cVehicleParams *params);
|
void ProcessVehicleHorn(cVehicleParams& params);
|
||||||
void ProcessVehicleOneShots(cVehicleParams *params);
|
void ProcessVehicleOneShots(cVehicleParams& params);
|
||||||
bool ProcessVehicleReverseWarning(cVehicleParams *params);
|
bool ProcessVehicleReverseWarning(cVehicleParams& params);
|
||||||
bool ProcessVehicleRoadNoise(cVehicleParams *params);
|
bool ProcessVehicleRoadNoise(cVehicleParams& params);
|
||||||
bool ProcessVehicleSirenOrAlarm(cVehicleParams *params);
|
bool ProcessVehicleSirenOrAlarm(cVehicleParams& params);
|
||||||
bool ProcessVehicleSkidding(cVehicleParams *params);
|
bool ProcessVehicleSkidding(cVehicleParams& params);
|
||||||
void ProcessWaterCannon(int32);
|
void ProcessWaterCannon(int32);
|
||||||
void ProcessWeather(int32 id);
|
void ProcessWeather(int32 id);
|
||||||
bool ProcessWetRoadNoise(cVehicleParams *params);
|
bool ProcessWetRoadNoise(cVehicleParams& params);
|
||||||
void ProcessWorkShopScriptObject(uint8 sound);
|
void ProcessWorkShopScriptObject(uint8 sound);
|
||||||
|
|
||||||
int32 RandomDisplacement(uint32 seed) const;
|
int32 RandomDisplacement(uint32 seed) const;
|
||||||
|
@ -161,7 +161,7 @@ cMusicManager::DisplayRadioStationName()
|
|||||||
CFont::SetPropOn();
|
CFont::SetPropOn();
|
||||||
CFont::SetFontStyle(FONT_HEADING);
|
CFont::SetFontStyle(FONT_HEADING);
|
||||||
CFont::SetCentreOn();
|
CFont::SetCentreOn();
|
||||||
CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH));
|
CFont::SetCentreSize(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
|
||||||
CFont::SetColor(CRGBA(0, 0, 0, 255));
|
CFont::SetColor(CRGBA(0, 0, 0, 255));
|
||||||
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), pCurrentStation);
|
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), pCurrentStation);
|
||||||
|
|
||||||
|
21
src/collision/ColBox.cpp
Normal file
21
src/collision/ColBox.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "ColBox.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
CColBox::Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece)
|
||||||
|
{
|
||||||
|
this->min = min;
|
||||||
|
this->max = max;
|
||||||
|
this->surface = surf;
|
||||||
|
this->piece = piece;
|
||||||
|
}
|
||||||
|
|
||||||
|
CColBox&
|
||||||
|
CColBox::operator=(const CColBox& other)
|
||||||
|
{
|
||||||
|
min = other.min;
|
||||||
|
max = other.max;
|
||||||
|
surface = other.surface;
|
||||||
|
piece = other.piece;
|
||||||
|
return *this;
|
||||||
|
}
|
16
src/collision/ColBox.h
Normal file
16
src/collision/ColBox.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SurfaceTable.h"
|
||||||
|
|
||||||
|
struct CColBox
|
||||||
|
{
|
||||||
|
CVector min;
|
||||||
|
CVector max;
|
||||||
|
uint8 surface;
|
||||||
|
uint8 piece;
|
||||||
|
|
||||||
|
void Set(const CVector &min, const CVector &max, uint8 surf = SURFACE_DEFAULT, uint8 piece = 0);
|
||||||
|
CVector GetSize(void) { return max - min; }
|
||||||
|
|
||||||
|
CColBox& operator=(const CColBox &other);
|
||||||
|
};
|
9
src/collision/ColLine.cpp
Normal file
9
src/collision/ColLine.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "ColLine.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
CColLine::Set(const CVector &p0, const CVector &p1)
|
||||||
|
{
|
||||||
|
this->p0 = p0;
|
||||||
|
this->p1 = p1;
|
||||||
|
}
|
14
src/collision/ColLine.h
Normal file
14
src/collision/ColLine.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct CColLine
|
||||||
|
{
|
||||||
|
// NB: this has to be compatible with two CVuVectors
|
||||||
|
CVector p0;
|
||||||
|
int pad0;
|
||||||
|
CVector p1;
|
||||||
|
int pad1;
|
||||||
|
|
||||||
|
CColLine(void) { };
|
||||||
|
CColLine(const CVector &p0, const CVector &p1) { this->p0 = p0; this->p1 = p1; };
|
||||||
|
void Set(const CVector &p0, const CVector &p1);
|
||||||
|
};
|
184
src/collision/ColModel.cpp
Normal file
184
src/collision/ColModel.cpp
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "ColModel.h"
|
||||||
|
#include "Game.h"
|
||||||
|
|
||||||
|
CColModel::CColModel(void)
|
||||||
|
{
|
||||||
|
numSpheres = 0;
|
||||||
|
spheres = nil;
|
||||||
|
numLines = 0;
|
||||||
|
lines = nil;
|
||||||
|
numBoxes = 0;
|
||||||
|
boxes = nil;
|
||||||
|
numTriangles = 0;
|
||||||
|
vertices = nil;
|
||||||
|
triangles = nil;
|
||||||
|
trianglePlanes = nil;
|
||||||
|
level = CGame::currLevel;
|
||||||
|
ownsCollisionVolumes = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CColModel::~CColModel(void)
|
||||||
|
{
|
||||||
|
RemoveCollisionVolumes();
|
||||||
|
RemoveTrianglePlanes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CColModel::RemoveCollisionVolumes(void)
|
||||||
|
{
|
||||||
|
if(ownsCollisionVolumes){
|
||||||
|
RwFree(spheres);
|
||||||
|
RwFree(lines);
|
||||||
|
RwFree(boxes);
|
||||||
|
RwFree(vertices);
|
||||||
|
RwFree(triangles);
|
||||||
|
}
|
||||||
|
numSpheres = 0;
|
||||||
|
numLines = 0;
|
||||||
|
numBoxes = 0;
|
||||||
|
numTriangles = 0;
|
||||||
|
spheres = nil;
|
||||||
|
lines = nil;
|
||||||
|
boxes = nil;
|
||||||
|
vertices = nil;
|
||||||
|
triangles = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CColModel::CalculateTrianglePlanes(void)
|
||||||
|
{
|
||||||
|
// HACK: allocate space for one more element to stuff the link pointer into
|
||||||
|
trianglePlanes = (CColTrianglePlane*)RwMalloc(sizeof(CColTrianglePlane) * (numTriangles+1));
|
||||||
|
for(int i = 0; i < numTriangles; i++)
|
||||||
|
trianglePlanes[i].Set(vertices, triangles[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CColModel::RemoveTrianglePlanes(void)
|
||||||
|
{
|
||||||
|
RwFree(trianglePlanes);
|
||||||
|
trianglePlanes = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CColModel::SetLinkPtr(CLink<CColModel*> *lptr)
|
||||||
|
{
|
||||||
|
assert(trianglePlanes);
|
||||||
|
*(CLink<CColModel*>**)ALIGNPTR(&trianglePlanes[numTriangles]) = lptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLink<CColModel*>*
|
||||||
|
CColModel::GetLinkPtr(void)
|
||||||
|
{
|
||||||
|
assert(trianglePlanes);
|
||||||
|
return *(CLink<CColModel*>**)ALIGNPTR(&trianglePlanes[numTriangles]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CColModel::GetTrianglePoint(CVector &v, int i) const
|
||||||
|
{
|
||||||
|
v = vertices[i].Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
CColModel&
|
||||||
|
CColModel::operator=(const CColModel &other)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int numVerts;
|
||||||
|
|
||||||
|
boundingSphere = other.boundingSphere;
|
||||||
|
boundingBox = other.boundingBox;
|
||||||
|
|
||||||
|
// copy spheres
|
||||||
|
if(other.numSpheres){
|
||||||
|
if(numSpheres != other.numSpheres){
|
||||||
|
numSpheres = other.numSpheres;
|
||||||
|
if(spheres)
|
||||||
|
RwFree(spheres);
|
||||||
|
spheres = (CColSphere*)RwMalloc(numSpheres*sizeof(CColSphere));
|
||||||
|
}
|
||||||
|
for(i = 0; i < numSpheres; i++)
|
||||||
|
spheres[i] = other.spheres[i];
|
||||||
|
}else{
|
||||||
|
numSpheres = 0;
|
||||||
|
if(spheres)
|
||||||
|
RwFree(spheres);
|
||||||
|
spheres = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy lines
|
||||||
|
if(other.numLines){
|
||||||
|
if(numLines != other.numLines){
|
||||||
|
numLines = other.numLines;
|
||||||
|
if(lines)
|
||||||
|
RwFree(lines);
|
||||||
|
lines = (CColLine*)RwMalloc(numLines*sizeof(CColLine));
|
||||||
|
}
|
||||||
|
for(i = 0; i < numLines; i++)
|
||||||
|
lines[i] = other.lines[i];
|
||||||
|
}else{
|
||||||
|
numLines = 0;
|
||||||
|
if(lines)
|
||||||
|
RwFree(lines);
|
||||||
|
lines = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy boxes
|
||||||
|
if(other.numBoxes){
|
||||||
|
if(numBoxes != other.numBoxes){
|
||||||
|
numBoxes = other.numBoxes;
|
||||||
|
if(boxes)
|
||||||
|
RwFree(boxes);
|
||||||
|
boxes = (CColBox*)RwMalloc(numBoxes*sizeof(CColBox));
|
||||||
|
}
|
||||||
|
for(i = 0; i < numBoxes; i++)
|
||||||
|
boxes[i] = other.boxes[i];
|
||||||
|
}else{
|
||||||
|
numBoxes = 0;
|
||||||
|
if(boxes)
|
||||||
|
RwFree(boxes);
|
||||||
|
boxes = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy mesh
|
||||||
|
if(other.numTriangles){
|
||||||
|
// copy vertices
|
||||||
|
numVerts = 0;
|
||||||
|
for(i = 0; i < other.numTriangles; i++){
|
||||||
|
if(other.triangles[i].a > numVerts)
|
||||||
|
numVerts = other.triangles[i].a;
|
||||||
|
if(other.triangles[i].b > numVerts)
|
||||||
|
numVerts = other.triangles[i].b;
|
||||||
|
if(other.triangles[i].c > numVerts)
|
||||||
|
numVerts = other.triangles[i].c;
|
||||||
|
}
|
||||||
|
numVerts++;
|
||||||
|
if(vertices)
|
||||||
|
RwFree(vertices);
|
||||||
|
if(numVerts){
|
||||||
|
vertices = (CompressedVector*)RwMalloc(numVerts*sizeof(CompressedVector));
|
||||||
|
for(i = 0; i < numVerts; i++)
|
||||||
|
vertices[i] = other.vertices[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy triangles
|
||||||
|
if(numTriangles != other.numTriangles){
|
||||||
|
numTriangles = other.numTriangles;
|
||||||
|
if(triangles)
|
||||||
|
RwFree(triangles);
|
||||||
|
triangles = (CColTriangle*)RwMalloc(numTriangles*sizeof(CColTriangle));
|
||||||
|
}
|
||||||
|
for(i = 0; i < numTriangles; i++)
|
||||||
|
triangles[i] = other.triangles[i];
|
||||||
|
}else{
|
||||||
|
numTriangles = 0;
|
||||||
|
if(triangles)
|
||||||
|
RwFree(triangles);
|
||||||
|
triangles = nil;
|
||||||
|
if(vertices)
|
||||||
|
RwFree(vertices);
|
||||||
|
vertices = nil;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
37
src/collision/ColModel.h
Normal file
37
src/collision/ColModel.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "templates.h"
|
||||||
|
#include "ColBox.h"
|
||||||
|
#include "ColSphere.h"
|
||||||
|
#include "ColLine.h"
|
||||||
|
#include "ColPoint.h"
|
||||||
|
#include "ColTriangle.h"
|
||||||
|
|
||||||
|
struct CColModel
|
||||||
|
{
|
||||||
|
CColSphere boundingSphere;
|
||||||
|
CColBox boundingBox;
|
||||||
|
int16 numSpheres;
|
||||||
|
int16 numLines;
|
||||||
|
int16 numBoxes;
|
||||||
|
int16 numTriangles;
|
||||||
|
int32 level;
|
||||||
|
bool ownsCollisionVolumes; // missing on PS2
|
||||||
|
CColSphere *spheres;
|
||||||
|
CColLine *lines;
|
||||||
|
CColBox *boxes;
|
||||||
|
CompressedVector *vertices;
|
||||||
|
CColTriangle *triangles;
|
||||||
|
CColTrianglePlane *trianglePlanes;
|
||||||
|
|
||||||
|
CColModel(void);
|
||||||
|
~CColModel(void);
|
||||||
|
void RemoveCollisionVolumes(void);
|
||||||
|
void CalculateTrianglePlanes(void);
|
||||||
|
void RemoveTrianglePlanes(void);
|
||||||
|
CLink<CColModel*> *GetLinkPtr(void);
|
||||||
|
void SetLinkPtr(CLink<CColModel*>*);
|
||||||
|
void GetTrianglePoint(CVector &v, int i) const;
|
||||||
|
|
||||||
|
CColModel& operator=(const CColModel& other);
|
||||||
|
};
|
16
src/collision/ColPoint.cpp
Normal file
16
src/collision/ColPoint.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "ColPoint.h"
|
||||||
|
|
||||||
|
CColPoint&
|
||||||
|
CColPoint::operator=(const CColPoint &other)
|
||||||
|
{
|
||||||
|
point = other.point;
|
||||||
|
normal = other.normal;
|
||||||
|
surfaceA = other.surfaceA;
|
||||||
|
pieceA = other.pieceA;
|
||||||
|
surfaceB = other.surfaceB;
|
||||||
|
pieceB = other.pieceB;
|
||||||
|
|
||||||
|
// no depth?
|
||||||
|
return *this;
|
||||||
|
}
|
34
src/collision/ColPoint.h
Normal file
34
src/collision/ColPoint.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct CColPoint
|
||||||
|
{
|
||||||
|
CVector point;
|
||||||
|
int pad1;
|
||||||
|
// the surface normal on the surface of point
|
||||||
|
CVector normal;
|
||||||
|
int pad2;
|
||||||
|
uint8 surfaceA;
|
||||||
|
uint8 pieceA;
|
||||||
|
uint8 surfaceB;
|
||||||
|
uint8 pieceB;
|
||||||
|
float depth;
|
||||||
|
|
||||||
|
const CVector &GetNormal() { return normal; }
|
||||||
|
float GetDepth() { return depth; }
|
||||||
|
void Set(float depth, uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) {
|
||||||
|
this->depth = depth;
|
||||||
|
this->surfaceA = surfA;
|
||||||
|
this->pieceA = pieceA;
|
||||||
|
this->surfaceB = surfB;
|
||||||
|
this->pieceB = pieceB;
|
||||||
|
}
|
||||||
|
void Set(uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) {
|
||||||
|
this->surfaceA = surfA;
|
||||||
|
this->pieceA = pieceA;
|
||||||
|
this->surfaceB = surfB;
|
||||||
|
this->pieceB = pieceB;
|
||||||
|
}
|
||||||
|
|
||||||
|
CColPoint &operator=(const CColPoint &other);
|
||||||
|
};
|
||||||
|
|
11
src/collision/ColSphere.cpp
Normal file
11
src/collision/ColSphere.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "ColSphere.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
CColSphere::Set(float radius, const CVector ¢er, uint8 surf, uint8 piece)
|
||||||
|
{
|
||||||
|
this->radius = radius;
|
||||||
|
this->center = center;
|
||||||
|
this->surface = surf;
|
||||||
|
this->piece = piece;
|
||||||
|
}
|
13
src/collision/ColSphere.h
Normal file
13
src/collision/ColSphere.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SurfaceTable.h"
|
||||||
|
|
||||||
|
struct CColSphere
|
||||||
|
{
|
||||||
|
// NB: this has to be compatible with a CVuVector
|
||||||
|
CVector center;
|
||||||
|
float radius;
|
||||||
|
uint8 surface;
|
||||||
|
uint8 piece;
|
||||||
|
void Set(float radius, const CVector ¢er, uint8 surf = SURFACE_DEFAULT, uint8 piece = 0);
|
||||||
|
};
|
41
src/collision/ColTriangle.cpp
Normal file
41
src/collision/ColTriangle.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "ColTriangle.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
CColTriangle::Set(const CompressedVector *, int a, int b, int c, uint8 surf, uint8 piece)
|
||||||
|
{
|
||||||
|
this->a = a;
|
||||||
|
this->b = b;
|
||||||
|
this->c = c;
|
||||||
|
this->surface = surf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef VU_COLLISION
|
||||||
|
void
|
||||||
|
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
|
||||||
|
{
|
||||||
|
CVector norm = CrossProduct(vc-va, vb-va);
|
||||||
|
norm.Normalise();
|
||||||
|
float d = DotProduct(norm, va);
|
||||||
|
normal.x = norm.x*4096.0f;
|
||||||
|
normal.y = norm.y*4096.0f;
|
||||||
|
normal.z = norm.z*4096.0f;
|
||||||
|
dist = d*128.0f;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
|
||||||
|
{
|
||||||
|
normal = CrossProduct(vc-va, vb-va);
|
||||||
|
normal.Normalise();
|
||||||
|
dist = DotProduct(normal, va);
|
||||||
|
CVector an(Abs(normal.x), Abs(normal.y), Abs(normal.z));
|
||||||
|
// find out largest component and its direction
|
||||||
|
if(an.x > an.y && an.x > an.z)
|
||||||
|
dir = normal.x < 0.0f ? DIR_X_NEG : DIR_X_POS;
|
||||||
|
else if(an.y > an.z)
|
||||||
|
dir = normal.y < 0.0f ? DIR_Y_NEG : DIR_Y_POS;
|
||||||
|
else
|
||||||
|
dir = normal.z < 0.0f ? DIR_Z_NEG : DIR_Z_POS;
|
||||||
|
}
|
||||||
|
#endif
|
68
src/collision/ColTriangle.h
Normal file
68
src/collision/ColTriangle.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CompressedVector.h"
|
||||||
|
|
||||||
|
enum Direction {
|
||||||
|
DIR_X_POS,
|
||||||
|
DIR_X_NEG,
|
||||||
|
DIR_Y_POS,
|
||||||
|
DIR_Y_NEG,
|
||||||
|
DIR_Z_POS,
|
||||||
|
DIR_Z_NEG,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CColTriangle
|
||||||
|
{
|
||||||
|
uint16 a;
|
||||||
|
uint16 b;
|
||||||
|
uint16 c;
|
||||||
|
uint8 surface;
|
||||||
|
|
||||||
|
void Set(const CompressedVector *v, int a, int b, int c, uint8 surf, uint8 piece);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CColTrianglePlane
|
||||||
|
{
|
||||||
|
#ifdef VU_COLLISION
|
||||||
|
CompressedVector normal;
|
||||||
|
int16 dist;
|
||||||
|
|
||||||
|
void Set(const CVector &va, const CVector &vb, const CVector &vc);
|
||||||
|
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
|
||||||
|
void GetNormal(CVector &n) const { n.x = normal.x/4096.0f; n.y = normal.y/4096.0f; n.z = normal.z/4096.0f; }
|
||||||
|
float CalcPoint(const CVector &v) const { CVector n; GetNormal(n); return DotProduct(n, v) - dist/128.0f; };
|
||||||
|
#ifdef GTA_PS2
|
||||||
|
void Unpack(uint128 &qword) const {
|
||||||
|
__asm__ volatile (
|
||||||
|
"lh $8, 0(%1)\n"
|
||||||
|
"lh $9, 2(%1)\n"
|
||||||
|
"lh $10, 4(%1)\n"
|
||||||
|
"lh $11, 6(%1)\n"
|
||||||
|
"pextlw $10, $8\n"
|
||||||
|
"pextlw $11, $9\n"
|
||||||
|
"pextlw $2, $11, $10\n"
|
||||||
|
"sq $2, %0\n"
|
||||||
|
: "=m" (qword)
|
||||||
|
: "r" (this)
|
||||||
|
: "$8", "$9", "$10", "$11", "$2"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void Unpack(int32 *qword) const {
|
||||||
|
qword[0] = normal.x;
|
||||||
|
qword[1] = normal.y;
|
||||||
|
qword[2] = normal.z;
|
||||||
|
qword[3] = dist;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
CVector normal;
|
||||||
|
float dist;
|
||||||
|
uint8 dir;
|
||||||
|
|
||||||
|
void Set(const CVector &va, const CVector &vb, const CVector &vc);
|
||||||
|
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
|
||||||
|
void GetNormal(CVector &n) const { n = normal; }
|
||||||
|
float CalcPoint(const CVector &v) const { return DotProduct(normal, v) - dist; };
|
||||||
|
#endif
|
||||||
|
};
|
@ -23,303 +23,8 @@
|
|||||||
#include "Collision.h"
|
#include "Collision.h"
|
||||||
#include "Frontend.h"
|
#include "Frontend.h"
|
||||||
|
|
||||||
|
|
||||||
// TODO: where do these go?
|
|
||||||
|
|
||||||
#ifdef VU_COLLISION
|
#ifdef VU_COLLISION
|
||||||
|
#include "VuCollision.h"
|
||||||
struct VuTriangle
|
|
||||||
{
|
|
||||||
// Compressed int16 but unpacked
|
|
||||||
#ifdef GTA_PS2
|
|
||||||
uint128 v0;
|
|
||||||
uint128 v1;
|
|
||||||
uint128 v2;
|
|
||||||
uint128 plane;
|
|
||||||
#else
|
|
||||||
int32 v0[4];
|
|
||||||
int32 v1[4];
|
|
||||||
int32 v2[4];
|
|
||||||
int32 plane[4];
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef GTA_PS2
|
|
||||||
static int16 vi01;
|
|
||||||
static CVuVector vf01;
|
|
||||||
static CVuVector vf02;
|
|
||||||
static CVuVector vf03;
|
|
||||||
|
|
||||||
CVuVector
|
|
||||||
DistanceBetweenSphereAndLine(const CVuVector ¢er, const CVuVector &p0, const CVuVector &line)
|
|
||||||
{
|
|
||||||
// center VF12
|
|
||||||
// p0 VF14
|
|
||||||
// line VF15
|
|
||||||
CVuVector ret; // VF16
|
|
||||||
CVuVector p1 = p0+line;
|
|
||||||
CVuVector dist0 = center - p0; // VF20
|
|
||||||
CVuVector dist1 = center - p1; // VF25
|
|
||||||
float lenSq = line.MagnitudeSqr(); // VF21
|
|
||||||
float distSq0 = dist0.MagnitudeSqr(); // VF22
|
|
||||||
float distSq1 = dist1.MagnitudeSqr();
|
|
||||||
float dot = DotProduct(dist0, line); // VF23
|
|
||||||
if(dot < 0.0f){
|
|
||||||
// not above line, closest to p0
|
|
||||||
ret = p0;
|
|
||||||
ret.w = distSq0;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
float t = dot/lenSq; // param of nearest point on infinite line
|
|
||||||
if(t > 1.0f){
|
|
||||||
// not above line, closest to p1
|
|
||||||
ret = p1;
|
|
||||||
ret.w = distSq1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
// closest to line
|
|
||||||
ret = p0 + line*t;
|
|
||||||
ret.w = (ret - center).MagnitudeSqr();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
inline int SignFlags(const CVector &v)
|
|
||||||
{
|
|
||||||
int f = 0;
|
|
||||||
if(v.x < 0.0f) f |= 1;
|
|
||||||
if(v.y < 0.0f) f |= 2;
|
|
||||||
if(v.z < 0.0f) f |= 4;
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern "C" void
|
|
||||||
LineToTriangleCollision(const CVuVector &p0, const CVuVector &p1,
|
|
||||||
const CVuVector &v0, const CVuVector &v1, const CVuVector &v2,
|
|
||||||
const CVuVector &plane)
|
|
||||||
{
|
|
||||||
#ifdef GTA_PS2
|
|
||||||
__asm__ volatile (
|
|
||||||
".set noreorder\n"
|
|
||||||
"lqc2 vf12, 0x0(%0)\n"
|
|
||||||
"lqc2 vf13, 0x0(%1)\n"
|
|
||||||
"lqc2 vf14, 0x0(%2)\n"
|
|
||||||
"lqc2 vf15, 0x0(%3)\n"
|
|
||||||
"lqc2 vf16, 0x0(%4)\n"
|
|
||||||
"lqc2 vf17, 0x0(%5)\n"
|
|
||||||
"vcallms Vu0LineToTriangleCollisionStart\n"
|
|
||||||
".set reorder\n"
|
|
||||||
:
|
|
||||||
: "r" (&p0), "r" (&p1), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane)
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
float dot0 = DotProduct(plane, p0);
|
|
||||||
float dot1 = DotProduct(plane, p1);
|
|
||||||
float dist0 = plane.w - dot0;
|
|
||||||
float dist1 = plane.w - dot1;
|
|
||||||
|
|
||||||
// if points are on the same side, no collision
|
|
||||||
if(dist0 * dist1 > 0.0f){
|
|
||||||
vi01 = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVuVector diff = p1 - p0;
|
|
||||||
float t = dist0/(dot1 - dot0);
|
|
||||||
CVuVector p = p0 + diff*t;
|
|
||||||
p.w = 0.0f;
|
|
||||||
vf01 = p;
|
|
||||||
vf03.x = t;
|
|
||||||
|
|
||||||
// Check if point is inside
|
|
||||||
CVector cross1 = CrossProduct(p-v0, v1-v0);
|
|
||||||
CVector cross2 = CrossProduct(p-v1, v2-v1);
|
|
||||||
CVector cross3 = CrossProduct(p-v2, v0-v2);
|
|
||||||
// Only check relevant directions
|
|
||||||
int flagmask = 0;
|
|
||||||
if(Abs(plane.x) > 0.5f) flagmask |= 1;
|
|
||||||
if(Abs(plane.y) > 0.5f) flagmask |= 2;
|
|
||||||
if(Abs(plane.z) > 0.5f) flagmask |= 4;
|
|
||||||
int flags1 = SignFlags(cross1) & flagmask;
|
|
||||||
int flags2 = SignFlags(cross2) & flagmask;
|
|
||||||
int flags3 = SignFlags(cross3) & flagmask;
|
|
||||||
// inside if on the same side of all edges
|
|
||||||
if(flags1 != flags2 || flags1 != flags3){
|
|
||||||
vi01 = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
vi01 = 1;
|
|
||||||
vf02 = plane;
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void
|
|
||||||
LineToTriangleCollisionCompressed(const CVuVector &p0, const CVuVector &p1, VuTriangle &tri)
|
|
||||||
{
|
|
||||||
#ifdef GTA_PS2
|
|
||||||
__asm__ volatile (
|
|
||||||
".set noreorder\n"
|
|
||||||
"lqc2 vf12, 0x0(%0)\n"
|
|
||||||
"lqc2 vf13, 0x0(%1)\n"
|
|
||||||
"lqc2 vf14, 0x0(%2)\n"
|
|
||||||
"lqc2 vf15, 0x10(%2)\n"
|
|
||||||
"lqc2 vf16, 0x20(%2)\n"
|
|
||||||
"lqc2 vf17, 0x30(%2)\n"
|
|
||||||
"vcallms Vu0LineToTriangleCollisionCompressedStart\n"
|
|
||||||
".set reorder\n"
|
|
||||||
:
|
|
||||||
: "r" (&p0), "r" (&p1), "r" (&tri)
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
CVuVector v0, v1, v2, plane;
|
|
||||||
v0.x = tri.v0[0]/128.0f;
|
|
||||||
v0.y = tri.v0[1]/128.0f;
|
|
||||||
v0.z = tri.v0[2]/128.0f;
|
|
||||||
v0.w = tri.v0[3]/128.0f;
|
|
||||||
v1.x = tri.v1[0]/128.0f;
|
|
||||||
v1.y = tri.v1[1]/128.0f;
|
|
||||||
v1.z = tri.v1[2]/128.0f;
|
|
||||||
v1.w = tri.v1[3]/128.0f;
|
|
||||||
v2.x = tri.v2[0]/128.0f;
|
|
||||||
v2.y = tri.v2[1]/128.0f;
|
|
||||||
v2.z = tri.v2[2]/128.0f;
|
|
||||||
v2.w = tri.v2[3]/128.0f;
|
|
||||||
plane.x = tri.plane[0]/4096.0f;
|
|
||||||
plane.y = tri.plane[1]/4096.0f;
|
|
||||||
plane.z = tri.plane[2]/4096.0f;
|
|
||||||
plane.w = tri.plane[3]/128.0f;
|
|
||||||
LineToTriangleCollision(p0, p1, v0, v1, v2, plane);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void
|
|
||||||
SphereToTriangleCollision(const CVuVector &sph,
|
|
||||||
const CVuVector &v0, const CVuVector &v1, const CVuVector &v2,
|
|
||||||
const CVuVector &plane)
|
|
||||||
{
|
|
||||||
#ifdef GTA_PS2
|
|
||||||
__asm__ volatile (
|
|
||||||
".set noreorder\n"
|
|
||||||
"lqc2 vf12, 0x0(%0)\n"
|
|
||||||
"lqc2 vf14, 0x0(%1)\n"
|
|
||||||
"lqc2 vf15, 0x0(%2)\n"
|
|
||||||
"lqc2 vf16, 0x0(%3)\n"
|
|
||||||
"lqc2 vf17, 0x0(%4)\n"
|
|
||||||
"vcallms Vu0SphereToTriangleCollisionStart\n"
|
|
||||||
".set reorder\n"
|
|
||||||
:
|
|
||||||
: "r" (&sph), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane)
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
float planedist = DotProduct(plane, sph) - plane.w; // VF02
|
|
||||||
if(Abs(planedist) > sph.w){
|
|
||||||
vi01 = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// point on plane
|
|
||||||
CVuVector p = sph - planedist*plane;
|
|
||||||
p.w = 0.0f;
|
|
||||||
vf01 = p;
|
|
||||||
planedist = Abs(planedist);
|
|
||||||
// edges
|
|
||||||
CVuVector v01 = v1 - v0;
|
|
||||||
CVuVector v12 = v2 - v1;
|
|
||||||
CVuVector v20 = v0 - v2;
|
|
||||||
// VU code calculates normal again for some weird reason...
|
|
||||||
// Check sides of point
|
|
||||||
CVector cross1 = CrossProduct(p-v0, v01);
|
|
||||||
CVector cross2 = CrossProduct(p-v1, v12);
|
|
||||||
CVector cross3 = CrossProduct(p-v2, v20);
|
|
||||||
// Only check relevant directions
|
|
||||||
int flagmask = 0;
|
|
||||||
if(Abs(plane.x) > 0.1f) flagmask |= 1;
|
|
||||||
if(Abs(plane.y) > 0.1f) flagmask |= 2;
|
|
||||||
if(Abs(plane.z) > 0.1f) flagmask |= 4;
|
|
||||||
int nflags = SignFlags(plane) & flagmask;
|
|
||||||
int flags1 = SignFlags(cross1) & flagmask;
|
|
||||||
int flags2 = SignFlags(cross2) & flagmask;
|
|
||||||
int flags3 = SignFlags(cross3) & flagmask;
|
|
||||||
int testcase = 0;
|
|
||||||
CVuVector closest(0.0f, 0.0f, 0.0f); // VF04
|
|
||||||
if(flags1 == nflags){
|
|
||||||
closest += v2;
|
|
||||||
testcase++;
|
|
||||||
}
|
|
||||||
if(flags2 == nflags){
|
|
||||||
closest += v0;
|
|
||||||
testcase++;
|
|
||||||
}
|
|
||||||
if(flags3 == nflags){
|
|
||||||
closest += v1;
|
|
||||||
testcase++;
|
|
||||||
}
|
|
||||||
if(testcase == 3){
|
|
||||||
// inside triangle - dist to plane already checked
|
|
||||||
vf02 = plane;
|
|
||||||
vf02.w = vf03.x = planedist;
|
|
||||||
vi01 = 1;
|
|
||||||
}else if(testcase == 1){
|
|
||||||
// outside two sides - closest to point opposide inside edge
|
|
||||||
vf01 = closest;
|
|
||||||
vf02 = sph - closest;
|
|
||||||
float distSq = vf02.MagnitudeSqr();
|
|
||||||
vi01 = sph.w*sph.w > distSq;
|
|
||||||
vf03.x = Sqrt(distSq);
|
|
||||||
vf02 *= 1.0f/vf03.x;
|
|
||||||
}else{
|
|
||||||
// inside two sides - closest to third edge
|
|
||||||
if(flags1 != nflags)
|
|
||||||
closest = DistanceBetweenSphereAndLine(sph, v0, v01);
|
|
||||||
else if(flags2 != nflags)
|
|
||||||
closest = DistanceBetweenSphereAndLine(sph, v1, v12);
|
|
||||||
else
|
|
||||||
closest = DistanceBetweenSphereAndLine(sph, v2, v20);
|
|
||||||
vi01 = sph.w*sph.w > closest.w;
|
|
||||||
vf01 = closest;
|
|
||||||
vf02 = sph - closest;
|
|
||||||
vf03.x = Sqrt(closest.w);
|
|
||||||
vf02 *= 1.0f/vf03.x;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void
|
|
||||||
SphereToTriangleCollisionCompressed(const CVuVector &sph, VuTriangle &tri)
|
|
||||||
{
|
|
||||||
#ifdef GTA_PS2
|
|
||||||
__asm__ volatile (
|
|
||||||
".set noreorder\n"
|
|
||||||
"lqc2 vf12, 0x0(%0)\n"
|
|
||||||
"lqc2 vf14, 0x0(%1)\n"
|
|
||||||
"lqc2 vf15, 0x10(%1)\n"
|
|
||||||
"lqc2 vf16, 0x20(%1)\n"
|
|
||||||
"lqc2 vf17, 0x30(%1)\n"
|
|
||||||
"vcallms Vu0SphereToTriangleCollisionCompressedStart\n"
|
|
||||||
".set reorder\n"
|
|
||||||
:
|
|
||||||
: "r" (&sph), "r" (&tri)
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
CVuVector v0, v1, v2, plane;
|
|
||||||
v0.x = tri.v0[0]/128.0f;
|
|
||||||
v0.y = tri.v0[1]/128.0f;
|
|
||||||
v0.z = tri.v0[2]/128.0f;
|
|
||||||
v0.w = tri.v0[3]/128.0f;
|
|
||||||
v1.x = tri.v1[0]/128.0f;
|
|
||||||
v1.y = tri.v1[1]/128.0f;
|
|
||||||
v1.z = tri.v1[2]/128.0f;
|
|
||||||
v1.w = tri.v1[3]/128.0f;
|
|
||||||
v2.x = tri.v2[0]/128.0f;
|
|
||||||
v2.y = tri.v2[1]/128.0f;
|
|
||||||
v2.z = tri.v2[2]/128.0f;
|
|
||||||
v2.w = tri.v2[3]/128.0f;
|
|
||||||
plane.x = tri.plane[0]/4096.0f;
|
|
||||||
plane.y = tri.plane[1]/4096.0f;
|
|
||||||
plane.z = tri.plane[2]/4096.0f;
|
|
||||||
plane.w = tri.plane[3]/128.0f;
|
|
||||||
SphereToTriangleCollision(sph, v0, v1, v2, plane);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int
|
inline int
|
||||||
GetVUresult(void)
|
GetVUresult(void)
|
||||||
@ -362,17 +67,6 @@ GetVUresult(CVuVector &point, CVuVector &normal, float &dist)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
enum Direction
|
|
||||||
{
|
|
||||||
DIR_X_POS,
|
|
||||||
DIR_X_NEG,
|
|
||||||
DIR_Y_POS,
|
|
||||||
DIR_Y_NEG,
|
|
||||||
DIR_Z_POS,
|
|
||||||
DIR_Z_NEG,
|
|
||||||
};
|
|
||||||
|
|
||||||
eLevelName CCollision::ms_collisionInMemory;
|
eLevelName CCollision::ms_collisionInMemory;
|
||||||
CLinkList<CColModel*> CCollision::ms_colModelCache;
|
CLinkList<CColModel*> CCollision::ms_colModelCache;
|
||||||
|
|
||||||
@ -2412,11 +2106,12 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
|
|||||||
assert(modelA.numLines <= MAXNUMLINES);
|
assert(modelA.numLines <= MAXNUMLINES);
|
||||||
|
|
||||||
// From model A space to model B space
|
// From model A space to model B space
|
||||||
Invert(matrixB, matAB);
|
matAB = Invert(matrixB, matAB);
|
||||||
matAB *= matrixA;
|
matAB *= matrixA;
|
||||||
|
|
||||||
CColSphere bsphereAB; // bounding sphere of A in B space
|
CColSphere bsphereAB; // bounding sphere of A in B space
|
||||||
bsphereAB.Set(modelA.boundingSphere.radius, matAB * modelA.boundingSphere.center);
|
bsphereAB.radius = modelA.boundingSphere.radius;
|
||||||
|
bsphereAB.center = matAB * modelA.boundingSphere.center;
|
||||||
if(!TestSphereBox(bsphereAB, modelB.boundingBox))
|
if(!TestSphereBox(bsphereAB, modelB.boundingBox))
|
||||||
return 0;
|
return 0;
|
||||||
// B to A space
|
// B to A space
|
||||||
@ -2449,7 +2144,8 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
|
|||||||
int numBoxesB = 0;
|
int numBoxesB = 0;
|
||||||
int numTrianglesB = 0;
|
int numTrianglesB = 0;
|
||||||
for(i = 0; i < modelB.numSpheres; i++){
|
for(i = 0; i < modelB.numSpheres; i++){
|
||||||
s.Set(modelB.spheres[i].radius, matBA * modelB.spheres[i].center);
|
s.radius = modelB.spheres[i].radius;
|
||||||
|
s.center = matBA * modelB.spheres[i].center;
|
||||||
if(TestSphereBox(s, modelA.boundingBox))
|
if(TestSphereBox(s, modelA.boundingBox))
|
||||||
aSphereIndicesB[numSpheresB++] = i;
|
aSphereIndicesB[numSpheresB++] = i;
|
||||||
}
|
}
|
||||||
@ -3037,254 +2733,4 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel,
|
|||||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ColModel code
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
CColSphere::Set(float radius, const CVector ¢er, uint8 surf, uint8 piece)
|
|
||||||
{
|
|
||||||
this->radius = radius;
|
|
||||||
this->center = center;
|
|
||||||
this->surface = surf;
|
|
||||||
this->piece = piece;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CColBox::Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece)
|
|
||||||
{
|
|
||||||
this->min = min;
|
|
||||||
this->max = max;
|
|
||||||
this->surface = surf;
|
|
||||||
this->piece = piece;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CColLine::Set(const CVector &p0, const CVector &p1)
|
|
||||||
{
|
|
||||||
this->p0 = p0;
|
|
||||||
this->p1 = p1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CColTriangle::Set(const CompressedVector *, int a, int b, int c, uint8 surf, uint8 piece)
|
|
||||||
{
|
|
||||||
this->a = a;
|
|
||||||
this->b = b;
|
|
||||||
this->c = c;
|
|
||||||
this->surface = surf;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef VU_COLLISION
|
|
||||||
void
|
|
||||||
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
|
|
||||||
{
|
|
||||||
CVector norm = CrossProduct(vc-va, vb-va);
|
|
||||||
norm.Normalise();
|
|
||||||
float d = DotProduct(norm, va);
|
|
||||||
normal.x = norm.x*4096.0f;
|
|
||||||
normal.y = norm.y*4096.0f;
|
|
||||||
normal.z = norm.z*4096.0f;
|
|
||||||
dist = d*128.0f;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void
|
|
||||||
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
|
|
||||||
{
|
|
||||||
normal = CrossProduct(vc-va, vb-va);
|
|
||||||
normal.Normalise();
|
|
||||||
dist = DotProduct(normal, va);
|
|
||||||
CVector an(Abs(normal.x), Abs(normal.y), Abs(normal.z));
|
|
||||||
// find out largest component and its direction
|
|
||||||
if(an.x > an.y && an.x > an.z)
|
|
||||||
dir = normal.x < 0.0f ? DIR_X_NEG : DIR_X_POS;
|
|
||||||
else if(an.y > an.z)
|
|
||||||
dir = normal.y < 0.0f ? DIR_Y_NEG : DIR_Y_POS;
|
|
||||||
else
|
|
||||||
dir = normal.z < 0.0f ? DIR_Z_NEG : DIR_Z_POS;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CColModel::CColModel(void)
|
|
||||||
{
|
|
||||||
numSpheres = 0;
|
|
||||||
spheres = nil;
|
|
||||||
numLines = 0;
|
|
||||||
lines = nil;
|
|
||||||
numBoxes = 0;
|
|
||||||
boxes = nil;
|
|
||||||
numTriangles = 0;
|
|
||||||
vertices = nil;
|
|
||||||
triangles = nil;
|
|
||||||
trianglePlanes = nil;
|
|
||||||
level = CGame::currLevel;
|
|
||||||
ownsCollisionVolumes = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CColModel::~CColModel(void)
|
|
||||||
{
|
|
||||||
RemoveCollisionVolumes();
|
|
||||||
RemoveTrianglePlanes();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CColModel::RemoveCollisionVolumes(void)
|
|
||||||
{
|
|
||||||
if(ownsCollisionVolumes){
|
|
||||||
RwFree(spheres);
|
|
||||||
RwFree(lines);
|
|
||||||
RwFree(boxes);
|
|
||||||
RwFree(vertices);
|
|
||||||
RwFree(triangles);
|
|
||||||
}
|
|
||||||
numSpheres = 0;
|
|
||||||
numLines = 0;
|
|
||||||
numBoxes = 0;
|
|
||||||
numTriangles = 0;
|
|
||||||
spheres = nil;
|
|
||||||
lines = nil;
|
|
||||||
boxes = nil;
|
|
||||||
vertices = nil;
|
|
||||||
triangles = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CColModel::CalculateTrianglePlanes(void)
|
|
||||||
{
|
|
||||||
// HACK: allocate space for one more element to stuff the link pointer into
|
|
||||||
trianglePlanes = (CColTrianglePlane*)RwMalloc(sizeof(CColTrianglePlane) * (numTriangles+1));
|
|
||||||
for(int i = 0; i < numTriangles; i++)
|
|
||||||
trianglePlanes[i].Set(vertices, triangles[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CColModel::RemoveTrianglePlanes(void)
|
|
||||||
{
|
|
||||||
RwFree(trianglePlanes);
|
|
||||||
trianglePlanes = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CColModel::SetLinkPtr(CLink<CColModel*> *lptr)
|
|
||||||
{
|
|
||||||
assert(trianglePlanes);
|
|
||||||
*(CLink<CColModel*>**)ALIGNPTR(&trianglePlanes[numTriangles]) = lptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLink<CColModel*>*
|
|
||||||
CColModel::GetLinkPtr(void)
|
|
||||||
{
|
|
||||||
assert(trianglePlanes);
|
|
||||||
return *(CLink<CColModel*>**)ALIGNPTR(&trianglePlanes[numTriangles]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CColModel::GetTrianglePoint(CVector &v, int i) const
|
|
||||||
{
|
|
||||||
v = vertices[i].Get();
|
|
||||||
}
|
|
||||||
|
|
||||||
CColModel&
|
|
||||||
CColModel::operator=(const CColModel &other)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int numVerts;
|
|
||||||
|
|
||||||
boundingSphere = other.boundingSphere;
|
|
||||||
boundingBox = other.boundingBox;
|
|
||||||
|
|
||||||
// copy spheres
|
|
||||||
if(other.numSpheres){
|
|
||||||
if(numSpheres != other.numSpheres){
|
|
||||||
numSpheres = other.numSpheres;
|
|
||||||
if(spheres)
|
|
||||||
RwFree(spheres);
|
|
||||||
spheres = (CColSphere*)RwMalloc(numSpheres*sizeof(CColSphere));
|
|
||||||
}
|
|
||||||
for(i = 0; i < numSpheres; i++)
|
|
||||||
spheres[i] = other.spheres[i];
|
|
||||||
}else{
|
|
||||||
numSpheres = 0;
|
|
||||||
if(spheres)
|
|
||||||
RwFree(spheres);
|
|
||||||
spheres = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy lines
|
|
||||||
if(other.numLines){
|
|
||||||
if(numLines != other.numLines){
|
|
||||||
numLines = other.numLines;
|
|
||||||
if(lines)
|
|
||||||
RwFree(lines);
|
|
||||||
lines = (CColLine*)RwMalloc(numLines*sizeof(CColLine));
|
|
||||||
}
|
|
||||||
for(i = 0; i < numLines; i++)
|
|
||||||
lines[i] = other.lines[i];
|
|
||||||
}else{
|
|
||||||
numLines = 0;
|
|
||||||
if(lines)
|
|
||||||
RwFree(lines);
|
|
||||||
lines = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy boxes
|
|
||||||
if(other.numBoxes){
|
|
||||||
if(numBoxes != other.numBoxes){
|
|
||||||
numBoxes = other.numBoxes;
|
|
||||||
if(boxes)
|
|
||||||
RwFree(boxes);
|
|
||||||
boxes = (CColBox*)RwMalloc(numBoxes*sizeof(CColBox));
|
|
||||||
}
|
|
||||||
for(i = 0; i < numBoxes; i++)
|
|
||||||
boxes[i] = other.boxes[i];
|
|
||||||
}else{
|
|
||||||
numBoxes = 0;
|
|
||||||
if(boxes)
|
|
||||||
RwFree(boxes);
|
|
||||||
boxes = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy mesh
|
|
||||||
if(other.numTriangles){
|
|
||||||
// copy vertices
|
|
||||||
numVerts = 0;
|
|
||||||
for(i = 0; i < other.numTriangles; i++){
|
|
||||||
if(other.triangles[i].a > numVerts)
|
|
||||||
numVerts = other.triangles[i].a;
|
|
||||||
if(other.triangles[i].b > numVerts)
|
|
||||||
numVerts = other.triangles[i].b;
|
|
||||||
if(other.triangles[i].c > numVerts)
|
|
||||||
numVerts = other.triangles[i].c;
|
|
||||||
}
|
|
||||||
numVerts++;
|
|
||||||
if(vertices)
|
|
||||||
RwFree(vertices);
|
|
||||||
if(numVerts){
|
|
||||||
vertices = (CompressedVector*)RwMalloc(numVerts*sizeof(CompressedVector));
|
|
||||||
for(i = 0; i < numVerts; i++)
|
|
||||||
vertices[i] = other.vertices[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy triangles
|
|
||||||
if(numTriangles != other.numTriangles){
|
|
||||||
numTriangles = other.numTriangles;
|
|
||||||
if(triangles)
|
|
||||||
RwFree(triangles);
|
|
||||||
triangles = (CColTriangle*)RwMalloc(numTriangles*sizeof(CColTriangle));
|
|
||||||
}
|
|
||||||
for(i = 0; i < numTriangles; i++)
|
|
||||||
triangles[i] = other.triangles[i];
|
|
||||||
}else{
|
|
||||||
numTriangles = 0;
|
|
||||||
if(triangles)
|
|
||||||
RwFree(triangles);
|
|
||||||
triangles = nil;
|
|
||||||
if(vertices)
|
|
||||||
RwFree(vertices);
|
|
||||||
vertices = nil;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
70
src/collision/Collision.h
Normal file
70
src/collision/Collision.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ColModel.h"
|
||||||
|
#include "Game.h" // for eLevelName
|
||||||
|
#ifdef VU_COLLISION
|
||||||
|
#include "VuVector.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct CStoredCollPoly
|
||||||
|
{
|
||||||
|
#ifdef VU_COLLISION
|
||||||
|
CVuVector verts[3];
|
||||||
|
#else
|
||||||
|
CVector verts[3];
|
||||||
|
#endif
|
||||||
|
bool valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
// If you spawn many tanks at once, you will see that collisions of two entity exceeds 32.
|
||||||
|
#if defined(FIX_BUGS) && !defined(SQUEEZE_PERFORMANCE)
|
||||||
|
#define MAX_COLLISION_POINTS 64
|
||||||
|
#else
|
||||||
|
#define MAX_COLLISION_POINTS 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class CCollision
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static eLevelName ms_collisionInMemory;
|
||||||
|
static CLinkList<CColModel*> ms_colModelCache;
|
||||||
|
#ifdef NO_ISLAND_LOADING
|
||||||
|
static bool bAlreadyLoaded;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void Init(void);
|
||||||
|
static void Shutdown(void);
|
||||||
|
static void Update(void);
|
||||||
|
static void LoadCollisionWhenINeedIt(bool changeLevel);
|
||||||
|
static void SortOutCollisionAfterLoad(void);
|
||||||
|
static void LoadCollisionScreen(eLevelName level);
|
||||||
|
static void DrawColModel(const CMatrix &mat, const CColModel &colModel);
|
||||||
|
static void DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id);
|
||||||
|
|
||||||
|
static void CalculateTrianglePlanes(CColModel *model);
|
||||||
|
|
||||||
|
// all these return true if there's a collision
|
||||||
|
static bool TestSphereSphere(const CColSphere &s1, const CColSphere &s2);
|
||||||
|
static bool TestSphereBox(const CColSphere &sph, const CColBox &box);
|
||||||
|
static bool TestLineBox(const CColLine &line, const CColBox &box);
|
||||||
|
static bool TestVerticalLineBox(const CColLine &line, const CColBox &box);
|
||||||
|
static bool TestLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
|
||||||
|
static bool TestLineSphere(const CColLine &line, const CColSphere &sph);
|
||||||
|
static bool TestSphereTriangle(const CColSphere &sphere, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
|
||||||
|
static bool TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough);
|
||||||
|
|
||||||
|
static bool ProcessSphereSphere(const CColSphere &s1, const CColSphere &s2, CColPoint &point, float &mindistsq);
|
||||||
|
static bool ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoint &point, float &mindistsq);
|
||||||
|
static bool ProcessLineBox(const CColLine &line, const CColBox &box, CColPoint &point, float &mindist);
|
||||||
|
static bool ProcessVerticalLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly);
|
||||||
|
static bool ProcessLineTriangle(const CColLine &line , const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist);
|
||||||
|
static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist);
|
||||||
|
static bool ProcessSphereTriangle(const CColSphere &sph, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq);
|
||||||
|
static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough);
|
||||||
|
static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly);
|
||||||
|
static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists);
|
||||||
|
static bool IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CColPoint &point, CStoredCollPoly *poly);
|
||||||
|
|
||||||
|
static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point);
|
||||||
|
static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point, CVector &closest);
|
||||||
|
};
|
36
src/collision/CompressedVector.h
Normal file
36
src/collision/CompressedVector.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct CompressedVector
|
||||||
|
{
|
||||||
|
#ifdef COMPRESSED_COL_VECTORS
|
||||||
|
int16 x, y, z;
|
||||||
|
CVector Get(void) const { return CVector(x, y, z)/128.0f; };
|
||||||
|
void Set(float x, float y, float z) { this->x = x*128.0f; this->y = y*128.0f; this->z = z*128.0f; };
|
||||||
|
#ifdef GTA_PS2
|
||||||
|
void Unpack(uint128 &qword) const {
|
||||||
|
__asm__ volatile (
|
||||||
|
"lh $8, 0(%1)\n"
|
||||||
|
"lh $9, 2(%1)\n"
|
||||||
|
"lh $10, 4(%1)\n"
|
||||||
|
"pextlw $10, $8\n"
|
||||||
|
"pextlw $2, $9, $10\n"
|
||||||
|
"sq $2, %0\n"
|
||||||
|
: "=m" (qword)
|
||||||
|
: "r" (this)
|
||||||
|
: "$8", "$9", "$10", "$2"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void Unpack(int32 *qword) const {
|
||||||
|
qword[0] = x;
|
||||||
|
qword[1] = y;
|
||||||
|
qword[2] = z;
|
||||||
|
qword[3] = 0; // junk
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
float x, y, z;
|
||||||
|
CVector Get(void) const { return CVector(x, y, z); };
|
||||||
|
void Set(float x, float y, float z) { this->x = x; this->y = y; this->z = z; };
|
||||||
|
#endif
|
||||||
|
};
|
@ -1,7 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include "TempColModels.h"
|
#include "TempColModels.h"
|
||||||
#include "SurfaceTable.h"
|
|
||||||
|
|
||||||
CColModel CTempColModels::ms_colModelPed1;
|
CColModel CTempColModels::ms_colModelPed1;
|
||||||
CColModel CTempColModels::ms_colModelPed2;
|
CColModel CTempColModels::ms_colModelPed2;
|
||||||
@ -45,13 +44,13 @@ CTempColModels::Initialise(void)
|
|||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
|
||||||
ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
|
ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
|
||||||
ms_colModelBBox.level = LEVEL_GENERIC;
|
ms_colModelBBox.level = LEVEL_GENERIC;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) {
|
for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) {
|
||||||
ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
|
||||||
ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
|
ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
|
||||||
ms_colModelCutObj[i].level = LEVEL_GENERIC;
|
ms_colModelCutObj[i].level = LEVEL_GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,8 +72,8 @@ CTempColModels::Initialise(void)
|
|||||||
s_aPedSpheres[i].piece = 0;
|
s_aPedSpheres[i].piece = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f));
|
||||||
ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f), SURFACE_DEFAULT, 0);
|
ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f));
|
||||||
SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres);
|
SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres);
|
||||||
|
|
||||||
// Ped 2 Spheres
|
// Ped 2 Spheres
|
||||||
@ -92,8 +91,8 @@ CTempColModels::Initialise(void)
|
|||||||
s_aPed2Spheres[i].piece = 0;
|
s_aPed2Spheres[i].piece = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
|
||||||
ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f));
|
||||||
|
|
||||||
SET_COLMODEL_SPHERES(ms_colModelPed2, s_aPed2Spheres);
|
SET_COLMODEL_SPHERES(ms_colModelPed2, s_aPed2Spheres);
|
||||||
|
|
||||||
@ -118,8 +117,8 @@ CTempColModels::Initialise(void)
|
|||||||
s_aPedGSpheres[2].piece = 0;
|
s_aPedGSpheres[2].piece = 0;
|
||||||
s_aPedGSpheres[3].piece = 6;
|
s_aPedGSpheres[3].piece = 6;
|
||||||
|
|
||||||
ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
|
||||||
ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f), SURFACE_DEFAULT, 0);
|
ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f));
|
||||||
|
|
||||||
SET_COLMODEL_SPHERES(ms_colModelPedGroundHit, s_aPedGSpheres);
|
SET_COLMODEL_SPHERES(ms_colModelPedGroundHit, s_aPedGSpheres);
|
||||||
|
|
||||||
@ -142,8 +141,8 @@ CTempColModels::Initialise(void)
|
|||||||
s_aDoorSpheres[i].piece = 0;
|
s_aDoorSpheres[i].piece = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f));
|
||||||
ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f), SURFACE_DEFAULT, 0);
|
ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f));
|
||||||
|
|
||||||
SET_COLMODEL_SPHERES(ms_colModelDoor1, s_aDoorSpheres);
|
SET_COLMODEL_SPHERES(ms_colModelDoor1, s_aDoorSpheres);
|
||||||
|
|
||||||
@ -162,8 +161,8 @@ CTempColModels::Initialise(void)
|
|||||||
s_aBumperSpheres[i].piece = 0;
|
s_aBumperSpheres[i].piece = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f));
|
||||||
ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, 0.2f), SURFACE_DEFAULT, 0);
|
ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, 0.2f));
|
||||||
|
|
||||||
SET_COLMODEL_SPHERES(ms_colModelBumper1, s_aBumperSpheres);
|
SET_COLMODEL_SPHERES(ms_colModelBumper1, s_aBumperSpheres);
|
||||||
|
|
||||||
@ -182,8 +181,8 @@ CTempColModels::Initialise(void)
|
|||||||
s_aPanelSpheres[i].piece = 0;
|
s_aPanelSpheres[i].piece = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f));
|
||||||
ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f), SURFACE_DEFAULT, 0);
|
ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f));
|
||||||
|
|
||||||
SET_COLMODEL_SPHERES(ms_colModelPanel1, s_aPanelSpheres);
|
SET_COLMODEL_SPHERES(ms_colModelPanel1, s_aPanelSpheres);
|
||||||
|
|
||||||
@ -202,8 +201,8 @@ CTempColModels::Initialise(void)
|
|||||||
s_aBonnetSpheres[i].piece = 0;
|
s_aBonnetSpheres[i].piece = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f));
|
||||||
ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f), SURFACE_DEFAULT, 0);
|
ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f));
|
||||||
|
|
||||||
SET_COLMODEL_SPHERES(ms_colModelBonnet1, s_aBonnetSpheres);
|
SET_COLMODEL_SPHERES(ms_colModelBonnet1, s_aBonnetSpheres);
|
||||||
|
|
||||||
@ -222,8 +221,8 @@ CTempColModels::Initialise(void)
|
|||||||
s_aBootSpheres[i].piece = 0;
|
s_aBootSpheres[i].piece = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f));
|
||||||
ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f), SURFACE_DEFAULT, 0);
|
ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f));
|
||||||
|
|
||||||
SET_COLMODEL_SPHERES(ms_colModelBoot1, s_aBootSpheres);
|
SET_COLMODEL_SPHERES(ms_colModelBoot1, s_aBootSpheres);
|
||||||
|
|
||||||
@ -244,8 +243,8 @@ CTempColModels::Initialise(void)
|
|||||||
s_aWheelSpheres[i].piece = 0;
|
s_aWheelSpheres[i].piece = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f));
|
||||||
ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f), SURFACE_DEFAULT, 0);
|
ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f));
|
||||||
|
|
||||||
SET_COLMODEL_SPHERES(ms_colModelWheel1, s_aWheelSpheres);
|
SET_COLMODEL_SPHERES(ms_colModelWheel1, s_aWheelSpheres);
|
||||||
|
|
||||||
@ -266,8 +265,8 @@ CTempColModels::Initialise(void)
|
|||||||
s_aBodyPartSpheres1[i].piece = 0;
|
s_aBodyPartSpheres1[i].piece = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f));
|
||||||
ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f), SURFACE_DEFAULT, 0);
|
ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f));
|
||||||
|
|
||||||
SET_COLMODEL_SPHERES(ms_colModelBodyPart1, s_aBodyPartSpheres1);
|
SET_COLMODEL_SPHERES(ms_colModelBodyPart1, s_aBodyPartSpheres1);
|
||||||
|
|
||||||
@ -288,8 +287,8 @@ CTempColModels::Initialise(void)
|
|||||||
s_aBodyPartSpheres2[i].piece = 0;
|
s_aBodyPartSpheres2[i].piece = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
|
ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f));
|
||||||
ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f), SURFACE_DEFAULT, 0);
|
ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f));
|
||||||
|
|
||||||
SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2);
|
SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2);
|
||||||
|
|
282
src/collision/VuCollision.cpp
Normal file
282
src/collision/VuCollision.cpp
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#ifdef VU_COLLISION
|
||||||
|
#include "VuVector.h"
|
||||||
|
#include "VuCollision.h"
|
||||||
|
|
||||||
|
#ifndef GTA_PS2
|
||||||
|
int16 vi01;
|
||||||
|
CVuVector vf01;
|
||||||
|
CVuVector vf02;
|
||||||
|
CVuVector vf03;
|
||||||
|
|
||||||
|
CVuVector
|
||||||
|
DistanceBetweenSphereAndLine(const CVuVector ¢er, const CVuVector &p0, const CVuVector &line)
|
||||||
|
{
|
||||||
|
// center VF12
|
||||||
|
// p0 VF14
|
||||||
|
// line VF15
|
||||||
|
CVuVector ret; // VF16
|
||||||
|
CVuVector p1 = p0+line;
|
||||||
|
CVuVector dist0 = center - p0; // VF20
|
||||||
|
CVuVector dist1 = center - p1; // VF25
|
||||||
|
float lenSq = line.MagnitudeSqr(); // VF21
|
||||||
|
float distSq0 = dist0.MagnitudeSqr(); // VF22
|
||||||
|
float distSq1 = dist1.MagnitudeSqr();
|
||||||
|
float dot = DotProduct(dist0, line); // VF23
|
||||||
|
if(dot < 0.0f){
|
||||||
|
// not above line, closest to p0
|
||||||
|
ret = p0;
|
||||||
|
ret.w = distSq0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
float t = dot/lenSq; // param of nearest point on infinite line
|
||||||
|
if(t > 1.0f){
|
||||||
|
// not above line, closest to p1
|
||||||
|
ret = p1;
|
||||||
|
ret.w = distSq1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// closest to line
|
||||||
|
ret = p0 + line*t;
|
||||||
|
ret.w = (ret - center).MagnitudeSqr();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
inline int SignFlags(const CVector &v)
|
||||||
|
{
|
||||||
|
int f = 0;
|
||||||
|
if(v.x < 0.0f) f |= 1;
|
||||||
|
if(v.y < 0.0f) f |= 2;
|
||||||
|
if(v.z < 0.0f) f |= 4;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
LineToTriangleCollision(const CVuVector &p0, const CVuVector &p1,
|
||||||
|
const CVuVector &v0, const CVuVector &v1, const CVuVector &v2,
|
||||||
|
const CVuVector &plane)
|
||||||
|
{
|
||||||
|
#ifdef GTA_PS2
|
||||||
|
__asm__ volatile (
|
||||||
|
".set noreorder\n"
|
||||||
|
"lqc2 vf12, 0x0(%0)\n"
|
||||||
|
"lqc2 vf13, 0x0(%1)\n"
|
||||||
|
"lqc2 vf14, 0x0(%2)\n"
|
||||||
|
"lqc2 vf15, 0x0(%3)\n"
|
||||||
|
"lqc2 vf16, 0x0(%4)\n"
|
||||||
|
"lqc2 vf17, 0x0(%5)\n"
|
||||||
|
"vcallms Vu0LineToTriangleCollisionStart\n"
|
||||||
|
".set reorder\n"
|
||||||
|
:
|
||||||
|
: "r" (&p0), "r" (&p1), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane)
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
float dot0 = DotProduct(plane, p0);
|
||||||
|
float dot1 = DotProduct(plane, p1);
|
||||||
|
float dist0 = plane.w - dot0;
|
||||||
|
float dist1 = plane.w - dot1;
|
||||||
|
|
||||||
|
// if points are on the same side, no collision
|
||||||
|
if(dist0 * dist1 > 0.0f){
|
||||||
|
vi01 = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CVuVector diff = p1 - p0;
|
||||||
|
float t = dist0/(dot1 - dot0);
|
||||||
|
CVuVector p = p0 + diff*t;
|
||||||
|
p.w = 0.0f;
|
||||||
|
vf01 = p;
|
||||||
|
vf03.x = t;
|
||||||
|
|
||||||
|
// Check if point is inside
|
||||||
|
CVector cross1 = CrossProduct(p-v0, v1-v0);
|
||||||
|
CVector cross2 = CrossProduct(p-v1, v2-v1);
|
||||||
|
CVector cross3 = CrossProduct(p-v2, v0-v2);
|
||||||
|
// Only check relevant directions
|
||||||
|
int flagmask = 0;
|
||||||
|
if(Abs(plane.x) > 0.5f) flagmask |= 1;
|
||||||
|
if(Abs(plane.y) > 0.5f) flagmask |= 2;
|
||||||
|
if(Abs(plane.z) > 0.5f) flagmask |= 4;
|
||||||
|
int flags1 = SignFlags(cross1) & flagmask;
|
||||||
|
int flags2 = SignFlags(cross2) & flagmask;
|
||||||
|
int flags3 = SignFlags(cross3) & flagmask;
|
||||||
|
// inside if on the same side of all edges
|
||||||
|
if(flags1 != flags2 || flags1 != flags3){
|
||||||
|
vi01 = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vi01 = 1;
|
||||||
|
vf02 = plane;
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
LineToTriangleCollisionCompressed(const CVuVector &p0, const CVuVector &p1, VuTriangle &tri)
|
||||||
|
{
|
||||||
|
#ifdef GTA_PS2
|
||||||
|
__asm__ volatile (
|
||||||
|
".set noreorder\n"
|
||||||
|
"lqc2 vf12, 0x0(%0)\n"
|
||||||
|
"lqc2 vf13, 0x0(%1)\n"
|
||||||
|
"lqc2 vf14, 0x0(%2)\n"
|
||||||
|
"lqc2 vf15, 0x10(%2)\n"
|
||||||
|
"lqc2 vf16, 0x20(%2)\n"
|
||||||
|
"lqc2 vf17, 0x30(%2)\n"
|
||||||
|
"vcallms Vu0LineToTriangleCollisionCompressedStart\n"
|
||||||
|
".set reorder\n"
|
||||||
|
:
|
||||||
|
: "r" (&p0), "r" (&p1), "r" (&tri)
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
CVuVector v0, v1, v2, plane;
|
||||||
|
v0.x = tri.v0[0]/128.0f;
|
||||||
|
v0.y = tri.v0[1]/128.0f;
|
||||||
|
v0.z = tri.v0[2]/128.0f;
|
||||||
|
v0.w = tri.v0[3]/128.0f;
|
||||||
|
v1.x = tri.v1[0]/128.0f;
|
||||||
|
v1.y = tri.v1[1]/128.0f;
|
||||||
|
v1.z = tri.v1[2]/128.0f;
|
||||||
|
v1.w = tri.v1[3]/128.0f;
|
||||||
|
v2.x = tri.v2[0]/128.0f;
|
||||||
|
v2.y = tri.v2[1]/128.0f;
|
||||||
|
v2.z = tri.v2[2]/128.0f;
|
||||||
|
v2.w = tri.v2[3]/128.0f;
|
||||||
|
plane.x = tri.plane[0]/4096.0f;
|
||||||
|
plane.y = tri.plane[1]/4096.0f;
|
||||||
|
plane.z = tri.plane[2]/4096.0f;
|
||||||
|
plane.w = tri.plane[3]/128.0f;
|
||||||
|
LineToTriangleCollision(p0, p1, v0, v1, v2, plane);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
SphereToTriangleCollision(const CVuVector &sph,
|
||||||
|
const CVuVector &v0, const CVuVector &v1, const CVuVector &v2,
|
||||||
|
const CVuVector &plane)
|
||||||
|
{
|
||||||
|
#ifdef GTA_PS2
|
||||||
|
__asm__ volatile (
|
||||||
|
".set noreorder\n"
|
||||||
|
"lqc2 vf12, 0x0(%0)\n"
|
||||||
|
"lqc2 vf14, 0x0(%1)\n"
|
||||||
|
"lqc2 vf15, 0x0(%2)\n"
|
||||||
|
"lqc2 vf16, 0x0(%3)\n"
|
||||||
|
"lqc2 vf17, 0x0(%4)\n"
|
||||||
|
"vcallms Vu0SphereToTriangleCollisionStart\n"
|
||||||
|
".set reorder\n"
|
||||||
|
:
|
||||||
|
: "r" (&sph), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane)
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
float planedist = DotProduct(plane, sph) - plane.w; // VF02
|
||||||
|
if(Abs(planedist) > sph.w){
|
||||||
|
vi01 = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// point on plane
|
||||||
|
CVuVector p = sph - planedist*plane;
|
||||||
|
p.w = 0.0f;
|
||||||
|
vf01 = p;
|
||||||
|
planedist = Abs(planedist);
|
||||||
|
// edges
|
||||||
|
CVuVector v01 = v1 - v0;
|
||||||
|
CVuVector v12 = v2 - v1;
|
||||||
|
CVuVector v20 = v0 - v2;
|
||||||
|
// VU code calculates normal again for some weird reason...
|
||||||
|
// Check sides of point
|
||||||
|
CVector cross1 = CrossProduct(p-v0, v01);
|
||||||
|
CVector cross2 = CrossProduct(p-v1, v12);
|
||||||
|
CVector cross3 = CrossProduct(p-v2, v20);
|
||||||
|
// Only check relevant directions
|
||||||
|
int flagmask = 0;
|
||||||
|
if(Abs(plane.x) > 0.1f) flagmask |= 1;
|
||||||
|
if(Abs(plane.y) > 0.1f) flagmask |= 2;
|
||||||
|
if(Abs(plane.z) > 0.1f) flagmask |= 4;
|
||||||
|
int nflags = SignFlags(plane) & flagmask;
|
||||||
|
int flags1 = SignFlags(cross1) & flagmask;
|
||||||
|
int flags2 = SignFlags(cross2) & flagmask;
|
||||||
|
int flags3 = SignFlags(cross3) & flagmask;
|
||||||
|
int testcase = 0;
|
||||||
|
CVuVector closest(0.0f, 0.0f, 0.0f); // VF04
|
||||||
|
if(flags1 == nflags){
|
||||||
|
closest += v2;
|
||||||
|
testcase++;
|
||||||
|
}
|
||||||
|
if(flags2 == nflags){
|
||||||
|
closest += v0;
|
||||||
|
testcase++;
|
||||||
|
}
|
||||||
|
if(flags3 == nflags){
|
||||||
|
closest += v1;
|
||||||
|
testcase++;
|
||||||
|
}
|
||||||
|
if(testcase == 3){
|
||||||
|
// inside triangle - dist to plane already checked
|
||||||
|
vf02 = plane;
|
||||||
|
vf02.w = vf03.x = planedist;
|
||||||
|
vi01 = 1;
|
||||||
|
}else if(testcase == 1){
|
||||||
|
// outside two sides - closest to point opposide inside edge
|
||||||
|
vf01 = closest;
|
||||||
|
vf02 = sph - closest;
|
||||||
|
float distSq = vf02.MagnitudeSqr();
|
||||||
|
vi01 = sph.w*sph.w > distSq;
|
||||||
|
vf03.x = Sqrt(distSq);
|
||||||
|
vf02 *= 1.0f/vf03.x;
|
||||||
|
}else{
|
||||||
|
// inside two sides - closest to third edge
|
||||||
|
if(flags1 != nflags)
|
||||||
|
closest = DistanceBetweenSphereAndLine(sph, v0, v01);
|
||||||
|
else if(flags2 != nflags)
|
||||||
|
closest = DistanceBetweenSphereAndLine(sph, v1, v12);
|
||||||
|
else
|
||||||
|
closest = DistanceBetweenSphereAndLine(sph, v2, v20);
|
||||||
|
vi01 = sph.w*sph.w > closest.w;
|
||||||
|
vf01 = closest;
|
||||||
|
vf02 = sph - closest;
|
||||||
|
vf03.x = Sqrt(closest.w);
|
||||||
|
vf02 *= 1.0f/vf03.x;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
SphereToTriangleCollisionCompressed(const CVuVector &sph, VuTriangle &tri)
|
||||||
|
{
|
||||||
|
#ifdef GTA_PS2
|
||||||
|
__asm__ volatile (
|
||||||
|
".set noreorder\n"
|
||||||
|
"lqc2 vf12, 0x0(%0)\n"
|
||||||
|
"lqc2 vf14, 0x0(%1)\n"
|
||||||
|
"lqc2 vf15, 0x10(%1)\n"
|
||||||
|
"lqc2 vf16, 0x20(%1)\n"
|
||||||
|
"lqc2 vf17, 0x30(%1)\n"
|
||||||
|
"vcallms Vu0SphereToTriangleCollisionCompressedStart\n"
|
||||||
|
".set reorder\n"
|
||||||
|
:
|
||||||
|
: "r" (&sph), "r" (&tri)
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
CVuVector v0, v1, v2, plane;
|
||||||
|
v0.x = tri.v0[0]/128.0f;
|
||||||
|
v0.y = tri.v0[1]/128.0f;
|
||||||
|
v0.z = tri.v0[2]/128.0f;
|
||||||
|
v0.w = tri.v0[3]/128.0f;
|
||||||
|
v1.x = tri.v1[0]/128.0f;
|
||||||
|
v1.y = tri.v1[1]/128.0f;
|
||||||
|
v1.z = tri.v1[2]/128.0f;
|
||||||
|
v1.w = tri.v1[3]/128.0f;
|
||||||
|
v2.x = tri.v2[0]/128.0f;
|
||||||
|
v2.y = tri.v2[1]/128.0f;
|
||||||
|
v2.z = tri.v2[2]/128.0f;
|
||||||
|
v2.w = tri.v2[3]/128.0f;
|
||||||
|
plane.x = tri.plane[0]/4096.0f;
|
||||||
|
plane.y = tri.plane[1]/4096.0f;
|
||||||
|
plane.z = tri.plane[2]/4096.0f;
|
||||||
|
plane.w = tri.plane[3]/128.0f;
|
||||||
|
SphereToTriangleCollision(sph, v0, v1, v2, plane);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
32
src/collision/VuCollision.h
Normal file
32
src/collision/VuCollision.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
struct VuTriangle
|
||||||
|
{
|
||||||
|
// Compressed int16 but unpacked
|
||||||
|
#ifdef GTA_PS2
|
||||||
|
uint128 v0;
|
||||||
|
uint128 v1;
|
||||||
|
uint128 v2;
|
||||||
|
uint128 plane;
|
||||||
|
#else
|
||||||
|
int32 v0[4];
|
||||||
|
int32 v1[4];
|
||||||
|
int32 v2[4];
|
||||||
|
int32 plane[4];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef GTA_PS2
|
||||||
|
extern int16 vi01;
|
||||||
|
extern CVuVector vf01;
|
||||||
|
extern CVuVector vf02;
|
||||||
|
extern CVuVector vf03;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void LineToTriangleCollision(const CVuVector &p0, const CVuVector &p1, const CVuVector &v0, const CVuVector &v1, const CVuVector &v2, const CVuVector &plane);
|
||||||
|
void LineToTriangleCollisionCompressed(const CVuVector &p0, const CVuVector &p1, VuTriangle &tri);
|
||||||
|
void SphereToTriangleCollision(const CVuVector &sph, const CVuVector &v0, const CVuVector &v1, const CVuVector &v2, const CVuVector &plane);
|
||||||
|
void SphereToTriangleCollisionCompressed(const CVuVector &sph, VuTriangle &tri);
|
||||||
|
}
|
@ -242,8 +242,15 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
|
|||||||
else
|
else
|
||||||
return STREAM_SUCCESS;
|
return STREAM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BIG_IMG
|
||||||
|
LARGE_INTEGER liDistanceToMove;
|
||||||
|
liDistanceToMove.QuadPart = _GET_OFFSET(offset);
|
||||||
|
liDistanceToMove.QuadPart *= CDSTREAM_SECTOR_SIZE;
|
||||||
|
SetFilePointerEx(hImage, liDistanceToMove, nil, FILE_BEGIN);
|
||||||
|
#else
|
||||||
SetFilePointer(hImage, _GET_OFFSET(offset) * CDSTREAM_SECTOR_SIZE, nil, FILE_BEGIN);
|
SetFilePointer(hImage, _GET_OFFSET(offset) * CDSTREAM_SECTOR_SIZE, nil, FILE_BEGIN);
|
||||||
|
#endif
|
||||||
|
|
||||||
DWORD NumberOfBytesRead;
|
DWORD NumberOfBytesRead;
|
||||||
|
|
||||||
|
@ -429,7 +429,7 @@ void *CdStreamThread(void *param)
|
|||||||
ASSERT(pChannel->hFile >= 0);
|
ASSERT(pChannel->hFile >= 0);
|
||||||
ASSERT(pChannel->pBuffer != nil );
|
ASSERT(pChannel->pBuffer != nil );
|
||||||
|
|
||||||
lseek(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, SEEK_SET);
|
lseek(pChannel->hFile, (size_t)pChannel->nSectorOffset * (size_t)CDSTREAM_SECTOR_SIZE, SEEK_SET);
|
||||||
if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) {
|
if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) {
|
||||||
// pChannel->nSectorsToRead == 0 at this point means we wanted to flush channel
|
// pChannel->nSectorsToRead == 0 at this point means we wanted to flush channel
|
||||||
// STREAM_WAITING is a little hack to make CStreaming not process this data
|
// STREAM_WAITING is a little hack to make CStreaming not process this data
|
||||||
|
@ -1,254 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "templates.h"
|
|
||||||
#include "Game.h" // for eLevelName
|
|
||||||
#ifdef VU_COLLISION
|
|
||||||
#include "VuVector.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// If you spawn many tanks at once, you will see that collisions of two entity exceeds 32.
|
|
||||||
#if defined(FIX_BUGS) && !defined(SQUEEZE_PERFORMANCE)
|
|
||||||
#define MAX_COLLISION_POINTS 64
|
|
||||||
#else
|
|
||||||
#define MAX_COLLISION_POINTS 32
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct CompressedVector
|
|
||||||
{
|
|
||||||
#ifdef COMPRESSED_COL_VECTORS
|
|
||||||
int16 x, y, z;
|
|
||||||
CVector Get(void) const { return CVector(x, y, z)/128.0f; };
|
|
||||||
void Set(float x, float y, float z) { this->x = x*128.0f; this->y = y*128.0f; this->z = z*128.0f; };
|
|
||||||
#ifdef GTA_PS2
|
|
||||||
void Unpack(uint128 &qword) const {
|
|
||||||
__asm__ volatile (
|
|
||||||
"lh $8, 0(%1)\n"
|
|
||||||
"lh $9, 2(%1)\n"
|
|
||||||
"lh $10, 4(%1)\n"
|
|
||||||
"pextlw $10, $8\n"
|
|
||||||
"pextlw $2, $9, $10\n"
|
|
||||||
"sq $2, %0\n"
|
|
||||||
: "=m" (qword)
|
|
||||||
: "r" (this)
|
|
||||||
: "$8", "$9", "$10", "$2"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void Unpack(int32 *qword) const {
|
|
||||||
qword[0] = x;
|
|
||||||
qword[1] = y;
|
|
||||||
qword[2] = z;
|
|
||||||
qword[3] = 0; // junk
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
float x, y, z;
|
|
||||||
CVector Get(void) const { return CVector(x, y, z); };
|
|
||||||
void Set(float x, float y, float z) { this->x = x; this->y = y; this->z = z; };
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CColSphere
|
|
||||||
{
|
|
||||||
// NB: this has to be compatible with a CVuVector
|
|
||||||
CVector center;
|
|
||||||
float radius;
|
|
||||||
uint8 surface;
|
|
||||||
uint8 piece;
|
|
||||||
|
|
||||||
void Set(float radius, const CVector ¢er, uint8 surf, uint8 piece);
|
|
||||||
void Set(float radius, const CVector ¢er) { this->center = center; this->radius = radius; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CColBox
|
|
||||||
{
|
|
||||||
CVector min;
|
|
||||||
CVector max;
|
|
||||||
uint8 surface;
|
|
||||||
uint8 piece;
|
|
||||||
|
|
||||||
void Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece);
|
|
||||||
CVector GetSize(void) { return max - min; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CColLine
|
|
||||||
{
|
|
||||||
// NB: this has to be compatible with two CVuVectors
|
|
||||||
CVector p0;
|
|
||||||
int pad0;
|
|
||||||
CVector p1;
|
|
||||||
int pad1;
|
|
||||||
|
|
||||||
CColLine(void) { };
|
|
||||||
CColLine(const CVector &p0, const CVector &p1) { this->p0 = p0; this->p1 = p1; };
|
|
||||||
void Set(const CVector &p0, const CVector &p1);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CColTriangle
|
|
||||||
{
|
|
||||||
uint16 a;
|
|
||||||
uint16 b;
|
|
||||||
uint16 c;
|
|
||||||
uint8 surface;
|
|
||||||
|
|
||||||
void Set(const CompressedVector *v, int a, int b, int c, uint8 surf, uint8 piece);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CColTrianglePlane
|
|
||||||
{
|
|
||||||
#ifdef VU_COLLISION
|
|
||||||
CompressedVector normal;
|
|
||||||
int16 dist;
|
|
||||||
|
|
||||||
void Set(const CVector &va, const CVector &vb, const CVector &vc);
|
|
||||||
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
|
|
||||||
void GetNormal(CVector &n) const { n.x = normal.x/4096.0f; n.y = normal.y/4096.0f; n.z = normal.z/4096.0f; }
|
|
||||||
float CalcPoint(const CVector &v) const { CVector n; GetNormal(n); return DotProduct(n, v) - dist/128.0f; };
|
|
||||||
#ifdef GTA_PS2
|
|
||||||
void Unpack(uint128 &qword) const {
|
|
||||||
__asm__ volatile (
|
|
||||||
"lh $8, 0(%1)\n"
|
|
||||||
"lh $9, 2(%1)\n"
|
|
||||||
"lh $10, 4(%1)\n"
|
|
||||||
"lh $11, 6(%1)\n"
|
|
||||||
"pextlw $10, $8\n"
|
|
||||||
"pextlw $11, $9\n"
|
|
||||||
"pextlw $2, $11, $10\n"
|
|
||||||
"sq $2, %0\n"
|
|
||||||
: "=m" (qword)
|
|
||||||
: "r" (this)
|
|
||||||
: "$8", "$9", "$10", "$11", "$2"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void Unpack(int32 *qword) const {
|
|
||||||
qword[0] = normal.x;
|
|
||||||
qword[1] = normal.y;
|
|
||||||
qword[2] = normal.z;
|
|
||||||
qword[3] = dist;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
CVector normal;
|
|
||||||
float dist;
|
|
||||||
uint8 dir;
|
|
||||||
|
|
||||||
void Set(const CVector &va, const CVector &vb, const CVector &vc);
|
|
||||||
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
|
|
||||||
void GetNormal(CVector &n) const { n = normal; }
|
|
||||||
float CalcPoint(const CVector &v) const { return DotProduct(normal, v) - dist; };
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CColPoint
|
|
||||||
{
|
|
||||||
CVector point;
|
|
||||||
int pad1;
|
|
||||||
// the surface normal on the surface of point
|
|
||||||
CVector normal;
|
|
||||||
int pad2;
|
|
||||||
uint8 surfaceA;
|
|
||||||
uint8 pieceA;
|
|
||||||
uint8 surfaceB;
|
|
||||||
uint8 pieceB;
|
|
||||||
float depth;
|
|
||||||
|
|
||||||
void Set(float depth, uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) {
|
|
||||||
this->depth = depth;
|
|
||||||
this->surfaceA = surfA;
|
|
||||||
this->pieceA = pieceA;
|
|
||||||
this->surfaceB = surfB;
|
|
||||||
this->pieceB = pieceB;
|
|
||||||
}
|
|
||||||
void Set(uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) {
|
|
||||||
this->surfaceA = surfA;
|
|
||||||
this->pieceA = pieceA;
|
|
||||||
this->surfaceB = surfB;
|
|
||||||
this->pieceB = pieceB;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CStoredCollPoly
|
|
||||||
{
|
|
||||||
#ifdef VU_COLLISION
|
|
||||||
CVuVector verts[3];
|
|
||||||
#else
|
|
||||||
CVector verts[3];
|
|
||||||
#endif
|
|
||||||
bool valid;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CColModel
|
|
||||||
{
|
|
||||||
CColSphere boundingSphere;
|
|
||||||
CColBox boundingBox;
|
|
||||||
int16 numSpheres;
|
|
||||||
int16 numLines;
|
|
||||||
int16 numBoxes;
|
|
||||||
int16 numTriangles;
|
|
||||||
int32 level;
|
|
||||||
bool ownsCollisionVolumes; // missing on PS2
|
|
||||||
CColSphere *spheres;
|
|
||||||
CColLine *lines;
|
|
||||||
CColBox *boxes;
|
|
||||||
CompressedVector *vertices;
|
|
||||||
CColTriangle *triangles;
|
|
||||||
CColTrianglePlane *trianglePlanes;
|
|
||||||
|
|
||||||
CColModel(void);
|
|
||||||
~CColModel(void);
|
|
||||||
void RemoveCollisionVolumes(void);
|
|
||||||
void CalculateTrianglePlanes(void);
|
|
||||||
void RemoveTrianglePlanes(void);
|
|
||||||
CLink<CColModel*> *GetLinkPtr(void);
|
|
||||||
void SetLinkPtr(CLink<CColModel*>*);
|
|
||||||
void GetTrianglePoint(CVector &v, int i) const;
|
|
||||||
|
|
||||||
CColModel& operator=(const CColModel& other);
|
|
||||||
};
|
|
||||||
|
|
||||||
class CCollision
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static eLevelName ms_collisionInMemory;
|
|
||||||
static CLinkList<CColModel*> ms_colModelCache;
|
|
||||||
#ifdef NO_ISLAND_LOADING
|
|
||||||
static bool bAlreadyLoaded;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void Init(void);
|
|
||||||
static void Shutdown(void);
|
|
||||||
static void Update(void);
|
|
||||||
static void LoadCollisionWhenINeedIt(bool changeLevel);
|
|
||||||
static void SortOutCollisionAfterLoad(void);
|
|
||||||
static void LoadCollisionScreen(eLevelName level);
|
|
||||||
static void DrawColModel(const CMatrix &mat, const CColModel &colModel);
|
|
||||||
static void DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id);
|
|
||||||
|
|
||||||
static void CalculateTrianglePlanes(CColModel *model);
|
|
||||||
|
|
||||||
// all these return true if there's a collision
|
|
||||||
static bool TestSphereSphere(const CColSphere &s1, const CColSphere &s2);
|
|
||||||
static bool TestSphereBox(const CColSphere &sph, const CColBox &box);
|
|
||||||
static bool TestLineBox(const CColLine &line, const CColBox &box);
|
|
||||||
static bool TestVerticalLineBox(const CColLine &line, const CColBox &box);
|
|
||||||
static bool TestLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
|
|
||||||
static bool TestLineSphere(const CColLine &line, const CColSphere &sph);
|
|
||||||
static bool TestSphereTriangle(const CColSphere &sphere, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
|
|
||||||
static bool TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough);
|
|
||||||
|
|
||||||
static bool ProcessSphereSphere(const CColSphere &s1, const CColSphere &s2, CColPoint &point, float &mindistsq);
|
|
||||||
static bool ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoint &point, float &mindistsq);
|
|
||||||
static bool ProcessLineBox(const CColLine &line, const CColBox &box, CColPoint &point, float &mindist);
|
|
||||||
static bool ProcessVerticalLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly);
|
|
||||||
static bool ProcessLineTriangle(const CColLine &line , const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist);
|
|
||||||
static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist);
|
|
||||||
static bool ProcessSphereTriangle(const CColSphere &sph, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq);
|
|
||||||
static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough);
|
|
||||||
static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly);
|
|
||||||
static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists);
|
|
||||||
static bool IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CColPoint &point, CStoredCollPoly *poly);
|
|
||||||
|
|
||||||
static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point);
|
|
||||||
static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point, CVector &closest);
|
|
||||||
};
|
|
@ -2500,10 +2500,11 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
|
|||||||
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
|
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
const char *XboxButtons_noIcons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK");
|
||||||
|
|
||||||
#ifdef BUTTON_ICONS
|
#ifdef BUTTON_ICONS
|
||||||
const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK");
|
const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK");
|
||||||
#else
|
|
||||||
const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -2524,12 +2525,12 @@ const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B",
|
|||||||
#define PS2_SQUARE "SQUARE"
|
#define PS2_SQUARE "SQUARE"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const char *PlayStationButtons_noIcons[][MAX_CONTROLLERACTIONS] =
|
||||||
|
CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT");
|
||||||
|
|
||||||
#ifdef BUTTON_ICONS
|
#ifdef BUTTON_ICONS
|
||||||
const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
|
const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
|
||||||
CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT");
|
CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT");
|
||||||
#else
|
|
||||||
const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
|
|
||||||
CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef PS2_TRIANGLE
|
#undef PS2_TRIANGLE
|
||||||
@ -2547,7 +2548,11 @@ void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *
|
|||||||
wchar wstr[16];
|
wchar wstr[16];
|
||||||
|
|
||||||
// TODO: INI and/or menu setting for Xbox/PS switch
|
// TODO: INI and/or menu setting for Xbox/PS switch
|
||||||
const char *(*Buttons)[MAX_CONTROLLERACTIONS] = XboxButtons;
|
#ifdef BUTTON_ICONS
|
||||||
|
const char *(*Buttons)[MAX_CONTROLLERACTIONS] = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons;
|
||||||
|
#else
|
||||||
|
const char *(*Buttons)[MAX_CONTROLLERACTIONS] = XboxButtons_noIcons;
|
||||||
|
#endif
|
||||||
|
|
||||||
assert(Buttons[CPad::GetPad(0)->Mode][action] != nil); // we cannot use these
|
assert(Buttons[CPad::GetPad(0)->Mode][action] != nil); // we cannot use these
|
||||||
AsciiToUnicode(Buttons[CPad::GetPad(0)->Mode][action], wstr);
|
AsciiToUnicode(Buttons[CPad::GetPad(0)->Mode][action], wstr);
|
||||||
|
@ -332,6 +332,16 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
|
|||||||
return atomic;
|
return atomic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LIBRW
|
||||||
|
void
|
||||||
|
InitClump(RpClump *clump)
|
||||||
|
{
|
||||||
|
RpClumpForAllAtomics(clump, ConvertPlatformAtomic, nil);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define InitClump(clump)
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
CFileLoader::LoadModelFile(const char *filename)
|
CFileLoader::LoadModelFile(const char *filename)
|
||||||
{
|
{
|
||||||
@ -343,6 +353,7 @@ CFileLoader::LoadModelFile(const char *filename)
|
|||||||
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){
|
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){
|
||||||
clump = RpClumpStreamRead(stream);
|
clump = RpClumpStreamRead(stream);
|
||||||
if(clump){
|
if(clump){
|
||||||
|
InitClump(clump);
|
||||||
RpClumpForAllAtomics(clump, FindRelatedModelInfoCB, clump);
|
RpClumpForAllAtomics(clump, FindRelatedModelInfoCB, clump);
|
||||||
RpClumpDestroy(clump);
|
RpClumpDestroy(clump);
|
||||||
}
|
}
|
||||||
@ -368,6 +379,7 @@ CFileLoader::LoadClumpFile(const char *filename)
|
|||||||
GetNameAndLOD(nodename, name, &n);
|
GetNameAndLOD(nodename, name, &n);
|
||||||
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(name, nil);
|
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(name, nil);
|
||||||
if(mi){
|
if(mi){
|
||||||
|
InitClump(clump);
|
||||||
assert(mi->IsClump());
|
assert(mi->IsClump());
|
||||||
mi->SetClump(clump);
|
mi->SetClump(clump);
|
||||||
}else
|
}else
|
||||||
@ -393,6 +405,7 @@ CFileLoader::LoadClumpFile(RwStream *stream, uint32 id)
|
|||||||
if (mi->GetModelType() == MITYPE_PED && id != 0 && RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)) {
|
if (mi->GetModelType() == MITYPE_PED && id != 0 && RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)) {
|
||||||
// Read LOD ped
|
// Read LOD ped
|
||||||
clump = RpClumpStreamRead(stream);
|
clump = RpClumpStreamRead(stream);
|
||||||
|
InitClump(clump);
|
||||||
if(clump){
|
if(clump){
|
||||||
((CPedModelInfo*)mi)->SetLowDetailClump(clump);
|
((CPedModelInfo*)mi)->SetLowDetailClump(clump);
|
||||||
RpClumpDestroy(clump);
|
RpClumpDestroy(clump);
|
||||||
@ -423,6 +436,7 @@ CFileLoader::FinishLoadClumpFile(RwStream *stream, uint32 id)
|
|||||||
clump = RpClumpGtaStreamRead2(stream);
|
clump = RpClumpGtaStreamRead2(stream);
|
||||||
|
|
||||||
if(clump){
|
if(clump){
|
||||||
|
InitClump(clump);
|
||||||
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
|
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
|
||||||
mi->SetClump(clump);
|
mi->SetClump(clump);
|
||||||
return true;
|
return true;
|
||||||
@ -443,6 +457,7 @@ CFileLoader::LoadAtomicFile(RwStream *stream, uint32 id)
|
|||||||
clump = RpClumpStreamRead(stream);
|
clump = RpClumpStreamRead(stream);
|
||||||
if(clump == nil)
|
if(clump == nil)
|
||||||
return false;
|
return false;
|
||||||
|
InitClump(clump);
|
||||||
gpRelatedModelInfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
|
gpRelatedModelInfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
|
||||||
RpClumpForAllAtomics(clump, SetRelatedModelInfoCB, clump);
|
RpClumpForAllAtomics(clump, SetRelatedModelInfoCB, clump);
|
||||||
RpClumpDestroy(clump);
|
RpClumpDestroy(clump);
|
||||||
@ -806,6 +821,8 @@ CFileLoader::LoadAtomicFile2Return(const char *filename)
|
|||||||
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
|
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
|
||||||
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
|
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
|
||||||
clump = RpClumpStreamRead(stream);
|
clump = RpClumpStreamRead(stream);
|
||||||
|
if(clump)
|
||||||
|
InitClump(clump);
|
||||||
RwStreamClose(stream, nil);
|
RwStreamClose(stream, nil);
|
||||||
return clump;
|
return clump;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#define MENU_X_MARGIN 40.0f
|
#define MENU_X_MARGIN 40.0f
|
||||||
#define MENUACTION_POS_Y 60.0f
|
#define MENUACTION_POS_Y 60.0f
|
||||||
#define MENUACTION_WIDTH 38.0f
|
|
||||||
#define MENUACTION_SCALE_MULT 0.9f
|
#define MENUACTION_SCALE_MULT 0.9f
|
||||||
|
|
||||||
#define MENURADIO_ICON_SCALE 60.0f
|
#define MENURADIO_ICON_SCALE 60.0f
|
||||||
@ -235,11 +234,11 @@ enum eMenuScreen
|
|||||||
MENUPAGE_KEYBOARD_CONTROLS = 55,
|
MENUPAGE_KEYBOARD_CONTROLS = 55,
|
||||||
MENUPAGE_MOUSE_CONTROLS = 56,
|
MENUPAGE_MOUSE_CONTROLS = 56,
|
||||||
MENUPAGE_MISSION_RETRY = 57,
|
MENUPAGE_MISSION_RETRY = 57,
|
||||||
|
#ifdef MENU_MAP
|
||||||
|
MENUPAGE_MAP = 58,
|
||||||
|
#endif
|
||||||
#ifdef CUSTOM_FRONTEND_OPTIONS
|
#ifdef CUSTOM_FRONTEND_OPTIONS
|
||||||
|
|
||||||
#ifdef MENU_MAP
|
|
||||||
MENUPAGE_MAP,
|
|
||||||
#endif
|
|
||||||
#ifdef GRAPHICS_MENU_OPTIONS
|
#ifdef GRAPHICS_MENU_OPTIONS
|
||||||
MENUPAGE_GRAPHICS_SETTINGS,
|
MENUPAGE_GRAPHICS_SETTINGS,
|
||||||
#else
|
#else
|
||||||
@ -380,9 +379,6 @@ enum eMenuAction
|
|||||||
// MENUACTION_MIPMAPS,
|
// MENUACTION_MIPMAPS,
|
||||||
// MENUACTION_TEXTURE_FILTERING,
|
// MENUACTION_TEXTURE_FILTERING,
|
||||||
//#endif
|
//#endif
|
||||||
//#ifdef NO_ISLAND_LOADING
|
|
||||||
// MENUACTION_ISLANDLOADING,
|
|
||||||
//#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eCheckHover
|
enum eCheckHover
|
||||||
@ -718,7 +714,6 @@ public:
|
|||||||
ISLAND_LOADING_HIGH
|
ISLAND_LOADING_HIGH
|
||||||
};
|
};
|
||||||
|
|
||||||
static int8 m_DisplayIslandLoading;
|
|
||||||
static int8 m_PrefsIslandLoading;
|
static int8 m_PrefsIslandLoading;
|
||||||
|
|
||||||
#define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
|
#define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
|
||||||
@ -786,6 +781,7 @@ public:
|
|||||||
void PageUpList(bool);
|
void PageUpList(bool);
|
||||||
void PageDownList(bool);
|
void PageDownList(bool);
|
||||||
int8 GetPreviousPageOption();
|
int8 GetPreviousPageOption();
|
||||||
|
void ProcessList(bool &goBack, bool &optionSelected);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef IMPROVED_VIDEOMODE
|
#ifndef IMPROVED_VIDEOMODE
|
||||||
|
@ -203,20 +203,6 @@ static const char* FrontendFilenames[][2] =
|
|||||||
{"fe_radio9", "" },
|
{"fe_radio9", "" },
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CUTSCENE_BORDERS_SWITCH
|
|
||||||
bool CMenuManager::m_PrefsCutsceneBorders = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MULTISAMPLING
|
|
||||||
int8 CMenuManager::m_nPrefsMSAALevel = 0;
|
|
||||||
int8 CMenuManager::m_nDisplayMSAALevel = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NO_ISLAND_LOADING
|
|
||||||
int8 CMenuManager::m_DisplayIslandLoading = ISLAND_LOADING_LOW;
|
|
||||||
int8 CMenuManager::m_PrefsIslandLoading = ISLAND_LOADING_LOW;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int32 CMenuManager::m_PrefsSfxVolume = 102;
|
int32 CMenuManager::m_PrefsSfxVolume = 102;
|
||||||
int32 CMenuManager::m_PrefsMusicVolume = 102;
|
int32 CMenuManager::m_PrefsMusicVolume = 102;
|
||||||
int32 CMenuManager::m_PrefsBrightness = 256;
|
int32 CMenuManager::m_PrefsBrightness = 256;
|
||||||
|
@ -160,31 +160,9 @@ public:
|
|||||||
static int32 m_PrefsLanguage;
|
static int32 m_PrefsLanguage;
|
||||||
static CONTRCONFIG m_PrefsControllerConfig;
|
static CONTRCONFIG m_PrefsControllerConfig;
|
||||||
static bool m_PrefsUseVibration;
|
static bool m_PrefsUseVibration;
|
||||||
#ifdef NO_ISLAND_LOADING
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
ISLAND_LOADING_LOW = 0,
|
|
||||||
ISLAND_LOADING_MEDIUM,
|
|
||||||
ISLAND_LOADING_HIGH
|
|
||||||
};
|
|
||||||
|
|
||||||
static int8 m_DisplayIslandLoading;
|
|
||||||
static int8 m_PrefsIslandLoading;
|
|
||||||
|
|
||||||
#define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
|
|
||||||
#define ISLAND_LOADING_ISNT(p) if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p)
|
|
||||||
#else
|
|
||||||
#define ISLAND_LOADING_IS(p)
|
#define ISLAND_LOADING_IS(p)
|
||||||
#define ISLAND_LOADING_ISNT(p)
|
#define ISLAND_LOADING_ISNT(p)
|
||||||
#endif
|
|
||||||
#ifdef CUTSCENE_BORDERS_SWITCH
|
|
||||||
static bool m_PrefsCutsceneBorders;
|
|
||||||
#endif
|
|
||||||
#ifdef MULTISAMPLING
|
|
||||||
static int8 m_nPrefsMSAALevel;
|
|
||||||
static int8 m_nDisplayMSAALevel;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GTA_PC
|
#ifdef GTA_PC
|
||||||
bool m_bQuitGameNoCD;
|
bool m_bQuitGameNoCD;
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ void MessageScreen(char *msg)
|
|||||||
|
|
||||||
CFont::SetFontStyle(FONT_BANK);
|
CFont::SetFontStyle(FONT_BANK);
|
||||||
CFont::SetBackgroundOff();
|
CFont::SetBackgroundOff();
|
||||||
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(190.0f)); // 450.0f // unused
|
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(190.0f)); // 450.0f
|
||||||
CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f));
|
CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f));
|
||||||
CFont::SetCentreOn();
|
CFont::SetCentreOn();
|
||||||
CFont::SetCentreSize(SCREEN_SCALE_X(450.0f)); // 450.0f
|
CFont::SetCentreSize(SCREEN_SCALE_X(450.0f)); // 450.0f
|
||||||
@ -734,10 +734,10 @@ void CGame::InitialiseWhenRestarting(void)
|
|||||||
|
|
||||||
//CFont::SetFontStyle(?);
|
//CFont::SetFontStyle(?);
|
||||||
CFont::SetBackgroundOff();
|
CFont::SetBackgroundOff();
|
||||||
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(160.0f)); // 480.0f // unused
|
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(160.0f)); // 480.0f
|
||||||
CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f));
|
CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f));
|
||||||
CFont::SetCentreOn();
|
CFont::SetCentreOn();
|
||||||
CFont::SetCentreSize(SCREEN_SCALE_X(480.0f)); // 480.0f
|
CFont::SetCentreSize(SCREEN_SCALE_X(480.0f));
|
||||||
CFont::SetJustifyOff();
|
CFont::SetJustifyOff();
|
||||||
CFont::SetColor(CRGBA(255, 255, 255, 255));
|
CFont::SetColor(CRGBA(255, 255, 255, 255));
|
||||||
CFont::SetBackGroundOnlyTextOff();
|
CFont::SetBackGroundOnlyTextOff();
|
||||||
|
@ -392,6 +392,9 @@ CMenuScreen aScreens[MENUPAGES] = {
|
|||||||
{ "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
{ "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||||
MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE,
|
MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||||
MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
|
MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
|
||||||
|
#ifdef MENU_MAP
|
||||||
|
MENUACTION_CHANGEMENU, "FEG_MAP", SAVESLOT_NONE, MENUPAGE_MAP,
|
||||||
|
#endif
|
||||||
MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS,
|
MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS,
|
||||||
MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS,
|
MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS,
|
||||||
MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS,
|
MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS,
|
||||||
@ -436,6 +439,14 @@ CMenuScreen aScreens[MENUPAGES] = {
|
|||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MENU_MAP
|
||||||
|
// MENUPAGE_MAP
|
||||||
|
{ "FEG_MAP", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 2,
|
||||||
|
MENUACTION_UNK110, "", SAVESLOT_NONE, MENUPAGE_NONE, // to prevent cross/enter to go back
|
||||||
|
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
|
||||||
// MENUPAGE_UNK
|
// MENUPAGE_UNK
|
||||||
{ "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0,
|
{ "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0,
|
||||||
|
|
||||||
|
@ -11,6 +11,10 @@
|
|||||||
#include "custompipes.h"
|
#include "custompipes.h"
|
||||||
#include "RwHelper.h"
|
#include "RwHelper.h"
|
||||||
#include "Text.h"
|
#include "Text.h"
|
||||||
|
#include "Streaming.h"
|
||||||
|
#include "FileLoader.h"
|
||||||
|
#include "Collision.h"
|
||||||
|
#include "ModelInfo.h"
|
||||||
|
|
||||||
// Menu screens array is at the bottom of the file.
|
// Menu screens array is at the bottom of the file.
|
||||||
|
|
||||||
@ -48,6 +52,12 @@
|
|||||||
#define DUALPASS_SELECTOR
|
#define DUALPASS_SELECTOR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NO_ISLAND_LOADING
|
||||||
|
#define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&CMenuManager::m_PrefsIslandLoading, "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) },
|
||||||
|
#else
|
||||||
|
#define ISLAND_LOADING_SELECTOR
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef EXTENDED_COLOURFILTER
|
#ifdef EXTENDED_COLOURFILTER
|
||||||
#define POSTFX_SELECTORS \
|
#define POSTFX_SELECTORS \
|
||||||
MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false, nil) }, \
|
MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false, nil) }, \
|
||||||
@ -80,6 +90,18 @@ void RestoreDefGraphics(int8 action) {
|
|||||||
#ifdef MULTISAMPLING
|
#ifdef MULTISAMPLING
|
||||||
FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel = 0;
|
FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel = 0;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef NO_ISLAND_LOADING
|
||||||
|
if (!FrontEndMenuManager.m_bGameNotLoaded) {
|
||||||
|
FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW;
|
||||||
|
CCollision::bAlreadyLoaded = false;
|
||||||
|
CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
|
||||||
|
CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
|
||||||
|
CStreaming::RemoveUnusedBuildings(CGame::currLevel);
|
||||||
|
CStreaming::RequestIslands(CGame::currLevel);
|
||||||
|
CStreaming::LoadAllRequestedModels(true);
|
||||||
|
} else
|
||||||
|
FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW;
|
||||||
|
#endif
|
||||||
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
|
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
|
||||||
CMenuManager::m_PrefsFrameLimiter = true;
|
CMenuManager::m_PrefsFrameLimiter = true;
|
||||||
CMenuManager::m_PrefsVsyncDisp = true;
|
CMenuManager::m_PrefsVsyncDisp = true;
|
||||||
@ -120,6 +142,47 @@ void RestoreDefDisplay(int8 action) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NO_ISLAND_LOADING
|
||||||
|
const char *islandLoadingOpts[] = { "FEM_LOW", "FEM_MED", "FEM_HIG" };
|
||||||
|
void IslandLoadingAfterChange(int8 before, int8 after) {
|
||||||
|
if (!FrontEndMenuManager.m_bGameNotLoaded) {
|
||||||
|
if (after > FrontEndMenuManager.ISLAND_LOADING_LOW) {
|
||||||
|
FrontEndMenuManager.m_PrefsIslandLoading = before; // calls below needs previous mode :shrug:
|
||||||
|
|
||||||
|
if (after == FrontEndMenuManager.ISLAND_LOADING_HIGH)
|
||||||
|
CStreaming::RemoveIslandsNotUsed(LEVEL_GENERIC);
|
||||||
|
if (before == FrontEndMenuManager.ISLAND_LOADING_LOW) {
|
||||||
|
if (CGame::currLevel != LEVEL_INDUSTRIAL)
|
||||||
|
CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL);
|
||||||
|
if (CGame::currLevel != LEVEL_COMMERCIAL)
|
||||||
|
CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL);
|
||||||
|
if (CGame::currLevel != LEVEL_SUBURBAN)
|
||||||
|
CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN);
|
||||||
|
CCollision::bAlreadyLoaded = true;
|
||||||
|
FrontEndMenuManager.m_PrefsIslandLoading = after;
|
||||||
|
CStreaming::RequestBigBuildings(CGame::currLevel);
|
||||||
|
|
||||||
|
} else if (before == FrontEndMenuManager.ISLAND_LOADING_HIGH) {
|
||||||
|
FrontEndMenuManager.m_PrefsIslandLoading = after;
|
||||||
|
CStreaming::RequestIslands(CGame::currLevel);
|
||||||
|
} else
|
||||||
|
FrontEndMenuManager.m_PrefsIslandLoading = after;
|
||||||
|
|
||||||
|
} else { // low
|
||||||
|
CCollision::bAlreadyLoaded = false;
|
||||||
|
CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
|
||||||
|
CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
|
||||||
|
CStreaming::RemoveUnusedBuildings(CGame::currLevel);
|
||||||
|
CStreaming::RequestIslands(CGame::currLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
CStreaming::LoadAllRequestedModels(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
FrontEndMenuManager.SetHelperText(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MORE_LANGUAGES
|
#ifdef MORE_LANGUAGES
|
||||||
void LangPolSelect(int8 action)
|
void LangPolSelect(int8 action)
|
||||||
{
|
{
|
||||||
@ -761,6 +824,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
|
|||||||
#ifdef EXTENDED_PIPELINES
|
#ifdef EXTENDED_PIPELINES
|
||||||
PIPELINES_SELECTOR
|
PIPELINES_SELECTOR
|
||||||
#endif
|
#endif
|
||||||
|
ISLAND_LOADING_SELECTOR
|
||||||
DUALPASS_SELECTOR
|
DUALPASS_SELECTOR
|
||||||
MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) },
|
MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) },
|
||||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||||
@ -770,6 +834,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
|
|||||||
{ "FET_ADV", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS,
|
{ "FET_ADV", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS,
|
||||||
new CCustomScreenLayout({MENUSPRITE_MAINMENU, 50, 0, 20, FONT_HEADING, FESCREEN_LEFT_ALIGN, true, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), nil,
|
new CCustomScreenLayout({MENUSPRITE_MAINMENU, 50, 0, 20, FONT_HEADING, FESCREEN_LEFT_ALIGN, true, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), nil,
|
||||||
|
|
||||||
|
ISLAND_LOADING_SELECTOR
|
||||||
DUALPASS_SELECTOR
|
DUALPASS_SELECTOR
|
||||||
CUTSCENE_BORDERS_TOGGLE
|
CUTSCENE_BORDERS_TOGGLE
|
||||||
FREE_CAM_TOGGLE
|
FREE_CAM_TOGGLE
|
||||||
|
@ -2610,7 +2610,7 @@ void CPad::PrintErrorMessage(void)
|
|||||||
CFont::SetScale(0.85f, 1.0f);
|
CFont::SetScale(0.85f, 1.0f);
|
||||||
CFont::SetJustifyOff();
|
CFont::SetJustifyOff();
|
||||||
CFont::SetBackgroundOff();
|
CFont::SetBackgroundOff();
|
||||||
CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20));
|
CFont::SetCentreSize(SCREEN_SCALE_X(SCREEN_WIDTH - 20));
|
||||||
CFont::SetCentreOn();
|
CFont::SetCentreOn();
|
||||||
CFont::SetPropOn();
|
CFont::SetPropOn();
|
||||||
CFont::SetColor(CRGBA(255, 255, 200, 200));
|
CFont::SetColor(CRGBA(255, 255, 200, 200));
|
||||||
@ -2627,7 +2627,7 @@ void CPad::PrintErrorMessage(void)
|
|||||||
CFont::SetScale(0.85f, 1.0f);
|
CFont::SetScale(0.85f, 1.0f);
|
||||||
CFont::SetJustifyOff();
|
CFont::SetJustifyOff();
|
||||||
CFont::SetBackgroundOff();
|
CFont::SetBackgroundOff();
|
||||||
CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20));
|
CFont::SetCentreSize(SCREEN_SCALE_X(SCREEN_WIDTH - 20));
|
||||||
CFont::SetCentreOn();
|
CFont::SetCentreOn();
|
||||||
CFont::SetPropOn();
|
CFont::SetPropOn();
|
||||||
CFont::SetColor(CRGBA(255, 255, 200, 200));
|
CFont::SetColor(CRGBA(255, 255, 200, 200));
|
||||||
|
@ -390,6 +390,7 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
|
|||||||
assert(sizeof(direntry) == 32);
|
assert(sizeof(direntry) == 32);
|
||||||
while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){
|
while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){
|
||||||
dot = strchr(direntry.name, '.');
|
dot = strchr(direntry.name, '.');
|
||||||
|
assert(dot);
|
||||||
if(dot) *dot = '\0';
|
if(dot) *dot = '\0';
|
||||||
if(direntry.size > (uint32)ms_streamingBufferSize)
|
if(direntry.size > (uint32)ms_streamingBufferSize)
|
||||||
ms_streamingBufferSize = direntry.size;
|
ms_streamingBufferSize = direntry.size;
|
||||||
@ -741,7 +742,9 @@ CStreaming::RequestBigBuildings(eLevelName level)
|
|||||||
b = CPools::GetBuildingPool()->GetSlot(i);
|
b = CPools::GetBuildingPool()->GetSlot(i);
|
||||||
if(b && b->bIsBIGBuilding
|
if(b && b->bIsBIGBuilding
|
||||||
#ifdef NO_ISLAND_LOADING
|
#ifdef NO_ISLAND_LOADING
|
||||||
&& ((CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) || (b->m_level == level))
|
&& (((CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODindustEntity) && (b != pIslandLODcomIndEntity) &&
|
||||||
|
(b != pIslandLODcomSubEntity) && (b != pIslandLODsubIndEntity) && (b != pIslandLODsubComEntity)
|
||||||
|
) || (b->m_level == level))
|
||||||
#else
|
#else
|
||||||
&& b->m_level == level
|
&& b->m_level == level
|
||||||
#endif
|
#endif
|
||||||
|
@ -212,10 +212,10 @@ enum Config {
|
|||||||
# define TIMEBARS // print debug timers
|
# define TIMEBARS // print debug timers
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
|
#define FIX_BUGS // fixes bugs that we've came across during reversing
|
||||||
#define MORE_LANGUAGES // Add more translations to the game
|
#define MORE_LANGUAGES // Add more translations to the game
|
||||||
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible
|
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible
|
||||||
#define LOAD_INI_SETTINGS
|
#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS
|
||||||
|
|
||||||
// Rendering/display
|
// Rendering/display
|
||||||
//#define EXTRA_MODEL_FLAGS // from mobile to optimize rendering
|
//#define EXTRA_MODEL_FLAGS // from mobile to optimize rendering
|
||||||
@ -227,19 +227,11 @@ enum Config {
|
|||||||
#define PS2_ALPHA_TEST // emulate ps2 alpha test
|
#define PS2_ALPHA_TEST // emulate ps2 alpha test
|
||||||
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
|
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
|
||||||
#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time
|
#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time
|
||||||
#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
|
|
||||||
//#define USE_TEXTURE_POOL
|
//#define USE_TEXTURE_POOL
|
||||||
#define CUTSCENE_BORDERS_SWITCH
|
|
||||||
#ifdef LIBRW
|
#ifdef LIBRW
|
||||||
//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
|
//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
|
||||||
//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
|
//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
|
||||||
#endif
|
#endif
|
||||||
#define MULTISAMPLING // adds MSAA option
|
|
||||||
|
|
||||||
#ifdef LIBRW
|
|
||||||
// these are not supported with librw yet
|
|
||||||
# undef MULTISAMPLING
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Particle
|
// Particle
|
||||||
//#define PC_PARTICLE
|
//#define PC_PARTICLE
|
||||||
@ -278,7 +270,13 @@ enum Config {
|
|||||||
//# define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc.
|
//# define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc.
|
||||||
//# define PS2_SAVE_DIALOG // PS2 style save dialog with transparent black box
|
//# define PS2_SAVE_DIALOG // PS2 style save dialog with transparent black box
|
||||||
# define CUSTOM_FRONTEND_OPTIONS
|
# define CUSTOM_FRONTEND_OPTIONS
|
||||||
# define GRAPHICS_MENU_OPTIONS // otherwise Advanced Options menu will appear if Display is full
|
|
||||||
|
# ifdef CUSTOM_FRONTEND_OPTIONS
|
||||||
|
# define GRAPHICS_MENU_OPTIONS // otherwise Advanced Options menu will appear if Display is full
|
||||||
|
# define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
|
||||||
|
# define CUTSCENE_BORDERS_SWITCH
|
||||||
|
# define MULTISAMPLING // adds MSAA option
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Script
|
// Script
|
||||||
@ -327,6 +325,8 @@ enum Config {
|
|||||||
#endif
|
#endif
|
||||||
//#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS
|
//#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS
|
||||||
|
|
||||||
|
// IMG
|
||||||
|
#define BIG_IMG // allows to read larger img files
|
||||||
|
|
||||||
//#define SQUEEZE_PERFORMANCE
|
//#define SQUEEZE_PERFORMANCE
|
||||||
#ifdef SQUEEZE_PERFORMANCE
|
#ifdef SQUEEZE_PERFORMANCE
|
||||||
@ -335,3 +335,8 @@ enum Config {
|
|||||||
#define PC_PARTICLE
|
#define PC_PARTICLE
|
||||||
#define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial
|
#define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIBRW
|
||||||
|
// these are not supported with librw yet
|
||||||
|
# undef MULTISAMPLING
|
||||||
|
#endif
|
||||||
|
@ -89,7 +89,11 @@ RwRGBA gColourTop;
|
|||||||
bool gameAlreadyInitialised;
|
bool gameAlreadyInitialised;
|
||||||
|
|
||||||
float NumberOfChunksLoaded;
|
float NumberOfChunksLoaded;
|
||||||
|
#ifdef GTA_PS2
|
||||||
|
#define TOTALNUMCHUNKS 48.0f
|
||||||
|
#else
|
||||||
#define TOTALNUMCHUNKS 73.0f
|
#define TOTALNUMCHUNKS 73.0f
|
||||||
|
#endif
|
||||||
|
|
||||||
bool g_SlowMode = false;
|
bool g_SlowMode = false;
|
||||||
char version_name[64];
|
char version_name[64];
|
||||||
@ -625,20 +629,20 @@ LoadingIslandScreen(const char *levelName)
|
|||||||
CFont::SetScale(1.5f, 1.5f);
|
CFont::SetScale(1.5f, 1.5f);
|
||||||
CFont::SetPropOn();
|
CFont::SetPropOn();
|
||||||
CFont::SetRightJustifyOn();
|
CFont::SetRightJustifyOn();
|
||||||
CFont::SetRightJustifyWrap(150.0f);
|
CFont::SetRightJustifyWrap(SCREEN_SCALE_X(150.0f));
|
||||||
CFont::SetFontStyle(FONT_HEADING);
|
CFont::SetFontStyle(FONT_HEADING);
|
||||||
sprintf(str, "WELCOME TO");
|
sprintf(str, "WELCOME TO");
|
||||||
AsciiToUnicode(str, wstr);
|
AsciiToUnicode(str, wstr);
|
||||||
CFont::SetDropColor(CRGBA(0, 0, 0, 255));
|
CFont::SetDropColor(CRGBA(0, 0, 0, 255));
|
||||||
CFont::SetDropShadowPosition(3);
|
CFont::SetDropShadowPosition(3);
|
||||||
CFont::SetColor(CRGBA(243, 237, 71, 255));
|
CFont::SetColor(CRGBA(243, 237, 71, 255));
|
||||||
CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f));
|
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
|
||||||
CFont::PrintString(SCREEN_WIDTH - 20, SCREEN_STRETCH_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
|
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_STRETCH_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
|
||||||
TextCopy(wstr, name);
|
TextCopy(wstr, name);
|
||||||
TheText.UpperCase(wstr);
|
TheText.UpperCase(wstr);
|
||||||
CFont::SetColor(CRGBA(243, 237, 71, 255));
|
CFont::SetColor(CRGBA(243, 237, 71, 255));
|
||||||
CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f));
|
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
|
||||||
CFont::PrintString(SCREEN_WIDTH-20, SCREEN_STRETCH_FROM_BOTTOM(80.0f), wstr);
|
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_STRETCH_FROM_BOTTOM(80.0f), wstr);
|
||||||
CFont::DrawFonts();
|
CFont::DrawFonts();
|
||||||
DoRWStuffEndOfFrame();
|
DoRWStuffEndOfFrame();
|
||||||
}
|
}
|
||||||
@ -852,7 +856,7 @@ DisplayGameDebugText()
|
|||||||
CFont::SetRightJustifyOff();
|
CFont::SetRightJustifyOff();
|
||||||
CFont::SetJustifyOff();
|
CFont::SetJustifyOff();
|
||||||
CFont::SetBackGroundOnlyTextOff();
|
CFont::SetBackGroundOnlyTextOff();
|
||||||
CFont::SetWrapx(SCREEN_WIDTH);
|
CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
|
||||||
CFont::SetFontStyle(FONT_HEADING);
|
CFont::SetFontStyle(FONT_HEADING);
|
||||||
|
|
||||||
CFont::SetColor(CRGBA(0, 0, 0, 255));
|
CFont::SetColor(CRGBA(0, 0, 0, 255));
|
||||||
|
@ -86,7 +86,8 @@ CustomFrontendOptionsPopulate(void)
|
|||||||
linb::ini cfg;
|
linb::ini cfg;
|
||||||
int CheckAndReadIniInt(const char *cat, const char *key, int original)
|
int CheckAndReadIniInt(const char *cat, const char *key, int original)
|
||||||
{
|
{
|
||||||
const char *value = (cfg.get(cat, key, "").c_str());
|
std::string strval = cfg.get(cat, key, "");
|
||||||
|
const char *value = strval.c_str();
|
||||||
if (value && value[0] != '\0')
|
if (value && value[0] != '\0')
|
||||||
return atoi(value);
|
return atoi(value);
|
||||||
|
|
||||||
@ -95,13 +96,34 @@ int CheckAndReadIniInt(const char *cat, const char *key, int original)
|
|||||||
|
|
||||||
float CheckAndReadIniFloat(const char *cat, const char *key, float original)
|
float CheckAndReadIniFloat(const char *cat, const char *key, float original)
|
||||||
{
|
{
|
||||||
const char *value = (cfg.get(cat, key, "").c_str());
|
std::string strval = cfg.get(cat, key, "");
|
||||||
|
const char *value = strval.c_str();
|
||||||
if (value && value[0] != '\0')
|
if (value && value[0] != '\0')
|
||||||
return atof(value);
|
return atof(value);
|
||||||
|
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckAndSaveIniInt(const char *cat, const char *key, int val, bool &changed)
|
||||||
|
{
|
||||||
|
char temp[10];
|
||||||
|
if (atoi(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it
|
||||||
|
changed = true;
|
||||||
|
sprintf(temp, "%u", val);
|
||||||
|
cfg.set(cat, key, temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckAndSaveIniFloat(const char *cat, const char *key, float val, bool &changed)
|
||||||
|
{
|
||||||
|
char temp[10];
|
||||||
|
if (atof(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it
|
||||||
|
changed = true;
|
||||||
|
sprintf(temp, "%f", val);
|
||||||
|
cfg.set(cat, key, temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LoadINISettings()
|
void LoadINISettings()
|
||||||
{
|
{
|
||||||
cfg.load_file("re3.ini");
|
cfg.load_file("re3.ini");
|
||||||
@ -156,11 +178,6 @@ void LoadINISettings()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NO_ISLAND_LOADING
|
|
||||||
CMenuManager::m_PrefsIslandLoading = CheckAndReadIniInt("FrontendOptions", "NoIslandLoading", CMenuManager::m_PrefsIslandLoading);
|
|
||||||
CMenuManager::m_DisplayIslandLoading = CMenuManager::m_PrefsIslandLoading;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EXTENDED_COLOURFILTER
|
#ifdef EXTENDED_COLOURFILTER
|
||||||
CPostFX::Intensity = CheckAndReadIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity);
|
CPostFX::Intensity = CheckAndReadIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity);
|
||||||
#endif
|
#endif
|
||||||
@ -192,21 +209,22 @@ void SaveINISettings()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
|
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
|
||||||
if (atoi(cfg.get("FrontendOptions", option.m_CFO->save, "xxx").c_str()) != *option.m_CFO->value) { // if .ini doesn't have that key compare with xxx, so we can add it
|
// Beware: CFO only supports saving uint8 right now
|
||||||
changed = true;
|
CheckAndSaveIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value, changed);
|
||||||
sprintf(temp, "%u", *option.m_CFO->value);
|
|
||||||
cfg.set("FrontendOptions", option.m_CFO->save, temp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef NO_ISLAND_LOADING
|
|
||||||
if (atoi(cfg.get("FrontendOptions", "NoIslandLoading", "xxx").c_str()) != CMenuManager::m_PrefsIslandLoading) {
|
#ifdef EXTENDED_COLOURFILTER
|
||||||
changed = true;
|
CheckAndSaveIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity, changed);
|
||||||
sprintf(temp, "%u", CMenuManager::m_PrefsIslandLoading);
|
#endif
|
||||||
cfg.set("FrontendOptions", "NoIslandLoading", temp);
|
#ifdef EXTENDED_PIPELINES
|
||||||
}
|
CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess, changed);
|
||||||
|
CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity, changed);
|
||||||
|
CheckAndSaveIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult, changed);
|
||||||
|
CheckAndSaveIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult, changed);
|
||||||
|
CheckAndSaveIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult, changed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (changed)
|
if (changed)
|
||||||
|
@ -572,7 +572,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
|
|||||||
if(IsGlass(B->GetModelIndex()))
|
if(IsGlass(B->GetModelIndex()))
|
||||||
CGlass::WindowRespondsToSoftCollision(B, impulseA);
|
CGlass::WindowRespondsToSoftCollision(B, impulseA);
|
||||||
if(!A->bInfiniteMass)
|
if(!A->bInfiniteMass)
|
||||||
A->ApplyMoveForce(colpoint.normal*(1.0f + A->m_fElasticity)*impulseA);
|
A->ApplyMoveForce(colpoint.GetNormal() * (1.0f + A->m_fElasticity) * impulseA);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}else if(!B->bInfiniteMass)
|
}else if(!B->bInfiniteMass)
|
||||||
@ -624,7 +624,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
|
|||||||
}else{
|
}else{
|
||||||
if(IsGlass(B->GetModelIndex()))
|
if(IsGlass(B->GetModelIndex()))
|
||||||
CGlass::WindowRespondsToSoftCollision(B, impulseA);
|
CGlass::WindowRespondsToSoftCollision(B, impulseA);
|
||||||
CVector f = colpoint.normal * impulseA;
|
CVector f = colpoint.GetNormal() * impulseA;
|
||||||
if(A->IsVehicle() && colpoint.normal.z < 0.7f)
|
if(A->IsVehicle() && colpoint.normal.z < 0.7f)
|
||||||
f.z *= 0.3f;
|
f.z *= 0.3f;
|
||||||
if(!A->bInfiniteMass){
|
if(!A->bInfiniteMass){
|
||||||
@ -1146,43 +1146,43 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
|
|||||||
|
|
||||||
mostColliding = 0;
|
mostColliding = 0;
|
||||||
for(j = 1; j < numCollisions; j++)
|
for(j = 1; j < numCollisions; j++)
|
||||||
if(colpoints[j].depth > colpoints[mostColliding].depth)
|
if (colpoints[j].GetDepth() > colpoints[mostColliding].GetDepth())
|
||||||
mostColliding = j;
|
mostColliding = j;
|
||||||
|
|
||||||
if(CWorld::bSecondShift)
|
if(CWorld::bSecondShift)
|
||||||
for(j = 0; j < numCollisions; j++)
|
for(j = 0; j < numCollisions; j++)
|
||||||
shift += colpoints[j].normal * colpoints[j].depth * 1.5f/numCollisions;
|
shift += colpoints[j].GetNormal() * colpoints[j].GetDepth() * 1.5f / numCollisions;
|
||||||
else
|
else
|
||||||
for(j = 0; j < numCollisions; j++)
|
for(j = 0; j < numCollisions; j++)
|
||||||
shift += colpoints[j].normal * colpoints[j].depth * 1.2f/numCollisions;
|
shift += colpoints[j].GetNormal() * colpoints[j].GetDepth() * 1.2f / numCollisions;
|
||||||
|
|
||||||
if(A->IsVehicle() && B->IsVehicle()){
|
if(A->IsVehicle() && B->IsVehicle()){
|
||||||
CVector dir = A->GetPosition() - B->GetPosition();
|
CVector dir = A->GetPosition() - B->GetPosition();
|
||||||
dir.Normalise();
|
dir.Normalise();
|
||||||
if(dir.z < 0.0f && dir.z < A->GetForward().z && dir.z < A->GetRight().z)
|
if(dir.z < 0.0f && dir.z < A->GetForward().z && dir.z < A->GetRight().z)
|
||||||
dir.z = Min(0.0f, Min(A->GetForward().z, A->GetRight().z));
|
dir.z = Min(0.0f, Min(A->GetForward().z, A->GetRight().z));
|
||||||
shift += dir * colpoints[mostColliding].depth * 0.5f;
|
shift += dir * colpoints[mostColliding].GetDepth() * 0.5f;
|
||||||
}else if(A->IsPed() && B->IsVehicle() && ((CVehicle*)B)->IsBoat()){
|
}else if(A->IsPed() && B->IsVehicle() && ((CVehicle*)B)->IsBoat()){
|
||||||
CVector dir = colpoints[mostColliding].normal;
|
CVector dir = colpoints[mostColliding].GetNormal();
|
||||||
float f = Min(Abs(dir.z), 0.9f);
|
float f = Min(Abs(dir.z), 0.9f);
|
||||||
dir.z = 0.0f;
|
dir.z = 0.0f;
|
||||||
dir.Normalise();
|
dir.Normalise();
|
||||||
shift += dir * colpoints[mostColliding].depth / (1.0f - f);
|
shift += dir * colpoints[mostColliding].GetDepth() / (1.0f - f);
|
||||||
boat = B;
|
boat = B;
|
||||||
}else if(B->IsPed() && A->IsVehicle() && ((CVehicle*)A)->IsBoat()){
|
}else if(B->IsPed() && A->IsVehicle() && ((CVehicle*)A)->IsBoat()){
|
||||||
CVector dir = colpoints[mostColliding].normal * -1.0f;
|
CVector dir = colpoints[mostColliding].GetNormal() * -1.0f;
|
||||||
float f = Min(Abs(dir.z), 0.9f);
|
float f = Min(Abs(dir.z), 0.9f);
|
||||||
dir.z = 0.0f;
|
dir.z = 0.0f;
|
||||||
dir.Normalise();
|
dir.Normalise();
|
||||||
B->GetMatrix().Translate(dir * colpoints[mostColliding].depth / (1.0f - f));
|
B->GetMatrix().Translate(dir * colpoints[mostColliding].GetDepth() / (1.0f - f));
|
||||||
// BUG? how can that ever happen? A is a Ped
|
// BUG? how can that ever happen? A is a Ped
|
||||||
if(B->IsVehicle())
|
if(B->IsVehicle())
|
||||||
B->ProcessEntityCollision(A, colpoints);
|
B->ProcessEntityCollision(A, colpoints);
|
||||||
}else{
|
}else{
|
||||||
if(CWorld::bSecondShift)
|
if(CWorld::bSecondShift)
|
||||||
shift += colpoints[mostColliding].normal * colpoints[mostColliding].depth * 0.4f;
|
shift += colpoints[mostColliding].GetNormal() * colpoints[mostColliding].GetDepth() * 0.4f;
|
||||||
else
|
else
|
||||||
shift += colpoints[mostColliding].normal * colpoints[mostColliding].depth * 0.2f;
|
shift += colpoints[mostColliding].GetNormal() * colpoints[mostColliding].GetDepth() * 0.2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
doShift = true;
|
doShift = true;
|
||||||
|
@ -294,32 +294,12 @@ RwTextureAddressMode RwTextureGetAddressingV(const RwTexture *texture);
|
|||||||
// TODO
|
// TODO
|
||||||
void _rwD3D8TexDictionaryEnableRasterFormatConversion(bool enable) { }
|
void _rwD3D8TexDictionaryEnableRasterFormatConversion(bool enable) { }
|
||||||
|
|
||||||
static rw::Raster*
|
|
||||||
ConvertTexRaster(rw::Raster *ras)
|
|
||||||
{
|
|
||||||
using namespace rw;
|
|
||||||
|
|
||||||
if(ras->platform == rw::platform)
|
|
||||||
return ras;
|
|
||||||
// compatible platforms
|
|
||||||
if(ras->platform == PLATFORM_D3D8 && rw::platform == PLATFORM_D3D9 ||
|
|
||||||
ras->platform == PLATFORM_D3D9 && rw::platform == PLATFORM_D3D8)
|
|
||||||
return ras;
|
|
||||||
|
|
||||||
Image *img = ras->toImage();
|
|
||||||
ras->destroy();
|
|
||||||
img->unpalettize();
|
|
||||||
ras = Raster::createFromImage(img);
|
|
||||||
img->destroy();
|
|
||||||
return ras;
|
|
||||||
}
|
|
||||||
|
|
||||||
// hack for reading native textures
|
// hack for reading native textures
|
||||||
RwBool rwNativeTextureHackRead(RwStream *stream, RwTexture **tex, RwInt32 size)
|
RwBool rwNativeTextureHackRead(RwStream *stream, RwTexture **tex, RwInt32 size)
|
||||||
{
|
{
|
||||||
*tex = Texture::streamReadNative(stream);
|
*tex = Texture::streamReadNative(stream);
|
||||||
#ifdef LIBRW
|
#ifdef LIBRW
|
||||||
(*tex)->raster = ConvertTexRaster((*tex)->raster);
|
(*tex)->raster = rw::Raster::convertTexToCurrentPlatform((*tex)->raster);
|
||||||
#endif
|
#endif
|
||||||
return *tex != nil;
|
return *tex != nil;
|
||||||
}
|
}
|
||||||
@ -796,6 +776,9 @@ RwBool RpWorldPluginAttach(void) {
|
|||||||
registerNativeDataPlugin();
|
registerNativeDataPlugin();
|
||||||
registerAtomicRightsPlugin();
|
registerAtomicRightsPlugin();
|
||||||
registerMaterialRightsPlugin();
|
registerMaterialRightsPlugin();
|
||||||
|
|
||||||
|
// not sure if this goes here
|
||||||
|
rw::xbox::registerVertexFormatPlugin();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
#include "CutsceneHead.h"
|
#include "CutsceneHead.h"
|
||||||
#include "CdStream.h"
|
#include "CdStream.h"
|
||||||
|
|
||||||
|
#ifdef GTA_PS2_STUFF
|
||||||
|
// this is a total hack to switch between PC and PS2 code
|
||||||
|
static bool lastLoadedSKA;
|
||||||
|
#endif
|
||||||
|
|
||||||
CCutsceneHead::CCutsceneHead(CObject *obj)
|
CCutsceneHead::CCutsceneHead(CObject *obj)
|
||||||
{
|
{
|
||||||
@ -87,6 +91,10 @@ CCutsceneHead::ProcessControl(void)
|
|||||||
assert(RwObjectGetType(m_rwObject) == rpCLUMP);
|
assert(RwObjectGetType(m_rwObject) == rpCLUMP);
|
||||||
atm = GetFirstAtomic((RpClump*)m_rwObject);
|
atm = GetFirstAtomic((RpClump*)m_rwObject);
|
||||||
hier = RpSkinAtomicGetHAnimHierarchy(atm);
|
hier = RpSkinAtomicGetHAnimHierarchy(atm);
|
||||||
|
#ifdef GTA_PS2_STUFF
|
||||||
|
// PS2 only plays anims in cutscene, PC always plays anims
|
||||||
|
if(!lastLoadedSKA || CCutsceneMgr::IsRunning())
|
||||||
|
#endif
|
||||||
RpHAnimHierarchyAddAnimTime(hier, CTimer::GetTimeStepNonClipped()/50.0f);
|
RpHAnimHierarchyAddAnimTime(hier, CTimer::GetTimeStepNonClipped()/50.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,6 +176,10 @@ CCutsceneHead::PlayAnimation(const char *animName)
|
|||||||
uint32 offset, size;
|
uint32 offset, size;
|
||||||
RwStream *stream;
|
RwStream *stream;
|
||||||
|
|
||||||
|
#ifdef GTA_PS2_STUFF
|
||||||
|
lastLoadedSKA = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
assert(RwObjectGetType(m_rwObject) == rpCLUMP);
|
assert(RwObjectGetType(m_rwObject) == rpCLUMP);
|
||||||
atm = GetFirstAtomic((RpClump*)m_rwObject);
|
atm = GetFirstAtomic((RpClump*)m_rwObject);
|
||||||
hier = RpSkinAtomicGetHAnimHierarchy(atm);
|
hier = RpSkinAtomicGetHAnimHierarchy(atm);
|
||||||
@ -191,4 +203,29 @@ CCutsceneHead::PlayAnimation(const char *animName)
|
|||||||
|
|
||||||
RwStreamClose(stream, nil);
|
RwStreamClose(stream, nil);
|
||||||
}
|
}
|
||||||
|
#ifdef GTA_PS2_STUFF
|
||||||
|
#ifdef LIBRW
|
||||||
|
else{
|
||||||
|
sprintf(gString, "%s.ska", animName);
|
||||||
|
|
||||||
|
if(CCutsceneMgr::ms_pCutsceneDir->FindItem(gString, offset, size)){
|
||||||
|
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG");
|
||||||
|
assert(stream);
|
||||||
|
|
||||||
|
CStreaming::MakeSpaceFor(size * CDSTREAM_SECTOR_SIZE);
|
||||||
|
CStreaming::ImGonnaUseStreamingMemory();
|
||||||
|
|
||||||
|
RwStreamSkip(stream, offset*2048);
|
||||||
|
anim = rw::Animation::streamReadLegacy(stream);
|
||||||
|
RpHAnimHierarchySetCurrentAnim(hier, anim);
|
||||||
|
|
||||||
|
CStreaming::IHaveUsedStreamingMemory();
|
||||||
|
|
||||||
|
RwStreamClose(stream, nil);
|
||||||
|
|
||||||
|
lastLoadedSKA = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
#include "Sprite2d.h"
|
#include "Sprite2d.h"
|
||||||
#include "TxdStore.h"
|
#include "TxdStore.h"
|
||||||
#include "Font.h"
|
#include "Font.h"
|
||||||
|
#ifdef BUTTON_ICONS
|
||||||
|
#include "FileMgr.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
AsciiToUnicode(const char *src, wchar *dst)
|
AsciiToUnicode(const char *src, wchar *dst)
|
||||||
@ -227,6 +230,7 @@ wchar foreign_table[128] = {
|
|||||||
#ifdef BUTTON_ICONS
|
#ifdef BUTTON_ICONS
|
||||||
CSprite2d CFont::ButtonSprite[MAX_BUTTON_ICONS];
|
CSprite2d CFont::ButtonSprite[MAX_BUTTON_ICONS];
|
||||||
int CFont::PS2Symbol = BUTTON_NONE;
|
int CFont::PS2Symbol = BUTTON_NONE;
|
||||||
|
int CFont::ButtonsSlot = -1;
|
||||||
#endif // BUTTON_ICONS
|
#endif // BUTTON_ICONS
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -275,8 +279,8 @@ CFont::Initialise(void)
|
|||||||
SetColor(CRGBA(0xFF, 0xFF, 0xFF, 0));
|
SetColor(CRGBA(0xFF, 0xFF, 0xFF, 0));
|
||||||
SetJustifyOff();
|
SetJustifyOff();
|
||||||
SetCentreOff();
|
SetCentreOff();
|
||||||
SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
|
SetWrapx(SCREEN_WIDTH);
|
||||||
SetCentreSize(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
|
SetCentreSize(SCREEN_WIDTH);
|
||||||
SetBackgroundOff();
|
SetBackgroundOff();
|
||||||
SetBackgroundColor(CRGBA(0x80, 0x80, 0x80, 0x80));
|
SetBackgroundColor(CRGBA(0x80, 0x80, 0x80, 0x80));
|
||||||
SetBackGroundOnlyTextOff();
|
SetBackGroundOnlyTextOff();
|
||||||
@ -288,28 +292,31 @@ CFont::Initialise(void)
|
|||||||
CTxdStore::PopCurrentTxd();
|
CTxdStore::PopCurrentTxd();
|
||||||
|
|
||||||
#ifdef BUTTON_ICONS
|
#ifdef BUTTON_ICONS
|
||||||
slot = CTxdStore::AddTxdSlot("buttons");
|
if (int file = CFileMgr::OpenFile("MODELS/X360BTNS.TXD")) {
|
||||||
CTxdStore::LoadTxd(slot, "MODELS/X360BTNS.TXD");
|
CFileMgr::CloseFile(file);
|
||||||
CTxdStore::AddRef(slot);
|
ButtonsSlot = CTxdStore::AddTxdSlot("buttons");
|
||||||
CTxdStore::PushCurrentTxd();
|
CTxdStore::LoadTxd(ButtonsSlot, "MODELS/X360BTNS.TXD");
|
||||||
CTxdStore::SetCurrentTxd(slot);
|
CTxdStore::AddRef(ButtonsSlot);
|
||||||
|
CTxdStore::PushCurrentTxd();
|
||||||
|
CTxdStore::SetCurrentTxd(ButtonsSlot);
|
||||||
#if 0 // unused
|
#if 0 // unused
|
||||||
ButtonSprite[BUTTON_UP].SetTexture("up");
|
ButtonSprite[BUTTON_UP].SetTexture("up");
|
||||||
ButtonSprite[BUTTON_DOWN].SetTexture("down");
|
ButtonSprite[BUTTON_DOWN].SetTexture("down");
|
||||||
ButtonSprite[BUTTON_LEFT].SetTexture("left");
|
ButtonSprite[BUTTON_LEFT].SetTexture("left");
|
||||||
ButtonSprite[BUTTON_RIGHT].SetTexture("right");
|
ButtonSprite[BUTTON_RIGHT].SetTexture("right");
|
||||||
#endif
|
#endif
|
||||||
ButtonSprite[BUTTON_CROSS].SetTexture("cross");
|
ButtonSprite[BUTTON_CROSS].SetTexture("cross");
|
||||||
ButtonSprite[BUTTON_CIRCLE].SetTexture("circle");
|
ButtonSprite[BUTTON_CIRCLE].SetTexture("circle");
|
||||||
ButtonSprite[BUTTON_SQUARE].SetTexture("square");
|
ButtonSprite[BUTTON_SQUARE].SetTexture("square");
|
||||||
ButtonSprite[BUTTON_TRIANGLE].SetTexture("triangle");
|
ButtonSprite[BUTTON_TRIANGLE].SetTexture("triangle");
|
||||||
ButtonSprite[BUTTON_L1].SetTexture("l1");
|
ButtonSprite[BUTTON_L1].SetTexture("l1");
|
||||||
ButtonSprite[BUTTON_L2].SetTexture("l2");
|
ButtonSprite[BUTTON_L2].SetTexture("l2");
|
||||||
ButtonSprite[BUTTON_L3].SetTexture("l3");
|
ButtonSprite[BUTTON_L3].SetTexture("l3");
|
||||||
ButtonSprite[BUTTON_R1].SetTexture("r1");
|
ButtonSprite[BUTTON_R1].SetTexture("r1");
|
||||||
ButtonSprite[BUTTON_R2].SetTexture("r2");
|
ButtonSprite[BUTTON_R2].SetTexture("r2");
|
||||||
ButtonSprite[BUTTON_R3].SetTexture("r3");
|
ButtonSprite[BUTTON_R3].SetTexture("r3");
|
||||||
CTxdStore::PopCurrentTxd();
|
CTxdStore::PopCurrentTxd();
|
||||||
|
}
|
||||||
#endif // BUTTON_ICONS
|
#endif // BUTTON_ICONS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,9 +367,11 @@ void
|
|||||||
CFont::Shutdown(void)
|
CFont::Shutdown(void)
|
||||||
{
|
{
|
||||||
#ifdef BUTTON_ICONS
|
#ifdef BUTTON_ICONS
|
||||||
for (int i = 0; i < MAX_BUTTON_ICONS; i++)
|
if (ButtonsSlot != -1) {
|
||||||
ButtonSprite[i].Delete();
|
for (int i = 0; i < MAX_BUTTON_ICONS; i++)
|
||||||
CTxdStore::RemoveTxdSlot(CTxdStore::FindTxdSlot("buttons"));
|
ButtonSprite[i].Delete();
|
||||||
|
CTxdStore::RemoveTxdSlot(ButtonsSlot);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
Sprite[0].Delete();
|
Sprite[0].Delete();
|
||||||
Sprite[1].Delete();
|
Sprite[1].Delete();
|
||||||
@ -692,7 +701,14 @@ CFont::GetNumberLines(float xstart, float ystart, wchar *s)
|
|||||||
y = ystart;
|
y = ystart;
|
||||||
|
|
||||||
while(*s){
|
while(*s){
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
float f = Details.centre ? Details.centreSize :
|
||||||
|
Details.rightJustify ? xstart - Details.rightJustifyWrap :
|
||||||
|
Details.wrapX;
|
||||||
|
#else
|
||||||
float f = (Details.centre ? Details.centreSize : Details.wrapX);
|
float f = (Details.centre ? Details.centreSize : Details.wrapX);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MORE_LANGUAGES
|
#ifdef MORE_LANGUAGES
|
||||||
if (IsJapaneseFont())
|
if (IsJapaneseFont())
|
||||||
f -= SCREEN_SCALE_X(21.0f * 2.0f);
|
f -= SCREEN_SCALE_X(21.0f * 2.0f);
|
||||||
@ -772,8 +788,15 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s)
|
|||||||
x = xstart;
|
x = xstart;
|
||||||
y = ystart;
|
y = ystart;
|
||||||
|
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
float xEnd = Details.centre ? Details.centreSize :
|
||||||
|
Details.rightJustify ? xstart - Details.rightJustifyWrap :
|
||||||
|
Details.wrapX;
|
||||||
|
#else
|
||||||
|
float xEnd = (Details.centre ? Details.centreSize : Details.wrapX);
|
||||||
|
#endif
|
||||||
while(*s){
|
while(*s){
|
||||||
if(x + GetStringWidth(s) > (Details.centre ? Details.centreSize : Details.wrapX)){
|
if(x + GetStringWidth(s) > xEnd){
|
||||||
// reached end of line
|
// reached end of line
|
||||||
if(x > maxlength)
|
if(x > maxlength)
|
||||||
maxlength = x;
|
maxlength = x;
|
||||||
|
@ -103,6 +103,7 @@ public:
|
|||||||
static CFontDetails Details;
|
static CFontDetails Details;
|
||||||
|
|
||||||
#ifdef BUTTON_ICONS
|
#ifdef BUTTON_ICONS
|
||||||
|
static int32 ButtonsSlot;
|
||||||
static CSprite2d ButtonSprite[MAX_BUTTON_ICONS];
|
static CSprite2d ButtonSprite[MAX_BUTTON_ICONS];
|
||||||
static int PS2Symbol;
|
static int PS2Symbol;
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ void CHud::Draw()
|
|||||||
CFont::SetScale(SCREEN_SCALE_X(0.4f), SCREEN_SCALE_Y(0.6f));
|
CFont::SetScale(SCREEN_SCALE_X(0.4f), SCREEN_SCALE_Y(0.6f));
|
||||||
CFont::SetJustifyOff();
|
CFont::SetJustifyOff();
|
||||||
CFont::SetCentreOn();
|
CFont::SetCentreOn();
|
||||||
CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH));
|
CFont::SetCentreSize(SCREEN_WIDTH);
|
||||||
CFont::SetPropOn();
|
CFont::SetPropOn();
|
||||||
CFont::SetFontStyle(FONT_BANK);
|
CFont::SetFontStyle(FONT_BANK);
|
||||||
|
|
||||||
@ -740,7 +740,7 @@ void CHud::Draw()
|
|||||||
CFont::SetRightJustifyWrap(0.0f);
|
CFont::SetRightJustifyWrap(0.0f);
|
||||||
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
|
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
|
||||||
CFont::SetColor(CRGBA(244, 20, 20, 255));
|
CFont::SetColor(CRGBA(244, 20, 20, 255));
|
||||||
CFont::SetWrapx(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH));
|
CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
|
||||||
CFont::SetPropOff();
|
CFont::SetPropOff();
|
||||||
CFont::SetBackGroundOnlyTextOn();
|
CFont::SetBackGroundOnlyTextOn();
|
||||||
|
|
||||||
@ -869,7 +869,7 @@ void CHud::Draw()
|
|||||||
else
|
else
|
||||||
CFont::SetCentreOff();
|
CFont::SetCentreOff();
|
||||||
|
|
||||||
CFont::SetWrapx(SCREEN_SCALE_X(CTheScripts::IntroTextLines[i].m_fWrapX));
|
CFont::SetWrapx(SCALE_AND_CENTER_X(CTheScripts::IntroTextLines[i].m_fWrapX));
|
||||||
CFont::SetCentreSize(SCREEN_SCALE_X(CTheScripts::IntroTextLines[i].m_fCenterSize));
|
CFont::SetCentreSize(SCREEN_SCALE_X(CTheScripts::IntroTextLines[i].m_fCenterSize));
|
||||||
|
|
||||||
if (CTheScripts::IntroTextLines[i].m_bBackground)
|
if (CTheScripts::IntroTextLines[i].m_bBackground)
|
||||||
@ -931,9 +931,9 @@ void CHud::Draw()
|
|||||||
CFont::SetPropOn();
|
CFont::SetPropOn();
|
||||||
CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
|
CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
|
||||||
|
|
||||||
float offsetX = SCREEN_SCALE_X(40.0f) + SCREEN_SCALE_X(8.0f);
|
float radarBulge = SCREEN_SCALE_X(40.0f) + SCREEN_SCALE_X(8.0f);
|
||||||
float center = SCREEN_SCALE_FROM_RIGHT(50.0f) - SCREEN_SCALE_X(8.0f) - offsetX;
|
float rectWidth = SCREEN_WIDTH - SCREEN_SCALE_X(50.0f) - SCREEN_SCALE_X(8.0f) - radarBulge;
|
||||||
CFont::SetCentreSize(center);
|
CFont::SetCentreSize(rectWidth);
|
||||||
|
|
||||||
const int16 shadow = 1;
|
const int16 shadow = 1;
|
||||||
CFont::SetDropShadowPosition(shadow);
|
CFont::SetDropShadowPosition(shadow);
|
||||||
@ -941,7 +941,7 @@ void CHud::Draw()
|
|||||||
CFont::SetColor(CRGBA(235, 235, 235, 255));
|
CFont::SetColor(CRGBA(235, 235, 235, 255));
|
||||||
|
|
||||||
// I'm not sure shadow substaction was intentional here, might be a leftover if CFont::PrintString was used for a shadow draw call
|
// I'm not sure shadow substaction was intentional here, might be a leftover if CFont::PrintString was used for a shadow draw call
|
||||||
CFont::PrintString(center / 2.0f + offsetX - SCREEN_SCALE_X(shadow), SCREEN_SCALE_Y(4.0f) + SCREEN_SCALE_FROM_BOTTOM(68.0f) - SCREEN_SCALE_Y(shadow), m_Message);
|
CFont::PrintString(rectWidth / 2.0f + radarBulge - SCREEN_SCALE_X(shadow), SCREEN_SCALE_Y(4.0f) + SCREEN_SCALE_FROM_BOTTOM(68.0f) - SCREEN_SCALE_Y(shadow), m_Message);
|
||||||
CFont::SetDropShadowPosition(0);
|
CFont::SetDropShadowPosition(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,7 +957,7 @@ void CHud::Draw()
|
|||||||
CFont::SetScale(SCREEN_SCALE_X(1.8f), SCREEN_SCALE_Y(1.8f));
|
CFont::SetScale(SCREEN_SCALE_X(1.8f), SCREEN_SCALE_Y(1.8f));
|
||||||
CFont::SetPropOn();
|
CFont::SetPropOn();
|
||||||
CFont::SetCentreOn();
|
CFont::SetCentreOn();
|
||||||
CFont::SetCentreSize(SCREEN_SCALE_X(590.0f));
|
CFont::SetCentreSize(SCREEN_SCALE_X(615.0f));
|
||||||
CFont::SetFontStyle(FONT_HEADING);
|
CFont::SetFontStyle(FONT_HEADING);
|
||||||
|
|
||||||
// Appearently sliding text in here was abandoned very early, since this text is centered now.
|
// Appearently sliding text in here was abandoned very early, since this text is centered now.
|
||||||
@ -1166,7 +1166,7 @@ void CHud::DrawAfterFade()
|
|||||||
else
|
else
|
||||||
CFont::SetCentreOff();
|
CFont::SetCentreOff();
|
||||||
|
|
||||||
CFont::SetWrapx(SCREEN_SCALE_X(line.m_fWrapX));
|
CFont::SetWrapx(SCALE_AND_CENTER_X(line.m_fWrapX));
|
||||||
CFont::SetCentreSize(SCREEN_SCALE_X(line.m_fCenterSize));
|
CFont::SetCentreSize(SCREEN_SCALE_X(line.m_fCenterSize));
|
||||||
if (line.m_bBackground)
|
if (line.m_bBackground)
|
||||||
CFont::SetBackgroundOn();
|
CFont::SetBackgroundOn();
|
||||||
@ -1318,7 +1318,7 @@ void CHud::DrawAfterFade()
|
|||||||
CFont::SetScale(SCREEN_SCALE_X(1.04f), SCREEN_SCALE_Y(1.6f));
|
CFont::SetScale(SCREEN_SCALE_X(1.04f), SCREEN_SCALE_Y(1.6f));
|
||||||
|
|
||||||
CFont::SetPropOn();
|
CFont::SetPropOn();
|
||||||
CFont::SetRightJustifyWrap(SCREEN_SCALE_X(-500.0f));
|
CFont::SetRightJustifyWrap(SCREEN_SCALE_FROM_RIGHT(DEFAULT_SCREEN_WIDTH + 500.0f));
|
||||||
CFont::SetRightJustifyOn();
|
CFont::SetRightJustifyOn();
|
||||||
CFont::SetFontStyle(FONT_HEADING);
|
CFont::SetFontStyle(FONT_HEADING);
|
||||||
if (BigMessageX[1] >= SCREEN_SCALE_FROM_RIGHT(20.0f)) {
|
if (BigMessageX[1] >= SCREEN_SCALE_FROM_RIGHT(20.0f)) {
|
||||||
|
@ -1058,7 +1058,7 @@ CMoneyMessage::Render()
|
|||||||
|
|
||||||
CFont::SetScale(fScaleX, fScaleY); // maybe use SCREEN_SCALE_X and SCREEN_SCALE_Y here?
|
CFont::SetScale(fScaleX, fScaleY); // maybe use SCREEN_SCALE_X and SCREEN_SCALE_Y here?
|
||||||
CFont::SetCentreOn();
|
CFont::SetCentreOn();
|
||||||
CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH));
|
CFont::SetCentreSize(SCREEN_WIDTH);
|
||||||
CFont::SetJustifyOff();
|
CFont::SetJustifyOff();
|
||||||
CFont::SetColor(CRGBA(m_Colour.r, m_Colour.g, m_Colour.b, (255.0f - 255.0f * fLifeTime) * m_fOpacity));
|
CFont::SetColor(CRGBA(m_Colour.r, m_Colour.g, m_Colour.b, (255.0f - 255.0f * fLifeTime) * m_fOpacity));
|
||||||
CFont::SetBackGroundOnlyTextOff();
|
CFont::SetBackGroundOnlyTextOff();
|
||||||
|
@ -649,6 +649,83 @@ WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x598B10); }
|
|||||||
WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x598B30); }
|
WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x598B30); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIBRW
|
||||||
|
#include <rpmatfx.h>
|
||||||
|
#include "VehicleModelInfo.h"
|
||||||
|
|
||||||
|
int32
|
||||||
|
findPlatform(rw::Atomic *a)
|
||||||
|
{
|
||||||
|
rw::Geometry *g = a->geometry;
|
||||||
|
if(g->instData)
|
||||||
|
return g->instData->platform;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// in CVehicleModelInfo in VC
|
||||||
|
static RpMaterial*
|
||||||
|
GetMatFXEffectMaterialCB(RpMaterial *material, void *data)
|
||||||
|
{
|
||||||
|
if(RpMatFXMaterialGetEffects(material) == rpMATFXEFFECTNULL)
|
||||||
|
return material;
|
||||||
|
*(int*)data = RpMatFXMaterialGetEffects(material);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Game doesn't read atomic extensions so we never get any other than the default pipe,
|
||||||
|
// but we need it for uninstancing
|
||||||
|
void
|
||||||
|
attachPipe(rw::Atomic *atomic)
|
||||||
|
{
|
||||||
|
if(RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic)))
|
||||||
|
atomic->pipeline = rw::skinGlobals.pipelines[rw::platform];
|
||||||
|
else{
|
||||||
|
int fx = rpMATFXEFFECTNULL;
|
||||||
|
RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), GetMatFXEffectMaterialCB, &fx);
|
||||||
|
if(fx != rpMATFXEFFECTNULL)
|
||||||
|
RpMatFXAtomicEnableEffects(atomic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach pipes for the platform we have native data for so we can uninstance
|
||||||
|
void
|
||||||
|
switchPipes(rw::Atomic *a, int32 platform)
|
||||||
|
{
|
||||||
|
if(a->pipeline && a->pipeline->platform != platform){
|
||||||
|
uint32 plgid = a->pipeline->pluginID;
|
||||||
|
switch(plgid){
|
||||||
|
// assume default pipe won't be attached explicitly
|
||||||
|
case rw::ID_SKIN:
|
||||||
|
a->pipeline = rw::skinGlobals.pipelines[platform];
|
||||||
|
break;
|
||||||
|
case rw::ID_MATFX:
|
||||||
|
a->pipeline = rw::matFXGlobals.pipelines[platform];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RpAtomic*
|
||||||
|
ConvertPlatformAtomic(RpAtomic *atomic, void *data)
|
||||||
|
{
|
||||||
|
int32 driver = rw::platform;
|
||||||
|
int32 platform = findPlatform(atomic);
|
||||||
|
if(platform != 0 && platform != driver){
|
||||||
|
attachPipe(atomic); // kludge
|
||||||
|
rw::ObjPipeline *origPipe = atomic->pipeline;
|
||||||
|
rw::platform = platform;
|
||||||
|
switchPipes(atomic, rw::platform);
|
||||||
|
if(atomic->geometry->flags & rw::Geometry::NATIVE)
|
||||||
|
atomic->uninstance();
|
||||||
|
// no ADC in this game
|
||||||
|
//rw::ps2::unconvertADC(atomic->geometry);
|
||||||
|
rw::platform = driver;
|
||||||
|
atomic->pipeline = origPipe;
|
||||||
|
}
|
||||||
|
return atomic;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(FIX_BUGS) && defined(GTA_PC)
|
#if defined(FIX_BUGS) && defined(GTA_PC)
|
||||||
RwUInt32 saved_alphafunc, saved_alpharef;
|
RwUInt32 saved_alphafunc, saved_alpharef;
|
||||||
|
|
||||||
|
@ -56,6 +56,8 @@ RwCamera *CameraCreate(RwInt32 width,
|
|||||||
void _TexturePoolsInitialise();
|
void _TexturePoolsInitialise();
|
||||||
void _TexturePoolsShutdown();
|
void _TexturePoolsShutdown();
|
||||||
|
|
||||||
|
RpAtomic *ConvertPlatformAtomic(RpAtomic *atomic, void *data);
|
||||||
|
|
||||||
#if defined(FIX_BUGS) && defined (GTA_PC)
|
#if defined(FIX_BUGS) && defined (GTA_PC)
|
||||||
void SetAlphaTest(RwUInt32 alpharef);
|
void SetAlphaTest(RwUInt32 alpharef);
|
||||||
void RestoreAlphaTest();
|
void RestoreAlphaTest();
|
||||||
|
2
vendor/librw
vendored
2
vendor/librw
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 8c00f787cb8f53781c4335ecbc9d28fb9c664ba7
|
Subproject commit 7e80d45cdb6663f97d89ed443198ce6e37c4435e
|
Loading…
Reference in New Issue
Block a user