mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-03-06 14:27:44 +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
|
||||
******************************************************************************/
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue