diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/SaturnusControllerDeck.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/SaturnusControllerDeck.cs index e11b923832..c47df5660d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/SaturnusControllerDeck.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/SaturnusControllerDeck.cs @@ -98,7 +98,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn private abstract class ButtonedDevice : IDevice { - private static readonly FloatRange AnalogFloatRange = new FloatRange(-32767, 0, 32767); + private static readonly FloatRange AnalogFloatRange = new FloatRange(0, 128, 255); protected ButtonedDevice() { @@ -164,13 +164,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn int pos = offset + AnalogByteOffset; for (int i = 0; i < _bakedAnalogNames.Length; i++) { - var data = (int)controller.GetFloat(_bakedAnalogNames[i]); - var datal = (short)Math.Max(-data, 0); - var datar = (short)Math.Max(data, 0); - dest[pos++] = (byte)datal; - dest[pos++] = (byte)(datal >> 8); - dest[pos++] = (byte)datar; - dest[pos++] = (byte)(datar >> 8); + var data = (byte)(int)controller.GetFloat(_bakedAnalogNames[i]); + dest[pos++] = data; } } @@ -233,11 +228,18 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn { "Stick Horizontal", "Stick Vertical", - "Third Axis" + "Left Shoulder", + "Right Shoulder" }; protected override string[] AnalogNames => _analogNames; + public ThreeDeeGamepad() + { + Definition.FloatRanges[2] = new FloatRange(0, 0, 255); + Definition.FloatRanges[3] = new FloatRange(0, 0, 255); + } + public override void Update(IController controller, byte[] dest, int offset) { base.Update(controller, dest, offset); @@ -248,37 +250,19 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn private class Mouse : ButtonedDevice { - private static readonly FloatRange MouseFloatRange = new FloatRange(-32768, 0, 32767); - private static readonly string[] _buttonNames = { "Left", "Right", "Middle", "Start" }; - protected override string[] ButtonNames => _buttonNames; - protected override int ButtonByteOffset => 8; - - public Mouse() + protected override string[] ButtonNames => _buttonNames; + + private static readonly string[] _analogNames = { - Definition.FloatControls.AddRange(new[] { "0X", "0Y" }); - Definition.FloatRanges.AddRange(new[] { MouseFloatRange, MouseFloatRange }); - } + "X", "Y" + }; - private void SetMouseAxis(float value, byte[] dest, int offset) - { - var data = (short)value; - dest[offset++] = 0; - dest[offset++] = 0; - dest[offset++] = (byte)data; - dest[offset++] = (byte)(data >> 8); - } - - public override void Update(IController controller, byte[] dest, int offset) - { - base.Update(controller, dest, offset); - SetMouseAxis(controller.GetFloat("0X"), dest, offset + 0); - SetMouseAxis(controller.GetFloat("0Y"), dest, offset + 4); - } + protected override string[] AnalogNames => _analogNames; } private class Wheel : ButtonedDevice @@ -319,7 +303,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn }; protected override string[] AnalogNames => _analogNames; - protected override int AnalogByteOffset => 3; + protected override int AnalogByteOffset => 4; } private class DualMission : Mission diff --git a/output/dll/ss.wbx.gz b/output/dll/ss.wbx.gz index f8965b2061..6b6cf90539 100644 Binary files a/output/dll/ss.wbx.gz and b/output/dll/ss.wbx.gz differ diff --git a/waterbox/ss/input/3dpad.cpp b/waterbox/ss/input/3dpad.cpp index 2c23fcc9cf..7246440709 100644 --- a/waterbox/ss/input/3dpad.cpp +++ b/waterbox/ss/input/3dpad.cpp @@ -1,176 +1,168 @@ -/******************************************************************************/ -/* Mednafen Sega Saturn Emulation Module */ -/******************************************************************************/ -/* 3dpad.cpp: -** Copyright (C) 2016-2017 Mednafen Team -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of the GNU General Public License -** as published by the Free Software Foundation; either version 2 -** of the License, or (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, Inc., -** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "common.h" -#include "3dpad.h" - -namespace MDFN_IEN_SS -{ - -IODevice_3DPad::IODevice_3DPad() : dbuttons(0), mode(false) -{ - -} - -IODevice_3DPad::~IODevice_3DPad() -{ - -} - -void IODevice_3DPad::Power(void) -{ - phase = -1; - tl = true; - data_out = 0x01; -} - -void IODevice_3DPad::UpdateInput(const uint8* data, const int32 time_elapsed) -{ - const uint16 dtmp = MDFN_de16lsb(&data[0]); - - dbuttons = (dbuttons & 0x8800) | (dtmp & 0x0FFF); - mode = (bool)(dtmp & 0x1000); - - for(unsigned axis = 0; axis < 2; axis++) - { - int32 tmp = 32767 + MDFN_de16lsb(&data[0x2 + (axis << 2) + 2]) - MDFN_de16lsb(&data[0x2 + (axis << 2) + 0]); - - if(tmp >= (32767 - 128) && tmp < 32767) - tmp = 32767; - - tmp = (tmp * 255 + 32767) / 65534; - thumb[axis] = tmp; - } - - for(unsigned w = 0; w < 2; w++) - { - shoulder[w] = (MDFN_de16lsb(&data[0xA + (w << 1)]) * 255 + 16383) / 32767; - - // May not be right for digital mode, but shouldn't matter too much: - if(shoulder[w] <= 0x55) - dbuttons &= ~(0x0800 << (w << 2)); - else if(shoulder[w] >= 0x8E) - dbuttons |= 0x0800 << (w << 2); - } -} - -uint8 IODevice_3DPad::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) -{ - uint8 tmp; - - if(smpc_out & 0x40) - { - phase = -1; - tl = true; - data_out = 0x01; - } - else - { - if((bool)(smpc_out & 0x20) != tl) - { - if(phase < 15) - { - tl = !tl; - phase++; - } - - if(!phase) - { - if(mode) - { - buffer[ 0] = 0x1; - buffer[ 1] = 0x6; - buffer[ 2] = (((dbuttons >> 0) & 0xF) ^ 0xF); - buffer[ 3] = (((dbuttons >> 4) & 0xF) ^ 0xF); - buffer[ 4] = (((dbuttons >> 8) & 0xF) ^ 0xF); - buffer[ 5] = (((dbuttons >> 12) & 0xF) ^ 0xF); - buffer[ 6] = (thumb[0] >> 4) & 0xF; - buffer[ 7] = (thumb[0] >> 0) & 0xF; - buffer[ 8] = (thumb[1] >> 4) & 0xF; - buffer[ 9] = (thumb[1] >> 0) & 0xF; - buffer[10] = (shoulder[0] >> 4) & 0xF; - buffer[11] = (shoulder[0] >> 0) & 0xF; - buffer[12] = (shoulder[1] >> 4) & 0xF; - buffer[13] = (shoulder[1] >> 0) & 0xF; - buffer[14] = 0x0; - buffer[15] = 0x1; - } - else - { - phase = 8; - buffer[ 8] = 0x0; - buffer[ 9] = 0x2; - buffer[10] = (((dbuttons >> 0) & 0xF) ^ 0xF); - buffer[11] = (((dbuttons >> 4) & 0xF) ^ 0xF); - buffer[12] = (((dbuttons >> 8) & 0xF) ^ 0xF); - buffer[13] = (((dbuttons >> 12) & 0xF) ^ 0xF); - buffer[14] = 0x0; - buffer[15] = 0x1; - } - } - - data_out = buffer[phase]; - } - } - - tmp = (tl << 4) | data_out; - - return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); -} - -static const char* const ModeSwitchPositions[] = -{ - gettext_noop("Digital(+)"), - gettext_noop("Analog(○)"), -}; - -IDIISG IODevice_3DPad_IDII = -{ - { "up", "D-Pad UP ↑", 0, IDIT_BUTTON, "down" }, - { "down", "D-Pad DOWN ↓", 1, IDIT_BUTTON, "up" }, - { "left", "D-Pad LEFT ←", 2, IDIT_BUTTON, "right" }, - { "right", "D-Pad RIGHT →", 3, IDIT_BUTTON, "left" }, - - { "b", "B", 6, IDIT_BUTTON }, - { "c", "C", 7, IDIT_BUTTON }, - { "a", "A", 5, IDIT_BUTTON }, - { "start", "START", 4, IDIT_BUTTON }, - - { "z", "Z", 10, IDIT_BUTTON }, - { "y", "Y", 9, IDIT_BUTTON }, - { "x", "X", 8, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - - IDIIS_Switch("mode", "Mode", 17, ModeSwitchPositions, sizeof(ModeSwitchPositions) / sizeof(ModeSwitchPositions[0])), - - { "analog_left", "Analog LEFT ←", 15, IDIT_BUTTON_ANALOG }, - { "analog_right", "Analog RIGHT →", 16, IDIT_BUTTON_ANALOG }, - { "analog_up", "Analog UP ↑", 13, IDIT_BUTTON_ANALOG }, - { "analog_down", "Analog DOWN ↓", 14, IDIT_BUTTON_ANALOG }, - - { "rs", "Right Shoulder (Analog)", 12, IDIT_BUTTON_ANALOG }, - { "ls", "Left Shoulder (Analog)", 11, IDIT_BUTTON_ANALOG }, -}; - - - - -} +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* 3dpad.cpp: +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "3dpad.h" + +namespace MDFN_IEN_SS +{ + +IODevice_3DPad::IODevice_3DPad() : dbuttons(0), mode(false) +{ + +} + +IODevice_3DPad::~IODevice_3DPad() +{ + +} + +void IODevice_3DPad::Power(void) +{ + phase = -1; + tl = true; + data_out = 0x01; +} + +void IODevice_3DPad::UpdateInput(const uint8 *data, const int32 time_elapsed) +{ + const uint16 dtmp = MDFN_de16lsb(&data[0]); + + dbuttons = (dbuttons & 0x8800) | (dtmp & 0x0FFF); + mode = (bool)(dtmp & 0x1000); + + thumb[0] = data[2]; + thumb[1] = data[3]; + shoulder[0] = data[4]; + shoulder[1] = data[5]; + + for (unsigned w = 0; w < 2; w++) + { + // May not be right for digital mode, but shouldn't matter too much: + if (shoulder[w] <= 0x55) + dbuttons &= ~(0x0800 << (w << 2)); + else if (shoulder[w] >= 0x8E) + dbuttons |= 0x0800 << (w << 2); + } +} + +uint8 IODevice_3DPad::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) +{ + uint8 tmp; + + if(smpc_out & 0x40) + { + phase = -1; + tl = true; + data_out = 0x01; + } + else + { + if((bool)(smpc_out & 0x20) != tl) + { + if(phase < 15) + { + tl = !tl; + phase++; + } + + if(!phase) + { + if(mode) + { + buffer[ 0] = 0x1; + buffer[ 1] = 0x6; + buffer[ 2] = (((dbuttons >> 0) & 0xF) ^ 0xF); + buffer[ 3] = (((dbuttons >> 4) & 0xF) ^ 0xF); + buffer[ 4] = (((dbuttons >> 8) & 0xF) ^ 0xF); + buffer[ 5] = (((dbuttons >> 12) & 0xF) ^ 0xF); + buffer[ 6] = (thumb[0] >> 4) & 0xF; + buffer[ 7] = (thumb[0] >> 0) & 0xF; + buffer[ 8] = (thumb[1] >> 4) & 0xF; + buffer[ 9] = (thumb[1] >> 0) & 0xF; + buffer[10] = (shoulder[0] >> 4) & 0xF; + buffer[11] = (shoulder[0] >> 0) & 0xF; + buffer[12] = (shoulder[1] >> 4) & 0xF; + buffer[13] = (shoulder[1] >> 0) & 0xF; + buffer[14] = 0x0; + buffer[15] = 0x1; + } + else + { + phase = 8; + buffer[ 8] = 0x0; + buffer[ 9] = 0x2; + buffer[10] = (((dbuttons >> 0) & 0xF) ^ 0xF); + buffer[11] = (((dbuttons >> 4) & 0xF) ^ 0xF); + buffer[12] = (((dbuttons >> 8) & 0xF) ^ 0xF); + buffer[13] = (((dbuttons >> 12) & 0xF) ^ 0xF); + buffer[14] = 0x0; + buffer[15] = 0x1; + } + } + + data_out = buffer[phase]; + } + } + + tmp = (tl << 4) | data_out; + + return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); +} + +static const char* const ModeSwitchPositions[] = +{ + gettext_noop("Digital(+)"), + gettext_noop("Analog(○)"), +}; + +IDIISG IODevice_3DPad_IDII = +{ + { "up", "D-Pad UP ↑", 0, IDIT_BUTTON, "down" }, + { "down", "D-Pad DOWN ↓", 1, IDIT_BUTTON, "up" }, + { "left", "D-Pad LEFT ←", 2, IDIT_BUTTON, "right" }, + { "right", "D-Pad RIGHT →", 3, IDIT_BUTTON, "left" }, + + { "b", "B", 6, IDIT_BUTTON }, + { "c", "C", 7, IDIT_BUTTON }, + { "a", "A", 5, IDIT_BUTTON }, + { "start", "START", 4, IDIT_BUTTON }, + + { "z", "Z", 10, IDIT_BUTTON }, + { "y", "Y", 9, IDIT_BUTTON }, + { "x", "X", 8, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + + IDIIS_Switch("mode", "Mode", 17, ModeSwitchPositions, sizeof(ModeSwitchPositions) / sizeof(ModeSwitchPositions[0])), + + { "analog_left", "Analog LEFT ←", 15, IDIT_BUTTON_ANALOG }, + { "analog_right", "Analog RIGHT →", 16, IDIT_BUTTON_ANALOG }, + { "analog_up", "Analog UP ↑", 13, IDIT_BUTTON_ANALOG }, + { "analog_down", "Analog DOWN ↓", 14, IDIT_BUTTON_ANALOG }, + + { "rs", "Right Shoulder (Analog)", 12, IDIT_BUTTON_ANALOG }, + { "ls", "Left Shoulder (Analog)", 11, IDIT_BUTTON_ANALOG }, +}; + + + + +} diff --git a/waterbox/ss/input/mission.cpp b/waterbox/ss/input/mission.cpp index 50797c8139..324fc2211f 100644 --- a/waterbox/ss/input/mission.cpp +++ b/waterbox/ss/input/mission.cpp @@ -1,330 +1,329 @@ -/******************************************************************************/ -/* Mednafen Sega Saturn Emulation Module */ -/******************************************************************************/ -/* mission.cpp: -** Copyright (C) 2017 Mednafen Team -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of the GNU General Public License -** as published by the Free Software Foundation; either version 2 -** of the License, or (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, Inc., -** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -/* - Real mission stick has bugs and quirks that aren't emulated here(like apparently latching/updating the physical input state at the end of the - read sequence instead of near the beginning like other controllers do, resulting in increased latency). -*/ - - -#include "common.h" -#include "mission.h" - -namespace MDFN_IEN_SS -{ - -IODevice_Mission::IODevice_Mission(const bool dual_) : dbuttons(0), afeswitches(0), afspeed(0), dual(dual_) -{ - -} - -IODevice_Mission::~IODevice_Mission() -{ - -} - -void IODevice_Mission::Power(void) -{ - phase = -1; - tl = true; - data_out = 0x01; - - // Power-on state not tested: - afcounter = 0; - afphase = false; -} - -void IODevice_Mission::UpdateInput(const uint8* data, const int32 time_elapsed) -{ - const uint32 dtmp = MDFN_de32lsb(&data[0]); - - dbuttons = (dbuttons & 0xF) | ((dtmp & 0xFFF) << 4); - afeswitches = ((dtmp >> 12) & 0x8FF) << 4; - afspeed = (dtmp >> 20) & 0x7; - - for(unsigned stick = 0; stick < (dual ? 2 : 1); stick++) - { - for(unsigned axis = 0; axis < 3; axis++) - { - int32 tmp = 32767 + MDFN_de16lsb(&data[0x3 + ((axis + (stick * 3)) * 4) + 2]) - MDFN_de16lsb(&data[0x3 + ((axis + (stick * 3)) * 4) + 0]); - - axes[stick][axis] = (tmp * 255 + 32767) / 65534; - } - } - - //printf("Update: %02x %02x %02x\n", axes[0][0], axes[0][1], axes[0][2]); -} - -uint8 IODevice_Mission::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) -{ - uint8 tmp; - - if(smpc_out & 0x40) - { - phase = -1; - tl = true; - data_out = 0x01; - } - else - { - if((bool)(smpc_out & 0x20) != tl) - { - if(phase < (dual ? 21 : 13)) - { - tl = !tl; - phase++; - } - - if(!phase) - { - unsigned dbaf = dbuttons & ((afphase - 1) | ~afeswitches); - unsigned c = 0; - - // Digital Left - dbuttons |= ((axes[0][0] <= 0x56) ? 0x4 : 0); - dbuttons &= ~((axes[0][0] >= 0x6C) ? 0x4 : 0); - - // Digital Right - dbuttons |= ((axes[0][0] >= 0xAB) ? 0x8 : 0); - dbuttons &= ~((axes[0][0] <= 0x95) ? 0x8 : 0); - - // Digital Up - dbuttons |= ((axes[0][1] <= 0x54) ? 0x1 : 0); - dbuttons &= ~((axes[0][1] >= 0x6A) ? 0x1 : 0); - - // Digital Down - dbuttons |= ((axes[0][1] >= 0xA9) ? 0x2 : 0); - dbuttons &= ~((axes[0][1] <= 0x94) ? 0x2 : 0); - - if(!afcounter) - { - static const uint8 speedtab[7] = { 12, 8, 7, 5, 4, 4/* ? */, 1 }; - afphase = !afphase; - afcounter = speedtab[afspeed]; - } - afcounter--; - - buffer[c++] = 0x1; - buffer[c++] = dual ? 0x9 : 0x5; - buffer[c++] = (((dbaf >> 0) & 0xF) ^ 0xF); - buffer[c++] = (((dbaf >> 4) & 0xF) ^ 0xF); - buffer[c++] = (((dbaf >> 8) & 0xF) ^ 0xF); - buffer[c++] = (((dbaf >> 12) & 0xF) ^ 0xF); - - for(unsigned stick = 0; stick < (dual ? 2 : 1); stick++) - { - if(stick) - { - // Not sure, looks like something buggy. - buffer[c++] = 0x0; - buffer[c++] = 0x0; - } - - buffer[c++] = (axes[stick][0] >> 4) & 0xF; - buffer[c++] = (axes[stick][0] >> 0) & 0xF; - buffer[c++] = (axes[stick][1] >> 4) & 0xF; - buffer[c++] = (axes[stick][1] >> 0) & 0xF; - buffer[c++] = (axes[stick][2] >> 4) & 0xF; - buffer[c++] = (axes[stick][2] >> 0) & 0xF; - } - buffer[c++] = 0x0; - buffer[c++] = 0x1; - } - - data_out = buffer[phase]; - } - } - - tmp = (tl << 4) | data_out; - - return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); -} - -static const char* const SpeedSwitchPositions[] = -{ - gettext_noop("1/7"), - gettext_noop("2/7"), - gettext_noop("3/7"), - gettext_noop("4/7"), - gettext_noop("5/7"), - gettext_noop("6/7"), - gettext_noop("7/7") -}; - -static const char* const AFSwitchPositions[] = -{ - gettext_noop("• (Off)"), - gettext_noop("•• (On)") -}; - -IDIISG IODevice_Mission_IDII = -{ - // 0 - { "b", "B (Stick Left Button)", 6, IDIT_BUTTON }, - { "c", "C (Stick Right Button)", 8, IDIT_BUTTON }, - { "a", "A (Stick Trigger)", 7, IDIT_BUTTON }, - { "start", "START", 9, IDIT_BUTTON }, - - // 4 - { "z", "Z", 13, IDIT_BUTTON }, - { "y", "Y", 12, IDIT_BUTTON }, - { "x", "X", 11, IDIT_BUTTON }, - { "r", "R", 14, IDIT_BUTTON }, - - // 8 - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { "l", "L", 10, IDIT_BUTTON }, - - // 12 - IDIIS_Switch("afb", "B AF", 20, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - IDIIS_Switch("afc", "C AF", 21, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - IDIIS_Switch("afa", "A AF", 19, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - { NULL, "empty", 0, IDIT_BUTTON }, - - // 16 - IDIIS_Switch("afz", "Z AF", 17, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - IDIIS_Switch("afy", "Y AF", 16, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - IDIIS_Switch("afx", "X AF", 15, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - IDIIS_Switch("afr", "R AF", 22, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - - // 20 - IDIIS_Switch("afspeed", "AF Speed", 23, SpeedSwitchPositions, sizeof(SpeedSwitchPositions) / sizeof(SpeedSwitchPositions[0])), - IDIIS_Switch("afl", "L AF", 18, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - - // 24 - { "stick_left", "Stick LEFT ← (Analog)", 2, IDIT_BUTTON_ANALOG }, - { "stick_right", "Stick RIGHT → (Analog)", 3, IDIT_BUTTON_ANALOG }, - { "stick_fore", "Stick FORE ↑ (Analog)", 0, IDIT_BUTTON_ANALOG }, - { "stick_back", "Stick BACK ↓ (Analog)", 1, IDIT_BUTTON_ANALOG }, - - { "throttle_down", "Throttle Down (Analog)", 5, IDIT_BUTTON_ANALOG }, - { "throttle_up", "Throttle Up (Analog)", 4, IDIT_BUTTON_ANALOG }, -}; - -IDIISG IODevice_MissionNoAF_IDII = -{ - // 0 - { "b", "B (Stick Left Button)", 6, IDIT_BUTTON }, - { "c", "C (Stick Right Button)", 8, IDIT_BUTTON }, - { "a", "A (Stick Trigger)", 7, IDIT_BUTTON }, - { "start", "START", 9, IDIT_BUTTON }, - - // 4 - { "z", "Z", 13, IDIT_BUTTON }, - { "y", "Y", 12, IDIT_BUTTON }, - { "x", "X", 11, IDIT_BUTTON }, - { "r", "R", 14, IDIT_BUTTON }, - - // 8 - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { "l", "L", 10, IDIT_BUTTON }, - - // 12 - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - - // 16 - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - - // 20 - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - - // 24 - { "stick_left", "Stick LEFT ← (Analog)", 2, IDIT_BUTTON_ANALOG }, - { "stick_right", "Stick RIGHT → (Analog)", 3, IDIT_BUTTON_ANALOG }, - { "stick_fore", "Stick FORE ↑ (Analog)", 0, IDIT_BUTTON_ANALOG }, - { "stick_back", "Stick BACK ↓ (Analog)", 1, IDIT_BUTTON_ANALOG }, - - { "throttle_down", "Throttle Down (Analog)", 5, IDIT_BUTTON_ANALOG }, - { "throttle_up", "Throttle Up (Analog)", 4, IDIT_BUTTON_ANALOG }, -}; - - -IDIISG IODevice_DualMission_IDII = -{ - // 0 - { "b", "B (R Stick Left Button)", 15, IDIT_BUTTON }, - { "c", "C (R Stick Right Button)", 17, IDIT_BUTTON }, - { "a", "A (R Stick Trigger)", 16, IDIT_BUTTON }, - { "start", "START", 18, IDIT_BUTTON }, - - // 4 - { "z", "Z (L Stick Right Button)", 8, IDIT_BUTTON }, - { "y", "Y (L Stick Left Button)", 6, IDIT_BUTTON }, - { "x", "X (L Stick Trigger)", 7, IDIT_BUTTON }, - { "r", "R", 20, IDIT_BUTTON }, - - // 8 - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { "l", "L", 19, IDIT_BUTTON }, - - // 12 - IDIIS_Switch("afb", "B AF", 26, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - IDIIS_Switch("afc", "C AF", 27, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - IDIIS_Switch("afa", "A AF", 25, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - { NULL, "empty", 0, IDIT_BUTTON }, - - // 16 - IDIIS_Switch("afz", "Z AF", 23, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - IDIIS_Switch("afy", "Y AF", 22, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - IDIIS_Switch("afx", "X AF", 21, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - IDIIS_Switch("afr", "R AF", 28, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - - // 20 - IDIIS_Switch("afspeed", "Autofire Speed", 29, SpeedSwitchPositions, sizeof(SpeedSwitchPositions) / sizeof(SpeedSwitchPositions[0])), - IDIIS_Switch("afl", "L AF", 24, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), - - // 24 - { "rstick_left", "R Stick LEFT ← (Analog)", 11, IDIT_BUTTON_ANALOG }, - { "rstick_right", "R Stick RIGHT → (Analog)", 12, IDIT_BUTTON_ANALOG }, - { "rstick_fore", "R Stick FORE ↑ (Analog)", 9, IDIT_BUTTON_ANALOG }, - { "rstick_back", "R Stick BACK ↓ (Analog)", 10, IDIT_BUTTON_ANALOG }, - - { "rthrottle_down", "R Throttle Down (Analog)", 14, IDIT_BUTTON_ANALOG }, - { "rthrottle_up", "R Throttle Up (Analog)", 13, IDIT_BUTTON_ANALOG }, - - { "lstick_left", "L Stick LEFT ← (Analog)", 2, IDIT_BUTTON_ANALOG }, - { "lstick_right", "L Stick RIGHT → (Analog)", 3, IDIT_BUTTON_ANALOG }, - { "lstick_fore", "L Stick FORE ↑ (Analog)", 0, IDIT_BUTTON_ANALOG }, - { "lstick_back", "L Stick BACK ↓ (Analog)", 1, IDIT_BUTTON_ANALOG }, - - { "lthrottle_down", "L Throttle Down (Analog)", 5, IDIT_BUTTON_ANALOG }, - { "lthrottle_up", "L Throttle Up (Analog)", 4, IDIT_BUTTON_ANALOG }, - -}; - - - -} +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* mission.cpp: +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/* + Real mission stick has bugs and quirks that aren't emulated here(like apparently latching/updating the physical input state at the end of the + read sequence instead of near the beginning like other controllers do, resulting in increased latency). +*/ + + +#include "common.h" +#include "mission.h" + +namespace MDFN_IEN_SS +{ + +IODevice_Mission::IODevice_Mission(const bool dual_) : dbuttons(0), afeswitches(0), afspeed(0), dual(dual_) +{ + +} + +IODevice_Mission::~IODevice_Mission() +{ + +} + +void IODevice_Mission::Power(void) +{ + phase = -1; + tl = true; + data_out = 0x01; + + // Power-on state not tested: + afcounter = 0; + afphase = false; +} + +void IODevice_Mission::UpdateInput(const uint8 *data, const int32 time_elapsed) +{ + const uint32 dtmp = MDFN_de32lsb(&data[0]); + + dbuttons = (dbuttons & 0xF) | ((dtmp & 0xFFF) << 4); + afeswitches = ((dtmp >> 12) & 0x8FF) << 4; + afspeed = (dtmp >> 20) & 0x7; + + int offs = 4; + for (unsigned stick = 0; stick < (dual ? 2 : 1); stick++) + { + for (unsigned axis = 0; axis < 3; axis++) + { + axes[stick][axis] = data[offs++]; + } + } + + //printf("Update: %02x %02x %02x\n", axes[0][0], axes[0][1], axes[0][2]); +} + +uint8 IODevice_Mission::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) +{ + uint8 tmp; + + if(smpc_out & 0x40) + { + phase = -1; + tl = true; + data_out = 0x01; + } + else + { + if((bool)(smpc_out & 0x20) != tl) + { + if(phase < (dual ? 21 : 13)) + { + tl = !tl; + phase++; + } + + if(!phase) + { + unsigned dbaf = dbuttons & ((afphase - 1) | ~afeswitches); + unsigned c = 0; + + // Digital Left + dbuttons |= ((axes[0][0] <= 0x56) ? 0x4 : 0); + dbuttons &= ~((axes[0][0] >= 0x6C) ? 0x4 : 0); + + // Digital Right + dbuttons |= ((axes[0][0] >= 0xAB) ? 0x8 : 0); + dbuttons &= ~((axes[0][0] <= 0x95) ? 0x8 : 0); + + // Digital Up + dbuttons |= ((axes[0][1] <= 0x54) ? 0x1 : 0); + dbuttons &= ~((axes[0][1] >= 0x6A) ? 0x1 : 0); + + // Digital Down + dbuttons |= ((axes[0][1] >= 0xA9) ? 0x2 : 0); + dbuttons &= ~((axes[0][1] <= 0x94) ? 0x2 : 0); + + if(!afcounter) + { + static const uint8 speedtab[7] = { 12, 8, 7, 5, 4, 4/* ? */, 1 }; + afphase = !afphase; + afcounter = speedtab[afspeed]; + } + afcounter--; + + buffer[c++] = 0x1; + buffer[c++] = dual ? 0x9 : 0x5; + buffer[c++] = (((dbaf >> 0) & 0xF) ^ 0xF); + buffer[c++] = (((dbaf >> 4) & 0xF) ^ 0xF); + buffer[c++] = (((dbaf >> 8) & 0xF) ^ 0xF); + buffer[c++] = (((dbaf >> 12) & 0xF) ^ 0xF); + + for(unsigned stick = 0; stick < (dual ? 2 : 1); stick++) + { + if(stick) + { + // Not sure, looks like something buggy. + buffer[c++] = 0x0; + buffer[c++] = 0x0; + } + + buffer[c++] = (axes[stick][0] >> 4) & 0xF; + buffer[c++] = (axes[stick][0] >> 0) & 0xF; + buffer[c++] = (axes[stick][1] >> 4) & 0xF; + buffer[c++] = (axes[stick][1] >> 0) & 0xF; + buffer[c++] = (axes[stick][2] >> 4) & 0xF; + buffer[c++] = (axes[stick][2] >> 0) & 0xF; + } + buffer[c++] = 0x0; + buffer[c++] = 0x1; + } + + data_out = buffer[phase]; + } + } + + tmp = (tl << 4) | data_out; + + return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); +} + +static const char* const SpeedSwitchPositions[] = +{ + gettext_noop("1/7"), + gettext_noop("2/7"), + gettext_noop("3/7"), + gettext_noop("4/7"), + gettext_noop("5/7"), + gettext_noop("6/7"), + gettext_noop("7/7") +}; + +static const char* const AFSwitchPositions[] = +{ + gettext_noop("• (Off)"), + gettext_noop("•• (On)") +}; + +IDIISG IODevice_Mission_IDII = +{ + // 0 + { "b", "B (Stick Left Button)", 6, IDIT_BUTTON }, + { "c", "C (Stick Right Button)", 8, IDIT_BUTTON }, + { "a", "A (Stick Trigger)", 7, IDIT_BUTTON }, + { "start", "START", 9, IDIT_BUTTON }, + + // 4 + { "z", "Z", 13, IDIT_BUTTON }, + { "y", "Y", 12, IDIT_BUTTON }, + { "x", "X", 11, IDIT_BUTTON }, + { "r", "R", 14, IDIT_BUTTON }, + + // 8 + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { "l", "L", 10, IDIT_BUTTON }, + + // 12 + IDIIS_Switch("afb", "B AF", 20, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + IDIIS_Switch("afc", "C AF", 21, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + IDIIS_Switch("afa", "A AF", 19, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + { NULL, "empty", 0, IDIT_BUTTON }, + + // 16 + IDIIS_Switch("afz", "Z AF", 17, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + IDIIS_Switch("afy", "Y AF", 16, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + IDIIS_Switch("afx", "X AF", 15, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + IDIIS_Switch("afr", "R AF", 22, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + + // 20 + IDIIS_Switch("afspeed", "AF Speed", 23, SpeedSwitchPositions, sizeof(SpeedSwitchPositions) / sizeof(SpeedSwitchPositions[0])), + IDIIS_Switch("afl", "L AF", 18, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + + // 24 + { "stick_left", "Stick LEFT ← (Analog)", 2, IDIT_BUTTON_ANALOG }, + { "stick_right", "Stick RIGHT → (Analog)", 3, IDIT_BUTTON_ANALOG }, + { "stick_fore", "Stick FORE ↑ (Analog)", 0, IDIT_BUTTON_ANALOG }, + { "stick_back", "Stick BACK ↓ (Analog)", 1, IDIT_BUTTON_ANALOG }, + + { "throttle_down", "Throttle Down (Analog)", 5, IDIT_BUTTON_ANALOG }, + { "throttle_up", "Throttle Up (Analog)", 4, IDIT_BUTTON_ANALOG }, +}; + +IDIISG IODevice_MissionNoAF_IDII = +{ + // 0 + { "b", "B (Stick Left Button)", 6, IDIT_BUTTON }, + { "c", "C (Stick Right Button)", 8, IDIT_BUTTON }, + { "a", "A (Stick Trigger)", 7, IDIT_BUTTON }, + { "start", "START", 9, IDIT_BUTTON }, + + // 4 + { "z", "Z", 13, IDIT_BUTTON }, + { "y", "Y", 12, IDIT_BUTTON }, + { "x", "X", 11, IDIT_BUTTON }, + { "r", "R", 14, IDIT_BUTTON }, + + // 8 + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { "l", "L", 10, IDIT_BUTTON }, + + // 12 + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + + // 16 + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + + // 20 + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + + // 24 + { "stick_left", "Stick LEFT ← (Analog)", 2, IDIT_BUTTON_ANALOG }, + { "stick_right", "Stick RIGHT → (Analog)", 3, IDIT_BUTTON_ANALOG }, + { "stick_fore", "Stick FORE ↑ (Analog)", 0, IDIT_BUTTON_ANALOG }, + { "stick_back", "Stick BACK ↓ (Analog)", 1, IDIT_BUTTON_ANALOG }, + + { "throttle_down", "Throttle Down (Analog)", 5, IDIT_BUTTON_ANALOG }, + { "throttle_up", "Throttle Up (Analog)", 4, IDIT_BUTTON_ANALOG }, +}; + + +IDIISG IODevice_DualMission_IDII = +{ + // 0 + { "b", "B (R Stick Left Button)", 15, IDIT_BUTTON }, + { "c", "C (R Stick Right Button)", 17, IDIT_BUTTON }, + { "a", "A (R Stick Trigger)", 16, IDIT_BUTTON }, + { "start", "START", 18, IDIT_BUTTON }, + + // 4 + { "z", "Z (L Stick Right Button)", 8, IDIT_BUTTON }, + { "y", "Y (L Stick Left Button)", 6, IDIT_BUTTON }, + { "x", "X (L Stick Trigger)", 7, IDIT_BUTTON }, + { "r", "R", 20, IDIT_BUTTON }, + + // 8 + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { "l", "L", 19, IDIT_BUTTON }, + + // 12 + IDIIS_Switch("afb", "B AF", 26, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + IDIIS_Switch("afc", "C AF", 27, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + IDIIS_Switch("afa", "A AF", 25, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + { NULL, "empty", 0, IDIT_BUTTON }, + + // 16 + IDIIS_Switch("afz", "Z AF", 23, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + IDIIS_Switch("afy", "Y AF", 22, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + IDIIS_Switch("afx", "X AF", 21, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + IDIIS_Switch("afr", "R AF", 28, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + + // 20 + IDIIS_Switch("afspeed", "Autofire Speed", 29, SpeedSwitchPositions, sizeof(SpeedSwitchPositions) / sizeof(SpeedSwitchPositions[0])), + IDIIS_Switch("afl", "L AF", 24, AFSwitchPositions, sizeof(AFSwitchPositions) / sizeof(AFSwitchPositions[0])), + + // 24 + { "rstick_left", "R Stick LEFT ← (Analog)", 11, IDIT_BUTTON_ANALOG }, + { "rstick_right", "R Stick RIGHT → (Analog)", 12, IDIT_BUTTON_ANALOG }, + { "rstick_fore", "R Stick FORE ↑ (Analog)", 9, IDIT_BUTTON_ANALOG }, + { "rstick_back", "R Stick BACK ↓ (Analog)", 10, IDIT_BUTTON_ANALOG }, + + { "rthrottle_down", "R Throttle Down (Analog)", 14, IDIT_BUTTON_ANALOG }, + { "rthrottle_up", "R Throttle Up (Analog)", 13, IDIT_BUTTON_ANALOG }, + + { "lstick_left", "L Stick LEFT ← (Analog)", 2, IDIT_BUTTON_ANALOG }, + { "lstick_right", "L Stick RIGHT → (Analog)", 3, IDIT_BUTTON_ANALOG }, + { "lstick_fore", "L Stick FORE ↑ (Analog)", 0, IDIT_BUTTON_ANALOG }, + { "lstick_back", "L Stick BACK ↓ (Analog)", 1, IDIT_BUTTON_ANALOG }, + + { "lthrottle_down", "L Throttle Down (Analog)", 5, IDIT_BUTTON_ANALOG }, + { "lthrottle_up", "L Throttle Up (Analog)", 4, IDIT_BUTTON_ANALOG }, + +}; + + + +} diff --git a/waterbox/ss/input/mouse.cpp b/waterbox/ss/input/mouse.cpp index 28dc28dbf3..2cfbf441b2 100644 --- a/waterbox/ss/input/mouse.cpp +++ b/waterbox/ss/input/mouse.cpp @@ -1,143 +1,143 @@ -/******************************************************************************/ -/* Mednafen Sega Saturn Emulation Module */ -/******************************************************************************/ -/* mouse.cpp: -** Copyright (C) 2016-2017 Mednafen Team -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of the GNU General Public License -** as published by the Free Software Foundation; either version 2 -** of the License, or (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, Inc., -** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "common.h" -#include "mouse.h" - -namespace MDFN_IEN_SS -{ - -IODevice_Mouse::IODevice_Mouse() : buttons(0) -{ - -} - -IODevice_Mouse::~IODevice_Mouse() -{ - -} - -void IODevice_Mouse::Power(void) -{ - phase = -1; - tl = true; - data_out = 0x00; - accum_xdelta = 0; - accum_ydelta = 0; -} - -void IODevice_Mouse::UpdateInput(const uint8* data, const int32 time_elapsed) -{ - accum_xdelta += MDFN_de32lsb(&data[0]); - accum_ydelta -= MDFN_de32lsb(&data[4]); - buttons = data[8] & 0xF; -} - -uint8 IODevice_Mouse::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) -{ - uint8 tmp; - - if(smpc_out & 0x40) - { - if(smpc_out & 0x20) - { - if(!tl) - accum_xdelta = accum_ydelta = 0; - - phase = -1; - tl = true; - data_out = 0x00; - } - else - { - if(tl) - tl = false; - } - } - else - { - if(phase < 0) - { - uint8 flags = 0; - - if(accum_xdelta < 0) - flags |= 0x1; - - if(accum_ydelta < 0) - flags |= 0x2; - - if(accum_xdelta > 255 || accum_xdelta < -256) - { - flags |= 0x4; - accum_xdelta = (accum_xdelta < 0) ? -256 : 255; - } - - if(accum_ydelta > 255 || accum_ydelta < -256) - { - flags |= 0x8; - accum_ydelta = (accum_ydelta < 0) ? -256 : 255; - } - - buffer[0] = 0xB; - buffer[1] = 0xF; - buffer[2] = 0xF; - buffer[3] = flags; - buffer[4] = buttons; - buffer[5] = (accum_xdelta >> 4) & 0xF; - buffer[6] = (accum_xdelta >> 0) & 0xF; - buffer[7] = (accum_ydelta >> 4) & 0xF; - buffer[8] = (accum_ydelta >> 0) & 0xF; - - for(int i = 9; i < 16; i++) - buffer[i] = buffer[8]; - - phase++; - } - - if((bool)(smpc_out & 0x20) != tl) - { - phase = (phase + 1) & 0xF; - tl = !tl; - - if(phase == 8) - accum_xdelta = accum_ydelta = 0; - } - data_out = buffer[phase]; - } - - tmp = (tl << 4) | data_out; - - return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); -} - -IDIISG IODevice_Mouse_IDII = -{ - { "x_axis", "X Axis", -1, IDIT_X_AXIS_REL }, - { "y_axis", "Y Axis", -1, IDIT_Y_AXIS_REL }, - - { "left", "Left Button", 0, IDIT_BUTTON }, - { "right", "Right Button", 2, IDIT_BUTTON }, - { "middle", "Middle Button", 1, IDIT_BUTTON }, - { "start", "Start", 3, IDIT_BUTTON }, -}; - - -} +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* mouse.cpp: +** Copyright (C) 2016-2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "mouse.h" + +namespace MDFN_IEN_SS +{ + +IODevice_Mouse::IODevice_Mouse() : buttons(0) +{ + +} + +IODevice_Mouse::~IODevice_Mouse() +{ + +} + +void IODevice_Mouse::Power(void) +{ + phase = -1; + tl = true; + data_out = 0x00; + accum_xdelta = 0; + accum_ydelta = 0; +} + +void IODevice_Mouse::UpdateInput(const uint8* data, const int32 time_elapsed) +{ + accum_xdelta += data[1]; + accum_ydelta -= data[2]; + buttons = data[0] & 0xF; +} + +uint8 IODevice_Mouse::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) +{ + uint8 tmp; + + if(smpc_out & 0x40) + { + if(smpc_out & 0x20) + { + if(!tl) + accum_xdelta = accum_ydelta = 0; + + phase = -1; + tl = true; + data_out = 0x00; + } + else + { + if(tl) + tl = false; + } + } + else + { + if(phase < 0) + { + uint8 flags = 0; + + if(accum_xdelta < 0) + flags |= 0x1; + + if(accum_ydelta < 0) + flags |= 0x2; + + if(accum_xdelta > 255 || accum_xdelta < -256) + { + flags |= 0x4; + accum_xdelta = (accum_xdelta < 0) ? -256 : 255; + } + + if(accum_ydelta > 255 || accum_ydelta < -256) + { + flags |= 0x8; + accum_ydelta = (accum_ydelta < 0) ? -256 : 255; + } + + buffer[0] = 0xB; + buffer[1] = 0xF; + buffer[2] = 0xF; + buffer[3] = flags; + buffer[4] = buttons; + buffer[5] = (accum_xdelta >> 4) & 0xF; + buffer[6] = (accum_xdelta >> 0) & 0xF; + buffer[7] = (accum_ydelta >> 4) & 0xF; + buffer[8] = (accum_ydelta >> 0) & 0xF; + + for(int i = 9; i < 16; i++) + buffer[i] = buffer[8]; + + phase++; + } + + if((bool)(smpc_out & 0x20) != tl) + { + phase = (phase + 1) & 0xF; + tl = !tl; + + if(phase == 8) + accum_xdelta = accum_ydelta = 0; + } + data_out = buffer[phase]; + } + + tmp = (tl << 4) | data_out; + + return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); +} + +IDIISG IODevice_Mouse_IDII = +{ + { "x_axis", "X Axis", -1, IDIT_X_AXIS_REL }, + { "y_axis", "Y Axis", -1, IDIT_Y_AXIS_REL }, + + { "left", "Left Button", 0, IDIT_BUTTON }, + { "right", "Right Button", 2, IDIT_BUTTON }, + { "middle", "Middle Button", 1, IDIT_BUTTON }, + { "start", "Start", 3, IDIT_BUTTON }, +}; + + +} diff --git a/waterbox/ss/input/wheel.cpp b/waterbox/ss/input/wheel.cpp index d557780c23..bb47175dd8 100644 --- a/waterbox/ss/input/wheel.cpp +++ b/waterbox/ss/input/wheel.cpp @@ -1,141 +1,134 @@ -/******************************************************************************/ -/* Mednafen Sega Saturn Emulation Module */ -/******************************************************************************/ -/* wheel.cpp: -** Copyright (C) 2017 Mednafen Team -** -** This program is free software; you can redistribute it and/or -** modify it under the terms of the GNU General Public License -** as published by the Free Software Foundation; either version 2 -** of the License, or (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, Inc., -** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "common.h" -#include "wheel.h" - -namespace MDFN_IEN_SS -{ - -IODevice_Wheel::IODevice_Wheel() : dbuttons(0) -{ - -} - -IODevice_Wheel::~IODevice_Wheel() -{ - -} - -void IODevice_Wheel::Power(void) -{ - phase = -1; - tl = true; - data_out = 0x01; -} - -void IODevice_Wheel::UpdateInput(const uint8* data, const int32 time_elapsed) -{ - dbuttons = (dbuttons & 0xC) | (MDFN_de16lsb(&data[0]) & 0x07F3); - - // - { - int32 tmp = 32767 + MDFN_de16lsb(&data[0x2 + 2]) - MDFN_de16lsb(&data[0x2 + 0]); - - wheel = 1 + tmp * 253 / 65534; - - if(wheel >= 0x6F) - dbuttons &= ~0x4; - else if(wheel <= 0x67) - dbuttons |= 0x4; - - if(wheel <= 0x8F) - dbuttons &= ~0x8; - else if(wheel >= 0x97) - dbuttons |= 0x8; - } -} - -uint8 IODevice_Wheel::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) -{ - uint8 tmp; - - if(smpc_out & 0x40) - { - phase = -1; - tl = true; - data_out = 0x01; - } - else - { - if((bool)(smpc_out & 0x20) != tl) - { - if(phase < 0) - { - buffer[ 0] = 0x1; - buffer[ 1] = 0x3; - buffer[ 2] = (((dbuttons >> 0) & 0xF) ^ 0xF); - buffer[ 3] = (((dbuttons >> 4) & 0xF) ^ 0xF); - buffer[ 4] = (((dbuttons >> 8) & 0xF) ^ 0xF); - buffer[ 5] = (((dbuttons >> 12) & 0xF) ^ 0xF); - buffer[ 6] = ((wheel >> 4) & 0xF); - buffer[ 7] = ((wheel >> 0) & 0xF); - buffer[ 8] = 0x0; - buffer[ 9] = 0x1; - buffer[10] = 0x1; - buffer[11] = ((wheel >> 0) & 0xF); - buffer[12] = 0x0; - buffer[13] = 0x1; - buffer[14] = 0x1; - buffer[15] = 0x1; - } - - phase = (phase + 1) & 0xF; - data_out = buffer[phase]; - tl = !tl; - } - } - - tmp = (tl << 4) | data_out; - - return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); -} - -IDIISG IODevice_Wheel_IDII = -{ - { "up", "L Gear Shift(Equiv. UP ↑)", 2, IDIT_BUTTON, "down" }, - { "down", "R Gear Shift(Equiv. DOWN ↓)", 3, IDIT_BUTTON, "up" }, - { NULL, "empty", 0, IDIT_BUTTON }, // left - { NULL, "empty", 0, IDIT_BUTTON }, // right - - { "b", "B (R Group)", 9, IDIT_BUTTON }, - { "c", "C (R Group)", 10, IDIT_BUTTON }, - { "a", "A (R Group)", 8, IDIT_BUTTON }, - { "start", "START", 7, IDIT_BUTTON }, - - { "z", "Z (L Group)", 4, IDIT_BUTTON }, - { "y", "Y (L Group)", 5, IDIT_BUTTON }, - { "x", "X (L Group)", 6, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - { NULL, "empty", 0, IDIT_BUTTON }, - - { "analog_left", "Analog LEFT ←", 0, IDIT_BUTTON_ANALOG }, - { "analog_right", "Analog RIGHT →", 1, IDIT_BUTTON_ANALOG }, -}; - - - - -} +/******************************************************************************/ +/* Mednafen Sega Saturn Emulation Module */ +/******************************************************************************/ +/* wheel.cpp: +** Copyright (C) 2017 Mednafen Team +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, Inc., +** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "common.h" +#include "wheel.h" + +namespace MDFN_IEN_SS +{ + +IODevice_Wheel::IODevice_Wheel() : dbuttons(0) +{ + +} + +IODevice_Wheel::~IODevice_Wheel() +{ + +} + +void IODevice_Wheel::Power(void) +{ + phase = -1; + tl = true; + data_out = 0x01; +} + +void IODevice_Wheel::UpdateInput(const uint8 *data, const int32 time_elapsed) +{ + dbuttons = (dbuttons & 0xC) | (MDFN_de16lsb(&data[0]) & 0x07F3); + wheel = data[2]; + if (wheel >= 0x6F) + dbuttons &= ~0x4; + else if (wheel <= 0x67) + dbuttons |= 0x4; + + if (wheel <= 0x8F) + dbuttons &= ~0x8; + else if (wheel >= 0x97) + dbuttons |= 0x8; +} + +uint8 IODevice_Wheel::UpdateBus(const uint8 smpc_out, const uint8 smpc_out_asserted) +{ + uint8 tmp; + + if(smpc_out & 0x40) + { + phase = -1; + tl = true; + data_out = 0x01; + } + else + { + if((bool)(smpc_out & 0x20) != tl) + { + if(phase < 0) + { + buffer[ 0] = 0x1; + buffer[ 1] = 0x3; + buffer[ 2] = (((dbuttons >> 0) & 0xF) ^ 0xF); + buffer[ 3] = (((dbuttons >> 4) & 0xF) ^ 0xF); + buffer[ 4] = (((dbuttons >> 8) & 0xF) ^ 0xF); + buffer[ 5] = (((dbuttons >> 12) & 0xF) ^ 0xF); + buffer[ 6] = ((wheel >> 4) & 0xF); + buffer[ 7] = ((wheel >> 0) & 0xF); + buffer[ 8] = 0x0; + buffer[ 9] = 0x1; + buffer[10] = 0x1; + buffer[11] = ((wheel >> 0) & 0xF); + buffer[12] = 0x0; + buffer[13] = 0x1; + buffer[14] = 0x1; + buffer[15] = 0x1; + } + + phase = (phase + 1) & 0xF; + data_out = buffer[phase]; + tl = !tl; + } + } + + tmp = (tl << 4) | data_out; + + return (smpc_out & (smpc_out_asserted | 0xE0)) | (tmp &~ smpc_out_asserted); +} + +IDIISG IODevice_Wheel_IDII = +{ + { "up", "L Gear Shift(Equiv. UP ↑)", 2, IDIT_BUTTON, "down" }, + { "down", "R Gear Shift(Equiv. DOWN ↓)", 3, IDIT_BUTTON, "up" }, + { NULL, "empty", 0, IDIT_BUTTON }, // left + { NULL, "empty", 0, IDIT_BUTTON }, // right + + { "b", "B (R Group)", 9, IDIT_BUTTON }, + { "c", "C (R Group)", 10, IDIT_BUTTON }, + { "a", "A (R Group)", 8, IDIT_BUTTON }, + { "start", "START", 7, IDIT_BUTTON }, + + { "z", "Z (L Group)", 4, IDIT_BUTTON }, + { "y", "Y (L Group)", 5, IDIT_BUTTON }, + { "x", "X (L Group)", 6, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + { NULL, "empty", 0, IDIT_BUTTON }, + + { "analog_left", "Analog LEFT ←", 0, IDIT_BUTTON_ANALOG }, + { "analog_right", "Analog RIGHT →", 1, IDIT_BUTTON_ANALOG }, +}; + + + + +}