From 5c8421d410573f11370c545ae13235f116bf5137 Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Fri, 8 Nov 2019 00:03:31 -0500 Subject: [PATCH] Palette mirror fix (#81) * ppuview and memview fixes for palette mirroring * New PPU $2001 rendering off palette mirroring fixed --- src/debug.h | 2 +- src/drivers/win/memview.cpp | 31 +++++++++++++++++++++++++++---- src/drivers/win/ppuview.cpp | 22 +++++++++++----------- src/ppu.cpp | 2 +- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/debug.h b/src/debug.h index 21aa3774..9c25b376 100644 --- a/src/debug.h +++ b/src/debug.h @@ -113,7 +113,7 @@ extern void IncrementInstructionsCounters(); //internal variables that debuggers will want access to 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 uint8 READPAL_MOTHEROFALL(uint32 A); extern int numWPs; diff --git a/src/drivers/win/memview.cpp b/src/drivers/win/memview.cpp index 60ef4f35..682ba7cf 100644 --- a/src/drivers/win/memview.cpp +++ b/src/drivers/win/memview.cpp @@ -147,6 +147,7 @@ void FindNext(); void OpenFindDialog(); static int GetFileData(uint32 offset); static int WriteFileData(uint32 offset,int data); +static void PalettePoke(uint32 addr, uint8 data); HWND hMemView, hMemFind; @@ -1013,7 +1014,7 @@ void InputData(char *input){ 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? if((addr >= 0x3F00) && (addr < 0x3FFF)) - PALRAM[addr&0x1F] = data[i]; + PalettePoke(addr,data[i]); } else if (EditingMode == MODE_NES_OAM) { addr &= 0xFF; @@ -1049,7 +1050,7 @@ if(EditingMode == MODE_NES_PPU){ 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) && (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); CursorStartAddy++; @@ -1915,7 +1916,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa i &= 0x3FFF; if(i < 0x2000) bar[i] = VPage[(i)>>10][(i)]; 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)); return 0; @@ -1952,7 +1953,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa if((addr >= 0x2000) && (addr < 0x3F00)) vnapage[(addr>>10)&0x3][addr&0x3FF] = v; //todo: this causes 0x3000-0x3f00 to mirror 0x2000-0x2f00, is this correct? if((addr >= 0x3F00) && (addr < 0x3FFF)) - PALRAM[addr&0x1F] = v; + PalettePoke(addr,v); } } return 0; @@ -2394,3 +2395,25 @@ void OpenFindDialog() hMemFind = CreateDialog(fceu_hInstance,"MEMVIEWFIND",hMemView,MemFindCallB); 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; + } +} diff --git a/src/drivers/win/ppuview.cpp b/src/drivers/win/ppuview.cpp index 140c94fe..95dbb55a 100644 --- a/src/drivers/win/ppuview.cpp +++ b/src/drivers/win/ppuview.cpp @@ -29,13 +29,15 @@ HWND hPPUView; extern uint8 *VPage[8]; extern uint8 PALRAM[0x20]; +extern uint8 UPALRAM[3]; int PPUViewPosX, PPUViewPosY; bool PPUView_maskUnusedGraphics = true; bool PPUView_invertTheMask = false; 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 *pattern0, *pattern1; //pattern table bitmap arrays uint8 *ppuv_palette; @@ -177,18 +179,17 @@ void FCEUD_UpdatePPUView(int scanline, int refreshchr) } // 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 - // will not work because of the lines below that change - // palcache which will make it not equal next time + memcpy(pallast, PALRAM, 32); + memcpy(pallast+32, UPALRAM, 3); // cache palette content memcpy(palcache,PALRAM,32); palcache[0x10] = palcache[0x00]; - palcache[0x14] = palcache[0x00]; - palcache[0x18] = palcache[0x00]; - palcache[0x1C] = palcache[0x00]; + palcache[0x04] = palcache[0x14] = UPALRAM[0]; + palcache[0x08] = palcache[0x18] = UPALRAM[1]; + palcache[0x0C] = palcache[0x1C] = UPALRAM[2]; //draw palettes for (y = 0; y < PALETTEHEIGHT; y++) @@ -220,7 +221,6 @@ void FCEUD_UpdatePPUView(int scanline, int refreshchr) } pbitmap += ((32*4*3)-6); } - memcpy(palcache,PALRAM,32); //palcache which will make it not equal next time } DrawPatternTable(pattern0,chrcache0,logcache0,pindex0); @@ -428,7 +428,8 @@ INT_PTR CALLBACK PPUViewCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa PPUViewSkip=100; //clear cache - memset(palcache,0,32); + memset(pallast,0,32+3); + memset(palcache,0,36); memset(chrcache0,0,0x1000); memset(chrcache1,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_y = (mouse_y - paletteDestY) / 32; 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]); SetDlgItemText(hwndDlg,LBL_PPUVIEW_TILE1,"Tile:"); SetDlgItemText(hwndDlg,LBL_PPUVIEW_TILE2,"Tile:"); diff --git a/src/ppu.cpp b/src/ppu.cpp index 1e56098c..5aa5aee3 100644 --- a/src/ppu.cpp +++ b/src/ppu.cpp @@ -2198,7 +2198,7 @@ int FCEUX_PPU_Loop(int skip) { { pixel = addr & 0x1F; } - pixelcolor = PALRAM[pixel]; + pixelcolor = READPAL_MOTHEROFALL(pixel); } //generate the BG data