This commit is contained in:
upthorn 2020-05-13 09:25:35 -07:00
commit 01089645cc
5 changed files with 235 additions and 46 deletions

View File

@ -305,11 +305,12 @@ namespace BizHawk.Client.EmuHawk
//add lua layer 'emu' //add lua layer 'emu'
AppendLuaLayer(chain, "emu"); AppendLuaLayer(chain, "emu");
if (Global.Config.DispPrescale != 1) if(includeUserFilters)
{ if (Global.Config.DispPrescale != 1)
var fPrescale = new Filters.PrescaleFilter() { Scale = Global.Config.DispPrescale }; {
chain.AddFilter(fPrescale, "user_prescale"); var fPrescale = new Filters.PrescaleFilter() { Scale = Global.Config.DispPrescale };
} chain.AddFilter(fPrescale, "user_prescale");
}
// add user-selected retro shader // add user-selected retro shader
if (selectedChain != null) if (selectedChain != null)
@ -352,7 +353,8 @@ namespace BizHawk.Client.EmuHawk
} }
// add final presentation // add final presentation
chain.AddFilter(fPresent, "presentation"); if (includeUserFilters)
chain.AddFilter(fPresent, "presentation");
//add lua layer 'native' //add lua layer 'native'
AppendLuaLayer(chain, "native"); AppendLuaLayer(chain, "native");
@ -699,7 +701,8 @@ namespace BizHawk.Client.EmuHawk
VideoProvider = fvp, VideoProvider = fvp,
Simulate = true, Simulate = true,
ChainOutsize = chainOutsize, ChainOutsize = chainOutsize,
IncludeUserFilters = true IncludeUserFilters = true,
IncludeOSD = true,
}; };
var filterProgram = UpdateSourceInternal(job); var filterProgram = UpdateSourceInternal(job);
@ -723,6 +726,12 @@ namespace BizHawk.Client.EmuHawk
public bool Offscreen; public bool Offscreen;
public BitmapBuffer OffscreenBb; public BitmapBuffer OffscreenBb;
public bool IncludeOSD; public bool IncludeOSD;
/// <summary>
/// This has been changed a bit to mean "not raw".
/// Someone needs to rename it, but the sense needs to be inverted and some method args need renaming too
/// Suggested: IsRaw (with inverted sense)
/// </summary>
public bool IncludeUserFilters; public bool IncludeUserFilters;
} }
@ -837,17 +846,20 @@ namespace BizHawk.Client.EmuHawk
//setup the final presentation filter //setup the final presentation filter
Filters.FinalPresentation fPresent = filterProgram["presentation"] as Filters.FinalPresentation; Filters.FinalPresentation fPresent = filterProgram["presentation"] as Filters.FinalPresentation;
fPresent.VirtualTextureSize = new Size(vw, vh); if (fPresent != null)
fPresent.TextureSize = new Size(presenterTextureWidth, presenterTextureHeight); {
fPresent.BackgroundColor = videoProvider.BackgroundColor; fPresent.VirtualTextureSize = new Size(vw, vh);
fPresent.GuiRenderer = Renderer; fPresent.TextureSize = new Size(presenterTextureWidth, presenterTextureHeight);
fPresent.Flip = isGlTextureId; fPresent.BackgroundColor = videoProvider.BackgroundColor;
fPresent.Config_FixAspectRatio = Global.Config.DispFixAspectRatio; fPresent.GuiRenderer = Renderer;
fPresent.Config_FixScaleInteger = Global.Config.DispFixScaleInteger; fPresent.Flip = isGlTextureId;
fPresent.Padding = ClientExtraPadding; fPresent.Config_FixAspectRatio = Global.Config.DispFixAspectRatio;
fPresent.AutoPrescale = Global.Config.DispAutoPrescale; fPresent.Config_FixScaleInteger = Global.Config.DispFixScaleInteger;
fPresent.Padding = ClientExtraPadding;
fPresent.AutoPrescale = Global.Config.DispAutoPrescale;
fPresent.GL = GL; fPresent.GL = GL;
}
//POOPY. why are we delivering the GL context this way? such bad //POOPY. why are we delivering the GL context this way? such bad
Filters.ScreenControlNDS fNDS = filterProgram["CoreScreenControl"] as Filters.ScreenControlNDS; Filters.ScreenControlNDS fNDS = filterProgram["CoreScreenControl"] as Filters.ScreenControlNDS;

View File

@ -359,6 +359,7 @@ namespace BizHawk.Emulation.Cores.Components.I8048
case ST_CNT: case ST_CNT:
counter_en = true; counter_en = true;
next_T1_check = TotalExecutedCycles + 20; next_T1_check = TotalExecutedCycles + 20;
timer_en = false;
break; break;
case STP_CNT: case STP_CNT:
counter_en = timer_en = false; counter_en = timer_en = false;
@ -366,6 +367,7 @@ namespace BizHawk.Emulation.Cores.Components.I8048
case ST_T: case ST_T:
timer_en = true; timer_en = true;
timer_prescale = 0; timer_prescale = 0;
counter_en = false;
break; break;
case SET_ADDR_8: case SET_ADDR_8:
reg_d_ad = cur_instr[instr_pntr++]; reg_d_ad = cur_instr[instr_pntr++];
@ -487,6 +489,7 @@ namespace BizHawk.Emulation.Cores.Components.I8048
if (TimIntEn) if (TimIntEn)
{ {
TIRQPending = true; TIRQPending = true;
//Console.WriteLine("Timer: " + TotalExecutedCycles);
} }
} }
Regs[TIM] = (ushort)((Regs[TIM] + 1) & 0xFF); Regs[TIM] = (ushort)((Regs[TIM] + 1) & 0xFF);
@ -504,7 +507,7 @@ namespace BizHawk.Emulation.Cores.Components.I8048
if (TimIntEn) if (TimIntEn)
{ {
TIRQPending = true; TIRQPending = true;
//Console.WriteLine(TotalExecutedCycles); //Console.WriteLine("Counter: " + TotalExecutedCycles);
} }
} }
Regs[TIM] = (ushort)((Regs[TIM] + 1) & 0xFF); Regs[TIM] = (ushort)((Regs[TIM] + 1) & 0xFF);

View File

@ -61,8 +61,6 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
_syncSettings = (O2SyncSettings)syncSettings ?? new O2SyncSettings(); _syncSettings = (O2SyncSettings)syncSettings ?? new O2SyncSettings();
_controllerDeck = new O2HawkControllerDeck("O2 Controller", "O2 Controller"); _controllerDeck = new O2HawkControllerDeck("O2 Controller", "O2 Controller");
ppu = new PPU();
_bios = comm.CoreFileProvider.GetFirmware("O2", "BIOS", true, "BIOS Not Found, Cannot Load") _bios = comm.CoreFileProvider.GetFirmware("O2", "BIOS", true, "BIOS Not Found, Cannot Load")
?? throw new MissingFirmwareException("Missing Odyssey2 Bios"); ?? throw new MissingFirmwareException("Missing Odyssey2 Bios");
@ -75,11 +73,9 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
_frameHz = 60; _frameHz = 60;
ppu.Core = this;
cpu.Core = this; cpu.Core = this;
ser.Register<IVideoProvider>(this); ser.Register<IVideoProvider>(this);
ser.Register<ISoundProvider>(ppu);
ServiceProvider = ser; ServiceProvider = ser;
_settings = (O2Settings)settings ?? new O2Settings(); _settings = (O2Settings)settings ?? new O2Settings();
@ -91,24 +87,30 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
SetupMemoryDomains(); SetupMemoryDomains();
cpu.SetCallbacks(ReadMemory, PeekMemory, PeekMemory, WriteMemory); cpu.SetCallbacks(ReadMemory, PeekMemory, PeekMemory, WriteMemory);
HardReset();
// set up differences between PAL and NTSC systems // set up differences between PAL and NTSC systems
is_pal = true;
pic_height = 288;
_frameHz = 50;
if (game.Region == "US" || game.Region == "EU-US" || game.Region == null) if (game.Region == "US" || game.Region == "EU-US" || game.Region == null)
{ {
is_pal = false; is_pal = false;
pic_height = 240; pic_height = 240;
_frameHz = 60; _frameHz = 60;
}
ppu = new NTSC_PPU();
}
else
{
is_pal = true;
pic_height = 288;
_frameHz = 50;
ppu = new PAL_PPU();
}
ppu.Core = this;
ppu.set_region(is_pal); ppu.set_region(is_pal);
ser.Register<ISoundProvider>(ppu);
_vidbuffer = new int[372 * pic_height]; _vidbuffer = new int[372 * pic_height];
frame_buffer = new int[320 * pic_height]; frame_buffer = new int[320 * pic_height];
HardReset();
} }
public DisplayType Region => DisplayType.NTSC; public DisplayType Region => DisplayType.NTSC;

View File

@ -58,7 +58,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
int right_shift_even; int right_shift_even;
int x_base; int x_base;
public byte ReadReg(int addr) public virtual byte ReadReg(int addr)
{ {
byte ret = 0; byte ret = 0;
@ -96,19 +96,20 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
if (VDC_collision.Bit(i)) if (VDC_collision.Bit(i))
{ {
ret |= VDC_col_ret[i]; ret |= VDC_col_ret[i];
} //VDC_col_ret[i] = 0;
}
} }
// register is reset when read // register is reset when read, but not external
for (int i = 0; i < 8; i++) { VDC_col_ret[i] = 0; } for (int i = 0; i < 8; i++) { VDC_col_ret[i] = 0; }
//Console.WriteLine("col: " + ret + " " + LY + " " + Core.cpu.TotalExecutedCycles); //Console.WriteLine("col: " + VDC_collision + " " + ret + " " + LY + " " + Core.cpu.TotalExecutedCycles);
} }
else if (addr == 0xA3) else if (addr == 0xA3)
{ {
ret = VDC_color; ret = VDC_color;
} }
else if(addr == 0xA4) else if (addr == 0xA4)
{ {
if (latch_x_y) { ret = A4_latch; } if (latch_x_y) { ret = A4_latch; }
else { ret = (byte)((LY_ret >= 0) ? LY_ret : 0); } else { ret = (byte)((LY_ret >= 0) ? LY_ret : 0); }
@ -140,7 +141,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
} }
//Peek method for memory domains that doesn't effect IRQ //Peek method for memory domains that doesn't effect IRQ
public byte PeekReg(int addr) public virtual byte PeekReg(int addr)
{ {
byte ret = 0; byte ret = 0;
@ -150,7 +151,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
else if (addr < 0xA0) { ret = Sprite_Shapes[addr - 0x80]; } else if (addr < 0xA0) { ret = Sprite_Shapes[addr - 0x80]; }
else if (addr == 0xA0) { ret = VDC_ctrl; } else if (addr == 0xA0) { ret = VDC_ctrl; }
else if (addr == 0xA1) { ret = VDC_status; } else if (addr == 0xA1) { ret = VDC_status; }
else if (addr == 0xA2) else if (addr == 0xA2)
{ {
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
@ -185,7 +186,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
if (addr < 0x10) if (addr < 0x10)
{ {
if (!VDC_ctrl.Bit(5)) { Sprites[addr] = value; } if (!VDC_ctrl.Bit(5)) { Sprites[addr] = value; }
//Console.WriteLine("spr: " + addr + " " + value + " " + Core.cpu.TotalExecutedCycles); //Console.WriteLine("spr: " + addr + " " + value + " " + Core.cpu.TotalExecutedCycles);
} }
else if (addr < 0x40) else if (addr < 0x40)
{ {
@ -198,8 +199,8 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
{ {
// chars position is not effected by last bit // chars position is not effected by last bit
if ((addr % 4) == 0) { value &= 0xFE; } if ((addr % 4) == 0) { value &= 0xFE; }
if (!VDC_ctrl.Bit(5)) if (!VDC_ctrl.Bit(5))
{ {
Quad_Chars[addr - 0x40] = value; Quad_Chars[addr - 0x40] = value;
// X and Y are mapped all together // X and Y are mapped all together
@ -211,7 +212,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
} }
} }
} }
//Console.WriteLine("quad: " + (addr - 0x40) + " " + value + " " + Core.cpu.TotalExecutedCycles); //Console.WriteLine("quad: " + (addr - 0x40) + " " + value + " " + Core.cpu.TotalExecutedCycles);
} }
else if (addr < 0xA0) else if (addr < 0xA0)
@ -246,7 +247,8 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
else if (addr == 0xA2) else if (addr == 0xA2)
{ {
VDC_collision = value; VDC_collision = value;
//Console.WriteLine("VDC_collide: " + value + " " + Core.cpu.TotalExecutedCycles);
Console.WriteLine("VDC_collide: " + value + " " + Core.cpu.TotalExecutedCycles);
} }
else if (addr == 0xA3) else if (addr == 0xA3)
{ {
@ -282,7 +284,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
//Console.WriteLine(addr + " " + value + " " + LY + " " + Core.cpu.TotalExecutedCycles); //Console.WriteLine(addr + " " + value + " " + LY + " " + Core.cpu.TotalExecutedCycles);
} }
public void tick() public virtual void tick()
{ {
Pixel_Stat = 0; Pixel_Stat = 0;
// drawing cycles // drawing cycles
@ -356,11 +358,11 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
{ {
HBL = false; HBL = false;
Core.cpu.T1 = false; Core.cpu.T1 = false;
} }
} }
} }
public void Reset() public virtual void Reset()
{ {
Sprites = new byte[16]; Sprites = new byte[16];
Sprite_Shapes = new byte[32]; Sprite_Shapes = new byte[32];
@ -378,7 +380,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
AudioReset(); AudioReset();
} }
public void set_region(bool pal_flag) public virtual void set_region(bool pal_flag)
{ {
is_pal = pal_flag; is_pal = pal_flag;
@ -394,7 +396,7 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
} }
} }
public void process_pixel() public virtual void process_pixel()
{ {
current_pixel_offset = cycle * 2; current_pixel_offset = cycle * 2;
@ -1219,4 +1221,166 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk
#endregion #endregion
} }
public class NTSC_PPU : PPU
{
public override void tick()
{
Pixel_Stat = 0;
// drawing cycles
// note: clipping might need to be handled differently between PAL and NTSC
if (cycle < 182)
{
if ((LY < LINE_VBL) && (LY >= 0))
{
// draw a pixel
process_pixel();
}
}
else
{
// NOTE: most games expect one less T1 pulse after VBL, maybe some pre-render line
if (cycle == 182 && (LY < LINE_VBL) && (LY > 0))
{
HBL = true;
// Send T1 pulses
Core.cpu.T1 = true;
}
if (cycle == 212 && (LY < LINE_VBL))
{
VDC_status &= 0xFE;
if (VDC_ctrl.Bit(0)) { Core.cpu.IRQPending = false; }
LY_ret = LY_ret + 1;
}
}
if (cycle == 113 && (LY < LINE_VBL))
{
VDC_status |= 0x01;
if (VDC_ctrl.Bit(0) && HBL_req) { Core.cpu.IRQPending = true; HBL_req = false; }
}
cycle++;
// end of scanline
if (cycle == 228)
{
cycle = 0;
LY++;
if (LY == LINE_VBL)
{
VBL = true;
Core.in_vblank = true;
VDC_status |= 0x08;
Core.cpu.IRQPending = true;
Core.cpu.T1 = true;
}
if (LY >= LINE_VBL)
{
LY_ret = 0;
}
if (LY == LINE_MAX)
{
LY = 0;
VBL = false;
Core.in_vblank = false;
Core.cpu.T1 = false;
if (Core.is_pal) { Core.cpu.IRQPending = false; }
LY_ret = 0;
}
if (LY < LINE_VBL)
{
HBL = false;
Core.cpu.T1 = false;
}
}
}
}
public class PAL_PPU : PPU
{
public override void tick()
{
Pixel_Stat = 0;
// drawing cycles
// note: clipping might need to be handled differently between PAL and NTSC
if (cycle < 182)
{
if ((LY < LINE_VBL) && (LY >= 0))
{
// draw a pixel
process_pixel();
}
}
else
{
// NOTE: most games expect one less T1 pulse after VBL, maybe some pre-render line
if (cycle == 182 && (LY < LINE_VBL) && (LY > 0))
{
HBL = true;
// Send T1 pulses
Core.cpu.T1 = true;
}
if (cycle == 212 && (LY < LINE_VBL))
{
VDC_status &= 0xFE;
if (VDC_ctrl.Bit(0)) { Core.cpu.IRQPending = false; }
LY_ret = LY_ret + 1;
}
}
if (cycle == 113 && (LY < LINE_VBL))
{
VDC_status |= 0x01;
if (VDC_ctrl.Bit(0) && HBL_req) { Core.cpu.IRQPending = true; HBL_req = false; }
}
cycle++;
// end of scanline
if (cycle == 228)
{
cycle = 0;
LY++;
if (LY == LINE_VBL)
{
VBL = true;
Core.in_vblank = true;
VDC_status |= 0x08;
Core.cpu.IRQPending = true;
Core.cpu.T1 = true;
}
if (LY >= LINE_VBL)
{
LY_ret = 0;
}
if (LY == LINE_MAX)
{
LY = 0;
VBL = false;
Core.in_vblank = false;
Core.cpu.T1 = false;
if (Core.is_pal) { Core.cpu.IRQPending = false; }
LY_ret = 0;
}
if (LY < LINE_VBL)
{
HBL = false;
Core.cpu.T1 = false;
}
}
}
}
} }

View File

@ -841,6 +841,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
WriteReg(addr, value); WriteReg(addr, value);
} }
else if (addr < 0x6000)
{
//let's ignore pokes to EXP until someone asks for it. there's really almost no way that could ever be done without the board having a PokeEXP method
}
else if (addr < 0x8000)
{
Board.WriteWram(addr - 0x6000, value);
}
else else
{ {
// apply a cheat to non-writable memory // apply a cheat to non-writable memory