mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-25 23:25:40 +00:00
Star Wars Trilogy lever feedback activated
This commit is contained in:
parent
402baf87b8
commit
5143669cb9
|
@ -2086,8 +2086,8 @@
|
||||||
<patches>
|
<patches>
|
||||||
<!-- skip force feedback lever check -->
|
<!-- skip force feedback lever check -->
|
||||||
<!-- <patch region="crom" bits="32" offset="0xf6e44" value="0x60000000" /> --> <!-- from MAME -->
|
<!-- <patch region="crom" bits="32" offset="0xf6e44" value="0x60000000" /> --> <!-- from MAME -->
|
||||||
<patch region="crom" bits="32" offset="0xf0e48" value="0x60000000" />
|
<!--<patch region="crom" bits="32" offset="0xf0e48" value="0x60000000" /> --> <!-- no more needed if ffb lever rom loaded -->
|
||||||
<patch region="crom" bits="32" offset="0x043dc" value="0x48000090" /> <!-- related to joystick feedback -->
|
<!--<patch region="crom" bits="32" offset="0x043dc" value="0x48000090" /> --> <!-- related to joystick feedback --> <!-- no more needed if ffb lever rom loaded -->
|
||||||
<patch region="crom" bits="32" offset="0x029a0" value="0x60000000" /> <!-- skip force feedback setup? -->
|
<patch region="crom" bits="32" offset="0x029a0" value="0x60000000" /> <!-- skip force feedback setup? -->
|
||||||
<patch region="crom" bits="32" offset="0x02a0c" value="0x60000000" />
|
<patch region="crom" bits="32" offset="0x02a0c" value="0x60000000" />
|
||||||
<!-- Additional patches from MAME for test menu -->
|
<!-- Additional patches from MAME for test menu -->
|
||||||
|
@ -2153,11 +2153,11 @@
|
||||||
<file offset="0xC00000" name="mpr-21378.24" crc32="0x1FCF715E" />
|
<file offset="0xC00000" name="mpr-21378.24" crc32="0x1FCF715E" />
|
||||||
</region>
|
</region>
|
||||||
<!-- Force feedback controller prg -->
|
<!-- Force feedback controller prg -->
|
||||||
<!--
|
|
||||||
<region name="ffb_program" stride="1" chunk_size="1">
|
<region name="ffb_program" stride="1" chunk_size="1">
|
||||||
<file offset="0" name="epr-21119.ic8" crc32="0x65082B14" />
|
<file offset="0" name="epr-21119.ic8" crc32="0x65082B14" />
|
||||||
</region>
|
</region>
|
||||||
-->
|
|
||||||
</roms>
|
</roms>
|
||||||
</game>
|
</game>
|
||||||
|
|
||||||
|
@ -2184,10 +2184,14 @@
|
||||||
<!--<patch region="crom" bits="32" offset="0xf6dd0" value="0x60000000" /> --> <!-- from MAME -->
|
<!--<patch region="crom" bits="32" offset="0xf6dd0" value="0x60000000" /> --> <!-- from MAME -->
|
||||||
<!-- Spindizzi notes : mimic patch from Bart's patch in swtrilgy to prevent game to be slow-->
|
<!-- Spindizzi notes : mimic patch from Bart's patch in swtrilgy to prevent game to be slow-->
|
||||||
<!-- instead of patch we can make hack timing in code -->
|
<!-- instead of patch we can make hack timing in code -->
|
||||||
<patch region="crom" bits="32" offset="0x043dc" value="0x48000090" />
|
<!--<patch region="crom" bits="32" offset="0x043dc" value="0x48000090" />--> <!-- no more needed if ffb lever rom loaded -->
|
||||||
<patch region="crom" bits="32" offset="0x029a0" value="0x60000000" />
|
<patch region="crom" bits="32" offset="0x029a0" value="0x60000000" />
|
||||||
<patch region="crom" bits="32" offset="0x02a0c" value="0x60000000" />
|
<patch region="crom" bits="32" offset="0x02a0c" value="0x60000000" />
|
||||||
<patch region="crom" bits="32" offset="0xf0dd4" value="0x60000000" />
|
<!--<patch region="crom" bits="32" offset="0xf0dd4" value="0x60000000" />--> <!-- no more needed if ffb lever rom loaded -->
|
||||||
|
<!-- Additional patches from MAME for test menu -->
|
||||||
|
<patch region="crom" bits="32" offset="0xf76f8" value="0x60000000" /> <!-- unemulated JTAG stuff -->
|
||||||
|
<patch region="crom" bits="32" offset="0xf76fc" value="0x60000000" /> <!-- "" -->
|
||||||
|
<patch region="crom" bits="32" offset="0xf7700" value="0x60000000" /> <!-- "" -->
|
||||||
</patches>
|
</patches>
|
||||||
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
||||||
<file offset="0" name="epr-21382.20" crc32="0x0B9C44A0" />
|
<file offset="0" name="epr-21382.20" crc32="0x0B9C44A0" />
|
||||||
|
|
|
@ -254,8 +254,10 @@ void CDriveBoard::Reset(void)
|
||||||
m_adcPortRead = 0;
|
m_adcPortRead = 0;
|
||||||
m_adcPortBit = 0;
|
m_adcPortBit = 0;
|
||||||
m_port42Out = 0;
|
m_port42Out = 0;
|
||||||
|
m_port45Out = 0;
|
||||||
m_port46Out = 0;
|
m_port46Out = 0;
|
||||||
m_prev42Out = 0;
|
m_prev42Out = 0;
|
||||||
|
m_prev45Out = 0;
|
||||||
m_prev46Out = 0;
|
m_prev46Out = 0;
|
||||||
|
|
||||||
m_initState = 0;
|
m_initState = 0;
|
||||||
|
@ -266,6 +268,7 @@ void CDriveBoard::Reset(void)
|
||||||
m_uncenterVal2 = 0;
|
m_uncenterVal2 = 0;
|
||||||
|
|
||||||
m_lastConstForce = 0;
|
m_lastConstForce = 0;
|
||||||
|
m_lastConstForceY = 0;
|
||||||
m_lastSelfCenter = 0;
|
m_lastSelfCenter = 0;
|
||||||
m_lastFriction = 0;
|
m_lastFriction = 0;
|
||||||
m_lastVibrate = 0;
|
m_lastVibrate = 0;
|
||||||
|
@ -496,32 +499,29 @@ UINT8 CDriveBoard::IORead8(UINT32 portNum)
|
||||||
UINT8 adcVal;
|
UINT8 adcVal;
|
||||||
switch (portNum)
|
switch (portNum)
|
||||||
{
|
{
|
||||||
case 32: // DIP 1 value
|
case 0x20: // DIP 1 value
|
||||||
return m_dip1;
|
return m_dip1;
|
||||||
case 33: // DIP 2 value
|
case 0x21: // DIP 2 value
|
||||||
return m_dip2;
|
return m_dip2;
|
||||||
case 36: // ADC channel 1 - not connected
|
case 0x24: // ADC channel 1 - Y analog axis for joystick
|
||||||
case 37: // ADC channel 2 - steering wheel position (0x00 = full left, 0x80 = center, 0xFF = full right)
|
case 0x25: // ADC channel 2 - steering wheel position (0x00 = full left, 0x80 = center, 0xFF = full right) and X analog axis for joystick
|
||||||
case 38: // ADC channel 3 - cockpit bank position (deluxe cabinets) (0x00 = full left, 0x80 = center, 0xFF = full right)
|
case 0x26: // ADC channel 3 - cockpit bank position (deluxe cabinets) (0x00 = full left, 0x80 = center, 0xFF = full right)
|
||||||
case 39: // ADC channel 4 - not connected
|
case 0x27: // ADC channel 4 - not connected
|
||||||
if (portNum == m_adcPortRead && m_adcPortBit-- > 0)
|
if (portNum == m_adcPortRead && m_adcPortBit-- > 0)
|
||||||
{
|
{
|
||||||
switch (portNum)
|
switch (portNum)
|
||||||
{
|
{
|
||||||
case 36: // Not connected
|
case 0x24: // Y analog axis for joystick
|
||||||
adcVal = 0x00;
|
adcVal = ReadADCChannel1();
|
||||||
break;
|
break;
|
||||||
case 37: // Steering wheel for twin racing cabinets - TODO - check actual range of steering, suspect it is not really 0x00-0xFF
|
case 0x25: // Steering wheel for twin racing cabinets - TODO - check actual range of steering, suspect it is not really 0x00-0xFF
|
||||||
if (m_initialized)
|
adcVal = ReadADCChannel2();
|
||||||
adcVal = (UINT8)m_inputs->steering->value;
|
|
||||||
else
|
|
||||||
adcVal = 0x80; // If not initialized, return 0x80 so that wheel centering test does not fail
|
|
||||||
break;
|
break;
|
||||||
case 38: // Cockpit bank position for deluxe racing cabinets
|
case 0x26: // Cockpit bank position for deluxe racing cabinets
|
||||||
adcVal = 0x80;
|
adcVal = ReadADCChannel3();
|
||||||
break;
|
break;
|
||||||
case 39: // Not connected
|
case 0x27: // Not connected
|
||||||
adcVal = 0x00;
|
adcVal = ReadADCChannel4();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -538,9 +538,9 @@ UINT8 CDriveBoard::IORead8(UINT32 portNum)
|
||||||
#endif
|
#endif
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
case 40: // PPC command
|
case 0x28: // PPC command
|
||||||
return m_dataSent;
|
return m_dataSent;
|
||||||
case 44: // Encoder error reporting (kept at 0x00 for no error)
|
case 0x2c: // Encoder error reporting (kept at 0x00 for no error)
|
||||||
// Bit 1 0
|
// Bit 1 0
|
||||||
// 0 0 = encoder okay, no error
|
// 0 0 = encoder okay, no error
|
||||||
// 0 1 = encoder error 1 - overcurrent error
|
// 0 1 = encoder error 1 - overcurrent error
|
||||||
|
@ -559,55 +559,66 @@ void CDriveBoard::IOWrite8(UINT32 portNum, UINT8 data)
|
||||||
{
|
{
|
||||||
switch (portNum)
|
switch (portNum)
|
||||||
{
|
{
|
||||||
case 16: // Unsure? - single byte 0x03 sent at initialization, then occasionally writes 0x07 & 0xFA to port
|
case 0x10: // Unsure? - single byte 0x03 sent at initialization, then occasionally writes 0x07 & 0xFA to port
|
||||||
return;
|
return;
|
||||||
case 17: // Interrupt control
|
case 0x11: // Interrupt control
|
||||||
if (data == 0x57)
|
if (data == 0x57)
|
||||||
m_allowInterrupts = true;
|
m_allowInterrupts = true;
|
||||||
else if (data == 0x53) // Strictly speaking 0x53 then 0x04
|
else if (data == 0x53) // Strictly speaking 0x53 then 0x04
|
||||||
m_allowInterrupts = false;
|
m_allowInterrupts = false;
|
||||||
return;
|
return;
|
||||||
case 28: // Unsure? - two bytes 0xFF, 0xFF sent at initialization only
|
case 0x1c: // Unsure? - two bytes 0xFF, 0xFF sent at initialization only
|
||||||
case 29: // Unsure? - two bytes 0x0F, 0x17 sent at initialization only
|
case 0x1d: // Unsure? - two bytes 0x0F, 0x17 sent at initialization only
|
||||||
case 30: // Unsure? - same as port 28
|
case 0x1e: // Unsure? - same as port 28
|
||||||
case 31: // Unsure? - same as port 31
|
case 0x1f: // Unsure? - same as port 31
|
||||||
return;
|
return;
|
||||||
case 32: // Left digit of 7-segment display 1
|
case 0x20: // Left digit of 7-segment display 1
|
||||||
m_seg1Digit1 = data;
|
m_seg1Digit1 = data;
|
||||||
return;
|
return;
|
||||||
case 33: // Right digit of 7-segment display 1
|
case 0x21: // Right digit of 7-segment display 1
|
||||||
m_seg1Digit2 = data;
|
m_seg1Digit2 = data;
|
||||||
return;
|
return;
|
||||||
case 34: // Left digit of 7-segment display 2
|
case 0x22: // Left digit of 7-segment display 2
|
||||||
m_seg2Digit1 = data;
|
m_seg2Digit1 = data;
|
||||||
return;
|
return;
|
||||||
case 35: // Right digit of 7-segment display 2
|
case 0x23: // Right digit of 7-segment display 2
|
||||||
m_seg2Digit2 = data;
|
m_seg2Digit2 = data;
|
||||||
return;
|
return;
|
||||||
case 36: // ADC channel 1 control
|
case 0x24: // ADC channel 1 control
|
||||||
case 37: // ADC channel 2 control
|
case 0x25: // ADC channel 2 control
|
||||||
case 38: // ADC channel 3 control
|
case 0x26: // ADC channel 3 control
|
||||||
case 39: // ADC channel 4 control
|
case 0x27: // ADC channel 4 control
|
||||||
m_adcPortRead = portNum;
|
m_adcPortRead = portNum;
|
||||||
m_adcPortBit = 8;
|
m_adcPortBit = 8;
|
||||||
return;
|
return;
|
||||||
case 41: // Reply for PPC
|
case 0x29: // Reply for PPC
|
||||||
m_dataReceived = data;
|
m_dataReceived = data;
|
||||||
if (data == 0xCC)
|
if ((data == 0xCC && m_boardType == Wheel) || (data==0xCB && m_boardType == Joystick))
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
return;
|
return;
|
||||||
case 42: // Encoder motor data
|
case 0x2a: // Encoder motor data (x axis)
|
||||||
m_port42Out = data;
|
m_port42Out = data;
|
||||||
|
switch (m_boardType)
|
||||||
|
{
|
||||||
|
case Wheel:
|
||||||
ProcessEncoderCmd();
|
ProcessEncoderCmd();
|
||||||
|
break;
|
||||||
|
case Joystick:
|
||||||
|
ProcessEncoderCmdJoystick();
|
||||||
|
break;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case 45: // Clutch/lamp control (deluxe cabinets)
|
case 0x2d: // Clutch/lamp control (deluxe cabinets) ( or y axis)
|
||||||
|
m_port45Out = data;
|
||||||
|
if (m_boardType==Joystick)
|
||||||
|
ProcessEncoderCmdJoystick();
|
||||||
return;
|
return;
|
||||||
case 46: // Encoder motor control
|
case 0x2e: // Encoder motor control
|
||||||
m_port46Out = data;
|
m_port46Out = data;
|
||||||
return;
|
return;
|
||||||
case 240: // Unsure? - single byte 0xBB sent at initialization only
|
case 0xf0: // Unsure? - single byte 0xBB sent at initialization only
|
||||||
return;
|
return;
|
||||||
case 241: // Unsure? - single byte 0x4E sent regularly - some sort of watchdog?
|
case 0xf1: // Unsure? - single byte 0x4E sent regularly - some sort of watchdog?
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -719,18 +730,148 @@ void CDriveBoard::ProcessEncoderCmd(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDriveBoard::ProcessEncoderCmdJoystick(void)
|
||||||
|
{
|
||||||
|
if (m_prev42Out != m_port42Out || m_prev46Out != m_port46Out || m_prev45Out != m_port45Out)
|
||||||
|
{
|
||||||
|
switch (m_port46Out)
|
||||||
|
{
|
||||||
|
case 0xEE:
|
||||||
|
// Apply constant force
|
||||||
|
|
||||||
|
if (m_port42Out > 0x7f) // X
|
||||||
|
{
|
||||||
|
SendConstantForce(2 * (m_port42Out - 0x7f));
|
||||||
|
}
|
||||||
|
else if (m_port42Out < 0x7f)
|
||||||
|
{
|
||||||
|
SendConstantForce(2 * (m_port42Out - 0x7f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendConstantForce(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_port45Out > 0x7f) // Y
|
||||||
|
{
|
||||||
|
SendConstantForceY(-2 * (m_port45Out - 0x7f));
|
||||||
|
}
|
||||||
|
else if (m_port45Out < 0x7f)
|
||||||
|
{
|
||||||
|
SendConstantForceY(-2 * (m_port45Out - 0x7f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendConstantForceY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_port42Out == 0x7f && m_port45Out == 0x81)
|
||||||
|
{
|
||||||
|
SendSelfCenter(255);
|
||||||
|
}
|
||||||
|
else SendSelfCenter(0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xFF:
|
||||||
|
// Stop all effects
|
||||||
|
if (m_port42Out == 0 || m_port45Out == 0)
|
||||||
|
SendStopAll();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xcc: // init
|
||||||
|
//42[0B] / 45[0A]
|
||||||
|
//42[0B] / 45[0B]
|
||||||
|
//42[FF] / 45[0B]
|
||||||
|
//42[FF] / 45[FF]
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xdd: // init
|
||||||
|
// 42[FF] / 45[00]
|
||||||
|
// 42[FF] / 45[FF]
|
||||||
|
|
||||||
|
// 42[0A] / 45[00]
|
||||||
|
// 42[0A] / 45[0A]
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xce:
|
||||||
|
// 42[7F] / 45[08]
|
||||||
|
// 42[7F] / 45[09]
|
||||||
|
// 42[7F] / 45[0A]
|
||||||
|
// 42[7F] / 45[0B]
|
||||||
|
// 42[7F] / 45[81]
|
||||||
|
if (m_port42Out == 0x7f && m_port45Out != 0x81) // X
|
||||||
|
{
|
||||||
|
SendConstantForce(2 * m_port45Out);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_port42Out == 0x7f && m_port45Out == 0x81)
|
||||||
|
{
|
||||||
|
SendSelfCenter(255);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xec:
|
||||||
|
// 42[09] / 45[81]
|
||||||
|
// 42[2A] / 45[81]
|
||||||
|
// 42[1B] / 45[81]
|
||||||
|
// 42[7F] / 45[81]
|
||||||
|
if (m_port45Out == 0x81 && m_port42Out != 0x7f) // Y
|
||||||
|
{
|
||||||
|
SendConstantForceY(2 * m_port42Out);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_port42Out == 0x7f && m_port45Out == 0x81)
|
||||||
|
{
|
||||||
|
SendSelfCenter(255);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x00: // init
|
||||||
|
// 42[FF] / 45[00]
|
||||||
|
// 42[FF] / 45[FF]
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x99: // init
|
||||||
|
// 42[B0] / 45[B0]
|
||||||
|
// 42[80] / 45[B0]
|
||||||
|
// 42[80] / 45[80]
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
//printf("Unknown = 46 [%02X] / 42 [%02X] / 45 [%02X]\n", m_port46Out, m_port42Out, m_port45Out);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_prev42Out = m_port42Out;
|
||||||
|
m_prev46Out = m_port46Out;
|
||||||
|
m_prev45Out = m_port45Out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CDriveBoard::SendStopAll(void)
|
void CDriveBoard::SendStopAll(void)
|
||||||
{
|
{
|
||||||
//printf(">> Stop All Effects\n");
|
//printf(">> Stop All Effects\n");
|
||||||
|
|
||||||
ForceFeedbackCmd ffCmd;
|
ForceFeedbackCmd ffCmd;
|
||||||
ffCmd.id = FFStop;
|
ffCmd.id = FFStop;
|
||||||
|
|
||||||
|
switch (m_boardType)
|
||||||
|
{
|
||||||
|
case Wheel:
|
||||||
m_inputs->steering->SendForceFeedbackCmd(ffCmd);
|
m_inputs->steering->SendForceFeedbackCmd(ffCmd);
|
||||||
|
break;
|
||||||
|
case Joystick:
|
||||||
|
m_inputs->analogJoyX->SendForceFeedbackCmd(ffCmd);
|
||||||
|
m_inputs->analogJoyY->SendForceFeedbackCmd(ffCmd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_lastConstForce = 0;
|
m_lastConstForce = 0;
|
||||||
m_lastSelfCenter = 0;
|
m_lastSelfCenter = 0;
|
||||||
m_lastFriction = 0;
|
m_lastFriction = 0;
|
||||||
m_lastVibrate = 0;
|
m_lastVibrate = 0;
|
||||||
|
m_lastConstForceY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDriveBoard::SendConstantForce(INT8 val)
|
void CDriveBoard::SendConstantForce(INT8 val)
|
||||||
|
@ -759,11 +900,32 @@ void CDriveBoard::SendConstantForce(INT8 val)
|
||||||
ForceFeedbackCmd ffCmd;
|
ForceFeedbackCmd ffCmd;
|
||||||
ffCmd.id = FFConstantForce;
|
ffCmd.id = FFConstantForce;
|
||||||
ffCmd.force = (float)val / (val >= 0 ? 127.0f : 128.0f);
|
ffCmd.force = (float)val / (val >= 0 ? 127.0f : 128.0f);
|
||||||
|
|
||||||
|
switch (m_boardType)
|
||||||
|
{
|
||||||
|
case Wheel:
|
||||||
m_inputs->steering->SendForceFeedbackCmd(ffCmd);
|
m_inputs->steering->SendForceFeedbackCmd(ffCmd);
|
||||||
|
break;
|
||||||
|
case Joystick:
|
||||||
|
m_inputs->analogJoyX->SendForceFeedbackCmd(ffCmd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_lastConstForce = val;
|
m_lastConstForce = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDriveBoard::SendConstantForceY(INT8 val)
|
||||||
|
{
|
||||||
|
if (val == m_lastConstForceY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ForceFeedbackCmd ffCmd;
|
||||||
|
ffCmd.id = FFConstantForce;
|
||||||
|
ffCmd.force = (float)val / (val >= 0 ? 127.0f : 128.0f);
|
||||||
|
m_inputs->analogJoyY->SendForceFeedbackCmd(ffCmd);
|
||||||
|
m_lastConstForceY = val;
|
||||||
|
}
|
||||||
|
|
||||||
void CDriveBoard::SendSelfCenter(UINT8 val)
|
void CDriveBoard::SendSelfCenter(UINT8 val)
|
||||||
{
|
{
|
||||||
if (val == m_lastSelfCenter)
|
if (val == m_lastSelfCenter)
|
||||||
|
@ -778,11 +940,22 @@ void CDriveBoard::SendSelfCenter(UINT8 val)
|
||||||
ForceFeedbackCmd ffCmd;
|
ForceFeedbackCmd ffCmd;
|
||||||
ffCmd.id = FFSelfCenter;
|
ffCmd.id = FFSelfCenter;
|
||||||
ffCmd.force = (float)val / 255.0f;
|
ffCmd.force = (float)val / 255.0f;
|
||||||
|
|
||||||
|
switch (m_boardType)
|
||||||
|
{
|
||||||
|
case Wheel:
|
||||||
m_inputs->steering->SendForceFeedbackCmd(ffCmd);
|
m_inputs->steering->SendForceFeedbackCmd(ffCmd);
|
||||||
|
break;
|
||||||
|
case Joystick:
|
||||||
|
m_inputs->analogJoyX->SendForceFeedbackCmd(ffCmd);
|
||||||
|
m_inputs->analogJoyY->SendForceFeedbackCmd(ffCmd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_lastSelfCenter = val;
|
m_lastSelfCenter = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CDriveBoard::SendFriction(UINT8 val)
|
void CDriveBoard::SendFriction(UINT8 val)
|
||||||
{
|
{
|
||||||
if (val == m_lastFriction)
|
if (val == m_lastFriction)
|
||||||
|
@ -821,6 +994,59 @@ void CDriveBoard::SendVibrate(UINT8 val)
|
||||||
m_lastVibrate = val;
|
m_lastVibrate = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t CDriveBoard::ReadADCChannel1()
|
||||||
|
{
|
||||||
|
switch (m_boardType)
|
||||||
|
{
|
||||||
|
case Wheel:
|
||||||
|
return 0x00;
|
||||||
|
break;
|
||||||
|
case Joystick:
|
||||||
|
if (m_initialized)
|
||||||
|
return (UINT8)m_inputs->analogJoyY->value;
|
||||||
|
else
|
||||||
|
return 0x80; // If not initialized, return 0x80 so that ffb centering test does not fail
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CDriveBoard::ReadADCChannel2()
|
||||||
|
{
|
||||||
|
switch (m_boardType)
|
||||||
|
{
|
||||||
|
case Wheel:
|
||||||
|
if (m_initialized)
|
||||||
|
return (UINT8)m_inputs->steering->value;
|
||||||
|
else
|
||||||
|
return 0x80; // If not initialized, return 0x80 so that wheel centering test does not fail
|
||||||
|
break;
|
||||||
|
case Joystick:
|
||||||
|
if (m_initialized)
|
||||||
|
return (UINT8)m_inputs->analogJoyX->value;
|
||||||
|
else
|
||||||
|
return 0x80; // If not initialized, return 0x80 so that ffb centering test does not fail
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CDriveBoard::ReadADCChannel3()
|
||||||
|
{
|
||||||
|
return 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CDriveBoard::ReadADCChannel4()
|
||||||
|
{
|
||||||
|
switch (m_boardType)
|
||||||
|
{
|
||||||
|
case Wheel:
|
||||||
|
return 0x00;
|
||||||
|
break;
|
||||||
|
case Joystick:
|
||||||
|
return 0x80;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CDriveBoard::CDriveBoard(const Util::Config::Node &config)
|
CDriveBoard::CDriveBoard(const Util::Config::Node &config)
|
||||||
: m_config(config),
|
: m_config(config),
|
||||||
m_attached(false),
|
m_attached(false),
|
||||||
|
|
|
@ -36,6 +36,14 @@
|
||||||
class CDriveBoard : public IBus
|
class CDriveBoard : public IBus
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum BoardType
|
||||||
|
{
|
||||||
|
Wheel=0,
|
||||||
|
Joystick
|
||||||
|
};
|
||||||
|
|
||||||
|
BoardType m_boardType;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IsAttached(void):
|
* IsAttached(void):
|
||||||
*
|
*
|
||||||
|
@ -281,9 +289,11 @@ private:
|
||||||
|
|
||||||
UINT8 m_port42Out; // Last value sent to Z80 I/O port 42 (encoder motor data)
|
UINT8 m_port42Out; // Last value sent to Z80 I/O port 42 (encoder motor data)
|
||||||
UINT8 m_port46Out; // Last value sent to Z80 I/O port 46 (encoder motor control)
|
UINT8 m_port46Out; // Last value sent to Z80 I/O port 46 (encoder motor control)
|
||||||
|
UINT8 m_port45Out; // Last value sent to Z80 I/O port 42 (up-down motor data)
|
||||||
|
|
||||||
UINT8 m_prev42Out; // Previous value sent to Z80 I/O port 42
|
UINT8 m_prev42Out; // Previous value sent to Z80 I/O port 42
|
||||||
UINT8 m_prev46Out; // Previous value sent to Z80 I/O port 46
|
UINT8 m_prev46Out; // Previous value sent to Z80 I/O port 46
|
||||||
|
UINT8 m_prev45Out; // Previous value sent to Z80 I/O port 45 (up-down)
|
||||||
|
|
||||||
UINT8 m_uncenterVal1; // First part of pending uncenter command
|
UINT8 m_uncenterVal1; // First part of pending uncenter command
|
||||||
UINT8 m_uncenterVal2; // Second part of pending uncenter command
|
UINT8 m_uncenterVal2; // Second part of pending uncenter command
|
||||||
|
@ -299,6 +309,7 @@ private:
|
||||||
|
|
||||||
// Feedback state
|
// Feedback state
|
||||||
INT8 m_lastConstForce; // Last constant force command sent
|
INT8 m_lastConstForce; // Last constant force command sent
|
||||||
|
INT8 m_lastConstForceY; // Last constant force command sent y axis
|
||||||
UINT8 m_lastSelfCenter; // Last self center command sent
|
UINT8 m_lastSelfCenter; // Last self center command sent
|
||||||
UINT8 m_lastFriction; // Last friction command sent
|
UINT8 m_lastFriction; // Last friction command sent
|
||||||
UINT8 m_lastVibrate; // Last vibrate command sent
|
UINT8 m_lastVibrate; // Last vibrate command sent
|
||||||
|
@ -313,15 +324,27 @@ private:
|
||||||
|
|
||||||
void ProcessEncoderCmd(void);
|
void ProcessEncoderCmd(void);
|
||||||
|
|
||||||
|
void ProcessEncoderCmdJoystick(void);
|
||||||
|
|
||||||
void SendStopAll(void);
|
void SendStopAll(void);
|
||||||
|
|
||||||
void SendConstantForce(INT8 val);
|
void SendConstantForce(INT8 val);
|
||||||
|
|
||||||
|
void SendConstantForceY(INT8 val);
|
||||||
|
|
||||||
void SendSelfCenter(UINT8 val);
|
void SendSelfCenter(UINT8 val);
|
||||||
|
|
||||||
void SendFriction(UINT8 val);
|
void SendFriction(UINT8 val);
|
||||||
|
|
||||||
void SendVibrate(UINT8 val);
|
void SendVibrate(UINT8 val);
|
||||||
|
|
||||||
|
uint8_t ReadADCChannel1();
|
||||||
|
|
||||||
|
uint8_t ReadADCChannel2();
|
||||||
|
|
||||||
|
uint8_t ReadADCChannel3();
|
||||||
|
|
||||||
|
uint8_t ReadADCChannel4();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INCLUDED_DRIVEBOARD_H
|
#endif // INCLUDED_DRIVEBOARD_H
|
||||||
|
|
|
@ -2932,6 +2932,7 @@ bool CModel3::LoadGame(const Game &game, const ROMSet &rom_set)
|
||||||
rom_set.get_rom("mpeg_program").CopyTo(dsbROM, 128*1024);
|
rom_set.get_rom("mpeg_program").CopyTo(dsbROM, 128*1024);
|
||||||
rom_set.get_rom("mpeg_music").CopyTo(mpegROM, 16*0x100000);
|
rom_set.get_rom("mpeg_music").CopyTo(mpegROM, 16*0x100000);
|
||||||
rom_set.get_rom("driveboard_program").CopyTo(driveROM, 64*1024);
|
rom_set.get_rom("driveboard_program").CopyTo(driveROM, 64*1024);
|
||||||
|
rom_set.get_rom("ffb_program").CopyTo(driveROM, 64 * 1024);
|
||||||
|
|
||||||
// Convert PowerPC and 68K ROMs to little endian words
|
// Convert PowerPC and 68K ROMs to little endian words
|
||||||
Util::FlipEndian32(crom, 8*0x100000 + 128*0x100000);
|
Util::FlipEndian32(crom, 8*0x100000 + 128*0x100000);
|
||||||
|
@ -3030,6 +3031,15 @@ bool CModel3::LoadGame(const Game &game, const ROMSet &rom_set)
|
||||||
{
|
{
|
||||||
if (DriveBoard.Init(driveROM))
|
if (DriveBoard.Init(driveROM))
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
else
|
||||||
|
DriveBoard.m_boardType = DriveBoard.Wheel;
|
||||||
|
}
|
||||||
|
else if (rom_set.get_rom("ffb_program").size)
|
||||||
|
{
|
||||||
|
if (DriveBoard.Init(driveROM))
|
||||||
|
return FAIL;
|
||||||
|
else
|
||||||
|
DriveBoard.m_boardType = DriveBoard.Joystick;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DriveBoard.Init(NULL);
|
DriveBoard.Init(NULL);
|
||||||
|
@ -3046,6 +3056,8 @@ bool CModel3::LoadGame(const Game &game, const ROMSet &rom_set)
|
||||||
extra_hw.insert(Util::Format() << "Digital Sound Board (Type " << game.mpeg_board << ")");
|
extra_hw.insert(Util::Format() << "Digital Sound Board (Type " << game.mpeg_board << ")");
|
||||||
if (rom_set.get_rom("driveboard_program").size)
|
if (rom_set.get_rom("driveboard_program").size)
|
||||||
extra_hw.insert("Drive Board");
|
extra_hw.insert("Drive Board");
|
||||||
|
if (rom_set.get_rom("ffb_program").size)
|
||||||
|
extra_hw.insert("Joystick FFB Board");
|
||||||
if (game.encryption_key)
|
if (game.encryption_key)
|
||||||
extra_hw.insert("Security Board");
|
extra_hw.insert("Security Board");
|
||||||
if (netboard_present.compare("true")==0)
|
if (netboard_present.compare("true")==0)
|
||||||
|
|
Loading…
Reference in a new issue