mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-26 04:32:35 +01:00
USIO: Support up to 4 players for Tekken Tag Tournament 2 Pair Play mode
This commit is contained in:
parent
52495c17d6
commit
009d8e13da
@ -186,7 +186,7 @@ void usb_device_usio::translate_input_taiko()
|
||||
std::lock_guard lock(pad::g_pad_mutex);
|
||||
const auto handler = pad::get_current_handler();
|
||||
|
||||
std::vector<u8> input_buf(96);
|
||||
std::vector<u8> input_buf(0x60);
|
||||
constexpr le_t<u16> c_hit = 0x1800;
|
||||
le_t<u16> digital_input = 0;
|
||||
|
||||
@ -204,6 +204,7 @@ void usb_device_usio::translate_input_taiko()
|
||||
}
|
||||
|
||||
const usz offset = player * 8ULL;
|
||||
auto& status = m_io_status[0];
|
||||
|
||||
const auto& cfg = ::at32(g_cfg_usio.players, pad_number);
|
||||
cfg->handle_input(pad, false, [&](usio_btn btn, u16 /*value*/, bool pressed)
|
||||
@ -212,15 +213,15 @@ void usb_device_usio::translate_input_taiko()
|
||||
{
|
||||
case usio_btn::test:
|
||||
if (player != 0) break;
|
||||
if (pressed && !test_key_pressed) // Solve the need to hold the Test key
|
||||
test_on = !test_on;
|
||||
test_key_pressed = pressed;
|
||||
if (pressed && !status.test_key_pressed) // Solve the need to hold the Test key
|
||||
status.test_on = !status.test_on;
|
||||
status.test_key_pressed = pressed;
|
||||
break;
|
||||
case usio_btn::coin:
|
||||
if (player != 0) break;
|
||||
if (pressed && !coin_key_pressed) // Ensure only one coin is inserted each time the Coin key is pressed
|
||||
coin_counter++;
|
||||
coin_key_pressed = pressed;
|
||||
if (pressed && !status.coin_key_pressed) // Ensure only one coin is inserted each time the Coin key is pressed
|
||||
status.coin_counter++;
|
||||
status.coin_key_pressed = pressed;
|
||||
break;
|
||||
case usio_btn::service:
|
||||
if (player == 0 && pressed)
|
||||
@ -258,14 +259,16 @@ void usb_device_usio::translate_input_taiko()
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
if (player == 0 && status.test_on)
|
||||
digital_input |= 0x80;
|
||||
};
|
||||
|
||||
for (usz i = 0; i < g_cfg_usio.players.size(); i++)
|
||||
translate_from_pad(i, i);
|
||||
|
||||
digital_input |= test_on ? 0x80 : 0x00;
|
||||
std::memcpy(input_buf.data(), &digital_input, sizeof(u16));
|
||||
std::memcpy(input_buf.data() + 16, &coin_counter, sizeof(u16));
|
||||
std::memcpy(input_buf.data() + 16, &m_io_status[0].coin_counter, sizeof(u16));
|
||||
|
||||
response = std::move(input_buf);
|
||||
}
|
||||
@ -275,8 +278,8 @@ void usb_device_usio::translate_input_tekken()
|
||||
std::lock_guard lock(pad::g_pad_mutex);
|
||||
const auto handler = pad::get_current_handler();
|
||||
|
||||
std::vector<u8> input_buf(256);
|
||||
le_t<u64> digital_input = 0;
|
||||
std::vector<u8> input_buf(0x180);
|
||||
le_t<u64> digital_input[2]{};
|
||||
le_t<u16> digital_input_lm = 0;
|
||||
|
||||
auto translate_from_pad = [&](usz pad_number, usz player)
|
||||
@ -292,7 +295,9 @@ void usb_device_usio::translate_input_tekken()
|
||||
return;
|
||||
}
|
||||
|
||||
const usz shift = player * 24ULL;
|
||||
const usz shift = (player % 2) * 24ULL;
|
||||
auto& status = m_io_status[player / 2];
|
||||
auto& input = digital_input[player / 2];
|
||||
|
||||
const auto& cfg = ::at32(g_cfg_usio.players, pad_number);
|
||||
cfg->handle_input(pad, false, [&](usio_btn btn, u16 /*value*/, bool pressed)
|
||||
@ -300,27 +305,27 @@ void usb_device_usio::translate_input_tekken()
|
||||
switch (btn)
|
||||
{
|
||||
case usio_btn::test:
|
||||
if (player != 0)
|
||||
if (player % 2 != 0)
|
||||
break;
|
||||
if (pressed && !test_key_pressed) // Solve the need to hold the Test button
|
||||
test_on = !test_on;
|
||||
test_key_pressed = pressed;
|
||||
if (pressed && !status.test_key_pressed) // Solve the need to hold the Test button
|
||||
status.test_on = !status.test_on;
|
||||
status.test_key_pressed = pressed;
|
||||
break;
|
||||
case usio_btn::coin:
|
||||
if (player != 0)
|
||||
if (player % 2 != 0)
|
||||
break;
|
||||
if (pressed && !coin_key_pressed) // Ensure only one coin is inserted each time the Coin button is pressed
|
||||
coin_counter++;
|
||||
coin_key_pressed = pressed;
|
||||
if (pressed && !status.coin_key_pressed) // Ensure only one coin is inserted each time the Coin button is pressed
|
||||
status.coin_counter++;
|
||||
status.coin_key_pressed = pressed;
|
||||
break;
|
||||
case usio_btn::service:
|
||||
if (player == 0 && pressed)
|
||||
digital_input |= 0x4000;
|
||||
if (player % 2 == 0 && pressed)
|
||||
input |= 0x4000;
|
||||
break;
|
||||
case usio_btn::enter:
|
||||
if (pressed)
|
||||
{
|
||||
digital_input |= 0x800000ULL << shift;
|
||||
input |= 0x800000ULL << shift;
|
||||
if (player == 0)
|
||||
digital_input_lm |= 0x800;
|
||||
}
|
||||
@ -328,7 +333,7 @@ void usb_device_usio::translate_input_tekken()
|
||||
case usio_btn::up:
|
||||
if (pressed)
|
||||
{
|
||||
digital_input |= 0x200000ULL << shift;
|
||||
input |= 0x200000ULL << shift;
|
||||
if (player == 0)
|
||||
digital_input_lm |= 0x200;
|
||||
}
|
||||
@ -336,7 +341,7 @@ void usb_device_usio::translate_input_tekken()
|
||||
case usio_btn::down:
|
||||
if (pressed)
|
||||
{
|
||||
digital_input |= 0x100000ULL << shift;
|
||||
input |= 0x100000ULL << shift;
|
||||
if (player == 0)
|
||||
digital_input_lm |= 0x400;
|
||||
}
|
||||
@ -344,7 +349,7 @@ void usb_device_usio::translate_input_tekken()
|
||||
case usio_btn::left:
|
||||
if (pressed)
|
||||
{
|
||||
digital_input |= 0x80000ULL << shift;
|
||||
input |= 0x80000ULL << shift;
|
||||
if (player == 0)
|
||||
digital_input_lm |= 0x2000;
|
||||
}
|
||||
@ -352,7 +357,7 @@ void usb_device_usio::translate_input_tekken()
|
||||
case usio_btn::right:
|
||||
if (pressed)
|
||||
{
|
||||
digital_input |= 0x40000ULL << shift;
|
||||
input |= 0x40000ULL << shift;
|
||||
if (player == 0)
|
||||
digital_input_lm |= 0x4000;
|
||||
}
|
||||
@ -360,47 +365,52 @@ void usb_device_usio::translate_input_tekken()
|
||||
case usio_btn::tekken_button1:
|
||||
if (pressed)
|
||||
{
|
||||
digital_input |= 0x20000ULL << shift;
|
||||
input |= 0x20000ULL << shift;
|
||||
if (player == 0)
|
||||
digital_input_lm |= 0x100;
|
||||
}
|
||||
break;
|
||||
case usio_btn::tekken_button2:
|
||||
if (pressed)
|
||||
digital_input |= 0x10000ULL << shift;
|
||||
input |= 0x10000ULL << shift;
|
||||
break;
|
||||
case usio_btn::tekken_button3:
|
||||
if (pressed)
|
||||
digital_input |= 0x40000000ULL << shift;
|
||||
input |= 0x40000000ULL << shift;
|
||||
break;
|
||||
case usio_btn::tekken_button4:
|
||||
if (pressed)
|
||||
digital_input |= 0x20000000ULL << shift;
|
||||
input |= 0x20000000ULL << shift;
|
||||
break;
|
||||
case usio_btn::tekken_button5:
|
||||
if (pressed)
|
||||
digital_input |= 0x80000000ULL << shift;
|
||||
input |= 0x80000000ULL << shift;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
if (player % 2 == 0 && status.test_on)
|
||||
{
|
||||
input |= 0x80;
|
||||
if (player == 0)
|
||||
digital_input_lm |= 0x1000;
|
||||
}
|
||||
};
|
||||
|
||||
for (usz i = 0; i < g_cfg_usio.players.size(); i++)
|
||||
translate_from_pad(i, i);
|
||||
|
||||
if (test_on)
|
||||
for (usz i = 0; i < 2; i++)
|
||||
{
|
||||
digital_input |= 0x80;
|
||||
digital_input_lm |= 0x1000;
|
||||
std::memcpy(input_buf.data() - i * 0x80 + 0x100, &digital_input[i], sizeof(u64));
|
||||
std::memcpy(input_buf.data() - i * 0x80 + 0x100 + 0x10, &m_io_status[i].coin_counter, sizeof(u16));
|
||||
}
|
||||
|
||||
std::memcpy(input_buf.data() + 128, &digital_input, sizeof(u64));
|
||||
std::memcpy(input_buf.data() + 128 + 16, &coin_counter, sizeof(u16));
|
||||
std::memcpy(input_buf.data(), &digital_input_lm, sizeof(u16));
|
||||
|
||||
input_buf[2] = 0b00010000; // DIP Switches, 8 in total
|
||||
input_buf[2] = 0b00010000; // DIP switches, 8 in total
|
||||
|
||||
response = std::move(input_buf);
|
||||
}
|
||||
@ -489,7 +499,7 @@ void usb_device_usio::usio_read(u8 channel, u16 reg, u16 size)
|
||||
// Get Buffer, rarely gives a reply on real HW
|
||||
// First U16 seems to be a timestamp of sort
|
||||
// Purpose seems related to connectivity check
|
||||
response = {0x7E, 0xE4, 0x00, 0x00, 0x74, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
response = {0x7E, 0xE4, 0x00, 0x00, 0x74, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
break;
|
||||
}
|
||||
case 0x0080:
|
||||
@ -522,7 +532,7 @@ void usb_device_usio::usio_read(u8 channel, u16 reg, u16 size)
|
||||
// Seems to contain a few extra bytes of info in addition to the firmware string
|
||||
// Firmware
|
||||
// "NBGI.;USIO01;Ver1.00;JPN,Multipurpose with PPG."
|
||||
constexpr std::array<u8, 0x100> info {0x4E, 0x42, 0x47, 0x49, 0x2E, 0x3B, 0x55, 0x53, 0x49, 0x4F, 0x30, 0x31, 0x3B, 0x56, 0x65, 0x72, 0x31, 0x2E, 0x30, 0x30, 0x3B, 0x4A, 0x50, 0x4E, 0x2C, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x75, 0x72, 0x70, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x50, 0x50, 0x47, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x42, 0x47, 0x49, 0x2E, 0x3B, 0x55, 0x53, 0x49, 0x4F, 0x30, 0x31, 0x3B, 0x56, 0x65, 0x72, 0x31, 0x2E, 0x30, 0x30, 0x3B, 0x4A, 0x50, 0x4E, 0x2C, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x75, 0x72, 0x70, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x50, 0x50, 0x47, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x13, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x75, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
constexpr std::array<u8, 0x180> info {0x4E, 0x42, 0x47, 0x49, 0x2E, 0x3B, 0x55, 0x53, 0x49, 0x4F, 0x30, 0x31, 0x3B, 0x56, 0x65, 0x72, 0x31, 0x2E, 0x30, 0x30, 0x3B, 0x4A, 0x50, 0x4E, 0x2C, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x75, 0x72, 0x70, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x50, 0x50, 0x47, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x42, 0x47, 0x49, 0x31, 0x3B, 0x55, 0x53, 0x49, 0x4F, 0x30, 0x31, 0x3B, 0x56, 0x65, 0x72, 0x31, 0x2E, 0x30, 0x30, 0x3B, 0x4A, 0x50, 0x4E, 0x2C, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x75, 0x72, 0x70, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x50, 0x50, 0x47, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x13, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x75, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x42, 0x47, 0x49, 0x32, 0x3B, 0x55, 0x53, 0x49, 0x4F, 0x30, 0x31, 0x3B, 0x56, 0x65, 0x72, 0x31, 0x2E, 0x30, 0x30, 0x3B, 0x4A, 0x50, 0x4E, 0x2C, 0x4D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x75, 0x72, 0x70, 0x6F, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x50, 0x50, 0x47, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x13, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x75, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
response = {info.begin() + (reg - 0x1800), info.end()};
|
||||
break;
|
||||
}
|
||||
|
@ -21,11 +21,17 @@ private:
|
||||
void usio_read(u8 channel, u16 reg, u16 size);
|
||||
|
||||
private:
|
||||
bool test_on = false;
|
||||
bool test_key_pressed = false;
|
||||
bool coin_key_pressed = false;
|
||||
bool is_used = false;
|
||||
le_t<u16> coin_counter = 0;
|
||||
const std::string usio_backup_path = rpcs3::utils::get_hdd1_dir() + "/caches/usiobackup.bin";
|
||||
std::vector<u8> response;
|
||||
|
||||
struct io_status
|
||||
{
|
||||
bool test_on = false;
|
||||
bool test_key_pressed = false;
|
||||
bool coin_key_pressed = false;
|
||||
le_t<u16> coin_counter = 0;
|
||||
};
|
||||
|
||||
std::array<io_status, 2> m_io_status;
|
||||
};
|
||||
|
@ -50,9 +50,9 @@ struct cfg_usio final : public emulated_pad_config<usio_btn>
|
||||
cfg_pad_btn<usio_btn> tekken_button5{this, "Tekken Button 5", usio_btn::tekken_button5, pad_button::R1};
|
||||
};
|
||||
|
||||
struct cfg_usios final : public emulated_pads_config<cfg_usio, 2>
|
||||
struct cfg_usios final : public emulated_pads_config<cfg_usio, 4>
|
||||
{
|
||||
cfg_usios() : emulated_pads_config<cfg_usio, 2>("usio") {};
|
||||
cfg_usios() : emulated_pads_config<cfg_usio, 4>("usio") {};
|
||||
};
|
||||
|
||||
extern cfg_usios g_cfg_usio;
|
||||
|
Loading…
Reference in New Issue
Block a user