newppu - process grayscale (and maybe deemph, not sure) on a per-pixel basis to fix the FF1 polygon effect (fixes #529)

This commit is contained in:
zeromus 2022-08-22 22:43:26 -04:00
parent 77b18ba989
commit 41feba2074
1 changed files with 51 additions and 11 deletions

View File

@ -57,6 +57,7 @@
#define PPU_status (PPU[2]) #define PPU_status (PPU[2])
#define READPALNOGS(ofs) (PALRAM[(ofs)])
#define READPAL(ofs) (PALRAM[(ofs)] & (GRAYSCALE ? 0x30 : 0xFF)) #define READPAL(ofs) (PALRAM[(ofs)] & (GRAYSCALE ? 0x30 : 0xFF))
#define READUPAL(ofs) (UPALRAM[(ofs)] & (GRAYSCALE ? 0x30 : 0xFF)) #define READUPAL(ofs) (UPALRAM[(ofs)] & (GRAYSCALE ? 0x30 : 0xFF))
@ -1987,6 +1988,7 @@ void runppu(int x) {
struct BGData { struct BGData {
struct Record { struct Record {
uint8 nt, pecnt, at, pt[2], qtnt; uint8 nt, pecnt, at, pt[2], qtnt;
uint8 ppu1[8];
INLINE void Read() { INLINE void Read() {
NTRefreshAddr = RefreshAddr = ppur.get_ntread(); NTRefreshAddr = RefreshAddr = ppur.get_ntread();
@ -1998,7 +2000,12 @@ struct BGData {
} }
pecnt = (RefreshAddr & 1) << 3; pecnt = (RefreshAddr & 1) << 3;
nt = CALL_PPUREAD(RefreshAddr); nt = CALL_PPUREAD(RefreshAddr);
runppu(kFetchTime); ppu1[0] = PPU[1];
runppu(1);
ppu1[1] = PPU[1];
runppu(1);
RefreshAddr = ppur.get_atread(); RefreshAddr = ppur.get_atread();
at = CALL_PPUREAD(RefreshAddr); at = CALL_PPUREAD(RefreshAddr);
@ -2010,37 +2017,57 @@ struct BGData {
at <<= 2; at <<= 2;
//horizontal scroll clocked at cycle 3 and then //horizontal scroll clocked at cycle 3 and then
//vertical scroll at 251 //vertical scroll at 251
ppu1[2] = PPU[1];
runppu(1); runppu(1);
if (PPUON) { if (PPUON) {
ppur.increment_hsc(); ppur.increment_hsc();
if (ppur.status.cycle == 251) if (ppur.status.cycle == 251)
ppur.increment_vs(); ppur.increment_vs();
} }
ppu1[3] = PPU[1];
runppu(1); runppu(1);
ppur.par = nt; ppur.par = nt;
RefreshAddr = ppur.get_ptread(); RefreshAddr = ppur.get_ptread();
if (PEC586Hack) { if (PEC586Hack) {
pt[0] = CALL_PPUREAD(RefreshAddr | pecnt); pt[0] = CALL_PPUREAD(RefreshAddr | pecnt);
runppu(kFetchTime); ppu1[4] = PPU[1];
runppu(1);
ppu1[5] = PPU[1];
runppu(1);
pt[1] = CALL_PPUREAD(RefreshAddr | pecnt); pt[1] = CALL_PPUREAD(RefreshAddr | pecnt);
runppu(kFetchTime); ppu1[6] = PPU[1];
runppu(1);
ppu1[7] = PPU[1];
runppu(1);
} else if (QTAIHack && (qtnt & 0x40)) { } else if (QTAIHack && (qtnt & 0x40)) {
pt[0] = *(CHRptr[0] + RefreshAddr); pt[0] = *(CHRptr[0] + RefreshAddr);
runppu(kFetchTime); ppu1[4] = PPU[1];
runppu(1);
ppu1[5] = PPU[1];
runppu(1);
RefreshAddr |= 8; RefreshAddr |= 8;
pt[1] = *(CHRptr[0] + RefreshAddr); pt[1] = *(CHRptr[0] + RefreshAddr);
runppu(kFetchTime); ppu1[6] = PPU[1];
runppu(1);
ppu1[7] = PPU[1];
runppu(1);
} else { } else {
if (ScreenON) if (ScreenON)
RENDER_LOG(RefreshAddr); RENDER_LOG(RefreshAddr);
pt[0] = CALL_PPUREAD(RefreshAddr); pt[0] = CALL_PPUREAD(RefreshAddr);
runppu(kFetchTime); ppu1[4] = PPU[1];
runppu(1);
ppu1[5] = PPU[1];
runppu(1);
RefreshAddr |= 8; RefreshAddr |= 8;
if (ScreenON) if (ScreenON)
RENDER_LOG(RefreshAddr); RENDER_LOG(RefreshAddr);
pt[1] = CALL_PPUREAD(RefreshAddr); pt[1] = CALL_PPUREAD(RefreshAddr);
runppu(kFetchTime); ppu1[6] = PPU[1];
runppu(1);
ppu1[7] = PPU[1];
runppu(1);
} }
} }
}; };
@ -2216,7 +2243,7 @@ int FCEUX_PPU_Loop(int skip) {
pixel = ((pt[0] >> (7 - bgpx)) & 1) | (((pt[1] >> (7 - bgpx)) & 1) << 1) | bgdata.main[bgtile].at; pixel = ((pt[0] >> (7 - bgpx)) & 1) | (((pt[1] >> (7 - bgpx)) & 1) << 1) | bgdata.main[bgtile].at;
} }
if (renderbg) if (renderbg)
pixelcolor = READPAL(pixel); pixelcolor = READPALNOGS(pixel);
//look for a sprite to be drawn //look for a sprite to be drawn
bool havepixel = false; bool havepixel = false;
@ -2261,12 +2288,25 @@ int FCEUX_PPU_Loop(int skip) {
spixel |= (oam[2] & 3) << 2; spixel |= (oam[2] & 3) << 2;
if (rendersprites) if (rendersprites)
pixelcolor = READPAL(0x10 + spixel); pixelcolor = READPALNOGS(0x10 + spixel);
} }
} }
*ptr++ = PaletteAdjustPixel(pixelcolor); //apply grayscale.. kind of clunky
*dptr++= PPU[1]>>5; //grab deemph //really we need to read the entire palette instead of just ppu1
//this will be needed for special color effects probably (very fine rainbows and whatnot?)
//are you allowed to chang the palette mid-line anyway? well you can definitely change the grayscale flag as we know from the FF1 "polygon" effect
if(bgdata.main[xt+2].ppu1[xp]&1)
pixelcolor &= 0x30;
//this does deemph stuff inside it.. which is probably wrong...
*ptr = PaletteAdjustPixel(pixelcolor);
ptr++;
//grab deemph..
//I guess this works the same way as the grayscale, ideally?
*dptr++ = bgdata.main[xt+2].ppu1[xp]>>5;
} }
} }
} }