Merge pull request #1 from GTAmodding/miami

Miami
This commit is contained in:
Fire_Head
2020-07-29 12:20:02 +03:00
committed by GitHub
267 changed files with 23832 additions and 29992 deletions

View File

@ -39,7 +39,7 @@ extern float fRangePlayerRadius;
extern float fCloseNearClipLimit;
#ifdef FREE_CAM
bool CCamera::bFreeCam;
bool CCamera::bFreeCam = false;
int nPreviousMode = -1;
#endif

View File

@ -193,8 +193,8 @@ CCamera::Init(void)
m_bMusicFading = false;
m_fTimeToFadeMusic = 0.0f;
m_fFLOATingFadeMusic = 0.0f;
m_fMouseAccelHorzntl = 0.003f;
m_fMouseAccelVertical = 0.0025f;
m_fMouseAccelVertical = 0.003f;
m_fMouseAccelHorzntl = 0.0025f;
}
if(FrontEndMenuManager.m_bWantToRestart)
m_fTimeToFadeMusic = 0.0f;
@ -3376,15 +3376,15 @@ CCamera::LoadTrainCamNodes(char const *name)
char token[16] = { 0 };
char filename[16] = { 0 };
uint8 *buf;
int bufpos = 0;
size_t bufpos = 0;
int field = 0;
int tokpos = 0;
char c;
int i;
int len;
size_t len;
strcpy(filename, name);
len = strlen(filename);
len = (int)strlen(filename);
filename[len] = '.';
filename[len+1] = 'd';
filename[len+2] = 'a';
@ -4031,7 +4031,7 @@ bool
CCamera::IsPointVisible(const CVector &center, const CMatrix *mat)
{
RwV3d c;
c = *(RwV3d*)&center;
c = center;
RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix);
if(c.y < CDraw::GetNearClipZ()) return false;
if(c.y > CDraw::GetFarClipZ()) return false;
@ -4046,7 +4046,7 @@ bool
CCamera::IsSphereVisible(const CVector &center, float radius, const CMatrix *mat)
{
RwV3d c;
c = *(RwV3d*)&center;
c = center;
RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix);
if(c.y + radius < CDraw::GetNearClipZ()) return false;
if(c.y - radius > CDraw::GetFarClipZ()) return false;

View File

@ -189,10 +189,11 @@ GetGTA3ImgSize(void)
realpath(gImgNames[0], path);
if (stat(path, &statbuf) == -1) {
// Try case-insensitivity
char *r = (char*)alloca(strlen(gImgNames[0]) + 2);
if (casepath(gImgNames[0], r))
char* real = casepath(gImgNames[0], false);
if (real)
{
realpath(r, path);
realpath(real, path);
free(real);
if (stat(path, &statbuf) != -1)
goto ok;
}
@ -210,7 +211,6 @@ CdStreamShutdown(void)
{
// Destroying semaphores and free(gpReadInfo) will be done at threads
#ifndef ONE_THREAD_PER_CHANNEL
free(gChannelRequestQ.items);
gCdStreamThreadStatus = 2;
sem_post(&gCdStreamSema);
#endif
@ -442,6 +442,7 @@ void *CdStreamThread(void *param)
sem_destroy(&gpReadInfo[i].pDoneSemaphore);
}
sem_destroy(&gCdStreamSema);
free(gChannelRequestQ.items);
#else
sem_destroy(&gpReadInfo[channel].pStartSemaphore);
sem_destroy(&gpReadInfo[channel].pDoneSemaphore);
@ -460,10 +461,11 @@ CdStreamAddImage(char const *path)
// Fix case sensitivity and backslashes.
if (gImgFiles[gNumImages] == -1) {
char *r = (char*)alloca(strlen(path) + 2);
if (casepath(path, r))
char* real = casepath(path, false);
if (real)
{
gImgFiles[gNumImages] = open(r, _gdwCdStreamFlags);
gImgFiles[gNumImages] = open(real, _gdwCdStreamFlags);
free(real);
}
}

View File

@ -23,6 +23,8 @@
#include "Camera.h"
#include "ColStore.h"
//--MIAMI: file done
enum Direction
{
DIR_X_POS,
@ -36,16 +38,14 @@ enum Direction
eLevelName CCollision::ms_collisionInMemory;
CLinkList<CColModel*> CCollision::ms_colModelCache;
//--MIAMI: done
void
CCollision::Init(void)
{
ms_colModelCache.Init(NUMCOLCACHELINKS);
ms_collisionInMemory = LEVEL_NONE;
ms_collisionInMemory = LEVEL_GENERIC;
CColStore::Initialise();
}
//--MIAMI: done
void
CCollision::Shutdown(void)
{
@ -53,7 +53,6 @@ CCollision::Shutdown(void)
CColStore::Shutdown();
}
//--MIAMI: done
void
CCollision::Update(void)
{
@ -70,10 +69,10 @@ GetCollisionInSectorList(CPtrList &list)
for(node = list.first; node; node = node->next){
e = (CEntity*)node->item;
level = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel()->level;
if(level != LEVEL_NONE)
if(level != LEVEL_GENERIC)
return (eLevelName)level;
}
return LEVEL_NONE;
return LEVEL_GENERIC;
}
//--MIAMI: unused
@ -84,29 +83,29 @@ GetCollisionInSector(CSector &sect)
int level;
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_BUILDINGS]);
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_BUILDINGS_OVERLAP]);
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_OBJECTS]);
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_OBJECTS_OVERLAP]);
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_DUMMIES]);
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = GetCollisionInSectorList(sect.m_lists[ENTITYLIST_DUMMIES_OVERLAP]);
return (eLevelName)level;
}
//--MIAMI: done
void
CCollision::LoadCollisionWhenINeedIt(bool forceChange)
{
}
//--MIAMI: done
void
CCollision::SortOutCollisionAfterLoad(void)
{
CColStore::LoadCollision(TheCamera.GetPosition());
CStreaming::LoadAllRequestedModels(false);
}
void
@ -251,7 +250,7 @@ CCollision::TestVerticalLineBox(const CColLine &line, const CBox &box)
}
bool
CCollision::TestLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane)
CCollision::TestLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane)
{
float t;
CVector normal;
@ -266,9 +265,9 @@ CCollision::TestLineTriangle(const CColLine &line, const CVector *verts, const C
// find point of intersection
CVector p = line.p0 + (line.p1-line.p0)*t;
const CVector &va = verts[tri.a];
const CVector &vb = verts[tri.b];
const CVector &vc = verts[tri.c];
const CVector &va = verts[tri.a].Get();
const CVector &vb = verts[tri.b].Get();
const CVector &vc = verts[tri.c].Get();
CVector2D vec1, vec2, vec3, vect;
// We do the test in 2D. With the plane direction we
@ -361,15 +360,16 @@ CCollision::TestLineSphere(const CColLine &line, const CColSphere &sph)
bool
CCollision::TestSphereTriangle(const CColSphere &sphere,
const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane)
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane)
{
// If sphere and plane don't intersect, no collision
if(Abs(plane.CalcPoint(sphere.center)) > sphere.radius)
float planedist = plane.CalcPoint(sphere.center);
if(Abs(planedist) > sphere.radius)
return false;
const CVector &va = verts[tri.a];
const CVector &vb = verts[tri.b];
const CVector &vc = verts[tri.c];
const CVector &va = verts[tri.a].Get();
const CVector &vb = verts[tri.b].Get();
const CVector &vc = verts[tri.c].Get();
// calculate two orthogonal basis vectors for the triangle
CVector vec2 = vb - va;
@ -393,28 +393,35 @@ CCollision::TestSphereTriangle(const CColSphere &sphere,
int testcase = insideAB + insideAC + insideBC;
float dist = 0.0f;
if(testcase == 1){
switch(testcase){
case 0:
return false; // shouldn't happen
case 1:
// closest to a vertex
if(insideAB) dist = (sphere.center - vc).Magnitude();
else if(insideAC) dist = (sphere.center - vb).Magnitude();
else if(insideBC) dist = (sphere.center - va).Magnitude();
else assert(0);
}else if(testcase == 2){
break;
case 2:
// closest to an edge
// looks like original game as DistToLine manually inlined
if(!insideAB) dist = DistToLine(&va, &vb, &sphere.center);
else if(!insideAC) dist = DistToLine(&va, &vc, &sphere.center);
else if(!insideBC) dist = DistToLine(&vb, &vc, &sphere.center);
else assert(0);
}else if(testcase == 3){
break;
case 3:
// center is in triangle
return true;
}else
assert(0); // front fell off
dist = Abs(planedist);
break;
default:
assert(0);
}
return dist < sphere.radius;
}
//--MIAMI: TODO
bool
CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough, bool ignoreShootThrough)
{
@ -429,25 +436,32 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
if(!TestLineBox(newline, model.boundingBox))
return false;
for(i = 0; i < model.numSpheres; i++)
if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_TRANSPARENT_CLOTH)
if(TestLineSphere(newline, model.spheres[i]))
return true;
for(i = 0; i < model.numSpheres; i++){
if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.spheres[i].surface)) continue;
if(TestLineSphere(newline, model.spheres[i]))
return true;
}
for(i = 0; i < model.numBoxes; i++)
if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_TRANSPARENT_CLOTH)
if(TestLineBox(newline, model.boxes[i]))
return true;
for(i = 0; i < model.numBoxes; i++){
if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.boxes[i].surface)) continue;
if(TestLineBox(newline, model.boxes[i]))
return true;
}
CalculateTrianglePlanes(&model);
for(i = 0; i < model.numTriangles; i++)
if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_TRANSPARENT_CLOTH)
if(TestLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i]))
return true;
for(i = 0; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue;
if(TestLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i]))
return true;
}
return false;
}
// TODO: TestPillWithSpheresInColModel, but only called from overloaded CWeapon::FireMelee which isn't used
//
// Process
@ -716,18 +730,19 @@ CCollision::ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CC
return true;
}
//--MIAMI: unused
bool
CCollision::ProcessVerticalLineTriangle(const CColLine &line,
const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindist, CStoredCollPoly *poly)
{
float t;
CVector normal;
const CVector &p0 = line.p0;
const CVector &va = verts[tri.a];
const CVector &vb = verts[tri.b];
const CVector &vc = verts[tri.c];
const CVector &va = verts[tri.a].Get();
const CVector &vb = verts[tri.b].Get();
const CVector &vc = verts[tri.c].Get();
// early out bound rect test
if(p0.x < va.x && p0.x < vb.x && p0.x < vc.x) return false;
@ -792,6 +807,7 @@ CCollision::ProcessVerticalLineTriangle(const CColLine &line,
if(CrossProduct2D(vec2-vec1, vect-vec1) < 0.0f) return false;
if(CrossProduct2D(vec3-vec1, vect-vec1) > 0.0f) return false;
if(CrossProduct2D(vec3-vec2, vect-vec2) < 0.0f) return false;
if(t >= mindist) return false;
point.point = p;
point.normal = normal;
point.surfaceA = 0;
@ -817,16 +833,12 @@ CCollision::IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CCol
return false;
// maybe inlined?
CColTriangle tri;
tri.a = 0;
tri.b = 1;
tri.c = 2;
CColTrianglePlane plane;
plane.Set(poly->verts, tri);
plane.Set(poly->verts[0], poly->verts[1], poly->verts[2]);
const CVector &va = poly->verts[tri.a];
const CVector &vb = poly->verts[tri.b];
const CVector &vc = poly->verts[tri.c];
const CVector &va = poly->verts[0];
const CVector &vb = poly->verts[1];
const CVector &vc = poly->verts[2];
CVector p0 = pos;
CVector p1(pos.x, pos.y, z);
@ -891,8 +903,8 @@ CCollision::IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CCol
bool
CCollision::ProcessLineTriangle(const CColLine &line ,
const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindist)
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindist, CStoredCollPoly *poly)
{
float t;
CVector normal;
@ -910,9 +922,9 @@ CCollision::ProcessLineTriangle(const CColLine &line ,
// find point of intersection
CVector p = line.p0 + (line.p1-line.p0)*t;
const CVector &va = verts[tri.a];
const CVector &vb = verts[tri.b];
const CVector &vc = verts[tri.c];
const CVector &va = verts[tri.a].Get();
const CVector &vb = verts[tri.b].Get();
const CVector &vc = verts[tri.c].Get();
CVector2D vec1, vec2, vec3, vect;
switch(plane.dir){
@ -958,19 +970,26 @@ CCollision::ProcessLineTriangle(const CColLine &line ,
if(CrossProduct2D(vec2-vec1, vect-vec1) < 0.0f) return false;
if(CrossProduct2D(vec3-vec1, vect-vec1) > 0.0f) return false;
if(CrossProduct2D(vec3-vec2, vect-vec2) < 0.0f) return false;
if(t >= mindist) return false;
point.point = p;
point.normal = normal;
point.surfaceA = 0;
point.pieceA = 0;
point.surfaceB = tri.surface;
point.pieceB = 0;
if(poly){
poly->verts[0] = va;
poly->verts[1] = vb;
poly->verts[2] = vc;
poly->valid = true;
}
mindist = t;
return true;
}
bool
CCollision::ProcessSphereTriangle(const CColSphere &sphere,
const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindistsq)
{
// If sphere and plane don't intersect, no collision
@ -979,9 +998,9 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
if(Abs(planedist) > sphere.radius || distsq > mindistsq)
return false;
const CVector &va = verts[tri.a];
const CVector &vb = verts[tri.b];
const CVector &vc = verts[tri.c];
const CVector &va = verts[tri.a].Get();
const CVector &vb = verts[tri.b].Get();
const CVector &vc = verts[tri.c].Get();
// calculate two orthogonal basis vectors for the triangle
CVector normal;
@ -1008,25 +1027,33 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
int testcase = insideAB + insideAC + insideBC;
float dist = 0.0f;
CVector p;
if(testcase == 1){
switch(testcase){
case 0:
return false; // shouldn't happen
case 1:
// closest to a vertex
if(insideAB) p = vc;
else if(insideAC) p = vb;
else if(insideBC) p = va;
else assert(0);
dist = (sphere.center - p).Magnitude();
}else if(testcase == 2){
break;
case 2:
// closest to an edge
// looks like original game as DistToLine manually inlined
if(!insideAB) dist = DistToLine(&va, &vb, &sphere.center, p);
else if(!insideAC) dist = DistToLine(&va, &vc, &sphere.center, p);
else if(!insideBC) dist = DistToLine(&vb, &vc, &sphere.center, p);
else assert(0);
}else if(testcase == 3){
break;
case 3:
// center is in triangle
dist = Abs(planedist);
p = sphere.center - normal*planedist;
}else
assert(0); // front fell off
break;
default:
assert(0);
}
if(dist >= sphere.radius || dist*dist >= mindistsq)
return false;
@ -1043,7 +1070,6 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
return true;
}
//--MIAMI: TODO
bool
CCollision::ProcessLineOfSight(const CColLine &line,
const CMatrix &matrix, CColModel &model,
@ -1061,18 +1087,24 @@ CCollision::ProcessLineOfSight(const CColLine &line,
return false;
float coldist = mindist;
for(i = 0; i < model.numSpheres; i++)
if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessLineSphere(newline, model.spheres[i], point, coldist);
for(i = 0; i < model.numSpheres; i++){
if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.spheres[i].surface)) continue;
ProcessLineSphere(newline, model.spheres[i], point, coldist);
}
for(i = 0; i < model.numBoxes; i++)
if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessLineBox(newline, model.boxes[i], point, coldist);
for(i = 0; i < model.numBoxes; i++){
if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.boxes[i].surface)) continue;
ProcessLineBox(newline, model.boxes[i], point, coldist);
}
CalculateTrianglePlanes(&model);
for(i = 0; i < model.numTriangles; i++)
if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist);
for(i = 0; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
if(ignoreShootThrough && IsShootThrough(model.triangles[i].surface)) continue;
ProcessLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist);
}
if(coldist < mindist){
point.point = matrix * point.point;
@ -1083,7 +1115,6 @@ CCollision::ProcessLineOfSight(const CColLine &line,
return false;
}
//--MIAMI: TODO
bool
CCollision::ProcessVerticalLine(const CColLine &line,
const CMatrix &matrix, CColModel &model,
@ -1095,31 +1126,33 @@ CCollision::ProcessVerticalLine(const CColLine &line,
// transform line to model space
// Why does the game seem to do this differently than above?
CColLine newline(MultiplyInverse(matrix, line.p0), MultiplyInverse(matrix, line.p1));
newline.p1.x = newline.p0.x;
newline.p1.y = newline.p0.y;
if(!TestVerticalLineBox(newline, model.boundingBox))
if(!TestLineBox(newline, model.boundingBox))
return false;
// BUG? is IsSeeThroughVertical really the right thing? also not checking shoot through
float coldist = mindist;
for(i = 0; i < model.numSpheres; i++)
if(!ignoreSeeThrough || model.spheres[i].surface != SURFACE_GLASS && model.spheres[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessLineSphere(newline, model.spheres[i], point, coldist);
for(i = 0; i < model.numSpheres; i++){
if(ignoreSeeThrough && IsSeeThroughVertical(model.spheres[i].surface)) continue;
ProcessLineSphere(newline, model.spheres[i], point, coldist);
}
for(i = 0; i < model.numBoxes; i++)
if(!ignoreSeeThrough || model.boxes[i].surface != SURFACE_GLASS && model.boxes[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessLineBox(newline, model.boxes[i], point, coldist);
for(i = 0; i < model.numBoxes; i++){
if(ignoreSeeThrough && IsSeeThroughVertical(model.boxes[i].surface)) continue;
ProcessLineBox(newline, model.boxes[i], point, coldist);
}
CalculateTrianglePlanes(&model);
TempStoredPoly.valid = false;
for(i = 0; i < model.numTriangles; i++)
if(!ignoreSeeThrough || model.triangles[i].surface != SURFACE_GLASS && model.triangles[i].surface != SURFACE_TRANSPARENT_CLOTH)
ProcessVerticalLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist, &TempStoredPoly);
for(i = 0; i < model.numTriangles; i++){
if(ignoreSeeThrough && IsSeeThroughVertical(model.triangles[i].surface)) continue;
ProcessLineTriangle(newline, model.vertices, model.triangles[i], model.trianglePlanes[i], point, coldist, &TempStoredPoly);
}
if(coldist < mindist){
point.point = matrix * point.point;
point.normal = Multiply3x3(matrix, point.normal);
if(poly && TempStoredPoly.valid){
if(TempStoredPoly.valid && poly){
*poly = TempStoredPoly;
poly->verts[0] = matrix * poly->verts[0];
poly->verts[1] = matrix * poly->verts[1];
@ -1353,6 +1386,15 @@ CCollision::CalculateTrianglePlanes(CColModel *model)
}
}
void
CCollision::RemoveTrianglePlanes(CColModel *model)
{
if(model->trianglePlanes){
ms_colModelCache.Remove(model->GetLinkPtr());
model->RemoveTrianglePlanes();
}
}
void
CCollision::DrawColModel(const CMatrix &mat, const CColModel &colModel)
{
@ -1575,15 +1617,75 @@ CCollision::DrawColModel(const CMatrix &mat, const CColModel &colModel)
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
}
static void
GetSurfaceColor(uint8 surf, uint8 &r, uint8 &g, uint8 &b)
{
// game doesn't do this
r = 255;
g = 128;
b = 0;
switch(CSurfaceTable::GetAdhesionGroup(surf)){
case ADHESIVE_RUBBER:
r = 255;
g = 0;
b = 0;
break;
case ADHESIVE_HARD:
r = 255;
g = 255;
b = 128;
break;
case ADHESIVE_ROAD:
r = 128;
g = 128;
b = 128;
break;
case ADHESIVE_LOOSE:
r = 0;
g = 255;
b = 0;
break;
case ADHESIVE_SAND:
r = 255;
g = 128;
b = 128;
break;
case ADHESIVE_WET:
r = 0;
g = 0;
b = 255;
break;
}
if(surf == SURFACE_SAND || surf == SURFACE_SAND_BEACH){
r = 255;
g = 255;
b = 0;
}
float f = (surf & 0xF)/32.0f + 0.5f;
r *= f;
g *= f;
b *= f;
if(surf == SURFACE_TRANSPARENT_CLOTH || surf == SURFACE_METAL_CHAIN_FENCE ||
surf == SURFACE_TRANSPARENT_STONE || surf == SURFACE_SCAFFOLD_POLE)
if(CTimer::GetFrameCounter() & 1){
r = 0;
g = 0;
b = 0;
}
}
void
CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id)
{
int i;
int s;
float f;
CVector verts[8];
CVector min, max;
int r, g, b;
uint8 r, g, b;
RwImVertexIndex *iptr;
RwIm3DVertex *vptr;
@ -1602,53 +1704,8 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel,
verts[1] = mat * verts[1];
verts[2] = mat * verts[2];
// game doesn't do this
r = 255;
g = 128;
b = 0;
s = colModel.triangles[i].surface;
f = (s & 0xF)/32.0f + 0.5f;
switch(CSurfaceTable::GetAdhesionGroup(s)){
case ADHESIVE_RUBBER:
r = f * 255.0f;
g = 0;
b = 0;
break;
case ADHESIVE_HARD:
r = f*255.0f;
g = f*255.0f;
b = f*128.0f;
break;
case ADHESIVE_ROAD:
r = f*128.0f;
g = f*128.0f;
b = f*128.0f;
break;
case ADHESIVE_LOOSE:
r = 0;
g = f * 255.0f;
b = 0;
break;
case ADHESIVE_WET:
r = 0;
g = 0;
b = f * 255.0f;
break;
default:
// this doesn't make much sense
r *= f;
g *= f;
b *= f;
}
if(s == SURFACE_TRANSPARENT_CLOTH || s == SURFACE_METAL_CHAIN_FENCE ||
s == SURFACE_TRANSPARENT_STONE || s == SURFACE_SCAFFOLD_POLE)
if(CTimer::GetFrameCounter() & 1){
r = 0;
g = 0;
b = 0;
}
GetSurfaceColor(s, r, g, b);
if(s > SURFACE_METAL_GATE){
r = CGeneral::GetRandomNumber();
@ -1689,47 +1746,7 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel,
verts[7] = mat * CVector(max.x, max.y, max.z);
s = colModel.boxes[i].surface;
f = (s & 0xF)/32.0f + 0.5f;
switch(CSurfaceTable::GetAdhesionGroup(s)){
case ADHESIVE_RUBBER:
r = f * 255.0f;
g = 0;
b = 0;
break;
case ADHESIVE_HARD:
r = f*255.0f;
g = f*255.0f;
b = f*128.0f;
break;
case ADHESIVE_ROAD:
r = f*128.0f;
g = f*128.0f;
b = f*128.0f;
break;
case ADHESIVE_LOOSE:
r = 0;
g = f * 255.0f;
b = 0;
break;
case ADHESIVE_WET:
r = 0;
g = 0;
b = f * 255.0f;
break;
default:
// this doesn't make much sense
r *= f;
g *= f;
b *= f;
}
if(s == SURFACE_TRANSPARENT_CLOTH || s == SURFACE_METAL_CHAIN_FENCE ||
s == SURFACE_TRANSPARENT_STONE || s == SURFACE_SCAFFOLD_POLE)
if(CTimer::GetFrameCounter() & 1){
r = 0;
g = 0;
b = 0;
}
GetSurfaceColor(s, r, g, b);
RenderBuffer::StartStoring(36, 8, &iptr, &vptr);
RwIm3DVertexSetRGBA(&vptr[0], r, g, b, 255);
@ -1833,7 +1850,7 @@ CColLine::Set(const CVector &p0, const CVector &p1)
}
void
CColTriangle::Set(const CVector *, int a, int b, int c, uint8 surf, uint8 piece)
CColTriangle::Set(const CompressedVector *, int a, int b, int c, uint8 surf, uint8 piece)
{
this->a = a;
this->b = b;
@ -1842,12 +1859,8 @@ CColTriangle::Set(const CVector *, int a, int b, int c, uint8 surf, uint8 piece)
}
void
CColTrianglePlane::Set(const CVector *v, CColTriangle &tri)
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
{
const CVector &va = v[tri.a];
const CVector &vb = v[tri.b];
const CVector &vc = v[tri.c];
normal = CrossProduct(vc-va, vb-va);
normal.Normalise();
dist = DotProduct(normal, va);
@ -1905,6 +1918,7 @@ CColModel::RemoveCollisionVolumes(void)
RwFree(boxes);
RwFree(vertices);
RwFree(triangles);
CCollision::RemoveTrianglePlanes(this);
}
numSpheres = 0;
numLines = 0;
@ -1950,7 +1964,7 @@ CColModel::GetLinkPtr(void)
void
CColModel::GetTrianglePoint(CVector &v, int i) const
{
v = vertices[i];
v = vertices[i].Get();
}
CColModel&
@ -2029,7 +2043,7 @@ CColModel::operator=(const CColModel &other)
if(vertices)
RwFree(vertices);
if(numVerts){
vertices = (CVector*)RwMalloc(numVerts*sizeof(CVector));
vertices = (CompressedVector*)RwMalloc(numVerts*sizeof(CompressedVector));
for(i = 0; i < numVerts; i++)
vertices[i] = other.vertices[i];
}

View File

@ -10,6 +10,19 @@
#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; };
#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 CSphere
{
CVector center;
@ -63,7 +76,7 @@ struct CColTriangle
uint16 c;
uint8 surface;
void Set(const CVector *v, int a, int b, int c, uint8 surf, uint8 piece);
void Set(const CompressedVector *v, int a, int b, int c, uint8 surf, uint8 piece);
};
struct CColTrianglePlane
@ -72,7 +85,8 @@ struct CColTrianglePlane
float dist;
uint8 dir;
void Set(const CVector *v, CColTriangle &tri);
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 GetNormalX() const { return normal.x; }
float GetNormalY() const { return normal.y; }
@ -116,7 +130,7 @@ struct CColModel
CColSphere *spheres;
CColLine *lines;
CColBox *boxes;
CVector *vertices;
CompressedVector *vertices;
CColTriangle *triangles;
CColTrianglePlane *trianglePlanes;
@ -148,24 +162,25 @@ public:
static void DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id);
static void CalculateTrianglePlanes(CColModel *model);
static void RemoveTrianglePlanes(CColModel *model);
// all these return true if there's a collision
static bool TestSphereSphere(const CSphere &s1, const CSphere &s2);
static bool TestSphereBox(const CSphere &sph, const CBox &box);
static bool TestLineBox(const CColLine &line, const CBox &box);
static bool TestVerticalLineBox(const CColLine &line, const CBox &box);
static bool TestLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
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 CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
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, bool ignoreShootThrough);
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 CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly);
static bool ProcessLineTriangle(const CColLine &line , const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, 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, CStoredCollPoly *poly = nil);
static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist);
static bool ProcessSphereTriangle(const CColSphere &sph, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq);
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, bool ignoreShootThrough);
static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, bool ignoreShootThrough, CStoredCollPoly *poly);
static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists);

View File

@ -131,6 +131,7 @@ void CControllerConfigManager::SaveSettings(int32 file)
void CControllerConfigManager::LoadSettings(int32 file)
{
bool bValid = true;
int nVersion = 0;
if (file)
{
@ -139,11 +140,13 @@ void CControllerConfigManager::LoadSettings(int32 file)
if (!strncmp(buff, TopLineEmptyFile, sizeof(TopLineEmptyFile)-1))
bValid = false;
else
else {
CFileMgr::Seek(file, 0, 0);
CFileMgr::Read(file, (char*)&nVersion, sizeof(nVersion));
}
}
if (bValid)
if (bValid && nVersion >= 3)
{
ControlsManager.MakeControllerActionsBlank();
@ -202,6 +205,8 @@ void CControllerConfigManager::InitDefaultControlConfiguration()
SetControllerKeyAssociatedWithAction (GO_BACK, rsDOWN, KEYBOARD);
SetControllerKeyAssociatedWithAction (GO_BACK, 'S', OPTIONAL_EXTRA);
SetControllerKeyAssociatedWithAction (NETWORK_TALK, 'T', KEYBOARD);
SetControllerKeyAssociatedWithAction (PED_LOOKBEHIND, rsPADEND, KEYBOARD);
SetControllerKeyAssociatedWithAction (PED_LOOKBEHIND, rsCAPSLK, OPTIONAL_EXTRA);
@ -436,6 +441,7 @@ void CControllerConfigManager::InitialiseControllerActionNameArray()
SETACTIONNAME(PED_SPRINT);
SETACTIONNAME(PED_CYCLE_TARGET_LEFT);
SETACTIONNAME(PED_CYCLE_TARGET_RIGHT);
SETACTIONNAME(PED_LOCK_TARGET); // duplicate
SETACTIONNAME(PED_CENTER_CAMERA_BEHIND_PLAYER);
SETACTIONNAME(VEHICLE_LOOKBEHIND);
SETACTIONNAME(PED_DUCK);
@ -1808,23 +1814,23 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
{
switch (action)
{
case CAMERA_CHANGE_VIEW_ALL_SITUATIONS:
case PED_FIREWEAPON:
case GO_LEFT:
case GO_RIGHT:
case CAMERA_CHANGE_VIEW_ALL_SITUATIONS:
case NETWORK_TALK:
case SWITCH_DEBUG_CAM_ON:
case TOGGLE_DPAD:
case SWITCH_DEBUG_CAM_ON:
case TAKE_SCREEN_SHOT:
case SHOW_MOUSE_POINTER_TOGGLE:
return ACTIONTYPE_COMMON;
break;
case PED_LOOKBEHIND:
case PED_CYCLE_WEAPON_LEFT:
case PED_CYCLE_WEAPON_RIGHT:
case PED_CYCLE_WEAPON_LEFT:
case PED_JUMPING:
case PED_SPRINT:
case PED_LOOKBEHIND:
case PED_DUCK:
case PED_ANSWER_PHONE:
case PED_CYCLE_TARGET_LEFT:
@ -1853,13 +1859,13 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
return ACTIONTYPE_VEHICLE_3RDPERSON;
break;
case PED_LOCK_TARGET:
case GO_FORWARD:
case GO_BACK:
case PED_1RST_PERSON_LOOK_LEFT:
case PED_1RST_PERSON_LOOK_RIGHT:
case PED_1RST_PERSON_LOOK_DOWN:
case PED_LOCK_TARGET:
case PED_1RST_PERSON_LOOK_UP:
case PED_1RST_PERSON_LOOK_DOWN:
return ACTIONTYPE_1RST3RDPERSON;
break;

View File

@ -61,6 +61,7 @@ enum e_ControllerAction
SWITCH_DEBUG_CAM_ON,
TAKE_SCREEN_SHOT,
SHOW_MOUSE_POINTER_TOGGLE,
UNKNOWN_ACTION,
MAX_CONTROLLERACTIONS,
};

View File

@ -30,7 +30,8 @@ CDirectory::ReadDirFile(const char *filename)
bool
CDirectory::WriteDirFile(const char *filename)
{
int fd, n;
int fd;
size_t n;
fd = CFileMgr::OpenFileForWriting(filename);
n = CFileMgr::Write(fd, (char*)entries, numEntries*sizeof(DirectoryInfo));
CFileMgr::CloseFile(fd);

View File

@ -189,7 +189,7 @@ CEventList::FindClosestEvent(eEventType type, CVector posn, int32 *event)
// --MIAMI: Done
void
CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCare)
CEventList::ReportCrimeForEvent(eEventType type, size_t crimeId, bool copsDontCare)
{
eCrimeType crime;
switch(type){
@ -227,10 +227,10 @@ CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCar
if(CWanted::WorkOutPolicePresence(playerCoors, 14.0f) != 0 ||
CGame::germanGame && (crime == CRIME_SHOOT_PED || crime == CRIME_SHOOT_COP || crime == CRIME_COP_BURNED || crime == CRIME_VEHICLE_BURNED)){
FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(crime, playerPedCoors, crimeId, copsDontCare);
FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(crime, playerPedCoors, (uint32)crimeId, copsDontCare);
FindPlayerPed()->m_pWanted->SetWantedLevelNoDrop(1);
}else
FindPlayerPed()->m_pWanted->RegisterCrime(crime, playerPedCoors, crimeId, copsDontCare);
FindPlayerPed()->m_pWanted->RegisterCrime(crime, playerPedCoors, (uint32)crimeId, copsDontCare);
if(type == EVENT_ASSAULT_POLICE)
FindPlayerPed()->SetWantedLevelNoDrop(1);

View File

@ -61,7 +61,7 @@ public:
static bool GetEvent(eEventType type, int32 *event);
static void ClearEvent(int32 event);
static bool FindClosestEvent(eEventType type, CVector posn, int32 *event);
static void ReportCrimeForEvent(eEventType type, int32, bool);
static void ReportCrimeForEvent(eEventType type, size_t, bool);
};
extern CEvent gaEvent[NUMEVENTS];

View File

@ -106,7 +106,9 @@ CFileLoader::LoadLevel(const char *filename)
LoadingScreenLoadingFile(line + 4);
LoadScene(line + 4);
}else if(strncmp(line, "SPLASH", 6) == 0){
#ifndef DISABLE_LOADING_SCREEN
LoadSplash(GetRandomSplashScreen());
#endif
}else if(strncmp(line, "CDIMAGE", 7) == 0){
CdStreamAddImage(line + 8);
}
@ -324,13 +326,13 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
int32 numVertices = *(int16*)buf;
buf += 4;
if(numVertices > 0){
model.vertices = (CVector*)RwMalloc(numVertices*sizeof(CVector));
model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector));
for(i = 0; i < numVertices; i++){
model.vertices[i] = *(CVector*)buf;
model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8));
#if 0
if(Abs(model.vertices[i].x) >= 256.0f ||
Abs(model.vertices[i].y) >= 256.0f ||
Abs(model.vertices[i].z) >= 256.0f)
if(Abs(*(float*)buf) >= 256.0f ||
Abs(*(float*)(buf+4)) >= 256.0f ||
Abs(*(float*)(buf+8)) >= 256.0f)
printf("%s:Collision volume too big\n", modelname);
#endif
buf += 12;
@ -393,6 +395,16 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
return atomic;
}
#ifdef LIBRW
void
InitClump(RpClump *clump)
{
RpClumpForAllAtomics(clump, ConvertPlatformAtomic, nil);
}
#else
#define InitClump(clump)
#endif
void
CFileLoader::LoadModelFile(const char *filename)
{
@ -404,6 +416,7 @@ CFileLoader::LoadModelFile(const char *filename)
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){
clump = RpClumpStreamRead(stream);
if(clump){
InitClump(clump);
RpClumpForAllAtomics(clump, FindRelatedModelInfoCB, clump);
RpClumpDestroy(clump);
}
@ -429,6 +442,7 @@ CFileLoader::LoadClumpFile(const char *filename)
GetNameAndLOD(nodename, name, &n);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(name, nil);
if(mi){
InitClump(clump);
assert(mi->IsClump());
mi->SetClump(clump);
}else
@ -449,6 +463,7 @@ CFileLoader::LoadClumpFile(RwStream *stream, uint32 id)
clump = RpClumpStreamRead(stream);
if(clump == nil)
return false;
InitClump(clump);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
mi->SetClump(clump);
return true;
@ -476,6 +491,7 @@ CFileLoader::FinishLoadClumpFile(RwStream *stream, uint32 id)
clump = RpClumpGtaStreamRead2(stream);
if(clump){
InitClump(clump);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
mi->SetClump(clump);
return true;
@ -496,6 +512,7 @@ CFileLoader::LoadAtomicFile(RwStream *stream, uint32 id)
clump = RpClumpStreamRead(stream);
if(clump == nil)
return false;
InitClump(clump);
gpRelatedModelInfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
RpClumpForAllAtomics(clump, SetRelatedModelInfoCB, clump);
RpClumpDestroy(clump);
@ -531,6 +548,8 @@ CFileLoader::LoadAtomicFile2Return(const char *filename)
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
clump = RpClumpStreamRead(stream);
if(clump)
InitClump(clump);
RwStreamClose(stream, nil);
return clump;
}
@ -1260,7 +1279,7 @@ CFileLoader::LoadOcclusionVolume(const char *line)
&x, &y, &z,
&width, &length, &height,
&angle);
COcclusion::AddOne(x, y, z, width, length, z + height/2.0f, angle);
COcclusion::AddOne(x, y, z + height/2.0f, width, length, height, angle);
}

View File

@ -4,6 +4,7 @@
#include <direct.h>
#endif
#include "common.h"
#include "crossplatform.h"
#include "FileMgr.h"
@ -31,19 +32,16 @@ static myFILE myfiles[NUMFILES];
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
#include "crossplatform.h"
#define _getcwd getcwd
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
void mychdir(char const *path)
{
char *r = (char*)alloca(strlen(path) + 2);
if (casepath(path, r))
{
char* r = casepath(path, false);
if (r) {
chdir(r);
}
else
{
free(r);
} else {
errno = ENOENT;
}
}
@ -73,30 +71,7 @@ found:
*p++ = 'b';
*p = '\0';
#if !defined(_WIN32)
char *newPath = strdup(filename);
// Normally casepath() fixes backslashes, but if the mode is sth other than r/rb it will create new file with backslashes on linux, so fix backslashes here
char *nextBs;
while(nextBs = strstr(newPath, "\\")){
*nextBs = '/';
}
#else
const char *newPath = filename;
#endif
myfiles[fd].file = fopen(newPath, realmode);
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
#if !defined(_WIN32)
if (!myfiles[fd].file) {
char *r = (char*)alloca(strlen(newPath) + 2);
if (casepath(newPath, r))
{
myfiles[fd].file = fopen(r, realmode);
}
}
free(newPath);
#endif
myfiles[fd].file = fcaseopen(filename, realmode);
if(myfiles[fd].file == nil)
return 0;
return fd;
@ -163,7 +138,7 @@ myfgets(char *buf, int len, int fd)
return buf;
}
static int
static size_t
myfread(void *buf, size_t elt, size_t n, int fd)
{
if(myfiles[fd].isText){
@ -184,7 +159,7 @@ myfread(void *buf, size_t elt, size_t n, int fd)
return fread(buf, elt, n, myfiles[fd].file);
}
static int
static size_t
myfwrite(void *buf, size_t elt, size_t n, int fd)
{
if(myfiles[fd].isText){
@ -265,11 +240,11 @@ CFileMgr::SetDirMyDocuments(void)
mychdir(_psGetUserFilesFolder());
}
int
size_t
CFileMgr::LoadFile(const char *file, uint8 *buf, int unused, const char *mode)
{
int fd;
int n, len;
size_t n, len;
fd = myfopen(file, mode);
if(fd == 0)
@ -298,14 +273,14 @@ CFileMgr::OpenFileForWriting(const char *file)
return OpenFile(file, "wb");
}
int
CFileMgr::Read(int fd, const char *buf, int len)
size_t
CFileMgr::Read(int fd, const char *buf, size_t len)
{
return myfread((void*)buf, 1, len, fd);
}
int
CFileMgr::Write(int fd, const char *buf, int len)
size_t
CFileMgr::Write(int fd, const char *buf, size_t len)
{
return myfwrite((void*)buf, 1, len, fd);
}

View File

@ -9,12 +9,12 @@ public:
static void ChangeDir(const char *dir);
static void SetDir(const char *dir);
static void SetDirMyDocuments(void);
static int LoadFile(const char *file, uint8 *buf, int unused, const char *mode);
static size_t LoadFile(const char *file, uint8 *buf, int unused, const char *mode);
static int OpenFile(const char *file, const char *mode);
static int OpenFile(const char *file) { return OpenFile(file, "rb"); }
static int OpenFileForWriting(const char *file);
static int Read(int fd, const char *buf, int len);
static int Write(int fd, const char *buf, int len);
static size_t Read(int fd, const char *buf, size_t len);
static size_t Write(int fd, const char *buf, size_t len);
static bool Seek(int fd, int offset, int whence);
static bool ReadLine(int fd, char *buf, int len);
static int CloseFile(int fd);

File diff suppressed because it is too large Load Diff

View File

@ -66,20 +66,23 @@
#define PLAYERSETUP_LIST_BODY_TOP 47
#define PLAYERSETUP_ROW_HEIGHT 9
#define STATS_SLIDE_Y_PER_SECOND 30.0f
#define STATS_ROW_HEIGHT 20.0f
#define STATS_ROW_X_MARGIN 50.0f
#define STATS_BOTTOM_MARGIN 135.0f
#define STATS_TOP_MARGIN 40.0f
#define STATS_TOP_DIMMING_AREA_LENGTH (93.0f - STATS_TOP_MARGIN)
#define STATS_BOTTOM_DIMMING_AREA_LENGTH 55.0f
#define STATS_PUT_BACK_TO_BOTTOM_Y 50.0f
#define STATS_RATING_X 24.0f
#define STATS_RATING_Y 20.0f
#define STATS_ROW_HEIGHT 17.0f
#define STATS_ROW_LEFT_MARGIN 110.0f
#define STATS_ROW_RIGHT_MARGIN 113.0f
#define STATS_TOP_Y 135.0f // Just faded in
#define STATS_BOTTOM_Y 300.0f // Starts to fade out after that
#define STATS_FADING_AREA_LENGTH 50.0f
#define STATS_VISIBLE_START_Y (STATS_TOP_Y - 10.f)
#define STATS_VISIBLE_END_Y (STATS_BOTTOM_Y + 21.f)
#define STATS_RATING_X 320.0f
#define STATS_RATING_Y_1 85.0f
#define STATS_RATING_Y_2 110.0f
#define BRIEFS_TOP_MARGIN 40.0f
#define BRIEFS_LINE_X 50.0f
#define BRIEFS_LINE_HEIGHT 60.0f
#define BRIEFS_TOP_MARGIN 140.0f
#define BRIEFS_BOTTOM_MARGIN 280.0f
#define BRIEFS_LINE_X 100.0f
#define BRIEFS_LINE_HEIGHT 20.0f
#define BRIEFS_LINE_SPACING 10.0f
#define CONTSETUP_STANDARD_ROW_HEIGHT 10.7f
#define CONTSETUP_CLASSIC_ROW_HEIGHT 9.0f
@ -262,17 +265,9 @@ enum eMenuAction
MENUACTION_DYNAMICACOUSTIC,
MENUACTION_MOUSESTEER,
MENUACTION_UNK110,
#ifdef MORE_LANGUAGES
MENUACTION_LANG_PL,
MENUACTION_LANG_RUS,
MENUACTION_LANG_JAP,
#endif
#ifdef IMPROVED_VIDEOMODE
MENUACTION_SCREENMODE,
#endif
#ifdef FREE_CAM
MENUACTION_FREECAM,
#endif
#ifdef LEGACY_MENU_OPTIONS
MENUACTION_CTRLVIBRATION,
MENUACTION_CTRLCONFIG,
@ -477,10 +472,10 @@ public:
int8 m_nPrefsAudio3DProviderIndex;
int8 m_PrefsSpeakers;
int8 m_PrefsDMA;
uint8 m_PrefsSfxVolume;
uint8 m_PrefsMusicVolume;
int8 m_PrefsSfxVolume;
int8 m_PrefsMusicVolume;
uint8 m_PrefsRadioStation;
uint8 field_2C;
uint8 m_PrefsStereoMono; // unused except restore settings
int32 m_nCurrOption;
bool m_bQuitGameNoCD;
bool m_bMenuMapActive;
@ -544,7 +539,7 @@ public:
int32 m_nMouseOldPosY;
int32 m_nHoverOption;
bool m_bShowMouse;
int32 m_nPrevOption;
int32 m_nOptionMouseHovering;
bool m_bStartWaitingForKeyBind;
bool m_bWaitingForNewKeyBind;
bool m_bKeyChangeNotProcessed;
@ -595,7 +590,9 @@ public:
};
bool GetIsMenuActive() {return !!m_bMenuActive;}
static uint8 m_PrefsStereoMono;
#ifdef CUTSCENE_BORDERS_SWITCH
static bool m_PrefsCutsceneBorders;
#endif
#ifndef MASTER
static bool m_PrefsMarketing;
@ -613,7 +610,7 @@ public:
void CheckCodesForControls(int);
bool CheckHover(int x1, int x2, int y1, int y2);
void CheckSliderMovement(int);
void DisplayHelperText();
void DisplayHelperText(char*);
int DisplaySlider(float, float, float, float, float, float, float);
void DoSettingsBeforeStartingAGame();
void DrawStandardMenus(bool);
@ -625,7 +622,7 @@ public:
void DrawBackground(bool transitionCall);
void DrawPlayerSetupScreen();
int FadeIn(int alpha);
void FilterOutColorMarkersFromString(wchar*, CRGBA &);
void FilterOutColorMarkersFromString(wchar*);
int GetStartOptionsCntrlConfigScreens();
void InitialiseChangedLanguageSettings();
void LoadAllTextures();
@ -659,6 +656,7 @@ public:
void ScrollDownListByOne();
void PageUpList(bool);
void PageDownList(bool);
int8 GetPreviousPageOption();
// uint8 GetNumberOfMenuOptions();
};
@ -668,6 +666,6 @@ VALIDATE_SIZE(CMenuManager, 0x688);
#endif
extern CMenuManager FrontEndMenuManager;
extern CMenuScreen aScreens[];
#endif

View File

@ -88,6 +88,7 @@
#include "Zones.h"
#include "Occlusion.h"
#include "debugmenu.h"
#include "Ropes.h"
eLevelName CGame::currLevel;
int32 CGame::currArea;
@ -151,6 +152,10 @@ CGame::InitialiseOnceBeforeRW(void)
return true;
}
#if !defined(LIBRW) && defined(PS2_MATFX)
void ReplaceMatFxCallback();
#endif
bool
CGame::InitialiseRenderWare(void)
{
@ -201,6 +206,8 @@ CGame::InitialiseRenderWare(void)
#else
rw::MatFX::modulateEnvMap = false;
#endif
#elif defined(PS2_MATFX)
ReplaceMatFxCallback();
#endif
CFont::Initialise();
@ -245,23 +252,20 @@ void CGame::ShutdownRenderWare(void)
bool CGame::InitialiseOnceAfterRW(void)
{
TheText.Load();
DMAudio.Initialise();
CTimer::Initialise();
CTempColModels::Initialise();
mod_HandlingManager.Initialise();
CSurfaceTable::Initialise("DATA\\SURFACE.DAT");
CPedStats::Initialise();
CTimeCycle::Initialise();
DMAudio.Initialise();
if ( DMAudio.GetNum3DProvidersAvailable() == 0 )
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = -1;
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = NO_AUDIO_PROVIDER;
if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -99 || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 )
if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == AUDIO_PROVIDER_NOT_DETERMINED || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 )
{
FrontEndMenuManager.m_PrefsSpeakers = 0;
int8 provider = DMAudio.AutoDetect3DProviders();
if ( provider != -1 )
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = provider;
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = DMAudio.AutoDetect3DProviders();
}
DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
@ -316,7 +320,6 @@ bool CGame::Initialise(const char* datFile)
COcclusion::Init();
CCollision::Init();
CSetPieces::Init();
TheText.Load();
CTheZones::Init();
CUserDisplay::Init();
CMessages::Init();
@ -358,9 +361,9 @@ bool CGame::Initialise(const char* datFile)
LoadingScreen("Loading the Game", "Setup streaming", nil);
CStreaming::LoadInitialVehicles();
CStreaming::LoadInitialPeds();
CStreaming::RequestBigBuildings(LEVEL_NONE);
CStreaming::RequestBigBuildings(LEVEL_GENERIC);
CStreaming::LoadAllRequestedModels(false);
printf("Streaming uses %dK of its memory", CStreaming::ms_memoryUsed / 1024);
printf("Streaming uses %zuK of its memory", CStreaming::ms_memoryUsed / 1024); // original modifier was %d
LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen());
CAnimManager::LoadAnimFiles();
CStreaming::LoadInitialWeapons();
@ -401,9 +404,11 @@ bool CGame::Initialise(const char* datFile)
CRubbish::Init();
CClouds::Init();
CSpecialFX::Init();
CRopes::Init();
CWaterCannons::Init();
CBridge::Init();
CGarages::Init();
LoadingScreen("Loading the Game", "Position dynamic objects", nil);
LoadingScreen("Loading the Game", "Initialise vehicle paths", nil);
CTrain::InitTrains();
CPlane::InitPlanes();
@ -414,6 +419,7 @@ bool CGame::Initialise(const char* datFile)
if ( !TheMemoryCard.m_bWantToLoad )
{
#endif
LoadingScreen("Loading the Game", "Start script", nil);
CTheScripts::StartTestScript();
CTheScripts::Process();
TheCamera.Process();
@ -424,6 +430,9 @@ bool CGame::Initialise(const char* datFile)
CCollision::ms_collisionInMemory = currLevel;
for (int i = 0; i < MAX_PADS; i++)
CPad::GetPad(i)->Clear(true);
// TODO(Miami)
// DMAudio.SetStartingTrackPositions(1);
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
return true;
}
@ -509,7 +518,7 @@ void CGame::ReInitGameObjectVariables(void)
CTimeCycle::Initialise();
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
CStreaming::RequestBigBuildings(LEVEL_NONE);
CStreaming::RequestBigBuildings(LEVEL_GENERIC);
CStreaming::LoadAllRequestedModels(false);
CPed::Initialise();
CEventList::Initialise();
@ -544,6 +553,7 @@ void CGame::ReInitGameObjectVariables(void)
CRemote::Init();
#endif
CSpecialFX::Init();
CRopes::Init();
CWaterCannons::Init();
CParticle::ReloadConfig();
@ -647,7 +657,7 @@ void CGame::InitialiseWhenRestarting(void)
CTimer::Initialise();
FrontEndMenuManager.m_bWantToLoad = false;
ReInitGameObjectVariables();
currLevel = LEVEL_NONE;
currLevel = LEVEL_GENERIC;
CCollision::SortOutCollisionAfterLoad();
}
}
@ -716,6 +726,7 @@ void CGame::Process(void)
CGarages::Update();
CRubbish::Update();
CSpecialFX::Update();
CRopes::Update();
CTimeCycle::Update();
if (CReplay::ShouldStandardCameraBeProcessed())
TheCamera.Process();

View File

@ -2,7 +2,7 @@
enum eLevelName {
LEVEL_IGNORE = -1, // beware, this is only used in CPhysical's m_nZoneLevel
LEVEL_NONE = 0,
LEVEL_GENERIC = 0,
LEVEL_BEACH,
LEVEL_MAINLAND
};

View File

@ -108,7 +108,7 @@ public:
if (angle >= TWOPI)
angle -= TWOPI;
return (int)floorf(angle / DEGTORAD(45.0f));
return (int)Floor(angle / DEGTORAD(45.0f));
}
// Unlike usual string comparison functions, these don't care about greater or lesser

View File

@ -1,10 +1,12 @@
#pragma once
#include "common.h"
#include "Frontend.h"
#ifdef PC_MENU
// --MIAMI: Done except commented things
// If you want to add new options, please don't do that here and see CustomFrontendOptionsPopulate in re3.cpp.
CMenuScreen aScreens[] = {
// MENUPAGE_STATS = 0
{ "FET_STA", MENUPAGE_NONE, 3,
{ "FEH_STA", MENUPAGE_NONE, 3,
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 190, 320, MENUALIGN_RIGHT,
},
@ -79,11 +81,9 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER,
},
// TODO(Miami): This is still my implementation
// MENUPAGE_MAP = 6
{ "FEH_MAP", MENUPAGE_NONE, 2,
MENUACTION_UNK110, "", SAVESLOT_NONE, 0, 0, 0, 0, // to prevent cross/enter to go back
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 70, 380, MENUALIGN_CENTER,
},
// MENUPAGE_NEW_GAME_RELOAD = 7
@ -343,3 +343,5 @@ CMenuScreen aScreens[] = {
},
#endif
};
#endif

View File

@ -39,6 +39,7 @@
#include "General.h"
#include "Fluff.h"
#include "Gangs.h"
#include "platform.h"
#ifdef GTA_PS2
#include "eetypes.h"
@ -518,9 +519,12 @@ void FlyingFishCheat(void)
bool
CControllerState::CheckForInput(void)
{
return !!LeftStickX || !!LeftStickY || !!RightStickX || !!RightStickY || !!LeftShoulder1 || !!LeftShoulder2 || !!RightShoulder1 || !!RightShoulder2 ||
!!DPadUp || !!DPadDown || !!DPadLeft || !!DPadRight || !!Start || !!Select || !!Square || !!Triangle || !!Cross || !!Circle || !!LeftShock ||
!!RightShock;
return !!RightStickX || !!RightStickY || !!LeftStickX || !!LeftStickY
|| !!DPadUp || !!DPadDown || !!DPadLeft || !!DPadRight
|| !!Triangle || !!Cross || !!Circle || !!Square
|| !!Start || !!Select
|| !!LeftShoulder1 || !!LeftShoulder2 || !!RightShoulder1 || !!RightShoulder2
|| !!LeftShock || !!RightShock;
}
void
@ -668,7 +672,7 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
#if defined RW_D3D9 || defined RWLIBS
if ( PSGLOBAL(mouse) == nil )
_InputInitialiseMouse();
_InputInitialiseMouse(!FrontEndMenuManager.m_bMenuActive && _InputMouseNeedsExclusive());
if ( PSGLOBAL(mouse) != nil )
{
@ -718,11 +722,11 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
void CPad::UpdateMouse()
{
#if defined RW_D3D9 || defined RWLIBS
if ( IsForegroundApp() )
{
#if defined RW_D3D9 || defined RWLIBS
if ( PSGLOBAL(mouse) == nil )
_InputInitialiseMouse();
_InputInitialiseMouse(!FrontEndMenuManager.m_bMenuActive && _InputMouseNeedsExclusive());
DIMOUSESTATE2 state;
@ -757,7 +761,10 @@ void CPad::UpdateMouse()
OldMouseControllerState = NewMouseControllerState;
NewMouseControllerState = PCTempMouseControllerState;
}
}
#else
if ( IsForegroundApp() && PSGLOBAL(cursorIsInWindow) )
{
double xpos = 1.0f, ypos;
glfwGetCursorPos(PSGLOBAL(window), &xpos, &ypos);
if (xpos == 0.f)
@ -795,8 +802,8 @@ void CPad::UpdateMouse()
OldMouseControllerState = NewMouseControllerState;
NewMouseControllerState = PCTempMouseControllerState;
#endif
}
#endif
}
CControllerState CPad::ReconcileTwoControllersInput(CControllerState const &State1, CControllerState const &State2)
@ -1447,6 +1454,13 @@ void CPad::UpdatePads(void)
#else
CapturePad(0);
#endif
// Improve keyboard input latency part 1
#ifdef FIX_BUGS
OldKeyState = NewKeyState;
NewKeyState = TempKeyState;
#endif
#ifdef DETECT_PAD_INPUT_SWITCH
if (GetPad(0)->PCTempJoyState.CheckForInput())
IsAffectedByController = true;
@ -1468,7 +1482,7 @@ void CPad::UpdatePads(void)
if ( bUpdate )
{
GetPad(0)->Update(0);
GetPad(1)->Update(0);
// GetPad(1)->Update(0); // not in VC
}
#if defined(MASTER) && !defined(XINPUT)
@ -1476,8 +1490,11 @@ void CPad::UpdatePads(void)
GetPad(1)->OldState.Clear();
#endif
// Improve keyboard input latency part 2
#ifndef FIX_BUGS
OldKeyState = NewKeyState;
NewKeyState = TempKeyState;
#endif
}
void CPad::ProcessPCSpecificStuff(void)
@ -3024,7 +3041,7 @@ void CPad::ResetCheats(void)
char *CPad::EditString(char *pStr, int32 nSize)
{
int32 pos = strlen(pStr);
int32 pos = (int32)strlen(pStr);
// letters
for ( int32 i = 0; i < ('Z' - 'A' + 1); i++ )

View File

@ -560,7 +560,7 @@ CPlayerInfo::Process(void)
veh->m_nZoneLevel = LEVEL_IGNORE;
for (int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
if (veh->pPassengers[i])
veh->pPassengers[i]->m_nZoneLevel = LEVEL_NONE;
veh->pPassengers[i]->m_nZoneLevel = LEVEL_GENERIC;
}
CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
} else {

View File

@ -121,11 +121,11 @@ static_assert(RADAR_TILE_SIZE == (RADAR_SIZE_Y / RADAR_NUM_TILES), "CRadar: not
#define RADAR_MIN_SPEED (0.3f)
#define RADAR_MAX_SPEED (0.9f)
#ifdef MENU_MAP
CRGBA CRadar::ArrowBlipColour1;
CRGBA CRadar::ArrowBlipColour2;
uint16 CRadar::MapLegendCounter;
int16 CRadar::MapLegendList[NUM_MAP_LEGENDS];
#ifdef MAP_ENHANCEMENTS
int CRadar::TargetMarkerId = -1;
CVector CRadar::TargetMarkerPos;
#endif
@ -263,10 +263,9 @@ int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &
uint8 CRadar::CalculateBlipAlpha(float dist)
{
#ifdef MENU_MAP
if (FrontEndMenuManager.m_bMenuMapActive)
return 255;
#endif
if (dist <= 1.0f)
return 255;
@ -486,9 +485,7 @@ void CRadar::DrawBlips()
CVector2D in = CVector2D(0.0f, 0.0f);
TransformRadarPointToScreenSpace(out, in);
#ifdef MENU_MAP
if (!FrontEndMenuManager.m_bMenuMapActive) {
#endif
float angle;
if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN)
angle = PI + FindPlayerHeading();
@ -508,9 +505,7 @@ void CRadar::DrawBlips()
LimitRadarPoint(in);
TransformRadarPointToScreenSpace(out, in);
DrawRadarSprite(RADAR_SPRITE_NORTH, out.x, out.y, 255);
#ifdef MENU_MAP
}
#endif
CEntity *blipEntity = nil;
for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
@ -743,14 +738,12 @@ void CRadar::DrawBlips()
break;
}
}
#ifdef MENU_MAP
if (FrontEndMenuManager.m_bMenuMapActive) {
CVector2D in, out;
TransformRealWorldPointToRadarSpace(in, FindPlayerCentreOfWorld_NoSniperShift());
TransformRadarPointToScreenSpace(out, in);
DrawYouAreHereSprite(out.x, out.y);
}
#endif
}
}
@ -773,7 +766,8 @@ void CRadar::DrawMap()
m_radarRange = RADAR_MIN_RANGE;
vec2DRadarOrigin = CVector2D(FindPlayerCentreOfWorld_NoSniperShift());
DrawRadarMap();
if (FrontEndMenuManager.m_PrefsRadarMode != 1)
DrawRadarMap();
}
}
@ -784,8 +778,8 @@ void CRadar::DrawRadarMap()
DrawRadarMask();
// top left ist (0, 0)
int x = floorf((vec2DRadarOrigin.x - RADAR_MIN_X) / RADAR_TILE_SIZE);
int y = ceilf((RADAR_NUM_TILES - 1) - (vec2DRadarOrigin.y - RADAR_MIN_Y) / RADAR_TILE_SIZE);
int x = Floor((vec2DRadarOrigin.x - RADAR_MIN_X) / RADAR_TILE_SIZE);
int y = Ceil((RADAR_NUM_TILES - 1) - (vec2DRadarOrigin.y - RADAR_MIN_Y) / RADAR_TILE_SIZE);
StreamRadarSections(x, y);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
@ -898,7 +892,7 @@ void CRadar::DrawRadarSection(int32 x, int32 y)
void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha)
{
RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha));
#ifdef MENU_MAP
if (FrontEndMenuManager.m_bMenuMapActive) {
bool alreadyThere = false;
for (int i = 0; i < NUM_MAP_LEGENDS; i++) {
@ -910,7 +904,6 @@ void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha)
MapLegendCounter++;
}
}
#endif
}
void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha)
@ -1046,10 +1039,10 @@ float CRadar::LimitRadarPoint(CVector2D &point)
float dist, invdist;
dist = point.Magnitude();
#ifdef MENU_MAP
if (FrontEndMenuManager.m_bMenuMapActive)
return dist;
#endif
if (dist > 1.0f) {
invdist = 1.0f / dist;
point.x *= invdist;
@ -1130,7 +1123,7 @@ void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size)
INITSAVEBUF
WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE);
#ifdef MENU_MAP
#ifdef MAP_ENHANCEMENTS
if (TargetMarkerId != -1) {
ClearBlip(TargetMarkerId);
TargetMarkerId = -1;
@ -1276,7 +1269,8 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red,
CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha));
break;
}
#ifdef MENU_MAP
// TODO(Miami): Map
// VC uses -1 for coords and -2 for entities but meh, I don't want to edit DrawBlips
if (FrontEndMenuManager.m_bMenuMapActive) {
bool alreadyThere = false;
@ -1290,7 +1284,6 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red,
ArrowBlipColour1 = CRGBA(red, green, blue, alpha);
}
}
#endif
}
void CRadar::Shutdown()
@ -1339,7 +1332,7 @@ void CRadar::Shutdown()
void CRadar::StreamRadarSections(const CVector &posn)
{
StreamRadarSections(floorf((2000.0f + posn.x) / 500.0f), ceilf(7.0f - (2000.0f + posn.y) / 500.0f));
StreamRadarSections(Floor((2000.0f + posn.x) / 500.0f), Ceil(7.0f - (2000.0f + posn.y) / 500.0f));
}
void CRadar::StreamRadarSections(int32 x, int32 y)
@ -1402,13 +1395,10 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D
// Radar space goes from -1.0 to 1.0 in x and y, top right is (1.0, 1.0)
void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in)
{
#ifdef MENU_MAP
if (FrontEndMenuManager.m_bMenuMapActive) {
out.x = (FrontEndMenuManager.m_fMapCenterX - FrontEndMenuManager.m_fMapSize) + (MENU_MAP_LENGTH / 2 + MENU_MAP_LEFT_OFFSET + in.x) * FrontEndMenuManager.m_fMapSize * MENU_MAP_WIDTH_SCALE * 2.0f / MENU_MAP_LENGTH;
out.y = (FrontEndMenuManager.m_fMapCenterY - FrontEndMenuManager.m_fMapSize) + (MENU_MAP_LENGTH / 2 - MENU_MAP_TOP_OFFSET - in.y) * FrontEndMenuManager.m_fMapSize * MENU_MAP_HEIGHT_SCALE * 2.0f / MENU_MAP_LENGTH;
} else
#endif
{
} else {
#ifdef FIX_BUGS
out.x = (in.x + 1.0f) * 0.5f * SCREEN_SCALE_X(RADAR_WIDTH) + SCREEN_SCALE_X(RADAR_LEFT);
#else
@ -1462,10 +1452,7 @@ void
CRadar::CalculateCachedSinCos()
{
if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED
#ifdef MENU_MAP
|| FrontEndMenuManager.m_bMenuMapActive
#endif
) {
|| FrontEndMenuManager.m_bMenuMapActive ) {
cachedSin = 0.0f;
cachedCos = 1.0f;
} else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) {
@ -1486,7 +1473,6 @@ CRadar::CalculateCachedSinCos()
}
}
#ifdef MENU_MAP
void
CRadar::InitFrontEndMap()
{
@ -1530,6 +1516,7 @@ CRadar::DrawYouAreHereSprite(float x, float y)
MapLegendList[MapLegendCounter++] = RADAR_SPRITE_CENTRE;
}
#ifdef MAP_ENHANCEMENTS
void
CRadar::ToggleTargetMarker(float x, float y)
{

View File

@ -21,6 +21,8 @@
#define COORDBLIP_MARKER_COLOR_B 242
#define COORDBLIP_MARKER_COLOR_A 255
#define NUM_MAP_LEGENDS 75
#define MENU_MAP_LENGTH_UNIT 1190.0f // in game unit
#define MENU_MAP_WIDTH_SCALE 1.112f // in game unit (originally 1.112494151260504f)
#define MENU_MAP_HEIGHT_SCALE 1.119f // in game unit (originally 1.118714268907563f)
@ -48,10 +50,8 @@ enum eBlipDisplay
enum eRadarSprite
{
#ifdef MENU_MAP
RADAR_SPRITE_ENTITY_BLIP = -2,
RADAR_SPRITE_COORD_BLIP = -1,
#endif
RADAR_SPRITE_NONE = 0,
RADAR_SPRITE_CENTRE,
RADAR_SPRITE_MAP_HERE,
@ -173,17 +173,19 @@ public:
static CSprite2d *RadarSprites[RADAR_SPRITE_COUNT];
static float cachedCos;
static float cachedSin;
#ifdef MENU_MAP
#define NUM_MAP_LEGENDS 75
static CRGBA ArrowBlipColour1;
static CRGBA ArrowBlipColour2;
static int16 MapLegendList[NUM_MAP_LEGENDS];
static uint16 MapLegendCounter;
#ifdef MAP_ENHANCEMENTS
static int TargetMarkerId;
static CVector TargetMarkerPos;
#endif
static void InitFrontEndMap();
static void DrawYouAreHereSprite(float, float);
#ifdef MAP_ENHANCEMENTS
static void ToggleTargetMarker(float, float);
#endif
static uint8 CalculateBlipAlpha(float dist);

173
src/core/Ropes.cpp Normal file
View File

@ -0,0 +1,173 @@
#include "common.h"
#include "Timer.h"
#include "ModelIndices.h"
#include "Streaming.h"
#include "CopPed.h"
#include "Population.h"
#include "RenderBuffer.h"
#include "Camera.h"
#include "Ropes.h"
CRope CRopes::aRopes[8];
RwImVertexIndex RopeIndices[64] = {
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15,
15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23,
23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31,
31, 32 // unused
};
void
CRope::Update(void)
{
int i;
float step = Pow(0.85f, CTimer::GetTimeStep());
if(!m_bWasRegistered && CTimer::GetTimeInMilliseconds() > m_updateTimer){
m_speed[0].z -= 0.0015f*CTimer::GetTimeStep();
m_pos[0] += m_speed[0]*CTimer::GetTimeStep();
}
for(i = 1; i < ARRAY_SIZE(m_pos); i++){
CVector prevPos = m_pos[i];
m_pos[i] += m_speed[i]*step*CTimer::GetTimeStep();
m_pos[i].z -= 0.05f*CTimer::GetTimeStep();
CVector dist = m_pos[i] - m_pos[i-1];
m_pos[i] = m_pos[i-1] + (0.625f/dist.Magnitude())*dist;
m_speed[i] = (m_pos[i] - prevPos)/CTimer::GetTimeStep();
}
if(!m_bWasRegistered && m_pos[0].z < 0.0f)
m_bActive = false;
m_bWasRegistered = false;
}
void
CRope::Render(void)
{
int i;
int numVerts = 0;
if(!TheCamera.IsSphereVisible(m_pos[16], 20.0f))
return;
for(i = 0; i < ARRAY_SIZE(m_pos); i++){
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[i], 128, 128, 128, 100);
RwIm3DVertexSetPos(&TempBufferRenderVertices[i], m_pos[i].x, m_pos[i].y, m_pos[i].z);
}
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
if(RwIm3DTransform(TempBufferRenderVertices, ARRAY_SIZE(m_pos), nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXRGBA)){
#ifdef FIX_BUGS
RwIm3DRenderIndexedPrimitive(rwPRIMTYPELINELIST, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1));
#else
RwIm3DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1));
#endif
RwIm3DEnd();
}
}
void
CRopes::Init(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
aRopes[i].m_bActive = false;
}
void
CRopes::Update(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive)
aRopes[i].Update();
}
void
CRopes::Render(void)
{
int i;
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive)
aRopes[i].Render();
}
bool
CRopes::RegisterRope(uintptr id, CVector pos, bool setUpdateTimer)
{
int i, j;
for(i = 0; i < ARRAY_SIZE(aRopes); i++){
if(aRopes[i].m_bActive && aRopes[i].m_id == id){
aRopes[i].m_pos[0] = pos;
aRopes[i].m_speed[0] = CVector(0.0f, 0.0f, 0.0f);
aRopes[i].m_bWasRegistered = true;
return true;
}
}
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(!aRopes[i].m_bActive){
aRopes[i].m_id = id;
aRopes[i].m_pos[0] = pos;
aRopes[i].m_speed[0] = CVector(0.0f, 0.0f, 0.0f);
aRopes[i].m_unk = false;
aRopes[i].m_bWasRegistered = true;
aRopes[i].m_updateTimer = setUpdateTimer ? CTimer::GetTimeInMilliseconds() + 20000 : 0;
for(j = 1; j < ARRAY_SIZE(CRope::m_pos); j++){
if(j & 1)
aRopes[i].m_pos[j] = aRopes[i].m_pos[j-1] + CVector(0.0f, 0.0f, 0.625f);
else
aRopes[i].m_pos[j] = aRopes[i].m_pos[j-1] - CVector(0.0f, 0.0f, 0.625f);
aRopes[i].m_speed[j] = CVector(0.0f, 0.0f, 0.0f);
}
aRopes[i].m_bActive = true;
return true;
}
return false;
}
void
CRopes::SetSpeedOfTopNode(uintptr id, CVector speed)
{
int i;
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive && aRopes[i].m_id == id){
aRopes[i].m_speed[0] = speed;
return;
}
}
bool
CRopes::FindCoorsAlongRope(uintptr id, float t, CVector *coors)
{
int i, j;
float f;
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive && aRopes[i].m_id == id){
t = (ARRAY_SIZE(CRope::m_pos)-1)*clamp(t, 0.0f, 0.999f);
j = t;
f = t - j;
*coors = (1.0f-f)*aRopes[i].m_pos[j] + f*aRopes[i].m_pos[j+1];
return true;
}
return false;
}
bool
CRopes::CreateRopeWithSwatComingDown(CVector pos)
{
static uint32 ropeId = 0;
if(!CStreaming::HasModelLoaded(MI_SWAT) || !RegisterRope(ropeId+100, pos, true))
return false;
CCopPed *swat = (CCopPed*)CPopulation::AddPed(PEDTYPE_COP, COP_HELI_SWAT, pos);
swat->bUsesCollision = false;
swat->m_pRopeEntity = (CEntity*)1;
swat->m_nRopeID = 100 + ropeId;
CAnimManager::BlendAnimation(swat->GetClump(), ASSOCGRP_STD, ANIM_ABSEIL, 4.0f);
ropeId++;
return true;
}

31
src/core/Ropes.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
class CRope
{
public:
bool m_bActive;
bool m_bWasRegistered;
bool m_unk;
uintptr m_id;
uint32 m_updateTimer;
CVector m_pos[32];
CVector m_speed[32];
void Update(void);
void Render(void);
};
class CRopes
{
static CRope aRopes[8];
public:
static void Init(void);
static void Update(void);
static void Render(void);
static bool RegisterRope(uintptr id, CVector pos, bool setUpdateTimer);
static void SetSpeedOfTopNode(uintptr id, CVector speed);
static bool FindCoorsAlongRope(uintptr id, float t, CVector *coors);
static bool CreateRopeWithSwatComingDown(CVector pos);
};

View File

@ -21,8 +21,8 @@ int32 CStats::PedsKilledOfThisType[NUM_PEDTYPES];
int32 CStats::TimesDied;
int32 CStats::TimesArrested;
int32 CStats::KillsSinceLastCheckpoint;
int32 CStats::DistanceTravelledInVehicle;
int32 CStats::DistanceTravelledOnFoot;
float CStats::DistanceTravelledInVehicle;
float CStats::DistanceTravelledOnFoot;
int32 CStats::ProgressMade;
int32 CStats::TotalProgressInGame;
int32 CStats::CarsExploded;
@ -49,7 +49,6 @@ int32 CStats::LivesSavedWithAmbulance;
int32 CStats::CriminalsCaught;
int32 CStats::HighestLevelAmbulanceMission;
int32 CStats::FiresExtinguished;
int32 CStats::LongestFlightInDodo;
int32 CStats::TimeTakenDefuseMission;
int32 CStats::TotalNumberKillFrenzies;
int32 CStats::TotalNumberMissions;
@ -58,8 +57,6 @@ int32 CStats::KgsOfExplosivesUsed;
int32 CStats::InstantHitsFiredByPlayer;
int32 CStats::InstantHitsHitByPlayer;
int32 CStats::BestTimeBombDefusal;
int32 CStats::mmRain;
int32 CStats::CarsCrushed;
int32 CStats::FastestTimes[CStats::TOTAL_FASTEST_TIMES];
int32 CStats::HighestScores[CStats::TOTAL_HIGHEST_SCORES];
int32 CStats::BestPositions[CStats::TOTAL_BEST_POSITIONS];
@ -83,13 +80,11 @@ void CStats::Init()
KgsOfExplosivesUsed = 0;
InstantHitsFiredByPlayer = 0;
InstantHitsHitByPlayer = 0;
CarsCrushed = 0;
HeadsPopped = 0;
TimesArrested = 0;
TimesDied = 0;
DaysPassed = 0;
NumberOfUniqueJumpsFound = 0;
mmRain = 0;
MaximumJumpFlips = 0;
MaximumJumpSpins = 0;
MaximumJumpDistance = 0;
@ -97,7 +92,6 @@ void CStats::Init()
BestStuntJump = 0;
TotalNumberOfUniqueJumps = 0;
Record4x4One = 0;
LongestFlightInDodo = 0;
Record4x4Two = 0;
PassengersDroppedOffWithTaxi = 0;
Record4x4Three = 0;
@ -202,11 +196,6 @@ void CStats::AnotherFireExtinguished()
++FiresExtinguished;
}
void CStats::RegisterLongestFlightInDodo(int32 time)
{
LongestFlightInDodo = Max(LongestFlightInDodo, time);
}
void CStats::RegisterTimeTakenDefuseMission(int32 time)
{
TimeTakenDefuseMission = (TimeTakenDefuseMission && TimeTakenDefuseMission < time) ? TimeTakenDefuseMission : time;
@ -296,12 +285,10 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
sizeof(KgsOfExplosivesUsed) +
sizeof(InstantHitsFiredByPlayer) +
sizeof(InstantHitsHitByPlayer) +
sizeof(CarsCrushed) +
sizeof(HeadsPopped) +
sizeof(TimesArrested) +
sizeof(TimesDied) +
sizeof(DaysPassed) +
sizeof(mmRain) +
sizeof(MaximumJumpDistance) +
sizeof(MaximumJumpHeight) +
sizeof(MaximumJumpFlips) +
@ -327,7 +314,6 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
sizeof(CriminalsCaught) +
sizeof(HighestLevelAmbulanceMission) +
sizeof(FiresExtinguished) +
sizeof(LongestFlightInDodo) +
sizeof(TimeTakenDefuseMission) +
sizeof(NumberKillFrenziesPassed) +
sizeof(TotalNumberKillFrenzies) +
@ -351,12 +337,10 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
CopyToBuf(buf, KgsOfExplosivesUsed);
CopyToBuf(buf, InstantHitsFiredByPlayer);
CopyToBuf(buf, InstantHitsHitByPlayer);
CopyToBuf(buf, CarsCrushed);
CopyToBuf(buf, HeadsPopped);
CopyToBuf(buf, TimesArrested);
CopyToBuf(buf, TimesDied);
CopyToBuf(buf, DaysPassed);
CopyToBuf(buf, mmRain);
CopyToBuf(buf, MaximumJumpDistance);
CopyToBuf(buf, MaximumJumpHeight);
CopyToBuf(buf, MaximumJumpFlips);
@ -382,7 +366,6 @@ void CStats::SaveStats(uint8 *buf, uint32 *size)
CopyToBuf(buf, CriminalsCaught);
CopyToBuf(buf, HighestLevelAmbulanceMission);
CopyToBuf(buf, FiresExtinguished);
CopyToBuf(buf, LongestFlightInDodo);
CopyToBuf(buf, TimeTakenDefuseMission);
CopyToBuf(buf, NumberKillFrenziesPassed);
CopyToBuf(buf, TotalNumberKillFrenzies);
@ -415,12 +398,10 @@ void CStats::LoadStats(uint8 *buf, uint32 size)
CopyFromBuf(buf, KgsOfExplosivesUsed);
CopyFromBuf(buf, InstantHitsFiredByPlayer);
CopyFromBuf(buf, InstantHitsHitByPlayer);
CopyFromBuf(buf, CarsCrushed);
CopyFromBuf(buf, HeadsPopped);
CopyFromBuf(buf, TimesArrested);
CopyFromBuf(buf, TimesDied);
CopyFromBuf(buf, DaysPassed);
CopyFromBuf(buf, mmRain);
CopyFromBuf(buf, MaximumJumpDistance);
CopyFromBuf(buf, MaximumJumpHeight);
CopyFromBuf(buf, MaximumJumpFlips);
@ -446,7 +427,6 @@ void CStats::LoadStats(uint8 *buf, uint32 size)
CopyFromBuf(buf, CriminalsCaught);
CopyFromBuf(buf, HighestLevelAmbulanceMission);
CopyFromBuf(buf, FiresExtinguished);
CopyFromBuf(buf, LongestFlightInDodo);
CopyFromBuf(buf, TimeTakenDefuseMission);
CopyFromBuf(buf, NumberKillFrenziesPassed);
CopyFromBuf(buf, TotalNumberKillFrenzies);

View File

@ -25,8 +25,8 @@ public:
static int32 TimesDied;
static int32 TimesArrested;
static int32 KillsSinceLastCheckpoint;
static int32 DistanceTravelledInVehicle;
static int32 DistanceTravelledOnFoot;
static float DistanceTravelledInVehicle;
static float DistanceTravelledOnFoot;
static int32 CarsExploded;
static int32 PeopleKilledByPlayer;
static int32 ProgressMade;
@ -53,7 +53,6 @@ public:
static int32 CriminalsCaught;
static int32 HighestLevelAmbulanceMission;
static int32 FiresExtinguished;
static int32 LongestFlightInDodo;
static int32 TimeTakenDefuseMission;
static int32 TotalNumberKillFrenzies;
static int32 TotalNumberMissions;
@ -62,8 +61,6 @@ public:
static int32 InstantHitsFiredByPlayer;
static int32 InstantHitsHitByPlayer;
static int32 BestTimeBombDefusal;
static int32 mmRain;
static int32 CarsCrushed;
static int32 FastestTimes[TOTAL_FASTEST_TIMES];
static int32 HighestScores[TOTAL_HIGHEST_SCORES];
static int32 BestPositions[TOTAL_BEST_POSITIONS];
@ -90,7 +87,6 @@ public:
static void RegisterLevelAmbulanceMission(int32);
static void AnotherFireExtinguished();
static wchar *FindCriminalRatingString();
static void RegisterLongestFlightInDodo(int32);
static void RegisterTimeTakenDefuseMission(int32);
static void AnotherKillFrenzyPassed();
static void SetTotalNumberKillFrenzies(int32);

View File

@ -44,7 +44,7 @@ int32 CStreaming::ms_oldSectorX;
int32 CStreaming::ms_oldSectorY;
int32 CStreaming::ms_streamingBufferSize;
int8 *CStreaming::ms_pStreamingBuffer[2];
int32 CStreaming::ms_memoryUsed;
size_t CStreaming::ms_memoryUsed;
CStreamingChannel CStreaming::ms_channel[2];
int32 CStreaming::ms_channelError;
int32 CStreaming::ms_numVehiclesLoaded;
@ -61,7 +61,7 @@ uint16 CStreaming::ms_loadedGangCars;
int32 CStreaming::ms_imageOffsets[NUMCDIMAGES];
int32 CStreaming::ms_lastImageRead;
int32 CStreaming::ms_imageSize;
uint32 CStreaming::ms_memoryAvailable;
size_t CStreaming::ms_memoryAvailable;
int32 desiredNumVehiclesLoaded = 12;
@ -200,9 +200,9 @@ CStreaming::Init2(void)
debug("Streaming buffer size is %d sectors", ms_streamingBufferSize);
#define MB (1024*1024)
ms_memoryAvailable = 65*MB;
ms_memoryAvailable = 65 * MB;
desiredNumVehiclesLoaded = 25;
debug("Memory allocated to Streaming is %dMB", ms_memoryAvailable/MB);
debug("Memory allocated to Streaming is %dMB", ms_memoryAvailable / MB);
#undef MB
// find island LODs
@ -723,7 +723,11 @@ CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos)
n = CPools::GetBuildingPool()->GetSize()-1;
for(i = n; i >= 0; i--){
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding && b->m_level == level)
if(b && b->bIsBIGBuilding
#ifndef NO_ISLAND_LOADING
&& b->m_level == level
#endif
)
if(b->bStreamBIGBuilding){
if(CRenderer::ShouldModelBeStreamed(b, pos))
RequestModel(b->GetModelIndex(), 0);
@ -795,6 +799,7 @@ CStreaming::InstanceLoadedModels(const CVector &pos)
void
CStreaming::RequestIslands(eLevelName level)
{
#ifndef NO_ISLAND_LOADING
switch(level){
case LEVEL_MAINLAND:
if(islandLODbeach != -1)
@ -806,6 +811,7 @@ CStreaming::RequestIslands(eLevelName level)
break;
default: break;
}
#endif
}
//--MIAMI: TODO
@ -1010,10 +1016,12 @@ CStreaming::RemoveBuildings(eLevelName level)
void
CStreaming::RemoveUnusedBigBuildings(eLevelName level)
{
#ifndef NO_ISLAND_LOADING
if(level != LEVEL_BEACH)
RemoveBigBuildings(LEVEL_BEACH);
if(level != LEVEL_MAINLAND)
RemoveBigBuildings(LEVEL_MAINLAND);
#endif
RemoveIslandsNotUsed(level);
}
@ -1035,6 +1043,7 @@ DeleteIsland(CEntity *island)
void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
#ifndef NO_ISLAND_LOADING
int i;
if(pIslandLODmainlandEntity == nil)
for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
@ -1053,8 +1062,10 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level)
break;
case LEVEL_BEACH:
DeleteIsland(pIslandLODbeachEntity);
break;
}
#endif // !NO_ISLAND_LOADING
}
//--MIAMI: done
@ -1380,11 +1391,11 @@ CStreaming::StreamVehiclesAndPeds(void)
}
if(FindPlayerPed()->m_pWanted->AreFbiRequired()){
RequestModel(MI_FBICAR, STREAMFLAGS_DONT_REMOVE);
RequestModel(MI_FBIRANCH, STREAMFLAGS_DONT_REMOVE);
RequestModel(MI_FBI, STREAMFLAGS_DONT_REMOVE);
}else{
SetModelIsDeletable(MI_FBICAR);
if(!HasModelLoaded(MI_FBICAR))
SetModelIsDeletable(MI_FBIRANCH);
if(!HasModelLoaded(MI_FBIRANCH))
SetModelIsDeletable(MI_FBI);
}
@ -1594,7 +1605,7 @@ CStreaming::LoadBigBuildingsWhenNeeded(void)
if(CCutsceneMgr::IsCutsceneProcessing())
return;
if(CTheZones::m_CurrLevel == LEVEL_NONE ||
if(CTheZones::m_CurrLevel == LEVEL_GENERIC ||
CTheZones::m_CurrLevel == CGame::currLevel)
return;
@ -1612,7 +1623,7 @@ CStreaming::LoadBigBuildingsWhenNeeded(void)
CGame::TidyUpMemory(true, true);
CReplay::EmptyReplayBuffer();
if(CGame::currLevel != LEVEL_NONE)
if(CGame::currLevel != LEVEL_GENERIC)
LoadSplash(GetLevelSplashScreen(CGame::currLevel));
CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
@ -2374,7 +2385,7 @@ CStreaming::DeleteRwObjectsAfterDeath(const CVector &pos)
}
void
CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
{
int ix, iy;
int x, y;
@ -2549,7 +2560,7 @@ CStreaming::DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y)
}
bool
CStreaming::DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, int32 mem)
CStreaming::DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem)
{
CPtrNode *node;
CEntity *e;
@ -2570,7 +2581,7 @@ CStreaming::DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, int32 mem)
}
bool
CStreaming::DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, int32 mem)
CStreaming::DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem)
{
CPtrNode *node;
CEntity *e;
@ -2597,7 +2608,7 @@ CStreaming::MakeSpaceFor(int32 size)
// the code still happens to work in that case because ms_memoryAvailable is unsigned
// but it's not nice....
while((uint32)ms_memoryUsed >= ms_memoryAvailable - size)
while(ms_memoryUsed >= ms_memoryAvailable - size)
if(!RemoveLeastUsedModel(STREAMFLAGS_20)){
DeleteRwObjectsBehindCamera(ms_memoryAvailable - size);
return;
@ -2620,16 +2631,16 @@ CStreaming::LoadScene(const CVector &pos)
}
CRenderer::m_loadingPriority = false;
DeleteAllRwObjects();
if(level == LEVEL_NONE)
if(level == LEVEL_GENERIC)
level = CGame::currLevel;
CGame::currLevel = level;
RemoveUnusedBigBuildings(level);
RequestBigBuildings(level, pos);
RequestBigBuildings(LEVEL_NONE, pos);
RequestBigBuildings(LEVEL_GENERIC, pos);
RemoveIslandsNotUsed(level);
LoadAllRequestedModels(false);
InstanceBigBuildings(level, pos);
InstanceBigBuildings(LEVEL_NONE, pos);
InstanceBigBuildings(LEVEL_GENERIC, pos);
AddModelsToRequestList(pos);
CRadar::StreamRadarSections(pos);
@ -2688,7 +2699,8 @@ CStreaming::UpdateForAnimViewer(void)
if (CStreaming::ms_channelError == -1) {
CStreaming::AddModelsToRequestList(CVector(0.0f, 0.0f, 0.0f));
CStreaming::LoadRequestedModels();
sprintf(gString, "Requested %d, memory size %dK\n", CStreaming::ms_numModelsRequested, 2 * CStreaming::ms_memoryUsed);
// original modifier was %d
sprintf(gString, "Requested %d, memory size %zuK\n", CStreaming::ms_numModelsRequested, 2 * CStreaming::ms_memoryUsed);
}
else {
CStreaming::RetryLoadFile(CStreaming::ms_channelError);

View File

@ -89,7 +89,7 @@ public:
static int32 ms_oldSectorY;
static int32 ms_streamingBufferSize;
static int8 *ms_pStreamingBuffer[2];
static int32 ms_memoryUsed;
static size_t ms_memoryUsed;
static CStreamingChannel ms_channel[2];
static int32 ms_channelError;
static int32 ms_numVehiclesLoaded;
@ -106,7 +106,7 @@ public:
static int32 ms_imageOffsets[NUMCDIMAGES];
static int32 ms_lastImageRead;
static int32 ms_imageSize;
static uint32 ms_memoryAvailable;
static size_t ms_memoryAvailable;
static void Init(void);
static void Init2(void);
@ -193,11 +193,11 @@ public:
static void DeleteFarAwayRwObjects(const CVector &pos);
static void DeleteAllRwObjects(void);
static void DeleteRwObjectsAfterDeath(const CVector &pos);
static void DeleteRwObjectsBehindCamera(int32 mem);
static void DeleteRwObjectsBehindCamera(size_t mem);
static void DeleteRwObjectsInSectorList(CPtrList &list);
static void DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y);
static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, int32 mem);
static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, int32 mem);
static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem);
static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem);
static void LoadScene(const CVector &pos);
static void LoadSceneCollision(const CVector &pos);

View File

@ -53,6 +53,41 @@ enum
struct CColPoint;
inline bool
IsSeeThrough(uint8 surfType)
{
switch(surfType)
case SURFACE_GLASS:
case SURFACE_TRANSPARENT_CLOTH:
case SURFACE_METAL_CHAIN_FENCE:
case SURFACE_TRANSPARENT_STONE:
case SURFACE_SCAFFOLD_POLE:
return true;
return false;
}
// I think the necessity of this function is really a bug
inline bool
IsSeeThroughVertical(uint8 surfType)
{
switch(surfType)
case SURFACE_GLASS:
case SURFACE_TRANSPARENT_CLOTH:
return true;
return false;
}
inline bool
IsShootThrough(uint8 surfType)
{
switch(surfType)
case SURFACE_METAL_CHAIN_FENCE:
case SURFACE_TRANSPARENT_STONE:
case SURFACE_SCAFFOLD_POLE:
return true;
return false;
}
class CSurfaceTable
{
static float ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];

View File

@ -37,19 +37,19 @@ CTempColModels::Initialise(void)
#define SET_COLMODEL_SPHERES(colmodel, sphrs)\
colmodel.numSpheres = ARRAY_SIZE(sphrs);\
colmodel.spheres = sphrs;\
colmodel.level = LEVEL_NONE;\
colmodel.level = LEVEL_GENERIC;\
colmodel.ownsCollisionVolumes = false;\
int i;
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));
ms_colModelBBox.level = LEVEL_NONE;
ms_colModelBBox.level = LEVEL_GENERIC;
for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) {
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));
ms_colModelCutObj[i].level = LEVEL_NONE;
ms_colModelCutObj[i].level = LEVEL_GENERIC;
}
// Ped Spheres

View File

@ -74,6 +74,14 @@ CPlaceName::Display()
CHud::SetZoneName(text);
}
void
CPlaceName::ProcessAfterFrontEndShutDown(void)
{
CHud::m_pLastZoneName = nil;
CHud::m_ZoneState = 0;
m_nAdditionalTimer = 250;
}
CCurrentVehicle::CCurrentVehicle()
{
Init();

View File

@ -16,6 +16,7 @@ public:
void Init();
void Process();
void Display();
void ProcessAfterFrontEndShutDown();
};
class CCurrentVehicle

View File

@ -182,7 +182,7 @@ CWanted::RegisterCrime(eCrimeType type, const CVector &coors, uint32 id, bool po
void
CWanted::RegisterCrime_Immediately(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare)
{
#ifdef FIX_BUGS
#ifdef FIX_SIGNIFICANT_BUGS
if(!AddCrimeToQ(type, id, coors, true, policeDoesntCare))
#else
if(!AddCrimeToQ(type, id, coors, false, policeDoesntCare))

View File

@ -1785,7 +1785,7 @@ CWorld::ClearForRestart(void)
CWorld::Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = GetBigBuildingList(LEVEL_NONE).first; pNode; pNode = pNode->next) {
for(CPtrNode *pNode = GetBigBuildingList(LEVEL_GENERIC).first; pNode; pNode = pNode->next) {
CVehicle *pVehicle = (CVehicle *)pNode->item;
if(pVehicle && pVehicle->IsVehicle() && pVehicle->IsPlane()) {
CWorld::Remove(pVehicle);

View File

@ -93,7 +93,7 @@ CTheZones::Init(void)
InfoZoneArray[0].maxx = 1600.0f;
InfoZoneArray[0].maxy = 2000.0f;
InfoZoneArray[0].maxz = 500.0f;
InfoZoneArray[0].level = LEVEL_NONE;
InfoZoneArray[0].level = LEVEL_GENERIC;
InfoZoneArray[0].type = ZONE_INFO;
strcpy(NavigationZoneArray[0].name, "VICE_C");
@ -103,10 +103,10 @@ CTheZones::Init(void)
NavigationZoneArray[0].maxx = 1600.0f;
NavigationZoneArray[0].maxy = 2000.0f;
NavigationZoneArray[0].maxz = 500.0f;
NavigationZoneArray[0].level = LEVEL_NONE;
NavigationZoneArray[0].type = ZONE_NAVIG;
NavigationZoneArray[0].level = LEVEL_GENERIC;
NavigationZoneArray[0].type = ZONE_DEFAULT;
m_CurrLevel = LEVEL_NONE;
m_CurrLevel = LEVEL_GENERIC;
for(i = 0; i < NUMMAPZONES; i++){
memset(&MapZoneArray[i], 0, sizeof(CZone));
@ -120,7 +120,7 @@ CTheZones::Init(void)
MapZoneArray[0].maxx = 1600.0f;
MapZoneArray[0].maxy = 2000.0f;
MapZoneArray[0].maxz = 500.0f;
MapZoneArray[0].level = LEVEL_NONE;
MapZoneArray[0].level = LEVEL_GENERIC;
}
//--MIAMI: done

View File

@ -17,7 +17,11 @@
#if defined _WIN32 && defined WITHD3D
#include <windows.h>
#ifndef USE_D3D9
#include <d3d8types.h>
#else
#include <d3d9types.h>
#endif
#endif
#include <rwcore.h>
@ -37,6 +41,7 @@
#define HIERNODEINFO(hier) ((hier)->pNodeInfo)
#define HIERNODEID(hier, i) ((hier)->pNodeInfo[i].nodeID)
#define HANIMFRAME(anim, i) ((RwUInt8*)(anim)->pFrames + (i)*(anim)->interpInfo->keyFrameSize)
#define RpHAnimStdInterpFrame RpHAnimStdKeyFrame
#endif
#ifdef RWHALFPIXEL

View File

@ -54,7 +54,7 @@ enum Config {
NUMBOATALPHALIST = 20,
NUMALPHAENTITYLIST = 200,
NUMALPHAUNTERWATERENTITYLIST = 30,
NUMCOLCACHELINKS = 200,
NUMCOLCACHELINKS = 50,
NUMREFERENCES = 800,
// Zones
@ -67,6 +67,7 @@ enum Config {
NUMATTRIBZONES = 704,
NUMOCCLUSIONVOLUMES = 350,
NUMACTIVEOCCLUDERS = 48,
PATHNODESIZE = 4500,
@ -165,6 +166,7 @@ enum Config {
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
# define COMPRESSED_COL_VECTORS
#elif defined GTA_PC
# define GTA3_1_1_PATCH
//# define GTA3_STEAM_PATCH
@ -213,7 +215,10 @@ enum Config {
#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
#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 NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
//#define USE_TEXTURE_POOL
#define CUTSCENE_BORDERS_SWITCH
// Water & Particle
#define PC_PARTICLE
@ -242,8 +247,7 @@ enum Config {
//# define PS2_MENU_USEALLPAGEICONS
#else
//# define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc.
# define MENU_MAP // VC-like menu map. Make sure you have new menu.txd
# define SCROLLABLE_STATS_PAGE // only draggable by mouse atm
# define MAP_ENHANCEMENTS // Adding waypoint etc.
# define TRIANGLE_BACK_BUTTON
//# define CIRCLE_BACK_BUTTON
//#define CUSTOM_FRONTEND_OPTIONS
@ -257,7 +261,7 @@ enum Config {
//#define MISSION_REPLAY // mobile feature
#endif
//#define SIMPLIER_MISSIONS // apply simplifications from mobile
//#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define SCRIPT_LOG_FILE_LEVEL 1 // 0 == no log, 1 == overwrite every frame, 2 == full log
#ifndef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
@ -270,7 +274,7 @@ enum Config {
// Vehicles
#define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher
//#define REMOVE_TREADABLE_PATHFIND
#define CPLANE_ROTORS // make the rotors of the NPC police heli rotate
// Pickups
//#define MONEY_MESSAGES
@ -286,3 +290,6 @@ enum Config {
// Camera
#define IMPROVED_CAMERA // Better Debug cam, and maybe more in the future
#define FREE_CAM // Rotating cam
// Audio
#define AUDIO_CACHE // cache sound lengths to speed up the cold boot

View File

@ -61,6 +61,8 @@
#include "MemoryCard.h"
#include "SceneEdit.h"
#include "debugmenu.h"
#include "Occlusion.h"
#include "Ropes.h"
GlobalScene Scene;
@ -249,7 +251,11 @@ DoFade(void)
}
// This is CCamera::GetScreenRect in VC
if(TheCamera.m_WideScreenOn){
if(TheCamera.m_WideScreenOn
#ifdef CUTSCENE_BORDERS_SWITCH
&& CMenuManager::m_PrefsCutsceneBorders
#endif
){
float y = SCREEN_HEIGHT/2 * TheCamera.m_ScreenReductionPercentage/100.0f;
rect.left = 0.0f;
rect.right = SCREEN_WIDTH;
@ -299,7 +305,12 @@ PluginAttach(void)
return FALSE;
}
#ifndef LIBRW
if (!RtAnimInitialize())
{
return FALSE;
}
#endif
if( !RpHAnimPluginAttach() )
{
printf("Couldn't attach RpHAnim plugin\n");
@ -464,6 +475,11 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
{
CSprite2d *splash;
#ifdef DISABLE_LOADING_SCREEN
if (str1 && str2)
return;
#endif
#ifndef RANDOMSPLASH
splashscreen = "LOADSC0";
#endif
@ -858,6 +874,7 @@ RenderEffects(void)
CGlass::Render();
CWaterCannons::Render();
CSpecialFX::Render();
CRopes::Render();
CShadows::RenderStaticShadows();
CShadows::RenderStoredShadows();
CSkidmarks::Render();
@ -885,7 +902,11 @@ Render2dStuff(void)
CReplay::Display();
CPickups::RenderPickUpText();
if(TheCamera.m_WideScreenOn)
if(TheCamera.m_WideScreenOn
#ifdef CUTSCENE_BORDERS_SWITCH
&& CMenuManager::m_PrefsCutsceneBorders
#endif
)
TheCamera.DrawBordersForWideScreen();
CPed *player = FindPlayerPed();
@ -930,6 +951,7 @@ Render2dStuff(void)
CGarages::PrintMessages();
CPad::PrintErrorMessage();
CFont::DrawFonts();
COcclusion::Render();
#ifdef DEBUGMENU
DebugMenuRender();

View File

@ -1,94 +0,0 @@
#define WITHWINDOWS
#include "common.h"
#include "patcher.h"
#include <algorithm>
#include <vector>
StaticPatcher *StaticPatcher::ms_head;
StaticPatcher::StaticPatcher(Patcher func)
: m_func(func)
{
m_next = ms_head;
ms_head = this;
}
void
StaticPatcher::Apply()
{
StaticPatcher *current = ms_head;
while(current){
current->Run();
current = current->m_next;
}
ms_head = nil;
}
#ifdef _WIN32
std::vector<uint32> usedAddresses;
static DWORD protect[2];
static uint32 protect_address;
static uint32 protect_size;
void
Protect_internal(uint32 address, uint32 size)
{
protect_address = address;
protect_size = size;
VirtualProtect((void*)address, size, PAGE_EXECUTE_READWRITE, &protect[0]);
}
void
Unprotect_internal(void)
{
VirtualProtect((void*)protect_address, protect_size, protect[0], &protect[1]);
}
void
InjectHook_internal(uint32 address, uint32 hook, int type)
{
if(std::any_of(usedAddresses.begin(), usedAddresses.end(),
[address](uint32 value) { return value == address; })) {
debug("Used address %#06x twice when injecting hook\n", address);
}
usedAddresses.push_back(address);
switch(type){
case PATCH_JUMP:
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &protect[0]);
*(uint8*)address = 0xE9;
break;
case PATCH_CALL:
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &protect[0]);
*(uint8*)address = 0xE8;
break;
default:
VirtualProtect((void*)(address + 1), 4, PAGE_EXECUTE_READWRITE, &protect[0]);
break;
}
*(ptrdiff_t*)(address + 1) = hook - address - 5;
if(type == PATCH_NOTHING)
VirtualProtect((void*)(address + 1), 4, protect[0], &protect[1]);
else
VirtualProtect((void*)address, 5, protect[0], &protect[1]);
}
#else
void
Protect_internal(uint32 address, uint32 size)
{
}
void
Unprotect_internal(void)
{
}
void
InjectHook_internal(uint32 address, uint32 hook, int type)
{
}
#endif

View File

@ -1,144 +0,0 @@
#pragma once
#define WRAPPER __declspec(naked)
#define DEPRECATED __declspec(deprecated)
#define EAXJMP(a) { _asm mov eax, a _asm jmp eax }
#define VARJMP(a) { _asm jmp a }
#define WRAPARG(a) UNREFERENCED_PARAMETER(a)
#include <string.h> //memset
enum
{
PATCH_CALL,
PATCH_JUMP,
PATCH_NOTHING,
};
enum
{
III_10 = 1,
III_11,
III_STEAM,
VC_10,
VC_11,
VC_STEAM
};
extern int gtaversion;
class StaticPatcher
{
private:
using Patcher = void(*)();
Patcher m_func;
StaticPatcher *m_next;
static StaticPatcher *ms_head;
void Run() { m_func(); }
public:
StaticPatcher(Patcher func);
static void Apply();
};
template<typename T>
inline T AddressByVersion(uint32_t addressIII10, uint32_t addressIII11, uint32_t addressIIISteam, uint32_t addressvc10, uint32_t addressvc11, uint32_t addressvcSteam)
{
if(gtaversion == -1){
if(*(uint32_t*)0x5C1E75 == 0xB85548EC) gtaversion = III_10;
else if(*(uint32_t*)0x5C2135 == 0xB85548EC) gtaversion = III_11;
else if(*(uint32_t*)0x5C6FD5 == 0xB85548EC) gtaversion = III_STEAM;
else if(*(uint32_t*)0x667BF5 == 0xB85548EC) gtaversion = VC_10;
else if(*(uint32_t*)0x667C45 == 0xB85548EC) gtaversion = VC_11;
else if(*(uint32_t*)0x666BA5 == 0xB85548EC) gtaversion = VC_STEAM;
else gtaversion = 0;
}
switch(gtaversion){
case III_10:
return (T)addressIII10;
case III_11:
return (T)addressIII11;
case III_STEAM:
return (T)addressIIISteam;
case VC_10:
return (T)addressvc10;
case VC_11:
return (T)addressvc11;
case VC_STEAM:
return (T)addressvcSteam;
default:
return (T)0;
}
}
inline bool
is10(void)
{
return gtaversion == III_10 || gtaversion == VC_10;
}
inline bool
isIII(void)
{
return gtaversion >= III_10 && gtaversion <= III_STEAM;
}
inline bool
isVC(void)
{
return gtaversion >= VC_10 && gtaversion <= VC_STEAM;
}
#define PTRFROMCALL(addr) (uint32_t)(*(uint32_t*)((uint32_t)addr+1) + (uint32_t)addr + 5)
#define INTERCEPT(saved, func, a) \
{ \
saved = PTRFROMCALL(a); \
InjectHook(a, func); \
}
void InjectHook_internal(uint32 address, uint32 hook, int type);
void Protect_internal(uint32 address, uint32 size);
void Unprotect_internal(void);
template<typename T, typename AT> inline void
Patch(AT address, T value)
{
Protect_internal((uint32)address, sizeof(T));
*(T*)address = value;
Unprotect_internal();
}
template<typename AT> inline void
Nop(AT address, unsigned int nCount)
{
Protect_internal((uint32)address, nCount);
memset((void*)address, 0x90, nCount);
Unprotect_internal();
}
template <typename T> inline void
InjectHook(uintptr_t address, T hook, unsigned int nType = PATCH_NOTHING)
{
InjectHook_internal(address, reinterpret_cast<uintptr_t>((void *&)hook), nType);
}
inline void ExtractCall(void *dst, uint32_t a)
{
*(uint32_t*)dst = (uint32_t)(*(uint32_t*)(a+1) + a + 5);
}
template<typename T>
inline void InterceptCall(void *dst, T func, uint32_t a)
{
ExtractCall(dst, a);
InjectHook(a, func);
}
template<typename T>
inline void InterceptVmethod(void *dst, T func, uint32_t a)
{
*(uint32_t*)dst = *(uint32_t*)a;
Patch(a, func);
}
#define STARTPATCHES static StaticPatcher Patcher([](){
#define ENDPATCHES });

View File

@ -2,8 +2,8 @@
#define WITHWINDOWS
#include "common.h"
#include "crossplatform.h"
#include "patcher.h"
#include "Renderer.h"
#include "Occlusion.h"
#include "Credits.h"
#include "Camera.h"
#include "Weather.h"
@ -77,7 +77,6 @@ mysrand(unsigned int seed)
void ReloadFrontendOptions(void)
{
RemoveCustomFrontendOptions();
CustomFrontendOptionsPopulate();
}
@ -135,10 +134,20 @@ void ToggleFreeCam(int8 action)
}
#endif
#ifdef CUTSCENE_BORDERS_SWITCH
void BorderModeChange(int8 displayedValue)
{
CMenuManager::m_PrefsCutsceneBorders = !!displayedValue;
FrontEndMenuManager.SaveSettings();
}
#endif
// Reloaded on language change, so you can use hardcoded wchar* and TheText.Get with peace of mind
void
CustomFrontendOptionsPopulate(void)
{
RemoveCustomFrontendOptions(); // if exist
#ifdef MORE_LANGUAGES
FrontendOptionSetPosition(MENUPAGE_LANGUAGE_SETTINGS);
FrontendOptionAddDynamic(TheText.Get("FEL_POL"), nil, LangPolSelect, nil);
@ -152,16 +161,17 @@ CustomFrontendOptionsPopulate(void)
FrontendOptionAddSelect(TheText.Get("SCRFOR"), screenModes, 2, (int8*)&FrontEndMenuManager.m_nPrefsWindowed, true, ScreenModeChange, nil);
#endif
#ifdef MENU_MAP
FrontendOptionSetPosition(MENUPAGE_PAUSE_MENU, 2);
FrontendOptionAddRedirect(TheText.Get("FEG_MAP"), MENUPAGE_MAP);
#endif
#ifdef FREE_CAM
static const wchar *text = (wchar*)L"TOGGLE FREE CAM";
FrontendOptionSetPosition(MENUPAGE_CONTROLLER_PC, 1);
FrontendOptionAddDynamic(text, nil, ToggleFreeCam, nil);
#endif
#ifdef CUTSCENE_BORDERS_SWITCH
static const wchar *off_on[] = { TheText.Get("FEM_OFF"), TheText.Get("FEM_ON") };
FrontendOptionSetPosition(MENUPAGE_GRAPHICS_SETTINGS, 9);
FrontendOptionAddSelect((const wchar *)L"CUTSCENE BORDERS", off_on, 2, (int8 *)&CMenuManager::m_PrefsCutsceneBorders, false, BorderModeChange, nil);
#endif
}
#endif
@ -252,7 +262,7 @@ FixCar(void)
}
}
#ifdef MENU_MAP
#ifdef MAP_ENHANCEMENTS
static void
TeleportToWaypoint(void)
{
@ -474,6 +484,8 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Spawn", "Spawn PCJ 600", [](){ SpawnCar(MI_PCJ600); });
DebugMenuAddCmd("Spawn", "Spawn Faggio", [](){ SpawnCar(MI_FAGGIO); });
DebugMenuAddCmd("Spawn", "Spawn Freeway", [](){ SpawnCar(MI_FREEWAY); });
DebugMenuAddCmd("Spawn", "Spawn Squalo", [](){ SpawnCar(MI_SQUALO); });
DebugMenuAddCmd("Spawn", "Spawn Skimmer", [](){ SpawnCar(MI_SKIMMER); });
DebugMenuAddVarBool8("Render", "Draw hud", &CHud::m_Wants_To_Draw_Hud, nil);
DebugMenuAddVarBool8("Render", "Backface Culling", &gBackfaceCulling, nil);
@ -483,6 +495,7 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Render", "Frame limiter", &FrontEndMenuManager.m_PrefsFrameLimiter, nil);
DebugMenuAddVarBool8("Render", "VSynch", &FrontEndMenuManager.m_PrefsVsync, nil);
DebugMenuAddVar("Render", "Max FPS", &RsGlobal.maxFPS, nil, 1, 1, 1000, nil);
DebugMenuAddVarBool8("Render", "Occlusion debug", &bDisplayOccDebugStuff, nil);
DebugMenuAddVarBool8("Render", "Show Ped Paths", &gbShowPedPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Paths", &gbShowCarPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Path Links", &gbShowCarPathsLinks, nil);
@ -497,7 +510,7 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Debug", "pad 1 -> pad 2", &CPad::m_bMapPadOneToPadTwo, nil);
DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil);
#ifdef MENU_MAP
#ifdef MAP_ENHANCEMENTS
DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint);
#endif
DebugMenuAddCmd("Debug", "Switch car collision", SwitchCarCollision);