mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 13:55:38 +00:00
Harmless math warning fixes. map->unordered_map in CNew3D::CacheModel. Avoid general aliasing problems (using bit_cast or the recommended/optimized-away memcpy).
This commit is contained in:
parent
0eef09ba2b
commit
22ffb5cc19
|
@ -166,11 +166,15 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.1415926535897932384626433832795
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Legacy3D {
|
namespace Legacy3D {
|
||||||
|
|
||||||
// Microsoft doesn't provide isnan() and isinf()
|
// Microsoft doesn't provide isnan() and isinf()
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include <float.h>
|
#include <cfloat>
|
||||||
#define ISNAN(x) (_isnan(x))
|
#define ISNAN(x) (_isnan(x))
|
||||||
#define ISINF(x) (!_finite(x))
|
#define ISINF(x) (!_finite(x))
|
||||||
#else
|
#else
|
||||||
|
@ -847,9 +851,9 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri, bool wideScreen)
|
||||||
int vpHeight = (vpnode[0x14]>>18)&0x3FFF; // height (14.2)
|
int vpHeight = (vpnode[0x14]>>18)&0x3FFF; // height (14.2)
|
||||||
|
|
||||||
// Field of view and clipping
|
// Field of view and clipping
|
||||||
GLfloat vpTopAngle = (float) asin(*(float *)&vpnode[0x0E]); // FOV Y upper half-angle (radians)
|
GLfloat vpTopAngle = asinf(uint_as_float(vpnode[0x0E])); // FOV Y upper half-angle (radians)
|
||||||
GLfloat vpBotAngle = (float) asin(*(float *)&vpnode[0x12]); // FOV Y lower half-angle
|
GLfloat vpBotAngle = asinf(uint_as_float(vpnode[0x12])); // FOV Y lower half-angle
|
||||||
GLfloat fovYDegrees = (vpTopAngle+vpBotAngle)*(float)(180.0/3.14159265358979323846);
|
GLfloat fovYDegrees = (vpTopAngle+vpBotAngle)*(float)(180.0/M_PI);
|
||||||
// TO-DO: investigate clipping planes
|
// TO-DO: investigate clipping planes
|
||||||
|
|
||||||
// Set up viewport and projection (TO-DO: near and far clipping)
|
// Set up viewport and projection (TO-DO: near and far clipping)
|
||||||
|
@ -929,35 +933,35 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri, bool wideScreen)
|
||||||
UINT32 matrixBase = vpnode[0x16] & 0xFFFFFF;
|
UINT32 matrixBase = vpnode[0x16] & 0xFFFFFF;
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
InitMatrixStack(matrixBase);
|
InitMatrixStack(matrixBase);
|
||||||
|
|
||||||
// Safeguard: weird coordinate system matrices usually indicate scenes that will choke the renderer
|
// Safeguard: weird coordinate system matrices usually indicate scenes that will choke the renderer
|
||||||
if (NULL != matrixBasePtr)
|
if (NULL != matrixBasePtr)
|
||||||
{
|
{
|
||||||
float m21, m32, m13;
|
float m21, m32, m13;
|
||||||
|
|
||||||
// Get the three elements that are usually set and see if their magnitudes are 1
|
// Get the three elements that are usually set and see if their magnitudes are 1
|
||||||
m21 = matrixBasePtr[6];
|
m21 = matrixBasePtr[6];
|
||||||
m32 = matrixBasePtr[10];
|
m32 = matrixBasePtr[10];
|
||||||
m13 = matrixBasePtr[5];
|
m13 = matrixBasePtr[5];
|
||||||
|
|
||||||
m21 *= m21;
|
m21 *= m21;
|
||||||
m32 *= m32;
|
m32 *= m32;
|
||||||
m13 *= m13;
|
m13 *= m13;
|
||||||
|
|
||||||
if ((m21>1.05) || (m21<0.95))
|
if ((m21>1.05f) || (m21<0.95f))
|
||||||
return;
|
return;
|
||||||
if ((m32>1.05) || (m32<0.95))
|
if ((m32>1.05f) || (m32<0.95f))
|
||||||
return;
|
return;
|
||||||
if ((m13>1.05) || (m13<0.95))
|
if ((m13>1.05f) || (m13<0.95f))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
AppendDisplayList(&VROMCache, true, 0); // add a viewport display list node
|
AppendDisplayList(&VROMCache, true, 0); // add a viewport display list node
|
||||||
AppendDisplayList(&PolyCache, true, 0);
|
AppendDisplayList(&PolyCache, true, 0);
|
||||||
stackDepth = 0;
|
stackDepth = 0;
|
||||||
listDepth = 0;
|
listDepth = 0;
|
||||||
|
|
||||||
// Descend down the node link: Use recursive traversal
|
// Descend down the node link: Use recursive traversal
|
||||||
DescendNodePtr(nodeAddr);
|
DescendNodePtr(nodeAddr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -725,7 +725,7 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
|
||||||
// Specular shininess
|
// Specular shininess
|
||||||
GLfloat specularCoefficient = (GLfloat) ((P->header[0]>>26) & 0x3F) * (1.0f/63.0f);
|
GLfloat specularCoefficient = (GLfloat) ((P->header[0]>>26) & 0x3F) * (1.0f/63.0f);
|
||||||
int shinyBits = (P->header[6] >> 5) & 3;
|
int shinyBits = (P->header[6] >> 5) & 3;
|
||||||
float shininess = std::pow(2.0f, 1.f + shinyBits);
|
float shininess = std::exp2f(1 + shinyBits);
|
||||||
if (!(P->header[0]&0x80)) //|| (shininess == 0)) // bit 0x80 seems to enable specular lighting
|
if (!(P->header[0]&0x80)) //|| (shininess == 0)) // bit 0x80 seems to enable specular lighting
|
||||||
{
|
{
|
||||||
specularCoefficient = 0.; // disable
|
specularCoefficient = 0.; // disable
|
||||||
|
@ -1224,7 +1224,7 @@ bool CLegacy3D::CreateModelCache(ModelCache *Cache, unsigned vboMaxVerts,
|
||||||
{
|
{
|
||||||
// Last ditch attempt: try the local buffer size
|
// Last ditch attempt: try the local buffer size
|
||||||
vboBytes = localBytes;
|
vboBytes = localBytes;
|
||||||
glBufferData(GL_ARRAY_BUFFER, vboBytes, 0, isDynamic?GL_STREAM_DRAW:GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, vboBytes, nullptr, isDynamic?GL_STREAM_DRAW:GL_STATIC_DRAW);
|
||||||
if (glGetError() != GL_NO_ERROR)
|
if (glGetError() != GL_NO_ERROR)
|
||||||
return ErrorLog("OpenGL was unable to provide a %s vertex buffer.", isDynamic?"dynamic":"static");
|
return ErrorLog("OpenGL was unable to provide a %s vertex buffer.", isDynamic?"dynamic":"static");
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
#define M_PI 3.14159265359
|
#define M_PI 3.1415926535897932384626433832795
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace New3D {
|
namespace New3D {
|
||||||
|
@ -17,10 +17,10 @@ void Mat4::LoadIdentity()
|
||||||
{
|
{
|
||||||
float *m = currentMatrix;
|
float *m = currentMatrix;
|
||||||
|
|
||||||
m[0] = 1; m[4] = 0; m[8 ] = 0; m[12] = 0;
|
m[0] = 1.f; m[4] = 0.f; m[8 ] = 0.f; m[12] = 0.f;
|
||||||
m[1] = 0; m[5] = 1; m[9 ] = 0; m[13] = 0;
|
m[1] = 0.f; m[5] = 1.f; m[9 ] = 0.f; m[13] = 0.f;
|
||||||
m[2] = 0; m[6] = 0; m[10] = 1; m[14] = 0;
|
m[2] = 0.f; m[6] = 0.f; m[10] = 1.f; m[14] = 0.f;
|
||||||
m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1;
|
m[3] = 0.f; m[7] = 0.f; m[11] = 0.f; m[15] = 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mat4::MultiMatrices(const float a[16], const float b[16], float r[16])
|
void Mat4::MultiMatrices(const float a[16], const float b[16], float r[16])
|
||||||
|
@ -29,8 +29,7 @@ void Mat4::MultiMatrices(const float a[16], const float b[16], float r[16])
|
||||||
#define B(row,col) b[(col<<2)+row]
|
#define B(row,col) b[(col<<2)+row]
|
||||||
#define P(row,col) r[(col<<2)+row]
|
#define P(row,col) r[(col<<2)+row]
|
||||||
|
|
||||||
int i;
|
for (int i = 0; i < 4; i++) {
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
const float ai0 = A(i, 0), ai1 = A(i, 1), ai2 = A(i, 2), ai3 = A(i, 3);
|
const float ai0 = A(i, 0), ai1 = A(i, 1), ai2 = A(i, 2), ai3 = A(i, 3);
|
||||||
P(i, 0) = ai0 * B(0, 0) + ai1 * B(1, 0) + ai2 * B(2, 0) + ai3 * B(3, 0);
|
P(i, 0) = ai0 * B(0, 0) + ai1 * B(1, 0) + ai2 * B(2, 0) + ai3 * B(3, 0);
|
||||||
P(i, 1) = ai0 * B(0, 1) + ai1 * B(1, 1) + ai2 * B(2, 1) + ai3 * B(3, 1);
|
P(i, 1) = ai0 * B(0, 1) + ai1 * B(1, 1) + ai2 * B(2, 1) + ai3 * B(3, 1);
|
||||||
|
@ -56,25 +55,25 @@ void Mat4::Translate(float x, float y, float z)
|
||||||
float m[16];
|
float m[16];
|
||||||
//==========
|
//==========
|
||||||
|
|
||||||
m[0] = 1;
|
m[0] = 1.f;
|
||||||
m[1] = 0;
|
m[1] = 0.f;
|
||||||
m[2] = 0;
|
m[2] = 0.f;
|
||||||
m[3] = 0;
|
m[3] = 0.f;
|
||||||
|
|
||||||
m[4] = 0;
|
m[4] = 0.f;
|
||||||
m[5] = 1;
|
m[5] = 1.f;
|
||||||
m[6] = 0;
|
m[6] = 0.f;
|
||||||
m[7] = 0;
|
m[7] = 0.f;
|
||||||
|
|
||||||
m[8] = 0;
|
m[8] = 0.f;
|
||||||
m[9] = 0;
|
m[9] = 0.f;
|
||||||
m[10] = 1;
|
m[10] = 1.f;
|
||||||
m[11] = 0;
|
m[11] = 0.f;
|
||||||
|
|
||||||
m[12] = x;
|
m[12] = x;
|
||||||
m[13] = y;
|
m[13] = y;
|
||||||
m[14] = z;
|
m[14] = z;
|
||||||
m[15] = 1;
|
m[15] = 1.f;
|
||||||
|
|
||||||
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
||||||
}
|
}
|
||||||
|
@ -86,155 +85,137 @@ void Mat4::Scale(float x, float y, float z)
|
||||||
//==========
|
//==========
|
||||||
|
|
||||||
m[0] = x;
|
m[0] = x;
|
||||||
m[1] = 0;
|
m[1] = 0.f;
|
||||||
m[2] = 0;
|
m[2] = 0.f;
|
||||||
m[3] = 0;
|
m[3] = 0.f;
|
||||||
|
|
||||||
m[4] = 0;
|
m[4] = 0.f;
|
||||||
m[5] = y;
|
m[5] = y;
|
||||||
m[6] = 0;
|
m[6] = 0.f;
|
||||||
m[7] = 0;
|
m[7] = 0.f;
|
||||||
|
|
||||||
m[8] = 0;
|
m[8] = 0.f;
|
||||||
m[9] = 0;
|
m[9] = 0.f;
|
||||||
m[10] = z;
|
m[10] = z;
|
||||||
m[11] = 0;
|
m[11] = 0.f;
|
||||||
|
|
||||||
m[12] = 0;
|
m[12] = 0.f;
|
||||||
m[13] = 0;
|
m[13] = 0.f;
|
||||||
m[14] = 0;
|
m[14] = 0.f;
|
||||||
m[15] = 1;
|
m[15] = 1.f;
|
||||||
|
|
||||||
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mat4::Rotate(float angle, float x, float y, float z)
|
void Mat4::Rotate(float angle, float x, float y, float z)
|
||||||
{
|
{
|
||||||
//===========
|
|
||||||
float c;
|
|
||||||
float s;
|
|
||||||
float m[16];
|
|
||||||
//===========
|
|
||||||
|
|
||||||
// normalise vector first
|
// normalise vector first
|
||||||
{
|
{
|
||||||
//========
|
//========
|
||||||
float len;
|
float inv_len;
|
||||||
//========
|
//========
|
||||||
|
|
||||||
len = std::sqrt(x * x + y * y + z * z);
|
inv_len = 1.f/std::sqrt(x * x + y * y + z * z);
|
||||||
|
|
||||||
x /= len;
|
x *= inv_len;
|
||||||
y /= len;
|
y *= inv_len;
|
||||||
z /= len;
|
z *= inv_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = std::cos(angle*3.14159265f / 180.0f);
|
float c = std::cos(angle*(float)(M_PI / 180.0));
|
||||||
s = std::sin(angle*3.14159265f / 180.0f);
|
float s = std::sin(angle*(float)(M_PI / 180.0));
|
||||||
|
|
||||||
m[0] = (x*x) * (1 - c) + c;
|
float m[16];
|
||||||
m[1] = (y*x) * (1 - c) + (z*s);
|
m[0] = (x*x) * (1.f - c) + c;
|
||||||
m[2] = (x*z) * (1 - c) - (y*s);
|
m[1] = (y*x) * (1.f - c) + (z*s);
|
||||||
m[3] = 0;
|
m[2] = (x*z) * (1.f - c) - (y*s);
|
||||||
|
m[3] = 0.f;
|
||||||
|
|
||||||
m[4] = (x*y) * (1 - c) - (z*s);
|
m[4] = (x*y) * (1.f - c) - (z*s);
|
||||||
m[5] = (y*y) * (1 - c) + c;
|
m[5] = (y*y) * (1.f - c) + c;
|
||||||
m[6] = (y*z) * (1 - c) + (x*s);
|
m[6] = (y*z) * (1.f - c) + (x*s);
|
||||||
m[7] = 0;
|
m[7] = 0.f;
|
||||||
|
|
||||||
m[8] = (x*z) * (1 - c) + (y*s);
|
m[8] = (x*z) * (1.f - c) + (y*s);
|
||||||
m[9] = (y*z) * (1 - c) - (x*s);
|
m[9] = (y*z) * (1.f - c) - (x*s);
|
||||||
m[10] = (z*z) * (1 - c) + c;
|
m[10] = (z*z) * (1.f - c) + c;
|
||||||
m[11] = 0;
|
m[11] = 0.f;
|
||||||
|
|
||||||
m[12] = 0;
|
m[12] = 0.f;
|
||||||
m[13] = 0;
|
m[13] = 0.f;
|
||||||
m[14] = 0;
|
m[14] = 0.f;
|
||||||
m[15] = 1;
|
m[15] = 1.f;
|
||||||
|
|
||||||
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mat4::Frustum(float left, float right, float bottom, float top, float nearVal, float farVal)
|
void Mat4::Frustum(float left, float right, float bottom, float top, float nearVal, float farVal)
|
||||||
{
|
{
|
||||||
//=====================
|
float x = (2.0F*nearVal) / (right - left);
|
||||||
|
float y = (2.0F*nearVal) / (top - bottom);
|
||||||
|
float a = (right + left) / (right - left);
|
||||||
|
float b = (top + bottom) / (top - bottom);
|
||||||
|
float c = -(farVal + nearVal) / (farVal - nearVal);
|
||||||
|
float d = -(2.0F*farVal*nearVal) / (farVal - nearVal);
|
||||||
|
|
||||||
float m[16];
|
float m[16];
|
||||||
float x, y, a, b, c, d;
|
|
||||||
//=====================
|
|
||||||
|
|
||||||
x = (2.0F*nearVal) / (right - left);
|
|
||||||
y = (2.0F*nearVal) / (top - bottom);
|
|
||||||
a = (right + left) / (right - left);
|
|
||||||
b = (top + bottom) / (top - bottom);
|
|
||||||
c = -(farVal + nearVal) / (farVal - nearVal);
|
|
||||||
d = -(2.0F*farVal*nearVal) / (farVal - nearVal);
|
|
||||||
|
|
||||||
m[0] = x;
|
m[0] = x;
|
||||||
m[1] = 0;
|
m[1] = 0.f;
|
||||||
m[2] = 0;
|
m[2] = 0.f;
|
||||||
m[3] = 0;
|
m[3] = 0.f;
|
||||||
|
|
||||||
m[4] = 0;
|
m[4] = 0.f;
|
||||||
m[5] = y;
|
m[5] = y;
|
||||||
m[6] = 0;
|
m[6] = 0.f;
|
||||||
m[7] = 0;
|
m[7] = 0.f;
|
||||||
|
|
||||||
m[8] = a;
|
m[8] = a;
|
||||||
m[9] = b;
|
m[9] = b;
|
||||||
m[10] = c;
|
m[10] = c;
|
||||||
m[11] = -1;
|
m[11] = -1.f;
|
||||||
|
|
||||||
m[12] = 0;
|
m[12] = 0.f;
|
||||||
m[13] = 0;
|
m[13] = 0.f;
|
||||||
m[14] = d;
|
m[14] = d;
|
||||||
m[15] = 0;
|
m[15] = 0.f;
|
||||||
|
|
||||||
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mat4::Perspective(float fovy, float aspect, float zNear, float zFar)
|
void Mat4::Perspective(float fovy, float aspect, float zNear, float zFar)
|
||||||
{
|
{
|
||||||
//=========
|
float ymax = zNear * tanf(fovy * (float)(M_PI / 360.0));
|
||||||
float ymax;
|
float xmax = ymax * aspect;
|
||||||
float xmax;
|
|
||||||
//=========
|
|
||||||
|
|
||||||
ymax = zNear * tanf(fovy * (float)M_PI / 360.0f);
|
|
||||||
xmax = ymax * aspect;
|
|
||||||
|
|
||||||
Frustum(-xmax, xmax, -ymax, ymax, zNear, zFar);
|
Frustum(-xmax, xmax, -ymax, ymax, zNear, zFar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mat4::Ortho(float left, float right, float bottom, float top, float nearVal, float farVal)
|
void Mat4::Ortho(float left, float right, float bottom, float top, float nearVal, float farVal)
|
||||||
{
|
{
|
||||||
//================
|
float tx = -(right + left) / (right - left);
|
||||||
|
float ty = -(top + bottom) / (top - bottom);
|
||||||
|
float tz = -(farVal + nearVal) / (farVal - nearVal);
|
||||||
|
|
||||||
float m[16];
|
float m[16];
|
||||||
float tx, ty, tz;
|
m[0] = 2.f/(right-left);
|
||||||
//================
|
m[1] = 0.f;
|
||||||
|
m[2] = 0.f;
|
||||||
|
m[3] = 0.f;
|
||||||
|
|
||||||
tx = -(right + left) / (right - left);
|
m[4] = 0.f;
|
||||||
ty = -(top + bottom) / (top - bottom);
|
m[5] = 2.f/(top-bottom);
|
||||||
tz = -(farVal + nearVal) / (farVal - nearVal);
|
m[6] = 0.f;
|
||||||
|
m[7] = 0.f;
|
||||||
|
|
||||||
m[0] = 2/(right-left);
|
m[8] = 0.f;
|
||||||
m[1] = 0;
|
m[9] = 0.f;
|
||||||
m[2] = 0;
|
m[10] = -2.f/(farVal-nearVal);
|
||||||
m[3] = 0;
|
m[11] = 0.f;
|
||||||
|
|
||||||
m[4] = 0;
|
|
||||||
m[5] = 2/(top-bottom);
|
|
||||||
m[6] = 0;
|
|
||||||
m[7] = 0;
|
|
||||||
|
|
||||||
m[8] = 0;
|
|
||||||
m[9] = 0;
|
|
||||||
m[10] = -2/(farVal-nearVal);
|
|
||||||
m[11] = 0;
|
|
||||||
|
|
||||||
m[12] = tx;
|
m[12] = tx;
|
||||||
m[13] = ty;
|
m[13] = ty;
|
||||||
m[14] = tz;
|
m[14] = tz;
|
||||||
m[15] = 1;
|
m[15] = 1.f;
|
||||||
|
|
||||||
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
||||||
}
|
}
|
||||||
|
@ -324,4 +305,4 @@ void Mat4::Release()
|
||||||
m_vMat4.clear();
|
m_vMat4.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
}// New3D
|
}// New3D
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
#include "New3D.h"
|
#include "New3D.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "Vec.h"
|
#include "Vec.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
#include <unordered_map>
|
||||||
#include "R3DFloat.h"
|
#include "R3DFloat.h"
|
||||||
|
|
||||||
#define MAX_RAM_VERTS 300000
|
#define MAX_RAM_VERTS 300000
|
||||||
#define MAX_ROM_VERTS 1500000
|
#define MAX_ROM_VERTS 1500000
|
||||||
|
|
||||||
#define BYTE_TO_FLOAT(B) ((2.0f * (B) + 1.0f) * (1.0F/255.0f))
|
#define BYTE_TO_FLOAT(B) ((2.0f * (B) + 1.0f) * (float)(1.0/255.0))
|
||||||
|
|
||||||
namespace New3D {
|
namespace New3D {
|
||||||
|
|
||||||
CNew3D::CNew3D(const Util::Config::Node &config, std::string gameName)
|
CNew3D::CNew3D(const Util::Config::Node &config, const std::string& gameName)
|
||||||
: m_r3dShader(config),
|
: m_r3dShader(config),
|
||||||
m_r3dScrollFog(config),
|
m_r3dScrollFog(config),
|
||||||
m_gameName(gameName)
|
m_gameName(gameName)
|
||||||
|
@ -26,7 +27,7 @@ CNew3D::CNew3D(const Util::Config::Node &config, std::string gameName)
|
||||||
m_textureRAM = nullptr;
|
m_textureRAM = nullptr;
|
||||||
m_sunClamp = true;
|
m_sunClamp = true;
|
||||||
m_shadeIsSigned = true;
|
m_shadeIsSigned = true;
|
||||||
m_numPolyVerts = 3;
|
m_numPolyVerts = 3;
|
||||||
m_primType = GL_TRIANGLES;
|
m_primType = GL_TRIANGLES;
|
||||||
|
|
||||||
if (config["QuadRendering"].ValueAs<bool>()) {
|
if (config["QuadRendering"].ValueAs<bool>()) {
|
||||||
|
@ -72,8 +73,8 @@ void CNew3D::SetStepping(int stepping)
|
||||||
bool CNew3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXResParam, unsigned totalYResParam)
|
bool CNew3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXResParam, unsigned totalYResParam)
|
||||||
{
|
{
|
||||||
// Resolution and offset within physical display area
|
// Resolution and offset within physical display area
|
||||||
m_xRatio = xRes / 496.0f;
|
m_xRatio = xRes * (float)(1.0 / 496.0);
|
||||||
m_yRatio = yRes / 384.0f;
|
m_yRatio = yRes * (float)(1.0 / 384.0);
|
||||||
m_xOffs = xOffset;
|
m_xOffs = xOffset;
|
||||||
m_yOffs = yOffset;
|
m_yOffs = yOffset;
|
||||||
m_xRes = xRes;
|
m_xRes = xRes;
|
||||||
|
@ -129,7 +130,7 @@ void CNew3D::DrawScrollFog()
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
for (auto &n : m_nodes) {
|
for (auto &n : m_nodes) {
|
||||||
if (n.viewport.priority == i) {
|
if (n.viewport.priority == i) {
|
||||||
if (n.viewport.scrollFog) {
|
if (n.viewport.scrollFog != 0.f) {
|
||||||
rgba[0] = n.viewport.fogParams[0];
|
rgba[0] = n.viewport.fogParams[0];
|
||||||
rgba[1] = n.viewport.fogParams[1];
|
rgba[1] = n.viewport.fogParams[1];
|
||||||
rgba[2] = n.viewport.fogParams[2];
|
rgba[2] = n.viewport.fogParams[2];
|
||||||
|
@ -149,7 +150,7 @@ CheckScroll:
|
||||||
if (n.viewport.priority == i) {
|
if (n.viewport.priority == i) {
|
||||||
|
|
||||||
//if we have a fog density value
|
//if we have a fog density value
|
||||||
if (n.viewport.fogParams[3]) {
|
if (n.viewport.fogParams[3] != 0.f) {
|
||||||
|
|
||||||
if (rgba[0] == n.viewport.fogParams[0] &&
|
if (rgba[0] == n.viewport.fogParams[0] &&
|
||||||
rgba[1] == n.viewport.fogParams[1] &&
|
rgba[1] == n.viewport.fogParams[1] &&
|
||||||
|
@ -246,7 +247,7 @@ bool CNew3D::SkipLayer(int layer)
|
||||||
{
|
{
|
||||||
for (const auto &n : m_nodes) {
|
for (const auto &n : m_nodes) {
|
||||||
if (n.viewport.priority == layer) {
|
if (n.viewport.priority == layer) {
|
||||||
if (n.models.size()) {
|
if (!n.models.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,7 +284,7 @@ void CNew3D::SetRenderStates()
|
||||||
glDisable (GL_BLEND);
|
glDisable (GL_BLEND);
|
||||||
|
|
||||||
glStencilFunc (GL_EQUAL, 0, 0xFF); // basically stencil test passes if the value is zero
|
glStencilFunc (GL_EQUAL, 0, 0xFF); // basically stencil test passes if the value is zero
|
||||||
glStencilOp (GL_KEEP, GL_INCR, GL_INCR); // if the stencil test passes, we incriment the value
|
glStencilOp (GL_KEEP, GL_INCR, GL_INCR); // if the stencil test passes, we increment the value
|
||||||
glStencilMask (0xFF);
|
glStencilMask (0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +319,7 @@ void CNew3D::RenderFrame(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// release any resources from last frame
|
// release any resources from last frame
|
||||||
m_polyBufferRam.clear(); // clear dyanmic model memory buffer
|
m_polyBufferRam.clear(); // clear dynamic model memory buffer
|
||||||
m_nodes.clear(); // memory will grow during the object life time, that's fine, no need to shrink to fit
|
m_nodes.clear(); // memory will grow during the object life time, that's fine, no need to shrink to fit
|
||||||
m_modelMat.Release(); // would hope we wouldn't need this but no harm in checking
|
m_modelMat.Release(); // would hope we wouldn't need this but no harm in checking
|
||||||
m_nodeAttribs.Reset();
|
m_nodeAttribs.Reset();
|
||||||
|
@ -329,7 +330,7 @@ void CNew3D::RenderFrame(void)
|
||||||
m_vbo.Bind(true);
|
m_vbo.Bind(true);
|
||||||
m_vbo.BufferSubData(MAX_ROM_VERTS*sizeof(FVertex), m_polyBufferRam.size()*sizeof(FVertex), m_polyBufferRam.data()); // upload all the dynamic data to GPU in one go
|
m_vbo.BufferSubData(MAX_ROM_VERTS*sizeof(FVertex), m_polyBufferRam.size()*sizeof(FVertex), m_polyBufferRam.data()); // upload all the dynamic data to GPU in one go
|
||||||
|
|
||||||
if (m_polyBufferRom.size()) {
|
if (!m_polyBufferRom.empty()) {
|
||||||
|
|
||||||
// sync rom memory with vbo
|
// sync rom memory with vbo
|
||||||
int romBytes = (int)m_polyBufferRom.size() * sizeof(FVertex);
|
int romBytes = (int)m_polyBufferRom.size() * sizeof(FVertex);
|
||||||
|
@ -355,10 +356,6 @@ void CNew3D::RenderFrame(void)
|
||||||
|
|
||||||
for (int pri = 0; pri <= 3; pri++) {
|
for (int pri = 0; pri <= 3; pri++) {
|
||||||
|
|
||||||
//==============
|
|
||||||
bool hasOverlay;
|
|
||||||
//==============
|
|
||||||
|
|
||||||
if (SkipLayer(pri)) continue;
|
if (SkipLayer(pri)) continue;
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
|
@ -367,12 +364,12 @@ void CNew3D::RenderFrame(void)
|
||||||
|
|
||||||
m_r3dFrameBuffers.SetFBO(Layer::colour);
|
m_r3dFrameBuffers.SetFBO(Layer::colour);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
SetRenderStates();
|
SetRenderStates();
|
||||||
|
|
||||||
m_r3dShader.DiscardAlpha(true); // discard all translucent pixels in opaque pass
|
m_r3dShader.DiscardAlpha(true); // discard all translucent pixels in opaque pass
|
||||||
m_r3dFrameBuffers.SetFBO(Layer::colour);
|
m_r3dFrameBuffers.SetFBO(Layer::colour);
|
||||||
hasOverlay = RenderScene(pri, renderOverlay, Layer::colour);
|
bool hasOverlay = RenderScene(pri, renderOverlay, Layer::colour);
|
||||||
|
|
||||||
if (!renderOverlay && ProcessLos(pri)) {
|
if (!renderOverlay && ProcessLos(pri)) {
|
||||||
ProcessLos(pri);
|
ProcessLos(pri);
|
||||||
|
@ -514,8 +511,8 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
||||||
UINT16 uCullRadius;
|
UINT16 uCullRadius;
|
||||||
float fCullRadius;
|
float fCullRadius;
|
||||||
UINT16 uBlendRadius;
|
UINT16 uBlendRadius;
|
||||||
float fBlendRadius;
|
//float fBlendRadius;
|
||||||
UINT8 lodTablePointer;
|
//UINT8 lodTablePointer;
|
||||||
NodeType nodeType;
|
NodeType nodeType;
|
||||||
|
|
||||||
if (m_nodeAttribs.StackLimit()) {
|
if (m_nodeAttribs.StackLimit()) {
|
||||||
|
@ -533,7 +530,7 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
||||||
child1Ptr = node[0x07 - m_offset] & 0x7FFFFFF; // mask colour table bits
|
child1Ptr = node[0x07 - m_offset] & 0x7FFFFFF; // mask colour table bits
|
||||||
sibling2Ptr = node[0x08 - m_offset] & 0x1FFFFFF; // mask colour table bits
|
sibling2Ptr = node[0x08 - m_offset] & 0x1FFFFFF; // mask colour table bits
|
||||||
matrixOffset = node[0x03 - m_offset] & 0xFFF;
|
matrixOffset = node[0x03 - m_offset] & 0xFFF;
|
||||||
lodTablePointer = (node[0x03 - m_offset] >> 12) & 0x7F;
|
//lodTablePointer = (node[0x03 - m_offset] >> 12) & 0x7F;
|
||||||
|
|
||||||
// check our node type
|
// check our node type
|
||||||
if (nodeType == NodeType::viewport) {
|
if (nodeType == NodeType::viewport) {
|
||||||
|
@ -556,7 +553,7 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
||||||
|
|
||||||
if (!m_offset) { // Step 1.5+
|
if (!m_offset) { // Step 1.5+
|
||||||
|
|
||||||
float modelScale = *(float *)&node[1];
|
float modelScale = uint_as_float(node[1]);
|
||||||
if (modelScale > std::numeric_limits<float>::min()) {
|
if (modelScale > std::numeric_limits<float>::min()) {
|
||||||
m_nodeAttribs.currentModelScale = modelScale;
|
m_nodeAttribs.currentModelScale = modelScale;
|
||||||
}
|
}
|
||||||
|
@ -576,9 +573,9 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
||||||
|
|
||||||
// apply translation vector
|
// apply translation vector
|
||||||
if (node[0x00] & 0x10) {
|
if (node[0x00] & 0x10) {
|
||||||
float x = *(float *)&node[0x04 - m_offset];
|
float x = uint_as_float(node[0x04 - m_offset]);
|
||||||
float y = *(float *)&node[0x05 - m_offset];
|
float y = uint_as_float(node[0x05 - m_offset]);
|
||||||
float z = *(float *)&node[0x06 - m_offset];
|
float z = uint_as_float(node[0x06 - m_offset]);
|
||||||
m_modelMat.Translate(x, y, z);
|
m_modelMat.Translate(x, y, z);
|
||||||
}
|
}
|
||||||
// multiply matrix, if specified
|
// multiply matrix, if specified
|
||||||
|
@ -590,7 +587,7 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
||||||
fCullRadius = R3DFloat::GetFloat16(uCullRadius);
|
fCullRadius = R3DFloat::GetFloat16(uCullRadius);
|
||||||
|
|
||||||
uBlendRadius = node[9 - m_offset] >> 16;
|
uBlendRadius = node[9 - m_offset] >> 16;
|
||||||
fBlendRadius = R3DFloat::GetFloat16(uBlendRadius);
|
//fBlendRadius = R3DFloat::GetFloat16(uBlendRadius);
|
||||||
|
|
||||||
if (m_nodeAttribs.currentClipStatus != Clip::INSIDE) {
|
if (m_nodeAttribs.currentClipStatus != Clip::INSIDE) {
|
||||||
|
|
||||||
|
@ -788,14 +785,14 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
{
|
{
|
||||||
static const GLfloat color[8][3] =
|
static const GLfloat color[8][3] =
|
||||||
{ // RGB1 color translation
|
{ // RGB1 color translation
|
||||||
{ 0.0, 0.0, 0.0 }, // off
|
{ 0.0f, 0.0f, 0.0f }, // off
|
||||||
{ 0.0, 0.0, 1.0 }, // blue
|
{ 0.0f, 0.0f, 1.0f }, // blue
|
||||||
{ 0.0, 1.0, 0.0 }, // green
|
{ 0.0f, 1.0f, 0.0f }, // green
|
||||||
{ 0.0, 1.0, 1.0 }, // cyan
|
{ 0.0f, 1.0f, 1.0f }, // cyan
|
||||||
{ 1.0, 0.0, 0.0 }, // red
|
{ 1.0f, 0.0f, 0.0f }, // red
|
||||||
{ 1.0, 0.0, 1.0 }, // purple
|
{ 1.0f, 0.0f, 1.0f }, // purple
|
||||||
{ 1.0, 1.0, 0.0 }, // yellow
|
{ 1.0f, 1.0f, 0.0f }, // yellow
|
||||||
{ 1.0, 1.0, 1.0 } // white
|
{ 1.0f, 1.0f, 1.0f } // white
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((addr & 0x00FFFFFF) == 0) {
|
if ((addr & 0x00FFFFFF) == 0) {
|
||||||
|
@ -824,10 +821,10 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
m_currentPriority = vp->priority;
|
m_currentPriority = vp->priority;
|
||||||
|
|
||||||
// Fetch viewport parameters (TO-DO: would rounding make a difference?)
|
// Fetch viewport parameters (TO-DO: would rounding make a difference?)
|
||||||
vp->vpX = (int)(((vpnode[0x1A] & 0xFFFF) / 16.0f) + 0.5f); // viewport X (12.4 fixed point)
|
vp->vpX = (int)(((vpnode[0x1A] & 0xFFFF) * (float)(1.0 / 16.0)) + 0.5f); // viewport X (12.4 fixed point)
|
||||||
vp->vpY = (int)(((vpnode[0x1A] >> 16) / 16.0f) + 0.5f); // viewport Y (12.4)
|
vp->vpY = (int)(((vpnode[0x1A] >> 16) * (float)(1.0 / 16.0)) + 0.5f); // viewport Y (12.4)
|
||||||
vp->vpWidth = (int)(((vpnode[0x14] & 0xFFFF) / 4.0f) + 0.5f); // width (14.2)
|
vp->vpWidth = (int)(((vpnode[0x14] & 0xFFFF) * (float)(1.0 / 4.0)) + 0.5f); // width (14.2)
|
||||||
vp->vpHeight = (int)(((vpnode[0x14] >> 16) / 4.0f) + 0.5f); // height (14.2)
|
vp->vpHeight = (int)(((vpnode[0x14] >> 16) * (float)(1.0 / 4.0)) + 0.5f); // height (14.2)
|
||||||
|
|
||||||
uint32_t matrixBase = vpnode[0x16] & 0xFFFFFF; // matrix base address
|
uint32_t matrixBase = vpnode[0x16] & 0xFFFFFF; // matrix base address
|
||||||
|
|
||||||
|
@ -840,29 +837,29 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
vp->angle_bottom = -atan2(*(float *)&vpnode[18], -*(float *)&vpnode[19]); // Perhaps they are just used for culling and not rendering.
|
vp->angle_bottom = -atan2(*(float *)&vpnode[18], -*(float *)&vpnode[19]); // Perhaps they are just used for culling and not rendering.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float cv = *(float *)&vpnode[0x8]; // 1/(left-right)
|
float cv = uint_as_float(vpnode[0x8]); // 1/(left-right)
|
||||||
float cw = *(float *)&vpnode[0x9]; // 1/(top-bottom)
|
float cw = uint_as_float(vpnode[0x9]); // 1/(top-bottom)
|
||||||
float io = *(float *)&vpnode[0xa]; // top / bottom (ratio) - ish
|
float io = uint_as_float(vpnode[0xa]); // top / bottom (ratio) - ish
|
||||||
float jo = *(float *)&vpnode[0xb]; // left / right (ratio)
|
float jo = uint_as_float(vpnode[0xb]); // left / right (ratio)
|
||||||
|
|
||||||
vp->angle_left = (1.0f / cv) * (0.0f - jo);
|
vp->angle_left = (0.0f - jo) / cv;
|
||||||
vp->angle_right = (1.0f / cv) * (1.0f - jo);
|
vp->angle_right = (1.0f - jo) / cv;
|
||||||
vp->angle_bottom = (1.0f / cw) * -(1.0f - io);
|
vp->angle_bottom = -(1.0f - io)/ cw;
|
||||||
vp->angle_top = (1.0f / cw) * -(0.0f - io);
|
vp->angle_top = -(0.0f - io)/ cw;
|
||||||
|
|
||||||
// calculate the frustum shape, near/far pair are dummy values
|
// calculate the frustum shape, near/far pair are dummy values
|
||||||
CalcViewport(vp, 1, 1000);
|
CalcViewport(vp, 1.f, 1000.f);
|
||||||
|
|
||||||
// calculate frustum planes
|
// calculate frustum planes
|
||||||
CalcFrustumPlanes(m_planes, vp->projectionMatrix); // we need to calc a 'projection matrix' to get the correct frustum planes for clipping
|
CalcFrustumPlanes(m_planes, vp->projectionMatrix); // we need to calc a 'projection matrix' to get the correct frustum planes for clipping
|
||||||
|
|
||||||
// Lighting (note that sun vector points toward sun -- away from vertex)
|
// Lighting (note that sun vector points toward sun -- away from vertex)
|
||||||
vp->lightingParams[0] = *(float *)&vpnode[0x05]; // sun X
|
vp->lightingParams[0] = uint_as_float(vpnode[0x05]); // sun X
|
||||||
vp->lightingParams[1] = -*(float *)&vpnode[0x06]; // sun Y (- to convert to ogl cordinate system)
|
vp->lightingParams[1] = -uint_as_float(vpnode[0x06]); // sun Y (- to convert to ogl cordinate system)
|
||||||
vp->lightingParams[2] = -*(float *)&vpnode[0x04]; // sun Z (- to convert to ogl cordinate system)
|
vp->lightingParams[2] = -uint_as_float(vpnode[0x04]); // sun Z (- to convert to ogl cordinate system)
|
||||||
vp->lightingParams[3] = std::max(0.f, std::min(*(float *)&vpnode[0x07], 1.0f)); // sun intensity (clamp to 0-1)
|
vp->lightingParams[3] = std::max(0.f, std::min(uint_as_float(vpnode[0x07]), 1.0f)); // sun intensity (clamp to 0-1)
|
||||||
vp->lightingParams[4] = (float)((vpnode[0x24] >> 8) & 0xFF) * (1.0f / 255.0f); // ambient intensity
|
vp->lightingParams[4] = (float)((vpnode[0x24] >> 8) & 0xFF) * (float)(1.0 / 255.0); // ambient intensity
|
||||||
vp->lightingParams[5] = 0.0; // reserved
|
vp->lightingParams[5] = 0.0f; // reserved
|
||||||
|
|
||||||
vp->sunClamp = m_sunClamp;
|
vp->sunClamp = m_sunClamp;
|
||||||
vp->intensityClamp = (m_step == 0x10); // just step 1.0 ?
|
vp->intensityClamp = (m_step == 0x10); // just step 1.0 ?
|
||||||
|
@ -871,13 +868,13 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
// Spotlight
|
// Spotlight
|
||||||
int spotColorIdx = (vpnode[0x20] >> 11) & 7; // spotlight color index
|
int spotColorIdx = (vpnode[0x20] >> 11) & 7; // spotlight color index
|
||||||
int spotFogColorIdx = (vpnode[0x20] >> 8) & 7; // spotlight on fog color index
|
int spotFogColorIdx = (vpnode[0x20] >> 8) & 7; // spotlight on fog color index
|
||||||
vp->spotEllipse[0] = (float)(INT16)(vpnode[0x1E] & 0xFFFF) / 8.0f; // spotlight X position (13.3 fixed point)
|
vp->spotEllipse[0] = (float)(INT16)(vpnode[0x1E] & 0xFFFF) * (float)(1.0 / 8.0); // spotlight X position (13.3 fixed point)
|
||||||
vp->spotEllipse[1] = (float)(INT16)(vpnode[0x1D] & 0xFFFF) / 8.0f; // spotlight Y
|
vp->spotEllipse[1] = (float)(INT16)(vpnode[0x1D] & 0xFFFF) * (float)(1.0 / 8.0); // spotlight Y
|
||||||
vp->spotEllipse[2] = (float)((vpnode[0x1E] >> 16) & 0xFFFF); // spotlight X size (16-bit)
|
vp->spotEllipse[2] = (float)((vpnode[0x1E] >> 16) & 0xFFFF); // spotlight X size (16-bit)
|
||||||
vp->spotEllipse[3] = (float)((vpnode[0x1D] >> 16) & 0xFFFF); // spotlight Y size
|
vp->spotEllipse[3] = (float)((vpnode[0x1D] >> 16) & 0xFFFF); // spotlight Y size
|
||||||
|
|
||||||
vp->spotRange[0] = 1.0f / (*(float *)&vpnode[0x21]); // spotlight start
|
vp->spotRange[0] = 1.0f / uint_as_float(vpnode[0x21]); // spotlight start
|
||||||
vp->spotRange[1] = *(float *)&vpnode[0x1F]; // spotlight extent
|
vp->spotRange[1] = uint_as_float(vpnode[0x1F]); // spotlight extent
|
||||||
|
|
||||||
vp->spotColor[0] = color[spotColorIdx][0]; // spotlight color
|
vp->spotColor[0] = color[spotColorIdx][0]; // spotlight color
|
||||||
vp->spotColor[1] = color[spotColorIdx][1];
|
vp->spotColor[1] = color[spotColorIdx][1];
|
||||||
|
@ -898,8 +895,8 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
vp->spotEllipse[3] = std::roundf(2047.0f / vp->spotEllipse[3]);
|
vp->spotEllipse[3] = std::roundf(2047.0f / vp->spotEllipse[3]);
|
||||||
|
|
||||||
// Scale the spotlight to the OpenGL viewport
|
// Scale the spotlight to the OpenGL viewport
|
||||||
vp->spotEllipse[0] = vp->spotEllipse[0] * m_xRatio + m_xOffs;
|
vp->spotEllipse[0] = vp->spotEllipse[0] * m_xRatio + (float)m_xOffs;
|
||||||
vp->spotEllipse[1] = vp->spotEllipse[1] * m_yRatio + m_yOffs;
|
vp->spotEllipse[1] = vp->spotEllipse[1] * m_yRatio + (float)m_yOffs;
|
||||||
vp->spotEllipse[2] *= m_xRatio;
|
vp->spotEllipse[2] *= m_xRatio;
|
||||||
vp->spotEllipse[3] *= m_yRatio;
|
vp->spotEllipse[3] *= m_yRatio;
|
||||||
|
|
||||||
|
@ -908,22 +905,22 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
vp->losPosY = (int)(((vpnode[0x1c] >> 16) / 16.0f) + 0.5f); // y position 0 starts from the top
|
vp->losPosY = (int)(((vpnode[0x1c] >> 16) / 16.0f) + 0.5f); // y position 0 starts from the top
|
||||||
|
|
||||||
// Fog
|
// Fog
|
||||||
vp->fogParams[0] = (float)((vpnode[0x22] >> 16) & 0xFF) * (1.0f / 255.0f); // fog color R
|
vp->fogParams[0] = (float)((vpnode[0x22] >> 16) & 0xFF) * (float)(1.0 / 255.0); // fog color R
|
||||||
vp->fogParams[1] = (float)((vpnode[0x22] >> 8) & 0xFF) * (1.0f / 255.0f); // fog color G
|
vp->fogParams[1] = (float)((vpnode[0x22] >> 8) & 0xFF) * (float)(1.0 / 255.0); // fog color G
|
||||||
vp->fogParams[2] = (float)((vpnode[0x22] >> 0) & 0xFF) * (1.0f / 255.0f); // fog color B
|
vp->fogParams[2] = (float)((vpnode[0x22] >> 0) & 0xFF) * (float)(1.0 / 255.0); // fog color B
|
||||||
vp->fogParams[3] = std::abs(*(float *)&vpnode[0x23]); // fog density - ocean hunter uses negative values, but looks the same
|
vp->fogParams[3] = std::abs(uint_as_float(vpnode[0x23])); // fog density - ocean hunter uses negative values, but looks the same
|
||||||
vp->fogParams[4] = (float)(INT16)(vpnode[0x25] & 0xFFFF)*(1.0f / 255.0f); // fog start
|
vp->fogParams[4] = (float)(INT16)(vpnode[0x25] & 0xFFFF)* (float)(1.0 / 255.0); // fog start
|
||||||
|
|
||||||
// Avoid Infinite and NaN values for Star Wars Trilogy
|
// Avoid Infinite and NaN values for Star Wars Trilogy
|
||||||
if (std::isinf(vp->fogParams[3]) || std::isnan(vp->fogParams[3])) {
|
if (std::isinf(vp->fogParams[3]) || std::isnan(vp->fogParams[3])) {
|
||||||
for (int i = 0; i < 7; i++) vp->fogParams[i] = 0.0f;
|
for (int i = 0; i < 7; i++) vp->fogParams[i] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
vp->fogParams[5] = (float)((vpnode[0x24] >> 16) & 0xFF) * (1.0f / 255.0f); // fog attenuation
|
vp->fogParams[5] = (float)((vpnode[0x24] >> 16) & 0xFF) * (float)(1.0 / 255.0); // fog attenuation
|
||||||
vp->fogParams[6] = (float)((vpnode[0x25] >> 16) & 0xFF) * (1.0f / 255.0f); // fog ambient
|
vp->fogParams[6] = (float)((vpnode[0x25] >> 16) & 0xFF) * (float)(1.0 / 255.0); // fog ambient
|
||||||
|
|
||||||
vp->scrollFog = (float)(vpnode[0x20] & 0xFF) * (1.0f / 255.0f); // scroll fog
|
vp->scrollFog = (float)(vpnode[0x20] & 0xFF) * (float)(1.0 / 255.0); // scroll fog
|
||||||
vp->scrollAtt = (float)(vpnode[0x24] & 0xFF) * (1.0f / 255.0f); // scroll attenuation
|
vp->scrollAtt = (float)(vpnode[0x24] & 0xFF) * (float)(1.0 / 255.0); // scroll attenuation
|
||||||
|
|
||||||
// Clear texture offsets before proceeding
|
// Clear texture offsets before proceeding
|
||||||
m_nodeAttribs.Reset();
|
m_nodeAttribs.Reset();
|
||||||
|
@ -947,7 +944,7 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
void CNew3D::CopyVertexData(const R3DPoly& r3dPoly, std::vector<FVertex>& vertexArray)
|
void CNew3D::CopyVertexData(const R3DPoly& r3dPoly, std::vector<FVertex>& vertexArray)
|
||||||
{
|
{
|
||||||
// both lemans 24 and dirt devils are rendering some totally transparent polys as the first object in each viewport
|
// both lemans 24 and dirt devils are rendering some totally transparent polys as the first object in each viewport
|
||||||
// in dirt devils it's parallel to the camera so is completel invisible, but breaks our depth calculation
|
// in dirt devils it's parallel to the camera so is completely invisible, but breaks our depth calculation
|
||||||
// in lemans 24 its a sort of diamond shape, but never leaves a hole in the transparent geometry so must be being skipped by the h/w
|
// in lemans 24 its a sort of diamond shape, but never leaves a hole in the transparent geometry so must be being skipped by the h/w
|
||||||
if (r3dPoly.faceColour[3] == 0) {
|
if (r3dPoly.faceColour[3] == 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -1058,7 +1055,7 @@ void CNew3D::SetMeshValues(SortingMesh *currentMesh, PolyHeader &ph)
|
||||||
|
|
||||||
if (currentMesh->microTexture) {
|
if (currentMesh->microTexture) {
|
||||||
|
|
||||||
float microTexScale[] = { 2, 4, 16, 256 };
|
static const float microTexScale[] = { 2.f, 4.f, 16.f, 256.f };
|
||||||
|
|
||||||
currentMesh->microTextureID = ph.MicroTextureID();
|
currentMesh->microTextureID = ph.MicroTextureID();
|
||||||
currentMesh->microTextureScale = microTexScale[ph.MicroTextureMinLOD()];
|
currentMesh->microTextureScale = microTexScale[ph.MicroTextureMinLOD()];
|
||||||
|
@ -1073,7 +1070,7 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
UINT64 lastHash = -1;
|
UINT64 lastHash = -1;
|
||||||
SortingMesh* currentMesh = nullptr;
|
SortingMesh* currentMesh = nullptr;
|
||||||
|
|
||||||
std::map<UINT64, SortingMesh> sMap;
|
std::unordered_map<UINT64, SortingMesh> sMap;
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -1086,7 +1083,6 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
|
|
||||||
R3DPoly p; // current polygon
|
R3DPoly p; // current polygon
|
||||||
float uvScale;
|
float uvScale;
|
||||||
int i, j;
|
|
||||||
|
|
||||||
if (ph.header[6] == 0) {
|
if (ph.header[6] == 0) {
|
||||||
break;
|
break;
|
||||||
|
@ -1099,9 +1095,7 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
|
|
||||||
if (sMap.count(hash) == 0) {
|
if (sMap.count(hash) == 0) {
|
||||||
|
|
||||||
sMap[hash] = SortingMesh();
|
currentMesh = &sMap.insert({hash, SortingMesh()}).first->second;
|
||||||
|
|
||||||
currentMesh = &sMap[hash];
|
|
||||||
|
|
||||||
//make space for our vertices
|
//make space for our vertices
|
||||||
currentMesh->verts.reserve(numTriangles * 3);
|
currentMesh->verts.reserve(numTriangles * 3);
|
||||||
|
@ -1109,8 +1103,8 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
//set mesh values
|
//set mesh values
|
||||||
SetMeshValues(currentMesh, ph);
|
SetMeshValues(currentMesh, ph);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
currentMesh = &sMap[hash];
|
currentMesh = &sMap[hash];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain basic polygon parameters
|
// Obtain basic polygon parameters
|
||||||
|
@ -1120,9 +1114,8 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
ph.FaceNormal(p.faceNormal);
|
ph.FaceNormal(p.faceNormal);
|
||||||
|
|
||||||
// Fetch reused vertices according to bitfield, then new verts
|
// Fetch reused vertices according to bitfield, then new verts
|
||||||
i = 0;
|
int j = 0;
|
||||||
j = 0;
|
for (int i = 0; i < 4; i++) // up to 4 reused vertices
|
||||||
for (i = 0; i < 4; i++) // up to 4 reused vertices
|
|
||||||
{
|
{
|
||||||
if (ph.SharedVertex(i))
|
if (ph.SharedVertex(i))
|
||||||
{
|
{
|
||||||
|
@ -1165,7 +1158,7 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have flat shading, we can't re-use normals from shared vertices
|
// if we have flat shading, we can't re-use normals from shared vertices
|
||||||
for (i = 0; i < p.number && !ph.SmoothShading(); i++) {
|
for (int i = 0; i < p.number && !ph.SmoothShading(); i++) {
|
||||||
p.v[i].normal[0] = p.faceNormal[0];
|
p.v[i].normal[0] = p.faceNormal[0];
|
||||||
p.v[i].normal[1] = p.faceNormal[1];
|
p.v[i].normal[1] = p.faceNormal[1];
|
||||||
p.v[i].normal[2] = p.faceNormal[2];
|
p.v[i].normal[2] = p.faceNormal[2];
|
||||||
|
@ -1202,7 +1195,7 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
//==========
|
//==========
|
||||||
|
|
||||||
if (!m_shadeIsSigned) {
|
if (!m_shadeIsSigned) {
|
||||||
shade = (ix & 0xFF) / 255.f;
|
shade = (ix & 0xFF) * (float)(1.0 / 255.0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
shade = BYTE_TO_FLOAT((INT8)(ix & 0xFF));
|
shade = BYTE_TO_FLOAT((INT8)(ix & 0xFF));
|
||||||
|
@ -1237,8 +1230,8 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
// flip normals
|
// flip normals
|
||||||
V3::inverse(tempP.faceNormal);
|
V3::inverse(tempP.faceNormal);
|
||||||
|
|
||||||
for (int i = 0; i < tempP.number; i++) {
|
for (int i2 = 0; i2 < tempP.number; i2++) {
|
||||||
V3::inverse(tempP.v[i].normal);
|
V3::inverse(tempP.v[i2].normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyVertexData(tempP, currentMesh->verts);
|
CopyVertexData(tempP, currentMesh->verts);
|
||||||
|
@ -1250,7 +1243,7 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy current vertices into previous vertex array
|
// Copy current vertices into previous vertex array
|
||||||
for (i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
m_prev[i] = p.v[i];
|
m_prev[i] = p.v[i];
|
||||||
m_prevTexCoords[i][0] = texCoords[i][0];
|
m_prevTexCoords[i][0] = texCoords[i][0];
|
||||||
m_prevTexCoords[i][1] = texCoords[i][1];
|
m_prevTexCoords[i][1] = texCoords[i][1];
|
||||||
|
@ -1365,10 +1358,10 @@ void CNew3D::CalcFrustumPlanes(Plane p[5], const float* matrix)
|
||||||
p[3].Normalise();
|
p[3].Normalise();
|
||||||
|
|
||||||
// Front Plane
|
// Front Plane
|
||||||
p[4].a = 0;
|
p[4].a = 0.f;
|
||||||
p[4].b = 0;
|
p[4].b = 0.f;
|
||||||
p[4].c = -1;
|
p[4].c = -1.f;
|
||||||
p[4].d =0;
|
p[4].d = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNew3D::CalcBox(float distance, BBox& box)
|
void CNew3D::CalcBox(float distance, BBox& box)
|
||||||
|
@ -1377,49 +1370,49 @@ void CNew3D::CalcBox(float distance, BBox& box)
|
||||||
box.points[0][0] = -distance;
|
box.points[0][0] = -distance;
|
||||||
box.points[0][1] = -distance;
|
box.points[0][1] = -distance;
|
||||||
box.points[0][2] = distance;
|
box.points[0][2] = distance;
|
||||||
box.points[0][3] = 1;
|
box.points[0][3] = 1.f;
|
||||||
|
|
||||||
//bottom left back
|
//bottom left back
|
||||||
box.points[1][0] = -distance;
|
box.points[1][0] = -distance;
|
||||||
box.points[1][1] = -distance;
|
box.points[1][1] = -distance;
|
||||||
box.points[1][2] = -distance;
|
box.points[1][2] = -distance;
|
||||||
box.points[1][3] = 1;
|
box.points[1][3] = 1.f;
|
||||||
|
|
||||||
//bottom right back
|
//bottom right back
|
||||||
box.points[2][0] = distance;
|
box.points[2][0] = distance;
|
||||||
box.points[2][1] = -distance;
|
box.points[2][1] = -distance;
|
||||||
box.points[2][2] = -distance;
|
box.points[2][2] = -distance;
|
||||||
box.points[2][3] = 1;
|
box.points[2][3] = 1.f;
|
||||||
|
|
||||||
//bottom right front
|
//bottom right front
|
||||||
box.points[3][0] = distance;
|
box.points[3][0] = distance;
|
||||||
box.points[3][1] = -distance;
|
box.points[3][1] = -distance;
|
||||||
box.points[3][2] = distance;
|
box.points[3][2] = distance;
|
||||||
box.points[3][3] = 1;
|
box.points[3][3] = 1.f;
|
||||||
|
|
||||||
//top left front
|
//top left front
|
||||||
box.points[4][0] = -distance;
|
box.points[4][0] = -distance;
|
||||||
box.points[4][1] = distance;
|
box.points[4][1] = distance;
|
||||||
box.points[4][2] = distance;
|
box.points[4][2] = distance;
|
||||||
box.points[4][3] = 1;
|
box.points[4][3] = 1.f;
|
||||||
|
|
||||||
//top left back
|
//top left back
|
||||||
box.points[5][0] = -distance;
|
box.points[5][0] = -distance;
|
||||||
box.points[5][1] = distance;
|
box.points[5][1] = distance;
|
||||||
box.points[5][2] = -distance;
|
box.points[5][2] = -distance;
|
||||||
box.points[5][3] = 1;
|
box.points[5][3] = 1.f;
|
||||||
|
|
||||||
//top right back
|
//top right back
|
||||||
box.points[6][0] = distance;
|
box.points[6][0] = distance;
|
||||||
box.points[6][1] = distance;
|
box.points[6][1] = distance;
|
||||||
box.points[6][2] = -distance;
|
box.points[6][2] = -distance;
|
||||||
box.points[6][3] = 1;
|
box.points[6][3] = 1.f;
|
||||||
|
|
||||||
//top right front
|
//top right front
|
||||||
box.points[7][0] = distance;
|
box.points[7][0] = distance;
|
||||||
box.points[7][1] = distance;
|
box.points[7][1] = distance;
|
||||||
box.points[7][2] = distance;
|
box.points[7][2] = distance;
|
||||||
box.points[7][3] = 1;
|
box.points[7][3] = 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNew3D::MultVec(const float matrix[16], const float in[4], float out[4])
|
void CNew3D::MultVec(const float matrix[16], const float in[4], float out[4])
|
||||||
|
@ -1444,7 +1437,7 @@ void CNew3D::TransformBox(const float *m, BBox& box)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Clip CNew3D::ClipBox(BBox& box, Plane planes[5])
|
Clip CNew3D::ClipBox(const BBox& box, Plane planes[5])
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
@ -1453,7 +1446,7 @@ Clip CNew3D::ClipBox(BBox& box, Plane planes[5])
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
|
|
||||||
for (int j = 0; j < 5; j++) {
|
for (int j = 0; j < 5; j++) {
|
||||||
if (planes[j].DistanceToPoint(box.points[i]) >= 0) {
|
if (planes[j].DistanceToPoint(box.points[i]) >= 0.f) {
|
||||||
temp++;
|
temp++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1472,7 +1465,7 @@ Clip CNew3D::ClipBox(BBox& box, Plane planes[5])
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
|
|
||||||
for (int j = 0; j < 8; j++) {
|
for (int j = 0; j < 8; j++) {
|
||||||
if (planes[i].DistanceToPoint(box.points[j]) >= 0) {
|
if (planes[i].DistanceToPoint(box.points[j]) >= 0.f) {
|
||||||
temp++;
|
temp++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1490,7 +1483,7 @@ Clip CNew3D::ClipBox(BBox& box, Plane planes[5])
|
||||||
void CNew3D::CalcBoxExtents(const BBox& box)
|
void CNew3D::CalcBoxExtents(const BBox& box)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
if (box.points[i][2] < 0) {
|
if (box.points[i][2] < 0.f) {
|
||||||
m_nfPairs[m_currentPriority].zNear = std::max(box.points[i][2], m_nfPairs[m_currentPriority].zNear);
|
m_nfPairs[m_currentPriority].zNear = std::max(box.points[i][2], m_nfPairs[m_currentPriority].zNear);
|
||||||
m_nfPairs[m_currentPriority].zFar = std::min(box.points[i][2], m_nfPairs[m_currentPriority].zFar);
|
m_nfPairs[m_currentPriority].zFar = std::min(box.points[i][2], m_nfPairs[m_currentPriority].zFar);
|
||||||
}
|
}
|
||||||
|
@ -1512,13 +1505,11 @@ void CNew3D::ClipPolygon(ClipPoly& clipPoly, Plane planes[5])
|
||||||
|
|
||||||
//=================
|
//=================
|
||||||
bool currentIn;
|
bool currentIn;
|
||||||
bool nextIn;
|
|
||||||
float currentDot;
|
float currentDot;
|
||||||
float nextDot;
|
|
||||||
//=================
|
//=================
|
||||||
|
|
||||||
currentDot = planes[i].DotProduct(in->list[0].pos);
|
currentDot = planes[i].DotProduct(in->list[0].pos);
|
||||||
currentIn = (currentDot + planes[i].d) >= 0;
|
currentIn = (currentDot + planes[i].d) >= 0.f;
|
||||||
out->count = 0;
|
out->count = 0;
|
||||||
|
|
||||||
for (int j = 0; j < in->count; j++) {
|
for (int j = 0; j < in->count; j++) {
|
||||||
|
@ -1533,16 +1524,16 @@ void CNew3D::ClipPolygon(ClipPoly& clipPoly, Plane planes[5])
|
||||||
nextIndex = 0;
|
nextIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextDot = planes[i].DotProduct(in->list[nextIndex].pos);
|
float nextDot = planes[i].DotProduct(in->list[nextIndex].pos);
|
||||||
nextIn = (nextDot + planes[i].d) >= 0;
|
bool nextIn = (nextDot + planes[i].d) >= 0.f;
|
||||||
|
|
||||||
// we have an intersection
|
// we have an intersection
|
||||||
if (currentIn != nextIn) {
|
if (currentIn != nextIn) {
|
||||||
|
|
||||||
float u = (currentDot + planes[i].d) / (currentDot - nextDot);
|
float u = (currentDot + planes[i].d) / (currentDot - nextDot);
|
||||||
|
|
||||||
float* p1 = in->list[j].pos;
|
const float* p1 = in->list[j].pos;
|
||||||
float* p2 = in->list[nextIndex].pos;
|
const float* p2 = in->list[nextIndex].pos;
|
||||||
|
|
||||||
out->list[out->count].pos[0] = p1[0] + ((p2[0] - p1[0]) * u);
|
out->list[out->count].pos[0] = p1[0] + ((p2[0] - p1[0]) * u);
|
||||||
out->list[out->count].pos[1] = p1[1] + ((p2[1] - p1[1]) * u);
|
out->list[out->count].pos[1] = p1[1] + ((p2[1] - p1[1]) * u);
|
||||||
|
@ -1590,7 +1581,7 @@ void CNew3D::ClipModel(const Model *m)
|
||||||
ClipPolygon(clipPoly, m_planes);
|
ClipPolygon(clipPoly, m_planes);
|
||||||
|
|
||||||
for (int j = 0; j < clipPoly.count; j++) {
|
for (int j = 0; j < clipPoly.count; j++) {
|
||||||
if (clipPoly.list[j].pos[2] < 0) {
|
if (clipPoly.list[j].pos[2] < 0.f) {
|
||||||
m_nfPairs[m_currentPriority].zNear = std::max(clipPoly.list[j].pos[2], m_nfPairs[m_currentPriority].zNear);
|
m_nfPairs[m_currentPriority].zNear = std::max(clipPoly.list[j].pos[2], m_nfPairs[m_currentPriority].zNear);
|
||||||
m_nfPairs[m_currentPriority].zFar = std::min(clipPoly.list[j].pos[2], m_nfPairs[m_currentPriority].zFar);
|
m_nfPairs[m_currentPriority].zFar = std::min(clipPoly.list[j].pos[2], m_nfPairs[m_currentPriority].zFar);
|
||||||
}
|
}
|
||||||
|
@ -1601,12 +1592,12 @@ void CNew3D::ClipModel(const Model *m)
|
||||||
|
|
||||||
void CNew3D::CalcViewport(Viewport* vp, float near, float far)
|
void CNew3D::CalcViewport(Viewport* vp, float near, float far)
|
||||||
{
|
{
|
||||||
if (far > 1e30) {
|
if (far > 1e30f) {
|
||||||
far = near * 1000000; // fix for ocean hunter which passes some FLT_MAX for a few matrices. HW must have some safe guard for these
|
far = near * 1000000.f; // fix for ocean hunter which passes some FLT_MAX for a few matrices. HW must have some safe guard for these
|
||||||
}
|
}
|
||||||
|
|
||||||
if (near < far / 1000000) {
|
if (near < far / 1000000.f) {
|
||||||
near = far / 1000000; // if we get really close to zero somehow, we will have almost no depth precision
|
near = far / 1000000.f; // if we get really close to zero somehow, we will have almost no depth precision
|
||||||
}
|
}
|
||||||
|
|
||||||
float l = near * vp->angle_left; // we need to calc the shape of the projection frustum for culling
|
float l = near * vp->angle_left; // we need to calc the shape of the projection frustum for culling
|
||||||
|
@ -1646,18 +1637,18 @@ void CNew3D::CalcViewport(Viewport* vp, float near, float far)
|
||||||
float correction = windowAR / viewableAreaAR;
|
float correction = windowAR / viewableAreaAR;
|
||||||
|
|
||||||
vp->x = 0;
|
vp->x = 0;
|
||||||
vp->y = m_yOffs + (int)((384 - (vp->vpY + vp->vpHeight))*m_yRatio);
|
vp->y = m_yOffs + (int)((float)(384 - (vp->vpY + vp->vpHeight))*m_yRatio);
|
||||||
vp->width = m_totalXRes;
|
vp->width = m_totalXRes;
|
||||||
vp->height = (int)(vp->vpHeight*m_yRatio);
|
vp->height = (int)((float)vp->vpHeight*m_yRatio);
|
||||||
|
|
||||||
vp->projectionMatrix.Frustum(l*correction, r*correction, b, t, near, far);
|
vp->projectionMatrix.Frustum(l*correction, r*correction, b, t, near, far);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
vp->x = m_xOffs + (int)(vp->vpX*m_xRatio);
|
vp->x = m_xOffs + (int)((float)vp->vpX*m_xRatio);
|
||||||
vp->y = m_yOffs + (int)((384 - (vp->vpY + vp->vpHeight))*m_yRatio);
|
vp->y = m_yOffs + (int)((float)(384 - (vp->vpY + vp->vpHeight))*m_yRatio);
|
||||||
vp->width = (int)(vp->vpWidth*m_xRatio);
|
vp->width = (int)((float)vp->vpWidth*m_xRatio);
|
||||||
vp->height = (int)(vp->vpHeight*m_yRatio);
|
vp->height = (int)((float)vp->vpHeight*m_yRatio);
|
||||||
|
|
||||||
vp->projectionMatrix.Frustum(l, r, b, t, near, far);
|
vp->projectionMatrix.Frustum(l, r, b, t, near, far);
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ public:
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* config Run-time configuration.
|
* config Run-time configuration.
|
||||||
*/
|
*/
|
||||||
CNew3D(const Util::Config::Node &config, std::string gameName);
|
CNew3D(const Util::Config::Node &config, const std::string& gameName);
|
||||||
~CNew3D(void);
|
~CNew3D(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -305,7 +305,7 @@ private:
|
||||||
void CalcBox (float distance, BBox& box);
|
void CalcBox (float distance, BBox& box);
|
||||||
void TransformBox (const float *m, BBox& box);
|
void TransformBox (const float *m, BBox& box);
|
||||||
void MultVec (const float matrix[16], const float in[4], float out[4]);
|
void MultVec (const float matrix[16], const float in[4], float out[4]);
|
||||||
Clip ClipBox (BBox& box, Plane planes[5]);
|
Clip ClipBox (const BBox& box, Plane planes[5]);
|
||||||
void ClipModel (const Model *m);
|
void ClipModel (const Model *m);
|
||||||
void ClipPolygon (ClipPoly& clipPoly, Plane planes[5]);
|
void ClipPolygon (ClipPoly& clipPoly, Plane planes[5]);
|
||||||
void CalcBoxExtents (const BBox& box);
|
void CalcBoxExtents (const BBox& box);
|
||||||
|
|
|
@ -8,11 +8,11 @@ struct Plane
|
||||||
float a, b, c, d;
|
float a, b, c, d;
|
||||||
|
|
||||||
void Normalise() {
|
void Normalise() {
|
||||||
float temp = std::sqrt((a * a) + (b * b) + (c * c));
|
float temp = 1.f/std::sqrt((a * a) + (b * b) + (c * c));
|
||||||
a /= temp;
|
a *= temp;
|
||||||
b /= temp;
|
b *= temp;
|
||||||
c /= temp;
|
c *= temp;
|
||||||
d /= temp;
|
d *= temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
float DistanceToPoint(const float v[3]) {
|
float DistanceToPoint(const float v[3]) {
|
||||||
|
@ -24,4 +24,4 @@ struct Plane
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
#include "R3DFloat.h"
|
#include "R3DFloat.h"
|
||||||
|
#include "Util\GenericValue.h"
|
||||||
|
|
||||||
float R3DFloat::GetFloat16(UINT16 f)
|
float R3DFloat::GetFloat16(UINT16 f)
|
||||||
{
|
{
|
||||||
|
@ -13,17 +14,16 @@ float R3DFloat::GetFloat32(UINT32 f)
|
||||||
|
|
||||||
UINT32 R3DFloat::ConvertProFloat(UINT32 a1)
|
UINT32 R3DFloat::ConvertProFloat(UINT32 a1)
|
||||||
{
|
{
|
||||||
int exponent = (a1 & 0x7E000000) >> 25;
|
UINT32 exponent = (a1 & 0x7E000000) >> 25;
|
||||||
|
|
||||||
if (exponent <= 31) { // positive
|
if (exponent <= 31) { // positive
|
||||||
exponent += 127;
|
exponent += 127;
|
||||||
}
|
}
|
||||||
else { // negative exponent
|
else { // negative exponent
|
||||||
exponent -= 64;
|
exponent += 127 - 64;
|
||||||
exponent += 127;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mantissa = (a1 & 0x1FFFFFF) >> 2;
|
UINT32 mantissa = (a1 & 0x1FFFFFF) >> 2;
|
||||||
|
|
||||||
return (a1 & 0x80000000) | (exponent << 23) | mantissa;
|
return (a1 & 0x80000000) | (exponent << 23) | mantissa;
|
||||||
}
|
}
|
||||||
|
@ -35,5 +35,5 @@ UINT32 R3DFloat::Convert16BitProFloat(UINT32 a1)
|
||||||
|
|
||||||
float R3DFloat::ToFloat(UINT32 a1)
|
float R3DFloat::ToFloat(UINT32 a1)
|
||||||
{
|
{
|
||||||
return *(float*)(&a1);
|
return uint_as_float(a1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
namespace R3DFloat
|
namespace R3DFloat
|
||||||
{
|
{
|
||||||
static const UINT16 Pro16BitMax = 0x7fff;
|
constexpr UINT16 Pro16BitMax = 0x7fff;
|
||||||
static const float Pro16BitFltMin = 1e-7f; // float min in IEEE
|
constexpr float Pro16BitFltMin = 1e-7f; // float min in IEEE
|
||||||
|
|
||||||
float GetFloat16(UINT16 f);
|
float GetFloat16(UINT16 f);
|
||||||
float GetFloat32(UINT32 f);
|
float GetFloat32(UINT32 f);
|
||||||
|
@ -14,4 +14,4 @@ namespace R3DFloat
|
||||||
float ToFloat(UINT32 a1); // integer float to actual IEEE 754 float
|
float ToFloat(UINT32 a1); // integer float to actual IEEE 754 float
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,7 +37,7 @@ private:
|
||||||
texCoords[1] = t;
|
texCoords[1] = t;
|
||||||
verts[0] = x;
|
verts[0] = x;
|
||||||
verts[1] = y;
|
verts[1] = y;
|
||||||
verts[2] = 0; // z = 0
|
verts[2] = 0.f; // z = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
float texCoords[2];
|
float texCoords[2];
|
||||||
|
@ -73,4 +73,4 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -602,7 +602,7 @@ void SCSP_StopSlot(_SLOT *slot,int keyoff)
|
||||||
//DebugLog("KEYOFF2 %d",slot->slot);
|
//DebugLog("KEYOFF2 %d",slot->slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define log2(n) (log((float) n)/log((float) 2))
|
//#define log2(n) (log((float) n)/log((float) 2))
|
||||||
|
|
||||||
bool SCSP_Init(const Util::Config::Node &config, int n)
|
bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
{
|
{
|
||||||
|
@ -641,7 +641,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
{
|
{
|
||||||
double fcent=(double) 1200.0*log2((double)(((double) 1024.0+(double)i)/(double)1024.0));
|
double fcent=(double) 1200.0*log2((double)(((double) 1024.0+(double)i)/(double)1024.0));
|
||||||
//float fcent=1.0+(float) i/1024.0;
|
//float fcent=1.0+(float) i/1024.0;
|
||||||
fcent=(double) 44100.0*pow(2.0,fcent/1200.0);
|
fcent=(double) 44100.0*exp2(fcent/1200.0);
|
||||||
FNS_Table[i]=(UINT32)((float) (1<<SHIFT) *fcent);
|
FNS_Table[i]=(UINT32)((float) (1<<SHIFT) *fcent);
|
||||||
//FNS_Table[i]=(i>>(10-SHIFT))|(1<<SHIFT);
|
//FNS_Table[i]=(i>>(10-SHIFT))|(1<<SHIFT);
|
||||||
|
|
||||||
|
@ -655,7 +655,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
#ifdef RB_VOLUME
|
#ifdef RB_VOLUME
|
||||||
// Volume table, 1 = -0.375dB, 8 = -3dB, 256 = -96dB
|
// Volume table, 1 = -0.375dB, 8 = -3dB, 256 = -96dB
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
volume[i] = 65536.0*pow(2.0, (-0.375 / 6.0)*i);
|
volume[i] = 65536.0*exp2((-0.375 / 6.0)*i);
|
||||||
for (i = 256; i < 256 * 4; i++)
|
for (i = 256; i < 256 * 4; i++)
|
||||||
volume[i] = 0;
|
volume[i] = 0;
|
||||||
|
|
||||||
|
|
|
@ -42,10 +42,10 @@ struct _LFO
|
||||||
#define LFIX(v) ((unsigned int) ((float) (1<<LFO_SHIFT)*(v)))
|
#define LFIX(v) ((unsigned int) ((float) (1<<LFO_SHIFT)*(v)))
|
||||||
|
|
||||||
//Convert DB to multiply amplitude
|
//Convert DB to multiply amplitude
|
||||||
#define DB(v) LFIX(pow(10.0,v/20.0))
|
#define DB(v) LFIX(pow(10.0,(v)*(1.0/20.0)))
|
||||||
|
|
||||||
//Convert cents to step increment
|
//Convert cents to step increment
|
||||||
#define CENTS(v) LFIX(pow(2.0,v/1200.0))
|
#define CENTS(v) LFIX(exp2((v)*(1.0/1200.0)))
|
||||||
|
|
||||||
static int PLFO_TRI[256], PLFO_SQR[256], PLFO_SAW[256], PLFO_NOI[256];
|
static int PLFO_TRI[256], PLFO_SQR[256], PLFO_SAW[256], PLFO_NOI[256];
|
||||||
static int ALFO_TRI[256], ALFO_SQR[256], ALFO_SAW[256], ALFO_NOI[256];
|
static int ALFO_TRI[256], ALFO_SQR[256], ALFO_SAW[256], ALFO_NOI[256];
|
||||||
|
@ -115,12 +115,12 @@ void LFO_Init(void)
|
||||||
float limit = PSCALE[s];
|
float limit = PSCALE[s];
|
||||||
for (i = -128; i < 128; ++i)
|
for (i = -128; i < 128; ++i)
|
||||||
{
|
{
|
||||||
PSCALES[s][i + 128] = CENTS(((limit*(float)i) / 128.0));
|
PSCALES[s][i + 128] = CENTS(((limit*(double)i) / 128.0));
|
||||||
}
|
}
|
||||||
limit = -ASCALE[s];
|
limit = -ASCALE[s];
|
||||||
for (i = 0; i < 256; ++i)
|
for (i = 0; i < 256; ++i)
|
||||||
{
|
{
|
||||||
ASCALES[s][i] = DB(((limit*(float)i) / 256.0));
|
ASCALES[s][i] = DB(((limit*(double)i) / 256.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,57 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
|
#if __cplusplus >= 202002L
|
||||||
|
#include <bit>
|
||||||
|
#define float_as_int(x) std::bit_cast<int>(x)
|
||||||
|
#define int_as_float(x) std::bit_cast<float>(x)
|
||||||
|
#define uint_as_float(x) std::bit_cast<float>(x)
|
||||||
|
#elif 1
|
||||||
|
template <class Dest, class Source>
|
||||||
|
inline Dest bit_cast(Source const& source) {
|
||||||
|
static_assert(sizeof(Dest) == sizeof(Source), "size of destination and source objects must be equal");
|
||||||
|
static_assert(std::is_trivially_copyable<Dest>::value, "destination type must be trivially copyable.");
|
||||||
|
static_assert(std::is_trivially_copyable<Source>::value, "source type must be trivially copyable");
|
||||||
|
|
||||||
|
Dest dest;
|
||||||
|
std::memcpy(&dest, &source, sizeof(dest));
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
#define float_as_int(x) bit_cast<int,float>(x)
|
||||||
|
#define int_as_float(x) bit_cast<float,int>(x)
|
||||||
|
#define uint_as_float(x) bit_cast<float,unsigned int>(x)
|
||||||
|
#else
|
||||||
|
inline int float_as_int(const float x)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
float f;
|
||||||
|
int i;
|
||||||
|
} uc;
|
||||||
|
uc.f = x;
|
||||||
|
return uc.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float int_as_float(const int i)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
int i;
|
||||||
|
float f;
|
||||||
|
} iaf;
|
||||||
|
iaf.i = i;
|
||||||
|
return iaf.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float uint_as_float(const unsigned int i)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
unsigned int u;
|
||||||
|
float f;
|
||||||
|
} iaf;
|
||||||
|
iaf.u = i;
|
||||||
|
return iaf.f;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Util
|
namespace Util
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
|
|
Loading…
Reference in a new issue