Fixed compiler warnings, whitespace, and moved local variable declarations to site of assignment

This commit is contained in:
Bart Trzynadlowski 2016-03-22 03:43:31 +00:00
parent ec7588e2cd
commit 3627213577
4 changed files with 1815 additions and 1913 deletions

View file

@ -146,9 +146,11 @@
* - Can some of the floating point flag attribs be replaced with ints?
*/
#include <cmath>
#include "Supermodel.h"
#include "Graphics/Legacy3D/Shaders3D.h" // fragment and vertex shaders
#include <algorithm>
#include <cmath>
#include <cstdint>
namespace Legacy3D {
@ -178,16 +180,14 @@ namespace Legacy3D {
#define NUM_DYNAMIC_MODELS 1024 // maximum number of unique dynamic models to cache
#define NUM_DISPLAY_LIST_ITEMS 10000 // maximum number of model instances displayed per frame
// Scene traversal stack
#define STACK_SIZE 1024
/******************************************************************************
Texture Management
******************************************************************************/
// Default mapping from Model3 texture format to texture sheet.
// Currently this is just a simple 1-to-1 mapping but if/when more formats get added, sheets will start to get reused.
// Currently this is just a simple 1-to-1 mapping but if/when more formats get
// added, sheets will start to get reused.
int CLegacy3D::defaultFmtToTexSheetNum[] = {
0, // Fmt 0 -> 0
1, // 1 -> 1
@ -197,14 +197,10 @@ int CLegacy3D::defaultFmtToTexSheetNum[] = {
5, // 5 -> 5
6, // 6 -> 6
7 // 7 -> 7
};
};
void CLegacy3D::DecodeTexture(int format, int x, int y, int width, int height)
{
int xi, yi, i;
UINT16 texel;
GLfloat c, a;
x &= 2047;
y &= 2047;
@ -226,14 +222,13 @@ void CLegacy3D::DecodeTexture(int format, int x, int y, int width, int height)
//printf("Decoding texture format %u: %u x %u @ (%u, %u) sheet %u\n", format, width, height, x, y, texNum);
// Copy and decode
i = 0;
int i = 0;
switch (format)
{
default: // Unknown
for (yi = y; yi < (y+height); yi++)
for (int yi = y; yi < (y+height); yi++)
{
for (xi = x; xi < (x+width); xi++)
for (int xi = x; xi < (x+width); xi++)
{
textureBuffer[i++] = 0.0; // R
textureBuffer[i++] = 0.0; // G
@ -242,11 +237,10 @@ void CLegacy3D::DecodeTexture(int format, int x, int y, int width, int height)
}
}
break;
case 0: // T1RGB5
for (yi = y; yi < (y+height); yi++)
for (int yi = y; yi < (y+height); yi++)
{
for (xi = x; xi < (x+width); xi++)
for (int xi = x; xi < (x+width); xi++)
{
textureBuffer[i++] = (GLfloat) ((textureRAM[yi*2048+xi]>>10)&0x1F) * (1.0f/31.0f); // R
textureBuffer[i++] = (GLfloat) ((textureRAM[yi*2048+xi]>>5)&0x1F) * (1.0f/31.0f); // G
@ -255,11 +249,10 @@ void CLegacy3D::DecodeTexture(int format, int x, int y, int width, int height)
}
}
break;
case 7: // RGBA4
for (yi = y; yi < (y+height); yi++)
for (int yi = y; yi < (y+height); yi++)
{
for (xi = x; xi < (x+width); xi++)
for (int xi = x; xi < (x+width); xi++)
{
textureBuffer[i++] = (GLfloat) ((textureRAM[yi*2048+xi]>>12)&0xF) * (1.0f/15.0f); // R
textureBuffer[i++] = (GLfloat) ((textureRAM[yi*2048+xi]>>8)&0xF) * (1.0f/15.0f); // G
@ -268,14 +261,13 @@ void CLegacy3D::DecodeTexture(int format, int x, int y, int width, int height)
}
}
break;
case 5: // 8-bit grayscale
for (yi = y; yi < (y+height); yi++)
for (int yi = y; yi < (y+height); yi++)
{
for (xi = x; xi < (x+width); xi++)
for (int xi = x; xi < (x+width); xi++)
{
/*
texel = textureRAM[yi*2048+xi];
UINT16 texel = textureRAM[yi*2048+xi];
c = (GLfloat) (texel&0xFF) * (1.0f/255.0f);
textureBuffer[i++] = c;
textureBuffer[i++] = c;
@ -283,79 +275,71 @@ void CLegacy3D::DecodeTexture(int format, int x, int y, int width, int height)
textureBuffer[i++] = 1.0;
*/
// Interpret as 8-bit grayscale
texel = textureRAM[yi*2048+xi];
c = (GLfloat) texel * (1.0f/255.0f);
UINT16 texel = textureRAM[yi*2048+xi];
GLfloat c = texel * (1.0f/255.0f);
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = 1.0f;
}
}
break;
case 4: // 8-bit, L4A4
for (yi = y; yi < (y+height); yi++)
for (int yi = y; yi < (y+height); yi++)
{
for (xi = x; xi < (x+width); xi++)
for (int xi = x; xi < (x+width); xi++)
{
texel = textureRAM[yi*2048+xi];
//c = (GLfloat) (~texel&0x0F) * (1.0f/15.0f);
//a = (GLfloat) ((texel>>4)&0xF) * (1.0f/15.0f);
c = (GLfloat) ((texel>>4)&0xF) * (1.0f/15.0f); // seems to work better in Lost World (raptor shadows)
a = (GLfloat) (texel&0xF) * (1.0f/15.0f);
UINT16 texel = textureRAM[yi*2048+xi];
//GLfloat c = (~texel&0x0F) * (1.0f/15.0f);
//GLfloat a = ((texel>>4)&0xF) * (1.0f/15.0f);
GLfloat c = ((texel>>4)&0xF) * (1.0f/15.0f); // seems to work better in Lost World (raptor shadows)
GLfloat a = (texel&0xF) * (1.0f/15.0f);
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = a;
}
}
break;
case 6: // 8-bit grayscale? (How does this differ from format 5? Alpha values?)
for (yi = y; yi < (y+height); yi++)
for (int yi = y; yi < (y+height); yi++)
{
for (xi = x; xi < (x+width); xi++)
for (int xi = x; xi < (x+width); xi++)
{
/*
texel = textureRAM[yi*2048+xi];
c = (GLfloat) ((texel>>4)&0xF) * (1.0f/15.0f);
a = (GLfloat) (texel&0xF) * (1.0f/15.0f);
UINT16 texel = textureRAM[yi*2048+xi];
GLfloat c = ((texel>>4)&0xF) * (1.0f/15.0f);
GLfloat a = (texel&0xF) * (1.0f/15.0f);
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = a;
*/
texel = textureRAM[yi*2048+xi]&0xFF;
c = (GLfloat) texel * (1.0f/255.0f);
UINT16 texel = textureRAM[yi*2048+xi]&0xFF;
GLfloat c = texel * (1.0f/255.0f);
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = 1.0f;
}
}
break;
case 2: // Unknown (all 16 bits appear present in Daytona 2, but only lower 8 bits in Le Mans 24)
for (yi = y; yi < (y+height); yi++)
for (int yi = y; yi < (y+height); yi++)
{
for (xi = x; xi < (x+width); xi++)
for (int xi = x; xi < (x+width); xi++)
{
texel = textureRAM[yi*2048+xi];
a = (GLfloat) ((texel>>4)&0xF) * (1.0f/15.0f);
c = (GLfloat) (texel&0xF) * (1.0f/15.0f);
UINT16 texel = textureRAM[yi*2048+xi];
GLfloat a = ((texel>>4)&0xF) * (1.0f/15.0f);
GLfloat c = (texel&0xF) * (1.0f/15.0f);
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = a;
//printf("%04X\n", textureRAM[yi*2048+xi]);
/*
texel = textureRAM[yi*2048+xi]&0xFF;
c = (GLfloat) texel * (1.0f/255.0f);
UINT16 texel = textureRAM[yi*2048+xi]&0xFF;
GLfloat c = texel * (1.0f/255.0f);
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = c;
@ -364,15 +348,14 @@ void CLegacy3D::DecodeTexture(int format, int x, int y, int width, int height)
}
}
break;
case 3: // Interleaved A4L4 (high byte)
for (yi = y; yi < (y+height); yi++)
for (int yi = y; yi < (y+height); yi++)
{
for (xi = x; xi < (x+width); xi++)
for (int xi = x; xi < (x+width); xi++)
{
texel = textureRAM[yi*2048+xi]>>8;
c = (GLfloat) (texel&0xF) * (1.0f/15.0f);
a = (GLfloat) (texel>>4) * (1.0f/15.0f);
UINT16 texel = textureRAM[yi*2048+xi]>>8;
GLfloat c = (texel&0xF) * (1.0f/15.0f);
GLfloat a = (texel>>4) * (1.0f/15.0f);
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = c;
@ -380,16 +363,15 @@ void CLegacy3D::DecodeTexture(int format, int x, int y, int width, int height)
}
}
break;
case 1: // Interleaved A4L4 (low byte)
for (yi = y; yi < (y+height); yi++)
for (int yi = y; yi < (y+height); yi++)
{
for (xi = x; xi < (x+width); xi++)
for (int xi = x; xi < (x+width); xi++)
{
// Interpret as A4L4
texel = textureRAM[yi*2048+xi]&0xFF;
c = (GLfloat) (texel&0xF) * (1.0f/15.0f);
a = (GLfloat) (texel>>4) * (1.0f/15.0f);
UINT16 texel = textureRAM[yi*2048+xi]&0xFF;
GLfloat c = (texel&0xF) * (1.0f/15.0f);
GLfloat a = (texel>>4) * (1.0f/15.0f);
textureBuffer[i++] = c;
textureBuffer[i++] = c;
textureBuffer[i++] = c;
@ -414,10 +396,8 @@ void CLegacy3D::DecodeTexture(int format, int x, int y, int width, int height)
// Signals that new textures have been uploaded. Flushes model caches. Be careful not to exceed bounds!
void CLegacy3D::UploadTextures(unsigned x, unsigned y, unsigned width, unsigned height)
{
unsigned texSheet, xi, yi;
// Make everything red
#ifdef DEBUG
// Make everything red
for (int i = 0; i < 512*512; )
{
textureBuffer[i++] = 1.0f;
@ -428,11 +408,11 @@ void CLegacy3D::UploadTextures(unsigned x, unsigned y, unsigned width, unsigned
#endif
// Update all texture sheets
for (texSheet = 0; texSheet < numTexSheets; texSheet++)
for (size_t texSheet = 0; texSheet < numTexSheets; texSheet++)
{
for (xi = x/32; xi < (x+width)/32; xi++)
for (size_t xi = x/32; xi < (x+width)/32; xi++)
{
for (yi = y/32; yi < (y+height)/32; yi++)
for (size_t yi = y/32; yi < (y+height)/32; yi++)
{
texSheets[texSheet].texFormat[yi][xi] = -1;
texSheets[texSheet].texWidth[yi][xi] = -1;
@ -494,7 +474,6 @@ void CLegacy3D::MultMatrix(UINT32 matrixOffset)
{
GLfloat m[4*4];
const float *src = &matrixBasePtr[matrixOffset*12];
if (matrixBasePtr==NULL) // LA Machineguns
return;
m[CMINDEX(0, 0)] = src[3];
@ -513,7 +492,6 @@ void CLegacy3D::MultMatrix(UINT32 matrixOffset)
m[CMINDEX(3, 1)] = 0.0;
m[CMINDEX(3, 2)] = 0.0;
m[CMINDEX(3, 3)] = 1.0;
glMultMatrixf(m);
}
@ -624,26 +602,18 @@ static bool IsDynamicModel(const UINT32 *data)
*/
bool CLegacy3D::DrawModel(UINT32 modelAddr)
{
ModelCache *Cache;
const UINT32 *model;
int lutIdx;
struct VBORef *ModelRef;
//if (modelAddr==0x7FFF00) // Fighting Vipers (this is not polygon data!)
// return;
if (modelAddr == 0x200000) // Virtual On 2 (during boot-up, causes slow-down)
return OKAY;
model = TranslateModelAddress(modelAddr);
const UINT32 *model = TranslateModelAddress(modelAddr);
// Determine whether model is in polygon RAM or VROM
if (IsVROMModel(modelAddr))
Cache = &VROMCache;
else
Cache = &PolyCache;
ModelCache *Cache = IsVROMModel(modelAddr) ? &VROMCache : &PolyCache;
// Look up the model in the LUT and cache it if necessary
lutIdx = modelAddr&0xFFFFFF;
ModelRef = LookUpModel(Cache, lutIdx, texOffset);
int lutIdx = modelAddr&0xFFFFFF;
struct VBORef *ModelRef = LookUpModel(Cache, lutIdx, texOffset);
if (NULL == ModelRef && Cache == &VROMCache)
{
// If the model was a VROM model, it may be dynamic, so we need to try
@ -691,12 +661,6 @@ bool CLegacy3D::DrawModel(UINT32 modelAddr)
// Descends into a 10-word culling node
void CLegacy3D::DescendCullingNode(UINT32 addr)
{
const UINT32 *node, *lodTable;
UINT32 matrixOffset, node1Ptr, node2Ptr;
float x, y, z, oldTexOffsetX, oldTexOffsetY;
int tx, ty;
UINT16 oldTexOffset;
++stackDepth;
// Stack depth of 64 is too small for Star Wars Trilogy (Hoth)
if (stackDepth>=(512+64)) // safety (prevent overflows -- OpenGL matrix stack will still overflow by this point)
@ -705,7 +669,7 @@ void CLegacy3D::DescendCullingNode(UINT32 addr)
return;
}
node = TranslateCullingAddress(addr);
const UINT32 *node = TranslateCullingAddress(addr);
if (NULL == node)
{
--stackDepth;
@ -720,21 +684,21 @@ void CLegacy3D::DescendCullingNode(UINT32 addr)
// printf("%X -> %02X %04X\n", addr, node[0x00]&0xFF, node[0x02]&0xFFFF);
// Extract known fields
node1Ptr = node[0x07-offset];
node2Ptr = node[0x08-offset];
matrixOffset = node[0x03-offset]&0xFFF;
x = *(float *) &node[0x04-offset];
y = *(float *) &node[0x05-offset];
z = *(float *) &node[0x06-offset];
const UINT32 node1Ptr = node[0x07-offset];
const UINT32 node2Ptr = node[0x08-offset];
const UINT32 matrixOffset = node[0x03-offset]&0xFFF;
const float x = *(float *) &node[0x04-offset];
const float y = *(float *) &node[0x05-offset];
const float z = *(float *) &node[0x06-offset];
// Texture offset?
oldTexOffsetX = texOffsetXY[0]; // save old offsets
oldTexOffsetY = texOffsetXY[1];
oldTexOffset = texOffset;
const float oldTexOffsetX = texOffsetXY[0]; // save old offsets
const float oldTexOffsetY = texOffsetXY[1];
const UINT16 oldTexOffset = texOffset;
if (!offset) // Step 1.5+
{
tx = 32*((node[0x02]>>7)&0x3F);
ty = 32*(node[0x02]&0x3F) + ((node[0x02]&0x4000)?1024:0); // TODO: 5 or 6 bits for Y coord?
int tx = 32*((node[0x02]>>7)&0x3F);
int ty = 32*(node[0x02]&0x3F) + ((node[0x02]&0x4000)?1024:0); // TODO: 5 or 6 bits for Y coord?
if ((node[0x02]&0x8000)) // apply texture offsets, else retain current ones
{
texOffsetXY[0] = (GLfloat) tx;
@ -754,7 +718,7 @@ void CLegacy3D::DescendCullingNode(UINT32 addr)
// Descend down first link
if ((node[0x00]&0x08)) // 4-element LOD table
{
lodTable = TranslateCullingAddress(node1Ptr);
const UINT32 *lodTable = TranslateCullingAddress(node1Ptr);
if (NULL != lodTable)
{
if ((node[0x03-offset]&0x20000000))
@ -781,41 +745,33 @@ void CLegacy3D::DescendCullingNode(UINT32 addr)
// A list of pointers. MAME assumes that these may only point to culling nodes.
void CLegacy3D::DescendPointerList(UINT32 addr)
{
const UINT32 *list;
UINT32 nodeAddr;
int listEnd;
if (listDepth > 2) // several Step 2.1 games require this safeguard
return;
list = TranslateCullingAddress(addr);
const UINT32 *list = TranslateCullingAddress(addr);
if (NULL == list)
return;
++listDepth;
//printf("%08x LIST\n", addr);
// Traverse the list forward and print it out
listEnd = 0;
int listEnd = 0;
while (1)
{
//printf(" %08x\n", list[listEnd]);
if ((list[listEnd] & 0x02000000)) // end of list (?)
break;
if ((list[listEnd] == 0) || (((list[listEnd])>>24) != 0))
{
//printf("ATTENTION: Unknown list termination: %08X.\n", list[listEnd]);
listEnd--; // back up to last valid list element
break;
}
++listEnd;
}
// Traverse the list backward and descend into each pointer
while (listEnd >= 0)
{
nodeAddr = list[listEnd]&0x00FFFFFF; // clear upper 8 bits to ensure this is processed as a culling node
UINT32 nodeAddr = list[listEnd]&0x00FFFFFF; // clear upper 8 bits to ensure this is processed as a culling node
if (!(list[listEnd]&0x01000000))//Fighting Vipers
{
if ((nodeAddr != 0) && (nodeAddr != 0x800800))
@ -863,8 +819,7 @@ void CLegacy3D::DescendNodePtr(UINT32 nodeAddr)
// Draws viewports of the given priority
void CLegacy3D::RenderViewport(UINT32 addr, int pri)
{
GLfloat color[8][3] = // RGB1 translation
{
static const GLfloat color[8][3] = {
{ 0.0, 0.0, 0.0 }, // off
{ 0.0, 0.0, 1.0 }, // blue
{ 0.0, 1.0, 0.0 }, // green
@ -874,44 +829,35 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri)
{ 1.0, 1.0, 0.0 }, // yellow
{ 1.0, 1.0, 1.0 } // white
};
const UINT32 *vpnode;
UINT32 nextAddr, nodeAddr, matrixBase;
int curPri;
int vpX, vpY, vpWidth, vpHeight;
int spotColorIdx;
GLfloat vpTopAngle, vpBotAngle, fovYDegrees;
GLfloat scrollFog, scrollAtt;
// Translate address and obtain pointer
vpnode = TranslateCullingAddress(addr);
const UINT32 *vpnode = TranslateCullingAddress(addr);
if (NULL == vpnode)
return;
curPri = (vpnode[0x00] >> 3) & 3; // viewport priority
nextAddr = vpnode[0x01] & 0xFFFFFF; // next viewport
nodeAddr = vpnode[0x02]; // scene database node pointer
// Recursively process next viewport
if (vpnode[0x01] == 0) // memory probably hasn't been set up yet, abort
UINT32 nextAddr = vpnode[0x01]; // next viewport
UINT32 nodeAddr = vpnode[0x02]; // scene database node pointer
if (nextAddr == 0) // memory probably hasn't been set up yet, abort
return;
if (vpnode[0x01] != 0x01000000)
RenderViewport(vpnode[0x01],pri);
if (nextAddr != 0x01000000)
RenderViewport(nextAddr, pri);
// If the priority doesn't match, do not process
int curPri = (vpnode[0x00] >> 3) & 3; // viewport priority
if (curPri != pri)
return;
// Fetch viewport parameters (TO-DO: would rounding make a difference?)
vpX = (vpnode[0x1A]&0xFFFF)>>4; // viewport X (12.4 fixed point)
vpY = (vpnode[0x1A]>>20)&0xFFF; // viewport Y (12.4)
vpWidth = (vpnode[0x14]&0xFFFF)>>2; // width (14.2)
vpHeight = (vpnode[0x14]>>18)&0x3FFF; // height (14.2)
matrixBase = vpnode[0x16]&0xFFFFFF; // matrix base address
int vpX = (vpnode[0x1A]&0xFFFF)>>4; // viewport X (12.4 fixed point)
int vpY = (vpnode[0x1A]>>20)&0xFFF; // viewport Y (12.4)
int vpWidth = (vpnode[0x14]&0xFFFF)>>2; // width (14.2)
int vpHeight = (vpnode[0x14]>>18)&0x3FFF; // height (14.2)
// Field of view and clipping
vpTopAngle = (float) asin(*(float *)&vpnode[0x0E]); // FOV Y upper half-angle (radians)
vpBotAngle = (float) asin(*(float *)&vpnode[0x12]); // FOV Y lower half-angle
fovYDegrees = (vpTopAngle+vpBotAngle)*(float)(180.0/3.14159265358979323846);
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);
// TO-DO: investigate clipping planes
// Set up viewport and projection (TO-DO: near and far clipping)
@ -945,7 +891,7 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri)
lightingParams[5] = 0.0; // reserved
// Spotlight
spotColorIdx = (vpnode[0x20]>>11)&7; // spotlight color index
int spotColorIdx = (vpnode[0x20]>>11)&7; // spotlight color index
spotEllipse[0] = (float) ((vpnode[0x1E]>>3)&0x1FFF); // spotlight X position (fractional component?)
spotEllipse[1] = (float) ((vpnode[0x1D]>>3)&0x1FFF); // spotlight Y
spotEllipse[2] = (float) ((vpnode[0x1E]>>16)&0xFFFF); // spotlight X size (16-bit? May have fractional component below bit 16)
@ -979,8 +925,8 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri)
fogParams[3] = fogParams[4] = 0.0f;
// Unknown light/fog parameters
scrollFog = (float) (vpnode[0x20]&0xFF) * (1.0f/255.0f); // scroll fog
scrollAtt = (float) (vpnode[0x24]&0xFF) * (1.0f/255.0f); // scroll attenuation
//GLfloat scrollFog = (float) (vpnode[0x20]&0xFF) * (1.0f/255.0f); // scroll fog
//GLfloat scrollAtt = (float) (vpnode[0x24]&0xFF) * (1.0f/255.0f); // scroll attenuation
//printf("scrollFog = %g, scrollAtt = %g\n", scrollFog, scrollAtt);
//printf("Fog: R=%02X G=%02X B=%02X density=%g (%X) %d start=%g\n", ((vpnode[0x22]>>16)&0xFF), ((vpnode[0x22]>>8)&0xFF), ((vpnode[0x22]>>0)&0xFF), fogParams[3], vpnode[0x23], (fogParams[3]==fogParams[3]), fogParams[4]);
@ -990,6 +936,7 @@ void CLegacy3D::RenderViewport(UINT32 addr, int pri)
texOffset = 0x0000;
// Set up coordinate system and base matrix
UINT32 matrixBase = vpnode[0x16] & 0xFFFFFF;
glMatrixMode(GL_MODELVIEW);
InitMatrixStack(matrixBase);
@ -1172,23 +1119,23 @@ bool CLegacy3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
totalYRes = totalYResParam;
// Get ideal number of texture sheets required by default mapping from Model3 texture format to texture sheet
unsigned idealTexSheets = 0;
for (unsigned fmt = 0; fmt < 8; fmt++)
int idealTexSheets = 0;
for (size_t fmt = 0; fmt < 8; fmt++)
{
int sheetNum = defaultFmtToTexSheetNum[fmt];
idealTexSheets = max<int>(idealTexSheets, sheetNum + 1);
idealTexSheets = std::max<int>(idealTexSheets, sheetNum + 1);
}
// Get upper limit for number of texture maps to use from max number of texture units supported by video card
GLint glMaxTexUnits;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &glMaxTexUnits);
unsigned maxTexMaps = max<int>(1, min<int>(g_Config.maxTexMaps, glMaxTexUnits));
int maxTexMaps = std::max<int>(1, std::min<int>(g_Config.maxTexMaps, glMaxTexUnits));
// Get upper limit for extent of texture maps to use from max texture size supported by video card
GLint maxTexSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
unsigned mapExtent = max<int>(1, min<unsigned>(g_Config.maxTexMapExtent, maxTexSize / 2048));
unsigned mapSize = 2048 * mapExtent;
int mapExtent = std::max<int>(1, std::min<unsigned>(g_Config.maxTexMapExtent, maxTexSize / 2048));
int mapSize = 2048 * mapExtent;
while (mapExtent > 1)
{
if ((mapExtent - 1) * (mapExtent - 1) < idealTexSheets)
@ -1216,12 +1163,12 @@ bool CLegacy3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
textureMapLoc = glGetUniformLocation(shaderProgram, "textureMap");
// If exists, bind to first texture unit
unsigned mapCount = 0;
int mapCount = 0;
if (textureMapLoc != -1)
glUniform1i(textureMapLoc, mapCount++);
// Try locating "textureMap[0-7]" uniforms in shader program
for (unsigned mapNum = 0; mapNum < 8 && mapCount < maxTexMaps; mapNum++)
for (int mapNum = 0; mapNum < 8 && mapCount < maxTexMaps; mapNum++)
{
char uniformName[12];
sprintf(uniformName, "textureMap%u", mapNum);
@ -1247,7 +1194,7 @@ bool CLegacy3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
unsigned sheetsPerMap = mapExtent * mapExtent;
while (true)
{
numTexMaps = min<unsigned>(mapCount, 1 + (idealTexSheets - 1) / sheetsPerMap);
numTexMaps = std::min<unsigned>(mapCount, 1 + (idealTexSheets - 1) / sheetsPerMap);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(numTexMaps, texMapIDs);
@ -1285,7 +1232,7 @@ bool CLegacy3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
InfoLog("Created %u %ux%u-texel GL texture map(s).", numTexMaps, mapSize, mapSize);
// Create texture sheet objects and assign them to texture maps
numTexSheets = min<unsigned>(numTexMaps * sheetsPerMap, idealTexSheets);
numTexSheets = std::min<unsigned>(numTexMaps * sheetsPerMap, idealTexSheets);
texSheets = new(std::nothrow) TexSheet[numTexSheets];
if (texSheets == NULL)
return ErrorLog("Unable to assign memory for %u texture sheet objects.", numTexSheets);

View file

@ -1,4 +1,4 @@
/**
/**
** Supermodel
** A Sega Model 3 Arcade Emulator.
** Copyright 2011 Bart Trzynadlowski, Nik Henson

View file

@ -28,8 +28,6 @@
* -----------
* - If vertex normals aren't offset from polygon normals, would that improve
* specular lighting?
* - Check to see if vertices in LA Machineguns and Dirt Devils contain color
* values rather than normals.
* - More should be predecoded into the polygon structures, so that things like
* texture base coordinates are not re-decoded in two different places!
*/
@ -85,7 +83,7 @@ namespace Legacy3D {
// Macro to generate column-major (OpenGL) index from y,x subscripts
#define CMINDEX(y,x) (x*4+y)
static void CrossProd(GLfloat out[3], GLfloat a[3], GLfloat b[3])
static void CrossProd(GLfloat out[3], const GLfloat a[3], const GLfloat b[3])
{
out[0] = a[1]*b[2]-a[2]*b[1];
out[1] = a[2]*b[0]-a[0]*b[2];
@ -93,7 +91,7 @@ static void CrossProd(GLfloat out[3], GLfloat a[3], GLfloat b[3])
}
// 3x3 matrix used (upper-left of m[])
static void MultMat3Vec3(GLfloat out[3], GLfloat m[4*4], GLfloat v[3])
static void MultMat3Vec3(GLfloat out[3], const GLfloat m[4*4], const GLfloat v[3])
{
out[0] = m[CMINDEX(0,0)]*v[0]+m[CMINDEX(0,1)]*v[1]+m[CMINDEX(0,2)]*v[2];
out[1] = m[CMINDEX(1,0)]*v[0]+m[CMINDEX(1,1)]*v[1]+m[CMINDEX(1,2)]*v[2];
@ -124,6 +122,7 @@ static void InvertTransposeMat3(GLfloat out[4*4], GLfloat m[4*4])
out[CMINDEX(0,2)] = invDet*(a21*a10-a20*a11); out[CMINDEX(1,2)] = invDet*(-(a21*a00-a20*a01)); out[CMINDEX(2,2)] = invDet*(a11*a00-a10*a01);
}
/*
static void PrintMatrix(GLfloat m[4*4])
{
for (int i = 0; i < 3; i++)
@ -133,6 +132,7 @@ static void PrintMatrix(GLfloat m[4*4])
printf("\n");
}
}
*/
/******************************************************************************
@ -150,8 +150,6 @@ static void PrintMatrix(GLfloat m[4*4])
// Draws the display list
void CLegacy3D::DrawDisplayList(ModelCache *Cache, POLY_STATE state)
{
DisplayList *D;
// Bind and activate VBO (pointers activate currently bound VBO)
glBindBuffer(GL_ARRAY_BUFFER, Cache->vboID);
glVertexPointer(3, GL_FLOAT, VBO_VERTEX_SIZE*sizeof(GLfloat), (GLvoid *) (VBO_VERTEX_OFFSET_X*sizeof(GLfloat)));
@ -179,7 +177,7 @@ void CLegacy3D::DrawDisplayList(ModelCache *Cache, POLY_STATE state)
}
// Draw if there are items in the list
D = Cache->ListHead[state];
const DisplayList *D = Cache->ListHead[state];
while (D != NULL)
{
if (D->isViewport)
@ -202,12 +200,11 @@ void CLegacy3D::DrawDisplayList(ModelCache *Cache, POLY_STATE state)
}
else
{
GLint frontFace;
if (D->Data.Model.frontFace == -GL_CW) // no backface culling (all normals have lost their Z component)
glDisable(GL_CULL_FACE);
else // use appropriate winding convention
{
GLint frontFace;
glGetIntegerv(GL_FRONT_FACE, &frontFace);
if (frontFace != D->Data.Model.frontFace)
glFrontFace(D->Data.Model.frontFace);
@ -228,14 +225,13 @@ void CLegacy3D::DrawDisplayList(ModelCache *Cache, POLY_STATE state)
// Appends an instance of a model or viewport to the display list, copying over the required state information
bool CLegacy3D::AppendDisplayList(ModelCache *Cache, bool isViewport, const struct VBORef *Model)
{
int lm, i;
if ((Cache->listSize+2) > Cache->maxListSize) // a model may have 2 states (viewports are added to both display lists)
return FAIL;
//return ErrorLog("Display list is full.");
// Insert states into the display list
for (i = 0; i < 2; i++)
size_t lm = 0;
for (size_t i = 0; i < 2; i++)
{
if (isViewport)
{
@ -299,9 +295,9 @@ bool CLegacy3D::AppendDisplayList(ModelCache *Cache, bool isViewport, const stru
* This is described further in InsertPolygon(), where the vertices
* are ordered in clockwise fashion.
*/
GLfloat x[3] = { 1.0f, 0.0f, 0.0f };
GLfloat y[3] = { 0.0f, 1.0f, 0.0f };
GLfloat z[3] = { 0.0f, 0.0f, -1.0f*matrixBasePtr[0x5] };
static const GLfloat x[3] = { 1.0f, 0.0f, 0.0f };
static const GLfloat y[3] = { 0.0f, 1.0f, 0.0f };
const GLfloat z[3] = { 0.0f, 0.0f, -1.0f*matrixBasePtr[0x5] };
GLfloat m[4*4];
GLfloat xT[3], yT[3], zT[3], pT[3];
@ -344,7 +340,7 @@ bool CLegacy3D::AppendDisplayList(ModelCache *Cache, bool isViewport, const stru
void CLegacy3D::ClearDisplayList(ModelCache *Cache)
{
Cache->listSize = 0;
for (int i = 0; i < 2; i++)
for (size_t i = 0; i < 2; i++)
{
Cache->ListHead[i] = NULL;
Cache->ListTail[i] = NULL;
@ -364,21 +360,15 @@ void CLegacy3D::ClearDisplayList(ModelCache *Cache)
// Inserts a vertex into the local vertex buffer, incrementing both the local and VBO pointers. The normal is scaled by normFlip.
void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P, float normFlip)
{
GLfloat r, g, b;
GLfloat translucence, fogIntensity, texWidth, texHeight, texBaseX, texBaseY, contourProcessing;
unsigned baseIdx, texFormat, texEnable, lightEnable, modulate, colorIdx;
TexSheet *texSheet;
int s, texPage, shininess;
// Texture selection
texEnable = P->header[6]&0x04000000;
texFormat = (P->header[6]>>7)&7;
texWidth = (GLfloat) (32<<((P->header[3]>>3)&7));
texHeight = (GLfloat) (32<<((P->header[3]>>0)&7));
texPage = (P->header[4]&0x40) ? 1024 : 0; // treat texture page as Y coordinate
texSheet = fmtToTexSheet[texFormat]; // get X&Y offset of texture sheet within texture map
texBaseX = (GLfloat) (texSheet->xOffset + (((32*(((P->header[4]&0x1F)<<1)|((P->header[5]>>7)&1))) + (int)texOffsetXY[0])&2047));
texBaseY = (GLfloat) (texSheet->yOffset + (((32*(P->header[5]&0x1F)+texPage) + (int)texOffsetXY[1])&2047));
unsigned texEnable = P->header[6]&0x04000000;
unsigned texFormat = (P->header[6]>>7)&7;
GLfloat texWidth = (GLfloat) (32<<((P->header[3]>>3)&7));
GLfloat texHeight = (GLfloat) (32<<((P->header[3]>>0)&7));
int texPage = (P->header[4]&0x40) ? 1024 : 0; // treat texture page as Y coordinate
TexSheet *texSheet = fmtToTexSheet[texFormat]; // get X&Y offset of texture sheet within texture map
GLfloat texBaseX = (GLfloat) (texSheet->xOffset + (((32*(((P->header[4]&0x1F)<<1)|((P->header[5]>>7)&1))) + (int)texOffsetXY[0])&2047));
GLfloat texBaseY = (GLfloat) (texSheet->yOffset + (((32*(P->header[5]&0x1F)+texPage) + (int)texOffsetXY[1])&2047));
/*
* Lighting and Color Modulation:
@ -419,25 +409,30 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
* correct, but cones are too dark. Need to investigate further.
*/
lightEnable = !(P->header[6]&0x00010000);
modulate = !(P->header[4]&0x80); // makes traffic lights blink in Daytona and works best in Sega Rally 2
//modulate = P->header[3]&0x80; // seems to work better overall (TODO: are header[3]&0x80 and header[4]&0x80 ever both set?)
unsigned lightEnable = !(P->header[6]&0x00010000);
unsigned modulate = !(P->header[4]&0x80); // makes traffic lights blink in Daytona and works best in Sega Rally 2
//unsigned modulate = P->header[3]&0x80; // seems to work better overall (TODO: are header[3]&0x80 and header[4]&0x80 ever both set?)
// Material color
GLfloat r = 1.0;
GLfloat g = 1.0;
GLfloat b = 1.0;
if ((P->header[1]&2) == 0)
{
colorIdx = ((P->header[4]>>20)&0x7FF) - 0; // works for Scud
colorIdx = ((P->header[4]>>8)&0x7FF) - 0; // works for Daytona2 lights
unsigned base = 0x400;
size_t base = 0x400;
//size_t colorIdx = ((P->header[4]>>20)&0x7FF) - 0; // works for Scud
size_t colorIdx = ((P->header[4]>>8)&0x7FF) - 0; // works for Daytona2 lights and Scud
b = (GLfloat) (polyRAM[base+colorIdx]&0xFF) * (1.0f/255.0f);
g = (GLfloat) ((polyRAM[base+colorIdx]>>8)&0xFF) * (1.0f/255.0f);
r = (GLfloat) ((polyRAM[base+colorIdx]>>16)&0xFF) * (1.0f/255.0f);
//modulate=true;
//modulate=true;
}
/*
else if ((P->header[6] & 0x02000000))
{
r = g = b = (GLfloat) ((P->header[6]>>26)&0x1f) * (1.0f/31.0f);
}
*/
else
{
// Colors are 8-bit (almost certainly true, see Star Wars)
@ -453,9 +448,9 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
if (!modulate)
r = g = b = 1.0f;
}
if ((P->header[6] & 0x02000000)) { lightEnable=false;r=b=0;g=1.0;texEnable=false;modulate=false;}
// Specular shininess
shininess = (P->header[0]>>26)&0x3F;
int shininess = (P->header[0]>>26)&0x3F;
//shininess = (P->header[0]>>28)&0xF;
//if (shininess)
// printf("%X\n", shininess);
@ -489,12 +484,12 @@ if ((P->header[6] & 0x02000000)) { lightEnable=false;r=b=0;g=1.0;texEnable=false
#endif
// Determine whether polygon is translucent
translucence = (GLfloat) ((P->header[6]>>18)&0x1F) * (1.0f/31.0f);
GLfloat translucence = (GLfloat) ((P->header[6]>>18)&0x1F) * (1.0f/31.0f);
if ((P->header[6]&0x00800000)) // if set, polygon is opaque
translucence = 1.0f;
// Fog intensity (for luminous polygons)
fogIntensity = (GLfloat) ((P->header[6]>>11)&0x1F) * (1.0f/31.0f);
GLfloat fogIntensity = (GLfloat) ((P->header[6]>>11)&0x1F) * (1.0f/31.0f);
if (!(P->header[6]&0x00010000)) // if not luminous, always use full fog intensity
fogIntensity = 1.0f;
@ -506,16 +501,15 @@ if ((P->header[6] & 0x02000000)) { lightEnable=false;r=b=0;g=1.0;texEnable=false
* alpha blended texture formats as well in order to discard fully
* transparent pixels.
*/
GLfloat contourProcessing = -1.0f;
if ((P->header[6]&0x80000000) || (texFormat==7) || // contour processing enabled or RGBA4 texture
((texFormat==1) && (P->header[6]&2)) || // A4L4 interleaved (these formats are not being interpreted correctly, see Scud Race clock tower)
((texFormat==3) && (P->header[6]&4))) // A4L4 interleaved
contourProcessing = 1.0f;
else
contourProcessing = -1.0f;
// Store to local vertex buffer
s = P->state;
baseIdx = Cache->curVertIdx[s]*VBO_VERTEX_SIZE;
size_t s = P->state;
size_t baseIdx = Cache->curVertIdx[s]*VBO_VERTEX_SIZE;
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_X] = V->x;
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_Y] = V->y;
@ -551,10 +545,6 @@ if ((P->header[6] & 0x02000000)) { lightEnable=false;r=b=0;g=1.0;texEnable=false
bool CLegacy3D::InsertPolygon(ModelCache *Cache, const Poly *P)
{
GLfloat n[3], v1[3], v2[3], normZFlip;
int i;
bool doubleSided;
// Bounds testing: up to 12 triangles will be inserted (worst case: double sided quad is 6 triangles)
if ((Cache->curVertIdx[P->state]+6*2) >= Cache->maxVertIdx)
return ErrorLocalVertexOverflow(); // local buffers are not expected to overflow
@ -562,7 +552,7 @@ bool CLegacy3D::InsertPolygon(ModelCache *Cache, const Poly *P)
return FAIL; // this just indicates we may need to re-cache
// Is the polygon double sided?
doubleSided = (P->header[1]&0x10) ? true : false;
bool doubleSided = (P->header[1]&0x10) ? true : false;
/*
* Determine polygon winding by taking cross product of vectors formed from
@ -581,6 +571,9 @@ bool CLegacy3D::InsertPolygon(ModelCache *Cache, const Poly *P)
* to do with using the correct Z convention to identify a vector pointing
* toward or away from the screen.
*/
GLfloat v1[3];
GLfloat v2[3];
GLfloat n[3];
v1[0] = P->Vert[0].x-P->Vert[1].x;
v1[1] = P->Vert[0].y-P->Vert[1].y;
v1[2] = P->Vert[0].z-P->Vert[1].z;
@ -589,19 +582,19 @@ bool CLegacy3D::InsertPolygon(ModelCache *Cache, const Poly *P)
v2[2] = P->Vert[2].z-P->Vert[1].z;
CrossProd(n,v1,v2);
normZFlip = -1.0f*matrixBasePtr[0x5]; // coordinate system m13 component
GLfloat normZFlip = -1.0f*matrixBasePtr[0x5]; // coordinate system m13 component
if (normZFlip*(n[0]*P->n[0]+n[1]*P->n[1]+n[2]*P->n[2]) >= 0.0) // clockwise winding confirmed
{
// Store the first triangle
for (i = 0; i < 3; i++)
for (int i = 0; i < 3; i++)
{
InsertVertex(Cache, &(P->Vert[i]), P, 1.0f);
}
if (doubleSided) // store backside as counter-clockwise
{
for (i = 2; i >=0; i--)
for (int i = 2; i >=0; i--)
{
InsertVertex(Cache, &(P->Vert[i]), P, -1.0f);
}
@ -624,14 +617,14 @@ bool CLegacy3D::InsertPolygon(ModelCache *Cache, const Poly *P)
}
else // counterclockwise winding, reverse it
{
for (i = 2; i >=0; i--)
for (int i = 2; i >=0; i--)
{
InsertVertex(Cache, &(P->Vert[i]), P, 1.0f);
}
if (doubleSided) // store backside as clockwise
{
for (i = 0; i < 3; i++)
for (int i = 0; i < 3; i++)
{
InsertVertex(Cache, &(P->Vert[i]), P, -1.0f);
}
@ -658,9 +651,7 @@ bool CLegacy3D::InsertPolygon(ModelCache *Cache, const Poly *P)
// Begins caching a new model by resetting to the start of the local vertex buffer
struct VBORef *CLegacy3D::BeginModel(ModelCache *Cache)
{
struct VBORef *Model;
unsigned m = Cache->numModels;
size_t m = Cache->numModels;
// Determine whether we've exceeded the model cache limits (caller will have to recache)
if (m >= Cache->maxModels)
@ -669,10 +660,10 @@ struct VBORef *CLegacy3D::BeginModel(ModelCache *Cache)
return NULL;
}
Model = &(Cache->Models[m]);
struct VBORef *Model = &(Cache->Models[m]);
// Reset to the beginning of the local vertex buffer
for (int i = 0; i < 2; i++)
for (size_t i = 0; i < 2; i++)
Cache->curVertIdx[i] = 0;
// Clear the VBO reference to 0 and clear texture references
@ -691,7 +682,7 @@ void CLegacy3D::EndModel(ModelCache *Cache, struct VBORef *Model, int lutIdx, UI
int m = Cache->numModels++;
// Record the number of vertices, completing the VBORef
for (int i = 0; i < 2; i++)
for (size_t i = 0; i < 2; i++)
Model->numVerts[i] = Cache->curVertIdx[i];
// First alpha polygon immediately follows the normal polygons
@ -730,10 +721,6 @@ void CLegacy3D::EndModel(ModelCache *Cache, struct VBORef *Model, int lutIdx, UI
struct VBORef *CLegacy3D::CacheModel(ModelCache *Cache, int lutIdx, UINT16 texOffset, const UINT32 *data)
{
Vertex Prev[4]; // previous vertices
int numPolys = 0;
bool done = false;
// Sega Rally 2 bad models
//if (lutIdx == 0x27a1 || lutIdx == 0x21e0)
// return FAIL;
@ -747,17 +734,13 @@ struct VBORef *CLegacy3D::CacheModel(ModelCache *Cache, int lutIdx, UINT16 texOf
return NULL; // too many models!
// Cache all polygons
Vertex Prev[4]; // previous vertices
int numPolys = 0;
bool done = false;
while (!done)
{
Poly P; // current polygon
GLfloat mag;
GLfloat uvScale;
int texEnable, texFormat, texWidth, texHeight, texPage, texBaseX, texBaseY;
unsigned i, j, vmask;
UINT32 ix, iy, iz, it;
bool validPoly;
// Set current header pointer (header is 7 words)
Poly P; // current polygon
P.header = data;
data += 7; // data will now point to first vertex
if (P.header[6]==0)// || P.header[0]==0)
@ -767,44 +750,21 @@ struct VBORef *CLegacy3D::CacheModel(ModelCache *Cache, int lutIdx, UINT16 texOf
// vertices (very large values or 0). Ignoring polygons with these bits set
// seems to fix the problem. Perhaps these polygons exist for alignment
// purposes or are another type of entity altogether?
validPoly = (P.header[0] & 0x300) != 0x300;
// if (!validPoly)
{
//printf("Invalid poly:\n");
//for (int i = 0; i < 7; i++)
// printf(" %d: %08x\n", i, P.header[i]);
}
bool validPoly = (P.header[0] & 0x300) != 0x300;
// Obtain basic polygon parameters
done = P.header[1]&4; // last polygon?
P.numVerts = (P.header[0]&0x40)?4:3;
#if 0
if ((P.header[0] & 0xf) && numPolys == 0)
{
validPoly=false;
printf("LNK=%x num=%d\n", P.header[0] & 0xf, P.numVerts);
}
if (lutIdx==0x8c0955)
{
for (int i = 0; i < 7; i++)
printf("%d %d: %08x\n", numPolys, i, P.header[i]);
}
#endif
// Texture data
texEnable = P.header[6]&0x04000000;
texFormat = (P.header[6]>>7)&7;
texWidth = (32<<((P.header[3]>>3)&7));
texHeight = (32<<((P.header[3]>>0)&7));
texPage = (P.header[4]&0x40) ? 1024 : 0; // treat texture page as Y coordinate
texBaseX = (32*(((P.header[4]&0x1F)<<1)|((P.header[5]>>7)&1))) + (int)texOffsetXY[0];
texBaseY = (32*(P.header[5]&0x1F)+texPage) + (int)texOffsetXY[1];
texBaseX &= 2047;
texBaseY &= 2047;
uvScale = (P.header[1]&0x40)?1.0f:(1.0f/8.0f);
int texEnable = P.header[6]&0x04000000;
int texFormat = (P.header[6]>>7)&7;
int texWidth = (32<<((P.header[3]>>3)&7));
int texHeight = (32<<((P.header[3]>>0)&7));
int texPage = (P.header[4]&0x40) ? 1024 : 0; // treat texture page as Y coordinate
int texBaseX = ((32*(((P.header[4]&0x1F)<<1)|((P.header[5]>>7)&1))) + (int)texOffsetXY[0]) & 2047;
int texBaseY = ((32*(P.header[5]&0x1F)+texPage) + (int)texOffsetXY[1]) & 2047;
GLfloat uvScale = (P.header[1]&0x40)?1.0f:(1.0f/8.0f);
// Determine whether this is an alpha polygon (TODO: when testing textures, test if texturing enabled? Might not matter)
if (((P.header[6]&0x00800000)==0) || // translucent polygon
@ -844,10 +804,9 @@ if (lutIdx==0x8c0955)
P.n[2] = (GLfloat) (((INT32)P.header[3])>>8) * (1.0f/4194304.0f);
// Fetch reused vertices according to bitfield, then new verts
i = 0;
j = 0;
vmask = 1;
for (i = 0; i < 4; i++) // up to 4 reused vertices
size_t j = 0;
size_t vmask = 1;
for (size_t i = 0; i < 4; i++) // up to 4 reused vertices
{
if ((P.header[0x00]&vmask))
{
@ -860,10 +819,10 @@ if (lutIdx==0x8c0955)
for (; j < P.numVerts; j++) // remaining vertices are new and defined here
{
// Fetch vertices
ix = data[0];
iy = data[1];
iz = data[2];
it = data[3];
UINT32 ix = data[0];
UINT32 iy = data[1];
UINT32 iz = data[2];
UINT32 it = data[3];
/*
// Check for bad vertices (Sega Rally 2)
@ -886,7 +845,7 @@ if (lutIdx==0x8c0955)
data += 4;
// Normalize the vertex normal
mag = sqrt(P.Vert[j].n[0]*P.Vert[j].n[0]+P.Vert[j].n[1]*P.Vert[j].n[1]+P.Vert[j].n[2]*P.Vert[j].n[2]);
GLfloat mag = sqrt(P.Vert[j].n[0]*P.Vert[j].n[0]+P.Vert[j].n[1]*P.Vert[j].n[1]+P.Vert[j].n[2]*P.Vert[j].n[2]);
P.Vert[j].n[0] /= mag;
P.Vert[j].n[1] /= mag;
P.Vert[j].n[2] /= mag;
@ -895,7 +854,7 @@ if (lutIdx==0x8c0955)
if (validPoly)
{
// Copy current vertices into previous vertex array
for (i = 0; i < 4; i++)
for (size_t i = 0; i < 4; i++)
Prev[i] = P.Vert[i];
// Copy this polygon into the model buffer
@ -941,9 +900,9 @@ struct VBORef *CLegacy3D::LookUpModel(ModelCache *Cache, int lutIdx, UINT16 texO
void CLegacy3D::ClearModelCache(ModelCache *Cache)
{
Cache->vboCurOffset = 0;
for (int i = 0; i < 2; i++)
for (size_t i = 0; i < 2; i++)
Cache->curVertIdx[i] = 0;
for (int i = 0; i < Cache->numModels; i++)
for (size_t i = 0; i < Cache->numModels; i++)
Cache->lut[Cache->Models[i].lutIdx] = -1;
Cache->numModels = 0;
@ -954,10 +913,6 @@ bool CLegacy3D::CreateModelCache(ModelCache *Cache, unsigned vboMaxVerts,
unsigned localMaxVerts, unsigned maxNumModels, unsigned numLUTEntries,
unsigned displayListSize, bool isDynamic)
{
unsigned i;
int vboBytes, localBytes;
bool success;
Cache->dynamic = isDynamic;
/*
@ -972,11 +927,11 @@ bool CLegacy3D::CreateModelCache(ModelCache *Cache, unsigned vboMaxVerts,
glGenBuffers(1, &(Cache->vboID));
glBindBuffer(GL_ARRAY_BUFFER, Cache->vboID);
vboBytes = vboMaxVerts*VBO_VERTEX_SIZE*sizeof(GLfloat);
localBytes = localMaxVerts*VBO_VERTEX_SIZE*sizeof(GLfloat);
size_t vboBytes = vboMaxVerts*VBO_VERTEX_SIZE*sizeof(GLfloat);
size_t localBytes = localMaxVerts*VBO_VERTEX_SIZE*sizeof(GLfloat);
// Try allocating until size is
success = false;
bool success = false;
while (vboBytes >= localBytes)
{
glBufferData(GL_ARRAY_BUFFER, vboBytes, 0, isDynamic?GL_STREAM_DRAW:GL_STATIC_DRAW);
@ -1006,7 +961,7 @@ bool CLegacy3D::CreateModelCache(ModelCache *Cache, unsigned vboMaxVerts,
Cache->vboCurOffset = 0;
// Attempt to allocate space for local VBO
for (i = 0; i < 2; i++)
for (size_t i = 0; i < 2; i++)
{
Cache->verts[i] = new(std::nothrow) GLfloat[localMaxVerts*VBO_VERTEX_SIZE];
Cache->curVertIdx[i] = 0;
@ -1035,7 +990,7 @@ bool CLegacy3D::CreateModelCache(ModelCache *Cache, unsigned vboMaxVerts,
}
// Clear LUT (MUST be done here because ClearModelCache() won't do it for dynamic models)
for (i = 0; i < numLUTEntries; i++)
for (size_t i = 0; i < numLUTEntries; i++)
Cache->lut[i] = -1;
// All good!
@ -1046,7 +1001,7 @@ void CLegacy3D::DestroyModelCache(ModelCache *Cache)
{
glDeleteBuffers(1, &(Cache->vboID));
for (int i = 0; i < 2; i++)
for (size_t i = 0; i < 2; i++)
{
if (Cache->verts[i] != NULL)
delete [] Cache->verts[i];

View file

@ -206,7 +206,7 @@ bool CTextureRefs::UpdateHashCapacity(unsigned capacity)
m_hashEntries = new(std::nothrow) HashEntry*[capacity];
if (!m_hashEntries)
return false;
memset(m_hashEntries, NULL, capacity * sizeof(HashEntry*));
memset(m_hashEntries, 0, capacity * sizeof(HashEntry*));
if (oldEntries)
{
// Redistribute entries into new entries array