Support for Maracas & Pop'n Music controllers, WIP for others (#1035)
Racing controller, fishing controller and Densha de Go controller Co-authored-by: Ricardo <ric.ce.br@gmail.com> Co-authored-by: Flyinghead <raphael.jean@gmail.com>
This commit is contained in:
parent
f95c7212bf
commit
885714e883
|
@ -1,4 +1,5 @@
|
|||
build/
|
||||
artifact/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
@ -6,8 +7,13 @@ shell/apple/emulator-ios/OpenMP/OpenMP.xcframework
|
|||
|
||||
# Visual Studio
|
||||
.vs/
|
||||
.vscode/
|
||||
out/
|
||||
|
||||
# JetBrains IDES
|
||||
.idea/
|
||||
cmake-build-*/
|
||||
|
||||
# Dependencies from .gitmodules
|
||||
core/deps/breakpad/
|
||||
core/deps/glslang/
|
||||
|
|
|
@ -76,8 +76,14 @@ void MapleConfigMap::GetInput(PlainJoystickState* pjs)
|
|||
pjs->kcode = inputState.kcode;
|
||||
pjs->joy[PJAI_X1] = GetBtFromSgn(inputState.fullAxes[PJAI_X1]);
|
||||
pjs->joy[PJAI_Y1] = GetBtFromSgn(inputState.fullAxes[PJAI_Y1]);
|
||||
pjs->joy[PJAI_X2] = GetBtFromSgn(inputState.fullAxes[PJAI_X2]);
|
||||
pjs->joy[PJAI_Y2] = GetBtFromSgn(inputState.fullAxes[PJAI_Y2]);
|
||||
pjs->joy[PJAI_X3] = GetBtFromSgn(inputState.fullAxes[PJAI_X3]);
|
||||
pjs->joy[PJAI_Y3] = GetBtFromSgn(inputState.fullAxes[PJAI_Y3]);
|
||||
pjs->trigger[PJTI_R] = inputState.halfAxes[PJTI_R];
|
||||
pjs->trigger[PJTI_L] = inputState.halfAxes[PJTI_L];
|
||||
pjs->trigger[PJTI_L2] = inputState.halfAxes[PJTI_L2];
|
||||
pjs->trigger[PJTI_R2] = inputState.halfAxes[PJTI_R2];
|
||||
}
|
||||
else if (settings.platform.isAtomiswave())
|
||||
{
|
||||
|
@ -290,27 +296,20 @@ static void createDreamcastDevices()
|
|||
break;
|
||||
|
||||
case MDT_Keyboard:
|
||||
mcfg_Create(MDT_Keyboard, bus, 5);
|
||||
break;
|
||||
|
||||
case MDT_Mouse:
|
||||
mcfg_Create(MDT_Mouse, bus, 5);
|
||||
case MDT_MaracasController:
|
||||
case MDT_FishingController:
|
||||
case MDT_PopnMusicController:
|
||||
case MDT_RacingController:
|
||||
case MDT_DenshaDeGoController:
|
||||
case MDT_Dreameye:
|
||||
mcfg_Create(config::MapleMainDevices[bus], bus, 5);
|
||||
break;
|
||||
|
||||
case MDT_LightGun:
|
||||
mcfg_Create(MDT_LightGun, bus, 5);
|
||||
if (config::MapleExpansionDevices[bus][0] != MDT_None)
|
||||
mcfg_Create(config::MapleExpansionDevices[bus][0], bus, 0);
|
||||
break;
|
||||
|
||||
case MDT_TwinStick:
|
||||
mcfg_Create(MDT_TwinStick, bus, 5);
|
||||
if (config::MapleExpansionDevices[bus][0] != MDT_None)
|
||||
mcfg_Create(config::MapleExpansionDevices[bus][0], bus, 0);
|
||||
break;
|
||||
|
||||
case MDT_AsciiStick:
|
||||
mcfg_Create(MDT_AsciiStick, bus, 5);
|
||||
mcfg_Create(config::MapleMainDevices[bus], bus, 5);
|
||||
if (config::MapleExpansionDevices[bus][0] != MDT_None)
|
||||
mcfg_Create(config::MapleExpansionDevices[bus][0], bus, 0);
|
||||
break;
|
||||
|
|
|
@ -3,21 +3,25 @@
|
|||
|
||||
enum MapleDeviceType
|
||||
{
|
||||
MDT_SegaController,
|
||||
|
||||
MDT_SegaVMU,
|
||||
MDT_Microphone,
|
||||
MDT_PurupuruPack,
|
||||
MDT_AsciiStick,
|
||||
MDT_Keyboard,
|
||||
MDT_Mouse,
|
||||
MDT_LightGun,
|
||||
MDT_TwinStick,
|
||||
|
||||
MDT_NaomiJamma,
|
||||
|
||||
MDT_None,
|
||||
MDT_RFIDReaderWriter,
|
||||
MDT_SegaController = 0,
|
||||
MDT_SegaVMU = 1,
|
||||
MDT_Microphone = 2,
|
||||
MDT_PurupuruPack = 3,
|
||||
MDT_AsciiStick = 4,
|
||||
MDT_Keyboard = 5,
|
||||
MDT_Mouse = 6,
|
||||
MDT_LightGun = 7,
|
||||
MDT_TwinStick = 8,
|
||||
MDT_NaomiJamma = 9,
|
||||
MDT_None = 10,
|
||||
MDT_RFIDReaderWriter = 11,
|
||||
MDT_MaracasController = 12,
|
||||
MDT_FishingController = 13,
|
||||
MDT_PopnMusicController = 14,
|
||||
MDT_RacingController = 15,
|
||||
MDT_DenshaDeGoController = 16,
|
||||
MDT_Dreameye = 17,
|
||||
MDT_Count
|
||||
};
|
||||
|
||||
enum PlainJoystickAxisId
|
||||
|
@ -26,24 +30,29 @@ enum PlainJoystickAxisId
|
|||
PJAI_Y1 = 1,
|
||||
PJAI_X2 = 2,
|
||||
PJAI_Y2 = 3,
|
||||
|
||||
PJAI_Count = 4
|
||||
PJAI_X3 = 4,
|
||||
PJAI_Y3 = 5,
|
||||
PJAI_Count = 6
|
||||
};
|
||||
|
||||
enum PlainJoystickTriggerId
|
||||
{
|
||||
PJTI_L = 0,
|
||||
PJTI_R = 1,
|
||||
|
||||
PJTI_Count = 2
|
||||
PJTI_L2 = 2,
|
||||
PJTI_R2 = 3,
|
||||
PJTI_Count = 4
|
||||
};
|
||||
|
||||
struct PlainJoystickState
|
||||
{
|
||||
PlainJoystickState()
|
||||
{
|
||||
joy[0]=joy[1]=joy[2]=joy[3]=0x80;
|
||||
trigger[0]=trigger[1]=0;
|
||||
u32 i;
|
||||
for (i=0; i < PJAI_Count; i++)
|
||||
joy[i] = 0x80;
|
||||
for (i=0; i < PJTI_Count; i++)
|
||||
trigger[i] = 0;
|
||||
}
|
||||
|
||||
u32 kcode = ~0;
|
||||
|
@ -81,8 +90,8 @@ struct MapleInputState
|
|||
}
|
||||
|
||||
u32 kcode = ~0;
|
||||
u8 halfAxes[PJTI_Count]; // LT, RT
|
||||
int8_t fullAxes[PJAI_Count]; // Left X, Y, Right X, Y
|
||||
u8 halfAxes[PJTI_Count]; // LT, RT, 2, 3
|
||||
int8_t fullAxes[PJAI_Count]; // Left X, Y, Right X, Y, Other X, Other Y
|
||||
u8 mouseButtons = ~0;
|
||||
struct {
|
||||
int x = -1;
|
||||
|
|
|
@ -11,16 +11,21 @@
|
|||
#include <time.h>
|
||||
|
||||
const char* maple_sega_controller_name = "Dreamcast Controller";
|
||||
const char* maple_sega_vmu_name = "Visual Memory";
|
||||
const char* maple_sega_kbd_name = "Emulated Dreamcast Keyboard";
|
||||
const char* maple_sega_mouse_name = "Emulated Dreamcast Mouse";
|
||||
const char* maple_sega_dreameye_name_1 = "Dreamcast Camera Flash Devic";
|
||||
const char* maple_sega_dreameye_name_2 = "Dreamcast Camera Flash LDevic";
|
||||
const char* maple_sega_mic_name = "MicDevice for Dreameye";
|
||||
const char* maple_sega_purupuru_name = "Puru Puru Pack";
|
||||
const char* maple_sega_lightgun_name = "Dreamcast Gun";
|
||||
const char* maple_sega_twinstick_name = "Twin Stick";
|
||||
const char* maple_ascii_stick_name = "ASCII STICK";
|
||||
const char* maple_sega_vmu_name = "Visual Memory";
|
||||
const char* maple_sega_kbd_name = "Emulated Dreamcast Keyboard";
|
||||
const char* maple_sega_mouse_name = "Emulated Dreamcast Mouse";
|
||||
const char* maple_sega_dreameye_name_1 = "Dreamcast Camera Flash Device";
|
||||
const char* maple_sega_dreameye_name_2 = "Dreamcast Camera Flash LDevice";
|
||||
const char* maple_sega_mic_name = "MicDevice for Dreameye";
|
||||
const char* maple_sega_purupuru_name = "Puru Puru Pack";
|
||||
const char* maple_sega_lightgun_name = "Dreamcast Gun";
|
||||
const char* maple_sega_twinstick_name = "Twin Stick";
|
||||
const char* maple_ascii_stick_name = "ASCII STICK";
|
||||
const char* maple_maracas_controller_name = "Maracas Controller";
|
||||
const char* maple_fishing_controller_name = "Dreamcast Fishing Controller";
|
||||
const char* maple_popnmusic_controller_name = "pop'n music controller";
|
||||
const char* maple_racing_controller_name = "Racing Controller";
|
||||
const char* maple_densha_controller_name = "TAITO 001 Controller";
|
||||
|
||||
const char* maple_sega_brand = "Produced By or Under License From SEGA ENTERPRISES,LTD.";
|
||||
|
||||
|
@ -104,6 +109,11 @@ struct maple_sega_controller: maple_base
|
|||
return maple_sega_brand;
|
||||
}
|
||||
|
||||
virtual u32 get_device_current(int get_max_current)
|
||||
{
|
||||
return get_max_current ? 0x01F4 : 0x01AE; // Max. 50 mA, standby: 43 mA
|
||||
}
|
||||
|
||||
u32 dma(u32 cmd) override
|
||||
{
|
||||
//printf("maple_sega_controller::dma Called 0x%X;Command %d\n", bus_id, cmd);
|
||||
|
@ -111,6 +121,8 @@ struct maple_sega_controller: maple_base
|
|||
{
|
||||
case MDC_DeviceRequest:
|
||||
case MDC_AllStatusReq:
|
||||
// Fixed Device Status
|
||||
// (Device ID)
|
||||
//caps
|
||||
//4
|
||||
w32(MFID_0_Input);
|
||||
|
@ -121,23 +133,23 @@ struct maple_sega_controller: maple_base
|
|||
w32(0);
|
||||
w32(0);
|
||||
|
||||
//1 area code
|
||||
//1 area code (Country specification)
|
||||
w8(0xFF);
|
||||
|
||||
//1 direction
|
||||
//1 direction (Connection method)
|
||||
w8(0);
|
||||
|
||||
//30
|
||||
//30 (Model name)
|
||||
wstr(get_device_name(), 30);
|
||||
|
||||
//60
|
||||
//60 (License)
|
||||
wstr(get_device_brand(), 60);
|
||||
|
||||
//2
|
||||
w16(0x01AE); // 43 mA
|
||||
//2 (Standby current consumption)
|
||||
w16(get_device_current(0));
|
||||
|
||||
//2
|
||||
w16(0x01F4); // 50 mA
|
||||
//2 (Maximum current consumption)
|
||||
w16(get_device_current(1));
|
||||
|
||||
return cmd == MDC_DeviceRequest ? MDRS_DeviceStatus : MDRS_DeviceStatusAll;
|
||||
|
||||
|
@ -249,6 +261,10 @@ struct maple_sega_twinstick: maple_sega_controller
|
|||
const char *get_device_name() override {
|
||||
return maple_sega_twinstick_name;
|
||||
}
|
||||
|
||||
u32 get_device_current(int get_max_current) override {
|
||||
return get_max_current ? 0x012C : 0x00DC; // Max. 30 mA, standby: 22 mA
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -284,14 +300,16 @@ struct maple_ascii_stick: maple_sega_controller
|
|||
const char *get_device_name() override {
|
||||
return maple_ascii_stick_name;
|
||||
}
|
||||
|
||||
u32 get_device_current(int get_max_current) override {
|
||||
return get_max_current ? 0x0172 : 0x010E; // Max. 37 mA, standby: 27 mA
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Sega Dreamcast Visual Memory Unit
|
||||
This is pretty much done (?)
|
||||
*/
|
||||
|
||||
|
||||
u8 vmu_default[] = {
|
||||
0x78,0x9c,0xed,0xd2,0x31,0x4e,0x02,0x61,0x10,0x06,0xd0,0x8f,0x04,0x28,0x4c,0x2c,
|
||||
0x28,0x2d,0x0c,0xa5,0x57,0xe0,0x16,0x56,0x16,0x76,0x14,0x1e,0xc4,0x03,0x50,0x98,
|
||||
|
@ -718,7 +736,6 @@ struct maple_sega_vmu: maple_base
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
struct maple_microphone: maple_base
|
||||
{
|
||||
u32 gain;
|
||||
|
@ -896,7 +913,6 @@ struct maple_microphone: maple_base
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
struct maple_sega_purupuru : maple_base
|
||||
{
|
||||
u16 AST = 19, AST_ms = 5000;
|
||||
|
@ -1327,6 +1343,391 @@ struct atomiswave_lightgun : maple_lightgun
|
|||
}
|
||||
};
|
||||
|
||||
struct maple_maracas_controller: maple_sega_controller
|
||||
{
|
||||
u32 get_capabilities() override {
|
||||
// byte 0: 0 0 0 0 0 0 0 0
|
||||
// byte 1: 0 0 a5 a4 a3 a2 a1 a0
|
||||
// byte 2: R2 L2 D2 U2 D X Y Z
|
||||
// byte 3: R L D U St A B C
|
||||
|
||||
return 0x0f093c00; // 4 analog axes (2-5) A B C D Z Start
|
||||
}
|
||||
|
||||
u32 transform_kcode(u32 kcode) override {
|
||||
return kcode | 0xf6f0; // mask off DPad2, X, Y, DPad;
|
||||
}
|
||||
|
||||
MapleDeviceType get_device_type() override {
|
||||
return MDT_MaracasController;
|
||||
}
|
||||
|
||||
u32 get_analog_axis(int index, const PlainJoystickState &pjs) override {
|
||||
if (index < 2 || index > 5)
|
||||
return 0;
|
||||
return pjs.joy[index -2];
|
||||
/* // This should be tested with real maracas to see if it is worth implementing or not
|
||||
u8 maracas_saturation_reduction = 2;
|
||||
s32 axis_val = (pjs.joy[index -2] - 0x80) / maracas_saturation_reduction + 0x80;
|
||||
if (axis_val < 0) axis_val = 0;
|
||||
else if (axis_val > 0xff) axis_val = 0xFF;
|
||||
return axis_val; */
|
||||
}
|
||||
|
||||
const char *get_device_name() override {
|
||||
return maple_maracas_controller_name;
|
||||
}
|
||||
|
||||
u32 get_device_current(int get_max_current) override {
|
||||
return get_max_current ? 0x0546 : 0x044C; // Max. 130 mA, standby: 100 mA
|
||||
}
|
||||
};
|
||||
|
||||
struct maple_fishing_controller: maple_sega_controller
|
||||
{
|
||||
u32 get_capabilities() override {
|
||||
// byte 0: 0 0 0 0 0 0 0 0
|
||||
// byte 1: 0 0 a5 a4 a3 a2 a1 a0
|
||||
// byte 2: R2 L2 D2 U2 D X Y Z
|
||||
// byte 3: R L D U St A B C
|
||||
|
||||
return 0x0fe063f00; // Ra,La,Da,Ua,A,B,X,Y,Start,A1,A2,A3,A4,A5,A6
|
||||
}
|
||||
|
||||
u32 transform_kcode(u32 kcode) override {
|
||||
mutualExclusion(kcode, DC_DPAD_UP | DC_DPAD_DOWN);
|
||||
mutualExclusion(kcode, DC_DPAD_LEFT | DC_DPAD_RIGHT);
|
||||
return kcode | 0xf901; // mask off DPad2, D, Z, C;
|
||||
}
|
||||
|
||||
MapleDeviceType get_device_type() override {
|
||||
return MDT_FishingController;
|
||||
}
|
||||
|
||||
u32 get_analog_axis(int index, const PlainJoystickState &pjs) override {
|
||||
// In the XYZ axes, acceleration sensor outputs 80 ± 8H (home position)
|
||||
// in the static state (± 0G), F0h or greater for maximum force (+10G)
|
||||
// in the positive direction and 11h or less
|
||||
// for the maximum force (-10G) applied in the negative direction
|
||||
// From the perspective of the player operating the controller:
|
||||
// X: Right is positive, left is negative
|
||||
// Y: Down is positive, up is negative
|
||||
// Z: Forward is positive, backward is negative
|
||||
if (index == 0)
|
||||
return pjs.trigger[PJTI_R]; // A1: Reel handle output
|
||||
else if (index == 1)
|
||||
return pjs.joy[4]; // A2: acceleration sensor Z
|
||||
else if (index >= 2 || index <= 5) // A3, A4 are also output as Ra, La, Ua, Da
|
||||
return pjs.joy[index -2]; // A5, A6: acceleration sensors X and Y
|
||||
return 0x80;
|
||||
}
|
||||
|
||||
const char *get_device_name() override {
|
||||
return maple_fishing_controller_name;
|
||||
}
|
||||
|
||||
u32 get_device_current(int get_max_current) override {
|
||||
return get_max_current ? 0x0960 : 0x0258; // Max. 240 mA, standby: 60 mA
|
||||
}
|
||||
|
||||
u32 dma(u32 cmd) override {
|
||||
//printf("maple_fishing_controller::dma Called 0x%X;Command %d\n", bus_id, cmd);
|
||||
switch (cmd)
|
||||
{
|
||||
case MDC_DeviceRequest:
|
||||
case MDC_AllStatusReq:
|
||||
// Fixed Device Status
|
||||
// (Device ID)
|
||||
//caps
|
||||
//4
|
||||
w32(MFID_0_Input);
|
||||
|
||||
//struct data
|
||||
//3*4
|
||||
w32(get_capabilities());
|
||||
w32(0);
|
||||
w32(0);
|
||||
|
||||
//1 area code (Country specification)
|
||||
w8(0xFF);
|
||||
|
||||
//1 direction (Connection method)
|
||||
w8(0);
|
||||
|
||||
//30 (Model name)
|
||||
wstr(get_device_name(), 30);
|
||||
|
||||
//60 (License)
|
||||
wstr(get_device_brand(), 60);
|
||||
|
||||
//2 (Standby current consumption)
|
||||
w16(get_device_current(0));
|
||||
|
||||
//2 (Maximum current consumption)
|
||||
w16(get_device_current(1));
|
||||
|
||||
return cmd == MDC_DeviceRequest ? MDRS_DeviceStatus : MDRS_DeviceStatusAll;
|
||||
|
||||
//controller condition
|
||||
case MDCF_GetCondition:
|
||||
{
|
||||
PlainJoystickState pjs;
|
||||
config->GetInput(&pjs);
|
||||
//INFO_LOG(MAPLE, "maple_fishing_controller: MDCF_GetCondition: r32(): %d", r32());
|
||||
//caps
|
||||
//4
|
||||
w32(MFID_0_Input);
|
||||
|
||||
//state data
|
||||
//2 key code
|
||||
w16(transform_kcode(pjs.kcode));
|
||||
|
||||
//triggers
|
||||
//1 R
|
||||
w8(get_analog_axis(0, pjs));
|
||||
//1 L
|
||||
w8(get_analog_axis(1, pjs));
|
||||
|
||||
//joyx
|
||||
//1
|
||||
w8(get_analog_axis(2, pjs));
|
||||
//joyy
|
||||
//1
|
||||
w8(get_analog_axis(3, pjs));
|
||||
|
||||
//not used on dreamcast
|
||||
//1
|
||||
w8(get_analog_axis(4, pjs));
|
||||
//1
|
||||
w8(get_analog_axis(5, pjs));
|
||||
}
|
||||
|
||||
return MDRS_DataTransfer;
|
||||
|
||||
case MDC_DeviceReset:
|
||||
return MDRS_DeviceReply;
|
||||
|
||||
case MDC_DeviceKill:
|
||||
return MDRS_DeviceReply;
|
||||
|
||||
default:
|
||||
INFO_LOG(MAPLE, "maple_fishing_controller: Unknown maple command %d", cmd);
|
||||
return MDRE_UnknownCmd;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct maple_popnmusic_controller: maple_sega_controller
|
||||
{
|
||||
u32 get_capabilities() override {
|
||||
// byte 0: 0 0 0 0 0 0 0 0
|
||||
// byte 1: 0 0 a5 a4 a3 a2 a1 a0
|
||||
// byte 2: R2 L2 D2 U2 D X Y Z
|
||||
// byte 3: R L D U St A B C
|
||||
|
||||
return 0xff060000; // no analog axes, X Y A B C Start U/D/L/R
|
||||
}
|
||||
|
||||
u32 transform_kcode(u32 kcode) override
|
||||
{
|
||||
return kcode | 0xf100; // mask off DPad2 and Z
|
||||
}
|
||||
|
||||
MapleDeviceType get_device_type() override {
|
||||
return MDT_PopnMusicController;
|
||||
}
|
||||
|
||||
u32 get_analog_axis(int index, const PlainJoystickState &pjs) override {
|
||||
if (index == 0 || index == 1)
|
||||
return 0; // Right and left triggers
|
||||
return 0x80;
|
||||
}
|
||||
|
||||
const char *get_device_name() override {
|
||||
return maple_popnmusic_controller_name;
|
||||
}
|
||||
|
||||
u32 get_device_current(int get_max_current) override {
|
||||
return get_max_current ? 0x012C : 0x00AA; // Max. 30 mA, standby: 17 mA
|
||||
}
|
||||
};
|
||||
|
||||
struct maple_racing_controller: maple_sega_controller
|
||||
{
|
||||
u32 get_capabilities() override {
|
||||
// byte 0: 0 0 0 0 0 0 0 0
|
||||
// byte 1: 0 0 a5 a4 a3 a2 a1 a0
|
||||
// byte 2: R2 L2 D2 U2 D X Y Z
|
||||
// byte 3: R L D U St A B C
|
||||
|
||||
return 0xfe003700; // Steering + accelerator/brake unit: Ra,La,Da,Ua,A,B,Start,A1,A2,A3,A5,A6
|
||||
// (A5 & A6 only valid when the accelerator/brake unit is connected.)
|
||||
//return 0xfe000700; // Steering only
|
||||
}
|
||||
|
||||
u32 transform_kcode_racing(const PlainJoystickState &pjs) {
|
||||
// Ra, La are ON when A3 threshold values (La: 40h, Ra: BEh) are exceeded
|
||||
u32 kcode = pjs.kcode;
|
||||
if (pjs.joy[PJAI_X1] < 0x40)
|
||||
kcode &= 0xffff -DC_DPAD_LEFT;
|
||||
else if (pjs.joy[PJAI_X1] > 0xBE)
|
||||
kcode &= 0xffff -DC_DPAD_RIGHT;
|
||||
mutualExclusion(kcode, DC_DPAD_UP | DC_DPAD_DOWN);
|
||||
mutualExclusion(kcode, DC_DPAD_LEFT | DC_DPAD_RIGHT);
|
||||
return kcode | 0xff01; // mask off DPad2, D, X, Y, Z, C
|
||||
}
|
||||
|
||||
MapleDeviceType get_device_type() override {
|
||||
return MDT_RacingController;
|
||||
}
|
||||
|
||||
u32 get_analog_axis(int index, const PlainJoystickState &pjs) override {
|
||||
if (index == 0)
|
||||
return pjs.trigger[PJTI_R]; // A1: lever, 0 at rest
|
||||
else if (index == 1)
|
||||
return pjs.trigger[PJTI_L]; // A2: lever, 0 at rest
|
||||
else if (index == 2)
|
||||
return pjs.joy[PJAI_X1]; // A3: 0-0xff, 0x80 at rest
|
||||
else if (index == 4) // (A5 and A6 are only valid when the accelerator/brake unit is connected)
|
||||
return pjs.trigger[PJTI_R2];// A5: lever, 0 at rest
|
||||
else if (index == 5)
|
||||
return pjs.trigger[PJTI_L2];// A6: lever, 0 at rest
|
||||
return 0x80; // unused
|
||||
}
|
||||
|
||||
const char *get_device_name() override {
|
||||
return maple_racing_controller_name;
|
||||
}
|
||||
|
||||
u32 get_device_current(int get_max_current) override {
|
||||
return get_max_current ? 0x0226 : 0x01B8; // Max. 55 mA, standby: 44 mA
|
||||
}
|
||||
|
||||
u32 dma(u32 cmd) override
|
||||
{
|
||||
//printf("maple_sega_controller::dma Called 0x%X;Command %d\n", bus_id, cmd);
|
||||
switch (cmd)
|
||||
{
|
||||
case MDC_DeviceRequest:
|
||||
case MDC_AllStatusReq:
|
||||
// Fixed Device Status
|
||||
// (Device ID)
|
||||
//caps
|
||||
//4
|
||||
w32(MFID_0_Input);
|
||||
|
||||
//struct data
|
||||
//3*4
|
||||
w32(get_capabilities());
|
||||
w32(0);
|
||||
w32(0);
|
||||
|
||||
//1 area code (Country specification)
|
||||
w8(0xFF);
|
||||
|
||||
//1 direction (Connection method)
|
||||
w8(0);
|
||||
|
||||
//30 (Model name)
|
||||
wstr(get_device_name(), 30);
|
||||
|
||||
//60 (License)
|
||||
wstr(get_device_brand(), 60);
|
||||
|
||||
//2 (Standby current consumption)
|
||||
w16(get_device_current(0));
|
||||
|
||||
//2 (Maximum current consumption)
|
||||
w16(get_device_current(1));
|
||||
|
||||
return cmd == MDC_DeviceRequest ? MDRS_DeviceStatus : MDRS_DeviceStatusAll;
|
||||
|
||||
//controller condition
|
||||
case MDCF_GetCondition:
|
||||
{
|
||||
PlainJoystickState pjs;
|
||||
config->GetInput(&pjs);
|
||||
//caps
|
||||
//4
|
||||
w32(MFID_0_Input);
|
||||
|
||||
//state data
|
||||
//2 key code
|
||||
w16(transform_kcode_racing(pjs));
|
||||
|
||||
//triggers
|
||||
//1 R
|
||||
w8(get_analog_axis(0, pjs));
|
||||
//1 L
|
||||
w8(get_analog_axis(1, pjs));
|
||||
|
||||
//joyx
|
||||
//1
|
||||
w8(get_analog_axis(2, pjs));
|
||||
//joyy
|
||||
//1
|
||||
w8(get_analog_axis(3, pjs));
|
||||
|
||||
//not used on dreamcast
|
||||
//1
|
||||
w8(get_analog_axis(4, pjs));
|
||||
//1
|
||||
w8(get_analog_axis(5, pjs));
|
||||
}
|
||||
|
||||
return MDRS_DataTransfer;
|
||||
|
||||
case MDC_DeviceReset:
|
||||
return MDRS_DeviceReply;
|
||||
|
||||
case MDC_DeviceKill:
|
||||
return MDRS_DeviceReply;
|
||||
|
||||
default:
|
||||
INFO_LOG(MAPLE, "maple_racing_controller: Unknown maple command %d", cmd);
|
||||
return MDRE_UnknownCmd;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct maple_densha_controller: maple_sega_controller
|
||||
{
|
||||
u32 get_capabilities() override {
|
||||
// byte 0: 0 0 0 0 0 0 0 0
|
||||
// byte 1: 0 0 a5 a4 a3 a2 a1 a0
|
||||
// byte 2: R2 L2 D2 U2 D X Y Z
|
||||
// byte 3: R L D U St A B C
|
||||
|
||||
return 0xff0f3f00; // Ra,La,Da,Ua A,B,C,D,X,Y,Z,Start Xa,Ya,Xb,Yb Analog levers R,L
|
||||
}
|
||||
|
||||
u32 transform_kcode(u32 kcode) override {
|
||||
// Ra,La,Da,Ua are used together, corresponding to the brake lever.
|
||||
return kcode | 0xF000; // mask off DPad2
|
||||
}
|
||||
|
||||
MapleDeviceType get_device_type() override {
|
||||
return MDT_DenshaDeGoController;
|
||||
}
|
||||
|
||||
u32 get_analog_axis(int index, const PlainJoystickState &pjs) override {
|
||||
if (index == 2 || index == 3)
|
||||
return 0;
|
||||
if (index == 0 || index == 1 || index == 4 || index == 5)
|
||||
return 0xff;
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
const char *get_device_name() override {
|
||||
return maple_densha_controller_name;
|
||||
}
|
||||
|
||||
u32 get_device_current(int get_max_current) override {
|
||||
return get_max_current ? 0x01F4 : 0x00DC; // Max. 50 mA, standby: 22 mA
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Emulates a 838-14245-92 maple to RS232 converter
|
||||
// wired to a 838-14243 RFID reader/writer (apparently Saxa HW210)
|
||||
struct RFIDReaderWriter : maple_base
|
||||
|
@ -1689,6 +2090,26 @@ maple_device* maple_Create(MapleDeviceType type)
|
|||
rv = new maple_ascii_stick();
|
||||
break;
|
||||
|
||||
case MDT_MaracasController:
|
||||
rv = new maple_maracas_controller();
|
||||
break;
|
||||
|
||||
case MDT_FishingController:
|
||||
rv = new maple_fishing_controller();
|
||||
break;
|
||||
|
||||
case MDT_PopnMusicController:
|
||||
rv = new maple_popnmusic_controller();
|
||||
break;
|
||||
|
||||
case MDT_RacingController:
|
||||
rv = new maple_racing_controller();
|
||||
break;
|
||||
|
||||
case MDT_DenshaDeGoController:
|
||||
rv = new maple_densha_controller();
|
||||
break;
|
||||
|
||||
case MDT_RFIDReaderWriter:
|
||||
rv = new RFIDReaderWriter();
|
||||
break;
|
||||
|
|
|
@ -55,6 +55,8 @@ enum DreamcastKey
|
|||
DC_AXIS_TRIGGERS = 0x1000000,
|
||||
DC_AXIS_LT,
|
||||
DC_AXIS_RT,
|
||||
DC_AXIS_LT2,
|
||||
DC_AXIS_RT2,
|
||||
DC_AXIS_STICKS = 0x2000000,
|
||||
DC_AXIS_LEFT,
|
||||
DC_AXIS_RIGHT,
|
||||
|
@ -64,6 +66,10 @@ enum DreamcastKey
|
|||
DC_AXIS2_RIGHT,
|
||||
DC_AXIS2_UP,
|
||||
DC_AXIS2_DOWN,
|
||||
DC_AXIS3_LEFT,
|
||||
DC_AXIS3_RIGHT,
|
||||
DC_AXIS3_UP,
|
||||
DC_AXIS3_DOWN,
|
||||
|
||||
// System axes
|
||||
EMU_AXIS_NONE = 0,
|
||||
|
|
|
@ -39,7 +39,11 @@ s8 joyrx[4];
|
|||
s8 joyry[4];
|
||||
u8 rt[4];
|
||||
u8 lt[4];
|
||||
s8 joy3x[4];
|
||||
s8 joy3y[4];
|
||||
// Keyboards
|
||||
u8 lt2[4];
|
||||
u8 rt2[4];
|
||||
u8 kb_shift[MAPLE_PORTS]; // shift keys pressed (bitmask)
|
||||
u8 kb_key[MAPLE_PORTS][6]; // normal keys pressed
|
||||
|
||||
|
@ -103,7 +107,14 @@ bool GamepadDevice::handleButtonInput(int port, DreamcastKey key, bool pressed)
|
|||
if (port >= 0)
|
||||
rt[port] = pressed ? 255 : 0;
|
||||
break;
|
||||
|
||||
case DC_AXIS_LT2:
|
||||
if (port >= 0)
|
||||
lt2[port] = pressed ? 255 : 0;
|
||||
break;
|
||||
case DC_AXIS_RT2:
|
||||
if (port >= 0)
|
||||
rt2[port] = pressed ? 255 : 0;
|
||||
break;
|
||||
case DC_AXIS_UP:
|
||||
case DC_AXIS_DOWN:
|
||||
buttonToAnalogInput<DC_AXIS_UP, DIGANA_UP, DIGANA_DOWN>(port, key, pressed, joyy[port]);
|
||||
|
@ -120,6 +131,14 @@ bool GamepadDevice::handleButtonInput(int port, DreamcastKey key, bool pressed)
|
|||
case DC_AXIS2_RIGHT:
|
||||
buttonToAnalogInput<DC_AXIS2_LEFT, DIGANA2_LEFT, DIGANA2_RIGHT>(port, key, pressed, joyrx[port]);
|
||||
break;
|
||||
case DC_AXIS3_UP:
|
||||
case DC_AXIS3_DOWN:
|
||||
buttonToAnalogInput<DC_AXIS3_UP, DIGANA3_UP, DIGANA3_DOWN>(port, key, pressed, joy3y[port]);
|
||||
break;
|
||||
case DC_AXIS3_LEFT:
|
||||
case DC_AXIS3_RIGHT:
|
||||
buttonToAnalogInput<DC_AXIS3_LEFT, DIGANA3_LEFT, DIGANA3_RIGHT>(port, key, pressed, joy3x[port]);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
@ -186,6 +205,10 @@ bool GamepadDevice::gamepad_axis_input(u32 code, int value)
|
|||
lt[port] = std::min(std::abs(v) >> 7, 255);
|
||||
else if (key == DC_AXIS_RT)
|
||||
rt[port] = std::min(std::abs(v) >> 7, 255);
|
||||
else if (key == DC_AXIS_LT2)
|
||||
lt2[port] = std::min(std::abs(v) >> 7, 255);
|
||||
else if (key == DC_AXIS_RT2)
|
||||
rt2[port] = std::min(std::abs(v) >> 7, 255);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -229,6 +252,22 @@ bool GamepadDevice::gamepad_axis_input(u32 code, int value)
|
|||
other_axis = &joyrx[port];
|
||||
break;
|
||||
|
||||
case DC_AXIS3_RIGHT:
|
||||
axisDirection = 1;
|
||||
//no break
|
||||
case DC_AXIS3_LEFT:
|
||||
this_axis = &joy3x[port];
|
||||
other_axis = &joy3y[port];
|
||||
break;
|
||||
|
||||
case DC_AXIS3_DOWN:
|
||||
axisDirection = 1;
|
||||
//no break
|
||||
case DC_AXIS3_UP:
|
||||
this_axis = &joy3y[port];
|
||||
other_axis = &joy3x[port];
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -124,6 +124,10 @@ private:
|
|||
DIGANA2_RIGHT = 1 << 5,
|
||||
DIGANA2_UP = 1 << 6,
|
||||
DIGANA2_DOWN = 1 << 7,
|
||||
DIGANA3_LEFT = 1 << 8,
|
||||
DIGANA3_RIGHT = 1 << 9,
|
||||
DIGANA3_UP = 1 << 10,
|
||||
DIGANA3_DOWN = 1 << 11,
|
||||
};
|
||||
|
||||
template<DreamcastKey DcNegDir, DigAnalog NegDir, DigAnalog PosDir>
|
||||
|
@ -167,6 +171,7 @@ void replay_input();
|
|||
#endif
|
||||
|
||||
extern u32 kcode[4];
|
||||
extern u8 rt[4], lt[4];
|
||||
extern u8 rt[4], lt[4], rt2[4], lt2[4];
|
||||
extern s8 joyx[4], joyy[4];
|
||||
extern s8 joyrx[4], joyry[4];
|
||||
extern s8 joy3x[4], joy3y[4];
|
||||
|
|
|
@ -50,6 +50,8 @@ button_list[] =
|
|||
{ EMU_BTN_FFORWARD, "emulator", "btn_fforward" },
|
||||
{ DC_AXIS_LT, "compat", "btn_trigger_left" },
|
||||
{ DC_AXIS_RT, "compat", "btn_trigger_right" },
|
||||
{ DC_AXIS_LT2, "compat", "btn_trigger_left2" },
|
||||
{ DC_AXIS_RT2, "compat", "btn_trigger_right2" },
|
||||
{ DC_AXIS_UP, "compat", "btn_analog_up" },
|
||||
{ DC_AXIS_DOWN, "compat", "btn_analog_down" },
|
||||
{ DC_AXIS_LEFT, "compat", "btn_analog_left" },
|
||||
|
@ -79,8 +81,14 @@ axis_list[] =
|
|||
{ DC_AXIS2_RIGHT, "", "axis2_right", "", "" },
|
||||
{ DC_AXIS2_UP, "", "axis2_up", "", "" },
|
||||
{ DC_AXIS2_DOWN, "", "axis2_down", "", "" },
|
||||
{ DC_AXIS3_LEFT, "", "axis3_left", "", "" },
|
||||
{ DC_AXIS3_RIGHT, "", "axis3_right", "", "" },
|
||||
{ DC_AXIS3_UP, "", "axis3_up", "", "" },
|
||||
{ DC_AXIS3_DOWN, "", "axis3_down", "", "" },
|
||||
{ DC_AXIS_LT, "dreamcast", "axis_trigger_left", "compat", "axis_trigger_left_inverted" },
|
||||
{ DC_AXIS_RT, "dreamcast", "axis_trigger_right", "compat", "axis_trigger_right_inverted" },
|
||||
{ DC_AXIS_LT2, "dreamcast", "axis_trigger_left2", "compat", "axis_trigger_left2_inverted" },
|
||||
{ DC_AXIS_RT2, "dreamcast", "axis_trigger_right2", "compat", "axis_trigger_right2_inverted" },
|
||||
|
||||
// legacy (v2)
|
||||
{ DC_AXIS_RIGHT, "dreamcast", "axis_x", "compat", "axis_x_inverted" },
|
||||
|
@ -306,6 +314,10 @@ void InputMapping::loadv1(ConfigFile& mf)
|
|||
this->set_axis(port, DC_AXIS2_LEFT, axis_code, inverted);
|
||||
else if (axis_list[i].id == DC_AXIS2_DOWN)
|
||||
this->set_axis(port, DC_AXIS2_UP, axis_code, inverted);
|
||||
else if (axis_list[i].id == DC_AXIS3_RIGHT)
|
||||
this->set_axis(port, DC_AXIS3_LEFT, axis_code, inverted);
|
||||
else if (axis_list[i].id == DC_AXIS3_DOWN)
|
||||
this->set_axis(port, DC_AXIS3_UP, axis_code, inverted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,9 +116,15 @@ public:
|
|||
set_axis(0, DC_AXIS_DOWN, DC_AXIS_DOWN, true);
|
||||
set_axis(0, DC_AXIS_LT, DC_AXIS_LT, true);
|
||||
set_axis(0, DC_AXIS_RT, DC_AXIS_RT, true);
|
||||
set_axis(0, DC_AXIS_LT2, DC_AXIS_LT2, true);
|
||||
set_axis(0, DC_AXIS_RT2, DC_AXIS_RT2, true);
|
||||
set_axis(0, DC_AXIS2_LEFT, DC_AXIS2_LEFT, true);
|
||||
set_axis(0, DC_AXIS2_RIGHT, DC_AXIS2_RIGHT, true);
|
||||
set_axis(0, DC_AXIS2_UP, DC_AXIS2_UP, true);
|
||||
set_axis(0, DC_AXIS2_DOWN, DC_AXIS2_DOWN, true);
|
||||
set_axis(0, DC_AXIS3_LEFT, DC_AXIS3_LEFT, true);
|
||||
set_axis(0, DC_AXIS3_RIGHT, DC_AXIS3_RIGHT, true);
|
||||
set_axis(0, DC_AXIS3_UP, DC_AXIS3_UP, true);
|
||||
set_axis(0, DC_AXIS3_DOWN, DC_AXIS3_DOWN, true);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -43,10 +43,14 @@ static void getLocalInput(MapleInputState inputState[4])
|
|||
state.kcode = kcode[player];
|
||||
state.halfAxes[PJTI_L] = lt[player];
|
||||
state.halfAxes[PJTI_R] = rt[player];
|
||||
state.halfAxes[PJTI_L2] = lt2[player];
|
||||
state.halfAxes[PJTI_R2] = rt2[player];
|
||||
state.fullAxes[PJAI_X1] = joyx[player];
|
||||
state.fullAxes[PJAI_Y1] = joyy[player];
|
||||
state.fullAxes[PJAI_X2] = joyrx[player];
|
||||
state.fullAxes[PJAI_Y2] = joyry[player];
|
||||
state.fullAxes[PJAI_X3] = joy3x[player];
|
||||
state.fullAxes[PJAI_Y3] = joy3y[player];
|
||||
state.mouseButtons = mo_buttons[player];
|
||||
state.absPos.x = mo_x_abs[player];
|
||||
state.absPos.y = mo_y_abs[player];
|
||||
|
|
|
@ -656,8 +656,30 @@ inline static void header(const char *title)
|
|||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
const char *maple_device_types[] = { "None", "Sega Controller", "Light Gun", "Keyboard", "Mouse", "Twin Stick", "Ascii Stick" };
|
||||
const char *maple_expansion_device_types[] = { "None", "Sega VMU", "Purupuru", "Microphone" };
|
||||
const char *maple_device_types[] =
|
||||
{
|
||||
"None",
|
||||
"Sega Controller",
|
||||
"Light Gun",
|
||||
"Keyboard",
|
||||
"Mouse",
|
||||
"Twin Stick",
|
||||
"Ascii Stick",
|
||||
"Maracas Controller",
|
||||
"Fishing Controller",
|
||||
"Pop'n Music controller",
|
||||
"Racing Controller",
|
||||
"Densha de Go! Controller",
|
||||
"Dreameye",
|
||||
};
|
||||
|
||||
const char *maple_expansion_device_types[] =
|
||||
{
|
||||
"None",
|
||||
"Sega VMU",
|
||||
"Purupuru",
|
||||
"Microphone"
|
||||
};
|
||||
|
||||
static const char *maple_device_name(MapleDeviceType type)
|
||||
{
|
||||
|
@ -675,6 +697,18 @@ static const char *maple_device_name(MapleDeviceType type)
|
|||
return maple_device_types[5];
|
||||
case MDT_AsciiStick:
|
||||
return maple_device_types[6];
|
||||
case MDT_MaracasController:
|
||||
return maple_device_types[7];
|
||||
case MDT_FishingController:
|
||||
return maple_device_types[8];
|
||||
case MDT_PopnMusicController:
|
||||
return maple_device_types[9];
|
||||
case MDT_RacingController:
|
||||
return maple_device_types[10];
|
||||
case MDT_DenshaDeGoController:
|
||||
return maple_device_types[11];
|
||||
case MDT_Dreameye:
|
||||
return maple_device_types[12];
|
||||
case MDT_None:
|
||||
default:
|
||||
return maple_device_types[0];
|
||||
|
@ -697,6 +731,18 @@ static MapleDeviceType maple_device_type_from_index(int idx)
|
|||
return MDT_TwinStick;
|
||||
case 6:
|
||||
return MDT_AsciiStick;
|
||||
case 7:
|
||||
return MDT_MaracasController;
|
||||
case 8:
|
||||
return MDT_FishingController;
|
||||
case 9:
|
||||
return MDT_PopnMusicController;
|
||||
case 10:
|
||||
return MDT_RacingController;
|
||||
case 11:
|
||||
return MDT_DenshaDeGoController;
|
||||
case 12:
|
||||
return MDT_Dreameye;
|
||||
case 0:
|
||||
default:
|
||||
return MDT_None;
|
||||
|
@ -738,9 +784,19 @@ const Mapping dcButtons[] = {
|
|||
{ DC_AXIS_LEFT, "Thumbstick Left" },
|
||||
{ DC_AXIS_RIGHT, "Thumbstick Right" },
|
||||
|
||||
{ DC_DPAD2_UP, "DPad2 Up" },
|
||||
{ DC_DPAD2_DOWN, "DPad2 Down" },
|
||||
{ DC_DPAD2_LEFT, "DPad2 Left" },
|
||||
{ DC_AXIS2_UP, "R.Thumbstick Up" },
|
||||
{ DC_AXIS2_DOWN, "R.Thumbstick Down" },
|
||||
{ DC_AXIS2_LEFT, "R.Thumbstick Left" },
|
||||
{ DC_AXIS2_RIGHT, "R.Thumbstick Right" },
|
||||
|
||||
{ DC_AXIS3_UP, "Axis 3 Up" },
|
||||
{ DC_AXIS3_DOWN, "Axis 3 Down" },
|
||||
{ DC_AXIS3_LEFT, "Axis 3 Left" },
|
||||
{ DC_AXIS3_RIGHT, "Axis 3 Right" },
|
||||
|
||||
{ DC_DPAD2_UP, "DPad2 Up" },
|
||||
{ DC_DPAD2_DOWN, "DPad2 Down" },
|
||||
{ DC_DPAD2_LEFT, "DPad2 Left" },
|
||||
{ DC_DPAD2_RIGHT, "DPad2 Right" },
|
||||
|
||||
{ EMU_BTN_NONE, "Buttons" },
|
||||
|
@ -752,9 +808,11 @@ const Mapping dcButtons[] = {
|
|||
{ DC_BTN_D, "D" },
|
||||
{ DC_BTN_Z, "Z" },
|
||||
|
||||
{ EMU_BTN_NONE, "Triggers" },
|
||||
{ DC_AXIS_LT, "Left Trigger" },
|
||||
{ DC_AXIS_RT, "Right Trigger" },
|
||||
{ EMU_BTN_NONE, "Triggers" },
|
||||
{ DC_AXIS_LT, "Left Trigger" },
|
||||
{ DC_AXIS_RT, "Right Trigger" },
|
||||
{ DC_AXIS_LT2, "Left Trigger 2" },
|
||||
{ DC_AXIS_RT2, "Right Trigger 2" },
|
||||
|
||||
{ EMU_BTN_NONE, "System Buttons" },
|
||||
{ DC_BTN_START, "Start" },
|
||||
|
@ -886,6 +944,14 @@ static DreamcastKey getOppositeDirectionKey(DreamcastKey key)
|
|||
return DC_AXIS2_RIGHT;
|
||||
case DC_AXIS2_RIGHT:
|
||||
return DC_AXIS2_LEFT;
|
||||
case DC_AXIS3_UP:
|
||||
return DC_AXIS3_DOWN;
|
||||
case DC_AXIS3_DOWN:
|
||||
return DC_AXIS3_UP;
|
||||
case DC_AXIS3_LEFT:
|
||||
return DC_AXIS3_RIGHT;
|
||||
case DC_AXIS3_RIGHT:
|
||||
return DC_AXIS3_LEFT;
|
||||
default:
|
||||
return EMU_BTN_NONE;
|
||||
}
|
||||
|
@ -1646,9 +1712,19 @@ static void gui_display_settings()
|
|||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
int port_count = config::MapleMainDevices[bus] == MDT_SegaController ? 2
|
||||
: config::MapleMainDevices[bus] == MDT_LightGun || config::MapleMainDevices[bus] == MDT_TwinStick || config::MapleMainDevices[bus] == MDT_AsciiStick ? 1
|
||||
: 0;
|
||||
int port_count = 0;
|
||||
switch (config::MapleMainDevices[bus]) {
|
||||
case MDT_SegaController:
|
||||
port_count = 2;
|
||||
break;
|
||||
case MDT_LightGun:
|
||||
case MDT_TwinStick:
|
||||
case MDT_AsciiStick:
|
||||
case MDT_RacingController:
|
||||
port_count = 1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
for (int port = 0; port < port_count; port++)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
|
|
|
@ -61,7 +61,8 @@ public:
|
|||
V34,
|
||||
V35,
|
||||
V36,
|
||||
Current = V36,
|
||||
V37,
|
||||
Current = V37,
|
||||
|
||||
Next = Current + 1,
|
||||
};
|
||||
|
|
|
@ -130,9 +130,12 @@ static bool lightgunSettingsShown = true;
|
|||
u32 kcode[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
|
||||
u8 rt[4];
|
||||
u8 lt[4];
|
||||
u8 lt2[4];
|
||||
u8 rt2[4];
|
||||
u32 vks[4];
|
||||
s8 joyx[4], joyy[4];
|
||||
s8 joyrx[4], joyry[4];
|
||||
s8 joy3x[4], joy3y[4];
|
||||
// Mouse buttons
|
||||
// bit 0: Button C
|
||||
// bit 1: Right button (B)
|
||||
|
|
Loading…
Reference in New Issue