From 13ec13a5563c94dad2a415d66c103af9814de447 Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Sat, 25 Nov 2017 21:16:14 -0500 Subject: [PATCH] GBHawk : Initial support for GPU Viewer --- BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs | 7 +- .../Nintendo/GBHawk/GBHawk.IEmulator.cs | 6 +- .../Consoles/Nintendo/GBHawk/GBHawk.cs | 85 ++++++++++++++++++- .../Consoles/Nintendo/GBHawk/PPU.cs | 10 +++ 4 files changed, 102 insertions(+), 6 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs b/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs index 8dc50567ef..ea6c8aaa0b 100644 --- a/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs +++ b/BizHawk.Client.EmuHawk/tools/GB/GBGPUView.cs @@ -87,7 +87,6 @@ namespace BizHawk.Client.EmuHawk { _cgb = Gb.IsCGBMode(); _lcdc = 0; - _memory = Gb.GetGPU(); tilespal = _memory.Bgpal; @@ -316,9 +315,11 @@ namespace BizHawk.Client.EmuHawk int* thispal = pal + 4 * (cgb ? flags & 7 : flags >> 4 & 1); if (cgb && flags.Bit(3)) tile += 8192; + DrawTileHv(tile, dest, pitch, thispal, hflip, vflip); + if (tall) - DrawTileHv((byte*)((int)tile ^ 16), dest + pitch * 8, pitch, thispal, hflip, vflip); + DrawTileHv(tile + 16, dest + pitch * 8, pitch, thispal, hflip, vflip); dest += 8; } b.UnlockBits(lockdata); @@ -465,7 +466,7 @@ namespace BizHawk.Client.EmuHawk } DrawOam(bmpViewOAM.BMP, _oam, _vram, _sppal, lcdc.Bit(2), _cgb); bmpViewOAM.Refresh(); - } + } // try to run the current mouseover, to refresh if the mouse is being held over a pane while the emulator runs // this doesn't really work well; the update rate seems to be throttled MouseEventArgs e = new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs index eda65a7a19..9c259f69f3 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs @@ -2,6 +2,7 @@ using BizHawk.Emulation.Common; using System; using System.Collections.Generic; +using System.Runtime.InteropServices; namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { @@ -161,7 +162,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk public void Dispose() { - + Marshal.FreeHGlobal(iptr0); + Marshal.FreeHGlobal(iptr1); + Marshal.FreeHGlobal(iptr2); + Marshal.FreeHGlobal(iptr3); } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs index 2f79545f90..62a83574c8 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs @@ -5,6 +5,9 @@ using BizHawk.Emulation.Common; using BizHawk.Emulation.Common.Components.LR35902; using BizHawk.Common.NumberExtensions; +using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy; +using System.Runtime.InteropServices; + namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { [Core( @@ -13,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk isPorted: false, isReleased: false)] [ServiceNotApplicable(typeof(IDriveLight))] - public partial class GBHawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable, + public partial class GBHawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable, IGameboyCommon, ISettable { // this register controls whether or not the GB BIOS is mapped into memory @@ -121,9 +124,87 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk ser.Register(_tracer); SetupMemoryDomains(); - HardReset(); + HardReset(); + + iptr0 = Marshal.AllocHGlobal(CHR_RAM.Length + BG_map_1.Length + BG_map_2.Length + 1); + iptr1 = Marshal.AllocHGlobal(OAM.Length + 1); + iptr2 = Marshal.AllocHGlobal(color_palette.Length * 2 + 1); + iptr3 = Marshal.AllocHGlobal(color_palette.Length + 1); + + _scanlineCallback = null; } + #region GPUViewer + + public bool IsCGBMode() => false; + + public IntPtr iptr0 = IntPtr.Zero; + public IntPtr iptr1 = IntPtr.Zero; + public IntPtr iptr2 = IntPtr.Zero; + public IntPtr iptr3 = IntPtr.Zero; + + private GPUMemoryAreas _gpuMemory + { + get + { + byte[] temp = new byte[CHR_RAM.Length + BG_map_1.Length + BG_map_2.Length]; + + for (int i = 0; i < CHR_RAM.Length; i++) + { + temp[i] = CHR_RAM[i]; + } + for (int i = 0; i < BG_map_1.Length; i++) + { + temp[CHR_RAM.Length + i] = BG_map_1[i]; + } + for (int i = 0; i < BG_map_2.Length; i++) + { + temp[CHR_RAM.Length + BG_map_1.Length + i] = BG_map_2[i]; + } + + Marshal.Copy(temp, 0, iptr0, temp.Length); + Marshal.Copy(OAM, 0, iptr1, OAM.Length); + + int[] cp = new int[4]; + for (int i = 0; i < 4; i++) + { + cp[i] = (int)color_palette[i]; + } + Marshal.Copy(cp, 0, iptr2, color_palette.Length); + Marshal.Copy(cp, 0, iptr3, color_palette.Length); + + Console.WriteLine("here"); + + return new GPUMemoryAreas(iptr0, iptr1, iptr2, iptr3); + } + } + + public GPUMemoryAreas GetGPU() => _gpuMemory; + + public ScanlineCallback _scanlineCallback; + public int _scanlineCallbackLine = 0; + + public void SetScanlineCallback(ScanlineCallback callback, int line) + { + _scanlineCallback = callback; + _scanlineCallbackLine = line; + + if (line == -2) + { + GetGPU(); + _scanlineCallback(ppu.LCDC); + } + } + + private PrinterCallback _printerCallback = null; + + public void SetPrinterCallback(PrinterCallback callback) + { + _printerCallback = null; + } + + #endregion + public DisplayType Region => DisplayType.NTSC; private readonly GBHawkControllerDeck _controllerDeck; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs index c21c2f46a5..21bb929a38 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs @@ -222,6 +222,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // start the next scanline if (cycle == 456) { + // scanline callback + if ((LY + LY_inc) == Core._scanlineCallbackLine) + { + if (Core._scanlineCallback != null) + { + Core._scanlineCallback(LCDC); + } + } + + cycle = 0; LY += LY_inc; //Console.WriteLine(Core.cpu.TotalExecutedCycles);