diff options
author | withmorten <morten.with@gmail.com> | 2020-11-15 22:08:40 +0100 |
---|---|---|
committer | withmorten <morten.with@gmail.com> | 2020-11-15 22:08:40 +0100 |
commit | 0669df763c5e50d506ee0a57febe993d53543447 (patch) | |
tree | 7c4f7457a98dee5d6ebbc10179f4ce6d9f9e95cb /src/core | |
parent | revert frontend changes for invertlook4pad (diff) | |
parent | Make collision code placement more like original (+ small fixes) (diff) | |
download | re3-0669df763c5e50d506ee0a57febe993d53543447.tar re3-0669df763c5e50d506ee0a57febe993d53543447.tar.gz re3-0669df763c5e50d506ee0a57febe993d53543447.tar.bz2 re3-0669df763c5e50d506ee0a57febe993d53543447.tar.lz re3-0669df763c5e50d506ee0a57febe993d53543447.tar.xz re3-0669df763c5e50d506ee0a57febe993d53543447.tar.zst re3-0669df763c5e50d506ee0a57febe993d53543447.zip |
Diffstat (limited to '')
23 files changed, 674 insertions, 1418 deletions
diff --git a/src/core/Collision.cpp b/src/collision/Collision.cpp index d8603cd8..41997e32 100644 --- a/src/core/Collision.cpp +++ b/src/collision/Collision.cpp @@ -23,303 +23,8 @@ #include "Collision.h" #include "Frontend.h" - -// TODO: where do these go? - #ifdef VU_COLLISION - -struct VuTriangle -{ - // Compressed int16 but unpacked -#ifdef GTA_PS2 - uint128 v0; - uint128 v1; - uint128 v2; - uint128 plane; -#else - int32 v0[4]; - int32 v1[4]; - int32 v2[4]; - int32 plane[4]; -#endif -}; - -#ifndef GTA_PS2 -static int16 vi01; -static CVuVector vf01; -static CVuVector vf02; -static CVuVector vf03; - -CVuVector -DistanceBetweenSphereAndLine(const CVuVector ¢er, const CVuVector &p0, const CVuVector &line) -{ - // center VF12 - // p0 VF14 - // line VF15 - CVuVector ret; // VF16 - CVuVector p1 = p0+line; - CVuVector dist0 = center - p0; // VF20 - CVuVector dist1 = center - p1; // VF25 - float lenSq = line.MagnitudeSqr(); // VF21 - float distSq0 = dist0.MagnitudeSqr(); // VF22 - float distSq1 = dist1.MagnitudeSqr(); - float dot = DotProduct(dist0, line); // VF23 - if(dot < 0.0f){ - // not above line, closest to p0 - ret = p0; - ret.w = distSq0; - return ret; - } - float t = dot/lenSq; // param of nearest point on infinite line - if(t > 1.0f){ - // not above line, closest to p1 - ret = p1; - ret.w = distSq1; - return ret; - } - // closest to line - ret = p0 + line*t; - ret.w = (ret - center).MagnitudeSqr(); - return ret; -} -inline int SignFlags(const CVector &v) -{ - int f = 0; - if(v.x < 0.0f) f |= 1; - if(v.y < 0.0f) f |= 2; - if(v.z < 0.0f) f |= 4; - return f; -} -#endif - -extern "C" void -LineToTriangleCollision(const CVuVector &p0, const CVuVector &p1, - const CVuVector &v0, const CVuVector &v1, const CVuVector &v2, - const CVuVector &plane) -{ -#ifdef GTA_PS2 - __asm__ volatile ( - ".set noreorder\n" - "lqc2 vf12, 0x0(%0)\n" - "lqc2 vf13, 0x0(%1)\n" - "lqc2 vf14, 0x0(%2)\n" - "lqc2 vf15, 0x0(%3)\n" - "lqc2 vf16, 0x0(%4)\n" - "lqc2 vf17, 0x0(%5)\n" - "vcallms Vu0LineToTriangleCollisionStart\n" - ".set reorder\n" - : - : "r" (&p0), "r" (&p1), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane) - ); -#else - float dot0 = DotProduct(plane, p0); - float dot1 = DotProduct(plane, p1); - float dist0 = plane.w - dot0; - float dist1 = plane.w - dot1; - - // if points are on the same side, no collision - if(dist0 * dist1 > 0.0f){ - vi01 = 0; - return; - } - - CVuVector diff = p1 - p0; - float t = dist0/(dot1 - dot0); - CVuVector p = p0 + diff*t; - p.w = 0.0f; - vf01 = p; - vf03.x = t; - - // Check if point is inside - CVector cross1 = CrossProduct(p-v0, v1-v0); - CVector cross2 = CrossProduct(p-v1, v2-v1); - CVector cross3 = CrossProduct(p-v2, v0-v2); - // Only check relevant directions - int flagmask = 0; - if(Abs(plane.x) > 0.5f) flagmask |= 1; - if(Abs(plane.y) > 0.5f) flagmask |= 2; - if(Abs(plane.z) > 0.5f) flagmask |= 4; - int flags1 = SignFlags(cross1) & flagmask; - int flags2 = SignFlags(cross2) & flagmask; - int flags3 = SignFlags(cross3) & flagmask; - // inside if on the same side of all edges - if(flags1 != flags2 || flags1 != flags3){ - vi01 = 0; - return; - } - vi01 = 1; - vf02 = plane; - return; -#endif -} - -extern "C" void -LineToTriangleCollisionCompressed(const CVuVector &p0, const CVuVector &p1, VuTriangle &tri) -{ -#ifdef GTA_PS2 - __asm__ volatile ( - ".set noreorder\n" - "lqc2 vf12, 0x0(%0)\n" - "lqc2 vf13, 0x0(%1)\n" - "lqc2 vf14, 0x0(%2)\n" - "lqc2 vf15, 0x10(%2)\n" - "lqc2 vf16, 0x20(%2)\n" - "lqc2 vf17, 0x30(%2)\n" - "vcallms Vu0LineToTriangleCollisionCompressedStart\n" - ".set reorder\n" - : - : "r" (&p0), "r" (&p1), "r" (&tri) - ); -#else - CVuVector v0, v1, v2, plane; - v0.x = tri.v0[0]/128.0f; - v0.y = tri.v0[1]/128.0f; - v0.z = tri.v0[2]/128.0f; - v0.w = tri.v0[3]/128.0f; - v1.x = tri.v1[0]/128.0f; - v1.y = tri.v1[1]/128.0f; - v1.z = tri.v1[2]/128.0f; - v1.w = tri.v1[3]/128.0f; - v2.x = tri.v2[0]/128.0f; - v2.y = tri.v2[1]/128.0f; - v2.z = tri.v2[2]/128.0f; - v2.w = tri.v2[3]/128.0f; - plane.x = tri.plane[0]/4096.0f; - plane.y = tri.plane[1]/4096.0f; - plane.z = tri.plane[2]/4096.0f; - plane.w = tri.plane[3]/128.0f; - LineToTriangleCollision(p0, p1, v0, v1, v2, plane); -#endif -} - -extern "C" void -SphereToTriangleCollision(const CVuVector &sph, - const CVuVector &v0, const CVuVector &v1, const CVuVector &v2, - const CVuVector &plane) -{ -#ifdef GTA_PS2 - __asm__ volatile ( - ".set noreorder\n" - "lqc2 vf12, 0x0(%0)\n" - "lqc2 vf14, 0x0(%1)\n" - "lqc2 vf15, 0x0(%2)\n" - "lqc2 vf16, 0x0(%3)\n" - "lqc2 vf17, 0x0(%4)\n" - "vcallms Vu0SphereToTriangleCollisionStart\n" - ".set reorder\n" - : - : "r" (&sph), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane) - ); -#else - float planedist = DotProduct(plane, sph) - plane.w; // VF02 - if(Abs(planedist) > sph.w){ - vi01 = 0; - return; - } - // point on plane - CVuVector p = sph - planedist*plane; - p.w = 0.0f; - vf01 = p; - planedist = Abs(planedist); - // edges - CVuVector v01 = v1 - v0; - CVuVector v12 = v2 - v1; - CVuVector v20 = v0 - v2; - // VU code calculates normal again for some weird reason... - // Check sides of point - CVector cross1 = CrossProduct(p-v0, v01); - CVector cross2 = CrossProduct(p-v1, v12); - CVector cross3 = CrossProduct(p-v2, v20); - // Only check relevant directions - int flagmask = 0; - if(Abs(plane.x) > 0.1f) flagmask |= 1; - if(Abs(plane.y) > 0.1f) flagmask |= 2; - if(Abs(plane.z) > 0.1f) flagmask |= 4; - int nflags = SignFlags(plane) & flagmask; - int flags1 = SignFlags(cross1) & flagmask; - int flags2 = SignFlags(cross2) & flagmask; - int flags3 = SignFlags(cross3) & flagmask; - int testcase = 0; - CVuVector closest(0.0f, 0.0f, 0.0f); // VF04 - if(flags1 == nflags){ - closest += v2; - testcase++; - } - if(flags2 == nflags){ - closest += v0; - testcase++; - } - if(flags3 == nflags){ - closest += v1; - testcase++; - } - if(testcase == 3){ - // inside triangle - dist to plane already checked - vf02 = plane; - vf02.w = vf03.x = planedist; - vi01 = 1; - }else if(testcase == 1){ - // outside two sides - closest to point opposide inside edge - vf01 = closest; - vf02 = sph - closest; - float distSq = vf02.MagnitudeSqr(); - vi01 = sph.w*sph.w > distSq; - vf03.x = Sqrt(distSq); - vf02 *= 1.0f/vf03.x; - }else{ - // inside two sides - closest to third edge - if(flags1 != nflags) - closest = DistanceBetweenSphereAndLine(sph, v0, v01); - else if(flags2 != nflags) - closest = DistanceBetweenSphereAndLine(sph, v1, v12); - else - closest = DistanceBetweenSphereAndLine(sph, v2, v20); - vi01 = sph.w*sph.w > closest.w; - vf01 = closest; - vf02 = sph - closest; - vf03.x = Sqrt(closest.w); - vf02 *= 1.0f/vf03.x; - } -#endif -} - -extern "C" void -SphereToTriangleCollisionCompressed(const CVuVector &sph, VuTriangle &tri) -{ -#ifdef GTA_PS2 - __asm__ volatile ( - ".set noreorder\n" - "lqc2 vf12, 0x0(%0)\n" - "lqc2 vf14, 0x0(%1)\n" - "lqc2 vf15, 0x10(%1)\n" - "lqc2 vf16, 0x20(%1)\n" - "lqc2 vf17, 0x30(%1)\n" - "vcallms Vu0SphereToTriangleCollisionCompressedStart\n" - ".set reorder\n" - : - : "r" (&sph), "r" (&tri) - ); -#else - CVuVector v0, v1, v2, plane; - v0.x = tri.v0[0]/128.0f; - v0.y = tri.v0[1]/128.0f; - v0.z = tri.v0[2]/128.0f; - v0.w = tri.v0[3]/128.0f; - v1.x = tri.v1[0]/128.0f; - v1.y = tri.v1[1]/128.0f; - v1.z = tri.v1[2]/128.0f; - v1.w = tri.v1[3]/128.0f; - v2.x = tri.v2[0]/128.0f; - v2.y = tri.v2[1]/128.0f; - v2.z = tri.v2[2]/128.0f; - v2.w = tri.v2[3]/128.0f; - plane.x = tri.plane[0]/4096.0f; - plane.y = tri.plane[1]/4096.0f; - plane.z = tri.plane[2]/4096.0f; - plane.w = tri.plane[3]/128.0f; - SphereToTriangleCollision(sph, v0, v1, v2, plane); -#endif -} +#include "VuCollision.h" inline int GetVUresult(void) @@ -362,17 +67,6 @@ GetVUresult(CVuVector &point, CVuVector &normal, float &dist) #endif - -enum Direction -{ - DIR_X_POS, - DIR_X_NEG, - DIR_Y_POS, - DIR_Y_NEG, - DIR_Z_POS, - DIR_Z_NEG, -}; - eLevelName CCollision::ms_collisionInMemory; CLinkList<CColModel*> CCollision::ms_colModelCache; @@ -2412,11 +2106,12 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA, assert(modelA.numLines <= MAXNUMLINES); // From model A space to model B space - Invert(matrixB, matAB); + matAB = Invert(matrixB, matAB); matAB *= matrixA; CColSphere bsphereAB; // bounding sphere of A in B space - bsphereAB.Set(modelA.boundingSphere.radius, matAB * modelA.boundingSphere.center); + bsphereAB.radius = modelA.boundingSphere.radius; + bsphereAB.center = matAB * modelA.boundingSphere.center; if(!TestSphereBox(bsphereAB, modelB.boundingBox)) return 0; // B to A space @@ -2449,7 +2144,8 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA, int numBoxesB = 0; int numTrianglesB = 0; for(i = 0; i < modelB.numSpheres; i++){ - s.Set(modelB.spheres[i].radius, matBA * modelB.spheres[i].center); + s.radius = modelB.spheres[i].radius; + s.center = matBA * modelB.spheres[i].center; if(TestSphereBox(s, modelA.boundingBox)) aSphereIndicesB[numSpheresB++] = i; } @@ -3037,254 +2733,4 @@ CCollision::DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); -} - - -/* - * ColModel code - */ - -void -CColSphere::Set(float radius, const CVector ¢er, uint8 surf, uint8 piece) -{ - this->radius = radius; - this->center = center; - this->surface = surf; - this->piece = piece; -} - -void -CColBox::Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece) -{ - this->min = min; - this->max = max; - this->surface = surf; - this->piece = piece; -} - -void -CColLine::Set(const CVector &p0, const CVector &p1) -{ - this->p0 = p0; - this->p1 = p1; -} - -void -CColTriangle::Set(const CompressedVector *, int a, int b, int c, uint8 surf, uint8 piece) -{ - this->a = a; - this->b = b; - this->c = c; - this->surface = surf; -} - -#ifdef VU_COLLISION -void -CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc) -{ - CVector norm = CrossProduct(vc-va, vb-va); - norm.Normalise(); - float d = DotProduct(norm, va); - normal.x = norm.x*4096.0f; - normal.y = norm.y*4096.0f; - normal.z = norm.z*4096.0f; - dist = d*128.0f; -} -#else -void -CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc) -{ - normal = CrossProduct(vc-va, vb-va); - normal.Normalise(); - dist = DotProduct(normal, va); - CVector an(Abs(normal.x), Abs(normal.y), Abs(normal.z)); - // find out largest component and its direction - if(an.x > an.y && an.x > an.z) - dir = normal.x < 0.0f ? DIR_X_NEG : DIR_X_POS; - else if(an.y > an.z) - dir = normal.y < 0.0f ? DIR_Y_NEG : DIR_Y_POS; - else - dir = normal.z < 0.0f ? DIR_Z_NEG : DIR_Z_POS; -} -#endif - -CColModel::CColModel(void) -{ - numSpheres = 0; - spheres = nil; - numLines = 0; - lines = nil; - numBoxes = 0; - boxes = nil; - numTriangles = 0; - vertices = nil; - triangles = nil; - trianglePlanes = nil; - level = CGame::currLevel; - ownsCollisionVolumes = true; -} - -CColModel::~CColModel(void) -{ - RemoveCollisionVolumes(); - RemoveTrianglePlanes(); -} - -void -CColModel::RemoveCollisionVolumes(void) -{ - if(ownsCollisionVolumes){ - RwFree(spheres); - RwFree(lines); - RwFree(boxes); - RwFree(vertices); - RwFree(triangles); - } - numSpheres = 0; - numLines = 0; - numBoxes = 0; - numTriangles = 0; - spheres = nil; - lines = nil; - boxes = nil; - vertices = nil; - triangles = nil; -} - -void -CColModel::CalculateTrianglePlanes(void) -{ - // HACK: allocate space for one more element to stuff the link pointer into - trianglePlanes = (CColTrianglePlane*)RwMalloc(sizeof(CColTrianglePlane) * (numTriangles+1)); - for(int i = 0; i < numTriangles; i++) - trianglePlanes[i].Set(vertices, triangles[i]); -} - -void -CColModel::RemoveTrianglePlanes(void) -{ - RwFree(trianglePlanes); - trianglePlanes = nil; -} - -void -CColModel::SetLinkPtr(CLink<CColModel*> *lptr) -{ - assert(trianglePlanes); - *(CLink<CColModel*>**)ALIGNPTR(&trianglePlanes[numTriangles]) = lptr; -} - -CLink<CColModel*>* -CColModel::GetLinkPtr(void) -{ - assert(trianglePlanes); - return *(CLink<CColModel*>**)ALIGNPTR(&trianglePlanes[numTriangles]); -} - -void -CColModel::GetTrianglePoint(CVector &v, int i) const -{ - v = vertices[i].Get(); -} - -CColModel& -CColModel::operator=(const CColModel &other) -{ - int i; - int numVerts; - - boundingSphere = other.boundingSphere; - boundingBox = other.boundingBox; - - // copy spheres - if(other.numSpheres){ - if(numSpheres != other.numSpheres){ - numSpheres = other.numSpheres; - if(spheres) - RwFree(spheres); - spheres = (CColSphere*)RwMalloc(numSpheres*sizeof(CColSphere)); - } - for(i = 0; i < numSpheres; i++) - spheres[i] = other.spheres[i]; - }else{ - numSpheres = 0; - if(spheres) - RwFree(spheres); - spheres = nil; - } - - // copy lines - if(other.numLines){ - if(numLines != other.numLines){ - numLines = other.numLines; - if(lines) - RwFree(lines); - lines = (CColLine*)RwMalloc(numLines*sizeof(CColLine)); - } - for(i = 0; i < numLines; i++) - lines[i] = other.lines[i]; - }else{ - numLines = 0; - if(lines) - RwFree(lines); - lines = nil; - } - - // copy boxes - if(other.numBoxes){ - if(numBoxes != other.numBoxes){ - numBoxes = other.numBoxes; - if(boxes) - RwFree(boxes); - boxes = (CColBox*)RwMalloc(numBoxes*sizeof(CColBox)); - } - for(i = 0; i < numBoxes; i++) - boxes[i] = other.boxes[i]; - }else{ - numBoxes = 0; - if(boxes) - RwFree(boxes); - boxes = nil; - } - - // copy mesh - if(other.numTriangles){ - // copy vertices - numVerts = 0; - for(i = 0; i < other.numTriangles; i++){ - if(other.triangles[i].a > numVerts) - numVerts = other.triangles[i].a; - if(other.triangles[i].b > numVerts) - numVerts = other.triangles[i].b; - if(other.triangles[i].c > numVerts) - numVerts = other.triangles[i].c; - } - numVerts++; - if(vertices) - RwFree(vertices); - if(numVerts){ - vertices = (CompressedVector*)RwMalloc(numVerts*sizeof(CompressedVector)); - for(i = 0; i < numVerts; i++) - vertices[i] = other.vertices[i]; - } - - // copy triangles - if(numTriangles != other.numTriangles){ - numTriangles = other.numTriangles; - if(triangles) - RwFree(triangles); - triangles = (CColTriangle*)RwMalloc(numTriangles*sizeof(CColTriangle)); - } - for(i = 0; i < numTriangles; i++) - triangles[i] = other.triangles[i]; - }else{ - numTriangles = 0; - if(triangles) - RwFree(triangles); - triangles = nil; - if(vertices) - RwFree(vertices); - vertices = nil; - } - return *this; -} +}
\ No newline at end of file diff --git a/src/core/TempColModels.cpp b/src/collision/TempColModels.cpp index f6796909..849eb01e 100644 --- a/src/core/TempColModels.cpp +++ b/src/collision/TempColModels.cpp @@ -1,7 +1,6 @@ #include "common.h" #include "TempColModels.h" -#include "SurfaceTable.h" CColModel CTempColModels::ms_colModelPed1; CColModel CTempColModels::ms_colModelPed2; @@ -45,13 +44,13 @@ CTempColModels::Initialise(void) int i; - ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0); + ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f)); 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), SURFACE_DEFAULT, 0); - ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0); + ms_colModelCutObj[i].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_GENERIC; } @@ -73,8 +72,8 @@ CTempColModels::Initialise(void) s_aPedSpheres[i].piece = 0; } - ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f), SURFACE_DEFAULT, 0); + ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f)); SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres); // Ped 2 Spheres @@ -92,8 +91,8 @@ CTempColModels::Initialise(void) s_aPed2Spheres[i].piece = 0; } - ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f), SURFACE_DEFAULT, 0); + ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f)); SET_COLMODEL_SPHERES(ms_colModelPed2, s_aPed2Spheres); @@ -118,8 +117,8 @@ CTempColModels::Initialise(void) s_aPedGSpheres[2].piece = 0; s_aPedGSpheres[3].piece = 6; - ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f), SURFACE_DEFAULT, 0); + ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f)); SET_COLMODEL_SPHERES(ms_colModelPedGroundHit, s_aPedGSpheres); @@ -142,8 +141,8 @@ CTempColModels::Initialise(void) s_aDoorSpheres[i].piece = 0; } - ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f), SURFACE_DEFAULT, 0); + ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f)); + ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f)); SET_COLMODEL_SPHERES(ms_colModelDoor1, s_aDoorSpheres); @@ -162,8 +161,8 @@ CTempColModels::Initialise(void) s_aBumperSpheres[i].piece = 0; } - ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, 0.2f), SURFACE_DEFAULT, 0); + ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f)); + ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, 0.2f)); SET_COLMODEL_SPHERES(ms_colModelBumper1, s_aBumperSpheres); @@ -182,8 +181,8 @@ CTempColModels::Initialise(void) s_aPanelSpheres[i].piece = 0; } - ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f), SURFACE_DEFAULT, 0); + ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f)); SET_COLMODEL_SPHERES(ms_colModelPanel1, s_aPanelSpheres); @@ -202,8 +201,8 @@ CTempColModels::Initialise(void) s_aBonnetSpheres[i].piece = 0; } - ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f), SURFACE_DEFAULT, 0); + ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f)); + ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f)); SET_COLMODEL_SPHERES(ms_colModelBonnet1, s_aBonnetSpheres); @@ -222,8 +221,8 @@ CTempColModels::Initialise(void) s_aBootSpheres[i].piece = 0; } - ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f), SURFACE_DEFAULT, 0); + ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f)); + ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f)); SET_COLMODEL_SPHERES(ms_colModelBoot1, s_aBootSpheres); @@ -244,8 +243,8 @@ CTempColModels::Initialise(void) s_aWheelSpheres[i].piece = 0; } - ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f), SURFACE_DEFAULT, 0); + ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f)); SET_COLMODEL_SPHERES(ms_colModelWheel1, s_aWheelSpheres); @@ -266,8 +265,8 @@ CTempColModels::Initialise(void) s_aBodyPartSpheres1[i].piece = 0; } - ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f), SURFACE_DEFAULT, 0); + ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f)); + ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f)); SET_COLMODEL_SPHERES(ms_colModelBodyPart1, s_aBodyPartSpheres1); @@ -288,8 +287,8 @@ CTempColModels::Initialise(void) s_aBodyPartSpheres2[i].piece = 0; } - ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f), SURFACE_DEFAULT, 0); + ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f)); + ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f)); SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2); diff --git a/src/core/TempColModels.h b/src/collision/TempColModels.h index 3e1dd5e1..3e1dd5e1 100644 --- a/src/core/TempColModels.h +++ b/src/collision/TempColModels.h diff --git a/src/core/vu0Collision.dsm b/src/collision/vu0Collision.dsm index 657c8b81..657c8b81 100644 --- a/src/core/vu0Collision.dsm +++ b/src/collision/vu0Collision.dsm diff --git a/src/core/vu0Collision_1.s b/src/collision/vu0Collision_1.s index 055c8640..055c8640 100644 --- a/src/core/vu0Collision_1.s +++ b/src/collision/vu0Collision_1.s diff --git a/src/core/vu0Collision_2.s b/src/collision/vu0Collision_2.s index 716c29ac..716c29ac 100644 --- a/src/core/vu0Collision_2.s +++ b/src/collision/vu0Collision_2.s diff --git a/src/core/CdStream.cpp b/src/core/CdStream.cpp index c11fb72a..1d39aa52 100644 --- a/src/core/CdStream.cpp +++ b/src/core/CdStream.cpp @@ -242,8 +242,15 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size) else return STREAM_SUCCESS; } - + +#ifdef BIG_IMG + LARGE_INTEGER liDistanceToMove; + liDistanceToMove.QuadPart = _GET_OFFSET(offset); + liDistanceToMove.QuadPart *= CDSTREAM_SECTOR_SIZE; + SetFilePointerEx(hImage, liDistanceToMove, nil, FILE_BEGIN); +#else SetFilePointer(hImage, _GET_OFFSET(offset) * CDSTREAM_SECTOR_SIZE, nil, FILE_BEGIN); +#endif DWORD NumberOfBytesRead; diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index 5c8d1b16..35a90a74 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -429,7 +429,7 @@ void *CdStreamThread(void *param) ASSERT(pChannel->hFile >= 0); ASSERT(pChannel->pBuffer != nil ); - lseek(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, SEEK_SET); + lseek(pChannel->hFile, (size_t)pChannel->nSectorOffset * (size_t)CDSTREAM_SECTOR_SIZE, SEEK_SET); if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) { // pChannel->nSectorsToRead == 0 at this point means we wanted to flush channel // STREAM_WAITING is a little hack to make CStreaming not process this data diff --git a/src/core/Collision.h b/src/core/Collision.h deleted file mode 100644 index da94dd34..00000000 --- a/src/core/Collision.h +++ /dev/null @@ -1,254 +0,0 @@ -#pragma once - -#include "templates.h" -#include "Game.h" // for eLevelName -#ifdef VU_COLLISION -#include "VuVector.h" -#endif - -// If you spawn many tanks at once, you will see that collisions of two entity exceeds 32. -#if defined(FIX_BUGS) && !defined(SQUEEZE_PERFORMANCE) -#define MAX_COLLISION_POINTS 64 -#else -#define MAX_COLLISION_POINTS 32 -#endif - -struct CompressedVector -{ -#ifdef COMPRESSED_COL_VECTORS - int16 x, y, z; - CVector Get(void) const { return CVector(x, y, z)/128.0f; }; - void Set(float x, float y, float z) { this->x = x*128.0f; this->y = y*128.0f; this->z = z*128.0f; }; -#ifdef GTA_PS2 - void Unpack(uint128 &qword) const { - __asm__ volatile ( - "lh $8, 0(%1)\n" - "lh $9, 2(%1)\n" - "lh $10, 4(%1)\n" - "pextlw $10, $8\n" - "pextlw $2, $9, $10\n" - "sq $2, %0\n" - : "=m" (qword) - : "r" (this) - : "$8", "$9", "$10", "$2" - ); - } -#else - void Unpack(int32 *qword) const { - qword[0] = x; - qword[1] = y; - qword[2] = z; - qword[3] = 0; // junk - } -#endif -#else - float x, y, z; - CVector Get(void) const { return CVector(x, y, z); }; - void Set(float x, float y, float z) { this->x = x; this->y = y; this->z = z; }; -#endif -}; - -struct CColSphere -{ - // NB: this has to be compatible with a CVuVector - CVector center; - float radius; - uint8 surface; - uint8 piece; - - void Set(float radius, const CVector ¢er, uint8 surf, uint8 piece); - void Set(float radius, const CVector ¢er) { this->center = center; this->radius = radius; } -}; - -struct CColBox -{ - CVector min; - CVector max; - uint8 surface; - uint8 piece; - - void Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece); - CVector GetSize(void) { return max - min; } -}; - -struct CColLine -{ - // NB: this has to be compatible with two CVuVectors - CVector p0; - int pad0; - CVector p1; - int pad1; - - CColLine(void) { }; - CColLine(const CVector &p0, const CVector &p1) { this->p0 = p0; this->p1 = p1; }; - void Set(const CVector &p0, const CVector &p1); -}; - -struct CColTriangle -{ - uint16 a; - uint16 b; - uint16 c; - uint8 surface; - - void Set(const CompressedVector *v, int a, int b, int c, uint8 surf, uint8 piece); -}; - -struct CColTrianglePlane -{ -#ifdef VU_COLLISION - CompressedVector normal; - int16 dist; - - void Set(const CVector &va, const CVector &vb, const CVector &vc); - void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); } - void GetNormal(CVector &n) const { n.x = normal.x/4096.0f; n.y = normal.y/4096.0f; n.z = normal.z/4096.0f; } - float CalcPoint(const CVector &v) const { CVector n; GetNormal(n); return DotProduct(n, v) - dist/128.0f; }; -#ifdef GTA_PS2 - void Unpack(uint128 &qword) const { - __asm__ volatile ( - "lh $8, 0(%1)\n" - "lh $9, 2(%1)\n" - "lh $10, 4(%1)\n" - "lh $11, 6(%1)\n" - "pextlw $10, $8\n" - "pextlw $11, $9\n" - "pextlw $2, $11, $10\n" - "sq $2, %0\n" - : "=m" (qword) - : "r" (this) - : "$8", "$9", "$10", "$11", "$2" - ); - } -#else - void Unpack(int32 *qword) const { - qword[0] = normal.x; - qword[1] = normal.y; - qword[2] = normal.z; - qword[3] = dist; - } -#endif -#else - CVector normal; - float dist; - uint8 dir; - - void Set(const CVector &va, const CVector &vb, const CVector &vc); - void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); } - void GetNormal(CVector &n) const { n = normal; } - float CalcPoint(const CVector &v) const { return DotProduct(normal, v) - dist; }; -#endif -}; - -struct CColPoint -{ - CVector point; - int pad1; - // the surface normal on the surface of point - CVector normal; - int pad2; - uint8 surfaceA; - uint8 pieceA; - uint8 surfaceB; - uint8 pieceB; - float depth; - - void Set(float depth, uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) { - this->depth = depth; - this->surfaceA = surfA; - this->pieceA = pieceA; - this->surfaceB = surfB; - this->pieceB = pieceB; - } - void Set(uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) { - this->surfaceA = surfA; - this->pieceA = pieceA; - this->surfaceB = surfB; - this->pieceB = pieceB; - } -}; - -struct CStoredCollPoly -{ -#ifdef VU_COLLISION - CVuVector verts[3]; -#else - CVector verts[3]; -#endif - bool valid; -}; - -struct CColModel -{ - CColSphere boundingSphere; - CColBox boundingBox; - int16 numSpheres; - int16 numLines; - int16 numBoxes; - int16 numTriangles; - int32 level; - bool ownsCollisionVolumes; // missing on PS2 - CColSphere *spheres; - CColLine *lines; - CColBox *boxes; - CompressedVector *vertices; - CColTriangle *triangles; - CColTrianglePlane *trianglePlanes; - - CColModel(void); - ~CColModel(void); - void RemoveCollisionVolumes(void); - void CalculateTrianglePlanes(void); - void RemoveTrianglePlanes(void); - CLink<CColModel*> *GetLinkPtr(void); - void SetLinkPtr(CLink<CColModel*>*); - void GetTrianglePoint(CVector &v, int i) const; - - CColModel& operator=(const CColModel& other); -}; - -class CCollision -{ -public: - static eLevelName ms_collisionInMemory; - static CLinkList<CColModel*> ms_colModelCache; -#ifdef NO_ISLAND_LOADING - static bool bAlreadyLoaded; -#endif - - static void Init(void); - static void Shutdown(void); - static void Update(void); - static void LoadCollisionWhenINeedIt(bool changeLevel); - static void SortOutCollisionAfterLoad(void); - static void LoadCollisionScreen(eLevelName level); - static void DrawColModel(const CMatrix &mat, const CColModel &colModel); - static void DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id); - - static void CalculateTrianglePlanes(CColModel *model); - - // all these return true if there's a collision - static bool TestSphereSphere(const CColSphere &s1, const CColSphere &s2); - static bool TestSphereBox(const CColSphere &sph, const CColBox &box); - static bool TestLineBox(const CColLine &line, const CColBox &box); - static bool TestVerticalLineBox(const CColLine &line, const CColBox &box); - static bool TestLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane); - static bool TestLineSphere(const CColLine &line, const CColSphere &sph); - static bool TestSphereTriangle(const CColSphere &sphere, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane); - static bool TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough); - - static bool ProcessSphereSphere(const CColSphere &s1, const CColSphere &s2, CColPoint &point, float &mindistsq); - static bool ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoint &point, float &mindistsq); - static bool ProcessLineBox(const CColLine &line, const CColBox &box, CColPoint &point, float &mindist); - static bool ProcessVerticalLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist, CStoredCollPoly *poly); - static bool ProcessLineTriangle(const CColLine &line , const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist); - static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist); - static bool ProcessSphereTriangle(const CColSphere &sph, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq); - static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough); - static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly); - static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists); - static bool IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CColPoint &point, CStoredCollPoly *poly); - - static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point); - static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point, CVector &closest); -}; diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp index 504b832c..cadba7f2 100644 --- a/src/core/ControllerConfig.cpp +++ b/src/core/ControllerConfig.cpp @@ -2500,10 +2500,11 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ }} + +const char *XboxButtons_noIcons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK"); + #ifdef BUTTON_ICONS const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK"); -#else -const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK"); #endif @@ -2524,12 +2525,12 @@ const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", #define PS2_SQUARE "SQUARE" #endif +const char *PlayStationButtons_noIcons[][MAX_CONTROLLERACTIONS] = + CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT"); + #ifdef BUTTON_ICONS const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT"); -#else -const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] = - CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT"); #endif #undef PS2_TRIANGLE @@ -2547,7 +2548,11 @@ void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar * wchar wstr[16]; // TODO: INI and/or menu setting for Xbox/PS switch - const char *(*Buttons)[MAX_CONTROLLERACTIONS] = XboxButtons; +#ifdef BUTTON_ICONS + const char *(*Buttons)[MAX_CONTROLLERACTIONS] = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons; +#else + const char *(*Buttons)[MAX_CONTROLLERACTIONS] = XboxButtons_noIcons; +#endif assert(Buttons[CPad::GetPad(0)->Mode][action] != nil); // we cannot use these AsciiToUnicode(Buttons[CPad::GetPad(0)->Mode][action], wstr); diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index aadafc29..3f731658 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -332,6 +332,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) { @@ -343,6 +353,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); } @@ -368,6 +379,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 @@ -393,6 +405,7 @@ CFileLoader::LoadClumpFile(RwStream *stream, uint32 id) if (mi->GetModelType() == MITYPE_PED && id != 0 && RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)) { // Read LOD ped clump = RpClumpStreamRead(stream); + InitClump(clump); if(clump){ ((CPedModelInfo*)mi)->SetLowDetailClump(clump); RpClumpDestroy(clump); @@ -423,6 +436,7 @@ CFileLoader::FinishLoadClumpFile(RwStream *stream, uint32 id) clump = RpClumpGtaStreamRead2(stream); if(clump){ + InitClump(clump); mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id); mi->SetClump(clump); return true; @@ -443,6 +457,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); @@ -806,6 +821,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; } diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index cf25e1b9..4be23b77 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -41,14 +41,7 @@ #define TIDY_UP_PBP // ProcessButtonPresses #define MAX_VISIBLE_LIST_ROW 30 #define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result - -#ifdef USE_PRECISE_MEASUREMENT_CONVERTION -#define MILES_IN_METER 0.000621371192f -#define FEET_IN_METER 3.28084f -#else -#define MILES_IN_METER 0.00059880241f -#define FEET_IN_METER 3.33f -#endif +#define SCROLLABLE_PAGES #ifdef SCROLLABLE_STATS_PAGE #define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS) @@ -56,6 +49,34 @@ #define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS || screen == MENUPAGE_STATS) #endif +#define hasNativeList(screen) (screen == MENUPAGE_MULTIPLAYER_FIND_GAME || screen == MENUPAGE_SKIN_SELECT \ + || screen == MENUPAGE_KEYBOARD_CONTROLS) + +#ifdef SCROLLABLE_PAGES +#define MAX_VISIBLE_OPTION 12 +#define MAX_VISIBLE_OPTION_ON_SCREEN (hasNativeList(m_nCurrScreen) ? MAX_VISIBLE_LIST_ROW : MAX_VISIBLE_OPTION) + +int GetOptionCount(int screen) +{ + int i = 0; + for (; i < NUM_MENUROWS && aScreens[screen].m_aEntries[i].m_Action != MENUACTION_NOTHING; i++); + return i; +} + +#define SETUP_SCROLLING(screen) \ + if (!hasNativeList(screen)) { \ + m_nTotalListRow = GetOptionCount(screen); \ + if (m_nTotalListRow > MAX_VISIBLE_OPTION) { \ + m_nSelectedListRow = 0; \ + m_nFirstVisibleRowOnList = 0; \ + m_nScrollbarTopMargin = 0; \ + } \ + } +#else +#define MAX_VISIBLE_OPTION_ON_SCREEN MAX_VISIBLE_LIST_ROW +#define SETUP_SCROLLING(screen) +#endif + #ifdef TRIANGLE_BACK_BUTTON #define GetBackJustUp GetTriangleJustUp #define GetBackJustDown GetTriangleJustDown @@ -80,13 +101,40 @@ float CMenuManager::fMapCenterX; BottomBarOption bbNames[8]; int bbTabCount = 0; bool bottomBarActive = false; -bool reverseAlpha = false; int pendingScreen = -1; int pendingOption = -1; int curBottomBarOption = -1; int hoveredBottomBarOption = -1; #endif +#ifdef CUTSCENE_BORDERS_SWITCH +bool CMenuManager::m_PrefsCutsceneBorders = true; +#endif + +#ifdef MULTISAMPLING +int8 CMenuManager::m_nPrefsMSAALevel = 0; +int8 CMenuManager::m_nDisplayMSAALevel = 0; +#endif + +#ifdef NO_ISLAND_LOADING +int8 CMenuManager::m_PrefsIslandLoading = ISLAND_LOADING_LOW; +#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 +const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); +#else +const CRGBA TEXT_COLOR = CRGBA(235, 170, 50, 255); // PC briefs text color +#endif + +#ifdef USE_PRECISE_MEASUREMENT_CONVERTION +#define MILES_IN_METER 0.000621371192f +#define FEET_IN_METER 3.28084f +#else +#define MILES_IN_METER 0.00059880241f +#define FEET_IN_METER 3.33f +#endif + int32 CMenuManager::OS_Language = LANG_ENGLISH; int8 CMenuManager::m_PrefsUseVibration; int8 CMenuManager::m_DisplayControllerOnFoot; @@ -112,31 +160,11 @@ int8 CMenuManager::m_bFrontEnd_ReloadObrTxtGxt; int32 CMenuManager::m_PrefsMusicVolume = 102; int32 CMenuManager::m_PrefsSfxVolume = 102; -#ifdef CUTSCENE_BORDERS_SWITCH -bool CMenuManager::m_PrefsCutsceneBorders = true; -#endif - -#ifdef MULTISAMPLING -int8 CMenuManager::m_nPrefsMSAALevel = 0; -int8 CMenuManager::m_nDisplayMSAALevel = 0; -#endif - -#ifdef NO_ISLAND_LOADING -int8 CMenuManager::m_DisplayIslandLoading = ISLAND_LOADING_LOW; -int8 CMenuManager::m_PrefsIslandLoading = ISLAND_LOADING_LOW; -#endif char CMenuManager::m_PrefsSkinFile[256] = DEFAULT_SKIN_NAME; int32 CMenuManager::m_KeyPressedCode = -1; -// 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 -const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); -#else -const CRGBA TEXT_COLOR = CRGBA(235, 170, 50, 255); // PC briefs text color -#endif - float MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE; float MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE; @@ -254,35 +282,12 @@ const char* MenuFilenames[][2] = { #define PAGE_NAME_X SCREEN_SCALE_FROM_RIGHT #endif -#ifdef PS2_LIKE_MENU -#define ChangeScreen(screen, option, updateDelay, withReverseAlpha) \ - do { \ - if (reverseAlpha) { \ - m_nPrevScreen = m_nCurrScreen; \ - m_nCurrScreen = pendingScreen; \ - m_nCurrOption = pendingOption; \ - reverseAlpha = false; \ - if (updateDelay) \ - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); \ - } \ - if (withReverseAlpha && !m_bRenderGameInMenu) { \ - pendingOption = option; \ - pendingScreen = screen; \ - reverseAlpha = true; \ - } else { \ - m_nPrevScreen = m_nCurrScreen; \ - m_nCurrScreen = screen; \ - m_nCurrOption = option; \ - if (updateDelay) \ - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); \ - } \ - m_nMenuFadeAlpha = 255; \ - } while(0) -#else +// Seperate func. in VC #define ChangeScreen(screen, option, updateDelay, clearAlpha) \ do { \ m_nPrevScreen = m_nCurrScreen; \ int newOpt = option; \ + SETUP_SCROLLING(screen) \ m_nCurrScreen = screen; \ m_nCurrOption = newOpt; \ if(updateDelay) \ @@ -290,7 +295,6 @@ const char* MenuFilenames[][2] = { if(clearAlpha) \ m_nMenuFadeAlpha = 0; \ } while(0) -#endif #define PREPARE_MENU_HEADER \ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); \ @@ -341,8 +345,8 @@ CMenuManager::ScrollUpListByOne() void CMenuManager::ScrollDownListByOne() { - if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) { - if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { + if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1) { + if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN) { m_nSelectedListRow++; m_nFirstVisibleRowOnList++; m_nScrollbarTopMargin += SCROLLBAR_MAX_HEIGHT / m_nTotalListRow; @@ -357,13 +361,13 @@ CMenuManager::ScrollDownListByOne() void CMenuManager::PageUpList(bool playSoundOnSuccess) { - if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { + if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) { if (m_nFirstVisibleRowOnList > 0) { if(playSoundOnSuccess) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); - m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW); - m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1); + m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_OPTION_ON_SCREEN); + m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1); } else { m_nFirstVisibleRowOnList = 0; m_nSelectedListRow = 0; @@ -375,15 +379,15 @@ CMenuManager::PageUpList(bool playSoundOnSuccess) void CMenuManager::PageDownList(bool playSoundOnSuccess) { - if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { - if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { + if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) { + if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN) { if(playSoundOnSuccess) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); - m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW); + m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN, m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN); m_nSelectedListRow = Max(m_nSelectedListRow, m_nFirstVisibleRowOnList); } else { - m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; + m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN; m_nSelectedListRow = m_nTotalListRow - 1; } m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; @@ -434,6 +438,14 @@ CMenuManager::ThingsToDoBeforeGoingBack() m_nTotalListRow = 0; } +#ifdef SCROLLABLE_PAGES + if (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) { + m_nSelectedListRow = 0; + m_nFirstVisibleRowOnList = 0; + m_nScrollbarTopMargin = 0; + } +#endif + #ifdef CUSTOM_FRONTEND_OPTIONS CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; @@ -476,6 +488,236 @@ CMenuManager::GetPreviousPageOption() #endif } +void +CMenuManager::ProcessList(bool &goBack, bool &optionSelected) +{ + if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) { + m_nTotalListRow = m_nSkinsTotal; + } + if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { + m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 30 : 25; + if (m_nSelectedListRow > m_nTotalListRow) + m_nSelectedListRow = m_nTotalListRow - 1; + } + +#ifndef TIDY_UP_PBP + if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { + m_bShowMouse = 0; + optionSelected = true; + } +#endif + if (CPad::GetPad(0)->GetBackspaceJustDown() && m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS && !field_535) { + if (m_nCurrExLayer == HOVEROPTION_LIST) { + m_nHoverOption = HOVEROPTION_NOT_HOVERING; + m_bWaitingForNewKeyBind = true; + m_bStartWaitingForKeyBind = true; + m_bKeyChangeNotProcessed = true; + pControlEdit = &m_KeyPressedCode; + } + } else { + field_535 = false; + } + + static uint32 lastTimeClickedScrollButton = 0; + + if (CTimer::GetTimeInMillisecondsPauseMode() - lastTimeClickedScrollButton >= 200) { + m_bPressedPgUpOnList = false; + m_bPressedPgDnOnList = false; + m_bPressedUpOnList = false; + m_bPressedDownOnList = false; + m_bPressedScrollButton = false; + lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); + } + + if (CPad::GetPad(0)->GetTabJustDown()) { + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + m_bShowMouse = false; + switch (m_nCurrExLayer) { + case HOVEROPTION_BACK: + default: + m_nCurrExLayer = HOVEROPTION_LIST; + break; + case HOVEROPTION_LIST: + m_nCurrExLayer = HOVEROPTION_USESKIN; + break; + case HOVEROPTION_USESKIN: + m_nCurrExLayer = HOVEROPTION_BACK; + } + if (((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) && strcmp(m_aSkinName, m_PrefsSkinFile) == 0) { + m_nCurrExLayer = HOVEROPTION_BACK; + } + if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) { + m_nCurrExLayer = HOVEROPTION_BACK; + } + } + + bool pressed = false; + if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) { + m_bShowMouse = false; + pressed = true; + } else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) { + m_bShowMouse = true; + pressed = true; + } + + // Up + if (pressed) { + m_nCurrExLayer = HOVEROPTION_LIST; + if (!m_bPressedUpOnList) { + m_bPressedUpOnList = true; + lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + ScrollUpListByOne(); + } + } else { + m_bPressedUpOnList = false; + } + + pressed = false; + if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) { + m_bShowMouse = false; + pressed = true; + } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) { + m_bShowMouse = true; + pressed = true; + } + + // Down + if (pressed) { + m_nCurrExLayer = HOVEROPTION_LIST; + if (!m_bPressedDownOnList) { + m_bPressedDownOnList = true; + lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + ScrollDownListByOne(); + } + } else { + m_bPressedDownOnList = false; + } + + if (m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) { + if (!CPad::GetPad(0)->GetPageUp()) { + m_bPressedPgUpOnList = false; + } else { + m_nCurrExLayer = HOVEROPTION_LIST; + if (!m_bPressedPgUpOnList) { + m_bPressedPgUpOnList = true; + lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); + m_bShowMouse = false; + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + PageUpList(false); + } + } + if (!CPad::GetPad(0)->GetPageDown()) { + m_bPressedPgDnOnList = false; + } else { + m_nCurrExLayer = HOVEROPTION_LIST; + if (!m_bPressedPgDnOnList) { + m_bPressedPgDnOnList = true; + lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); + m_bShowMouse = false; + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + PageDownList(false); + } + } + if (CPad::GetPad(0)->GetHome()) { + m_nCurrExLayer = HOVEROPTION_LIST; + m_bShowMouse = false; + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) { + m_nFirstVisibleRowOnList = 0; + } + m_nSelectedListRow = 0; + m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; + } + if (CPad::GetPad(0)->GetEnd()) { + m_nCurrExLayer = HOVEROPTION_LIST; + m_bShowMouse = false; + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) { + m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN; + } + m_nSelectedListRow = m_nTotalListRow - 1; + m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; + } + } + +#ifndef TIDY_UP_PBP + if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustDown()) { + m_bShowMouse = false; + goBack = true; + } +#endif + + if (CPad::GetPad(0)->GetLeftMouseJustDown()) { + switch (m_nHoverOption) { + case HOVEROPTION_BACK: + goBack = true; + break; + case HOVEROPTION_PAGEUP: + PageUpList(true); + break; + case HOVEROPTION_PAGEDOWN: + PageDownList(true); + break; + case HOVEROPTION_USESKIN: + if (m_nSkinsTotal > 0) { + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); + m_pSelectedSkin = m_pSkinListHead.nextSkin; + strcpy(m_PrefsSkinFile, m_aSkinName); + CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); + SaveSettings(); + } + } + } + + if (CPad::GetPad(0)->GetLeftMouseJustDown()) { + switch (m_nHoverOption) { + case HOVEROPTION_OVER_SCROLL_UP: + m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_UP; + break; + case HOVEROPTION_OVER_SCROLL_DOWN: + m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_DOWN; + break; + case HOVEROPTION_LIST: + m_nHoverOption = HOVEROPTION_SKIN; + } + } else if ((CPad::GetPad(0)->GetLeftMouseJustUp()) + && ((m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP || (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN)))) { + m_nHoverOption = HOVEROPTION_NOT_HOVERING; + } + + if (!CPad::GetPad(0)->GetLeftMouse()) { + holdingScrollBar = false; + } else { + if ((m_nHoverOption == HOVEROPTION_HOLDING_SCROLLBAR) || holdingScrollBar) { + holdingScrollBar = true; + // TODO: This part is a bit hard to reverse. Not much code tho + assert(0 && "Holding scrollbar isn't done yet"); + } else { + switch (m_nHoverOption) { + case HOVEROPTION_OVER_SCROLL_UP: + case HOVEROPTION_CLICKED_SCROLL_UP: + if (!m_bPressedScrollButton) { + m_bPressedScrollButton = true; + lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); + ScrollUpListByOne(); + } + break; + case HOVEROPTION_OVER_SCROLL_DOWN: + case HOVEROPTION_CLICKED_SCROLL_DOWN: + if (!m_bPressedScrollButton) { + m_bPressedScrollButton = true; + lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); + ScrollDownListByOne(); + } + break; + default: + m_bPressedScrollButton = false; + } + } + } +} // ------ Functions not in the game/inlined ends void @@ -773,7 +1015,7 @@ CMenuManager::Draw() CFont::SetRightJustifyOn(); CFont::SetFontStyle(FONT_HEADING); CFont::SetScale(MENU_X(0.7f), MENU_Y(0.5f)); - CFont::SetWrapx(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)); + CFont::SetWrapx(SCREEN_WIDTH); CFont::SetRightJustifyWrap(0.0f); strcpy(gString, "V1.1"); AsciiToUnicode(gString, gUString); @@ -781,7 +1023,7 @@ CMenuManager::Draw() #endif #endif CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); - CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f)); switch (m_nCurrScreen) { case MENUPAGE_STATS: @@ -853,7 +1095,11 @@ CMenuManager::Draw() #endif } +#ifdef ASPECT_RATIO_SCALE CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)); +#else + CFont::SetCentreSize(SCREEN_WIDTH); +#endif #ifdef PS2_LIKE_MENU bool itemsAreSelectable = !bottomBarActive; @@ -1015,13 +1261,24 @@ CMenuManager::Draw() #endif #ifdef CUSTOM_FRONTEND_OPTIONS - static int lastOption = m_nCurrOption; + static int lastSelectedOpt = m_nCurrOption; #endif +#ifdef SCROLLABLE_PAGES + int firstOption = m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen) ? m_nFirstVisibleRowOnList : 0; + for (int i = firstOption; i < firstOption + MAX_VISIBLE_OPTION && i < NUM_MENUROWS; ++i) { +#else for (int i = 0; i < NUM_MENUROWS; ++i) { +#endif + #ifdef CUSTOM_FRONTEND_OPTIONS bool isOptionDisabled = false; #endif + // Hide back button +#ifdef PS2_LIKE_MENU + if ((i == NUM_MENUROWS - 1 || aScreens[m_nCurrScreen].m_aEntries[i+1].m_EntryName[0] == '\0') && strncmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEDS_TB", 8) == 0) + break; +#endif if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') { wchar *rightText = nil; wchar *leftText; @@ -1061,8 +1318,8 @@ CMenuManager::Draw() } } - if (m_nCurrOption != lastOption && lastOption == i) { - CMenuScreenCustom::CMenuEntry &oldOption = aScreens[m_nCurrScreen].m_aEntries[lastOption]; + if (m_nCurrOption != lastSelectedOpt && lastSelectedOpt == i) { + CMenuScreenCustom::CMenuEntry &oldOption = aScreens[m_nCurrScreen].m_aEntries[lastSelectedOpt]; if (oldOption.m_Action == MENUACTION_CFO_DYNAMIC) if(oldOption.m_CFODynamic->buttonPressFunc) oldOption.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); @@ -1236,21 +1493,6 @@ CMenuManager::Draw() AsciiToUnicode(_psGetVideoModeList()[m_nDisplayVideoMode], unicodeTemp); rightText = unicodeTemp; break; -//#ifdef NO_ISLAND_LOADING -// case MENUACTION_ISLANDLOADING: -// switch (m_DisplayIslandLoading) { -// case ISLAND_LOADING_LOW: -// rightText = TheText.Get("FEM_LOW"); -// break; -// case ISLAND_LOADING_MEDIUM: -// rightText = TheText.Get("FEM_MED"); -// break; -// case ISLAND_LOADING_HIGH: -// rightText = TheText.Get("FEM_HIG"); -// break; -// } -// break; -//#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex == -1) rightText = TheText.Get("FEA_NAH"); @@ -1329,9 +1571,20 @@ CMenuManager::Draw() int nextYToCheck = bitAboveNextItemY; if (!foundTheHoveringItem) { +#ifdef SCROLLABLE_PAGES + for (int rowToCheck = firstOption + (aScreens[m_nCurrScreen].m_aEntries[firstOption].m_Action == MENUACTION_LABEL); rowToCheck < firstOption + MAX_VISIBLE_OPTION && rowToCheck < NUM_MENUROWS; ++rowToCheck) { +#else for (int rowToCheck = aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL; rowToCheck < NUM_MENUROWS; ++rowToCheck) { +#endif if(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_NOTHING) break; + + // Hide back button +#ifdef PS2_LIKE_MENU + if ((rowToCheck == NUM_MENUROWS - 1 || aScreens[m_nCurrScreen].m_aEntries[rowToCheck+1].m_EntryName[0] == '\0') && + strncmp(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_EntryName, "FEDS_TB", 8) == 0) + break; +#endif int extraOffset = 0; if (aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_RADIO) @@ -1430,12 +1683,6 @@ CMenuManager::Draw() if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") && m_nHelperTextMsgId == 1) ResetHelperText(); } -//#ifdef NO_ISLAND_LOADING -// if (m_DisplayIslandLoading == m_PrefsIslandLoading) { -// if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEM_ISL") && m_nHelperTextMsgId == 1) -// ResetHelperText(); -// } -//#endif if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH")) SetHelperText(1); @@ -1444,12 +1691,6 @@ CMenuManager::Draw() if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES")) SetHelperText(1); } -//#ifdef NO_ISLAND_LOADING -// if (m_DisplayIslandLoading != m_PrefsIslandLoading) { -// if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEM_ISL")) -// SetHelperText(1); -// } -//#endif if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0 // To make assigning built-in actions to new custom options possible. @@ -1496,6 +1737,12 @@ CMenuManager::Draw() break; } + // Needed after the bug fix in Font.cpp +#ifdef FIX_BUGS + if (!CFont::Details.centre) + CFont::SetRightJustifyOff(); +#endif + // 60.0 is silly nextYToUse += lineHeight * CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(60.0f), MENU_Y(nextYToUse), leftText); @@ -1520,7 +1767,36 @@ CMenuManager::Draw() } #ifdef CUSTOM_FRONTEND_OPTIONS - lastOption = m_nCurrOption; + lastSelectedOpt = m_nCurrOption; +#endif + +#ifdef SCROLLABLE_PAGES + #define SCROLLBAR_BOTTOM_X 125.0f // only for background, scrollbar's itself is calculated + #define SCROLLBAR_RIGHT_X 36.0f + #define SCROLLBAR_WIDTH 9.5f + #define SCROLLBAR_TOP_X 64 + + if (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) { + // Scrollbar background + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2), MENU_Y(SCROLLBAR_TOP_X), + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2 - SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(SCROLLBAR_BOTTOM_X)), CRGBA(100, 100, 66, FadeIn(205))); + + float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / (m_nTotalListRow / (float) MAX_VISIBLE_OPTION); + float scrollbarBottom, scrollbarTop; + + scrollbarBottom = MENU_Y(SCROLLBAR_TOP_X - 8 + m_nScrollbarTopMargin + scrollbarHeight); + scrollbarTop = MENU_Y(SCROLLBAR_TOP_X + m_nScrollbarTopMargin); + // Scrollbar shadow + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 1 - SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), + CRGBA(50, 50, 50, FadeIn(255))); + + // Scrollbar + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - SCROLLBAR_WIDTH), scrollbarBottom), + CRGBA(235, 170, 50, FadeIn(255))); + + } #endif switch (m_nCurrScreen) { @@ -2004,7 +2280,7 @@ CMenuManager::DrawControllerSetupScreen() CFont::SetRightJustifyOff(); CFont::SetBackGroundOnlyTextOn(); CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); - CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f)); PREPARE_MENU_HEADER @@ -2193,27 +2469,28 @@ CMenuManager::DrawFrontEnd() CFont::SetAlphaFade(255.0f); #ifdef PS2_LIKE_MENU + #define setBbItem(a, b, c) strcpy(a.name, b); a.screenId = c; if (m_nCurrScreen == MENUPAGE_NONE) { if (m_bGameNotLoaded) { if (bbTabCount != 6) { - bbNames[0] = { "FEB_SAV",MENUPAGE_NEW_GAME }; - bbNames[1] = { "FEB_CON",MENUPAGE_CONTROLLER_PC }; - bbNames[2] = { "FEB_AUD",MENUPAGE_SOUND_SETTINGS }; - bbNames[3] = { "FEB_DIS",MENUPAGE_DISPLAY_SETTINGS }; - bbNames[4] = { "FEB_LAN",MENUPAGE_LANGUAGE_SETTINGS }; - bbNames[5] = { "FESZ_QU",MENUPAGE_EXIT }; + setBbItem(bbNames[0], "FEB_SAV",MENUPAGE_NEW_GAME) + setBbItem(bbNames[1], "FEB_CON",MENUPAGE_CONTROLLER_PC) + setBbItem(bbNames[2], "FEB_AUD",MENUPAGE_SOUND_SETTINGS) + setBbItem(bbNames[3], "FEB_DIS",MENUPAGE_DISPLAY_SETTINGS) + setBbItem(bbNames[4], "FEB_LAN",MENUPAGE_LANGUAGE_SETTINGS) + setBbItem(bbNames[5], "FESZ_QU",MENUPAGE_EXIT) bbTabCount = 6; } } else { if (bbTabCount != 8) { - bbNames[0] = { "FEB_STA",MENUPAGE_STATS }; - bbNames[1] = { "FEB_SAV",MENUPAGE_NEW_GAME }; - bbNames[2] = { "FEB_BRI",MENUPAGE_BRIEFS }; - bbNames[3] = { "FEB_CON",MENUPAGE_CONTROLLER_PC }; - bbNames[4] = { "FEB_AUD",MENUPAGE_SOUND_SETTINGS }; - bbNames[5] = { "FEB_DIS",MENUPAGE_DISPLAY_SETTINGS }; - bbNames[6] = { "FEB_LAN",MENUPAGE_LANGUAGE_SETTINGS }; - bbNames[7] = { "FESZ_QU",MENUPAGE_EXIT }; + setBbItem(bbNames[0], "FEB_STA",MENUPAGE_STATS) + setBbItem(bbNames[1], "FEB_SAV",MENUPAGE_NEW_GAME) + setBbItem(bbNames[2], "FEB_BRI",MENUPAGE_BRIEFS) + setBbItem(bbNames[3], "FEB_CON",MENUPAGE_CONTROLLER_PC) + setBbItem(bbNames[4], "FEB_AUD",MENUPAGE_SOUND_SETTINGS) + setBbItem(bbNames[5], "FEB_DIS",MENUPAGE_DISPLAY_SETTINGS) + setBbItem(bbNames[6], "FEB_LAN",MENUPAGE_LANGUAGE_SETTINGS) + setBbItem(bbNames[7], "FESZ_QU",MENUPAGE_EXIT) bbTabCount = 8; } } @@ -2221,6 +2498,7 @@ CMenuManager::DrawFrontEnd() bottomBarActive = true; curBottomBarOption = 0; } + #undef setBbItem #else if (m_nCurrScreen == MENUPAGE_NONE) { if (m_bGameNotLoaded) { @@ -2311,7 +2589,7 @@ CMenuManager::DrawFrontEndNormal() m_aFrontEndSprites[FE2_MAINPANEL_UR].Draw(CRect(SCREEN_WIDTH / 2, 0.0f, MENU_X_RIGHT_ALIGNED(0.0f), SCREEN_HEIGHT / 2), CRGBA(255, 255, 255, 255)); m_aFrontEndSprites[FE2_MAINPANEL_DL].Draw(CRect(MENU_X_LEFT_ALIGNED(0.0f), SCREEN_HEIGHT / 2, SCREEN_WIDTH / 2, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); m_aFrontEndSprites[FE2_MAINPANEL_DR].Draw(CRect(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, MENU_X_RIGHT_ALIGNED(0.0f), SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); - + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); eFrontendSprites currentSprite; switch (m_nCurrScreen) { @@ -2351,39 +2629,15 @@ CMenuManager::DrawFrontEndNormal() break; } - m_aFrontEndSprites[currentSprite].Draw(CRect(MENU_X_LEFT_ALIGNED(50.0f), MENU_Y(50.0f), MENU_X_RIGHT_ALIGNED(50.0f), SCREEN_SCALE_FROM_BOTTOM(95.0f)), CRGBA(255, 255, 255, m_nMenuFadeAlpha > 255 ? 255 : m_nMenuFadeAlpha)); - static float fadeAlpha = 0.0f; - static int lastState = 0; - // reverseAlpha = PS2 fading (wait for 255->0, then change screen) if (m_nMenuFadeAlpha < 255) { - if (lastState == 1 && !reverseAlpha) - fadeAlpha = 0.f; - - if (m_nMenuFadeAlpha <= 0 && reverseAlpha) { - reverseAlpha = false; - ChangeScreen(pendingScreen, pendingOption, true, false); - } else { - // +20 per every 33 ms (1000.f/30.f - original frame limiter fps) - if (!reverseAlpha) - fadeAlpha += (frameTime) * 20.f / 33.f; - else - fadeAlpha = max(0.0f, fadeAlpha - (frameTime) * 30.f / 33.f); - - m_nMenuFadeAlpha = fadeAlpha; - } - lastState = 0; + if (m_nMenuFadeAlpha == 0 && fadeAlpha > 1.0f) fadeAlpha = 0.0f; + + // +20 per every 33 ms (1000.f/30.f - original frame limiter fps) + fadeAlpha += (frameTime) * 20.f / 33.f; + m_nMenuFadeAlpha = fadeAlpha; } else { - if (lastState == 0) fadeAlpha = 255.f; - - if (reverseAlpha) { - fadeAlpha -= (frameTime) * 30.f / 33.f; - - m_nMenuFadeAlpha = fadeAlpha; - } - lastState = 1; - // TODO: what is this? waiting mouse? if(field_518 == 4){ if(m_nHoverOption == HOVEROPTION_3 || m_nHoverOption == HOVEROPTION_4 || @@ -2395,6 +2649,8 @@ CMenuManager::DrawFrontEndNormal() } } + m_aFrontEndSprites[currentSprite].Draw(CRect(MENU_X_LEFT_ALIGNED(50.0f), MENU_Y(50.0f), MENU_X_RIGHT_ALIGNED(50.0f), SCREEN_SCALE_FROM_BOTTOM(95.0f)), CRGBA(255, 255, 255, m_nMenuFadeAlpha > 255 ? 255 : m_nMenuFadeAlpha)); + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST); RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); @@ -2420,7 +2676,7 @@ CMenuManager::DrawFrontEndNormal() CFont::SetJustifyOn(); CFont::SetRightJustifyOff(); CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(40.0f)); // 600.0f + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); // 600.0f CFont::SetColor(CRGBA(16, 16, 16, 255)); switch (m_nCurrScreen) { @@ -2738,7 +2994,7 @@ CMenuManager::DrawPlayerSetupScreen() CFont::SetRightJustifyOff(); CFont::SetBackGroundOnlyTextOn(); CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); - CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f)); PREPARE_MENU_HEADER @@ -2930,14 +3186,13 @@ CMenuManager::DrawPlayerSetupScreen() CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(100, 100, 66, FadeIn(205))); - // Scrollbar - float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal * (float) MAX_VISIBLE_LIST_ROW; + float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / (m_nSkinsTotal / (float) MAX_VISIBLE_LIST_ROW); float scrollbarBottom, scrollbarTop; if (m_nSkinsTotal <= MAX_VISIBLE_LIST_ROW) { scrollbarBottom = SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 4.0f); scrollbarTop = MENU_Y(PLAYERSETUP_LIST_BODY_TOP); - // Shadow + // Scrollbar shadow CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1 - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), CRGBA(50, 50, 50, FadeIn(255))); } else { @@ -2948,12 +3203,13 @@ CMenuManager::DrawPlayerSetupScreen() scrollbarBottom = MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 4 + m_nScrollbarTopMargin + scrollbarHeight - SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal); scrollbarTop = MENU_Y(SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal + PLAYERSETUP_LIST_BODY_TOP - 3 + m_nScrollbarTopMargin); #endif - // Shadow + // Scrollbar shadow CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1 - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), CRGBA(50, 50, 50, FadeIn(255))); } + // Scrollbar CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom), CRGBA(235, 170, 50, FadeIn(255))); @@ -3518,8 +3774,8 @@ CMenuManager::MessageScreen(const char *text) CFont::SetPropOn(); CFont::SetJustifyOn(); CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(SCREEN_WIDTH - StretchX(170.0f)); // not used - CFont::SetRightJustifyWrap(SCREEN_WIDTH - StretchX(170.0f)); // not used + CFont::SetWrapx(SCREEN_WIDTH - StretchX(170.0f)); // unused + CFont::SetRightJustifyWrap(SCREEN_WIDTH - StretchX(170.0f)); // unused CSprite2d::DrawRect(CRect(StretchX(120.0f), StretchY(150.0f), SCREEN_WIDTH - StretchX(120.0f), SCREEN_HEIGHT - StretchY(220.0f)), CRGBA(50, 50, 50, 210)); CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); CFont::SetCentreSize(SCREEN_SCALE_X(380.0f)); @@ -3613,7 +3869,7 @@ CMenuManager::PrintErrorMessage() CFont::SetJustifyOn(); CFont::SetRightJustifyOff(); CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(40.0f)); + CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(MENU_X_MARGIN)); #ifdef FIX_BUGS CFont::PrintString(SCREEN_SCALE_X(50.0f), SCREEN_SCALE_Y(180.0f), TheText.Get(CPad::bDisplayNoControllerMessage ? "NOCONT" : "WRCONT")); #else @@ -3925,235 +4181,10 @@ CMenuManager::ProcessButtonPresses(void) if (m_nMousePosY < 0) m_nMousePosY = 0; if (m_nMousePosY > SCREEN_HEIGHT) m_nMousePosY = SCREEN_HEIGHT; - if (m_nCurrScreen == MENUPAGE_MULTIPLAYER_FIND_GAME || m_nCurrScreen == MENUPAGE_SKIN_SELECT - || m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { - - if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) { - m_nTotalListRow = m_nSkinsTotal; - } - if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { - m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 30 : 25; - if (m_nSelectedListRow > m_nTotalListRow) - m_nSelectedListRow = m_nTotalListRow - 1; - } - -#ifndef TIDY_UP_PBP - if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { - m_bShowMouse = 0; - optionSelected = true; - } -#endif - if (CPad::GetPad(0)->GetBackspaceJustDown() && m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS && !field_535) { - if (m_nCurrExLayer == HOVEROPTION_LIST) { - m_nHoverOption = HOVEROPTION_NOT_HOVERING; - m_bWaitingForNewKeyBind = true; - m_bStartWaitingForKeyBind = true; - m_bKeyChangeNotProcessed = true; - pControlEdit = &m_KeyPressedCode; - } - } else { - field_535 = false; - } - - static uint32 lastTimeClickedScrollButton = 0; - - if (CTimer::GetTimeInMillisecondsPauseMode() - lastTimeClickedScrollButton >= 200) { - m_bPressedPgUpOnList = false; - m_bPressedPgDnOnList = false; - m_bPressedUpOnList = false; - m_bPressedDownOnList = false; - m_bPressedScrollButton = false; - lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); - } - - if (CPad::GetPad(0)->GetTabJustDown()) { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); - m_bShowMouse = false; - switch (m_nCurrExLayer) { - case HOVEROPTION_BACK: - default: - m_nCurrExLayer = HOVEROPTION_LIST; - break; - case HOVEROPTION_LIST: - m_nCurrExLayer = HOVEROPTION_USESKIN; - break; - case HOVEROPTION_USESKIN: - m_nCurrExLayer = HOVEROPTION_BACK; - } - if (((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) && strcmp(m_aSkinName, m_PrefsSkinFile) == 0) { - m_nCurrExLayer = HOVEROPTION_BACK; - } - if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) { - m_nCurrExLayer = HOVEROPTION_BACK; - } - } - - bool pressed = false; - if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) { - m_bShowMouse = false; - pressed = true; - } else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) { - m_bShowMouse = true; - pressed = true; - } - - // Up - if (pressed) { - m_nCurrExLayer = HOVEROPTION_LIST; - if (!m_bPressedUpOnList) { - m_bPressedUpOnList = true; - lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); - ScrollUpListByOne(); - } - } else { - m_bPressedUpOnList = false; - } - - pressed = false; - if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) { - m_bShowMouse = false; - pressed = true; - } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) { - m_bShowMouse = true; - pressed = true; - } - - // Down - if (pressed) { - m_nCurrExLayer = HOVEROPTION_LIST; - if (!m_bPressedDownOnList) { - m_bPressedDownOnList = true; - lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); - ScrollDownListByOne(); - } - } else { - m_bPressedDownOnList = false; - } + if (hasNativeList(m_nCurrScreen)) { + // Not split to seperate function in III as in VC, but we need it for scrollable pages :) + ProcessList(goBack, optionSelected); - if (m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) { - if (!CPad::GetPad(0)->GetPageUp()) { - m_bPressedPgUpOnList = false; - } else { - m_nCurrExLayer = HOVEROPTION_LIST; - if (!m_bPressedPgUpOnList) { - m_bPressedPgUpOnList = true; - lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); - m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); - PageUpList(false); - } - } - if (!CPad::GetPad(0)->GetPageDown()) { - m_bPressedPgDnOnList = false; - } else { - m_nCurrExLayer = HOVEROPTION_LIST; - if (!m_bPressedPgDnOnList) { - m_bPressedPgDnOnList = true; - lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); - m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); - PageDownList(false); - } - } - if (CPad::GetPad(0)->GetHome()) { - m_nCurrExLayer = HOVEROPTION_LIST; - m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); - if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) { - m_nFirstVisibleRowOnList = 0; - } - m_nSelectedListRow = 0; - m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; - } - if (CPad::GetPad(0)->GetEnd()) { - m_nCurrExLayer = HOVEROPTION_LIST; - m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); - if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) { - m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; - } - m_nSelectedListRow = m_nTotalListRow - 1; - m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; - } - } - -#ifndef TIDY_UP_PBP - if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustDown()) { - m_bShowMouse = false; - goBack = true; - } -#endif - - if (CPad::GetPad(0)->GetLeftMouseJustDown()) { - switch (m_nHoverOption) { - case HOVEROPTION_BACK: - goBack = true; - break; - case HOVEROPTION_PAGEUP: - PageUpList(true); - break; - case HOVEROPTION_PAGEDOWN: - PageDownList(true); - break; - case HOVEROPTION_USESKIN: - if (m_nSkinsTotal > 0) { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - m_pSelectedSkin = m_pSkinListHead.nextSkin; - strcpy(m_PrefsSkinFile, m_aSkinName); - CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); - SaveSettings(); - } - } - } - - if (CPad::GetPad(0)->GetLeftMouseJustDown()) { - switch (m_nHoverOption) { - case HOVEROPTION_OVER_SCROLL_UP: - m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_UP; - break; - case HOVEROPTION_OVER_SCROLL_DOWN: - m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_DOWN; - break; - case HOVEROPTION_LIST: - m_nHoverOption = HOVEROPTION_SKIN; - } - } else if ((CPad::GetPad(0)->GetLeftMouseJustUp()) - && ((m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP || (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN)))) { - m_nHoverOption = HOVEROPTION_NOT_HOVERING; - } - - if (!CPad::GetPad(0)->GetLeftMouse()) { - holdingScrollBar = false; - } else { - if ((m_nHoverOption == HOVEROPTION_HOLDING_SCROLLBAR) || holdingScrollBar) { - holdingScrollBar = true; - // TODO: This part is a bit hard to reverse. Not much code tho - assert(0 && "Holding scrollbar isn't done yet"); - } else { - switch (m_nHoverOption) { - case HOVEROPTION_OVER_SCROLL_UP: - case HOVEROPTION_CLICKED_SCROLL_UP: - if (!m_bPressedScrollButton) { - m_bPressedScrollButton = true; - lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); - ScrollUpListByOne(); - } - break; - case HOVEROPTION_OVER_SCROLL_DOWN: - case HOVEROPTION_CLICKED_SCROLL_DOWN: - if (!m_bPressedScrollButton) { - m_bPressedScrollButton = true; - lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); - ScrollDownListByOne(); - } - break; - default: - m_bPressedScrollButton = false; - } - } - } } else if (isPlainTextScreen(m_nCurrScreen)) { #ifndef TIDY_UP_PBP if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown() || CPad::GetPad(0)->GetLeftMouseJustDown()) { @@ -4392,7 +4423,7 @@ CMenuManager::ProcessButtonPresses(void) TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl; SaveSettings(); break; - } + } #else switch (m_nHoverOption) { case HOVEROPTION_INCREASE_BRIGHTNESS: @@ -4411,7 +4442,26 @@ CMenuManager::ProcessButtonPresses(void) break; } #endif - } + } + +#ifdef SCROLLABLE_PAGES + if (m_nTotalListRow > MAX_VISIBLE_OPTION) { + bool temp = false; + + m_nSelectedListRow = m_nCurrOption; + + // ignore detected back/select states, it's our screen's job + ProcessList(temp, temp); + + // and ignore our screen's goUp/Down, now it's ProcessList's job + goUp = false; + goDown = false; + m_nCurrOption = m_nSelectedListRow; + } + + // Prevent sound on scroll. Mouse wheel is now belongs to us! + if (!(m_nTotalListRow > MAX_VISIBLE_OPTION && (CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustDown()))) +#endif if (CPad::GetPad(0)->GetLeftMouseJustUp() || CPad::GetPad(0)->GetLeftJustUp() || CPad::GetPad(0)->GetRightJustUp() || CPad::GetPad(0)->GetDPadLeftJustUp() || CPad::GetPad(0)->GetDPadRightJustUp() @@ -4426,6 +4476,7 @@ CMenuManager::ProcessButtonPresses(void) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); } + #ifndef TIDY_UP_PBP if (CPad::GetPad(0)->GetBackJustDown()) { if (m_nCurrScreen != MENUPAGE_START_MENU && m_nCurrScreen != MENUPAGE_PAUSE_MENU) { @@ -4445,7 +4496,7 @@ CMenuManager::ProcessButtonPresses(void) goBack = false; } #endif - } + } // Centralized enter/back (except some conditions) #ifdef TIDY_UP_PBP @@ -4498,16 +4549,10 @@ CMenuManager::ProcessButtonPresses(void) if (bbNames[curBottomBarOption].screenId == MENUPAGE_SOUND_SETTINGS) DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); - // If there's a menu change with fade ongoing, finish it now - if (reverseAlpha) - m_nMenuFadeAlpha = 0; return; } else if (CPad::GetPad(0)->GetLeftJustDown() || CPad::GetPad(0)->GetAnaloguePadLeft() || CPad::GetPad(0)->GetDPadLeftJustDown() || CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) { - if (reverseAlpha && m_nMenuFadeAlpha > 30) - return; - m_bShowMouse = false; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); curBottomBarOption = ((curBottomBarOption + bbTabCount) - 1) % bbTabCount; @@ -4516,9 +4561,6 @@ CMenuManager::ProcessButtonPresses(void) } else if (CPad::GetPad(0)->GetRightJustDown() || CPad::GetPad(0)->GetAnaloguePadRight() || CPad::GetPad(0)->GetDPadRightJustDown() || CPad::GetPad(0)->GetDownJustDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) { - if (reverseAlpha && m_nMenuFadeAlpha > 30) - return; - m_bShowMouse = false; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); curBottomBarOption = ((curBottomBarOption + bbTabCount) + 1) % bbTabCount; @@ -4549,6 +4591,12 @@ CMenuManager::ProcessButtonPresses(void) } } + // Hide back button +#ifdef PS2_LIKE_MENU + if ((goUp || goDown) && m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME && strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB", 8) == 0) + m_nCurrOption = goUp ? m_nCurrOption - 1 : (aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL); +#endif + if (optionSelected) { int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; if ((option == MENUACTION_CHANGEMENU) || (option == MENUACTION_POPULATESLOTS_CHANGEMENU)) { @@ -4822,45 +4870,6 @@ CMenuManager::ProcessButtonPresses(void) SaveSettings(); } break; -//#ifdef NO_ISLAND_LOADING -// case MENUACTION_ISLANDLOADING: -// if (m_DisplayIslandLoading != m_PrefsIslandLoading) { -// if (!m_bGameNotLoaded) { -// if (m_DisplayIslandLoading > ISLAND_LOADING_LOW) { -// if (m_DisplayIslandLoading == ISLAND_LOADING_HIGH) -// CStreaming::RemoveIslandsNotUsed(LEVEL_GENERIC); -// if (m_PrefsIslandLoading == ISLAND_LOADING_LOW) { -// if (CGame::currLevel != LEVEL_INDUSTRIAL) -// CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL); -// if (CGame::currLevel != LEVEL_COMMERCIAL) -// CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL); -// if (CGame::currLevel != LEVEL_SUBURBAN) -// CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN); -// CCollision::bAlreadyLoaded = true; -// m_PrefsIslandLoading = m_DisplayIslandLoading; -// CStreaming::RequestBigBuildings(CGame::currLevel); -// } else if (m_PrefsIslandLoading == ISLAND_LOADING_HIGH) { -// m_PrefsIslandLoading = m_DisplayIslandLoading; -// CStreaming::RequestIslands(CGame::currLevel); -// } else -// m_PrefsIslandLoading = m_DisplayIslandLoading; -// } else { // low -// m_PrefsIslandLoading = m_DisplayIslandLoading; -// CCollision::bAlreadyLoaded = false; -// CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); -// CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); -// CStreaming::RemoveUnusedBuildings(CGame::currLevel); -// CStreaming::RequestIslands(CGame::currLevel); -// } -// -// CStreaming::LoadAllRequestedModels(true); -// } else -// m_PrefsIslandLoading = m_DisplayIslandLoading; -// SetHelperText(0); -// SaveSettings(); -// } -// break; -//#endif case MENUACTION_AUDIOHW: { int selectedProvider = m_nPrefsAudio3DProviderIndex; @@ -4935,40 +4944,6 @@ CMenuManager::ProcessButtonPresses(void) RestoreDefGraphics(FEOPTION_ACTION_SELECT); RestoreDefDisplay(FEOPTION_ACTION_SELECT); #endif -//#ifdef NO_ISLAND_LOADING -// m_DisplayIslandLoading = ISLAND_LOADING_LOW; -// if (!m_bGameNotLoaded) { -// if (m_DisplayIslandLoading > ISLAND_LOADING_LOW) { -// if (m_DisplayIslandLoading == ISLAND_LOADING_HIGH) -// CStreaming::RemoveIslandsNotUsed(LEVEL_GENERIC); -// if (m_PrefsIslandLoading == ISLAND_LOADING_LOW) { -// if (CGame::currLevel != LEVEL_INDUSTRIAL) -// CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL); -// if (CGame::currLevel != LEVEL_COMMERCIAL) -// CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL); -// if (CGame::currLevel != LEVEL_SUBURBAN) -// CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN); -// CCollision::bAlreadyLoaded = true; -// m_PrefsIslandLoading = m_DisplayIslandLoading; -// CStreaming::RequestBigBuildings(CGame::currLevel); -// } else if (m_PrefsIslandLoading == ISLAND_LOADING_HIGH) { -// m_PrefsIslandLoading = m_DisplayIslandLoading; -// CStreaming::RequestIslands(CGame::currLevel); -// } else -// m_PrefsIslandLoading = m_DisplayIslandLoading; -// } else { // low -// m_PrefsIslandLoading = m_DisplayIslandLoading; -// CCollision::bAlreadyLoaded = false; -// CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); -// CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); -// CStreaming::RemoveUnusedBuildings(CGame::currLevel); -// CStreaming::RequestIslands(CGame::currLevel); -// } -// -// CStreaming::LoadAllRequestedModels(true); -// } else -// m_PrefsIslandLoading = m_DisplayIslandLoading; -//#endif // NO_ISLAND_LOADING SaveSettings(); } else if ((m_nCurrScreen != MENUPAGE_SKIN_SELECT_OLD) && (m_nCurrScreen == MENUPAGE_CONTROLLER_PC)) { ControlsManager.MakeControllerActionsBlank(); @@ -5147,23 +5122,27 @@ CMenuManager::ProcessButtonPresses(void) if (CPad::GetPad(0)->GetRightJustDown() || CPad::GetPad(0)->GetAnaloguePadRight() || CPad::GetPad(0)->GetDPadRightJustDown()) { m_bShowMouse = false; increase = true; - } else if (CPad::GetPad(0)->GetMouseWheelUpJustDown() && m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) { + } else if ( +#ifdef SCROLLABLE_PAGES + !(m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) && +#endif + CPad::GetPad(0)->GetMouseWheelUpJustDown() && m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) { increase = true; CheckSliderMovement(1); m_bShowMouse = true; } - if (!CPad::GetPad(0)->GetLeftJustDown() && !CPad::GetPad(0)->GetAnaloguePadLeft() && !CPad::GetPad(0)->GetDPadLeftJustDown()) { - if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) { - if (m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) { - decrease = true; - CheckSliderMovement(-1); - m_bShowMouse = true; - } - } - } else { + if (CPad::GetPad(0)->GetLeftJustDown() || CPad::GetPad(0)->GetAnaloguePadLeft() || CPad::GetPad(0)->GetDPadLeftJustDown()) { m_bShowMouse = false; decrease = true; + } else if ( +#ifdef SCROLLABLE_PAGES + !(m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) && +#endif + CPad::GetPad(0)->GetMouseWheelDownJustDown() && m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) { + decrease = true; + CheckSliderMovement(-1); + m_bShowMouse = true; } if (increase) @@ -5228,15 +5207,6 @@ CMenuManager::ProcessButtonPresses(void) } } break; -//#ifdef NO_ISLAND_LOADING -// case MENUACTION_ISLANDLOADING: -// m_DisplayIslandLoading += changeValueBy; -// if (m_DisplayIslandLoading > ISLAND_LOADING_HIGH) -// m_DisplayIslandLoading = ISLAND_LOADING_LOW; -// else if (m_DisplayIslandLoading < ISLAND_LOADING_LOW) -// m_DisplayIslandLoading = ISLAND_LOADING_HIGH; -// break; -//#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex != -1) { m_nPrefsAudio3DProviderIndex += changeValueBy; diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 70b4cd31..21124fdb 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -18,7 +18,6 @@ #define MENU_X_MARGIN 40.0f #define MENUACTION_POS_Y 60.0f -#define MENUACTION_WIDTH 38.0f #define MENUACTION_SCALE_MULT 0.9f #define MENURADIO_ICON_SCALE 60.0f @@ -235,11 +234,11 @@ enum eMenuScreen MENUPAGE_KEYBOARD_CONTROLS = 55, MENUPAGE_MOUSE_CONTROLS = 56, MENUPAGE_MISSION_RETRY = 57, -#ifdef CUSTOM_FRONTEND_OPTIONS - #ifdef MENU_MAP - MENUPAGE_MAP, + MENUPAGE_MAP = 58, #endif +#ifdef CUSTOM_FRONTEND_OPTIONS + #ifdef GRAPHICS_MENU_OPTIONS MENUPAGE_GRAPHICS_SETTINGS, #else @@ -380,9 +379,6 @@ enum eMenuAction // MENUACTION_MIPMAPS, // MENUACTION_TEXTURE_FILTERING, //#endif -//#ifdef NO_ISLAND_LOADING -// MENUACTION_ISLANDLOADING, -//#endif }; enum eCheckHover @@ -718,7 +714,6 @@ public: ISLAND_LOADING_HIGH }; - static int8 m_DisplayIslandLoading; static int8 m_PrefsIslandLoading; #define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p) @@ -786,6 +781,7 @@ public: void PageUpList(bool); void PageDownList(bool); int8 GetPreviousPageOption(); + void ProcessList(bool &goBack, bool &optionSelected); }; #ifndef IMPROVED_VIDEOMODE diff --git a/src/core/Frontend_PS2.cpp b/src/core/Frontend_PS2.cpp index a1d802f2..824f342b 100644 --- a/src/core/Frontend_PS2.cpp +++ b/src/core/Frontend_PS2.cpp @@ -203,20 +203,6 @@ static const char* FrontendFilenames[][2] = {"fe_radio9", "" }, }; -#ifdef CUTSCENE_BORDERS_SWITCH -bool CMenuManager::m_PrefsCutsceneBorders = true; -#endif - -#ifdef MULTISAMPLING -int8 CMenuManager::m_nPrefsMSAALevel = 0; -int8 CMenuManager::m_nDisplayMSAALevel = 0; -#endif - -#ifdef NO_ISLAND_LOADING -int8 CMenuManager::m_DisplayIslandLoading = ISLAND_LOADING_LOW; -int8 CMenuManager::m_PrefsIslandLoading = ISLAND_LOADING_LOW; -#endif - int32 CMenuManager::m_PrefsSfxVolume = 102; int32 CMenuManager::m_PrefsMusicVolume = 102; int32 CMenuManager::m_PrefsBrightness = 256; diff --git a/src/core/Frontend_PS2.h b/src/core/Frontend_PS2.h index c1e42291..4bab7df9 100644 --- a/src/core/Frontend_PS2.h +++ b/src/core/Frontend_PS2.h @@ -160,31 +160,9 @@ public: static int32 m_PrefsLanguage; static CONTRCONFIG m_PrefsControllerConfig; static bool m_PrefsUseVibration; -#ifdef NO_ISLAND_LOADING - enum - { - ISLAND_LOADING_LOW = 0, - ISLAND_LOADING_MEDIUM, - ISLAND_LOADING_HIGH - }; - - static int8 m_DisplayIslandLoading; - static int8 m_PrefsIslandLoading; -#define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p) -#define ISLAND_LOADING_ISNT(p) if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p) -#else #define ISLAND_LOADING_IS(p) #define ISLAND_LOADING_ISNT(p) -#endif -#ifdef CUTSCENE_BORDERS_SWITCH - static bool m_PrefsCutsceneBorders; -#endif -#ifdef MULTISAMPLING - static int8 m_nPrefsMSAALevel; - static int8 m_nDisplayMSAALevel; -#endif - #ifdef GTA_PC bool m_bQuitGameNoCD; diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 83c75d91..f7589d2b 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -128,7 +128,7 @@ void MessageScreen(char *msg) CFont::SetFontStyle(FONT_BANK); CFont::SetBackgroundOff(); - CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(190.0f)); // 450.0f // unused + CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(190.0f)); // 450.0f CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f)); CFont::SetCentreOn(); CFont::SetCentreSize(SCREEN_SCALE_X(450.0f)); // 450.0f @@ -734,10 +734,10 @@ void CGame::InitialiseWhenRestarting(void) //CFont::SetFontStyle(?); CFont::SetBackgroundOff(); - CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(160.0f)); // 480.0f // unused + CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(160.0f)); // 480.0f CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f)); CFont::SetCentreOn(); - CFont::SetCentreSize(SCREEN_SCALE_X(480.0f)); // 480.0f + CFont::SetCentreSize(SCREEN_SCALE_X(480.0f)); CFont::SetJustifyOff(); CFont::SetColor(CRGBA(255, 255, 255, 255)); CFont::SetBackGroundOnlyTextOff(); diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp index c2eadb3b..9eff09e6 100644 --- a/src/core/MenuScreens.cpp +++ b/src/core/MenuScreens.cpp @@ -392,6 +392,9 @@ CMenuScreen aScreens[MENUPAGES] = { { "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME, +#ifdef MENU_MAP + MENUACTION_CHANGEMENU, "FEG_MAP", SAVESLOT_NONE, MENUPAGE_MAP, +#endif MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS, MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS, MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS, @@ -436,6 +439,14 @@ CMenuScreen aScreens[MENUPAGES] = { }, #endif +#ifdef MENU_MAP + // MENUPAGE_MAP + { "FEG_MAP", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 2, + MENUACTION_UNK110, "", SAVESLOT_NONE, MENUPAGE_NONE, // to prevent cross/enter to go back + MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, + }, +#endif + // MENUPAGE_UNK { "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0, diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp index fb0888fc..d3d7474d 100644 --- a/src/core/MenuScreensCustom.cpp +++ b/src/core/MenuScreensCustom.cpp @@ -11,6 +11,10 @@ #include "custompipes.h" #include "RwHelper.h" #include "Text.h" +#include "Streaming.h" +#include "FileLoader.h" +#include "Collision.h" +#include "ModelInfo.h" // Menu screens array is at the bottom of the file. @@ -48,6 +52,12 @@ #define DUALPASS_SELECTOR #endif +#ifdef NO_ISLAND_LOADING + #define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&CMenuManager::m_PrefsIslandLoading, "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) }, +#else + #define ISLAND_LOADING_SELECTOR +#endif + #ifdef EXTENDED_COLOURFILTER #define POSTFX_SELECTORS \ MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false, nil) }, \ @@ -80,6 +90,18 @@ void RestoreDefGraphics(int8 action) { #ifdef MULTISAMPLING FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel = 0; #endif + #ifdef NO_ISLAND_LOADING + if (!FrontEndMenuManager.m_bGameNotLoaded) { + FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW; + CCollision::bAlreadyLoaded = false; + CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + CStreaming::LoadAllRequestedModels(true); + } else + FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW; + #endif #ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those CMenuManager::m_PrefsFrameLimiter = true; CMenuManager::m_PrefsVsyncDisp = true; @@ -120,6 +142,47 @@ void RestoreDefDisplay(int8 action) { #endif } +#ifdef NO_ISLAND_LOADING +const char *islandLoadingOpts[] = { "FEM_LOW", "FEM_MED", "FEM_HIG" }; +void IslandLoadingAfterChange(int8 before, int8 after) { + if (!FrontEndMenuManager.m_bGameNotLoaded) { + if (after > FrontEndMenuManager.ISLAND_LOADING_LOW) { + FrontEndMenuManager.m_PrefsIslandLoading = before; // calls below needs previous mode :shrug: + + if (after == FrontEndMenuManager.ISLAND_LOADING_HIGH) + CStreaming::RemoveIslandsNotUsed(LEVEL_GENERIC); + if (before == FrontEndMenuManager.ISLAND_LOADING_LOW) { + if (CGame::currLevel != LEVEL_INDUSTRIAL) + CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL); + if (CGame::currLevel != LEVEL_COMMERCIAL) + CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL); + if (CGame::currLevel != LEVEL_SUBURBAN) + CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN); + CCollision::bAlreadyLoaded = true; + FrontEndMenuManager.m_PrefsIslandLoading = after; + CStreaming::RequestBigBuildings(CGame::currLevel); + + } else if (before == FrontEndMenuManager.ISLAND_LOADING_HIGH) { + FrontEndMenuManager.m_PrefsIslandLoading = after; + CStreaming::RequestIslands(CGame::currLevel); + } else + FrontEndMenuManager.m_PrefsIslandLoading = after; + + } else { // low + CCollision::bAlreadyLoaded = false; + CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + } + + CStreaming::LoadAllRequestedModels(true); + } + + FrontEndMenuManager.SetHelperText(0); +} +#endif + #ifdef MORE_LANGUAGES void LangPolSelect(int8 action) { @@ -761,6 +824,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = { #ifdef EXTENDED_PIPELINES PIPELINES_SELECTOR #endif + ISLAND_LOADING_SELECTOR DUALPASS_SELECTOR MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) }, MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, @@ -770,6 +834,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = { { "FET_ADV", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, new CCustomScreenLayout({MENUSPRITE_MAINMENU, 50, 0, 20, FONT_HEADING, FESCREEN_LEFT_ALIGN, true, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), nil, + ISLAND_LOADING_SELECTOR DUALPASS_SELECTOR CUTSCENE_BORDERS_TOGGLE FREE_CAM_TOGGLE diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index 104c8b40..44a347bd 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -2610,7 +2610,7 @@ void CPad::PrintErrorMessage(void) CFont::SetScale(0.85f, 1.0f); CFont::SetJustifyOff(); CFont::SetBackgroundOff(); - CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20)); + CFont::SetCentreSize(SCREEN_SCALE_X(SCREEN_WIDTH - 20)); CFont::SetCentreOn(); CFont::SetPropOn(); CFont::SetColor(CRGBA(255, 255, 200, 200)); @@ -2627,7 +2627,7 @@ void CPad::PrintErrorMessage(void) CFont::SetScale(0.85f, 1.0f); CFont::SetJustifyOff(); CFont::SetBackgroundOff(); - CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20)); + CFont::SetCentreSize(SCREEN_SCALE_X(SCREEN_WIDTH - 20)); CFont::SetCentreOn(); CFont::SetPropOn(); CFont::SetColor(CRGBA(255, 255, 200, 200)); diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index 3c5689fd..e9a7af88 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -390,6 +390,7 @@ CStreaming::LoadCdDirectory(const char *dirname, int n) assert(sizeof(direntry) == 32); while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){ dot = strchr(direntry.name, '.'); + assert(dot); if(dot) *dot = '\0'; if(direntry.size > (uint32)ms_streamingBufferSize) ms_streamingBufferSize = direntry.size; @@ -741,7 +742,9 @@ CStreaming::RequestBigBuildings(eLevelName level) b = CPools::GetBuildingPool()->GetSlot(i); if(b && b->bIsBIGBuilding #ifdef NO_ISLAND_LOADING - && ((CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) || (b->m_level == level)) + && (((CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODindustEntity) && (b != pIslandLODcomIndEntity) && + (b != pIslandLODcomSubEntity) && (b != pIslandLODsubIndEntity) && (b != pIslandLODsubComEntity) + ) || (b->m_level == level)) #else && b->m_level == level #endif diff --git a/src/core/config.h b/src/core/config.h index e604699d..39c5d782 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -212,10 +212,10 @@ enum Config { # define TIMEBARS // print debug timers #endif -#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more +#define FIX_BUGS // fixes bugs that we've came across during reversing #define MORE_LANGUAGES // Add more translations to the game #define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible -#define LOAD_INI_SETTINGS +#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS // Rendering/display //#define EXTRA_MODEL_FLAGS // from mobile to optimize rendering @@ -227,19 +227,11 @@ enum Config { #define PS2_ALPHA_TEST // emulate ps2 alpha test #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 #ifdef LIBRW //#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur) //#define EXTENDED_PIPELINES // custom render pipelines (includes Neo) #endif -#define MULTISAMPLING // adds MSAA option - -#ifdef LIBRW -// these are not supported with librw yet -# undef MULTISAMPLING -#endif // Particle //#define PC_PARTICLE @@ -278,7 +270,13 @@ enum Config { //# define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc. //# define PS2_SAVE_DIALOG // PS2 style save dialog with transparent black box # define CUSTOM_FRONTEND_OPTIONS -# define GRAPHICS_MENU_OPTIONS // otherwise Advanced Options menu will appear if Display is full + +# ifdef CUSTOM_FRONTEND_OPTIONS +# define GRAPHICS_MENU_OPTIONS // otherwise Advanced Options menu will appear if Display is full +# define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU +# define CUTSCENE_BORDERS_SWITCH +# define MULTISAMPLING // adds MSAA option +# endif #endif // Script @@ -327,6 +325,8 @@ enum Config { #endif //#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS +// IMG +#define BIG_IMG // allows to read larger img files //#define SQUEEZE_PERFORMANCE #ifdef SQUEEZE_PERFORMANCE @@ -335,3 +335,8 @@ enum Config { #define PC_PARTICLE #define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial #endif + +#ifdef LIBRW +// these are not supported with librw yet +# undef MULTISAMPLING +#endif diff --git a/src/core/main.cpp b/src/core/main.cpp index 36c94043..cd234588 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -89,7 +89,11 @@ RwRGBA gColourTop; bool gameAlreadyInitialised; float NumberOfChunksLoaded; +#ifdef GTA_PS2 +#define TOTALNUMCHUNKS 48.0f +#else #define TOTALNUMCHUNKS 73.0f +#endif bool g_SlowMode = false; char version_name[64]; @@ -625,20 +629,20 @@ LoadingIslandScreen(const char *levelName) CFont::SetScale(1.5f, 1.5f); CFont::SetPropOn(); CFont::SetRightJustifyOn(); - CFont::SetRightJustifyWrap(150.0f); + CFont::SetRightJustifyWrap(SCREEN_SCALE_X(150.0f)); CFont::SetFontStyle(FONT_HEADING); sprintf(str, "WELCOME TO"); AsciiToUnicode(str, wstr); CFont::SetDropColor(CRGBA(0, 0, 0, 255)); CFont::SetDropShadowPosition(3); CFont::SetColor(CRGBA(243, 237, 71, 255)); - CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f)); - CFont::PrintString(SCREEN_WIDTH - 20, SCREEN_STRETCH_FROM_BOTTOM(110.0f), TheText.Get("WELCOME")); + CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_STRETCH_FROM_BOTTOM(110.0f), TheText.Get("WELCOME")); TextCopy(wstr, name); TheText.UpperCase(wstr); CFont::SetColor(CRGBA(243, 237, 71, 255)); - CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f)); - CFont::PrintString(SCREEN_WIDTH-20, SCREEN_STRETCH_FROM_BOTTOM(80.0f), wstr); + CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_STRETCH_FROM_BOTTOM(80.0f), wstr); CFont::DrawFonts(); DoRWStuffEndOfFrame(); } @@ -852,7 +856,7 @@ DisplayGameDebugText() CFont::SetRightJustifyOff(); CFont::SetJustifyOff(); CFont::SetBackGroundOnlyTextOff(); - CFont::SetWrapx(SCREEN_WIDTH); + CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH)); CFont::SetFontStyle(FONT_HEADING); CFont::SetColor(CRGBA(0, 0, 0, 255)); diff --git a/src/core/re3.cpp b/src/core/re3.cpp index aa13ba29..4783e513 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -86,7 +86,8 @@ CustomFrontendOptionsPopulate(void) linb::ini cfg; int CheckAndReadIniInt(const char *cat, const char *key, int original) { - const char *value = (cfg.get(cat, key, "").c_str()); + std::string strval = cfg.get(cat, key, ""); + const char *value = strval.c_str(); if (value && value[0] != '\0') return atoi(value); @@ -95,13 +96,34 @@ int CheckAndReadIniInt(const char *cat, const char *key, int original) float CheckAndReadIniFloat(const char *cat, const char *key, float original) { - const char *value = (cfg.get(cat, key, "").c_str()); + std::string strval = cfg.get(cat, key, ""); + const char *value = strval.c_str(); if (value && value[0] != '\0') return atof(value); return original; } +void CheckAndSaveIniInt(const char *cat, const char *key, int val, bool &changed) +{ + char temp[10]; + if (atoi(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it + changed = true; + sprintf(temp, "%u", val); + cfg.set(cat, key, temp); + } +} + +void CheckAndSaveIniFloat(const char *cat, const char *key, float val, bool &changed) +{ + char temp[10]; + if (atof(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it + changed = true; + sprintf(temp, "%f", val); + cfg.set(cat, key, temp); + } +} + void LoadINISettings() { cfg.load_file("re3.ini"); @@ -156,11 +178,6 @@ void LoadINISettings() } #endif -#ifdef NO_ISLAND_LOADING - CMenuManager::m_PrefsIslandLoading = CheckAndReadIniInt("FrontendOptions", "NoIslandLoading", CMenuManager::m_PrefsIslandLoading); - CMenuManager::m_DisplayIslandLoading = CMenuManager::m_PrefsIslandLoading; -#endif - #ifdef EXTENDED_COLOURFILTER CPostFX::Intensity = CheckAndReadIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity); #endif @@ -192,21 +209,22 @@ void SaveINISettings() break; if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) { - if (atoi(cfg.get("FrontendOptions", option.m_CFO->save, "xxx").c_str()) != *option.m_CFO->value) { // if .ini doesn't have that key compare with xxx, so we can add it - changed = true; - sprintf(temp, "%u", *option.m_CFO->value); - cfg.set("FrontendOptions", option.m_CFO->save, temp); - } + // Beware: CFO only supports saving uint8 right now + CheckAndSaveIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value, changed); } } } #endif -#ifdef NO_ISLAND_LOADING - if (atoi(cfg.get("FrontendOptions", "NoIslandLoading", "xxx").c_str()) != CMenuManager::m_PrefsIslandLoading) { - changed = true; - sprintf(temp, "%u", CMenuManager::m_PrefsIslandLoading); - cfg.set("FrontendOptions", "NoIslandLoading", temp); - } + +#ifdef EXTENDED_COLOURFILTER + CheckAndSaveIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity, changed); +#endif +#ifdef EXTENDED_PIPELINES + CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess, changed); + CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity, changed); + CheckAndSaveIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult, changed); + CheckAndSaveIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult, changed); + CheckAndSaveIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult, changed); #endif if (changed) |