mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-29 00:55:41 +00:00
address review and move bit casts to new header
This commit is contained in:
parent
1b0e3be8dc
commit
519d695f57
|
@ -161,6 +161,7 @@
|
||||||
#include "Supermodel.h"
|
#include "Supermodel.h"
|
||||||
#include "Shaders3D.h" // fragment and vertex shaders
|
#include "Shaders3D.h" // fragment and vertex shaders
|
||||||
#include "Graphics/Shader.h"
|
#include "Graphics/Shader.h"
|
||||||
|
#include "Util/BitCast.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
@ -851,8 +852,8 @@ 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 = asinf(uint_as_float(vpnode[0x0E])); // FOV Y upper half-angle (radians)
|
GLfloat vpTopAngle = asinf(Util::UintAsFloat(vpnode[0x0E])); // FOV Y upper half-angle (radians)
|
||||||
GLfloat vpBotAngle = asinf(uint_as_float(vpnode[0x12])); // FOV Y lower half-angle
|
GLfloat vpBotAngle = asinf(Util::UintAsFloat(vpnode[0x12])); // FOV Y lower half-angle
|
||||||
GLfloat fovYDegrees = (vpTopAngle+vpBotAngle)*(float)(180.0/M_PI);
|
GLfloat fovYDegrees = (vpTopAngle+vpBotAngle)*(float)(180.0/M_PI);
|
||||||
// TO-DO: investigate clipping planes
|
// TO-DO: investigate clipping planes
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "R3DFloat.h"
|
#include "R3DFloat.h"
|
||||||
|
#include "Util/BitCast.h"
|
||||||
|
|
||||||
#define MAX_RAM_VERTS 300000
|
#define MAX_RAM_VERTS 300000
|
||||||
#define MAX_ROM_VERTS 1500000
|
#define MAX_ROM_VERTS 1500000
|
||||||
|
@ -553,7 +554,7 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
||||||
|
|
||||||
if (!m_offset) { // Step 1.5+
|
if (!m_offset) { // Step 1.5+
|
||||||
|
|
||||||
float modelScale = uint_as_float(node[1]);
|
float modelScale = Util::UintAsFloat(node[1]);
|
||||||
if (modelScale > std::numeric_limits<float>::min()) {
|
if (modelScale > std::numeric_limits<float>::min()) {
|
||||||
m_nodeAttribs.currentModelScale = modelScale;
|
m_nodeAttribs.currentModelScale = modelScale;
|
||||||
}
|
}
|
||||||
|
@ -573,9 +574,9 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
||||||
|
|
||||||
// apply translation vector
|
// apply translation vector
|
||||||
if (node[0x00] & 0x10) {
|
if (node[0x00] & 0x10) {
|
||||||
float x = uint_as_float(node[0x04 - m_offset]);
|
float x = Util::UintAsFloat(node[0x04 - m_offset]);
|
||||||
float y = uint_as_float(node[0x05 - m_offset]);
|
float y = Util::UintAsFloat(node[0x05 - m_offset]);
|
||||||
float z = uint_as_float(node[0x06 - m_offset]);
|
float z = Util::UintAsFloat(node[0x06 - m_offset]);
|
||||||
m_modelMat.Translate(x, y, z);
|
m_modelMat.Translate(x, y, z);
|
||||||
}
|
}
|
||||||
// multiply matrix, if specified
|
// multiply matrix, if specified
|
||||||
|
@ -831,16 +832,16 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
m_LODBlendTable = (LODBlendTable*)TranslateCullingAddress(vpnode[0x17] & 0xFFFFFF);
|
m_LODBlendTable = (LODBlendTable*)TranslateCullingAddress(vpnode[0x17] & 0xFFFFFF);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vp->angle_left = -atan2(*(float *)&vpnode[12], *(float *)&vpnode[13]); // These values work out as the normals for the clipping planes.
|
vp->angle_left = -atan2f(Util::UintAsFloat(vpnode[12]), Util::UintAsFloat(vpnode[13])); // These values work out as the normals for the clipping planes.
|
||||||
vp->angle_right = atan2(*(float *)&vpnode[16], -*(float *)&vpnode[17]); // Sometimes these values (dirt devils,lost world) are totally wrong
|
vp->angle_right = atan2f(Util::UintAsFloat(vpnode[16]), -Util::UintAsFloat(vpnode[17])); // Sometimes these values (dirt devils,lost world) are totally wrong
|
||||||
vp->angle_top = atan2(*(float *)&vpnode[14], *(float *)&vpnode[15]); // and don't work for the frustum values exactly.
|
vp->angle_top = atan2f(Util::UintAsFloat(vpnode[14]), Util::UintAsFloat(vpnode[15])); // and don't work for the frustum values exactly.
|
||||||
vp->angle_bottom = -atan2(*(float *)&vpnode[18], -*(float *)&vpnode[19]); // Perhaps they are just used for culling and not rendering.
|
vp->angle_bottom = -atan2f(Util::UintAsFloat(vpnode[18]), -Util::UintAsFloat(vpnode[19])); // Perhaps they are just used for culling and not rendering.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float cv = uint_as_float(vpnode[0x8]); // 1/(left-right)
|
float cv = Util::UintAsFloat(vpnode[0x8]); // 1/(left-right)
|
||||||
float cw = uint_as_float(vpnode[0x9]); // 1/(top-bottom)
|
float cw = Util::UintAsFloat(vpnode[0x9]); // 1/(top-bottom)
|
||||||
float io = uint_as_float(vpnode[0xa]); // top / bottom (ratio) - ish
|
float io = Util::UintAsFloat(vpnode[0xa]); // top / bottom (ratio) - ish
|
||||||
float jo = uint_as_float(vpnode[0xb]); // left / right (ratio)
|
float jo = Util::UintAsFloat(vpnode[0xb]); // left / right (ratio)
|
||||||
|
|
||||||
vp->angle_left = (0.0f - jo) / cv;
|
vp->angle_left = (0.0f - jo) / cv;
|
||||||
vp->angle_right = (1.0f - jo) / cv;
|
vp->angle_right = (1.0f - jo) / cv;
|
||||||
|
@ -854,10 +855,10 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
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] = uint_as_float(vpnode[0x05]); // sun X
|
vp->lightingParams[0] = Util::UintAsFloat(vpnode[0x05]); // sun X
|
||||||
vp->lightingParams[1] = -uint_as_float(vpnode[0x06]); // sun Y (- to convert to ogl cordinate system)
|
vp->lightingParams[1] = -Util::UintAsFloat(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[2] = -Util::UintAsFloat(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[3] = std::max(0.f, std::min(Util::UintAsFloat(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[4] = (float)((vpnode[0x24] >> 8) & 0xFF) * (float)(1.0 / 255.0); // ambient intensity
|
||||||
vp->lightingParams[5] = 0.0f; // reserved
|
vp->lightingParams[5] = 0.0f; // reserved
|
||||||
|
|
||||||
|
@ -868,13 +869,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) * (float)(1.0 / 8.0); // 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) * (float)(1.0 / 8.0); // 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 / uint_as_float(vpnode[0x21]); // spotlight start
|
vp->spotRange[0] = 1.0f / Util::UintAsFloat(vpnode[0x21]); // spotlight start
|
||||||
vp->spotRange[1] = uint_as_float(vpnode[0x1F]); // spotlight extent
|
vp->spotRange[1] = Util::UintAsFloat(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];
|
||||||
|
@ -908,7 +909,7 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
vp->fogParams[0] = (float)((vpnode[0x22] >> 16) & 0xFF) * (float)(1.0 / 255.0); // 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) * (float)(1.0 / 255.0); // 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) * (float)(1.0 / 255.0); // fog color B
|
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[3] = std::abs(Util::UintAsFloat(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
|
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
|
||||||
|
@ -1065,6 +1066,9 @@ void CNew3D::SetMeshValues(SortingMesh *currentMesh, PolyHeader &ph)
|
||||||
|
|
||||||
void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
{
|
{
|
||||||
|
if (data == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
UINT16 texCoords[4][2];
|
UINT16 texCoords[4][2];
|
||||||
PolyHeader ph;
|
PolyHeader ph;
|
||||||
UINT64 lastHash = -1;
|
UINT64 lastHash = -1;
|
||||||
|
@ -1072,9 +1076,6 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
|
|
||||||
std::unordered_map<UINT64, SortingMesh> sMap;
|
std::unordered_map<UINT64, SortingMesh> sMap;
|
||||||
|
|
||||||
if (data == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ph = data;
|
ph = data;
|
||||||
int numTriangles = ph.NumTrianglesTotal();
|
int numTriangles = ph.NumTrianglesTotal();
|
||||||
|
|
||||||
|
@ -1253,7 +1254,7 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
|
|
||||||
//sorted the data, now copy to main data structures
|
//sorted the data, now copy to main data structures
|
||||||
|
|
||||||
// we know how many meshes we have so reserve appropriate space
|
// we know how many meshes we have to reserve appropriate space
|
||||||
m->meshes->reserve(sMap.size());
|
m->meshes->reserve(sMap.size());
|
||||||
|
|
||||||
for (auto& it : sMap) {
|
for (auto& it : sMap) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
#include "R3DFloat.h"
|
#include "R3DFloat.h"
|
||||||
#include "Util/GenericValue.h"
|
#include "Util/BitCast.h"
|
||||||
|
|
||||||
float R3DFloat::GetFloat16(UINT16 f)
|
float R3DFloat::GetFloat16(UINT16 f)
|
||||||
{
|
{
|
||||||
|
@ -35,5 +35,5 @@ UINT32 R3DFloat::Convert16BitProFloat(UINT32 a1)
|
||||||
|
|
||||||
float R3DFloat::ToFloat(UINT32 a1)
|
float R3DFloat::ToFloat(UINT32 a1)
|
||||||
{
|
{
|
||||||
return uint_as_float(a1);
|
return Util::UintAsFloat(a1);
|
||||||
}
|
}
|
||||||
|
|
61
Src/Util/BitCast.h
Normal file
61
Src/Util/BitCast.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef INCLUDED_UTIL_BITCAST_H
|
||||||
|
#define INCLUDED_UTIL_BITCAST_H
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace Util
|
||||||
|
{
|
||||||
|
#if __cplusplus >= 202002L
|
||||||
|
#include <bit>
|
||||||
|
#define FloatAsInt(x) std::bit_cast<int>(x)
|
||||||
|
#define IntAsFloat(x) std::bit_cast<float>(x)
|
||||||
|
#define UintAsFloat(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 FloatAsInt(x) bit_cast<int,float>(x)
|
||||||
|
#define IntAsFloat(x) bit_cast<float,int>(x)
|
||||||
|
#define UintAsFloat(x) bit_cast<float,unsigned int>(x)
|
||||||
|
#else
|
||||||
|
inline int FloatAsInt(const float x)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
float f;
|
||||||
|
int i;
|
||||||
|
} uc;
|
||||||
|
uc.f = x;
|
||||||
|
return uc.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float IntAsFloat(const int i)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
int i;
|
||||||
|
float f;
|
||||||
|
} iaf;
|
||||||
|
iaf.i = i;
|
||||||
|
return iaf.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float UintAsFloat(const unsigned int i)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
unsigned int u;
|
||||||
|
float f;
|
||||||
|
} iaf;
|
||||||
|
iaf.u = i;
|
||||||
|
return iaf.f;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} // Util
|
||||||
|
|
||||||
|
#endif // INCLUDED_UTIL_BITCAST_H
|
|
@ -20,57 +20,6 @@
|
||||||
#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
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
@ -545,6 +545,7 @@ xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"</Command>
|
||||||
<ClInclude Include="..\Src\Sound\SCSP.h" />
|
<ClInclude Include="..\Src\Sound\SCSP.h" />
|
||||||
<ClInclude Include="..\Src\Sound\SCSPDSP.h" />
|
<ClInclude Include="..\Src\Sound\SCSPDSP.h" />
|
||||||
<ClInclude Include="..\Src\Supermodel.h" />
|
<ClInclude Include="..\Src\Supermodel.h" />
|
||||||
|
<ClInclude Include="..\Src\Util\BitCast.h" />
|
||||||
<ClInclude Include="..\Src\Util\BitRegister.h" />
|
<ClInclude Include="..\Src\Util\BitRegister.h" />
|
||||||
<ClInclude Include="..\Src\Util\BMPFile.h" />
|
<ClInclude Include="..\Src\Util\BMPFile.h" />
|
||||||
<ClInclude Include="..\Src\Util\ByteSwap.h" />
|
<ClInclude Include="..\Src\Util\ByteSwap.h" />
|
||||||
|
|
|
@ -847,6 +847,9 @@
|
||||||
<ClInclude Include="..\Src\Graphics\New3D\Vec.h">
|
<ClInclude Include="..\Src\Graphics\New3D\Vec.h">
|
||||||
<Filter>Header Files\Graphics\New</Filter>
|
<Filter>Header Files\Graphics\New</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Src\Util\BitCast.h">
|
||||||
|
<Filter>Header Files\Util</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="..\Src\Debugger\ReadMe.txt">
|
<CustomBuild Include="..\Src\Debugger\ReadMe.txt">
|
||||||
|
|
Loading…
Reference in a new issue