diff options
author | Fire_Head <Fire-Head@users.noreply.github.com> | 2020-07-29 11:20:02 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-29 11:20:02 +0200 |
commit | 52e77c66345399f7f1064b80676a2495e299bb46 (patch) | |
tree | 358b7762beb8809084c65358087d5899e4546f18 /src/core | |
parent | miami shadows (diff) | |
parent | some fakerw additions for shadows; update librw (diff) | |
download | re3-52e77c66345399f7f1064b80676a2495e299bb46.tar re3-52e77c66345399f7f1064b80676a2495e299bb46.tar.gz re3-52e77c66345399f7f1064b80676a2495e299bb46.tar.bz2 re3-52e77c66345399f7f1064b80676a2495e299bb46.tar.lz re3-52e77c66345399f7f1064b80676a2495e299bb46.tar.xz re3-52e77c66345399f7f1064b80676a2495e299bb46.tar.zst re3-52e77c66345399f7f1064b80676a2495e299bb46.zip |
Diffstat (limited to 'src/core')
42 files changed, 1344 insertions, 1130 deletions
diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index c37e6b33..c4768fdc 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -39,7 +39,7 @@ extern float fRangePlayerRadius; extern float fCloseNearClipLimit; #ifdef FREE_CAM -bool CCamera::bFreeCam; +bool CCamera::bFreeCam = false; int nPreviousMode = -1; #endif diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index d558e3ad..9f3646e2 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -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 ¢er, const CMatrix *mat) { RwV3d c; - c = *(RwV3d*)¢er; + 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 ¢er, float radius, const CMatrix *mat) { RwV3d c; - c = *(RwV3d*)¢er; + 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; diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index 4d6bcdab..45fd9832 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -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); } } diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index 76019c2f..268e3c5e 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -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 §) 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]; @@ -1354,6 +1387,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) { int i; @@ -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]; } diff --git a/src/core/Collision.h b/src/core/Collision.h index d79352b5..1dc29efb 100644 --- a/src/core/Collision.h +++ b/src/core/Collision.h @@ -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); diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp index c3e4e872..d194cebb 100644 --- a/src/core/ControllerConfig.cpp +++ b/src/core/ControllerConfig.cpp @@ -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; diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h index 5f0b6862..05c37c22 100644 --- a/src/core/ControllerConfig.h +++ b/src/core/ControllerConfig.h @@ -61,6 +61,7 @@ enum e_ControllerAction SWITCH_DEBUG_CAM_ON, TAKE_SCREEN_SHOT, SHOW_MOUSE_POINTER_TOGGLE, + UNKNOWN_ACTION, MAX_CONTROLLERACTIONS, }; diff --git a/src/core/Directory.cpp b/src/core/Directory.cpp index cc4d65d8..05344065 100644 --- a/src/core/Directory.cpp +++ b/src/core/Directory.cpp @@ -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); diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp index 4fab29bc..e5f264c7 100644 --- a/src/core/EventList.cpp +++ b/src/core/EventList.cpp @@ -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); diff --git a/src/core/EventList.h b/src/core/EventList.h index f2c3d7a8..0531aed7 100644 --- a/src/core/EventList.h +++ b/src/core/EventList.h @@ -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];
\ No newline at end of file diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index 08126081..635192ea 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -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); } diff --git a/src/core/FileMgr.cpp b/src/core/FileMgr.cpp index 1939c861..4477a190 100644 --- a/src/core/FileMgr.cpp +++ b/src/core/FileMgr.cpp @@ -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); } diff --git a/src/core/FileMgr.h b/src/core/FileMgr.h index 1d0faf50..51e30694 100644 --- a/src/core/FileMgr.h +++ b/src/core/FileMgr.h @@ -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); diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 19e8e8f3..06744ac2 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -24,7 +24,6 @@ #include "GenericGameStorage.h" #include "Script.h" #include "Camera.h" -#include "MenuScreens.h" #include "ControllerConfig.h" #include "Vehicle.h" #include "MBlur.h" @@ -38,8 +37,8 @@ #include "Messages.h" #include "FileLoader.h" -// TODO(Miami): This is -3 on VC but still -1 on AudioManager?!? What the hell? -#define INVALID_AUDIO_PROVIDER -1 +// TODO(Miami): Remove that!! That was my map implementation for III, instead use MAP_ENHACEMENTS on some places +#define CUSTOM_MAP // Similar story to Hud.cpp: // Game has colors inlined in code. @@ -52,7 +51,7 @@ CRGBA HEADER_COLOR(255, 150, 255, 255); CRGBA DARKMENUOPTION_COLOR(195, 90, 165, 255); CRGBA SLIDERON_COLOR(97, 194, 247, 255); CRGBA SLIDEROFF_COLOR(27, 89, 130, 255); -CRGBA MAPINFOBOX_COLOR(255, 150, 225, 150); +CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 255); #define TIDY_UP_PBP // ProcessButtonPresses #define MAX_VISIBLE_LIST_ROW 30 @@ -66,11 +65,7 @@ CRGBA MAPINFOBOX_COLOR(255, 150, 225, 150); #define FEET_IN_METER 3.33f #endif -#ifdef SCROLLABLE_STATS_PAGE -#define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS) -#else #define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS || screen == MENUPAGE_STATS) -#endif #ifdef TRIANGLE_BACK_BUTTON #define GetBackJustUp GetTriangleJustUp @@ -95,7 +90,9 @@ int curBottomBarOption = -1; int hoveredBottomBarOption = -1; #endif -uint8 CMenuManager::m_PrefsStereoMono; // unused except restore settings +#ifdef CUTSCENE_BORDERS_SWITCH +bool CMenuManager::m_PrefsCutsceneBorders = true; +#endif // Originally that was PS2 option color, they forget it here and used in PrintBriefs once(but didn't use the output anyway) #ifdef PS2_LIKE_MENU @@ -117,9 +114,10 @@ MenuTrapezoid menuBg(CGeneral::GetRandomNumber() % 40 + 65, CGeneral::GetRandomN MenuTrapezoid menuOptionHighlight(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); -// TODO(Miami): TEMPORARY +#ifdef CUSTOM_MAP bool bMapLoaded = false; bool bMapMouseShownOnce = false; +#endif #ifndef MASTER bool CMenuManager::m_PrefsMarketing = false; @@ -215,75 +213,6 @@ ScaleAndCenterX(float x) // --- Functions not in the game/inlined starts -bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); -void DoRWStuffEndOfFrame(void); - -#ifdef PS2_LIKE_MENU -void -CMenuManager::SwitchToNewScreen(int8 screen) -{ - if (reverseAlpha) { - m_nPrevScreen = m_nCurrScreen; - m_nCurrScreen = pendingScreen; - m_nCurrOption = pendingOption; - reverseAlpha = false; - if (updateDelay) - m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode(); - } - if (withReverseAlpha) { - pendingOption = option; - pendingScreen = screen; - reverseAlpha = true; - } else { - m_nPrevScreen = m_nCurrScreen; - m_nCurrScreen = screen; - m_nCurrOption = option; - if (updateDelay) - m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode(); - } - m_nMenuFadeAlpha = 255; -} -#else - -// --MIAMI: Done except using VC's gMenuPages -void -CMenuManager::SwitchToNewScreen(int8 screen) -{ - bMenuChangeOngoing = true; - DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); - DrawBackground(true); - DoRWStuffEndOfFrame(); - DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); - DrawBackground(true); - DoRWStuffEndOfFrame(); - m_nPrevScreen = m_nCurrScreen; - m_ShowEmptyBindingError = false; - ResetHelperText(); - - ThingsToDoBeforeLeavingPage(); - - if (screen == -2) { - int oldScreen = aScreens[m_nCurrScreen].m_PreviousPage; - int oldOption = (m_nCurrScreen == MENUPAGE_NEW_GAME ? 0 : (m_nCurrScreen == MENUPAGE_OPTIONS ? 1 : (m_nCurrScreen == MENUPAGE_EXIT ? 2 : aScreens[m_nCurrScreen].m_ParentEntry))); - - m_nCurrOption = oldOption; - m_nCurrScreen = oldScreen; - } else if (screen == 0) { - m_nCurrScreen = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu; - m_nCurrOption = 0; - } else { - m_nCurrOption = 0; - m_nCurrScreen = screen; - } - - if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT) - m_nCurrOption = 8; - m_nMenuFadeAlpha = 0; - m_nOptionHighlightTransitionBlend = 0; - m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode(); -} -#endif - inline void CMenuManager::ScrollUpListByOne() { @@ -350,14 +279,13 @@ CMenuManager::PageDownList(bool playSoundOnSuccess) } } -// TODO(Miami) inline void CMenuManager::ThingsToDoBeforeLeavingPage() { if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) { CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); } else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) { - if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); #ifdef TIDY_UP_PBP DMAudio.StopFrontEndTrack(); @@ -374,13 +302,123 @@ CMenuManager::ThingsToDoBeforeLeavingPage() CPlayerSkin::EndFrontendSkinEdit(); } - if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) { - m_nTotalListRow = 0; +#ifdef CUSTOM_FRONTEND_OPTIONS + for (int i = 0; i < numCustomFrontendOptions; i++) { + FrontendOption& option = customFrontendOptions[i]; + if (option.type != FEOPTION_REDIRECT && option.type != FEOPTION_GOBACK && m_nCurrScreen == option.screen) { + if (option.returnPrevPageFunc) + option.returnPrevPageFunc(); + + if (m_nCurrOption == option.screenOptionOrder && option.type == FEOPTION_DYNAMIC) + option.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + + if (option.onlyApplyOnEnter) + option.displayedValue = *option.value; + } + } +#endif +} + +int8 +CMenuManager::GetPreviousPageOption() +{ +#ifndef CUSTOM_FRONTEND_OPTIONS + return (!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry : + (m_nCurrScreen == MENUPAGE_NEW_GAME ? 0 : (m_nCurrScreen == MENUPAGE_OPTIONS ? 1 : (m_nCurrScreen == MENUPAGE_EXIT ? 2 : aScreens[m_nCurrScreen].m_ParentEntry)))); +#else + int8 prevPage = aScreens[m_nCurrScreen].m_PreviousPage; + + if (prevPage == -1) // Game also does same + return 0; + + prevPage = prevPage == MENUPAGE_NONE ? (!m_bGameNotLoaded ? MENUPAGE_PAUSE_MENU : MENUPAGE_START_MENU) : prevPage; + + for (int i = 0; i < NUM_MENUROWS; i++) { + if (aScreens[prevPage].m_aEntries[i].m_TargetMenu == m_nCurrScreen) { + return i; + } } + + // Couldn't find current screen option on previous page, use default behaviour (maybe save-related screen?) + return (!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry : + (m_nCurrScreen == MENUPAGE_NEW_GAME ? 0 : (m_nCurrScreen == MENUPAGE_OPTIONS ? 1 : (m_nCurrScreen == MENUPAGE_EXIT ? 2 : aScreens[m_nCurrScreen].m_ParentEntry)))); +#endif } // ------ Functions not in the game/inlined ends +bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); +void DoRWStuffEndOfFrame(void); + +#ifdef PS2_LIKE_MENU +void +CMenuManager::SwitchToNewScreen(int8 screen) +{ + if (reverseAlpha) { + m_nPrevScreen = m_nCurrScreen; + m_nCurrScreen = pendingScreen; + m_nCurrOption = pendingOption; + reverseAlpha = false; + if (updateDelay) + m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode(); + } + if (withReverseAlpha) { + pendingOption = option; + pendingScreen = screen; + reverseAlpha = true; + } else { + m_nPrevScreen = m_nCurrScreen; + m_nCurrScreen = screen; + m_nCurrOption = option; + if (updateDelay) + m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode(); + } + m_nMenuFadeAlpha = 255; +} +#else + +// --MIAMI: Done +void +CMenuManager::SwitchToNewScreen(int8 screen) +{ + bMenuChangeOngoing = true; + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DrawBackground(true); + DoRWStuffEndOfFrame(); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DrawBackground(true); + DoRWStuffEndOfFrame(); + m_nPrevScreen = m_nCurrScreen; + m_ShowEmptyBindingError = false; + ResetHelperText(); + + ThingsToDoBeforeLeavingPage(); + + if (screen == -2) { + int oldScreen = aScreens[m_nCurrScreen].m_PreviousPage; + int oldOption = GetPreviousPageOption(); + + m_nCurrOption = oldOption; + m_nCurrScreen = oldScreen; + } else if (screen == 0) { + m_nCurrScreen = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu; + m_nCurrOption = 0; + } else { + m_nCurrOption = 0; + m_nCurrScreen = screen; + } + + if (m_nPrevScreen == MENUPAGE_SKIN_SELECT || m_nPrevScreen == MENUPAGE_KEYBOARD_CONTROLS) + m_nTotalListRow = 0; + + if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT) + m_nCurrOption = 8; + m_nMenuFadeAlpha = 0; + m_nOptionHighlightTransitionBlend = 0; + m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode(); +} +#endif + CMenuManager::CMenuManager() { m_StatsScrollSpeed = 150.0f; @@ -388,9 +426,9 @@ CMenuManager::CMenuManager() m_PrefsSfxVolume = 49; m_PrefsMusicVolume = 49; m_PrefsRadioStation = 0; - field_2C = 1; + m_PrefsStereoMono = 1; m_PrefsBrightness = 256; - m_PrefsLOD = 1.2f; + m_PrefsLOD = CRenderer::ms_lodDistScale; m_KeyPressedCode = -1; m_bFrontEnd_ReloadObrTxtGxt = false; m_PrefsMP3BoostVolume = 0; @@ -423,7 +461,7 @@ CMenuManager::CMenuManager() m_nScrollbarTopMargin = 0.0f; m_nSelectedListRow = 0; m_nSkinsTotal = 0; - m_nPrefsAudio3DProviderIndex = -99; + m_nPrefsAudio3DProviderIndex = AUDIO_PROVIDER_NOT_DETERMINED; m_bGameNotLoaded = true; m_nMousePosX = m_nMouseTempPosX; m_nMousePosY = m_nMouseTempPosY; @@ -464,7 +502,7 @@ CMenuManager::Initialise(void) DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); DoRWStuffEndOfFrame(); m_AllowNavigation = false; - m_menuTransitionProgress = -50; + m_menuTransitionProgress = -50; // to start from black m_nMenuFadeAlpha = 0; m_nCurrOption = 0; m_nOptionHighlightTransitionBlend = 0; @@ -631,31 +669,30 @@ CMenuManager::CheckSliderMovement(int value) { switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) { case MENUACTION_BRIGHTNESS: - m_PrefsBrightness += value * (512/16); - m_PrefsBrightness = clamp(m_PrefsBrightness, 0, 511); + m_PrefsBrightness += value * 24.19f; + m_PrefsBrightness = clamp(m_PrefsBrightness, 0, 384); break; case MENUACTION_DRAWDIST: if(value > 0) - m_PrefsLOD += ((1.8f - 0.8f) / 16.0f); + m_PrefsLOD += ((1.8f - 0.925f) / 16.0f); else - m_PrefsLOD -= ((1.8f - 0.8f) / 16.0f); - m_PrefsLOD = clamp(m_PrefsLOD, 0.8f, 1.8f); + m_PrefsLOD -= ((1.8f - 0.925f) / 16.0f); + m_PrefsLOD = clamp(m_PrefsLOD, 0.925f, 1.8f); CRenderer::ms_lodDistScale = m_PrefsLOD; break; case MENUACTION_MUSICVOLUME: - m_PrefsMusicVolume += value * (128/16); - m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 127); + m_PrefsMusicVolume += value * (128/32); + m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 65); DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); break; case MENUACTION_SFXVOLUME: - m_PrefsSfxVolume += value * (128/16); - m_PrefsSfxVolume = clamp(m_PrefsSfxVolume, 0, 127); + m_PrefsSfxVolume += value * (128/32); + m_PrefsSfxVolume = clamp(m_PrefsSfxVolume, 0, 65); DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); break; case MENUACTION_MOUSESENS: TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // ??? TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f); - TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl; break; default: return; @@ -663,12 +700,27 @@ CMenuManager::CheckSliderMovement(int value) SaveSettings(); } +// --MIAMI: Done void -CMenuManager::DisplayHelperText() +CMenuManager::DisplayHelperText(char *text) { + if (m_nMenuFadeAlpha != 255) + return; + // there was a unused static bool static PauseModeTime LastFlash = 0; - int32 alpha; + int32 alpha = 255; + + CFont::SetRightJustifyOn(); + CFont::SetScale(SCREEN_SCALE_X(SMALLESTTEXT_X_SCALE), SCREEN_SCALE_Y(SMALLESTTEXT_Y_SCALE)); + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + CFont::SetDropShadowPosition(0); + + if (text) { + CFont::SetColor(CRGBA(255, 255, 255, 255)); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get(text)); + return; + } if (m_nHelperTextMsgId != 0 && m_nHelperTextMsgId != 1) { if (CTimer::GetTimeInMillisecondsPauseMode() - LastFlash > 10) { @@ -682,41 +734,67 @@ CMenuManager::DisplayHelperText() alpha = m_nHelperTextAlpha > 255 ? 255 : m_nHelperTextAlpha; } - CFont::SetCentreOn(); - CFont::SetScale(SCREEN_SCALE_X(SMALLESTTEXT_X_SCALE), SCREEN_SCALE_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - + CFont::SetColor(CRGBA(255, 255, 255, alpha)); // TODO: name this cases? switch (m_nHelperTextMsgId) { - case 0: - { - int action = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; - if (action != MENUACTION_CHANGEMENU && action != MENUACTION_KEYBOARDCTRLS && action != MENUACTION_RESTOREDEF) { - CFont::SetColor(CRGBA(255, 255, 255, 255)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_MIG")); - } - break; - } case 1: - CFont::SetColor(CRGBA(255, 255, 255, 255)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_APP")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_APP")); break; case 2: - CFont::SetColor(CRGBA(255, 255, 255, alpha)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_HRD")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_HRD")); break; case 3: - CFont::SetColor(CRGBA(255, 255, 255, alpha)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_RSO")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_RSO")); break; case 4: - CFont::SetColor(CRGBA(255, 255, 255, alpha)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_RSC")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_STS")); + break; + case 5: + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_RSC")); break; default: + if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_NO) + return; + + if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_MUSICVOLUME || + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SFXVOLUME) { + + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); + return; + } + + if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_KEYBOARDCTRLS) + return; + + if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SCREENRES) { + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + m_bGameNotLoaded ? TheText.Get("FET_MIG") : TheText.Get("FEH_NA")); + return; + } + + if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_AUDIOHW || + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SPEAKERCONF) { + + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); + return; + } + + if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_RESTOREDEF) + return; + + if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_MP3VOLUMEBOOST) { + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); + return; + } + + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + m_nCurrScreen != MENUPAGE_STATS ? TheText.Get("FET_MIG") : TheText.Get("FEH_SSA")); + break; } - CFont::SetRightJustifyOff(); } // --MIAMI: Done @@ -755,10 +833,10 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR void CMenuManager::DoSettingsBeforeStartingAGame() { - CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD; +#ifdef LEGACY_MENU_OPTIONS if (m_PrefsVsyncDisp != m_PrefsVsync) m_PrefsVsync = m_PrefsVsyncDisp; - +#endif DMAudio.DestroyAllGameCreatedEntities(); DMAudio.Service(); m_bShutDownFrontEndRequested = true; @@ -795,7 +873,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(38.0f), MENU_Y(85.0f), MENU_X_LEFT_ALIGNED(615.0f), MENU_Y(75.0f), MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(320.0f), - MENU_X_LEFT_ALIGNED(605.0f), MENU_Y(330.0f), CRGBA(49, 101, 148, FadeIn(130))); + MENU_X_LEFT_ALIGNED(605.0f), MENU_Y(330.0f), CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(130))); break; /* // TODO(Miami) @@ -816,10 +894,10 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) PREPARE_MENU_HEADER CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); } // Label @@ -880,28 +958,6 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) wchar unicodeTemp[64]; char asciiTemp[32]; -#ifdef MENU_MAP - if (m_nCurrScreen == MENUPAGE_MAP) { - // Back button - wchar *backTx = TheText.Get("FEDS_TB"); - CFont::SetDropShadowPosition(1); - CFont::SetDropColor(CRGBA(0, 0, 0, 255)); - CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); - CFont::SetRightJustifyOff(); - CFont::SetCentreOn(); - CFont::PrintString(MENU_X(60.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), backTx); - CFont::SetDropShadowPosition(0); - if (!CheckHover(MENU_X(30.0f), MENU_X(30.0f) + CFont::GetStringWidth(backTx), SCREEN_SCALE_FROM_BOTTOM(125.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f))) { - m_nHoverOption = HOVEROPTION_NOT_HOVERING; - m_nCurrOption = m_nPrevOption = 0; - } else { - m_nHoverOption = HOVEROPTION_RANDOM_ITEM; - m_nCurrOption = m_nPrevOption = 1; - } - return; - } -#endif - bool weHaveLabel = aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL; uint8 section = 0; // 0: highlight trapezoid 1: texts @@ -962,7 +1018,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) leftText = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName); } - if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) { + if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) { if (strncmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEO_AUD", 8) == 0) { CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); } @@ -1028,7 +1084,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) case MENUACTION_MUSICVOLUME: case MENUACTION_SFXVOLUME: - if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) + if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) rightText = TheText.Get("FEA_NAH"); break; @@ -1057,6 +1113,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) break; case MENUACTION_HUD: rightText = TheText.Get(m_PrefsShowHud ? "FEM_ON" : "FEM_OFF"); + break; #ifdef LEGACY_MENU_OPTIONS case MENUACTION_SETDBGFLAG: rightText = TheText.Get(CTheScripts::IsDebugOn() ? "FEM_ON" : "FEM_OFF"); @@ -1094,7 +1151,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) break; #endif case MENUACTION_AUDIOHW: - if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) + if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) rightText = TheText.Get("FEA_NAH"); else if (m_nPrefsAudio3DProviderIndex == -1) rightText = TheText.Get("FEA_ADP"); @@ -1112,7 +1169,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) } break; case MENUACTION_SPEAKERCONF: { - if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) + if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) rightText = TheText.Get("FEA_NAH"); else { switch (m_PrefsSpeakers) { @@ -1154,22 +1211,52 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) rightText = TheText.Get("FEA_NM3"); } break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_TRIGGERFUNC: + FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; + if (m_nCurrScreen == option.screen && i == option.screenOptionOrder) { + leftText = (wchar*)option.leftText; + if (option.type == FEOPTION_SELECT) { + if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0) + option.displayedValue = 0; + + rightText = (wchar*)option.rightTexts[option.displayedValue]; + + } else if (option.type == FEOPTION_DYNAMIC) { + if (option.drawFunc) { + bool isOptionDisabled = false; + rightText = option.drawFunc(&isOptionDisabled); + if (isOptionDisabled) + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); + } + } + } else { + debug("A- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, i, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu, option.screen, option.screenOptionOrder); + assert(0 && "Custom frontend options is borked"); + } + + break; +#endif } // Highlight trapezoid if (drawCurrScreen && i == m_nCurrOption && itemsAreSelectable && section == 0) { int leftXMax, rightXMin; - CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); + + // FIX: Let's don't scale those so GetStringWidth will give unscaled width, which will be handy to other calculations below that's done without scaling in mind. + // CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); + CFont::SetScale(BIGTEXT_X_SCALE, BIGTEXT_Y_SCALE); + wchar *curOptionName = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName); float curOptionWidth = CFont::GetStringWidth(curOptionName, true); if (CFont::Details.centre) { leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth / 2.f); - rightXMin = Min(SCREEN_WIDTH, curOptionWidth / 2.f + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X); + rightXMin = Min(DEFAULT_SCREEN_WIDTH, curOptionWidth / 2.f + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X); } else if (!CFont::Details.rightJustify) { leftXMax = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X; - rightXMin = Min(SCREEN_WIDTH, curOptionWidth + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X); + rightXMin = Min(DEFAULT_SCREEN_WIDTH, curOptionWidth + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X); } else { leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth); rightXMin = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X; @@ -1283,7 +1370,7 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) } if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0 - && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS && m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) { + && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); SetHelperText(3); @@ -1304,6 +1391,24 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) } } #endif +#ifdef CUSTOM_FRONTEND_OPTIONS + static int lastOption = m_nCurrOption; + + if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_TRIGGERFUNC) { + FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; + if (option.onlyApplyOnEnter && m_nCurrOption != i) + option.displayedValue = *option.value; + + if (m_nCurrOption != lastOption && lastOption == i) { + FrontendOption& oldOption = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[lastOption].m_TargetMenu]; + if (oldOption.type == FEOPTION_DYNAMIC) + oldOption.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + } + } + + if (i == MAX_MENUROWS - 1 || aScreens[m_nCurrScreen].m_aEntries[i + 1].m_EntryName[0] == '\0') + lastOption = m_nCurrOption; +#endif // TODO(Miami): check // Sliders @@ -1316,11 +1421,11 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) ProcessSlider((m_PrefsLOD - 0.925f) / 0.875f, 99.0f, HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); break; case MENUACTION_MUSICVOLUME: - if(m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) + if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) ProcessSlider(m_PrefsMusicVolume / 64.0f, 70.0f, HOVEROPTION_INCREASE_MUSICVOLUME, HOVEROPTION_DECREASE_MUSICVOLUME, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); break; case MENUACTION_SFXVOLUME: - if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) ProcessSlider(m_PrefsSfxVolume / 64.0f, 99.0f, HOVEROPTION_INCREASE_SFXVOLUME, HOVEROPTION_DECREASE_SFXVOLUME, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); break; case MENUACTION_MOUSESENS: @@ -1356,8 +1461,6 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) section++; } - // TODO(Miami) - /* switch (m_nCurrScreen) { case MENUPAGE_STATS: case MENUPAGE_CONTROLLER_PC: @@ -1367,11 +1470,10 @@ CMenuManager::DrawStandardMenus(bool drawCurrScreen) DisplayHelperText(nil); break; case MENUPAGE_OPTIONS: - if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_LOADRADIO) + if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_LOADRADIO) DisplayHelperText("FEA_NAH"); break; } - */ if (m_nCurrScreen == MENUPAGE_DELETING_IN_PROGRESS) { SmallMessageScreen("FEDL_WR"); @@ -1832,25 +1934,25 @@ CMenuManager::DrawControllerSetupScreen() CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENU_UNK_WIDTH)); - PREPARE_MENU_HEADER - switch (m_ControlMethod) { case CONTROL_STANDARD: + PREPARE_MENU_HEADER CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); - PREPARE_MENU_HEADER - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); break; case CONTROL_CLASSIC: + PREPARE_MENU_HEADER CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get("FET_CTI")); - PREPARE_MENU_HEADER - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get("FET_CTI")); break; default: @@ -1936,10 +2038,10 @@ CMenuManager::DrawControllerSetupScreen() float curOptY = i * rowHeight + yStart; if (m_nMousePosY > MENU_Y(curOptY) && m_nMousePosY < MENU_Y(rowHeight + curOptY)) { - if (m_nPrevOption != i && m_nCurrExLayer == HOVEROPTION_LIST) + if (m_nOptionMouseHovering != i && m_nCurrExLayer == HOVEROPTION_LIST) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); - m_nPrevOption = i; + m_nOptionMouseHovering = i; if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) { m_nCurrExLayer = HOVEROPTION_LIST; m_nSelectedListRow = i; @@ -2467,9 +2569,9 @@ CMenuManager::DrawBackground(bool transitionCall) if (m_nCurrScreen != MENUPAGE_OUTRO) if (m_menuTransitionProgress == 255) { - m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X(27.0f), MENU_Y(8.0f), MENU_X(157.0f), MENU_Y(138.0f)), CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(27.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, 255)); } else { - m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X(27.0f), MENU_Y(8.0f), MENU_X(157.0f), MENU_Y(138.0f)), CRGBA(255, 255, 255, FadeIn(255))); + m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(27.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, FadeIn(255))); } if (m_ShowEmptyBindingError) { @@ -2514,7 +2616,7 @@ CMenuManager::DrawPlayerSetupScreen() PREPARE_MENU_HEADER - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get("FET_PS")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get("FET_PS")); // lstrcpy's changed with strcpy @@ -2551,7 +2653,7 @@ CMenuManager::DrawPlayerSetupScreen() char nameTemp[256]; for (m_pSelectedSkin = m_pSkinListHead.nextSkin; m_pSelectedSkin; m_pSelectedSkin = m_pSelectedSkin->nextSkin) { // Drop extension - int oldLength = strlen(m_pSelectedSkin->skinNameDisplayed); + int oldLength = (int)strlen(m_pSelectedSkin->skinNameDisplayed); m_pSelectedSkin->skinNameDisplayed[oldLength - 4] = '\0'; m_pSelectedSkin->skinNameOriginal[oldLength - 4] = '\0'; @@ -2641,7 +2743,7 @@ CMenuManager::DrawPlayerSetupScreen() if (m_nMousePosX > MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT) && m_nMousePosX < MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT)) { if (m_nMousePosY > MENU_Y(rowStartY) && m_nMousePosY < MENU_Y(rowEndY)) { - m_nPrevOption = rowIdx; + m_nOptionMouseHovering = rowIdx; if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) { m_nCurrExLayer = HOVEROPTION_LIST; } @@ -2917,7 +3019,7 @@ CMenuManager::FadeIn(int alpha) } void -CMenuManager::FilterOutColorMarkersFromString(wchar *str, CRGBA &newColor) +CMenuManager::FilterOutColorMarkersFromString(wchar *str) { int newIdx = 0; wchar copy[256], *c; @@ -2926,16 +3028,6 @@ CMenuManager::FilterOutColorMarkersFromString(wchar *str, CRGBA &newColor) for (c = copy; *c != '\0'; c++) { if (*c == '~') { c++; - switch (*c) { - case 'b': newColor = CRGBA(40, 40, 255, 255); break; - case 'g': newColor = CRGBA(40, 235, 40, 255); break; - // There is no case for "h", is that a mistake? - case 'l': newColor = CRGBA(0, 0, 0, 255); break; - case 'p': newColor = CRGBA(255, 0, 255, 255); break; - case 'r': newColor = CRGBA(255, 0, 0, 255); break; - case 'w': newColor = CRGBA(255, 255, 255, 255); break; - case 'y': newColor = CRGBA(255, 255, 0, 255); break; - } while (*c != '~') c++; } else { str[newIdx++] = *c; @@ -3014,6 +3106,10 @@ CMenuManager::InitialiseChangedLanguageSettings() default: break; } + +#ifdef CUSTOM_FRONTEND_OPTIONS + CustomFrontendOptionsPopulate(); +#endif } } @@ -3076,28 +3172,32 @@ CMenuManager::LoadAllTextures() CTimer::Update(); } +// --MIAMI: Done void CMenuManager::LoadSettings() { CFileMgr::SetDirMyDocuments(); - int fileHandle = CFileMgr::OpenFile("gta3.set", "r"); + int fileHandle = CFileMgr::OpenFile("gta_vc.set", "r"); int32 prevLang = m_PrefsLanguage; -#ifdef GTA3_1_1_PATCH - CMBlur::BlurOn = (_dwOperatingSystemVersion != OS_WIN98); -#else - CMBlur::BlurOn = true; -#endif MousePointerStateHelper.bInvertVertically = true; + CMBlur::BlurOn = false; // 50 is silly - char Ver[50]; + char headerText[50]; + int someVersion = 0; + bool fileIsValid = true; if (fileHandle) { - CFileMgr::Read(fileHandle, Ver, 29); + CFileMgr::Read(fileHandle, headerText, 29); - if (strncmp(Ver, TopLineEmptyFile, sizeof(TopLineEmptyFile) - 1)) { + if (strncmp(headerText, TopLineEmptyFile, sizeof(TopLineEmptyFile) - 1) == 0) { + fileIsValid = false; + } else { CFileMgr::Seek(fileHandle, 0, 0); + CFileMgr::Read(fileHandle, (char*)&someVersion, sizeof(someVersion)); + } + if (fileIsValid && someVersion >= 3) { ControlsManager.LoadSettings(fileHandle); #ifdef IMPROVED_VIDEOMODE CFileMgr::Read(fileHandle, (char*)&m_nPrefsWidth, sizeof(m_nPrefsWidth)); @@ -3121,33 +3221,44 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, gString, 20); CFileMgr::Read(fileHandle, gString, 4); CFileMgr::Read(fileHandle, gString, 4); +#ifdef FREE_CAM + CFileMgr::Read(fileHandle, (char*)&TheCamera.bFreeCam, 1); +#else CFileMgr::Read(fileHandle, gString, 1); +#endif + +#ifdef LEGACY_MENU_OPTIONS + CFileMgr::Read(fileHandle, (char*)&m_PrefsVsyncDisp, 1); + CFileMgr::Read(fileHandle, (char*)&CMBlur::BlurOn, 1); +#else CFileMgr::Read(fileHandle, gString, 1); CFileMgr::Read(fileHandle, gString, 1); +#endif CFileMgr::Read(fileHandle, (char*)&TheCamera.m_bHeadBob, 1); CFileMgr::Read(fileHandle, (char*)&TheCamera.m_fMouseAccelHorzntl, 4); - CFileMgr::Read(fileHandle, (char*)&TheCamera.m_fMouseAccelVertical, 4); CFileMgr::Read(fileHandle, (char*)&MousePointerStateHelper.bInvertVertically, 1); CFileMgr::Read(fileHandle, (char*)&CVehicle::m_bDisableMouseSteering, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsSfxVolume, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsMusicVolume, 1); + CFileMgr::Read(fileHandle, (char*)&m_PrefsMP3BoostVolume, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsRadioStation, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsSpeakers, 1); CFileMgr::Read(fileHandle, (char*)&m_nPrefsAudio3DProviderIndex, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsDMA, 1); - CFileMgr::Read(fileHandle, (char*)&m_PrefsBrightness, 1); - CFileMgr::Read(fileHandle, (char*)&m_PrefsLOD, 4); + CFileMgr::Read(fileHandle, (char*)&m_PrefsBrightness, 2); + CFileMgr::Read(fileHandle, (char*)&m_PrefsLOD, sizeof(m_PrefsLOD)); CFileMgr::Read(fileHandle, (char*)&m_PrefsShowSubtitles, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsUseWideScreen, 1); - CFileMgr::Read(fileHandle, (char*)&m_PrefsVsyncDisp, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsFrameLimiter, 1); CFileMgr::Read(fileHandle, (char*)&m_nDisplayVideoMode, 1); - CFileMgr::Read(fileHandle, (char*)&CMBlur::BlurOn, 1); CFileMgr::Read(fileHandle, m_PrefsSkinFile, 256); CFileMgr::Read(fileHandle, (char*)&m_ControlMethod, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsLanguage, 1); -#ifdef FREE_CAM - CFileMgr::Read(fileHandle, (char*)&TheCamera.bFreeCam, 1); + CFileMgr::Read(fileHandle, (char*)&m_PrefsShowHud, 1); + CFileMgr::Read(fileHandle, (char*)&m_PrefsRadarMode, 1); + CFileMgr::Read(fileHandle, (char*)&m_PrefsShowLegends, 1); +#ifdef CUTSCENE_BORDERS_SWITCH + CFileMgr::Read(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1); #endif } } @@ -3155,10 +3266,13 @@ CMenuManager::LoadSettings() CFileMgr::CloseFile(fileHandle); CFileMgr::SetDir(""); + CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD; +#ifdef LEGACY_MENU_OPTIONS m_PrefsVsync = m_PrefsVsyncDisp; +#endif CRenderer::ms_lodDistScale = m_PrefsLOD; - if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) + if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) m_nPrefsAudio3DProviderIndex = -2; m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex; @@ -3194,15 +3308,18 @@ CMenuManager::LoadSettings() } } +// --MIAMI: Done void CMenuManager::SaveSettings() { static char RubbishString[48] = "stuffmorestuffevenmorestuff etc"; + static int SomeVersion = 3; CFileMgr::SetDirMyDocuments(); - int fileHandle = CFileMgr::OpenFile("gta3.set", "w+"); + int fileHandle = CFileMgr::OpenFile("gta_vc.set", "w+"); if (fileHandle) { + CFileMgr::Write(fileHandle, (char*)&SomeVersion, sizeof(SomeVersion)); ControlsManager.SaveSettings(fileHandle); #ifdef IMPROVED_VIDEOMODE CFileMgr::Write(fileHandle, (char*)&m_nPrefsWidth, sizeof(m_nPrefsWidth)); @@ -3216,33 +3333,44 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, RubbishString, 20); CFileMgr::Write(fileHandle, RubbishString, 4); CFileMgr::Write(fileHandle, RubbishString, 4); +#ifdef FREE_CAM + CFileMgr::Write(fileHandle, (char*)&TheCamera.bFreeCam, 1); +#else CFileMgr::Write(fileHandle, RubbishString, 1); +#endif + +#ifdef LEGACY_MENU_OPTIONS + CFileMgr::Write(fileHandle, (char*)&m_PrefsVsyncDisp, 1); + CFileMgr::Write(fileHandle, (char*)&CMBlur::BlurOn, 1); +#else CFileMgr::Write(fileHandle, RubbishString, 1); CFileMgr::Write(fileHandle, RubbishString, 1); +#endif CFileMgr::Write(fileHandle, (char*)&TheCamera.m_bHeadBob, 1); CFileMgr::Write(fileHandle, (char*)&TheCamera.m_fMouseAccelHorzntl, 4); - CFileMgr::Write(fileHandle, (char*)&TheCamera.m_fMouseAccelVertical, 4); CFileMgr::Write(fileHandle, (char*)&MousePointerStateHelper.bInvertVertically, 1); CFileMgr::Write(fileHandle, (char*)&CVehicle::m_bDisableMouseSteering, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsSfxVolume, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsMusicVolume, 1); + CFileMgr::Write(fileHandle, (char*)&m_PrefsMP3BoostVolume, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsRadioStation, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsSpeakers, 1); CFileMgr::Write(fileHandle, (char*)&m_nPrefsAudio3DProviderIndex, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsDMA, 1); - CFileMgr::Write(fileHandle, (char*)&m_PrefsBrightness, 1); + CFileMgr::Write(fileHandle, (char*)&m_PrefsBrightness, 2); CFileMgr::Write(fileHandle, (char*)&m_PrefsLOD, sizeof(m_PrefsLOD)); CFileMgr::Write(fileHandle, (char*)&m_PrefsShowSubtitles, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsUseWideScreen, 1); - CFileMgr::Write(fileHandle, (char*)&m_PrefsVsyncDisp, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsFrameLimiter, 1); CFileMgr::Write(fileHandle, (char*)&m_nPrefsVideoMode, 1); - CFileMgr::Write(fileHandle, (char*)&CMBlur::BlurOn, 1); CFileMgr::Write(fileHandle, m_PrefsSkinFile, 256); CFileMgr::Write(fileHandle, (char*)&m_ControlMethod, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsLanguage, 1); -#ifdef FREE_CAM - CFileMgr::Write(fileHandle, (char*)&TheCamera.bFreeCam, 1); + CFileMgr::Write(fileHandle, (char*)&m_PrefsShowHud, 1); + CFileMgr::Write(fileHandle, (char*)&m_PrefsRadarMode, 1); + CFileMgr::Write(fileHandle, (char*)&m_PrefsShowLegends, 1); +#ifdef CUTSCENE_BORDERS_SWITCH + CFileMgr::Write(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1); #endif } m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex; @@ -3300,17 +3428,22 @@ CMenuManager::SmallMessageScreen(const char* text) CFont::PrintString(SCREEN_WIDTH / 2.f, y, TheText.Get(text)); } +// --MIAMI: Done, but FilterOutColorMarkersFromString is actually in CFont void CMenuManager::PrintBriefs() { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + CFont::SetScale(MENU_X(MEDIUMTEXT_X_SCALE), MENU_Y(MEDIUMTEXT_Y_SCALE)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(80.0f)); + CFont::SetDropShadowPosition(0); - float nextY = BRIEFS_TOP_MARGIN; - CRGBA newColor; + float nextY = BRIEFS_BOTTOM_MARGIN; for (int i = 4; i >= 0; i--) { + if (nextY < BRIEFS_TOP_MARGIN) + break; + tPreviousBrief &brief = CMessages::PreviousBriefs[i]; if (brief.m_pText) { CMessages::InsertNumberInString(brief.m_pText, @@ -3319,127 +3452,125 @@ CMenuManager::PrintBriefs() brief.m_nNumber[4], brief.m_nNumber[5], gUString); CMessages::InsertStringInString(gUString, brief.m_pString); CMessages::InsertPlayerControlKeysInString(gUString); - newColor = TEXT_COLOR; - FilterOutColorMarkersFromString(gUString, newColor); + FilterOutColorMarkersFromString(gUString); -#ifdef PS2_LIKE_MENU - // This PS2 code was always here, but unused - bool rgSame = newColor.r == TEXT_COLOR.r && newColor.g == TEXT_COLOR.g; - bool bSame = rgSame && newColor.b == TEXT_COLOR.b; - bool colorNotChanged = bSame; /* && newColor.a == TEXT_COLOR.a; */ - - if (!colorNotChanged) { - newColor.r /= 2; - newColor.g /= 2; - newColor.b /= 2; - } - CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); // But this is from PS2 - CFont::SetDropShadowPosition(1); -#endif - -#if defined(FIX_BUGS) || defined(PS2_LIKE_MENU) - newColor.a = FadeIn(255); - CFont::SetColor(newColor); -#endif - CFont::PrintString(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), nextY, gUString); - nextY += MENU_Y(BRIEFS_LINE_HEIGHT); + nextY -= CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), nextY, gUString) * BRIEFS_LINE_HEIGHT + BRIEFS_LINE_SPACING; + CFont::PrintString(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), MENU_Y(nextY), gUString); } } - -#ifdef PS2_LIKE_MENU - CFont::SetDropShadowPosition(0); -#endif } +// --MIAMI: Done void CMenuManager::PrintStats() { + static uint8 pirateCheck = 0; + static float scrollY = 0; + int rowNum = ConstructStatLine(99999); -#ifdef GTA3_1_1_PATCH + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(142.0f), + MENU_X_LEFT_ALIGNED(543.0f), MENU_Y(142.f), + MENU_X_LEFT_ALIGNED(107.0f), MENU_Y(316.f), + MENU_X_LEFT_ALIGNED(531.f), MENU_Y(299.f), CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(130))); + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); -#endif - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why - float nextYChange, y, alphaMult; + CFont::SetPropOn(); + CFont::SetDropShadowPosition(0); - // Scroll stats with mouse -#ifdef SCROLLABLE_STATS_PAGE - static float scrollY = 0; - static PauseModeTime lastChange = m_LastScreenSwitch; - if (CPad::GetPad(0)->GetLeftMouse()) { - scrollY += (m_nMouseOldPosY - m_nMousePosY); - lastChange = CTimer::GetTimeInMillisecondsPauseMode(); - } else { - scrollY += MENU_Y(STATS_SLIDE_Y_PER_SECOND) / 1000.0f * (CTimer::GetTimeInMillisecondsPauseMode() - lastChange); - lastChange = CTimer::GetTimeInMillisecondsPauseMode(); + if (pirateCheck == 0) + // if not pirated game + pirateCheck = 46; + // else + // pirateCheck = 45; + + if (m_PrefsLanguage == LANGUAGE_AMERICAN) + CFont::SetScale(MENU_X(0.43f), MENU_Y(0.75f)); + else + CFont::SetScale(MENU_X(0.37f), MENU_Y(0.75f)); + + static PauseModeTime lastCheck = 0; + + if (CTimer::GetTimeInMillisecondsPauseMode() - lastCheck > 40) { + + if (m_StatsScrollSpeed > 0.f) { + if (m_StatsScrollDirection == 0) + scrollY -= MENU_Y(100.f) / m_StatsScrollSpeed; + else + scrollY += MENU_Y(100.f) / m_StatsScrollSpeed; + } + lastCheck = CTimer::GetTimeInMillisecondsPauseMode(); } -#else - // MENU_Y(30.0f) per second - float scrollY = MENU_Y(STATS_SLIDE_Y_PER_SECOND) * (CTimer::GetTimeInMillisecondsPauseMode() - m_LastScreenSwitch) / 1000.0f; -#endif + if (pirateCheck == 45) + return; + + float nextYChange, y, alpha; + + float totalHeight = (rowNum + 7) * STATS_ROW_HEIGHT; for (int row = 0; row < rowNum; ++row) { - // Put just got hidden text at the top back to the bottom, in circular fashion - for (y = MENU_Y(STATS_ROW_HEIGHT - 1) * row + SCREEN_HEIGHT - scrollY; MENU_Y(STATS_PUT_BACK_TO_BOTTOM_Y) > y; y += nextYChange) { - nextYChange = (MENU_Y(STATS_ROW_HEIGHT) + rowNum) * MENU_Y(STATS_ROW_HEIGHT - 1); + // Put faded away text at the top back to the bottom, in circular fashion + for (y = MENU_Y(STATS_ROW_HEIGHT) * row + MENU_Y(100.f) - scrollY; MENU_Y(STATS_FADING_AREA_LENGTH) > y; y += nextYChange) { + nextYChange = MENU_Y(totalHeight); + } + + // Put faded away text at the bottom back to the top + while (SCREEN_SCALE_FROM_BOTTOM(STATS_FADING_AREA_LENGTH) < y) { + y -= MENU_Y(totalHeight); } + alpha = 0.f; // If it's still on screen - if (y > 0.0f && SCREEN_HEIGHT > y) { + if (y > MENU_Y(STATS_VISIBLE_START_Y) && y < MENU_Y(STATS_VISIBLE_END_Y)) { ConstructStatLine(row); - // But about to dim from top - if (y - MENU_Y(STATS_BOTTOM_MARGIN) < MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH)) { - if ((y - MENU_Y(STATS_BOTTOM_MARGIN)) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH) < 0.0f) - alphaMult = 0.0f; - else - alphaMult = (y - MENU_Y(STATS_BOTTOM_MARGIN)) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH); + // But about to dim from bottom + if (y < MENU_Y(STATS_BOTTOM_Y)) { + if (y > MENU_Y(STATS_BOTTOM_Y - STATS_FADING_AREA_LENGTH)) + alpha = (MENU_Y(STATS_BOTTOM_Y) - y) * 5.f; + } - // About to dim from bottom - } else if (y > SCREEN_SCALE_FROM_BOTTOM(STATS_TOP_DIMMING_AREA_LENGTH) - MENU_Y(STATS_BOTTOM_DIMMING_AREA_LENGTH)) { - if ((SCREEN_SCALE_FROM_BOTTOM(STATS_BOTTOM_DIMMING_AREA_LENGTH) - y) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH) < 0.0f) - alphaMult = 0.0f; - else - alphaMult = (SCREEN_SCALE_FROM_BOTTOM(STATS_BOTTOM_DIMMING_AREA_LENGTH) - y) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH); - } else - alphaMult = 1.0f; + // About to dim from top + if (y > MENU_Y(STATS_TOP_Y)) { + if (y < MENU_Y(STATS_TOP_Y + STATS_FADING_AREA_LENGTH)) + alpha = (y - MENU_Y(STATS_TOP_Y)) * 5.f; + } + + // Content + if (y >= MENU_Y(STATS_TOP_Y + STATS_FADING_AREA_LENGTH) && y <= MENU_Y(STATS_BOTTOM_Y - STATS_FADING_AREA_LENGTH)) + alpha = 255.0f; - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255.0f * alphaMult))); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(Min(255.f, alpha)))); CFont::SetRightJustifyOff(); - CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_ROW_X_MARGIN), y - MENU_Y(STATS_BOTTOM_MARGIN - STATS_TOP_MARGIN), gUString); + CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_ROW_LEFT_MARGIN), y, gUString); CFont::SetRightJustifyOn(); - CFont::PrintString(MENU_X_RIGHT_ALIGNED(STATS_ROW_X_MARGIN), y - MENU_Y(STATS_BOTTOM_MARGIN - STATS_TOP_MARGIN), gUString2); + CFont::PrintString(MENU_X_RIGHT_ALIGNED(STATS_ROW_RIGHT_MARGIN), y, gUString2); } } - // Game doesn't do that, but it's better - float nextX = MENU_X_LEFT_ALIGNED(STATS_RATING_X); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); + CFont::SetCentreOn(); + CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + CFont::SetScale(MENU_X(0.65f), MENU_Y(1.05f)); + CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_RATING_X), MENU_Y(STATS_RATING_Y_1), TheText.Get("CRIMRA")); - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetCentreOff(); CFont::SetRightJustifyOff(); - CFont::PrintString(nextX, MENU_Y(STATS_RATING_Y), TheText.Get("CRIMRA")); -#ifdef MORE_LANGUAGES - if (CFont::IsJapanese()) - nextX += MENU_X(10.0f) + CFont::GetStringWidth_Jap(TheText.Get("CRIMRA")); - else -#endif - nextX += MENU_X(10.0f) + CFont::GetStringWidth(TheText.Get("CRIMRA"), true); - UnicodeStrcpy(gUString, CStats::FindCriminalRatingString()); - CFont::PrintString(nextX, MENU_Y(STATS_RATING_Y), gUString); -#ifdef MORE_LANGUAGES - if (CFont::IsJapanese()) - nextX += MENU_X(6.0f) + CFont::GetStringWidth_Jap(gUString); - else -#endif - nextX += MENU_X(6.0f) + CFont::GetStringWidth(gUString, true); - sprintf(gString, "%d", CStats::FindCriminalRatingNumber()); + + // FIX: Game does that in a weird way, alignment and spacing is now ok + + sprintf(gString, "(%d)", CStats::FindCriminalRatingNumber()); AsciiToUnicode(gString, gUString); - CFont::PrintString(nextX, MENU_Y(STATS_RATING_Y), gUString); - // ::Draw already does that. - /* - PREPARE_MENU_HEADER - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); - */ - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y)); + UnicodeStrcpy(gUString2, CStats::FindCriminalRatingString()); + UnicodeStrcat(gUString2, gUString); + + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + CFont::SetScale(MENU_X(0.5f), MENU_Y(0.9f)); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); + CFont::SetDropShadowPosition(0); + + CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_RATING_X) - CFont::GetStringWidth(gUString2, true) / 2.f, MENU_Y(STATS_RATING_Y_2), gUString2); } // --MIAMI: Done @@ -3574,7 +3705,7 @@ CMenuManager::ProcessButtonPresses(void) m_nMousePosY < MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y + MENU_DEFAULT_LINE_HEIGHT)) { static int oldScreen = m_nCurrScreen; - m_nPrevOption = rowToCheck; + m_nOptionMouseHovering = rowToCheck; if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) { m_nCurrOption = rowToCheck; m_bShowMouse = true; @@ -3588,7 +3719,7 @@ CMenuManager::ProcessButtonPresses(void) break; } if (m_bShowMouse && m_nMenuFadeAlpha == 255) { - m_nPrevOption = oldOption; + m_nOptionMouseHovering = oldOption; m_nCurrOption = oldOption; } } @@ -3597,7 +3728,7 @@ CMenuManager::ProcessButtonPresses(void) if (oldOption != m_nCurrOption) { if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_LABEL) { ++m_nCurrOption; - ++m_nPrevOption; + ++m_nOptionMouseHovering; } m_nOptionHighlightTransitionBlend = 0; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); @@ -3879,7 +4010,7 @@ CMenuManager::ProcessButtonPresses(void) if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_RESUME && #endif (m_nHoverOption == HOVEROPTION_RANDOM_ITEM)) { - m_nCurrOption = m_nPrevOption; + m_nCurrOption = m_nOptionMouseHovering; optionSelected = true; } } else if (CPad::GetPad(0)->GetLeftMouseJustDown()) { @@ -3893,7 +4024,7 @@ CMenuManager::ProcessButtonPresses(void) OutputDebugString("FRONTEND RADIO STATION CHANGED"); } else if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_RESUME) { - m_nCurrOption = m_nPrevOption; + m_nCurrOption = m_nOptionMouseHovering; optionSelected = true; } #else @@ -3980,7 +4111,7 @@ CMenuManager::ProcessButtonPresses(void) break; case HOVEROPTION_RANDOM_ITEM: if (((m_nCurrOption != 0) || (m_nCurrScreen != MENUPAGE_PAUSE_MENU)) { - m_nCurrOption = m_nPrevOption; + m_nCurrOption = m_nOptionMouseHovering; optionSelected = true; } break; @@ -4065,13 +4196,11 @@ CMenuManager::ProcessButtonPresses(void) case HOVEROPTION_INCREASE_MOUSESENS: TheCamera.m_fMouseAccelHorzntl += (1.0f / 3000); TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200); - TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl; SaveSettings(); break; case HOVEROPTION_DECREASE_MOUSESENS: TheCamera.m_fMouseAccelHorzntl -= (1.0f / 3000); TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200); - TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl; SaveSettings(); break; } @@ -4316,26 +4445,6 @@ CMenuManager::ProcessButtonPresses(void) InitialiseChangedLanguageSettings(); SaveSettings(); break; -#ifdef MORE_LANGUAGES - case MENUACTION_LANG_PL: - m_PrefsLanguage = LANGUAGE_POLISH; - m_bFrontEnd_ReloadObrTxtGxt = true; - InitialiseChangedLanguageSettings(); - SaveSettings(); - break; - case MENUACTION_LANG_RUS: - m_PrefsLanguage = LANGUAGE_RUSSIAN; - m_bFrontEnd_ReloadObrTxtGxt = true; - CMenuManager::InitialiseChangedLanguageSettings(); - SaveSettings(); - break; - case MENUACTION_LANG_JAP: - m_PrefsLanguage = LANGUAGE_JAPANESE; - m_bFrontEnd_ReloadObrTxtGxt = true; - InitialiseChangedLanguageSettings(); - SaveSettings(); - break; -#endif case MENUACTION_POPULATESLOTS_CHANGEMENU: PcSaveHelper.PopulateSlotInfo(); @@ -4344,8 +4453,7 @@ CMenuManager::ProcessButtonPresses(void) case MENUACTION_YES: case MENUACTION_NO: { - // TODO(Miami): TEMP -#ifdef MENU_MAP +#ifdef CUSTOM_MAP if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_MAP) { bMapLoaded = false; } @@ -4399,9 +4507,11 @@ CMenuManager::ProcessButtonPresses(void) SwitchToNewScreen(MENUPAGE_OUTRO); break; case MENUACTION_RESUME: +#ifdef LEGACY_MENU_OPTIONS if (m_PrefsVsyncDisp != m_PrefsVsync) { m_PrefsVsync = m_PrefsVsyncDisp; } +#endif RequestFrontEndShutDown(); break; case MENUACTION_DONTCANCEL: @@ -4411,12 +4521,11 @@ CMenuManager::ProcessButtonPresses(void) if (m_nDisplayVideoMode != m_nPrefsVideoMode) { m_nPrefsVideoMode = m_nDisplayVideoMode; _psSelectScreenVM(m_nPrefsVideoMode); - SetHelperText(0); // TODO(Miami): Remove that DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND); DMAudio.Service(); CentreMousePointer(); m_bShowMouse = true; - // m_nCurrOption = 5; // Why? + // m_nCurrOption = 5; // Why? TODO(Miami) m_nOptionHighlightTransitionBlend = 0; SaveSettings(); } @@ -4426,7 +4535,6 @@ CMenuManager::ProcessButtonPresses(void) if (m_nSelectedScreenMode != m_nPrefsWindowed) { m_nPrefsWindowed = m_nSelectedScreenMode; _psSelectScreenVM(m_nPrefsVideoMode); // apply same resolution - SetHelperText(0); SaveSettings(); } break; @@ -4434,14 +4542,12 @@ CMenuManager::ProcessButtonPresses(void) case MENUACTION_AUDIOHW: { int selectedProvider = m_nPrefsAudio3DProviderIndex; - if (selectedProvider != INVALID_AUDIO_PROVIDER) { + if (selectedProvider != NO_AUDIO_PROVIDER) { + if (selectedProvider == -1) + selectedProvider = m_nPrefsAudio3DProviderIndex = DMAudio.AutoDetect3DProviders(); m_nPrefsAudio3DProviderIndex = DMAudio.SetCurrent3DProvider(m_nPrefsAudio3DProviderIndex); - if (selectedProvider == m_nPrefsAudio3DProviderIndex) { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - SetHelperText(0); - } else { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0); - SetHelperText(4); + if (selectedProvider != m_nPrefsAudio3DProviderIndex) { + SetHelperText(5); } SaveSettings(); } @@ -4449,7 +4555,7 @@ CMenuManager::ProcessButtonPresses(void) } case MENUACTION_SPEAKERCONF: #ifndef TIDY_UP_PBP - if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) { + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { if (--m_PrefsSpeakers < 0) m_PrefsSpeakers = 2; DMAudio.SetSpeakerConfig(m_PrefsSpeakers); @@ -4467,38 +4573,36 @@ CMenuManager::ProcessButtonPresses(void) break; case MENUACTION_RESTOREDEF: if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) { - m_PrefsSfxVolume = 102; + m_nPrefsAudio3DProviderIndex = DMAudio.AutoDetect3DProviders(); + DMAudio.SetCurrent3DProvider(m_nPrefsAudio3DProviderIndex); + m_PrefsSfxVolume = 49; + m_PrefsMusicVolume = 49; + m_PrefsRadioStation = EMOTION; + m_PrefsMP3BoostVolume = 0; + m_PrefsStereoMono = 1; m_PrefsSpeakers = 0; - m_PrefsMusicVolume = 102; - m_PrefsStereoMono = 0; - m_PrefsRadioStation = WILDSTYLE; - DMAudio.SetMusicMasterVolume(102); + // DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); // TODO(Miami) + DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); DMAudio.SetRadioInCar(m_PrefsRadioStation); DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); SaveSettings(); } else if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { - m_PrefsFrameLimiter = true; m_PrefsBrightness = 256; - m_PrefsVsyncDisp = true; m_PrefsLOD = 1.2f; +#ifdef LEGACY_MENU_OPTIONS m_PrefsVsync = true; - CRenderer::ms_lodDistScale = 1.2f; +#endif + CRenderer::ms_lodDistScale = m_PrefsLOD; + m_PrefsShowSubtitles = false; m_PrefsUseWideScreen = false; - m_PrefsShowSubtitles = true; + m_PrefsShowLegends = true; + m_PrefsVsyncDisp = true; + m_PrefsFrameLimiter = true; + m_PrefsRadarMode = 0; + m_PrefsShowHud = true; m_nDisplayVideoMode = m_nPrefsVideoMode; -#ifdef GTA3_1_1_PATCH - if (_dwOperatingSystemVersion == OS_WIN98) { - CMBlur::BlurOn = false; - CMBlur::MotionBlurClose(); - } - else { - CMBlur::BlurOn = true; - CMBlur::MotionBlurOpen(Scene.camera); - } -#else - CMBlur::BlurOn = true; -#endif + CMBlur::BlurOn = false; SaveSettings(); } else if (m_nCurrScreen == MENUPAGE_CONTROLLER_PC) { ControlsManager.MakeControllerActionsBlank(); @@ -4518,11 +4622,12 @@ CMenuManager::ProcessButtonPresses(void) ControlsManager.InitDefaultControlConfigJoyPad(count); } #endif - m_ControlMethod = CONTROL_STANDARD; - MousePointerStateHelper.bInvertVertically = false; + MousePointerStateHelper.bInvertVertically = true; + TheCamera.m_bHeadBob = false; TheCamera.m_fMouseAccelHorzntl = 0.0025f; CVehicle::m_bDisableMouseSteering = true; - TheCamera.m_bHeadBob = false; + m_ControlMethod = CONTROL_STANDARD; + TheCamera.m_bUseMouse3rdPerson = true; SaveSettings(); } SetHelperText(2); @@ -4556,6 +4661,33 @@ CMenuManager::ProcessButtonPresses(void) } break; } +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_TRIGGERFUNC: + FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu]; + if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) { + if (option.type == FEOPTION_SELECT) { + if (!option.onlyApplyOnEnter) { + option.displayedValue++; + if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0) + option.displayedValue = 0; + } + option.changeFunc(option.displayedValue); + *option.value = option.displayedValue; + + } else if (option.type == FEOPTION_DYNAMIC) { + option.buttonPressFunc(FEOPTION_ACTION_SELECT); + } else if (option.type == FEOPTION_REDIRECT) { + ChangeScreen(option.to, option.option, true, option.fadeIn); + } else if (option.type == FEOPTION_GOBACK) { + goBack = true; + } + } else { + debug("B- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, m_nCurrOption, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, option.screen, option.screenOptionOrder); + assert(0 && "Custom frontend options are borked"); + } + + break; +#endif } } ProcessOnOffMenuOptions(); @@ -4570,9 +4702,11 @@ CMenuManager::ProcessButtonPresses(void) if (m_nCurrScreen == MENUPAGE_PAUSE_MENU) { #endif if (!m_bGameNotLoaded) { +#ifdef LEGACY_MENU_OPTIONS if (m_PrefsVsyncDisp != m_PrefsVsync) { m_PrefsVsync = m_PrefsVsyncDisp; } +#endif RequestFrontEndShutDown(); } @@ -4600,6 +4734,9 @@ CMenuManager::ProcessButtonPresses(void) if (oldScreen != -1) { ThingsToDoBeforeLeavingPage(); + if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) { + m_nTotalListRow = 0; + } #ifdef PS2_LIKE_MENU if (!bottomBarActive && @@ -4735,14 +4872,14 @@ CMenuManager::ProcessButtonPresses(void) break; #endif case MENUACTION_AUDIOHW: - if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) { + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex += changeValueBy; m_nPrefsAudio3DProviderIndex = clamp(m_nPrefsAudio3DProviderIndex, 0, DMAudio.GetNum3DProvidersAvailable() - 1); } DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); break; case MENUACTION_SPEAKERCONF: - if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) { + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { m_PrefsSpeakers -= changeValueBy; m_PrefsSpeakers = clamp(m_PrefsSpeakers, 0, 2); DMAudio.SetSpeakerConfig(m_PrefsSpeakers); @@ -4756,6 +4893,36 @@ CMenuManager::ProcessButtonPresses(void) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_TRIGGERFUNC: + FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu]; + if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) { + if (option.type == FEOPTION_SELECT) { + if (changeValueBy > 0) { + option.displayedValue++; + if (option.displayedValue >= option.numRightTexts) + option.displayedValue = 0; + } else { + option.displayedValue--; + if (option.displayedValue < 0) + option.displayedValue = option.numRightTexts - 1; + } + if (!option.onlyApplyOnEnter) { + option.changeFunc(option.displayedValue); + *option.value = option.displayedValue; + } + } else if (option.type == FEOPTION_DYNAMIC) { + option.buttonPressFunc(changeValueBy > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT); + } + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); + } + else { + debug("C- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, m_nCurrOption, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, option.screen, option.screenOptionOrder); + assert(0 && "Custom frontend options are borked"); + } + + break; +#endif } ProcessOnOffMenuOptions(); if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { @@ -4849,13 +5016,6 @@ CMenuManager::ProcessOnOffMenuOptions() DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; -#ifdef FREE_CAM - case MENUACTION_FREECAM: - TheCamera.bFreeCam = !TheCamera.bFreeCam; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - SaveSettings(); - break; -#endif } } @@ -4969,7 +5129,7 @@ CMenuManager::ProcessFileActions() } } -// --MIAMI: Done except DxInput things, are they even needed? +// --MIAMI: Done void CMenuManager::SwitchMenuOnAndOff() { @@ -4995,8 +5155,10 @@ CMenuManager::SwitchMenuOnAndOff() m_bMenuActive = !m_bMenuActive; if (m_bMenuActive) { - // TODO(Miami): DxInput?? - + if (_InputMouseNeedsExclusive()) { + _InputShutdownMouse(); + _InputInitialiseMouse(false); + } Initialise(); LoadAllTextures(); } else { @@ -5008,8 +5170,10 @@ CMenuManager::SwitchMenuOnAndOff() DoRWStuffEndOfFrame(); DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); DoRWStuffEndOfFrame(); - - // TODO(Miami): DxInput?? + if (_InputMouseNeedsExclusive()) { + _InputShutdownMouse(); + _InputInitialiseMouse(true); + } #ifdef PS2_LIKE_MENU bottomBarActive = false; @@ -5054,7 +5218,10 @@ CMenuManager::SwitchMenuOnAndOff() m_bMenuActive = true; m_OnlySaveMenu = true; - // TODO(Miami): DxInput?? + if (_InputMouseNeedsExclusive()) { + _InputShutdownMouse(); + _InputInitialiseMouse(false); + } Initialise(); LoadAllTextures(); @@ -5163,7 +5330,7 @@ CMenuManager::DrawQuitGameScreen(void) m_AllowNavigation = false; } -#ifdef MENU_MAP +#ifdef CUSTOM_MAP #define ZOOM(x, y, in) \ do { \ @@ -5177,15 +5344,17 @@ CMenuManager::DrawQuitGameScreen(void) break; \ \ m_fMapSize *= z2; \ - } while(0) \ + } while(0) + +#endif void CMenuManager::PrintMap(void) { - CFont::SetJustifyOn(); m_bMenuMapActive = true; CRadar::InitFrontEndMap(); +#ifdef CUSTOM_MAP // Just entered to map if (!bMapLoaded) { m_fMapSize = SCREEN_HEIGHT * 2.0f; @@ -5207,15 +5376,11 @@ CMenuManager::PrintMap(void) return; } } +#endif // Because m_fMapSize is half of the map length, and map consists of 3x3 tiles. float halfTile = m_fMapSize / 3.0f; - // Darken background a bit - CSprite2d::DrawRect(CRect(0, 0, - SCREEN_WIDTH, SCREEN_HEIGHT), - CRGBA(0, 0, 0, FadeIn(128))); - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); if (SCREEN_WIDTH >= m_fMapCenterX - m_fMapSize || SCREEN_HEIGHT >= m_fMapCenterY - m_fMapSize) { @@ -5265,6 +5430,7 @@ CMenuManager::PrintMap(void) CRadar::DrawBlips(); +#ifdef CUSTOM_MAP CVector2D mapPoint; mapPoint.x = m_nMousePosX; mapPoint.y = m_nMousePosY; @@ -5338,56 +5504,15 @@ CMenuManager::PrintMap(void) if (m_fMapCenterY - m_fMapSize > SCREEN_HEIGHT / 2) m_fMapCenterY = SCREEN_HEIGHT / 2 + m_fMapSize; - - m_bMenuMapActive = false; - - // CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(5.0f)); // From VC - // CFont::SetRightJustifyWrap(10.0f); - - CSprite2d::DrawRect(CRect(MENU_X(14.0f), SCREEN_STRETCH_FROM_BOTTOM(95.0f), - SCREEN_STRETCH_FROM_RIGHT(11.0f), SCREEN_STRETCH_FROM_BOTTOM(59.0f)), - CRGBA(MAPINFOBOX_COLOR.r, MAPINFOBOX_COLOR.g, MAPINFOBOX_COLOR.b, MAPINFOBOX_COLOR.a)); - - CFont::SetScale(MENU_X(0.4f), MENU_Y(0.7f)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); - - float nextX = MENU_X(30.0f), nextY = 95.0f; - wchar *text; -#ifdef MORE_LANGUAGES -#define TEXT_PIECE(key,extraSpace) \ - text = TheText.Get(key);\ - CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), text);\ - if (CFont::IsJapanese())\ - nextX += CFont::GetStringWidth_Jap(text) + MENU_X(extraSpace);\ - else\ - nextX += CFont::GetStringWidth(text, true) + MENU_X(extraSpace); -#else -#define TEXT_PIECE(key,extraSpace) \ - text = TheText.Get(key); CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), text); nextX += CFont::GetStringWidth(text, true) + MENU_X(extraSpace); #endif + m_bMenuMapActive = false; - TEXT_PIECE("FEC_MWF", 3.0f); - TEXT_PIECE("FEC_PGU", 1.0f); - TEXT_PIECE("FEC_IBT", 1.0f); - TEXT_PIECE("FEC_ZIN", 20.0f); - TEXT_PIECE("FEC_MWB", 3.0f); - TEXT_PIECE("FEC_PGD", 1.0f); - TEXT_PIECE("FEC_IBT", 1.0f); - CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEC_ZOT")); nextX = MENU_X(30.0f); nextY -= 11.0f; - TEXT_PIECE("FEC_UPA", 2.0f); - TEXT_PIECE("FEC_DWA", 2.0f); - TEXT_PIECE("FEC_LFA", 2.0f); - TEXT_PIECE("FEC_RFA", 2.0f); - TEXT_PIECE("FEC_MSL", 1.0f); - TEXT_PIECE("FEC_IBT", 1.0f); - CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEC_MOV")); nextX = MENU_X(30.0f); nextY -= 11.0f; - TEXT_PIECE("FEC_MSR", 2.0f); - TEXT_PIECE("FEC_IBT", 1.0f); - CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEC_TAR")); -#undef TEXT_PIECE + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(5.0f)); + CFont::SetRightJustifyWrap(SCREEN_SCALE_X(10.0f)); + DisplayHelperText("FEH_MPH"); } +#ifdef CUSTOM_MAP #undef ZOOM #endif @@ -5458,13 +5583,9 @@ CMenuManager::ConstructStatLine(int rowIdx) if (CStats::Record4x4Mayhem > 0) { STAT_LINE("FEST_RM", &CStats::Record4x4Mayhem, false, nil); } - if (CStats::LongestFlightInDodo > 0) { - STAT_LINE("FEST_LF", &CStats::LongestFlightInDodo, false, nil); - } if (CStats::TimeTakenDefuseMission > 0) { STAT_LINE("FEST_BD", &CStats::TimeTakenDefuseMission, false, nil); } - STAT_LINE("CAR_CRU", &CStats::CarsCrushed, false, nil); if (CStats::HighestScores[0] > 0) { STAT_LINE("FEST_BB", nil, false, nil); @@ -5492,7 +5613,6 @@ CMenuManager::ConstructStatLine(int rowIdx) float fTemp; STAT_LINE("FEST_DF", &(fTemp = CStats::DistanceTravelledOnFoot * MILES_IN_METER), true, nil); STAT_LINE("FEST_DC", &(fTemp = CStats::DistanceTravelledInVehicle * MILES_IN_METER), true, nil); - STAT_LINE("MMRAIN", &CStats::mmRain, false, nil); STAT_LINE("MXCARD", &(fTemp = CStats::MaximumJumpDistance * FEET_IN_METER), true, nil); STAT_LINE("MXCARJ", &(fTemp = CStats::MaximumJumpHeight * FEET_IN_METER), true, nil); break; @@ -5508,7 +5628,6 @@ CMenuManager::ConstructStatLine(int rowIdx) #endif STAT_LINE("FESTDFM", &CStats::DistanceTravelledOnFoot, true, nil); STAT_LINE("FESTDCM", &CStats::DistanceTravelledInVehicle, true, nil); - STAT_LINE("MMRAIN", &CStats::mmRain, false, nil); STAT_LINE("MXCARDM", &CStats::MaximumJumpDistance, true, nil); STAT_LINE("MXCARJM", &CStats::MaximumJumpHeight, true, nil); break; diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 4655c971..83d86d5b 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -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 BRIEFS_TOP_MARGIN 40.0f -#define BRIEFS_LINE_X 50.0f -#define BRIEFS_LINE_HEIGHT 60.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 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
\ No newline at end of file diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 92564289..39bbd364 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -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(); diff --git a/src/core/Game.h b/src/core/Game.h index 49a3e67c..67d83c00 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -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 }; diff --git a/src/core/General.h b/src/core/General.h index dbf169e9..7ab444a4 100644 --- a/src/core/General.h +++ b/src/core/General.h @@ -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 diff --git a/src/core/MenuScreens.h b/src/core/MenuScreens.cpp index cae65316..6fbf597b 100644 --- a/src/core/MenuScreens.h +++ b/src/core/MenuScreens.cpp @@ -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 diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index 99b9c8a8..8043bb6c 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -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++ ) diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index 2511ce9a..3c01a176 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -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 { diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index 475ca4d3..559a8cd6 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -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) { diff --git a/src/core/Radar.h b/src/core/Radar.h index 95b74b84..a36faaea 100644 --- a/src/core/Radar.h +++ b/src/core/Radar.h @@ -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); diff --git a/src/core/Ropes.cpp b/src/core/Ropes.cpp new file mode 100644 index 00000000..dbae9ee3 --- /dev/null +++ b/src/core/Ropes.cpp @@ -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; +} diff --git a/src/core/Ropes.h b/src/core/Ropes.h new file mode 100644 index 00000000..7930fa98 --- /dev/null +++ b/src/core/Ropes.h @@ -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); +}; diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp index b8ea0943..2e3a27b2 100644 --- a/src/core/Stats.cpp +++ b/src/core/Stats.cpp @@ -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); diff --git a/src/core/Stats.h b/src/core/Stats.h index 8588fef1..7dd527ea 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -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); diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index d560a695..3c32b856 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -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); diff --git a/src/core/Streaming.h b/src/core/Streaming.h index 8a92266f..569c06d8 100644 --- a/src/core/Streaming.h +++ b/src/core/Streaming.h @@ -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); diff --git a/src/core/SurfaceTable.h b/src/core/SurfaceTable.h index d8f9be3d..359ebd5c 100644 --- a/src/core/SurfaceTable.h +++ b/src/core/SurfaceTable.h @@ -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]; diff --git a/src/core/TempColModels.cpp b/src/core/TempColModels.cpp index c6a9d368..e12b48dd 100644 --- a/src/core/TempColModels.cpp +++ b/src/core/TempColModels.cpp @@ -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 diff --git a/src/core/User.cpp b/src/core/User.cpp index 56e37ac4..53196d03 100644 --- a/src/core/User.cpp +++ b/src/core/User.cpp @@ -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(); diff --git a/src/core/User.h b/src/core/User.h index 153ef57b..dd53a40a 100644 --- a/src/core/User.h +++ b/src/core/User.h @@ -16,6 +16,7 @@ public: void Init(); void Process(); void Display(); + void ProcessAfterFrontEndShutDown(); }; class CCurrentVehicle diff --git a/src/core/Wanted.cpp b/src/core/Wanted.cpp index 83407c56..c70a3ab5 100644 --- a/src/core/Wanted.cpp +++ b/src/core/Wanted.cpp @@ -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)) diff --git a/src/core/World.cpp b/src/core/World.cpp index 8399161f..7126b26f 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -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); diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp index 84b5ca29..3095b36d 100644 --- a/src/core/Zones.cpp +++ b/src/core/Zones.cpp @@ -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 diff --git a/src/core/common.h b/src/core/common.h index 3ead4f1d..d22c1715 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -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 diff --git a/src/core/config.h b/src/core/config.h index 7ba1a6fd..c9c65051 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -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 diff --git a/src/core/main.cpp b/src/core/main.cpp index 6e6092f3..d4ef8c4b 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -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(); diff --git a/src/core/patcher.cpp b/src/core/patcher.cpp deleted file mode 100644 index 83e06886..00000000 --- a/src/core/patcher.cpp +++ /dev/null @@ -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 diff --git a/src/core/patcher.h b/src/core/patcher.h deleted file mode 100644 index 2722b6fd..00000000 --- a/src/core/patcher.h +++ /dev/null @@ -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 }); diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 6032fc4a..81b2bfc0 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -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); |