saturnus: get rid of the round-tripping of analogs through the mednafen input system.
This commit is contained in:
parent
9ff2da5265
commit
37b285fe8d
|
@ -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
|
||||
|
|
Binary file not shown.
|
@ -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 },
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue