diff --git a/BizHawk.Emulation/Consoles/Nintendo/GBA/LibMeteor.cs b/BizHawk.Emulation/Consoles/Nintendo/GBA/LibMeteor.cs index ae7168156b..e0c33e2c34 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/GBA/LibMeteor.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/GBA/LibMeteor.cs @@ -77,5 +77,38 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA /// [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void libmeteor_setmessagecallback(MessageCallback cb); + + /// + /// combination of button flags used by the key callback + /// + [Flags] + public enum Buttons : ushort + { + BTN_A = 0x001, + BTN_B = 0x002, + BTN_SELECT = 0x004, + BTN_START = 0x008, + BTN_RIGHT = 0x010, + BTN_LEFT = 0x020, + BTN_UP = 0x040, + BTN_DOWN = 0x080, + BTN_R = 0x100, + BTN_L = 0x200 + } + + /// + /// core callback to get input state + /// + /// buttons pressed bitfield + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate Buttons InputCallback(); + + /// + /// set callback for whenever input is requested + /// + /// + [DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void libmeteor_setkeycallback(InputCallback callback); + } } diff --git a/BizHawk.Emulation/Consoles/Nintendo/GBA/Meteor.cs b/BizHawk.Emulation/Consoles/Nintendo/GBA/Meteor.cs index fc5cfef4ac..43a75cb3c3 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/GBA/Meteor.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/GBA/Meteor.cs @@ -31,12 +31,17 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA public void FrameAdvance(bool render, bool rendersound = true) { + Controller.UpdateControls(Frame++); + IsLagFrame = true; LibMeteor.libmeteor_frameadvance(); + if (IsLagFrame) + LagCount++; } public int Frame { - get { return 0; } + get; + private set; } public int LagCount @@ -47,7 +52,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA public bool IsLagFrame { - get { return false; } + get; + private set; } public string SystemId @@ -77,8 +83,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA public void ResetFrameCounter() { + Frame = 0; + LagCount = 0; } + #region savestates + public void SaveStateText(System.IO.TextWriter writer) { } @@ -104,6 +114,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA return ms.ToArray(); } + #endregion + public CoreInputComm CoreInputComm { get; set; } CoreOutputComm _CoreOutputComm = new CoreOutputComm @@ -126,6 +138,25 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA static GBA attachedcore; LibMeteor.MessageCallback messagecallback; + LibMeteor.InputCallback inputcallback; + + LibMeteor.Buttons GetInput() + { + IsLagFrame = false; + LibMeteor.Buttons ret = 0; + if (Controller["Up"]) ret |= LibMeteor.Buttons.BTN_UP; + if (Controller["Down"]) ret |= LibMeteor.Buttons.BTN_DOWN; + if (Controller["Left"]) ret |= LibMeteor.Buttons.BTN_LEFT; + if (Controller["Right"]) ret |= LibMeteor.Buttons.BTN_RIGHT; + if (Controller["Select"]) ret |= LibMeteor.Buttons.BTN_SELECT; + if (Controller["Start"]) ret |= LibMeteor.Buttons.BTN_START; + if (Controller["B"]) ret |= LibMeteor.Buttons.BTN_B; + if (Controller["A"]) ret |= LibMeteor.Buttons.BTN_A; + if (Controller["L"]) ret |= LibMeteor.Buttons.BTN_L; + if (Controller["R"]) ret |= LibMeteor.Buttons.BTN_R; + return ret; + } + void Init() { @@ -133,7 +164,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA attachedcore.Dispose(); messagecallback = (str) => Console.Write(str.Replace("\n","\r\n")); + inputcallback = GetInput; LibMeteor.libmeteor_setmessagecallback(messagecallback); + LibMeteor.libmeteor_setkeycallback(inputcallback); LibMeteor.libmeteor_init(); videobuffer = new int[240 * 160]; diff --git a/BizHawk.MultiClient/output/dll/libmeteor.dll b/BizHawk.MultiClient/output/dll/libmeteor.dll index bb3bdf477d..a6a52228bf 100644 Binary files a/BizHawk.MultiClient/output/dll/libmeteor.dll and b/BizHawk.MultiClient/output/dll/libmeteor.dll differ diff --git a/libmeteor/cinterface.cpp b/libmeteor/cinterface.cpp index ff8957f675..712faed8f0 100644 --- a/libmeteor/cinterface.cpp +++ b/libmeteor/cinterface.cpp @@ -23,6 +23,19 @@ void print_bizhawk(std::string &msg) messagecallback(msg.c_str()); } +uint16_t (*keycallback)() = NULL; + +void keyupdate_bizhawk() +{ + if (keycallback) + AMeteor::_keypad.SetPadState(keycallback() ^ 0x3FF); +} + +EXPORT void libmeteor_setkeycallback(uint16_t (*callback)()) +{ + keycallback = callback; +} + EXPORT void libmeteor_reset() { AMeteor::Reset(AMeteor::UNIT_ALL ^ AMeteor::UNIT_MEMORY_BIOS); @@ -96,7 +109,7 @@ EXPORT void libmeteor_init() EXPORT void libmeteor_frameadvance() { - AMeteor::_keypad.SetPadState(0x3ff); + //AMeteor::_keypad.SetPadState(0x3ff); AMeteor::Run(10000000); } diff --git a/libmeteor/source/debug.hpp b/libmeteor/source/debug.hpp index 3e77a7e181..a3324ee7d9 100644 --- a/libmeteor/source/debug.hpp +++ b/libmeteor/source/debug.hpp @@ -28,6 +28,7 @@ // from cinterface.cpp void print_bizhawk(const char *msg); void print_bizhawk(std::string &msg); +void keyupdate_bizhawk(); #if 0 #define met_abort(str) \ diff --git a/libmeteor/source/io.cpp b/libmeteor/source/io.cpp index c0cd244ab1..c9cbffc25a 100644 --- a/libmeteor/source/io.cpp +++ b/libmeteor/source/io.cpp @@ -99,6 +99,8 @@ namespace AMeteor // TODO implement unreadable or write-only io uint8_t Io::Read8 (uint32_t add) { + if ((add & 0xFFE) == KEYINPUT) + keyupdate_bizhawk(); //debug ("IO Read8 at " << IOS_ADD << add << " of " << IOS_ADD << (int)*(uint8_t*)(m_iomem + (add & 0xFFF))); if ((add & 0xFF0) == 0x100) switch (add & 0xF) @@ -114,6 +116,8 @@ namespace AMeteor uint16_t Io::Read16 (uint32_t add) { + if ((add & 0xFFE) == KEYINPUT) + keyupdate_bizhawk(); //debug ("IO Read16 at " << IOS_ADD << add << " of " << IOS_ADD << *(uint16_t*)(m_iomem + (add & 0xFFF))); // special case, reading timers if ((add & 0xFF0) == 0x100) @@ -129,6 +133,8 @@ namespace AMeteor uint32_t Io::Read32 (uint32_t add) { + if ((add & 0xFFC) == KEYINPUT) + keyupdate_bizhawk(); //debug ("IO Read32 at " << IOS_ADD << add << " of " << IOS_ADD << *(uint32_t*)(m_iomem + (add & 0xFFF))); // special case, reading timers if ((add & 0xFF0) == 0x100)