From 264436e6140fb40d6416cb16efceea5b2a268713 Mon Sep 17 00:00:00 2001 From: nattthebear Date: Sun, 2 Jul 2017 16:15:54 -0400 Subject: [PATCH] PicoDrive: input plus lagged and callback --- .../Consoles/Sega/PicoDrive/LibPicoDrive.cs | 7 +++++ .../Consoles/Sega/PicoDrive/PicoDrive.cs | 29 ++++++++++++++++++- waterbox/picodrive/bizhawk.c | 11 +++++++ waterbox/picodrive/pico/memory.c | 20 ++++++++----- waterbox/picodrive/pico/pico.h | 3 ++ 5 files changed, 62 insertions(+), 8 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/LibPicoDrive.cs b/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/LibPicoDrive.cs index 0d7e44e51e..43c153f1ab 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/LibPicoDrive.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/LibPicoDrive.cs @@ -3,6 +3,7 @@ using BizHawk.Emulation.Cores.Waterbox; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; @@ -10,6 +11,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive { public abstract class LibPicoDrive : LibWaterboxCore { + [StructLayout(LayoutKind.Sequential)] + public new class FrameInfo : LibWaterboxCore.FrameInfo + { + public int Buttons; + } + [BizImport(CC)] public abstract bool Init(); } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/PicoDrive.cs b/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/PicoDrive.cs index e5792d474e..2bf854b7cb 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/PicoDrive.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/PicoDrive.cs @@ -41,11 +41,38 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive throw new InvalidOperationException("Core rejected the rom!"); _exe.RemoveReadonlyFile("romfile.md"); PostInit(); + ControllerDefinition = PicoDriveController; } + public static readonly ControllerDefinition PicoDriveController = new ControllerDefinition + { + Name = "PicoDrive Genesis Controller", + BoolButtons = + { + "P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 A", "P1 B", "P1 C", "P1 Start", "P1 X", "P1 Y", "P1 Z", "P1 Mode", + "P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 A", "P2 B", "P2 C", "P2 Start", "P2 X", "P2 Y", "P2 Z", "P2 Mode", + "Power", "Reset" + } + }; + + private static readonly string[] ButtonOrders = + { + "P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 B", "P1 C", "P1 A", "P1 Start", "P1 Z", "P1 Y", "P1 X", "P1 Mode", + "P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 B", "P2 C", "P2 A", "P2 Start", "P2 Z", "P2 Y", "P2 X", "P2 Mode", + "Power", "Reset" + }; + protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound) { - return new LibWaterboxCore.FrameInfo(); + var b = 0; + var v = 1; + foreach (var s in ButtonOrders) + { + if (controller.IsPressed(s)) + b |= v; + v <<= 1; + } + return new LibPicoDrive.FrameInfo { Buttons = b }; } } } diff --git a/waterbox/picodrive/bizhawk.c b/waterbox/picodrive/bizhawk.c index 41c8d18389..ae697886d3 100644 --- a/waterbox/picodrive/bizhawk.c +++ b/waterbox/picodrive/bizhawk.c @@ -64,6 +64,7 @@ int pm_close(pm_file *fp) typedef struct { FrameInfo b; + uint32_t Buttons; } MyFrameInfo; static int video_start_line; @@ -147,8 +148,17 @@ static void Blit(void) ECL_EXPORT void FrameAdvance(MyFrameInfo *f) { current_frame = f; + PicoInputWasRead = 0; + PicoPad[0] = f->Buttons & 0xfff; + PicoPad[1] = f->Buttons >> 12 & 0xfff; + if (f->Buttons & 0x1000000) + PicoPower(); + if (f->Buttons & 0x2000000) + PicoReset(); + PicoFrame(); Blit(); + f->b.Lagged = !PicoInputWasRead; current_frame = NULL; } @@ -163,6 +173,7 @@ ECL_EXPORT void GetMemoryAreas(MemoryArea *m) ECL_EXPORT void SetInputCallback(void (*callback)(void)) { + PicoInputCallback = callback; } int main(void) diff --git a/waterbox/picodrive/pico/memory.c b/waterbox/picodrive/pico/memory.c index 4f38e5e2a3..f64b3a23a6 100644 --- a/waterbox/picodrive/pico/memory.c +++ b/waterbox/picodrive/pico/memory.c @@ -241,18 +241,24 @@ static port_read_func *port_readers[3] = { read_nothing }; +void (*PicoInputCallback)(void); +int PicoInputWasRead; + static NOINLINE u32 port_read(int i) { - u32 data_reg = Pico.ioports[i + 1]; - u32 ctrl_reg = Pico.ioports[i + 4] | 0x80; - u32 in, out; + PicoInputWasRead = 1; + if (PicoInputCallback) + PicoInputCallback(); + u32 data_reg = Pico.ioports[i + 1]; + u32 ctrl_reg = Pico.ioports[i + 4] | 0x80; + u32 in, out; - out = data_reg & ctrl_reg; - out |= 0x7f & ~ctrl_reg; // pull-ups + out = data_reg & ctrl_reg; + out |= 0x7f & ~ctrl_reg; // pull-ups - in = port_readers[i](i, out); + in = port_readers[i](i, out); - return (in & ~ctrl_reg) | (data_reg & ctrl_reg); + return (in & ~ctrl_reg) | (data_reg & ctrl_reg); } void PicoSetInputDevice(int port, enum input_device device) diff --git a/waterbox/picodrive/pico/pico.h b/waterbox/picodrive/pico/pico.h index 9a4e2b8f70..b15f67672e 100644 --- a/waterbox/picodrive/pico/pico.h +++ b/waterbox/picodrive/pico/pico.h @@ -84,6 +84,9 @@ typedef enum { PI_ROM, PI_ISPAL, PI_IS40_CELL, PI_IS240_LINES } pint_t; typedef union { int vint; void *vptr; } pint_ret_t; void PicoGetInternal(pint_t which, pint_ret_t *ret); +extern void (*PicoInputCallback)(void); +extern int PicoInputWasRead; + // cd/mcd.c extern void (*PicoMCDopenTray)(void); extern void (*PicoMCDcloseTray)(void);