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:
Bart Trzynadlowski 2011-07-04 20:53:37 +00:00
parent 97ac46c82a
commit cd2621b2ce
5 changed files with 75 additions and 16 deletions

View file

@ -737,11 +737,27 @@ void CRender2D::EndFrame(void)
Emulation Callbacks
******************************************************************************/
void CRender2D::WritePalette(unsigned color, UINT32 data)
{
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)
{
unsigned color;
UINT8 r, g, b, a;
if (vram[addr/4] == data) // do nothing if no changes
return;
@ -751,21 +767,29 @@ void CRender2D::WriteVRAM(unsigned addr, UINT32 data)
// Palette
if (addr >= 0x100000)
{
color = (addr-0x100000)/4; // color index
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;
unsigned color = (addr-0x100000)/4; // color index
WritePalette(color, data);
}
}
/*
* 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)
{
for (int i = 0; i < 0x20000/4; i++)
WritePalette(i, vram[0x100000/4 + i]);
}
/******************************************************************************
Configuration, Initialization, and Shutdown
@ -780,6 +804,7 @@ void CRender2D::AttachRegisters(const UINT32 *regPtr)
void CRender2D::AttachVRAM(const UINT8 *vramPtr)
{
vram = (UINT32 *) vramPtr;
InitPalette();
DebugLog("Render2D attached VRAM\n");
}

View file

@ -145,6 +145,8 @@ private:
void DisplayLayer(int layerNum, GLfloat z);
void Setup2D(void);
void ColorOffset(GLfloat colorOffset[3], UINT32 reg);
void WritePalette(unsigned color, UINT32 data);
void InitPalette(void);
// Data received from tile generator device object
const UINT32 *vram;

View file

@ -188,6 +188,9 @@ void CRender3D::DecodeTexture(int format, int x, int y, int width, int height)
UINT16 texel;
GLfloat c, a;
x %= 2048;
y %= 2048;
if ((x+width)>2048 || (y+height)>2048)
return;
if (width > 512 || height > 512)
@ -662,7 +665,8 @@ void CRender3D::DescendCullingNode(UINT32 addr)
{
const UINT32 *node, *lodTable;
UINT32 matrixOffset, node1Ptr, node2Ptr;
float x, y, z;
float x, y, z, oldTexOffsetX, oldTexOffsetY;
int tx, ty;
++stackDepth;
// 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];
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
glPushMatrix();
if ((node[0x00]&0x10)) // apply translation vector
@ -717,6 +733,10 @@ void CRender3D::DescendCullingNode(UINT32 addr)
glPopMatrix();
DescendNodePtr(node2Ptr);
--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.
@ -1098,6 +1118,10 @@ void CRender3D::RenderViewport(UINT32 addr, int pri)
//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]);
// Clear texture offsets before proceeding
texOffset[0] = 0.0;
texOffset[1] = 0.0;
// Set up coordinate system and base matrix
glMatrixMode(GL_MODELVIEW);
InitMatrixStack(matrixBase);
@ -1305,6 +1329,7 @@ BOOL CRender3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
spotEllipseLoc = glGetUniformLocation(shaderProgram, "spotEllipse");
spotRangeLoc = glGetUniformLocation(shaderProgram, "spotRange");
spotColorLoc = glGetUniformLocation(shaderProgram, "spotColor");
texOffsetLoc = glGetUniformLocation(shaderProgram, "texOffset");
// Get locations of custom vertex attributes
subTextureLoc = glGetAttribLocation(shaderProgram,"subTexture");

View file

@ -92,6 +92,7 @@ struct DisplayList
struct
{
GLfloat modelViewMatrix[4*4]; // model-view matrix
GLfloat texOffset[2]; // texture offset (X, Y)
unsigned index; // index in VBO
unsigned numVerts; // number of vertices
} Model;
@ -357,6 +358,9 @@ private:
int listDepth; // how many lists have we recursed into
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
GLfloat xRatio, yRatio;
unsigned xOffs, yOffs;
@ -375,6 +379,7 @@ private:
GLuint spotEllipseLoc; // uniform
GLuint spotRangeLoc; // uniform
GLuint spotColorLoc; // uniform
GLuint texOffsetLoc; // uniform
GLuint subTextureLoc; // attribute
GLuint texParamsLoc; // attribute
GLuint texFormatLoc; // attribute

View file

@ -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 vec2 spotRange; // spotlight Z range: .x=start (viewspace coordinates), .y=limit
uniform vec3 spotColor; // spotlight RGB color
uniform vec2 texOffset; // offset (within 2048x2048 texture sheet) to apply to texture base coordinates
// Custom vertex attributes
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
gl_TexCoord[0] = gl_MultiTexCoord0;
fsSubTexture = subTexture;
fsSubTexture.xy += texOffset; // apply texture offset
fsTexParams = texParams;
fsTransLevel = transLevel;
fsTexFormat = texFormat;