puae: controller config wip

This commit is contained in:
feos 2024-11-05 23:57:56 +03:00
parent 6b2d2cb646
commit 869bef4989
8 changed files with 311 additions and 142 deletions

Binary file not shown.

View File

@ -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
}
}
}

View File

@ -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";
}
}
}

View File

@ -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<string>
@ -240,6 +248,17 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga
AppendSetting("sound_stereo_separation=" + settings.StereoSeparation / 10);
}
private void EnableCycleExact()
{
AppendSetting(new List<string>
{
"cpu_compatible=true",
"cpu_cycle_exact=true",
"cpu_memory_cycle_exact=true",
"blitter_cycle_exact=true",
});
}
private void AppendSetting(List<string> settings)
{
foreach (var s in settings)
@ -255,17 +274,6 @@ namespace BizHawk.Emulation.Cores.Computers.Amiga
"-s", setting
});
}
private void EnableCycleExact()
{
AppendSetting(new List<string>
{
"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)]

View File

@ -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<string>();
CreateArguments(_syncSettings);
ControllerDefinition = _controllerDefinition;
ControllerDefinition = CreateControllerDefinition(_syncSettings);
var paue = PreInit<LibPUAE>(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";
}
}
}

View File

@ -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);

View File

@ -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

@ -1 +1 @@
Subproject commit 5de7a00350b21f79805881cf36af8234aa7c3fd6
Subproject commit 79fa9cd5a067713a4e5e51472b9bca1f7e499bc8