mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-25 23:25:40 +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 <cstdint>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
namespace Legacy3D {
|
||||
|
||||
// Microsoft doesn't provide isnan() and isinf()
|
||||
#ifdef _MSC_VER
|
||||
#include <float.h>
|
||||
#include <cfloat>
|
||||
#define ISNAN(x) (_isnan(x))
|
||||
#define ISINF(x) (!_finite(x))
|
||||
#else
|
||||
|
@ -847,9 +851,9 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri, bool wideScreen)
|
|||
int vpHeight = (vpnode[0x14]>>18)&0x3FFF; // height (14.2)
|
||||
|
||||
// Field of view and clipping
|
||||
GLfloat vpTopAngle = (float) asin(*(float *)&vpnode[0x0E]); // FOV Y upper half-angle (radians)
|
||||
GLfloat vpBotAngle = (float) asin(*(float *)&vpnode[0x12]); // FOV Y lower half-angle
|
||||
GLfloat fovYDegrees = (vpTopAngle+vpBotAngle)*(float)(180.0/3.14159265358979323846);
|
||||
GLfloat vpTopAngle = asinf(uint_as_float(vpnode[0x0E])); // FOV Y upper half-angle (radians)
|
||||
GLfloat vpBotAngle = asinf(uint_as_float(vpnode[0x12])); // FOV Y lower half-angle
|
||||
GLfloat fovYDegrees = (vpTopAngle+vpBotAngle)*(float)(180.0/M_PI);
|
||||
// TO-DO: investigate clipping planes
|
||||
|
||||
// Set up viewport and projection (TO-DO: near and far clipping)
|
||||
|
@ -944,11 +948,11 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri, bool wideScreen)
|
|||
m32 *= m32;
|
||||
m13 *= m13;
|
||||
|
||||
if ((m21>1.05) || (m21<0.95))
|
||||
if ((m21>1.05f) || (m21<0.95f))
|
||||
return;
|
||||
if ((m32>1.05) || (m32<0.95))
|
||||
if ((m32>1.05f) || (m32<0.95f))
|
||||
return;
|
||||
if ((m13>1.05) || (m13<0.95))
|
||||
if ((m13>1.05f) || (m13<0.95f))
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -725,7 +725,7 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
|
|||
// Specular shininess
|
||||
GLfloat specularCoefficient = (GLfloat) ((P->header[0]>>26) & 0x3F) * (1.0f/63.0f);
|
||||
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
|
||||
{
|
||||
specularCoefficient = 0.; // disable
|
||||
|
@ -1224,7 +1224,7 @@ bool CLegacy3D::CreateModelCache(ModelCache *Cache, unsigned vboMaxVerts,
|
|||
{
|
||||
// Last ditch attempt: try the local buffer size
|
||||
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)
|
||||
return ErrorLog("OpenGL was unable to provide a %s vertex buffer.", isDynamic?"dynamic":"static");
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <utility>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265359
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
namespace New3D {
|
||||
|
@ -17,10 +17,10 @@ void Mat4::LoadIdentity()
|
|||
{
|
||||
float *m = currentMatrix;
|
||||
|
||||
m[0] = 1; m[4] = 0; m[8 ] = 0; m[12] = 0;
|
||||
m[1] = 0; m[5] = 1; m[9 ] = 0; m[13] = 0;
|
||||
m[2] = 0; m[6] = 0; m[10] = 1; m[14] = 0;
|
||||
m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1;
|
||||
m[0] = 1.f; m[4] = 0.f; m[8 ] = 0.f; m[12] = 0.f;
|
||||
m[1] = 0.f; m[5] = 1.f; m[9 ] = 0.f; m[13] = 0.f;
|
||||
m[2] = 0.f; m[6] = 0.f; m[10] = 1.f; m[14] = 0.f;
|
||||
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])
|
||||
|
@ -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 P(row,col) r[(col<<2)+row]
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
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, 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];
|
||||
//==========
|
||||
|
||||
m[0] = 1;
|
||||
m[1] = 0;
|
||||
m[2] = 0;
|
||||
m[3] = 0;
|
||||
m[0] = 1.f;
|
||||
m[1] = 0.f;
|
||||
m[2] = 0.f;
|
||||
m[3] = 0.f;
|
||||
|
||||
m[4] = 0;
|
||||
m[5] = 1;
|
||||
m[6] = 0;
|
||||
m[7] = 0;
|
||||
m[4] = 0.f;
|
||||
m[5] = 1.f;
|
||||
m[6] = 0.f;
|
||||
m[7] = 0.f;
|
||||
|
||||
m[8] = 0;
|
||||
m[9] = 0;
|
||||
m[10] = 1;
|
||||
m[11] = 0;
|
||||
m[8] = 0.f;
|
||||
m[9] = 0.f;
|
||||
m[10] = 1.f;
|
||||
m[11] = 0.f;
|
||||
|
||||
m[12] = x;
|
||||
m[13] = y;
|
||||
m[14] = z;
|
||||
m[15] = 1;
|
||||
m[15] = 1.f;
|
||||
|
||||
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
||||
}
|
||||
|
@ -86,155 +85,137 @@ void Mat4::Scale(float x, float y, float z)
|
|||
//==========
|
||||
|
||||
m[0] = x;
|
||||
m[1] = 0;
|
||||
m[2] = 0;
|
||||
m[3] = 0;
|
||||
m[1] = 0.f;
|
||||
m[2] = 0.f;
|
||||
m[3] = 0.f;
|
||||
|
||||
m[4] = 0;
|
||||
m[4] = 0.f;
|
||||
m[5] = y;
|
||||
m[6] = 0;
|
||||
m[7] = 0;
|
||||
m[6] = 0.f;
|
||||
m[7] = 0.f;
|
||||
|
||||
m[8] = 0;
|
||||
m[9] = 0;
|
||||
m[8] = 0.f;
|
||||
m[9] = 0.f;
|
||||
m[10] = z;
|
||||
m[11] = 0;
|
||||
m[11] = 0.f;
|
||||
|
||||
m[12] = 0;
|
||||
m[13] = 0;
|
||||
m[14] = 0;
|
||||
m[15] = 1;
|
||||
m[12] = 0.f;
|
||||
m[13] = 0.f;
|
||||
m[14] = 0.f;
|
||||
m[15] = 1.f;
|
||||
|
||||
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
||||
}
|
||||
|
||||
void Mat4::Rotate(float angle, float x, float y, float z)
|
||||
{
|
||||
//===========
|
||||
float c;
|
||||
float s;
|
||||
float m[16];
|
||||
//===========
|
||||
|
||||
// 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;
|
||||
y /= len;
|
||||
z /= len;
|
||||
x *= inv_len;
|
||||
y *= inv_len;
|
||||
z *= inv_len;
|
||||
}
|
||||
|
||||
c = std::cos(angle*3.14159265f / 180.0f);
|
||||
s = std::sin(angle*3.14159265f / 180.0f);
|
||||
float c = std::cos(angle*(float)(M_PI / 180.0));
|
||||
float s = std::sin(angle*(float)(M_PI / 180.0));
|
||||
|
||||
m[0] = (x*x) * (1 - c) + c;
|
||||
m[1] = (y*x) * (1 - c) + (z*s);
|
||||
m[2] = (x*z) * (1 - c) - (y*s);
|
||||
m[3] = 0;
|
||||
float m[16];
|
||||
m[0] = (x*x) * (1.f - c) + c;
|
||||
m[1] = (y*x) * (1.f - c) + (z*s);
|
||||
m[2] = (x*z) * (1.f - c) - (y*s);
|
||||
m[3] = 0.f;
|
||||
|
||||
m[4] = (x*y) * (1 - c) - (z*s);
|
||||
m[5] = (y*y) * (1 - c) + c;
|
||||
m[6] = (y*z) * (1 - c) + (x*s);
|
||||
m[7] = 0;
|
||||
m[4] = (x*y) * (1.f - c) - (z*s);
|
||||
m[5] = (y*y) * (1.f - c) + c;
|
||||
m[6] = (y*z) * (1.f - c) + (x*s);
|
||||
m[7] = 0.f;
|
||||
|
||||
m[8] = (x*z) * (1 - c) + (y*s);
|
||||
m[9] = (y*z) * (1 - c) - (x*s);
|
||||
m[10] = (z*z) * (1 - c) + c;
|
||||
m[11] = 0;
|
||||
m[8] = (x*z) * (1.f - c) + (y*s);
|
||||
m[9] = (y*z) * (1.f - c) - (x*s);
|
||||
m[10] = (z*z) * (1.f - c) + c;
|
||||
m[11] = 0.f;
|
||||
|
||||
m[12] = 0;
|
||||
m[13] = 0;
|
||||
m[14] = 0;
|
||||
m[15] = 1;
|
||||
m[12] = 0.f;
|
||||
m[13] = 0.f;
|
||||
m[14] = 0.f;
|
||||
m[15] = 1.f;
|
||||
|
||||
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
||||
}
|
||||
|
||||
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 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[1] = 0;
|
||||
m[2] = 0;
|
||||
m[3] = 0;
|
||||
m[1] = 0.f;
|
||||
m[2] = 0.f;
|
||||
m[3] = 0.f;
|
||||
|
||||
m[4] = 0;
|
||||
m[4] = 0.f;
|
||||
m[5] = y;
|
||||
m[6] = 0;
|
||||
m[7] = 0;
|
||||
m[6] = 0.f;
|
||||
m[7] = 0.f;
|
||||
|
||||
m[8] = a;
|
||||
m[9] = b;
|
||||
m[10] = c;
|
||||
m[11] = -1;
|
||||
m[11] = -1.f;
|
||||
|
||||
m[12] = 0;
|
||||
m[13] = 0;
|
||||
m[12] = 0.f;
|
||||
m[13] = 0.f;
|
||||
m[14] = d;
|
||||
m[15] = 0;
|
||||
m[15] = 0.f;
|
||||
|
||||
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
||||
}
|
||||
|
||||
void Mat4::Perspective(float fovy, float aspect, float zNear, float zFar)
|
||||
{
|
||||
//=========
|
||||
float ymax;
|
||||
float xmax;
|
||||
//=========
|
||||
|
||||
ymax = zNear * tanf(fovy * (float)M_PI / 360.0f);
|
||||
xmax = ymax * aspect;
|
||||
float ymax = zNear * tanf(fovy * (float)(M_PI / 360.0));
|
||||
float xmax = ymax * aspect;
|
||||
|
||||
Frustum(-xmax, xmax, -ymax, ymax, zNear, zFar);
|
||||
}
|
||||
|
||||
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 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);
|
||||
ty = -(top + bottom) / (top - bottom);
|
||||
tz = -(farVal + nearVal) / (farVal - nearVal);
|
||||
m[4] = 0.f;
|
||||
m[5] = 2.f/(top-bottom);
|
||||
m[6] = 0.f;
|
||||
m[7] = 0.f;
|
||||
|
||||
m[0] = 2/(right-left);
|
||||
m[1] = 0;
|
||||
m[2] = 0;
|
||||
m[3] = 0;
|
||||
|
||||
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[8] = 0.f;
|
||||
m[9] = 0.f;
|
||||
m[10] = -2.f/(farVal-nearVal);
|
||||
m[11] = 0.f;
|
||||
|
||||
m[12] = tx;
|
||||
m[13] = ty;
|
||||
m[14] = tz;
|
||||
m[15] = 1;
|
||||
m[15] = 1.f;
|
||||
|
||||
Mat4::MultiMatrices(currentMatrix, m, currentMatrix);
|
||||
}
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
#include "New3D.h"
|
||||
#include "New3D.h"
|
||||
#include "Texture.h"
|
||||
#include "Vec.h"
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <string.h>
|
||||
#include <cstring>
|
||||
#include <unordered_map>
|
||||
#include "R3DFloat.h"
|
||||
|
||||
#define MAX_RAM_VERTS 300000
|
||||
#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 {
|
||||
|
||||
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_r3dScrollFog(config),
|
||||
m_gameName(gameName)
|
||||
|
@ -72,8 +73,8 @@ void CNew3D::SetStepping(int stepping)
|
|||
bool CNew3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXResParam, unsigned totalYResParam)
|
||||
{
|
||||
// Resolution and offset within physical display area
|
||||
m_xRatio = xRes / 496.0f;
|
||||
m_yRatio = yRes / 384.0f;
|
||||
m_xRatio = xRes * (float)(1.0 / 496.0);
|
||||
m_yRatio = yRes * (float)(1.0 / 384.0);
|
||||
m_xOffs = xOffset;
|
||||
m_yOffs = yOffset;
|
||||
m_xRes = xRes;
|
||||
|
@ -129,7 +130,7 @@ void CNew3D::DrawScrollFog()
|
|||
for (int i = 0; i < 4; i++) {
|
||||
for (auto &n : m_nodes) {
|
||||
if (n.viewport.priority == i) {
|
||||
if (n.viewport.scrollFog) {
|
||||
if (n.viewport.scrollFog != 0.f) {
|
||||
rgba[0] = n.viewport.fogParams[0];
|
||||
rgba[1] = n.viewport.fogParams[1];
|
||||
rgba[2] = n.viewport.fogParams[2];
|
||||
|
@ -149,7 +150,7 @@ CheckScroll:
|
|||
if (n.viewport.priority == i) {
|
||||
|
||||
//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] &&
|
||||
rgba[1] == n.viewport.fogParams[1] &&
|
||||
|
@ -246,7 +247,7 @@ bool CNew3D::SkipLayer(int layer)
|
|||
{
|
||||
for (const auto &n : m_nodes) {
|
||||
if (n.viewport.priority == layer) {
|
||||
if (n.models.size()) {
|
||||
if (!n.models.empty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +284,7 @@ void CNew3D::SetRenderStates()
|
|||
glDisable (GL_BLEND);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -318,7 +319,7 @@ void CNew3D::RenderFrame(void)
|
|||
}
|
||||
|
||||
// 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_modelMat.Release(); // would hope we wouldn't need this but no harm in checking
|
||||
m_nodeAttribs.Reset();
|
||||
|
@ -329,7 +330,7 @@ void CNew3D::RenderFrame(void)
|
|||
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
|
||||
|
||||
if (m_polyBufferRom.size()) {
|
||||
if (!m_polyBufferRom.empty()) {
|
||||
|
||||
// sync rom memory with vbo
|
||||
int romBytes = (int)m_polyBufferRom.size() * sizeof(FVertex);
|
||||
|
@ -355,10 +356,6 @@ void CNew3D::RenderFrame(void)
|
|||
|
||||
for (int pri = 0; pri <= 3; pri++) {
|
||||
|
||||
//==============
|
||||
bool hasOverlay;
|
||||
//==============
|
||||
|
||||
if (SkipLayer(pri)) continue;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
@ -372,7 +369,7 @@ void CNew3D::RenderFrame(void)
|
|||
|
||||
m_r3dShader.DiscardAlpha(true); // discard all translucent pixels in opaque pass
|
||||
m_r3dFrameBuffers.SetFBO(Layer::colour);
|
||||
hasOverlay = RenderScene(pri, renderOverlay, Layer::colour);
|
||||
bool hasOverlay = RenderScene(pri, renderOverlay, Layer::colour);
|
||||
|
||||
if (!renderOverlay && ProcessLos(pri)) {
|
||||
ProcessLos(pri);
|
||||
|
@ -514,8 +511,8 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
|||
UINT16 uCullRadius;
|
||||
float fCullRadius;
|
||||
UINT16 uBlendRadius;
|
||||
float fBlendRadius;
|
||||
UINT8 lodTablePointer;
|
||||
//float fBlendRadius;
|
||||
//UINT8 lodTablePointer;
|
||||
NodeType nodeType;
|
||||
|
||||
if (m_nodeAttribs.StackLimit()) {
|
||||
|
@ -533,7 +530,7 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
|||
child1Ptr = node[0x07 - m_offset] & 0x7FFFFFF; // mask colour table bits
|
||||
sibling2Ptr = node[0x08 - m_offset] & 0x1FFFFFF; // mask colour table bits
|
||||
matrixOffset = node[0x03 - m_offset] & 0xFFF;
|
||||
lodTablePointer = (node[0x03 - m_offset] >> 12) & 0x7F;
|
||||
//lodTablePointer = (node[0x03 - m_offset] >> 12) & 0x7F;
|
||||
|
||||
// check our node type
|
||||
if (nodeType == NodeType::viewport) {
|
||||
|
@ -556,7 +553,7 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
|||
|
||||
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()) {
|
||||
m_nodeAttribs.currentModelScale = modelScale;
|
||||
}
|
||||
|
@ -576,9 +573,9 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
|||
|
||||
// apply translation vector
|
||||
if (node[0x00] & 0x10) {
|
||||
float x = *(float *)&node[0x04 - m_offset];
|
||||
float y = *(float *)&node[0x05 - m_offset];
|
||||
float z = *(float *)&node[0x06 - m_offset];
|
||||
float x = uint_as_float(node[0x04 - m_offset]);
|
||||
float y = uint_as_float(node[0x05 - m_offset]);
|
||||
float z = uint_as_float(node[0x06 - m_offset]);
|
||||
m_modelMat.Translate(x, y, z);
|
||||
}
|
||||
// multiply matrix, if specified
|
||||
|
@ -590,7 +587,7 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
|||
fCullRadius = R3DFloat::GetFloat16(uCullRadius);
|
||||
|
||||
uBlendRadius = node[9 - m_offset] >> 16;
|
||||
fBlendRadius = R3DFloat::GetFloat16(uBlendRadius);
|
||||
//fBlendRadius = R3DFloat::GetFloat16(uBlendRadius);
|
||||
|
||||
if (m_nodeAttribs.currentClipStatus != Clip::INSIDE) {
|
||||
|
||||
|
@ -788,14 +785,14 @@ void CNew3D::RenderViewport(UINT32 addr)
|
|||
{
|
||||
static const GLfloat color[8][3] =
|
||||
{ // RGB1 color translation
|
||||
{ 0.0, 0.0, 0.0 }, // off
|
||||
{ 0.0, 0.0, 1.0 }, // blue
|
||||
{ 0.0, 1.0, 0.0 }, // green
|
||||
{ 0.0, 1.0, 1.0 }, // cyan
|
||||
{ 1.0, 0.0, 0.0 }, // red
|
||||
{ 1.0, 0.0, 1.0 }, // purple
|
||||
{ 1.0, 1.0, 0.0 }, // yellow
|
||||
{ 1.0, 1.0, 1.0 } // white
|
||||
{ 0.0f, 0.0f, 0.0f }, // off
|
||||
{ 0.0f, 0.0f, 1.0f }, // blue
|
||||
{ 0.0f, 1.0f, 0.0f }, // green
|
||||
{ 0.0f, 1.0f, 1.0f }, // cyan
|
||||
{ 1.0f, 0.0f, 0.0f }, // red
|
||||
{ 1.0f, 0.0f, 1.0f }, // purple
|
||||
{ 1.0f, 1.0f, 0.0f }, // yellow
|
||||
{ 1.0f, 1.0f, 1.0f } // white
|
||||
};
|
||||
|
||||
if ((addr & 0x00FFFFFF) == 0) {
|
||||
|
@ -824,10 +821,10 @@ void CNew3D::RenderViewport(UINT32 addr)
|
|||
m_currentPriority = vp->priority;
|
||||
|
||||
// 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->vpY = (int)(((vpnode[0x1A] >> 16) / 16.0f) + 0.5f); // viewport Y (12.4)
|
||||
vp->vpWidth = (int)(((vpnode[0x14] & 0xFFFF) / 4.0f) + 0.5f); // width (14.2)
|
||||
vp->vpHeight = (int)(((vpnode[0x14] >> 16) / 4.0f) + 0.5f); // height (14.2)
|
||||
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) * (float)(1.0 / 16.0)) + 0.5f); // viewport Y (12.4)
|
||||
vp->vpWidth = (int)(((vpnode[0x14] & 0xFFFF) * (float)(1.0 / 4.0)) + 0.5f); // width (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
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
float cv = *(float *)&vpnode[0x8]; // 1/(left-right)
|
||||
float cw = *(float *)&vpnode[0x9]; // 1/(top-bottom)
|
||||
float io = *(float *)&vpnode[0xa]; // top / bottom (ratio) - ish
|
||||
float jo = *(float *)&vpnode[0xb]; // left / right (ratio)
|
||||
float cv = uint_as_float(vpnode[0x8]); // 1/(left-right)
|
||||
float cw = uint_as_float(vpnode[0x9]); // 1/(top-bottom)
|
||||
float io = uint_as_float(vpnode[0xa]); // top / bottom (ratio) - ish
|
||||
float jo = uint_as_float(vpnode[0xb]); // left / right (ratio)
|
||||
|
||||
vp->angle_left = (1.0f / cv) * (0.0f - jo);
|
||||
vp->angle_right = (1.0f / cv) * (1.0f - jo);
|
||||
vp->angle_bottom = (1.0f / cw) * -(1.0f - io);
|
||||
vp->angle_top = (1.0f / cw) * -(0.0f - io);
|
||||
vp->angle_left = (0.0f - jo) / cv;
|
||||
vp->angle_right = (1.0f - jo) / cv;
|
||||
vp->angle_bottom = -(1.0f - io)/ cw;
|
||||
vp->angle_top = -(0.0f - io)/ cw;
|
||||
|
||||
// calculate the frustum shape, near/far pair are dummy values
|
||||
CalcViewport(vp, 1, 1000);
|
||||
CalcViewport(vp, 1.f, 1000.f);
|
||||
|
||||
// calculate frustum planes
|
||||
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)
|
||||
vp->lightingParams[0] = *(float *)&vpnode[0x05]; // sun X
|
||||
vp->lightingParams[1] = -*(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[3] = std::max(0.f, std::min(*(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[5] = 0.0; // reserved
|
||||
vp->lightingParams[0] = uint_as_float(vpnode[0x05]); // sun X
|
||||
vp->lightingParams[1] = -uint_as_float(vpnode[0x06]); // sun Y (- 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(uint_as_float(vpnode[0x07]), 1.0f)); // sun intensity (clamp to 0-1)
|
||||
vp->lightingParams[4] = (float)((vpnode[0x24] >> 8) & 0xFF) * (float)(1.0 / 255.0); // ambient intensity
|
||||
vp->lightingParams[5] = 0.0f; // reserved
|
||||
|
||||
vp->sunClamp = m_sunClamp;
|
||||
vp->intensityClamp = (m_step == 0x10); // just step 1.0 ?
|
||||
|
@ -871,13 +868,13 @@ void CNew3D::RenderViewport(UINT32 addr)
|
|||
// Spotlight
|
||||
int spotColorIdx = (vpnode[0x20] >> 11) & 7; // spotlight 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[1] = (float)(INT16)(vpnode[0x1D] & 0xFFFF) / 8.0f; // spotlight Y
|
||||
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) * (float)(1.0 / 8.0); // spotlight Y
|
||||
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->spotRange[0] = 1.0f / (*(float *)&vpnode[0x21]); // spotlight start
|
||||
vp->spotRange[1] = *(float *)&vpnode[0x1F]; // spotlight extent
|
||||
vp->spotRange[0] = 1.0f / uint_as_float(vpnode[0x21]); // spotlight start
|
||||
vp->spotRange[1] = uint_as_float(vpnode[0x1F]); // spotlight extent
|
||||
|
||||
vp->spotColor[0] = color[spotColorIdx][0]; // spotlight color
|
||||
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]);
|
||||
|
||||
// Scale the spotlight to the OpenGL viewport
|
||||
vp->spotEllipse[0] = vp->spotEllipse[0] * m_xRatio + m_xOffs;
|
||||
vp->spotEllipse[1] = vp->spotEllipse[1] * m_yRatio + m_yOffs;
|
||||
vp->spotEllipse[0] = vp->spotEllipse[0] * m_xRatio + (float)m_xOffs;
|
||||
vp->spotEllipse[1] = vp->spotEllipse[1] * m_yRatio + (float)m_yOffs;
|
||||
vp->spotEllipse[2] *= m_xRatio;
|
||||
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
|
||||
|
||||
// Fog
|
||||
vp->fogParams[0] = (float)((vpnode[0x22] >> 16) & 0xFF) * (1.0f / 255.0f); // fog color R
|
||||
vp->fogParams[1] = (float)((vpnode[0x22] >> 8) & 0xFF) * (1.0f / 255.0f); // fog color G
|
||||
vp->fogParams[2] = (float)((vpnode[0x22] >> 0) & 0xFF) * (1.0f / 255.0f); // fog color B
|
||||
vp->fogParams[3] = std::abs(*(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[0] = (float)((vpnode[0x22] >> 16) & 0xFF) * (float)(1.0 / 255.0); // fog color R
|
||||
vp->fogParams[1] = (float)((vpnode[0x22] >> 8) & 0xFF) * (float)(1.0 / 255.0); // fog color G
|
||||
vp->fogParams[2] = (float)((vpnode[0x22] >> 0) & 0xFF) * (float)(1.0 / 255.0); // fog color B
|
||||
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)* (float)(1.0 / 255.0); // fog start
|
||||
|
||||
// Avoid Infinite and NaN values for Star Wars Trilogy
|
||||
if (std::isinf(vp->fogParams[3]) || std::isnan(vp->fogParams[3])) {
|
||||
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[6] = (float)((vpnode[0x25] >> 16) & 0xFF) * (1.0f / 255.0f); // fog ambient
|
||||
vp->fogParams[5] = (float)((vpnode[0x24] >> 16) & 0xFF) * (float)(1.0 / 255.0); // fog attenuation
|
||||
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->scrollAtt = (float)(vpnode[0x24] & 0xFF) * (1.0f / 255.0f); // scroll attenuation
|
||||
vp->scrollFog = (float)(vpnode[0x20] & 0xFF) * (float)(1.0 / 255.0); // scroll fog
|
||||
vp->scrollAtt = (float)(vpnode[0x24] & 0xFF) * (float)(1.0 / 255.0); // scroll attenuation
|
||||
|
||||
// Clear texture offsets before proceeding
|
||||
m_nodeAttribs.Reset();
|
||||
|
@ -947,7 +944,7 @@ void CNew3D::RenderViewport(UINT32 addr)
|
|||
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
|
||||
// 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
|
||||
if (r3dPoly.faceColour[3] == 0) {
|
||||
return;
|
||||
|
@ -1058,7 +1055,7 @@ void CNew3D::SetMeshValues(SortingMesh *currentMesh, PolyHeader &ph)
|
|||
|
||||
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->microTextureScale = microTexScale[ph.MicroTextureMinLOD()];
|
||||
|
@ -1073,7 +1070,7 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
|||
UINT64 lastHash = -1;
|
||||
SortingMesh* currentMesh = nullptr;
|
||||
|
||||
std::map<UINT64, SortingMesh> sMap;
|
||||
std::unordered_map<UINT64, SortingMesh> sMap;
|
||||
|
||||
if (data == NULL)
|
||||
return;
|
||||
|
@ -1086,7 +1083,6 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
|||
|
||||
R3DPoly p; // current polygon
|
||||
float uvScale;
|
||||
int i, j;
|
||||
|
||||
if (ph.header[6] == 0) {
|
||||
break;
|
||||
|
@ -1099,9 +1095,7 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
|||
|
||||
if (sMap.count(hash) == 0) {
|
||||
|
||||
sMap[hash] = SortingMesh();
|
||||
|
||||
currentMesh = &sMap[hash];
|
||||
currentMesh = &sMap.insert({hash, SortingMesh()}).first->second;
|
||||
|
||||
//make space for our vertices
|
||||
currentMesh->verts.reserve(numTriangles * 3);
|
||||
|
@ -1109,8 +1103,8 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
|||
//set mesh values
|
||||
SetMeshValues(currentMesh, ph);
|
||||
}
|
||||
|
||||
currentMesh = &sMap[hash];
|
||||
else
|
||||
currentMesh = &sMap[hash];
|
||||
}
|
||||
|
||||
// Obtain basic polygon parameters
|
||||
|
@ -1120,9 +1114,8 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
|||
ph.FaceNormal(p.faceNormal);
|
||||
|
||||
// Fetch reused vertices according to bitfield, then new verts
|
||||
i = 0;
|
||||
j = 0;
|
||||
for (i = 0; i < 4; i++) // up to 4 reused vertices
|
||||
int j = 0;
|
||||
for (int i = 0; i < 4; i++) // up to 4 reused vertices
|
||||
{
|
||||
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
|
||||
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[1] = p.faceNormal[1];
|
||||
p.v[i].normal[2] = p.faceNormal[2];
|
||||
|
@ -1202,7 +1195,7 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
|||
//==========
|
||||
|
||||
if (!m_shadeIsSigned) {
|
||||
shade = (ix & 0xFF) / 255.f;
|
||||
shade = (ix & 0xFF) * (float)(1.0 / 255.0);
|
||||
}
|
||||
else {
|
||||
shade = BYTE_TO_FLOAT((INT8)(ix & 0xFF));
|
||||
|
@ -1237,8 +1230,8 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
|||
// flip normals
|
||||
V3::inverse(tempP.faceNormal);
|
||||
|
||||
for (int i = 0; i < tempP.number; i++) {
|
||||
V3::inverse(tempP.v[i].normal);
|
||||
for (int i2 = 0; i2 < tempP.number; i2++) {
|
||||
V3::inverse(tempP.v[i2].normal);
|
||||
}
|
||||
|
||||
CopyVertexData(tempP, currentMesh->verts);
|
||||
|
@ -1250,7 +1243,7 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
|||
}
|
||||
|
||||
// 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_prevTexCoords[i][0] = texCoords[i][0];
|
||||
m_prevTexCoords[i][1] = texCoords[i][1];
|
||||
|
@ -1365,10 +1358,10 @@ void CNew3D::CalcFrustumPlanes(Plane p[5], const float* matrix)
|
|||
p[3].Normalise();
|
||||
|
||||
// Front Plane
|
||||
p[4].a = 0;
|
||||
p[4].b = 0;
|
||||
p[4].c = -1;
|
||||
p[4].d =0;
|
||||
p[4].a = 0.f;
|
||||
p[4].b = 0.f;
|
||||
p[4].c = -1.f;
|
||||
p[4].d = 0.f;
|
||||
}
|
||||
|
||||
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][1] = -distance;
|
||||
box.points[0][2] = distance;
|
||||
box.points[0][3] = 1;
|
||||
box.points[0][3] = 1.f;
|
||||
|
||||
//bottom left back
|
||||
box.points[1][0] = -distance;
|
||||
box.points[1][1] = -distance;
|
||||
box.points[1][2] = -distance;
|
||||
box.points[1][3] = 1;
|
||||
box.points[1][3] = 1.f;
|
||||
|
||||
//bottom right back
|
||||
box.points[2][0] = distance;
|
||||
box.points[2][1] = -distance;
|
||||
box.points[2][2] = -distance;
|
||||
box.points[2][3] = 1;
|
||||
box.points[2][3] = 1.f;
|
||||
|
||||
//bottom right front
|
||||
box.points[3][0] = distance;
|
||||
box.points[3][1] = -distance;
|
||||
box.points[3][2] = distance;
|
||||
box.points[3][3] = 1;
|
||||
box.points[3][3] = 1.f;
|
||||
|
||||
//top left front
|
||||
box.points[4][0] = -distance;
|
||||
box.points[4][1] = distance;
|
||||
box.points[4][2] = distance;
|
||||
box.points[4][3] = 1;
|
||||
box.points[4][3] = 1.f;
|
||||
|
||||
//top left back
|
||||
box.points[5][0] = -distance;
|
||||
box.points[5][1] = distance;
|
||||
box.points[5][2] = -distance;
|
||||
box.points[5][3] = 1;
|
||||
box.points[5][3] = 1.f;
|
||||
|
||||
//top right back
|
||||
box.points[6][0] = distance;
|
||||
box.points[6][1] = distance;
|
||||
box.points[6][2] = -distance;
|
||||
box.points[6][3] = 1;
|
||||
box.points[6][3] = 1.f;
|
||||
|
||||
//top right front
|
||||
box.points[7][0] = distance;
|
||||
box.points[7][1] = 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])
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1453,7 +1446,7 @@ Clip CNew3D::ClipBox(BBox& box, Plane planes[5])
|
|||
int temp = 0;
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
@ -1472,7 +1465,7 @@ Clip CNew3D::ClipBox(BBox& box, Plane planes[5])
|
|||
int temp = 0;
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
@ -1490,7 +1483,7 @@ Clip CNew3D::ClipBox(BBox& box, Plane planes[5])
|
|||
void CNew3D::CalcBoxExtents(const BBox& box)
|
||||
{
|
||||
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].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 nextIn;
|
||||
float currentDot;
|
||||
float nextDot;
|
||||
//=================
|
||||
|
||||
currentDot = planes[i].DotProduct(in->list[0].pos);
|
||||
currentIn = (currentDot + planes[i].d) >= 0;
|
||||
currentIn = (currentDot + planes[i].d) >= 0.f;
|
||||
out->count = 0;
|
||||
|
||||
for (int j = 0; j < in->count; j++) {
|
||||
|
@ -1533,16 +1524,16 @@ void CNew3D::ClipPolygon(ClipPoly& clipPoly, Plane planes[5])
|
|||
nextIndex = 0;
|
||||
}
|
||||
|
||||
nextDot = planes[i].DotProduct(in->list[nextIndex].pos);
|
||||
nextIn = (nextDot + planes[i].d) >= 0;
|
||||
float nextDot = planes[i].DotProduct(in->list[nextIndex].pos);
|
||||
bool nextIn = (nextDot + planes[i].d) >= 0.f;
|
||||
|
||||
// we have an intersection
|
||||
if (currentIn != nextIn) {
|
||||
|
||||
float u = (currentDot + planes[i].d) / (currentDot - nextDot);
|
||||
|
||||
float* p1 = in->list[j].pos;
|
||||
float* p2 = in->list[nextIndex].pos;
|
||||
const float* p1 = in->list[j].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[1] = p1[1] + ((p2[1] - p1[1]) * u);
|
||||
|
@ -1590,7 +1581,7 @@ void CNew3D::ClipModel(const Model *m)
|
|||
ClipPolygon(clipPoly, m_planes);
|
||||
|
||||
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].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)
|
||||
{
|
||||
if (far > 1e30) {
|
||||
far = near * 1000000; // fix for ocean hunter which passes some FLT_MAX for a few matrices. HW must have some safe guard for these
|
||||
if (far > 1e30f) {
|
||||
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) {
|
||||
near = far / 1000000; // if we get really close to zero somehow, we will have almost no depth precision
|
||||
if (near < far / 1000000.f) {
|
||||
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
|
||||
|
@ -1646,18 +1637,18 @@ void CNew3D::CalcViewport(Viewport* vp, float near, float far)
|
|||
float correction = windowAR / viewableAreaAR;
|
||||
|
||||
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->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);
|
||||
}
|
||||
else {
|
||||
|
||||
vp->x = m_xOffs + (int)(vp->vpX*m_xRatio);
|
||||
vp->y = m_yOffs + (int)((384 - (vp->vpY + vp->vpHeight))*m_yRatio);
|
||||
vp->width = (int)(vp->vpWidth*m_xRatio);
|
||||
vp->height = (int)(vp->vpHeight*m_yRatio);
|
||||
vp->x = m_xOffs + (int)((float)vp->vpX*m_xRatio);
|
||||
vp->y = m_yOffs + (int)((float)(384 - (vp->vpY + vp->vpHeight))*m_yRatio);
|
||||
vp->width = (int)((float)vp->vpWidth*m_xRatio);
|
||||
vp->height = (int)((float)vp->vpHeight*m_yRatio);
|
||||
|
||||
vp->projectionMatrix.Frustum(l, r, b, t, near, far);
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ public:
|
|||
* Parameters:
|
||||
* 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);
|
||||
|
||||
private:
|
||||
|
@ -305,7 +305,7 @@ private:
|
|||
void CalcBox (float distance, BBox& box);
|
||||
void TransformBox (const float *m, BBox& box);
|
||||
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 ClipPolygon (ClipPoly& clipPoly, Plane planes[5]);
|
||||
void CalcBoxExtents (const BBox& box);
|
||||
|
|
|
@ -8,11 +8,11 @@ struct Plane
|
|||
float a, b, c, d;
|
||||
|
||||
void Normalise() {
|
||||
float temp = std::sqrt((a * a) + (b * b) + (c * c));
|
||||
a /= temp;
|
||||
b /= temp;
|
||||
c /= temp;
|
||||
d /= temp;
|
||||
float temp = 1.f/std::sqrt((a * a) + (b * b) + (c * c));
|
||||
a *= temp;
|
||||
b *= temp;
|
||||
c *= temp;
|
||||
d *= temp;
|
||||
}
|
||||
|
||||
float DistanceToPoint(const float v[3]) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "Types.h"
|
||||
#include "R3DFloat.h"
|
||||
#include "Util\GenericValue.h"
|
||||
|
||||
float R3DFloat::GetFloat16(UINT16 f)
|
||||
{
|
||||
|
@ -13,17 +14,16 @@ float R3DFloat::GetFloat32(UINT32 f)
|
|||
|
||||
UINT32 R3DFloat::ConvertProFloat(UINT32 a1)
|
||||
{
|
||||
int exponent = (a1 & 0x7E000000) >> 25;
|
||||
UINT32 exponent = (a1 & 0x7E000000) >> 25;
|
||||
|
||||
if (exponent <= 31) { // positive
|
||||
exponent += 127;
|
||||
}
|
||||
else { // negative exponent
|
||||
exponent -= 64;
|
||||
exponent += 127;
|
||||
exponent += 127 - 64;
|
||||
}
|
||||
|
||||
int mantissa = (a1 & 0x1FFFFFF) >> 2;
|
||||
UINT32 mantissa = (a1 & 0x1FFFFFF) >> 2;
|
||||
|
||||
return (a1 & 0x80000000) | (exponent << 23) | mantissa;
|
||||
}
|
||||
|
@ -35,5 +35,5 @@ UINT32 R3DFloat::Convert16BitProFloat(UINT32 a1)
|
|||
|
||||
float R3DFloat::ToFloat(UINT32 a1)
|
||||
{
|
||||
return *(float*)(&a1);
|
||||
return uint_as_float(a1);
|
||||
}
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
namespace R3DFloat
|
||||
{
|
||||
static const UINT16 Pro16BitMax = 0x7fff;
|
||||
static const float Pro16BitFltMin = 1e-7f; // float min in IEEE
|
||||
constexpr UINT16 Pro16BitMax = 0x7fff;
|
||||
constexpr float Pro16BitFltMin = 1e-7f; // float min in IEEE
|
||||
|
||||
float GetFloat16(UINT16 f);
|
||||
float GetFloat32(UINT32 f);
|
||||
|
|
|
@ -37,7 +37,7 @@ private:
|
|||
texCoords[1] = t;
|
||||
verts[0] = x;
|
||||
verts[1] = y;
|
||||
verts[2] = 0; // z = 0
|
||||
verts[2] = 0.f; // z = 0
|
||||
}
|
||||
|
||||
float texCoords[2];
|
||||
|
|
|
@ -602,7 +602,7 @@ void SCSP_StopSlot(_SLOT *slot,int keyoff)
|
|||
//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)
|
||||
{
|
||||
|
@ -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));
|
||||
//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]=(i>>(10-SHIFT))|(1<<SHIFT);
|
||||
|
||||
|
@ -655,7 +655,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
|||
#ifdef RB_VOLUME
|
||||
// Volume table, 1 = -0.375dB, 8 = -3dB, 256 = -96dB
|
||||
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++)
|
||||
volume[i] = 0;
|
||||
|
||||
|
|
|
@ -42,10 +42,10 @@ struct _LFO
|
|||
#define LFIX(v) ((unsigned int) ((float) (1<<LFO_SHIFT)*(v)))
|
||||
|
||||
//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
|
||||
#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 ALFO_TRI[256], ALFO_SQR[256], ALFO_SAW[256], ALFO_NOI[256];
|
||||
|
@ -115,12 +115,12 @@ void LFO_Init(void)
|
|||
float limit = PSCALE[s];
|
||||
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];
|
||||
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 <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 detail
|
||||
|
|
Loading…
Reference in a new issue