NES PPU update sprite evaluation
This commit is contained in:
parent
535bfa4ab4
commit
b453745404
|
@ -450,6 +450,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
{
|
{
|
||||||
ret = OAM[reg_2003];
|
ret = OAM[reg_2003];
|
||||||
}
|
}
|
||||||
|
|
||||||
ppu_open_bus = ret;
|
ppu_open_bus = ret;
|
||||||
ppu_open_bus_decay(1);
|
ppu_open_bus_decay(1);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -22,15 +22,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
public short[] xbuf = new short[256 * 240];
|
public short[] xbuf = new short[256 * 240];
|
||||||
|
|
||||||
// values here are used in sprite evaluation
|
// values here are used in sprite evaluation
|
||||||
|
public int spr_true_count;
|
||||||
public bool sprite_eval_write;
|
public bool sprite_eval_write;
|
||||||
public byte read_value;
|
public byte read_value;
|
||||||
public int soam_index;
|
public int soam_index;
|
||||||
public int soam_index_prev;
|
public int soam_index_prev;
|
||||||
public int soam_m_index;
|
public int soam_m_index;
|
||||||
public int oam_index;
|
public int oam_index;
|
||||||
public int read_value_aux;
|
public byte read_value_aux;
|
||||||
public int soam_m_index_aux;
|
public int soam_m_index_aux;
|
||||||
public int oam_index_aux;
|
public int oam_index_aux;
|
||||||
|
public int soam_index_aux;
|
||||||
public bool is_even_cycle;
|
public bool is_even_cycle;
|
||||||
public bool sprite_zero_in_range = false;
|
public bool sprite_zero_in_range = false;
|
||||||
public bool sprite_zero_go = false;
|
public bool sprite_zero_go = false;
|
||||||
|
@ -127,11 +129,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
case 6:
|
case 6:
|
||||||
ppu_addr_temp |= 8;
|
ppu_addr_temp |= 8;
|
||||||
bgdata.pt_1 = ppubus_read(ppu_addr_temp, true, true);
|
bgdata.pt_1 = ppubus_read(ppu_addr_temp, true, true);
|
||||||
|
|
||||||
|
runppu(1);
|
||||||
if (reg_2001.PPUON)
|
if (reg_2001.PPUON)
|
||||||
{
|
{
|
||||||
ppu_was_on = true;
|
ppu_was_on = true;
|
||||||
}
|
}
|
||||||
runppu(1);
|
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
race_2006 = false;
|
race_2006 = false;
|
||||||
|
@ -199,6 +202,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
|
|
||||||
ppur.status.sl = sl;
|
ppur.status.sl = sl;
|
||||||
|
|
||||||
|
spr_true_count = 0;
|
||||||
soam_index = 0;
|
soam_index = 0;
|
||||||
soam_m_index = 0;
|
soam_m_index = 0;
|
||||||
soam_m_index_aux = 0;
|
soam_m_index_aux = 0;
|
||||||
|
@ -253,7 +257,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
soam_index++;
|
soam_index++;
|
||||||
}
|
}
|
||||||
if (ppur.status.cycle == 64)
|
if (ppur.status.cycle == 64)
|
||||||
|
{
|
||||||
soam_index = 0;
|
soam_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// otherwise, scan through OAM and test if sprites are in range
|
// otherwise, scan through OAM and test if sprites are in range
|
||||||
// if they are, they get copied to the secondary OAM
|
// if they are, they get copied to the secondary OAM
|
||||||
|
@ -261,70 +267,102 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
{
|
{
|
||||||
if (oam_index == 64)
|
if (oam_index == 64)
|
||||||
{
|
{
|
||||||
|
oam_index = 0;
|
||||||
sprite_eval_write = false;
|
sprite_eval_write = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_even_cycle && oam_index<64)
|
if (is_even_cycle && oam_index<64)
|
||||||
{
|
{
|
||||||
|
if ((oam_index * 4 + soam_m_index) < 256)
|
||||||
read_value = OAM[oam_index * 4 + soam_m_index];
|
read_value = OAM[oam_index * 4 + soam_m_index];
|
||||||
|
else
|
||||||
if (oam_index_aux > 63)
|
read_value = OAM[oam_index * 4 + soam_m_index - 256];
|
||||||
oam_index_aux = 63;
|
}
|
||||||
|
else if (!sprite_eval_write)
|
||||||
read_value_aux = OAM[oam_index_aux * 4 + soam_m_index_aux];
|
{
|
||||||
|
// if we don't write sprites anymore, just scan through the oam
|
||||||
|
read_value = soam[0];
|
||||||
|
oam_index++;
|
||||||
}
|
}
|
||||||
else if (sprite_eval_write)
|
else if (sprite_eval_write)
|
||||||
{
|
{
|
||||||
if (soam_index >= 8)
|
|
||||||
{
|
|
||||||
// this code mirrors sprite overflow bug behaviour
|
|
||||||
// see http://wiki.nesdev.com/w/index.php/PPU_sprite_evaluation
|
|
||||||
if (yp >= read_value && yp < read_value + spriteHeight && reg_2001.PPUON)
|
|
||||||
{
|
|
||||||
Reg2002_objoverflow = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
soam_m_index++;
|
|
||||||
oam_index++;
|
|
||||||
if (soam_m_index == 4)
|
|
||||||
soam_m_index = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//look for sprites
|
//look for sprites
|
||||||
soam[soam_index * 4] = OAM[oam_index_aux * 4];
|
if (spr_true_count==0 && soam_index<8)
|
||||||
if (yp >= read_value_aux && yp < read_value_aux + spriteHeight && soam_m_index_aux == 0)
|
|
||||||
{
|
{
|
||||||
//a flag gets set if sprite zero is in range
|
soam[soam_index * 4] = read_value;
|
||||||
if (oam_index_aux == 0)
|
|
||||||
sprite_zero_in_range = true;
|
|
||||||
|
|
||||||
soam_m_index_aux++;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (soam_m_index_aux > 0 && soam_m_index_aux < 4)
|
|
||||||
{
|
|
||||||
soam[soam_index * 4 + soam_m_index_aux] = OAM[oam_index_aux * 4 + soam_m_index_aux];
|
|
||||||
soam_m_index_aux++;
|
|
||||||
if (soam_m_index_aux == 4)
|
|
||||||
{
|
|
||||||
oam_index_aux++;
|
|
||||||
soam_index++;
|
|
||||||
soam_m_index_aux = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oam_index_aux++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (soam_index < 8)
|
if (soam_index < 8)
|
||||||
{
|
{
|
||||||
soam_m_index = soam_m_index_aux;
|
if (yp >= read_value && yp < read_value + spriteHeight && spr_true_count == 0)
|
||||||
oam_index = oam_index_aux;
|
{
|
||||||
|
//a flag gets set if sprite zero is in range
|
||||||
|
if (oam_index == 0)
|
||||||
|
sprite_zero_in_range = true;
|
||||||
|
|
||||||
|
spr_true_count++;
|
||||||
|
soam_m_index++;
|
||||||
|
}
|
||||||
|
else if (spr_true_count > 0 && spr_true_count < 4)
|
||||||
|
{
|
||||||
|
soam[soam_index * 4 + soam_m_index] = read_value;
|
||||||
|
|
||||||
|
soam_m_index++;
|
||||||
|
|
||||||
|
spr_true_count++;
|
||||||
|
if (spr_true_count == 4)
|
||||||
|
{
|
||||||
|
oam_index++;
|
||||||
|
soam_index++;
|
||||||
|
if (soam_index == 8)
|
||||||
|
oam_index_aux = oam_index;
|
||||||
|
|
||||||
|
soam_m_index = 0;
|
||||||
|
spr_true_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oam_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (soam_index>=8)
|
||||||
|
{
|
||||||
|
if (yp >= read_value && yp < read_value + spriteHeight && reg_2001.PPUON)
|
||||||
|
{
|
||||||
|
Reg2002_objoverflow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yp >= read_value && yp < read_value + spriteHeight && spr_true_count == 0)
|
||||||
|
{
|
||||||
|
spr_true_count++;
|
||||||
|
soam_m_index++;
|
||||||
|
}
|
||||||
|
else if (spr_true_count > 0 && spr_true_count < 4)
|
||||||
|
{
|
||||||
|
soam_m_index++;
|
||||||
|
|
||||||
|
spr_true_count++;
|
||||||
|
if (spr_true_count == 4)
|
||||||
|
{
|
||||||
|
oam_index++;
|
||||||
|
soam_index++;
|
||||||
|
soam_m_index = 0;
|
||||||
|
spr_true_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oam_index++;
|
||||||
|
if (soam_index==8)
|
||||||
|
{
|
||||||
|
soam_m_index++; // glitchy increment
|
||||||
|
soam_m_index &= 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
read_value = soam[0]; //writes change to reads
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -422,11 +460,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
}
|
}
|
||||||
} //rasterpos in sprite range
|
} //rasterpos in sprite range
|
||||||
} //oamcount loop
|
} //oamcount loop
|
||||||
/*
|
|
||||||
if (reg_2001.color_disable)
|
|
||||||
pixelcolor &= 0x30;
|
|
||||||
xbuf[target] = PaletteAdjustPixel(pixelcolor);
|
|
||||||
*/
|
|
||||||
pipeline(pixelcolor, target, xt*32+xp);
|
pipeline(pixelcolor, target, xt*32+xp);
|
||||||
target++;
|
target++;
|
||||||
|
|
||||||
|
@ -438,20 +472,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
Read_bgdata(ref bgdata[xt + 2]);
|
Read_bgdata(ref bgdata[xt + 2]);
|
||||||
|
|
||||||
// normally only 8 sprites are allowed, but with a particular setting we can have more then that
|
// normally only 8 sprites are allowed, but with a particular setting we can have more then that
|
||||||
// this extra bit is here because the actual loop doesn't have enough time to scann all sprites if there are more then 8
|
// this extra bit takes care of it quickly
|
||||||
|
soam_index_aux = 8;
|
||||||
|
|
||||||
if (nes.Settings.AllowMoreThanEightSprites)
|
if (nes.Settings.AllowMoreThanEightSprites)
|
||||||
{
|
{
|
||||||
while (oam_index_aux < 64)
|
while (oam_index_aux < 64)
|
||||||
{
|
{
|
||||||
//look for sprites
|
//look for sprites
|
||||||
soam[soam_index * 4] = OAM[oam_index_aux * 4];
|
soam[soam_index_aux * 4] = OAM[oam_index_aux * 4];
|
||||||
read_value_aux = OAM[oam_index_aux * 4];
|
read_value_aux = OAM[oam_index_aux * 4];
|
||||||
if (yp >= read_value_aux && yp < read_value_aux + spriteHeight)
|
if (yp >= read_value_aux && yp < read_value_aux + spriteHeight)
|
||||||
{
|
{
|
||||||
soam[soam_index * 4 + 1] = OAM[oam_index_aux * 4 + 1];
|
soam[soam_index_aux * 4 + 1] = OAM[oam_index_aux * 4 + 1];
|
||||||
soam[soam_index * 4 + 2] = OAM[oam_index_aux * 4 + 2];
|
soam[soam_index_aux * 4 + 2] = OAM[oam_index_aux * 4 + 2];
|
||||||
soam[soam_index * 4 + 3] = OAM[oam_index_aux * 4 + 3];
|
soam[soam_index_aux * 4 + 3] = OAM[oam_index_aux * 4 + 3];
|
||||||
soam_index++;
|
soam_index_aux++;
|
||||||
oam_index_aux++;
|
oam_index_aux++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -461,7 +497,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
soam_index_prev = soam_index;
|
soam_index_prev = soam_index_aux;
|
||||||
|
|
||||||
if (soam_index_prev > 8 && !nes.Settings.AllowMoreThanEightSprites)
|
if (soam_index_prev > 8 && !nes.Settings.AllowMoreThanEightSprites)
|
||||||
soam_index_prev = 8;
|
soam_index_prev = 8;
|
||||||
|
@ -470,25 +506,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
|
|
||||||
spriteHeight = reg_2000.obj_size_16 ? 16 : 8;
|
spriteHeight = reg_2000.obj_size_16 ? 16 : 8;
|
||||||
|
|
||||||
// if there are less then 8 evaluated sprites, we still process 8 sprites
|
|
||||||
int bound;
|
|
||||||
|
|
||||||
if (soam_index_prev > 8)
|
|
||||||
{
|
|
||||||
bound = soam_index_prev;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bound = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int s = 0; s < 8; s++)
|
for (int s = 0; s < 8; s++)
|
||||||
{
|
{
|
||||||
//if this is a real sprite sprite, then it is not above the 8 sprite limit.
|
|
||||||
//this is how we support the no 8 sprite limit feature.
|
|
||||||
//not that at some point we may need a virtual CALL_PPUREAD which just peeks and doesnt increment any counters
|
|
||||||
//this could be handy for the debugging tools also
|
|
||||||
bool realSprite = (s < 8);
|
|
||||||
bool junksprite = (!reg_2001.PPUON);
|
bool junksprite = (!reg_2001.PPUON);
|
||||||
|
|
||||||
t_oam[s].oam_y = soam[s * 4];
|
t_oam[s].oam_y = soam[s * 4];
|
||||||
|
@ -528,39 +547,51 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
{
|
{
|
||||||
if (sl == 0 && ppur.status.cycle == 304)
|
if (sl == 0 && ppur.status.cycle == 304)
|
||||||
{
|
{
|
||||||
runppu(1);
|
|
||||||
read_value = t_oam[s].oam_y;
|
read_value = t_oam[s].oam_y;
|
||||||
if (reg_2001.PPUON) ppur.install_latches();
|
|
||||||
runppu(1);
|
runppu(1);
|
||||||
|
|
||||||
|
if (reg_2001.PPUON) ppur.install_latches();
|
||||||
|
|
||||||
read_value = t_oam[s].oam_ind;
|
read_value = t_oam[s].oam_ind;
|
||||||
|
runppu(1);
|
||||||
|
|
||||||
|
|
||||||
garbage_todo = 0;
|
garbage_todo = 0;
|
||||||
}
|
}
|
||||||
if ((sl != 0) && ppur.status.cycle == 256)
|
if ((sl != 0) && ppur.status.cycle == 256)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
read_value = t_oam[s].oam_y;
|
||||||
|
|
||||||
runppu(1);
|
runppu(1);
|
||||||
|
|
||||||
if (target<=61441 && target > 0 && s==0)
|
if (target<=61441 && target > 0 && s==0)
|
||||||
{
|
{
|
||||||
pipeline(0, target,256);
|
pipeline(0, target,256);
|
||||||
target++;
|
target++;
|
||||||
}
|
}
|
||||||
read_value = t_oam[s].oam_y;
|
|
||||||
//at 257: 3d world runner is ugly if we do this at 256
|
//at 257: 3d world runner is ugly if we do this at 256
|
||||||
if (reg_2001.PPUON) ppur.install_h_latches();
|
if (reg_2001.PPUON) ppur.install_h_latches();
|
||||||
|
read_value = t_oam[s].oam_ind;
|
||||||
runppu(1);
|
runppu(1);
|
||||||
|
|
||||||
if (target <= 61441 && target > 0 && s==0)
|
if (target <= 61441 && target > 0 && s==0)
|
||||||
{
|
{
|
||||||
pipeline(0, target, 257); // last pipeline call option 1 of 2
|
pipeline(0, target, 257); // last pipeline call option 1 of 2
|
||||||
}
|
}
|
||||||
|
|
||||||
read_value = t_oam[s].oam_ind;
|
|
||||||
garbage_todo = 0;
|
garbage_todo = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (realSprite)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < garbage_todo; i++)
|
for (int i = 0; i < garbage_todo; i++)
|
||||||
{
|
{
|
||||||
|
if (i==0)
|
||||||
|
read_value = t_oam[s].oam_y;
|
||||||
|
else
|
||||||
|
read_value = t_oam[s].oam_ind;
|
||||||
|
|
||||||
runppu(1);
|
runppu(1);
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
|
@ -570,7 +601,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
pipeline(0, target,256);
|
pipeline(0, target,256);
|
||||||
target++;
|
target++;
|
||||||
}
|
}
|
||||||
read_value = t_oam[s].oam_y;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -578,49 +608,35 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
{
|
{
|
||||||
pipeline(0, target, 257); // last pipeline call option 2 of 2
|
pipeline(0, target, 257); // last pipeline call option 2 of 2
|
||||||
}
|
}
|
||||||
read_value = t_oam[s].oam_ind;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ppubus_read(ppur.get_atread(), true, true); //at or nt?
|
ppubus_read(ppur.get_atread(), true, true); //at or nt?
|
||||||
if (realSprite)
|
|
||||||
{
|
|
||||||
runppu(1);
|
|
||||||
read_value = t_oam[s].oam_attr;
|
read_value = t_oam[s].oam_attr;
|
||||||
runppu(1);
|
runppu(1);
|
||||||
read_value = t_oam[s].oam_x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO - fake sprites should not come through ppubus_read but rather peek it
|
read_value = t_oam[s].oam_x;
|
||||||
// (at least, they should not probe it with AddressPPU. maybe the difference between peek and read is not necessary)
|
runppu(1);
|
||||||
|
|
||||||
|
// if the PPU is off, we don't put anything on the bus
|
||||||
if (junksprite)
|
if (junksprite)
|
||||||
{
|
|
||||||
if (realSprite)
|
|
||||||
{
|
{
|
||||||
ppubus_read(patternAddress, true, false);
|
ppubus_read(patternAddress, true, false);
|
||||||
ppubus_read(patternAddress, true, false);
|
ppubus_read(patternAddress, true, false);
|
||||||
runppu(kFetchTime * 2);
|
runppu(kFetchTime * 2);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int addr = patternAddress;
|
int addr = patternAddress;
|
||||||
t_oam[s].patterns_0 = ppubus_read(addr, true, true);
|
t_oam[s].patterns_0 = ppubus_read(addr, true, true);
|
||||||
if (realSprite)
|
|
||||||
{
|
|
||||||
runppu(kFetchTime);
|
|
||||||
read_value = t_oam[s].oam_x;
|
read_value = t_oam[s].oam_x;
|
||||||
}
|
runppu(kFetchTime);
|
||||||
|
|
||||||
addr += 8;
|
addr += 8;
|
||||||
t_oam[s].patterns_1 = ppubus_read(addr, true, true);
|
t_oam[s].patterns_1 = ppubus_read(addr, true, true);
|
||||||
if (realSprite)
|
|
||||||
{
|
|
||||||
runppu(kFetchTime);
|
|
||||||
read_value = t_oam[s].oam_x;
|
read_value = t_oam[s].oam_x;
|
||||||
}
|
runppu(kFetchTime);
|
||||||
|
|
||||||
|
|
||||||
// hflip
|
// hflip
|
||||||
if ((t_oam[s].oam_attr & 0x40) == 0)
|
if ((t_oam[s].oam_attr & 0x40) == 0)
|
||||||
|
@ -629,14 +645,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
t_oam[s].patterns_1 = BitReverse.Byte8[t_oam[s].patterns_1];
|
t_oam[s].patterns_1 = BitReverse.Byte8[t_oam[s].patterns_1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the sprites attribute is 0xFF, then this indicates a non-existent sprite
|
||||||
|
// I think the logic here is that bits 2-4 in OAM are disabled, but soam is initialized with 0xFF
|
||||||
|
// so the only way a sprite could have an 0xFF attribute is if it is not in the scope of the scanline
|
||||||
|
if (t_oam[s].oam_attr==0xFF)
|
||||||
|
{
|
||||||
|
t_oam[s].patterns_0 = 0;
|
||||||
|
t_oam[s].patterns_1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // sprite pattern fetch loop
|
} // sprite pattern fetch loop
|
||||||
|
|
||||||
//now do the same for extra sprites, but without any cycles run
|
//now do the same for extra sprites, but without any cycles run
|
||||||
if (bound>8)
|
if (soam_index_aux>8)
|
||||||
{
|
{
|
||||||
for (int s = 8; s < bound; s++)
|
for (int s = 8; s < soam_index_aux; s++)
|
||||||
{
|
{
|
||||||
bool junksprite = (!reg_2001.PPUON);
|
bool junksprite = (!reg_2001.PPUON);
|
||||||
|
|
||||||
|
@ -668,9 +693,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
//so we just need the line offset for the second pattern
|
//so we just need the line offset for the second pattern
|
||||||
patternAddress += line & 7;
|
patternAddress += line & 7;
|
||||||
|
|
||||||
//garbage nametable fetches + scroll resets
|
|
||||||
int garbage_todo = 2;
|
|
||||||
|
|
||||||
ppubus_read(ppur.get_ntread(), true, false);
|
ppubus_read(ppur.get_ntread(), true, false);
|
||||||
|
|
||||||
ppubus_read(ppur.get_atread(), true, false); //at or nt?
|
ppubus_read(ppur.get_atread(), true, false); //at or nt?
|
||||||
|
@ -688,6 +710,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
t_oam[s].patterns_1 = BitReverse.Byte8[t_oam[s].patterns_1];
|
t_oam[s].patterns_1 = BitReverse.Byte8[t_oam[s].patterns_1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the sprites attribute is 0xFF, then this indicates a non-existent sprite
|
||||||
|
// I think the logic here is that bits 2-4 in OAM are disabled, but soam is initialized with 0xFF
|
||||||
|
// so the only way a sprite could have an 0xFF attribute is if it is not in the scope of the scanline
|
||||||
|
if (t_oam[s].oam_attr == 0xFF)
|
||||||
|
{
|
||||||
|
t_oam[s].patterns_0 = 0;
|
||||||
|
t_oam[s].patterns_1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // sprite pattern fetch loop
|
} // sprite pattern fetch loop
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -700,7 +731,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
Read_bgdata(ref bgdata[xt]);
|
Read_bgdata(ref bgdata[xt]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// this sequence is tuned to pass 10-even_odd_timing.nes
|
// this sequence is tuned to pass 10-even_odd_timing.nes
|
||||||
runppu(kFetchTime);
|
runppu(kFetchTime);
|
||||||
bool evenOddDestiny = (reg_2001.show_bg || reg_2001.show_obj);
|
bool evenOddDestiny = (reg_2001.show_bg || reg_2001.show_obj);
|
||||||
|
@ -725,7 +755,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
|
|
||||||
} //FrameAdvance
|
} //FrameAdvance
|
||||||
|
|
||||||
|
|
||||||
void FrameAdvance_ppudead()
|
void FrameAdvance_ppudead()
|
||||||
{
|
{
|
||||||
//not quite emulating all the NES power up behavior
|
//not quite emulating all the NES power up behavior
|
||||||
|
|
Loading…
Reference in New Issue