Palette mirror fix (#81)

* ppuview and memview fixes for palette mirroring
* New PPU $2001 rendering off palette mirroring fixed
This commit is contained in:
Brad Smith 2019-11-08 00:03:31 -05:00 committed by GitHub
parent 25c0b96c30
commit 5c8421d410
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 17 deletions

View File

@ -113,7 +113,7 @@ extern void IncrementInstructionsCounters();
//internal variables that debuggers will want access to //internal variables that debuggers will want access to
extern uint8 *vnapage[4],*VPage[8]; extern uint8 *vnapage[4],*VPage[8];
extern uint8 PPU[4],PALRAM[0x20],SPRAM[0x100],VRAMBuffer,PPUGenLatch,XOffset; extern uint8 PPU[4],PALRAM[0x20],UPALRAM[3],SPRAM[0x100],VRAMBuffer,PPUGenLatch,XOffset;
extern uint32 FCEUPPU_PeekAddress(); extern uint32 FCEUPPU_PeekAddress();
extern uint8 READPAL_MOTHEROFALL(uint32 A); extern uint8 READPAL_MOTHEROFALL(uint32 A);
extern int numWPs; extern int numWPs;

View File

@ -147,6 +147,7 @@ void FindNext();
void OpenFindDialog(); void OpenFindDialog();
static int GetFileData(uint32 offset); static int GetFileData(uint32 offset);
static int WriteFileData(uint32 offset,int data); static int WriteFileData(uint32 offset,int data);
static void PalettePoke(uint32 addr, uint8 data);
HWND hMemView, hMemFind; HWND hMemView, hMemFind;
@ -1013,7 +1014,7 @@ void InputData(char *input){
if((addr >= 0x2000) && (addr < 0x3F00)) if((addr >= 0x2000) && (addr < 0x3F00))
vnapage[(addr>>10)&0x3][addr&0x3FF] = data[i]; //todo: this causes 0x3000-0x3f00 to mirror 0x2000-0x2f00, is this correct? vnapage[(addr>>10)&0x3][addr&0x3FF] = data[i]; //todo: this causes 0x3000-0x3f00 to mirror 0x2000-0x2f00, is this correct?
if((addr >= 0x3F00) && (addr < 0x3FFF)) if((addr >= 0x3F00) && (addr < 0x3FFF))
PALRAM[addr&0x1F] = data[i]; PalettePoke(addr,data[i]);
} else if (EditingMode == MODE_NES_OAM) } else if (EditingMode == MODE_NES_OAM)
{ {
addr &= 0xFF; addr &= 0xFF;
@ -1049,7 +1050,7 @@ if(EditingMode == MODE_NES_PPU){
addr &= 0x3FFF; addr &= 0x3FFF;
if(addr < 0x2000)VPage[addr>>10][addr] = data; //todo: detect if this is vrom and turn it red if so if(addr < 0x2000)VPage[addr>>10][addr] = data; //todo: detect if this is vrom and turn it red if so
if((addr > 0x2000) && (addr < 0x3F00))vnapage[(addr>>10)&0x3][addr&0x3FF] = data; //todo: this causes 0x3000-0x3f00 to mirror 0x2000-0x2f00, is this correct? if((addr > 0x2000) && (addr < 0x3F00))vnapage[(addr>>10)&0x3][addr&0x3FF] = data; //todo: this causes 0x3000-0x3f00 to mirror 0x2000-0x2f00, is this correct?
if((addr > 0x3F00) && (addr < 0x3FFF))PALRAM[addr&0x1F] = data; if((addr > 0x3F00) && (addr < 0x3FFF)) PalettePoke(addr,data);
} }
if(EditingMode == MODE_NES_FILE)ApplyPatch(addr,1,(uint8 *)&data); if(EditingMode == MODE_NES_FILE)ApplyPatch(addr,1,(uint8 *)&data);
CursorStartAddy++; CursorStartAddy++;
@ -1915,7 +1916,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
i &= 0x3FFF; i &= 0x3FFF;
if(i < 0x2000) bar[i] = VPage[(i)>>10][(i)]; if(i < 0x2000) bar[i] = VPage[(i)>>10][(i)];
else if(i < 0x3F00) bar[i] = vnapage[(i>>10)&0x3][i&0x3FF]; else if(i < 0x3F00) bar[i] = vnapage[(i>>10)&0x3][i&0x3FF];
else bar[i] = PALRAM[i&0x1F]; else bar[i] = READPAL_MOTHEROFALL(i & 0x1F);
} }
dumpToFile(bar, sizeof(bar)); dumpToFile(bar, sizeof(bar));
return 0; return 0;
@ -1952,7 +1953,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
if((addr >= 0x2000) && (addr < 0x3F00)) if((addr >= 0x2000) && (addr < 0x3F00))
vnapage[(addr>>10)&0x3][addr&0x3FF] = v; //todo: this causes 0x3000-0x3f00 to mirror 0x2000-0x2f00, is this correct? vnapage[(addr>>10)&0x3][addr&0x3FF] = v; //todo: this causes 0x3000-0x3f00 to mirror 0x2000-0x2f00, is this correct?
if((addr >= 0x3F00) && (addr < 0x3FFF)) if((addr >= 0x3F00) && (addr < 0x3FFF))
PALRAM[addr&0x1F] = v; PalettePoke(addr,v);
} }
} }
return 0; return 0;
@ -2394,3 +2395,25 @@ void OpenFindDialog()
hMemFind = CreateDialog(fceu_hInstance,"MEMVIEWFIND",hMemView,MemFindCallB); hMemFind = CreateDialog(fceu_hInstance,"MEMVIEWFIND",hMemView,MemFindCallB);
return; return;
} }
void PalettePoke(uint32 addr, uint8 data)
{
data = data & 0x3F;
addr = addr & 0x1F;
if ((addr & 3) == 0)
{
addr = (addr & 0xC) >> 2;
if (addr == 0)
{
PALRAM[0x00] = PALRAM[0x04] = PALRAM[0x08] = PALRAM[0x0C] = data;
}
else
{
UPALRAM[addr-1] = UPALRAM[0x10|(addr-1)] = data;
}
}
else
{
PALRAM[addr] = data;
}
}

View File

@ -29,13 +29,15 @@ HWND hPPUView;
extern uint8 *VPage[8]; extern uint8 *VPage[8];
extern uint8 PALRAM[0x20]; extern uint8 PALRAM[0x20];
extern uint8 UPALRAM[3];
int PPUViewPosX, PPUViewPosY; int PPUViewPosX, PPUViewPosY;
bool PPUView_maskUnusedGraphics = true; bool PPUView_maskUnusedGraphics = true;
bool PPUView_invertTheMask = false; bool PPUView_invertTheMask = false;
int PPUView_sprite16Mode = 0; int PPUView_sprite16Mode = 0;
static uint8 palcache[36] = { 0xFF }; //palette cache static uint8 pallast[32+3] = { 0 }; // palette cache for change comparison
static uint8 palcache[36] = { 0 }; //palette cache for drawing
uint8 chrcache0[0x1000], chrcache1[0x1000], logcache0[0x1000], logcache1[0x1000]; //cache CHR, fixes a refresh problem when right-clicking uint8 chrcache0[0x1000], chrcache1[0x1000], logcache0[0x1000], logcache1[0x1000]; //cache CHR, fixes a refresh problem when right-clicking
uint8 *pattern0, *pattern1; //pattern table bitmap arrays uint8 *pattern0, *pattern1; //pattern table bitmap arrays
uint8 *ppuv_palette; uint8 *ppuv_palette;
@ -177,18 +179,17 @@ void FCEUD_UpdatePPUView(int scanline, int refreshchr)
} }
// update palette only if required // update palette only if required
if (memcmp(palcache, PALRAM, 32) != 0) if ((memcmp(pallast, PALRAM, 32) != 0) || (memcmp(pallast+32, UPALRAM, 3) != 0))
{ {
// bbit note: let para know that this if is useless and memcpy(pallast, PALRAM, 32);
// will not work because of the lines below that change memcpy(pallast+32, UPALRAM, 3);
// palcache which will make it not equal next time
// cache palette content // cache palette content
memcpy(palcache,PALRAM,32); memcpy(palcache,PALRAM,32);
palcache[0x10] = palcache[0x00]; palcache[0x10] = palcache[0x00];
palcache[0x14] = palcache[0x00]; palcache[0x04] = palcache[0x14] = UPALRAM[0];
palcache[0x18] = palcache[0x00]; palcache[0x08] = palcache[0x18] = UPALRAM[1];
palcache[0x1C] = palcache[0x00]; palcache[0x0C] = palcache[0x1C] = UPALRAM[2];
//draw palettes //draw palettes
for (y = 0; y < PALETTEHEIGHT; y++) for (y = 0; y < PALETTEHEIGHT; y++)
@ -220,7 +221,6 @@ void FCEUD_UpdatePPUView(int scanline, int refreshchr)
} }
pbitmap += ((32*4*3)-6); pbitmap += ((32*4*3)-6);
} }
memcpy(palcache,PALRAM,32); //palcache which will make it not equal next time
} }
DrawPatternTable(pattern0,chrcache0,logcache0,pindex0); DrawPatternTable(pattern0,chrcache0,logcache0,pindex0);
@ -428,7 +428,8 @@ INT_PTR CALLBACK PPUViewCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
PPUViewSkip=100; PPUViewSkip=100;
//clear cache //clear cache
memset(palcache,0,32); memset(pallast,0,32+3);
memset(palcache,0,36);
memset(chrcache0,0,0x1000); memset(chrcache0,0,0x1000);
memset(chrcache1,0,0x1000); memset(chrcache1,0,0x1000);
memset(logcache0,0,0x1000); memset(logcache0,0,0x1000);
@ -537,7 +538,6 @@ INT_PTR CALLBACK PPUViewCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
mouse_x = (mouse_x - paletteDestX) / 32; mouse_x = (mouse_x - paletteDestX) / 32;
mouse_y = (mouse_y - paletteDestY) / 32; mouse_y = (mouse_y - paletteDestY) / 32;
int ix = (mouse_y<<4)|mouse_x; int ix = (mouse_y<<4)|mouse_x;
if ((ix & 0x10) && !(ix & 0x03)) ix = 0; // palcache 0x10/14/18/1C is bogus $00 values
sprintf(str,"Palette: $%02X",palcache[ix]); sprintf(str,"Palette: $%02X",palcache[ix]);
SetDlgItemText(hwndDlg,LBL_PPUVIEW_TILE1,"Tile:"); SetDlgItemText(hwndDlg,LBL_PPUVIEW_TILE1,"Tile:");
SetDlgItemText(hwndDlg,LBL_PPUVIEW_TILE2,"Tile:"); SetDlgItemText(hwndDlg,LBL_PPUVIEW_TILE2,"Tile:");

View File

@ -2198,7 +2198,7 @@ int FCEUX_PPU_Loop(int skip) {
{ {
pixel = addr & 0x1F; pixel = addr & 0x1F;
} }
pixelcolor = PALRAM[pixel]; pixelcolor = READPAL_MOTHEROFALL(pixel);
} }
//generate the BG data //generate the BG data