diff --git a/Assets/dll/puae.wbx.zst b/Assets/dll/puae.wbx.zst index 1330a3e5e3..27c7c9d6c0 100644 Binary files a/Assets/dll/puae.wbx.zst and b/Assets/dll/puae.wbx.zst differ diff --git a/src/BizHawk.Emulation.Cores/Computers/Amiga/LibPUAE.cs b/src/BizHawk.Emulation.Cores/Computers/Amiga/LibPUAE.cs index 0d76d1e7d6..831c78bcff 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Amiga/LibPUAE.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Amiga/LibPUAE.cs @@ -16,16 +16,39 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga public const int FILENAME_MAXLENGTH = 64; public const int KEY_COUNT = 0x68; + public const byte MouseButtonsMask = + (byte)(AllButtons.Button1 + | AllButtons.Button2 + | AllButtons.Button3); + public const byte JoystickMask = + (byte)(AllButtons.Up + | AllButtons.Down + | AllButtons.Left + | AllButtons.Right + | AllButtons.Button1 + | AllButtons.Button2 + | AllButtons.Button3); + public const short Cd32padMask = + (short)(AllButtons.Up + | AllButtons.Down + | AllButtons.Left + | AllButtons.Right + | AllButtons.Play + | AllButtons.Rewind + | AllButtons.Forward + | AllButtons.Green + | AllButtons.Yellow + | AllButtons.Red + | AllButtons.Blue); + [BizImport(CC, Compatibility = true)] public abstract bool Init(int argc, string[] argv); [StructLayout(LayoutKind.Sequential)] public new class FrameInfo : LibWaterboxCore.FrameInfo { - public PUAEJoystick JoystickState; - public byte MouseButtons; - public int MouseX; - public int MouseY; + public ControllerState Port1; + public ControllerState Port2; public KeyBuffer Keys; public struct KeyBuffer { @@ -40,23 +63,31 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga } } - public enum DriveAction : int + [StructLayout(LayoutKind.Sequential)] + public struct ControllerState { - None, - Eject, - Insert + public AllButtons Buttons; + public int MouseX; + public int MouseY; } [Flags] - public enum PUAEJoystick : byte + public enum AllButtons : short { - Joystick_Up = 0b00000001, - Joystick_Down = 0b00000010, - Joystick_Left = 0b00000100, - Joystick_Right = 0b00001000, - Joystick_Button_1 = 0b00010000, - Joystick_Button_2 = 0b00100000, - Joystick_Button_3 = 0b01000000 + Up = 0b0000000000000001, + Down = 0b0000000000000010, + Left = 0b0000000000000100, + Right = 0b0000000000001000, + Button1 = 0b0000000000010000, + Button2 = 0b0000000000100000, + Button3 = 0b0000000001000000, + Play = 0b0000000010000000, + Rewind = 0b0000000100000000, + Forward = 0b0000001000000000, + Green = 0b0000010000000000, + Yellow = 0b0000100000000000, + Red = 0b0001000000000000, + Blue = 0b0010000000000000 } // https://wiki.amigaos.net/wiki/Keymap_Library @@ -167,5 +198,12 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga Key_Left_Amiga = 0x66, Key_Right_Amiga = 0x67, } + + public enum DriveAction : int + { + None, + Eject, + Insert + } } } \ No newline at end of file diff --git a/src/BizHawk.Emulation.Cores/Computers/Amiga/PUAE.Controllers.cs b/src/BizHawk.Emulation.Cores/Computers/Amiga/PUAE.Controllers.cs new file mode 100644 index 0000000000..eb1d58cbcc --- /dev/null +++ b/src/BizHawk.Emulation.Cores/Computers/Amiga/PUAE.Controllers.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using BizHawk.Common; +using BizHawk.Common.CollectionExtensions; +using BizHawk.Emulation.Common; + +namespace BizHawk.Emulation.Cores.Computers.Amiga +{ + public partial class PUAE + { + private static readonly (string Name, LibPUAE.AllButtons Button)[] _joystickMap = CreateJoystickMap(); + private static readonly (string Name, LibPUAE.AllButtons Button)[] _cd32padMap = CreateCd32padMap(); + private static readonly (string Name, LibPUAE.PUAEKeyboard Key)[] _keyboardMap = CreateKeyboardMap(); + + private static (string Name, LibPUAE.AllButtons Value)[] CreateJoystickMap() + { + var joystickMap = new List<(string, LibPUAE.AllButtons)>(); + // ReSharper disable once LoopCanBeConvertedToQuery + foreach (var b in Enum.GetValues(typeof(LibPUAE.AllButtons))) + { + if (((short)b & LibPUAE.JoystickMask) == 0) + continue; + + var name = Enum.GetName(typeof(LibPUAE.AllButtons), b)!.Replace('_', ' '); + joystickMap.Add((name, (LibPUAE.AllButtons)b)); + } + return joystickMap.ToArray(); + } + + private static (string Name, LibPUAE.AllButtons Value)[] CreateCd32padMap() + { + var joystickMap = new List<(string, LibPUAE.AllButtons)>(); + // ReSharper disable once LoopCanBeConvertedToQuery + foreach (var b in Enum.GetValues(typeof(LibPUAE.AllButtons))) + { + if (((short)b & LibPUAE.Cd32padMask) == 0) + continue; + + var name = Enum.GetName(typeof(LibPUAE.AllButtons), b)!.Replace('_', ' '); + joystickMap.Add((name, (LibPUAE.AllButtons)b)); + } + return joystickMap.ToArray(); + } + + private static (string Name, LibPUAE.PUAEKeyboard Value)[] CreateKeyboardMap() + { + var keyboardMap = new List<(string, LibPUAE.PUAEKeyboard)>(); + // ReSharper disable once LoopCanBeConvertedToQuery + foreach (var k in Enum.GetValues(typeof(LibPUAE.PUAEKeyboard))) + { + var name = Enum.GetName(typeof(LibPUAE.PUAEKeyboard), k)!.Replace('_', ' '); + keyboardMap.Add((name, (LibPUAE.PUAEKeyboard)k)); + } + + return keyboardMap.ToArray(); + } + + private static ControllerDefinition CreateControllerDefinition(PUAESyncSettings settings) + { + var controller = new ControllerDefinition("Amiga Controller"); + + for (int port = 1; port <= 2; port++) + { + ControllerType type = port == 1 + ? settings.ControllerPort1 + : settings.ControllerPort2; + + switch (type) + { + case ControllerType.Joystick: + { + foreach (var (name, _) in _joystickMap) + { + controller.BoolButtons.Add($"P{port} {Inputs.Joystick} {name}"); + } + break; + } + case ControllerType.CD32_pad: + { + foreach (var (name, _) in _cd32padMap) + { + controller.BoolButtons.Add($"P{port} {Inputs.Cd32Pad} {name}"); + } + break; + } + case ControllerType.Mouse: + { + controller.BoolButtons.AddRange( + [ + $"P{port} {Inputs.MouseLeftButton}", + $"P{port} {Inputs.MouseMiddleButton}", + $"P{port} {Inputs.MouseRightButton}" + ]); + controller + .AddAxis($"P{port} {Inputs.MouseX}", 0.RangeTo(LibPUAE.PAL_WIDTH), LibPUAE.PAL_WIDTH / 2) + .AddAxis($"P{port} {Inputs.MouseY}", 0.RangeTo(LibPUAE.PAL_HEIGHT), LibPUAE.PAL_HEIGHT / 2); + break; + } + } + } + + controller.BoolButtons.AddRange( + [ + Inputs.NextDrive, Inputs.NextSlot, Inputs.Insert, Inputs.Eject + ]); + + foreach (var (name, _) in _keyboardMap) + { + controller.BoolButtons.Add(name); + controller.CategoryLabels[name] = "Keyboard"; + } + + return controller.MakeImmutable(); + } + + private static class Inputs + { + public const string Joystick = "Joystick"; + public const string Cd32Pad = "CD32 pad"; + public const string MouseLeftButton = "Mouse Left Button"; + public const string MouseRightButton = "Mouse Right Button"; + public const string MouseMiddleButton = "Mouse Middle Button"; + public const string MouseX = "Mouse X"; + public const string MouseY = "Mouse Y"; + public const string Eject = "Eject"; + public const string Insert = "Insert"; + public const string NextDrive = "Next Drive"; + public const string NextSlot = "Next Slot"; + } + } +} diff --git a/src/BizHawk.Emulation.Cores/Computers/Amiga/PUAE.ISettable.cs b/src/BizHawk.Emulation.Cores/Computers/Amiga/PUAE.ISettable.cs index 8dbbec06b8..3af8335484 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Amiga/PUAE.ISettable.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Amiga/PUAE.ISettable.cs @@ -130,6 +130,14 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga DRV_FB } + public enum ControllerType + { + Joystick, + Mouse, + [Display(Name = "CD32 pad")] + CD32_pad + } + private void CreateArguments(PUAESyncSettings settings) { _args = new List @@ -240,6 +248,17 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga AppendSetting("sound_stereo_separation=" + settings.StereoSeparation / 10); } + private void EnableCycleExact() + { + AppendSetting(new List + { + "cpu_compatible=true", + "cpu_cycle_exact=true", + "cpu_memory_cycle_exact=true", + "blitter_cycle_exact=true", + }); + } + private void AppendSetting(List settings) { foreach (var s in settings) @@ -255,17 +274,6 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga "-s", setting }); } - - private void EnableCycleExact() - { - AppendSetting(new List - { - "cpu_compatible=true", - "cpu_cycle_exact=true", - "cpu_memory_cycle_exact=true", - "blitter_cycle_exact=true", - }); - } public object GetSettings() => null; public PutSettingsDirtyBits PutSettings(object o) => PutSettingsDirtyBits.None; @@ -326,6 +334,18 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga [TypeConverter(typeof(ConstrainedIntConverter))] public int FastMemory { get; set; } + [DisplayName("Controller port 1")] + [Description("")] + [DefaultValue(ControllerType.Joystick)] + [TypeConverter(typeof(DescribableEnumConverter))] + public ControllerType ControllerPort1 { get; set; } + + [DisplayName("Controller port 2")] + [Description("")] + [DefaultValue(ControllerType.Mouse)] + [TypeConverter(typeof(DescribableEnumConverter))] + public ControllerType ControllerPort2 { get; set; } + [DisplayName("Mouse speed")] [Description("Mouse speed in percents (1% - 1000%). Adjust if there's mismatch between emulated and host mouse movement. Note that maximum mouse movement is still 127 pixels due to Amiga hardware limitations.")] [Range(1, 1000)] diff --git a/src/BizHawk.Emulation.Cores/Computers/Amiga/PUAE.cs b/src/BizHawk.Emulation.Cores/Computers/Amiga/PUAE.cs index 3ee5f7bf12..858bd75623 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Amiga/PUAE.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Amiga/PUAE.cs @@ -3,7 +3,6 @@ using System.IO; using System.Text; using BizHawk.Common; -using BizHawk.Common.CollectionExtensions; using BizHawk.Common.StringExtensions; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Waterbox; @@ -52,7 +51,7 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga _syncSettings.FloppyDrives = Math.Min(LibPUAE.MAX_FLOPPIES, _syncSettings.FloppyDrives); var filesToRemove = new List(); CreateArguments(_syncSettings); - ControllerDefinition = _controllerDefinition; + ControllerDefinition = CreateControllerDefinition(_syncSettings); var paue = PreInit(new WaterboxOptions { @@ -68,7 +67,7 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga for (var index = 0; index < lp.Roms.Count; index++) { - if (lp.Roms[index].Extension.ToLowerInvariant() == ".hdf") + if (lp.Roms[index].Extension.ToLowerInvariant() == ".hdf") // doesn't work yet { var access = "ro"; var device_name = "DH0"; @@ -141,111 +140,74 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga PostInit(); } - private static readonly (string Name, LibPUAE.PUAEJoystick Button)[] _joystickMap = CreateJoystickMap(); - private static readonly (string Name, LibPUAE.PUAEKeyboard Key)[] _keyboardMap = CreateKeyboardMap(); - private static readonly ControllerDefinition _controllerDefinition = CreateControllerDefinition(); - - private static (string Name, LibPUAE.PUAEJoystick Value)[] CreateJoystickMap() - { - var joystickMap = new List<(string, LibPUAE.PUAEJoystick)>(); - // ReSharper disable once LoopCanBeConvertedToQuery - foreach (var b in Enum.GetValues(typeof(LibPUAE.PUAEJoystick))) - { - var name = Enum.GetName(typeof(LibPUAE.PUAEJoystick), b)!.Replace('_', ' '); - joystickMap.Add((name, (LibPUAE.PUAEJoystick)b)); - } - - return joystickMap.ToArray(); - } - - private static (string Name, LibPUAE.PUAEKeyboard Value)[] CreateKeyboardMap() - { - var keyboardMap = new List<(string, LibPUAE.PUAEKeyboard)>(); - // ReSharper disable once LoopCanBeConvertedToQuery - foreach (var k in Enum.GetValues(typeof(LibPUAE.PUAEKeyboard))) - { - var name = Enum.GetName(typeof(LibPUAE.PUAEKeyboard), k)!.Replace('_', ' '); - keyboardMap.Add((name, (LibPUAE.PUAEKeyboard)k)); - } - - return keyboardMap.ToArray(); - } - - private static ControllerDefinition CreateControllerDefinition() - { - var controller = new ControllerDefinition("Amiga Controller"); - - foreach (var (name, _) in _joystickMap) - { - controller.BoolButtons.Add(name); - controller.CategoryLabels[name] = "Joystick"; - } - - controller.BoolButtons.AddRange( - [ - Inputs.MouseLeftButton, Inputs.MouseMIddleButton, Inputs.MouseRightButton - ]); - - controller - .AddAxis(Inputs.MouseX, 0.RangeTo(LibPUAE.PAL_WIDTH), LibPUAE.PAL_WIDTH / 2) - .AddAxis(Inputs.MouseY, 0.RangeTo(LibPUAE.PAL_HEIGHT), LibPUAE.PAL_HEIGHT / 2); - - foreach (var b in controller.BoolButtons) - { - if (b.StartsWithOrdinal("Mouse")) - { - controller.CategoryLabels[b] = "Mouse"; - } - } - - controller.BoolButtons.AddRange( - [ - Inputs.NextDrive, Inputs.NextSlot, Inputs.Insert, Inputs.Eject - ]); - - foreach (var (name, _) in _keyboardMap) - { - controller.BoolButtons.Add(name); - controller.CategoryLabels[name] = "Keyboard"; - } - - return controller.MakeImmutable(); - } - protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound) { var fi = new LibPUAE.FrameInfo { - MouseButtons = 0, + Port1 = new LibPUAE.ControllerState + { + Buttons = 0 + }, + Port2 = new LibPUAE.ControllerState + { + Buttons = 0 + }, Action = LibPUAE.DriveAction.None }; - foreach (var (name, button) in _joystickMap) - { - if (controller.IsPressed(name)) + for (int port = 1; port <= 2; port++) + { + ControllerType type = (port == 1) ? _syncSettings.ControllerPort1 : _syncSettings.ControllerPort2; + var currentPort = (port == 1) ? fi.Port1 : fi.Port2; + + switch (type) { - fi.JoystickState |= button; + case ControllerType.Joystick: + { + foreach (var (name, button) in _joystickMap) + { + if (controller.IsPressed($"P{port} {name}")) + { + currentPort.Buttons |= button; + } + } + break; + } + case ControllerType.CD32_pad: + { + foreach (var (name, button) in _cd32padMap) + { + if (controller.IsPressed($"P{port} {name}")) + { + currentPort.Buttons |= button; + } + } + break; + } + case ControllerType.Mouse: + { + if (controller.IsPressed($"P{port} {Inputs.MouseLeftButton}")) + { + currentPort.Buttons |= LibPUAE.AllButtons.Button1; + } + + if (controller.IsPressed($"P{port} {Inputs.MouseRightButton}")) + { + currentPort.Buttons |= LibPUAE.AllButtons.Button2; + } + + if (controller.IsPressed($"P{port} {Inputs.MouseMiddleButton}")) + { + currentPort.Buttons |= LibPUAE.AllButtons.Button3; + } + + currentPort.MouseX = controller.AxisValue($"P{port} {Inputs.MouseX}"); + currentPort.MouseY = controller.AxisValue($"P{port} {Inputs.MouseY}"); + break; + } } } - if (controller.IsPressed(Inputs.MouseLeftButton)) - { - fi.MouseButtons |= 0b00000001; - } - - if (controller.IsPressed(Inputs.MouseRightButton)) - { - fi.MouseButtons |= 0b00000010; - } - - if (controller.IsPressed(Inputs.MouseMIddleButton)) - { - fi.MouseButtons |= 0b00000100; - } - - fi.MouseX = controller.AxisValue(Inputs.MouseX); - fi.MouseY = controller.AxisValue(Inputs.MouseY); - if (controller.IsPressed(Inputs.Eject)) { if (!_ejectPressed) @@ -344,18 +306,5 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga public const string CD = "CompactDisk"; public const string HD = "HardDrive"; } - - private static class Inputs - { - public const string MouseLeftButton = "Mouse Left Button"; - public const string MouseRightButton = "Mouse Right Button"; - public const string MouseMIddleButton = "Mouse Middle Button"; - public const string MouseX = "Mouse X"; - public const string MouseY = "Mouse Y"; - public const string Eject = "Eject"; - public const string Insert = "Insert"; - public const string NextDrive = "Next Drive"; - public const string NextSlot = "Next Slot"; - } } } \ No newline at end of file diff --git a/waterbox/uae/bizhawk.c b/waterbox/uae/bizhawk.c index c6e7d78996..c9b2b77724 100644 --- a/waterbox/uae/bizhawk.c +++ b/waterbox/uae/bizhawk.c @@ -23,8 +23,19 @@ ECL_EXPORT bool Init(int argc, char **argv) return true; } +void SetCD32ButtonState(int port, int button, int state) +{ + if (state) + joybutton[port] |= 1 << button; + else + joybutton[port] &= ~(1 << button); +} + ECL_EXPORT void FrameAdvance(MyFrameInfo* f) { + + cd32_pad_enabled[0] = 1; + cd32_pad_enabled[1] = 1; bool is_ntsc = minfirstline == VBLANK_ENDLINE_NTSC; f->base.Width = PUAE_VIDEO_WIDTH; f->base.Height = is_ntsc ? PUAE_VIDEO_HEIGHT_NTSC : PUAE_VIDEO_HEIGHT_PAL; @@ -38,9 +49,17 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo* f) setjoystickstate(PORT_0, AXIS_HORIZONTAL, f->JoystickState.left ? JOY_MIN : f->JoystickState.right ? JOY_MAX : JOY_MID, 1); - setjoybuttonstate(PORT_0, 0, f->JoystickState.b1); - setjoybuttonstate(PORT_0, 1, f->JoystickState.b2); - setjoybuttonstate(PORT_0, 2, f->JoystickState.b3); + setjoybuttonstate(PORT_0, JOYBUTTON_1, f->JoystickState.b1); + setjoybuttonstate(PORT_0, JOYBUTTON_2, f->JoystickState.b2); + setjoybuttonstate(PORT_0, JOYBUTTON_3, f->JoystickState.b3); + + SetCD32ButtonState(PORT_0, JOYBUTTON_CD32_PLAY, f->JoystickState.b4); + SetCD32ButtonState(PORT_0, JOYBUTTON_CD32_RWD, f->JoystickState.b5); + SetCD32ButtonState(PORT_0, JOYBUTTON_CD32_FFW, f->JoystickState.b6); + SetCD32ButtonState(PORT_0, JOYBUTTON_CD32_GREEN, f->JoystickState.b7); + SetCD32ButtonState(PORT_0, JOYBUTTON_CD32_YELLOW, f->JoystickState.b8); + SetCD32ButtonState(PORT_0, JOYBUTTON_CD32_RED, f->JoystickState.b9); + SetCD32ButtonState(PORT_0, JOYBUTTON_CD32_BLUE, f->JoystickState.b10); setmousebuttonstate(PORT_0, MOUSE_LEFT, f->MouseButtons & 1); setmousebuttonstate(PORT_0, MOUSE_RIGHT, f->MouseButtons & 2); diff --git a/waterbox/uae/bizhawk.h b/waterbox/uae/bizhawk.h index 45a88f7034..0b4560d808 100644 --- a/waterbox/uae/bizhawk.h +++ b/waterbox/uae/bizhawk.h @@ -19,6 +19,7 @@ #include "include/drawing.h" #include "include/inputdevice.h" +// libretro #include "libretro/libretro-core.h" static const int FILENAME_MAXLENGTH = 4; @@ -34,6 +35,8 @@ extern int thisframe_y_adjust; extern unsigned short int defaultw; extern unsigned short int defaulth; extern int retro_max_diwlastword; +extern int cd32_pad_enabled[NORMAL_JPORTS]; +extern int joybutton[MAX_JPORTS]; extern int umain(int argc, char **argv); extern int m68k_go(int may_quit, int resume); @@ -98,8 +101,15 @@ typedef union bool b1:1; bool b2:1; bool b3:1; + bool b4:1; + bool b5:1; + bool b6:1; + bool b7:1; + bool b8:1; + bool b9:1; + bool b10:1; }; - uint8_t data; + uint16_t data; } PUAEJoystick; typedef struct diff --git a/waterbox/uae/libretro-uae b/waterbox/uae/libretro-uae index 5de7a00350..79fa9cd5a0 160000 --- a/waterbox/uae/libretro-uae +++ b/waterbox/uae/libretro-uae @@ -1 +1 @@ -Subproject commit 5de7a00350b21f79805881cf36af8234aa7c3fd6 +Subproject commit 79fa9cd5a067713a4e5e51472b9bca1f7e499bc8