summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--premake5.lua7
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/collision/ColLine.h4
-rw-r--r--src/collision/ColPoint.h4
-rw-r--r--src/collision/ColSphere.h5
-rw-r--r--src/collision/ColTriangle.h1
-rw-r--r--src/collision/Collision.cpp18
-rw-r--r--src/core/config.h1
-rw-r--r--src/math/Vector.cpp15
-rw-r--r--src/math/Vector.h9
-rw-r--r--src/math/VuVector.h4
-rw-r--r--src/render/WaterCannon.cpp60
-rw-r--r--src/render/WaterCannon.h3
13 files changed, 98 insertions, 35 deletions
diff --git a/premake5.lua b/premake5.lua
index 2a8e6c93..010810a0 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -71,6 +71,13 @@ workspace "reLCS"
symbols "Full"
staticruntime "off"
+ -- for CVECTORHACK
+ configuration { "gmake*" }
+ buildoptions { "-fpermissive" }
+
+ filter { "platforms:macosx*" }
+ buildoptions { "-Wno-address-of-temporary" }
+
if _OPTIONS["with-asan"] then
buildoptions { "-fsanitize=address -g3 -fno-omit-frame-pointer" }
linkoptions { "-fsanitize=address" }
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f3d51b06..8325938c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -102,6 +102,8 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang
if (NOT LIBRW_PLATFORM_PS2)
target_compile_options(${EXECUTABLE}
PRIVATE
+ -fpermissive # for CVECTORHACK
+ -Wno-address-of-temporary # for CVECTORHACK
-Wextra
-Wdouble-promotion
-Wpedantic
diff --git a/src/collision/ColLine.h b/src/collision/ColLine.h
index 21587a06..a2cb9a0b 100644
--- a/src/collision/ColLine.h
+++ b/src/collision/ColLine.h
@@ -4,9 +4,9 @@ struct CColLine
{
// NB: this has to be compatible with two CVuVectors
CVector p0;
- int pad0;
+// int pad0;
CVector p1;
- int pad1;
+// int pad1;
CColLine(void) { };
CColLine(const CVector &p0, const CVector &p1) { this->p0 = p0; this->p1 = p1; };
diff --git a/src/collision/ColPoint.h b/src/collision/ColPoint.h
index a15b2345..f978720d 100644
--- a/src/collision/ColPoint.h
+++ b/src/collision/ColPoint.h
@@ -3,10 +3,10 @@
struct CColPoint
{
CVector point;
- int pad1;
+ int pad1; // this is stupid
// the surface normal on the surface of point
CVector normal;
- int pad2;
+ //int pad2;
uint8 surfaceA;
uint8 pieceA;
uint8 surfaceB;
diff --git a/src/collision/ColSphere.h b/src/collision/ColSphere.h
index f86b282a..3f18d8c0 100644
--- a/src/collision/ColSphere.h
+++ b/src/collision/ColSphere.h
@@ -2,10 +2,11 @@
#include "SurfaceTable.h"
-struct CSphere
+// TODO(LCS): maybe this was in a union with CVuVector? or is the alignment manual?
+struct TYPEALIGN(16) CSphere
{
// NB: this has to be compatible with a CVuVector
- CVector center;
+ RwV3d center;
float radius;
void Set(float radius, const CVector &center) { this->center = center; this->radius = radius; }
};
diff --git a/src/collision/ColTriangle.h b/src/collision/ColTriangle.h
index a2580c58..5ce543b5 100644
--- a/src/collision/ColTriangle.h
+++ b/src/collision/ColTriangle.h
@@ -62,6 +62,7 @@ struct CColTrianglePlane
}
#endif
#else
+ // TODO(LCS): LCS actually uses CompressedVector too
CVector normal;
float dist;
uint8 dir;
diff --git a/src/collision/Collision.cpp b/src/collision/Collision.cpp
index bead5183..82681645 100644
--- a/src/collision/Collision.cpp
+++ b/src/collision/Collision.cpp
@@ -24,6 +24,10 @@
#include "Camera.h"
#include "ColStore.h"
+// gotta figure out how they handled CSphere exactly
+// so using this to remind me to look into it again.
+#define CVECTORHACK(rwv3d) CVector(rwv3d)
+
#ifdef VU_COLLISION
#include "VuCollision.h"
@@ -391,7 +395,7 @@ CCollision::TestLineSphere(const CColLine &line, const CColSphere &sph)
// The length of the tangent would be this: Sqrt((c-p0)^2 - r^2).
// Negative if p0 is inside the sphere! This breaks the test!
float tansq = 4.0f * linesq *
- (sph.center.MagnitudeSqr() - 2.0f*DotProduct(sph.center, line.p0) + line.p0.MagnitudeSqr() - sph.radius*sph.radius);
+ (CVECTORHACK(sph.center).MagnitudeSqr() - 2.0f*DotProduct(sph.center, line.p0) + line.p0.MagnitudeSqr() - sph.radius*sph.radius);
float diffsq = projline*projline - tansq;
// if diffsq < 0 that means the line is a passant, so no intersection
if(diffsq < 0.0f)
@@ -470,9 +474,9 @@ CCollision::TestSphereTriangle(const CColSphere &sphere,
case 2:
// closest to an edge
// looks like original game as DistToLine manually inlined
- if(!insideAB) dist = DistToLine(&va, &vb, &sphere.center);
- else if(!insideAC) dist = DistToLine(&va, &vc, &sphere.center);
- else if(!insideBC) dist = DistToLine(&vb, &vc, &sphere.center);
+ if(!insideAB) dist = DistToLine(&va, &vb, &CVECTORHACK(sphere.center));
+ else if(!insideAC) dist = DistToLine(&va, &vc, &CVECTORHACK(sphere.center));
+ else if(!insideBC) dist = DistToLine(&vb, &vc, &CVECTORHACK(sphere.center));
else assert(0);
break;
case 3:
@@ -1279,9 +1283,9 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
case 2:
// closest to an edge
// looks like original game as DistToLine manually inlined
- if(!insideAB) dist = DistToLine(&va, &vb, &sphere.center, p);
- else if(!insideAC) dist = DistToLine(&va, &vc, &sphere.center, p);
- else if(!insideBC) dist = DistToLine(&vb, &vc, &sphere.center, p);
+ if(!insideAB) dist = DistToLine(&va, &vb, &CVECTORHACK(sphere.center), p);
+ else if(!insideAC) dist = DistToLine(&va, &vc, &CVECTORHACK(sphere.center), p);
+ else if(!insideBC) dist = DistToLine(&vb, &vc, &CVECTORHACK(sphere.center), p);
else assert(0);
break;
case 3:
diff --git a/src/core/config.h b/src/core/config.h
index c5799817..94b2eb60 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -287,6 +287,7 @@ enum Config {
// Water & Particle
// #define PC_WATER
#define WATER_CHEATS
+//#define PSP_WATERCANNON
//#define USE_CUTSCENE_SHADOW_FOR_PED
#define DISABLE_CUTSCENE_SHADOWS
diff --git a/src/math/Vector.cpp b/src/math/Vector.cpp
index ee76e555..e29d4335 100644
--- a/src/math/Vector.cpp
+++ b/src/math/Vector.cpp
@@ -44,3 +44,18 @@ operator*(const CMatrix &mat, const CVector &vec)
mat.ry * vec.x + mat.fy * vec.y + mat.uy * vec.z + mat.py,
mat.rz * vec.x + mat.fz * vec.y + mat.uz * vec.z + mat.pz);
}
+
+void
+RwV3dTransformPoints(CVector * pointsOut, const CVector * pointsIn, RwInt32 numPoints, const RwMatrix * matrix)
+{
+ while(numPoints--){
+ float x = pointsIn->x*matrix->right.x + pointsIn->y*matrix->up.x + pointsIn->z*matrix->at.x + matrix->pos.x;
+ float y = pointsIn->x*matrix->right.y + pointsIn->y*matrix->up.y + pointsIn->z*matrix->at.y + matrix->pos.y;
+ float z = pointsIn->x*matrix->right.z + pointsIn->y*matrix->up.z + pointsIn->z*matrix->at.z + matrix->pos.z;
+ pointsOut->x = x;
+ pointsOut->y = y;
+ pointsOut->z = z;
+ pointsOut++;
+ pointsIn++;
+ }
+}
diff --git a/src/math/Vector.h b/src/math/Vector.h
index 02128454..87895806 100644
--- a/src/math/Vector.h
+++ b/src/math/Vector.h
@@ -1,8 +1,12 @@
#pragma once
+// TODO(LCS): this should have 16 byte alignment but VS doesn't like passing aligned values by value
+// need a solution for this eventually if we ever want to load original assets
class CVector : public RwV3d
{
public:
+ float w;
+
CVector(void) {}
CVector(float x, float y, float z)
{
@@ -126,4 +130,7 @@ class CMatrix;
CVector Multiply3x3(const CMatrix &mat, const CVector &vec);
CVector Multiply3x3(const CVector &vec, const CMatrix &mat);
-CVector operator*(const CMatrix &mat, const CVector &vec); \ No newline at end of file
+CVector operator*(const CMatrix &mat, const CVector &vec);
+
+// we need this because CVector and RwV3d have different size now
+void RwV3dTransformPoints(CVector * pointsOut, const CVector * pointsIn, RwInt32 numPoints, const RwMatrix * matrix);
diff --git a/src/math/VuVector.h b/src/math/VuVector.h
index 30d62cfc..026965d1 100644
--- a/src/math/VuVector.h
+++ b/src/math/VuVector.h
@@ -3,10 +3,10 @@
class TYPEALIGN(16) CVuVector : public CVector
{
public:
- float w;
+// float w; // in CVector now
CVuVector(void) {}
CVuVector(float x, float y, float z) : CVector(x, y, z) {}
- CVuVector(float x, float y, float z, float w) : CVector(x, y, z), w(w) {}
+ CVuVector(float x, float y, float z, float w) : CVector(x, y, z)/*, w(w)*/ { this->w = w;}
CVuVector(const CVector &v) : CVector(v.x, v.y, v.z) {}
CVuVector(const RwV3d &v) : CVector(v) {}
/*
diff --git a/src/render/WaterCannon.cpp b/src/render/WaterCannon.cpp
index 53b4d30e..65d8b388 100644
--- a/src/render/WaterCannon.cpp
+++ b/src/render/WaterCannon.cpp
@@ -13,6 +13,16 @@
#include "Camera.h"
#include "Particle.h"
+// --LCS: file done
+
+#ifdef PSP_WATERCANNON
+ //PSP:
+ #define WATER_COLOR 255
+#else
+ //PS2:
+ #define WATER_COLOR 127
+#endif
+
#define WATERCANNONVERTS 4
#define WATERCANNONINDEXES 12
@@ -115,24 +125,34 @@ void CWaterCannon::Update_NewInput(CVector *pos, CVector *dir)
m_abUsed[m_nCur] = true;
}
+static float fWaterCannonU = 0.0f;
void CWaterCannon::Render(void)
{
+ extern RwRaster *gpFireHoseRaster;
+
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpWaterRaster);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpFireHoseRaster);
- float v = float(CGeneral::GetRandomNumber() & 255) / 256;
-
- RwIm3DVertexSetV(&WaterCannonVertices[0], v);
- RwIm3DVertexSetV(&WaterCannonVertices[1], v);
- RwIm3DVertexSetV(&WaterCannonVertices[2], v);
- RwIm3DVertexSetV(&WaterCannonVertices[3], v);
+ fWaterCannonU += CTimer::GetTimeStepInSeconds() * 6.0f;
- int16 pointA = m_nCur % NUM_SEGMENTPOINTS;
+ while ( fWaterCannonU >= 1.0f )
+ fWaterCannonU -= 1.0f;
+ RwIm3DVertexSetU(&WaterCannonVertices[0], -fWaterCannonU);
+ RwIm3DVertexSetV(&WaterCannonVertices[0], 0.0f);
+ RwIm3DVertexSetU(&WaterCannonVertices[1], -fWaterCannonU);
+ RwIm3DVertexSetV(&WaterCannonVertices[1], 1.0f);
+ RwIm3DVertexSetU(&WaterCannonVertices[2], 1.0f - fWaterCannonU);
+ RwIm3DVertexSetV(&WaterCannonVertices[2], 0.0f);
+ RwIm3DVertexSetU(&WaterCannonVertices[3], 1.0f - fWaterCannonU);
+ RwIm3DVertexSetV(&WaterCannonVertices[3], 1.0f);
+
+ int16 pointA = m_nCur % NUM_SEGMENTPOINTS;
int16 pointB = pointA - 1;
- if ( (pointA - 1) < 0 )
+ int16 pointC = pointA;
+ if ( pointB < 0 )
pointB += NUM_SEGMENTPOINTS;
bool bInit = false;
@@ -142,6 +162,10 @@ void CWaterCannon::Render(void)
{
if ( m_abUsed[pointA] && m_abUsed[pointB] )
{
+ bool bFirst = false;
+ if ( i == 0 || m_abUsed[pointA] && !m_abUsed[pointC] )
+ bFirst = true;
+
if ( !bInit )
{
CVector cp = CrossProduct(m_avecPos[pointB] - m_avecPos[pointA], TheCamera.GetForward());
@@ -149,26 +173,25 @@ void CWaterCannon::Render(void)
bInit = true;
}
- float dist = float(i*i*i) / 300.0f + 1.0f;
float brightness = float(i) / NUM_SEGMENTPOINTS;
-
int32 color = (int32)((1.0f - brightness*brightness) * 255.0f);
- CVector offset = dist * norm;
- RwIm3DVertexSetRGBA(&WaterCannonVertices[0], color, color, color, color);
+ CVector offset = (float(i)+1.0f) * norm;
+
+ RwIm3DVertexSetRGBA(&WaterCannonVertices[0], WATER_COLOR, WATER_COLOR, WATER_COLOR, bFirst ? 0 : color);
RwIm3DVertexSetPos (&WaterCannonVertices[0], m_avecPos[pointA].x - offset.x, m_avecPos[pointA].y - offset.y, m_avecPos[pointA].z - offset.z);
- RwIm3DVertexSetRGBA(&WaterCannonVertices[1], color, color, color, color);
+ RwIm3DVertexSetRGBA(&WaterCannonVertices[1], WATER_COLOR, WATER_COLOR, WATER_COLOR, bFirst ? 0 : color);
RwIm3DVertexSetPos (&WaterCannonVertices[1], m_avecPos[pointA].x + offset.x, m_avecPos[pointA].y + offset.y, m_avecPos[pointA].z + offset.z);
- RwIm3DVertexSetRGBA(&WaterCannonVertices[2], color, color, color, color);
+ offset = (float(i+1)+1.0f) * norm;
+
+ RwIm3DVertexSetRGBA(&WaterCannonVertices[2], WATER_COLOR, WATER_COLOR, WATER_COLOR, color);
RwIm3DVertexSetPos (&WaterCannonVertices[2], m_avecPos[pointB].x - offset.x, m_avecPos[pointB].y - offset.y, m_avecPos[pointB].z - offset.z);
- RwIm3DVertexSetRGBA(&WaterCannonVertices[3], color, color, color, color);
+ RwIm3DVertexSetRGBA(&WaterCannonVertices[3], WATER_COLOR, WATER_COLOR, WATER_COLOR, color);
RwIm3DVertexSetPos (&WaterCannonVertices[3], m_avecPos[pointB].x + offset.x, m_avecPos[pointB].y + offset.y, m_avecPos[pointB].z + offset.z);
- LittleTest();
-
if ( RwIm3DTransform(WaterCannonVertices, WATERCANNONVERTS, NULL, rwIM3D_VERTEXUV) )
{
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, WaterCannonIndexList, WATERCANNONINDEXES);
@@ -176,6 +199,7 @@ void CWaterCannon::Render(void)
}
}
+ pointC = pointA;
pointA = pointB--;
if ( pointB < 0 )
pointB += NUM_SEGMENTPOINTS;
diff --git a/src/render/WaterCannon.h b/src/render/WaterCannon.h
index a37bdd12..5b60639c 100644
--- a/src/render/WaterCannon.h
+++ b/src/render/WaterCannon.h
@@ -14,6 +14,7 @@ public:
int32 m_nId;
int16 m_nCur;
uint32 m_nTimeCreated;
+ int32 field_C;
CVector m_avecPos[NUM_SEGMENTPOINTS];
CVector m_avecVelocity[NUM_SEGMENTPOINTS];
bool m_abUsed[NUM_SEGMENTPOINTS];
@@ -25,7 +26,7 @@ public:
void PushPeds(void);
};
-VALIDATE_SIZE(CWaterCannon, 412);
+VALIDATE_SIZE(CWaterCannon, 0x1A0);
class CWaterCannons
{