mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-04-10 19:15:14 +00:00
Added texture offsets. Vertex shader has been updated in Shaders/Vertex.glsl.
Added palette initialization to 2D renderer. Fixes 2D graphics corruption when loading states (most visible in Scud Race).
This commit is contained in:
parent
97ac46c82a
commit
cd2621b2ce
|
@ -737,11 +737,27 @@ void CRender2D::EndFrame(void)
|
||||||
Emulation Callbacks
|
Emulation Callbacks
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void CRender2D::WriteVRAM(unsigned addr, UINT32 data)
|
void CRender2D::WritePalette(unsigned color, UINT32 data)
|
||||||
{
|
{
|
||||||
unsigned color;
|
|
||||||
UINT8 r, g, b, a;
|
UINT8 r, g, b, a;
|
||||||
|
|
||||||
|
a = 0xFF * ((data>>15)&1); // decode the RGBA (make alpha 0xFF or 0x00)
|
||||||
|
a = ~a; // invert it (set on Model 3 means clear pixel)
|
||||||
|
|
||||||
|
if ((data&0x8000))
|
||||||
|
r = g = b = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b = (data>>7)&0xF8;
|
||||||
|
g = (data>>2)&0xF8;
|
||||||
|
r = (data<<3)&0xF8;
|
||||||
|
}
|
||||||
|
|
||||||
|
pal[color] = (a<<24)|(b<<16)|(g<<8)|r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRender2D::WriteVRAM(unsigned addr, UINT32 data)
|
||||||
|
{
|
||||||
if (vram[addr/4] == data) // do nothing if no changes
|
if (vram[addr/4] == data) // do nothing if no changes
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -751,19 +767,27 @@ void CRender2D::WriteVRAM(unsigned addr, UINT32 data)
|
||||||
// Palette
|
// Palette
|
||||||
if (addr >= 0x100000)
|
if (addr >= 0x100000)
|
||||||
{
|
{
|
||||||
color = (addr-0x100000)/4; // color index
|
unsigned color = (addr-0x100000)/4; // color index
|
||||||
a = 0xFF * ((data>>15)&1); // decode the RGBA (make alpha 0xFF or 0x00)
|
WritePalette(color, data);
|
||||||
a = ~a; // invert it (set on Model 3 means clear pixel)
|
}
|
||||||
if ((data&0x8000))
|
}
|
||||||
r = g = b = 0;
|
|
||||||
else
|
/*
|
||||||
|
* InitPalette():
|
||||||
|
*
|
||||||
|
* This must be called from AttachVRAM() to initialize the palette. The reason
|
||||||
|
* is that because WriteVRAM() always compares incoming data to what is already
|
||||||
|
* in the VRAM, there is no actual way to initialize the palette by calling
|
||||||
|
* WriteVRAM() and passing it the initial VRAM contents. It will always fail to
|
||||||
|
* update because nothing is being changed.
|
||||||
|
*
|
||||||
|
* This function fixes the transparent pixel bug that frequently occurred when
|
||||||
|
* loading save states in Supermodel 0.1a.
|
||||||
|
*/
|
||||||
|
void CRender2D::InitPalette(void)
|
||||||
{
|
{
|
||||||
b = (data>>7)&0xF8;
|
for (int i = 0; i < 0x20000/4; i++)
|
||||||
g = (data>>2)&0xF8;
|
WritePalette(i, vram[0x100000/4 + i]);
|
||||||
r = (data<<3)&0xF8;
|
|
||||||
}
|
|
||||||
pal[color] = (a<<24)|(b<<16)|(g<<8)|r;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -780,6 +804,7 @@ void CRender2D::AttachRegisters(const UINT32 *regPtr)
|
||||||
void CRender2D::AttachVRAM(const UINT8 *vramPtr)
|
void CRender2D::AttachVRAM(const UINT8 *vramPtr)
|
||||||
{
|
{
|
||||||
vram = (UINT32 *) vramPtr;
|
vram = (UINT32 *) vramPtr;
|
||||||
|
InitPalette();
|
||||||
DebugLog("Render2D attached VRAM\n");
|
DebugLog("Render2D attached VRAM\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,8 @@ private:
|
||||||
void DisplayLayer(int layerNum, GLfloat z);
|
void DisplayLayer(int layerNum, GLfloat z);
|
||||||
void Setup2D(void);
|
void Setup2D(void);
|
||||||
void ColorOffset(GLfloat colorOffset[3], UINT32 reg);
|
void ColorOffset(GLfloat colorOffset[3], UINT32 reg);
|
||||||
|
void WritePalette(unsigned color, UINT32 data);
|
||||||
|
void InitPalette(void);
|
||||||
|
|
||||||
// Data received from tile generator device object
|
// Data received from tile generator device object
|
||||||
const UINT32 *vram;
|
const UINT32 *vram;
|
||||||
|
|
|
@ -188,6 +188,9 @@ void CRender3D::DecodeTexture(int format, int x, int y, int width, int height)
|
||||||
UINT16 texel;
|
UINT16 texel;
|
||||||
GLfloat c, a;
|
GLfloat c, a;
|
||||||
|
|
||||||
|
x %= 2048;
|
||||||
|
y %= 2048;
|
||||||
|
|
||||||
if ((x+width)>2048 || (y+height)>2048)
|
if ((x+width)>2048 || (y+height)>2048)
|
||||||
return;
|
return;
|
||||||
if (width > 512 || height > 512)
|
if (width > 512 || height > 512)
|
||||||
|
@ -662,7 +665,8 @@ void CRender3D::DescendCullingNode(UINT32 addr)
|
||||||
{
|
{
|
||||||
const UINT32 *node, *lodTable;
|
const UINT32 *node, *lodTable;
|
||||||
UINT32 matrixOffset, node1Ptr, node2Ptr;
|
UINT32 matrixOffset, node1Ptr, node2Ptr;
|
||||||
float x, y, z;
|
float x, y, z, oldTexOffsetX, oldTexOffsetY;
|
||||||
|
int tx, ty;
|
||||||
|
|
||||||
++stackDepth;
|
++stackDepth;
|
||||||
// Stack depth of 64 is too small for Star Wars Trilogy (Hoth)
|
// Stack depth of 64 is too small for Star Wars Trilogy (Hoth)
|
||||||
|
@ -691,6 +695,18 @@ void CRender3D::DescendCullingNode(UINT32 addr)
|
||||||
y = *(float *) &node[0x05-offset];
|
y = *(float *) &node[0x05-offset];
|
||||||
z = *(float *) &node[0x06-offset];
|
z = *(float *) &node[0x06-offset];
|
||||||
|
|
||||||
|
// Texture offset?
|
||||||
|
oldTexOffsetX = texOffset[0]; // save old offsets
|
||||||
|
oldTexOffsetY = texOffset[1];
|
||||||
|
tx = 32*((node[0x02]>>7)&0x3F);
|
||||||
|
ty = 32*(node[0x02]&0x3F) + ((node[0x02]&0x4000)?1024:0);
|
||||||
|
if ((node[0x02]&0x8000)) // apply texture offsets, else retain current ones
|
||||||
|
{
|
||||||
|
texOffset[0] = (GLfloat) tx;
|
||||||
|
texOffset[1] = (GLfloat) ty;
|
||||||
|
//printf("Tex Offset: %d, %d (%08X %08X)\n", tx, ty, node[0x02], node[0x00]);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply matrix and translation
|
// Apply matrix and translation
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
if ((node[0x00]&0x10)) // apply translation vector
|
if ((node[0x00]&0x10)) // apply translation vector
|
||||||
|
@ -717,6 +733,10 @@ void CRender3D::DescendCullingNode(UINT32 addr)
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
DescendNodePtr(node2Ptr);
|
DescendNodePtr(node2Ptr);
|
||||||
--stackDepth;
|
--stackDepth;
|
||||||
|
|
||||||
|
// Restore old texture offsets
|
||||||
|
texOffset[0] = oldTexOffsetX;
|
||||||
|
texOffset[1] = oldTexOffsetY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A list of pointers. MAME assumes that these may only point to culling nodes.
|
// A list of pointers. MAME assumes that these may only point to culling nodes.
|
||||||
|
@ -1098,6 +1118,10 @@ void CRender3D::RenderViewport(UINT32 addr, int pri)
|
||||||
//printf("scrollFog = %g, scrollAtt = %g\n", scrollFog, scrollAtt);
|
//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]);
|
//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]);
|
||||||
|
|
||||||
|
// Clear texture offsets before proceeding
|
||||||
|
texOffset[0] = 0.0;
|
||||||
|
texOffset[1] = 0.0;
|
||||||
|
|
||||||
// Set up coordinate system and base matrix
|
// Set up coordinate system and base matrix
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
InitMatrixStack(matrixBase);
|
InitMatrixStack(matrixBase);
|
||||||
|
@ -1305,6 +1329,7 @@ BOOL CRender3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
|
||||||
spotEllipseLoc = glGetUniformLocation(shaderProgram, "spotEllipse");
|
spotEllipseLoc = glGetUniformLocation(shaderProgram, "spotEllipse");
|
||||||
spotRangeLoc = glGetUniformLocation(shaderProgram, "spotRange");
|
spotRangeLoc = glGetUniformLocation(shaderProgram, "spotRange");
|
||||||
spotColorLoc = glGetUniformLocation(shaderProgram, "spotColor");
|
spotColorLoc = glGetUniformLocation(shaderProgram, "spotColor");
|
||||||
|
texOffsetLoc = glGetUniformLocation(shaderProgram, "texOffset");
|
||||||
|
|
||||||
// Get locations of custom vertex attributes
|
// Get locations of custom vertex attributes
|
||||||
subTextureLoc = glGetAttribLocation(shaderProgram,"subTexture");
|
subTextureLoc = glGetAttribLocation(shaderProgram,"subTexture");
|
||||||
|
|
|
@ -92,6 +92,7 @@ struct DisplayList
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
GLfloat modelViewMatrix[4*4]; // model-view matrix
|
GLfloat modelViewMatrix[4*4]; // model-view matrix
|
||||||
|
GLfloat texOffset[2]; // texture offset (X, Y)
|
||||||
unsigned index; // index in VBO
|
unsigned index; // index in VBO
|
||||||
unsigned numVerts; // number of vertices
|
unsigned numVerts; // number of vertices
|
||||||
} Model;
|
} Model;
|
||||||
|
@ -357,6 +358,9 @@ private:
|
||||||
int listDepth; // how many lists have we recursed into
|
int listDepth; // how many lists have we recursed into
|
||||||
int stackDepth; // for debugging and error handling purposes
|
int stackDepth; // for debugging and error handling purposes
|
||||||
|
|
||||||
|
// Texture offset (during scene graph processing)
|
||||||
|
GLfloat texOffset[2]; // X, Y
|
||||||
|
|
||||||
// Resolution scaling factors (to support resolutions higher than 496x384) and offsets
|
// Resolution scaling factors (to support resolutions higher than 496x384) and offsets
|
||||||
GLfloat xRatio, yRatio;
|
GLfloat xRatio, yRatio;
|
||||||
unsigned xOffs, yOffs;
|
unsigned xOffs, yOffs;
|
||||||
|
@ -375,6 +379,7 @@ private:
|
||||||
GLuint spotEllipseLoc; // uniform
|
GLuint spotEllipseLoc; // uniform
|
||||||
GLuint spotRangeLoc; // uniform
|
GLuint spotRangeLoc; // uniform
|
||||||
GLuint spotColorLoc; // uniform
|
GLuint spotColorLoc; // uniform
|
||||||
|
GLuint texOffsetLoc; // uniform
|
||||||
GLuint subTextureLoc; // attribute
|
GLuint subTextureLoc; // attribute
|
||||||
GLuint texParamsLoc; // attribute
|
GLuint texParamsLoc; // attribute
|
||||||
GLuint texFormatLoc; // attribute
|
GLuint texFormatLoc; // attribute
|
||||||
|
|
|
@ -34,6 +34,7 @@ uniform vec3 lighting[2]; // lighting state (lighting[0] = sun direction, light
|
||||||
uniform vec4 spotEllipse; // spotlight ellipse position: .x=X position (normalized device coordinates), .y=Y position, .z=half-width, .w=half-height)
|
uniform vec4 spotEllipse; // spotlight ellipse position: .x=X position (normalized device coordinates), .y=Y position, .z=half-width, .w=half-height)
|
||||||
uniform vec2 spotRange; // spotlight Z range: .x=start (viewspace coordinates), .y=limit
|
uniform vec2 spotRange; // spotlight Z range: .x=start (viewspace coordinates), .y=limit
|
||||||
uniform vec3 spotColor; // spotlight RGB color
|
uniform vec3 spotColor; // spotlight RGB color
|
||||||
|
uniform vec2 texOffset; // offset (within 2048x2048 texture sheet) to apply to texture base coordinates
|
||||||
|
|
||||||
// Custom vertex attributes
|
// Custom vertex attributes
|
||||||
attribute vec4 subTexture; // .x=texture X, .y=texture Y, .z=texture width, .w=texture height (all in texels)
|
attribute vec4 subTexture; // .x=texture X, .y=texture Y, .z=texture width, .w=texture height (all in texels)
|
||||||
|
@ -138,6 +139,7 @@ void main(void)
|
||||||
// Pass remaining parameters to fragment shader
|
// Pass remaining parameters to fragment shader
|
||||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
fsSubTexture = subTexture;
|
fsSubTexture = subTexture;
|
||||||
|
fsSubTexture.xy += texOffset; // apply texture offset
|
||||||
fsTexParams = texParams;
|
fsTexParams = texParams;
|
||||||
fsTransLevel = transLevel;
|
fsTransLevel = transLevel;
|
||||||
fsTexFormat = texFormat;
|
fsTexFormat = texFormat;
|
||||||
|
|
Loading…
Reference in a new issue