fix matrix stacks better (re: #39). fixes broken mario 64 head

This commit is contained in:
zeromus 2017-02-22 00:26:03 -06:00
parent 1cc22ae2aa
commit b553ff917b
1 changed files with 23 additions and 41 deletions

View File

@ -943,17 +943,14 @@ static void gfx3d_glMatrixMode(u32 v)
static void gfx3d_glPushMatrix() static void gfx3d_glPushMatrix()
{ {
//in case we're in Position-Vector mode, actually work on the Position matrix first (we'll update the vector matrix secondarily)
const MatrixMode mymode = ((mode == MATRIXMODE_POSITION_VECTOR) ? MATRIXMODE_POSITION : mode);
//1. apply offset specified by push (well, it's always +1) to internal counter //1. apply offset specified by push (well, it's always +1) to internal counter
//2. mask that bit off to actually index the matrix for reading //2. mask that bit off to actually index the matrix for reading
//3. SE is set depending on resulting internal counter //3. SE is set depending on resulting internal counter
if(mymode == MATRIXMODE_PROJECTION || mymode == MATRIXMODE_TEXTURE) if(mode == MATRIXMODE_PROJECTION || mode == MATRIXMODE_TEXTURE)
{ {
u32& index = mtxStack[mymode].position; u32& index = mtxStack[mode].position;
MatrixCopy(MatrixStackGetPos(&mtxStack[mymode], index&1), mtxCurrent[mymode]); MatrixCopy(MatrixStackGetPos(&mtxStack[mode], index&1), mtxCurrent[mode]);
index += 1; index += 1;
index &= 3; index &= 3;
@ -962,10 +959,9 @@ static void gfx3d_glPushMatrix()
else else
{ {
u32& index = mtxStack[MATRIXMODE_POSITION].position; u32& index = mtxStack[MATRIXMODE_POSITION].position;
MatrixCopy(MatrixStackGetPos(&mtxStack[MATRIXMODE_POSITION], index&31), mtxCurrent[MATRIXMODE_POSITION]); MatrixCopy(MatrixStackGetPos(&mtxStack[MATRIXMODE_POSITION], index&31), mtxCurrent[MATRIXMODE_POSITION]);
MatrixCopy(MatrixStackGetPos(&mtxStack[MATRIXMODE_POSITION_VECTOR], index&31), mtxCurrent[MATRIXMODE_POSITION_VECTOR]);
if(mode == MATRIXMODE_POSITION_VECTOR)
MatrixCopy(MatrixStackGetPos(&mtxStack[MATRIXMODE_POSITION_VECTOR], index&31), mtxCurrent[MATRIXMODE_POSITION_VECTOR]);
index += 1; index += 1;
index &= 63; index &= 63;
@ -975,40 +971,35 @@ static void gfx3d_glPushMatrix()
GFX_DELAY(17); GFX_DELAY(17);
} }
static void gfx3d_glPopMatrix(s32 v) static void gfx3d_glPopMatrix(u32 v)
{ {
//in case we're in Position-Vector mode, actually work on the Position matrix first (we'll update the vector matrix secondarily)
const MatrixMode mymode = ((mode == MATRIXMODE_POSITION_VECTOR) ? MATRIXMODE_POSITION : mode);
//1. apply offset specified by pop to internal counter //1. apply offset specified by pop to internal counter
//2. SE is set depending on resulting internal counter //2. SE is set depending on resulting internal counter
//3. mask that bit off to actually index the matrix for reading //3. mask that bit off to actually index the matrix for reading
if(mymode == MATRIXMODE_PROJECTION || mymode == MATRIXMODE_TEXTURE) if(mode == MATRIXMODE_PROJECTION || mode == MATRIXMODE_TEXTURE)
{ {
//parameter ignored and treated as sensible, as a pop argument anyway //parameter ignored and treated as sensible, as a pop argument anyway
v = 1; v = 1;
u32& index = mtxStack[mymode].position; u32& index = mtxStack[mode].position;
index -= v; index -= v;
index &= 3; index &= 3;
if(index >= 2) MMU_new.gxstat.se = 1; //unknown if this applies to the texture matrix if(index >= 2) MMU_new.gxstat.se = 1; //unknown if this applies to the texture matrix
MatrixCopy(mtxCurrent[mymode], MatrixStackGetPos(&mtxStack[mymode], index&1)); MatrixCopy(mtxCurrent[mode], MatrixStackGetPos(&mtxStack[mode], index&1));
} }
else else
{ {
u32& index = mtxStack[MATRIXMODE_POSITION].position; u32& index = mtxStack[MATRIXMODE_POSITION].position;
index -= v; index -= v & 63;
index &= 63; index &= 63;
if(index >= 32) MMU_new.gxstat.se = 1; if(index >= 32) MMU_new.gxstat.se = 1;
MatrixCopy(mtxCurrent[MATRIXMODE_POSITION], MatrixStackGetPos(&mtxStack[MATRIXMODE_POSITION], index&31)); MatrixCopy(mtxCurrent[MATRIXMODE_POSITION], MatrixStackGetPos(&mtxStack[MATRIXMODE_POSITION], index&31));
MatrixCopy(mtxCurrent[MATRIXMODE_POSITION_VECTOR], MatrixStackGetPos(&mtxStack[MATRIXMODE_POSITION_VECTOR], index&31));
if(mode == MATRIXMODE_POSITION_VECTOR)
MatrixCopy(mtxCurrent[MATRIXMODE_POSITION_VECTOR], MatrixStackGetPos(&mtxStack[MATRIXMODE_POSITION_VECTOR], index&31));
} }
GFX_DELAY(36); GFX_DELAY(36);
@ -1016,53 +1007,44 @@ static void gfx3d_glPopMatrix(s32 v)
static void gfx3d_glStoreMatrix(u32 v) static void gfx3d_glStoreMatrix(u32 v)
{ {
//in case we're in Position-Vector mode, actually work on the Position matrix first (we'll update the vector matrix secondarily) if(mode == MATRIXMODE_PROJECTION || mode == MATRIXMODE_TEXTURE)
const MatrixMode mymode = ((mode == MATRIXMODE_POSITION_VECTOR) ? MATRIXMODE_POSITION : mode);
if(mymode == MATRIXMODE_PROJECTION || mymode == MATRIXMODE_TEXTURE)
{ {
//parameter ignored and treated as sensible //parameter ignored and treated as sensible
v = 0; v = 0;
MatrixStackLoadMatrix(&mtxStack[mode], v, mtxCurrent[mode]);
} }
else else
{ {
v &= 31;
//out of bounds function fully properly, but set errors //out of bounds function fully properly, but set errors
if(v >= 31) MMU_new.gxstat.se = 1; if(v >= 31) MMU_new.gxstat.se = 1;
}
//the counter is [0,63] but only the bottom 5 bits index the stack MatrixStackLoadMatrix(&mtxStack[MATRIXMODE_POSITION], v, mtxCurrent[MATRIXMODE_POSITION]);
v &= 31;
MatrixStackLoadMatrix(&mtxStack[mymode], v, mtxCurrent[mymode]);
//apply to Position-Vector matrix too, if appropriate
if (mode == MATRIXMODE_POSITION_VECTOR)
MatrixStackLoadMatrix(&mtxStack[MATRIXMODE_POSITION_VECTOR], v, mtxCurrent[MATRIXMODE_POSITION_VECTOR]); MatrixStackLoadMatrix(&mtxStack[MATRIXMODE_POSITION_VECTOR], v, mtxCurrent[MATRIXMODE_POSITION_VECTOR]);
}
GFX_DELAY(17); GFX_DELAY(17);
} }
static void gfx3d_glRestoreMatrix(u32 v) static void gfx3d_glRestoreMatrix(u32 v)
{ {
//in case we're in Position-Vector mode, actually work on the Position matrix first (we'll update the vector matrix secondarily) if(mode == MATRIXMODE_PROJECTION || mode == MATRIXMODE_TEXTURE)
const MatrixMode mymode = ((mode == MATRIXMODE_POSITION_VECTOR) ? MATRIXMODE_POSITION : mode);
if(mymode == MATRIXMODE_PROJECTION || mymode == MATRIXMODE_TEXTURE)
{ {
//parameter ignored and treated as sensible //parameter ignored and treated as sensible
v = 0; v = 0;
MatrixCopy(mtxCurrent[mode], MatrixStackGetPos(&mtxStack[mode], v));
} }
else else
{ {
//out of bounds errors function fully properly, but set errors //out of bounds errors function fully properly, but set errors
MMU_new.gxstat.se = v>=31; MMU_new.gxstat.se = v>=31;
MatrixCopy(mtxCurrent[MATRIXMODE_POSITION], MatrixStackGetPos(&mtxStack[MATRIXMODE_POSITION], v));
MatrixCopy(mtxCurrent[MATRIXMODE_POSITION_VECTOR], MatrixStackGetPos(&mtxStack[MATRIXMODE_POSITION_VECTOR], v));
} }
MatrixCopy(mtxCurrent[mymode], MatrixStackGetPos(&mtxStack[mymode], v));
//apply to Position-Vector matrix too, if appropriate
if (mode == MATRIXMODE_POSITION_VECTOR)
MatrixCopy(mtxCurrent[MATRIXMODE_POSITION_VECTOR], MatrixStackGetPos(&mtxStack[MATRIXMODE_POSITION_VECTOR], v));
GFX_DELAY(36); GFX_DELAY(36);
} }