From 278b29a8409e563c71679d9289dd563118079bba Mon Sep 17 00:00:00 2001 From: nattthebear Date: Sun, 18 Jun 2017 16:05:33 -0400 Subject: [PATCH] pizza: use waterboxcore --- .../Consoles/Nintendo/Gameboy/LibPizza.cs | 15 +- .../Consoles/Nintendo/Gameboy/Pizza.cs | 130 ++++-------------- waterbox/pizza/lib/input.c | 4 +- waterbox/pizza/lib/input.h | 2 +- waterbox/pizza/pizza.c | 51 +++++-- 5 files changed, 71 insertions(+), 131 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibPizza.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibPizza.cs index 5c2776fa44..7075d63cf2 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibPizza.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibPizza.cs @@ -1,4 +1,5 @@ using BizHawk.Common.BizInvoke; +using BizHawk.Emulation.Cores.Waterbox; using System; using System.Collections.Generic; using System.Linq; @@ -8,11 +9,10 @@ using System.Threading.Tasks; namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy { - public abstract class LibPizza + public abstract class LibPizza : LibWaterboxCore { - private const CallingConvention CC = CallingConvention.Cdecl; [Flags] - public enum Buttons : ushort + public enum Buttons : int { A = 0x01, B = 0x02, @@ -24,20 +24,13 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy DOWN = 0x80 } [StructLayout(LayoutKind.Sequential)] - public class FrameInfo + public new class FrameInfo : LibWaterboxCore.FrameInfo { - public IntPtr VideoBuffer; - public IntPtr SoundBuffer; - public int Clocks; - public int Samples; public Buttons Keys; } - [BizImport(CC)] public abstract bool Init(byte[] rom, int romlen); [BizImport(CC)] - public abstract void FrameAdvance([In,Out] FrameInfo frame); - [BizImport(CC)] public abstract bool IsCGB(); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Pizza.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Pizza.cs index 7b4d174b78..d89109fe83 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Pizza.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Pizza.cs @@ -12,33 +12,42 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy { [CoreAttributes("Pizza Boy", "Davide Berra", true, false, "c7bc6ee376028b3766de8d7a02e60ab794841f45", "https://github.com/davideberra/emu-pizza/", false)] - public class Pizza : IEmulator, IInputPollable, IVideoProvider, IGameboyCommon, ISoundProvider + public class Pizza : WaterboxCore, IGameboyCommon { private LibPizza _pizza; - private PeRunner _exe; - private bool _disposed; [CoreConstructor("GB")] public Pizza(byte[] rom, CoreComm comm) + :base(comm, new Configuration + { + DefaultWidth = 160, + DefaultHeight = 144, + MaxWidth = 160, + MaxHeight = 144, + MaxSamples = 1024, + SystemId = "GB", + DefaultFpsNumerator = TICKSPERSECOND, + DefaultFpsDenominator = TICKSPERFRAME + }) { - CoreComm = comm; - ServiceProvider = new BasicServiceProvider(this); + ControllerDefinition = BizHawk.Emulation.Cores.Nintendo.Gameboy.Gameboy.GbController; - _exe = new PeRunner(new PeRunnerOptions + _pizza = PreInit(new PeRunnerOptions { Filename = "pizza.wbx", - Path = comm.CoreFileProvider.DllPath(), SbrkHeapSizeKB = 2 * 1024, InvisibleHeapSizeKB = 16 * 1024, SealedHeapSizeKB = 16 * 1024, PlainHeapSizeKB = 16 * 1024, MmapHeapSizeKB = 32 * 1024 }); - _pizza = BizInvoker.GetInvoker(_exe, _exe, CallingConventionAdapters.Waterbox); + if (!_pizza.Init(rom, rom.Length)) { throw new InvalidOperationException("Core rejected the rom!"); } + + PostInit(); } /// @@ -56,8 +65,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy /// private const int TICKSPERSECOND_SGB = 2147727; - private int _tickOverflow = 0; - private static LibPizza.Buttons GetButtons(IController c) { LibPizza.Buttons b = 0; @@ -80,108 +87,23 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy return b; } - public unsafe void FrameAdvance(IController controller, bool render, bool rendersound = true) + LibPizza.FrameInfo _tmp; // TODO: clean this up so it's not so hacky + + protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound) { - fixed (int* vp = _videoBuffer) - fixed (short* sp = _soundBuffer) + return _tmp = new LibPizza.FrameInfo { - var targetClocks = TICKSPERFRAME - _tickOverflow; - - var frame = new LibPizza.FrameInfo - { - VideoBuffer = (IntPtr)vp, - SoundBuffer = (IntPtr)sp, - Clocks = targetClocks, - Keys = GetButtons(controller) - }; - - _pizza.FrameAdvance(frame); - _tickOverflow = frame.Clocks - targetClocks; - _numSamples = frame.Samples; - Frame++; - } + Keys = GetButtons(controller) + }; } - public void Dispose() + protected override void FrameAdvancePost() { - if (!_disposed) - { - _exe.Dispose(); - _exe = null; - _pizza = null; - _disposed = true; - } + Console.WriteLine(_tmp.Cycles); + _tmp = null; } public bool IsCGBMode() => _pizza.IsCGB(); - public ControllerDefinition ControllerDefinition => BizHawk.Emulation.Cores.Nintendo.Gameboy.Gameboy.GbController; - public int Frame { get; private set; } - public int LagCount { get; set; } - public bool IsLagFrame { get; set; } - public IInputCallbackSystem InputCallbacks { get; } = new InputCallbackSystem(); - - public void ResetCounters() - { - Frame = 0; - } - - public IEmulatorServiceProvider ServiceProvider { get; private set; } - public string SystemId { get { return "GB"; } } - public bool DeterministicEmulation { get; private set; } - public CoreComm CoreComm { get; } - - #region ISoundProvider - - private short[] _soundBuffer = new short[2048]; - private int _numSamples; - - public void SetSyncMode(SyncSoundMode mode) - { - if (mode == SyncSoundMode.Async) - { - throw new NotSupportedException("Async mode is not supported."); - } - } - - public void GetSamplesSync(out short[] samples, out int nsamp) - { - samples = _soundBuffer; - nsamp = _numSamples; - } - - public void GetSamplesAsync(short[] samples) - { - throw new InvalidOperationException("Async mode is not supported."); - } - - public void DiscardSamples() - { - } - - public bool CanProvideAsync => false; - - public SyncSoundMode SyncMode => SyncSoundMode.Sync; - - #endregion - - #region IVideoProvider - - private int[] _videoBuffer = new int[160 * 144]; - - public int[] GetVideoBuffer() - { - return _videoBuffer; - } - - public int VirtualWidth => 160; - public int VirtualHeight => 144; - public int BufferWidth => 160; - public int BufferHeight => 144; - public int VsyncNumerator { get; private set; } = TICKSPERSECOND; - public int VsyncDenominator { get; private set; } = TICKSPERFRAME; - public int BackgroundColor => unchecked((int)0xff000000); - - #endregion } } diff --git a/waterbox/pizza/lib/input.c b/waterbox/pizza/lib/input.c index 0f258043a8..4dfde8d5aa 100644 --- a/waterbox/pizza/lib/input.c +++ b/waterbox/pizza/lib/input.c @@ -23,9 +23,9 @@ #include /* button states */ -static uint16_t input_keys; +static uint8_t input_keys; -void input_set_keys(uint16_t keys) +void input_set_keys(uint8_t keys) { // 7......0 // DULRSsBA diff --git a/waterbox/pizza/lib/input.h b/waterbox/pizza/lib/input.h index d878206050..3f678ea009 100644 --- a/waterbox/pizza/lib/input.h +++ b/waterbox/pizza/lib/input.h @@ -22,6 +22,6 @@ /* prototypes */ uint8_t input_get_keys(uint8_t line); -void input_set_keys(uint16_t keys); +void input_set_keys(uint8_t keys); #endif diff --git a/waterbox/pizza/pizza.c b/waterbox/pizza/pizza.c index fa34f7e56c..c72a6cc36a 100644 --- a/waterbox/pizza/pizza.c +++ b/waterbox/pizza/pizza.c @@ -20,7 +20,8 @@ #include #include #include -#include +#include "../emulibc/emulibc.h" +#include "../emulibc/waterboxcore.h" #include #define EXPORT ECL_EXPORT @@ -79,23 +80,34 @@ EXPORT int Init(const void *rom, int romlen) typedef struct { - uint32_t* vbuff; - int16_t* sbuff; - int32_t clocks; // desired(in) actual(out) time to run; 2MHZ - int32_t samples; // actual number of samples produced - uint16_t keys; // keypad input -} frameinfo_t; + uint32_t* VideoBuffer; + int16_t* SoundBuffer; + int64_t Cycles; + int32_t Width; + int32_t Height; + int32_t Samples; + int32_t Lagged; + uint32_t Keys; +} MyFrameInfo; static uint32_t* current_vbuff; +static uint64_t overflow; -EXPORT void FrameAdvance(frameinfo_t* frame) +EXPORT void FrameAdvance(MyFrameInfo* frame) { - input_set_keys(frame->keys); + input_set_keys(frame->Keys); + current_vbuff = frame->VideoBuffer; + uint64_t current = cycles.sampleclock; - current_vbuff = frame->vbuff; - gameboy_run(current + frame->clocks); - frame->clocks = cycles.sampleclock - current; - frame->samples = sound_output_read(frame->sbuff); + uint64_t target = current + 35112 - overflow; + gameboy_run(target); + uint64_t elapsed = cycles.sampleclock - current; + frame->Cycles = elapsed; + overflow = cycles.sampleclock - target; + + frame->Samples = sound_output_read(frame->SoundBuffer); + frame->Width = 160; + frame->Height = 144; current_vbuff = NULL; } @@ -104,6 +116,19 @@ EXPORT int IsCGB(void) return global_cgb; } +EXPORT void SetInputCallback(void (*callback)(void)) +{ + // TODO +} + +EXPORT void GetMemoryAreas(MemoryArea* m) +{ + m[0].Data = mmu.memory; + m[0].Name = "Fake System Bus"; + m[0].Size = 0x10000; + m[0].Flags = MEMORYAREA_FLAGS_PRIMARY | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1; +} + void frame_cb() { memcpy(current_vbuff, gpu.frame_buffer, sizeof(gpu.frame_buffer));