diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index 02c00dc88..4816ff018 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -204,6 +204,19 @@ void mcfg_CreateDevices() if (settings.input.maple_expansion_devices[bus][0] != MDT_None) mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0); break; + + case MDT_TwinStick: + mcfg_Create(MDT_TwinStick, bus, 5); + if (settings.input.maple_expansion_devices[bus][0] != MDT_None) + mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0); + break; + + case MDT_AsciiStick: + mcfg_Create(MDT_AsciiStick, bus, 5); + if (settings.input.maple_expansion_devices[bus][0] != MDT_None) + mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0); + break; + default: WARN_LOG(MAPLE, "Invalid device type %d for port %d", settings.input.maple_devices[bus], bus); break; diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index a745a748c..213f994f3 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -26,6 +26,8 @@ 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_brand = "Produced By or Under License From SEGA ENTERPRISES,LTD."; @@ -222,6 +224,16 @@ struct maple_sega_controller: maple_base return MDT_SegaController; } + virtual const char *get_device_name() + { + return maple_sega_controller_name; + } + + virtual const char *get_device_brand() + { + return maple_sega_brand; + } + virtual u32 dma(u32 cmd) { //printf("maple_sega_controller::dma Called 0x%X;Command %d\n", bus_id, cmd); @@ -245,10 +257,10 @@ struct maple_sega_controller: maple_base w8(0); //30 - wstr(maple_sega_controller_name,30); + wstr(get_device_name(), 30); //60 - wstr(maple_sega_brand,60); + wstr(get_device_brand(), 60); //2 w16(0x01AE); // 43 mA @@ -332,6 +344,73 @@ struct maple_atomiswave_controller: maple_sega_controller } }; +/* + Sega Twin Stick Controller +*/ +struct maple_sega_twinstick: maple_sega_controller +{ + virtual 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 0xfefe0000; // no analog axes, X Y A B D Start U/D/L/R U2/D2/L2/R2 + } + + virtual u32 transform_kcode(u32 kcode) override { + return kcode | 0x0101; + } + + virtual MapleDeviceType get_device_type() override + { + return MDT_TwinStick; + } + + virtual u32 get_analog_axis(int index, const PlainJoystickState &pjs) override { + return 0x80; + } + + virtual const char *get_device_name() + { + return maple_sega_twinstick_name; + } +}; + + +/* + Ascii Stick (Arcade/FT Stick) +*/ +struct maple_ascii_stick: maple_sega_controller +{ + virtual 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 0xff070000; // no analog axes, X Y Z A B C Start U/D/L/R + } + + virtual u32 transform_kcode(u32 kcode) override { + return kcode | 0xF800; + } + + virtual MapleDeviceType get_device_type() + { + return MDT_AsciiStick; + } + + virtual u32 get_analog_axis(int index, const PlainJoystickState &pjs) override { + return 0x80; + } + + virtual const char *get_device_name() + { + return maple_ascii_stick_name; + } +}; + /* Sega Dreamcast Visual Memory Unit This is pretty much done (?) @@ -2656,6 +2735,14 @@ maple_device* maple_Create(MapleDeviceType type) rv = new maple_naomi_jamma(); break; + case MDT_TwinStick: + rv = new maple_sega_twinstick(); + break; + + case MDT_AsciiStick: + rv = new maple_ascii_stick(); + break; + default: ERROR_LOG(MAPLE, "Invalid device type %d", type); die("Invalid maple device type"); diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index e87b3a4fd..58334b202 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -356,7 +356,7 @@ static void gui_display_commands() settings_opening = false; } -const char *maple_device_types[] = { "None", "Sega Controller", "Light Gun", "Keyboard", "Mouse" }; +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" }; static const char *maple_device_name(MapleDeviceType type) @@ -371,6 +371,10 @@ static const char *maple_device_name(MapleDeviceType type) return maple_device_types[3]; case MDT_Mouse: return maple_device_types[4]; + case MDT_TwinStick: + return maple_device_types[5]; + case MDT_AsciiStick: + return maple_device_types[6]; case MDT_None: default: return maple_device_types[0]; @@ -389,6 +393,10 @@ static MapleDeviceType maple_device_type_from_index(int idx) return MDT_Keyboard; case 4: return MDT_Mouse; + case 5: + return MDT_TwinStick; + case 6: + return MDT_AsciiStick; case 0: default: return MDT_None; @@ -829,7 +837,9 @@ static void gui_display_settings() } ImGui::EndCombo(); } - int port_count = settings.input.maple_devices[bus] == MDT_SegaController ? 2 : settings.input.maple_devices[bus] == MDT_LightGun ? 1 : 0; + int port_count = settings.input.maple_devices[bus] == MDT_SegaController ? 2 + : settings.input.maple_devices[bus] == MDT_LightGun || settings.input.maple_devices[bus] == MDT_TwinStick || settings.input.maple_devices[bus] == MDT_AsciiStick ? 1 + : 0; for (int port = 0; port < port_count; port++) { ImGui::SameLine();