naomi: emulate midi ffb drive board response
needed for driving simulator
This commit is contained in:
parent
15ca7e82bd
commit
fc9e1e401b
|
@ -18,6 +18,7 @@ InterruptInfo* MCIRE;
|
|||
InterruptInfo* SCIEB;
|
||||
InterruptInfo* SCIPD;
|
||||
InterruptInfo* SCIRE;
|
||||
std::deque<u8> midiSendBuffer;
|
||||
|
||||
//Interrupts
|
||||
//arm side
|
||||
|
@ -235,6 +236,15 @@ template void WriteAicaReg<>(u32 reg, u8 data);
|
|||
template void WriteAicaReg<>(u32 reg, u16 data);
|
||||
template void WriteAicaReg<>(u32 reg, u32 data);
|
||||
|
||||
void aica_midiSend(u8 data)
|
||||
{
|
||||
midiSendBuffer.push_back(data);
|
||||
SCIPD->MIDI_IN = 1;
|
||||
update_arm_interrupts();
|
||||
MCIPD->MIDI_IN = 1;
|
||||
UpdateSh4Ints();
|
||||
}
|
||||
|
||||
//misc :p
|
||||
s32 libAICA_Init()
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "types.h"
|
||||
#include <deque>
|
||||
|
||||
#define SCIEB_addr 0x289C
|
||||
#define SCIPD_addr (0x289C+4)
|
||||
|
@ -299,6 +300,7 @@ extern InterruptInfo* MCIRE;
|
|||
extern InterruptInfo* SCIEB;
|
||||
extern InterruptInfo* SCIPD;
|
||||
extern InterruptInfo* SCIRE;
|
||||
extern std::deque<u8> midiSendBuffer;
|
||||
|
||||
extern CommonData_struct* CommonData;
|
||||
extern DSPData_struct* DSPData;
|
||||
|
|
|
@ -14,6 +14,7 @@ void aica_Init();
|
|||
void aica_Reset(bool hard);
|
||||
void aica_Term();
|
||||
void aica_setMidiReceiver(void (*handler)(u8 data));
|
||||
void aica_midiSend(u8 data);
|
||||
|
||||
void aica_sb_Init();
|
||||
void aica_sb_Reset(bool hard);
|
||||
|
|
|
@ -1338,10 +1338,23 @@ void ReadCommonReg(u32 reg,bool byte)
|
|||
{
|
||||
case 0x2808:
|
||||
case 0x2809:
|
||||
CommonData->MIEMP = 1;
|
||||
CommonData->MOEMP = 1;
|
||||
if (!midiSendBuffer.empty())
|
||||
{
|
||||
if (!byte || reg == 0x2808)
|
||||
{
|
||||
CommonData->MIBUF = midiSendBuffer.front();
|
||||
midiSendBuffer.pop_front();
|
||||
}
|
||||
CommonData->MIEMP = 0;
|
||||
CommonData->MIFUL = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CommonData->MIEMP = 1;
|
||||
CommonData->MIFUL = 0;
|
||||
}
|
||||
CommonData->MIOVF = 0;
|
||||
CommonData->MIFUL = 0;
|
||||
CommonData->MOEMP = 1;
|
||||
CommonData->MOFUL = 0;
|
||||
break;
|
||||
case 0x2810: // EG, SGC, LP
|
||||
|
@ -1627,6 +1640,9 @@ void channel_serialize(Serializer& ser)
|
|||
ser << beepCounter;
|
||||
ser << cdda_sector;
|
||||
ser << cdda_index;
|
||||
ser << (u32)midiSendBuffer.size();
|
||||
for (u8 b : midiSendBuffer)
|
||||
ser << b;
|
||||
}
|
||||
|
||||
void channel_deserialize(Deserializer& deser)
|
||||
|
@ -1761,4 +1777,16 @@ void channel_deserialize(Deserializer& deser)
|
|||
deser.skip(4 * 64); // mxlr
|
||||
deser.skip(4); // samples_gen
|
||||
}
|
||||
midiSendBuffer.clear();
|
||||
if (deser.version() >= Deserializer::V28)
|
||||
{
|
||||
u32 size;
|
||||
deser >> size;
|
||||
for (u32 i = 0; i < size; i++)
|
||||
{
|
||||
u8 b;
|
||||
deser >> b;
|
||||
midiSendBuffer.push_back(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -748,13 +748,34 @@ void naomi_Deserialize(Deserializer& deser)
|
|||
}
|
||||
}
|
||||
|
||||
static void initFFBMidiReceiver(u8 data)
|
||||
static void midiSend(u8 b1, u8 b2, u8 b3)
|
||||
{
|
||||
aica_midiSend(b1);
|
||||
aica_midiSend(b2);
|
||||
aica_midiSend(b3);
|
||||
aica_midiSend((b1 ^ b2 ^ b3) & 0x7f);
|
||||
}
|
||||
|
||||
static void forceFeedbackMidiReceiver(u8 data)
|
||||
{
|
||||
static float position = 8192.f;
|
||||
static float torque;
|
||||
position = std::min(16383.f, std::max(0.f, position + torque));
|
||||
if (data & 0x80)
|
||||
midiTxBufIndex = 0;
|
||||
midiTxBuf[midiTxBufIndex] = data;
|
||||
if (midiTxBufIndex == 3 && ((midiTxBuf[0] ^ midiTxBuf[1] ^ midiTxBuf[2]) & 0x7f) == midiTxBuf[3])
|
||||
{
|
||||
if (midiTxBuf[0] == 0x84)
|
||||
torque = ((midiTxBuf[1] << 7) | midiTxBuf[2]) - 0x80;
|
||||
else if (midiTxBuf[0] == 0xff)
|
||||
{
|
||||
torque = 0;
|
||||
position = 8192;
|
||||
}
|
||||
// required: b1 & 0x1f == 0x10 && b1 & 0x40 == 0
|
||||
midiSend(0x90, ((int)position >> 7) & 0x7f, (int)position & 0x7f);
|
||||
|
||||
// decoding from FFB Arcade Plugin (by Boomslangnz)
|
||||
// https://github.com/Boomslangnz/FFBArcadePlugin/blob/master/Game%20Files/Demul.cpp
|
||||
if (midiTxBuf[0] == 0x85 && midiTxBuf[1] == 0x3f)
|
||||
|
@ -763,7 +784,7 @@ static void initFFBMidiReceiver(u8 data)
|
|||
midiTxBufIndex = (midiTxBufIndex + 1) % ARRAY_SIZE(midiTxBuf);
|
||||
}
|
||||
|
||||
void initdFFBInit()
|
||||
void initMidiForceFeedback()
|
||||
{
|
||||
aica_setMidiReceiver(initFFBMidiReceiver);
|
||||
aica_setMidiReceiver(forceFeedbackMidiReceiver);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ extern u32 reg_dimm_parameterl;
|
|||
extern u32 reg_dimm_parameterh;
|
||||
extern u32 reg_dimm_status;
|
||||
|
||||
void initdFFBInit();
|
||||
void initMidiForceFeedback();
|
||||
|
||||
u32 libExtDevice_ReadMem_A0_006(u32 addr, u32 size);
|
||||
void libExtDevice_WriteMem_A0_006(u32 addr, u32 data, u32 size);
|
||||
|
|
|
@ -587,13 +587,17 @@ void naomi_cart_LoadRom(const char* file, LoadProgress *progress)
|
|||
|| gameId == "INITIAL D CYCRAFT")
|
||||
{
|
||||
card_reader::initialDCardReader.init();
|
||||
initdFFBInit();
|
||||
initMidiForceFeedback();
|
||||
}
|
||||
else if (gameId == "MAXIMUM SPEED")
|
||||
{
|
||||
maxSpeedNetPipe.init();
|
||||
configure_maxspeed_flash(config::NetworkEnable, config::ActAsServer);
|
||||
}
|
||||
else if (gameId == "SAMPLE GAME MAX LONG NAME-") // Driving Simulator
|
||||
{
|
||||
initMidiForceFeedback();
|
||||
}
|
||||
}
|
||||
else
|
||||
NOTICE_LOG(NAOMI, "NAOMI GAME ID [%s]", naomi_game_id);
|
||||
|
|
|
@ -41,29 +41,30 @@ public:
|
|||
VLAST_LIBRETRO = V13_LIBRETRO,
|
||||
|
||||
V5 = 800,
|
||||
V6 = 801,
|
||||
V7 = 802,
|
||||
V8 = 803,
|
||||
V9 = 804,
|
||||
V10 = 805,
|
||||
V11 = 806,
|
||||
V12 = 807,
|
||||
V13 = 808,
|
||||
V14 = 809,
|
||||
V15 = 810,
|
||||
V16 = 811,
|
||||
V17 = 812,
|
||||
V18 = 813,
|
||||
V19 = 814,
|
||||
V20 = 815,
|
||||
V21 = 816,
|
||||
V22 = 817,
|
||||
V23 = 818,
|
||||
V24 = 819,
|
||||
V25 = 820,
|
||||
V26 = 821,
|
||||
V27 = 822,
|
||||
Current = V27,
|
||||
V6,
|
||||
V7,
|
||||
V8,
|
||||
V9,
|
||||
V10,
|
||||
V11,
|
||||
V12,
|
||||
V13,
|
||||
V14,
|
||||
V15,
|
||||
V16,
|
||||
V17,
|
||||
V18,
|
||||
V19,
|
||||
V20,
|
||||
V21,
|
||||
V22,
|
||||
V23,
|
||||
V24,
|
||||
V25,
|
||||
V26,
|
||||
V27,
|
||||
V28,
|
||||
Current = V28,
|
||||
|
||||
Next = Current + 1,
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@ TEST_F(SerializeTest, SizeTest)
|
|||
std::vector<char> data(30000000);
|
||||
Serializer ser(data.data(), data.size());
|
||||
dc_serialize(ser);
|
||||
ASSERT_EQ(28191595u, ser.size());
|
||||
ASSERT_EQ(28191599u, ser.size());
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue