Update to spice2x-25-04-25 (pre-apply)

> broken commit
This commit is contained in:
[ ]
2025-05-07 00:25:31 +09:00
parent 04dee88276
commit c94de456b5
543 changed files with 78491 additions and 91698 deletions
+56
View File
@@ -10,6 +10,7 @@
#include "util/libutils.h"
#include "util/fileutils.h"
#include "util/detour.h"
#include "cfg/configurator.h"
#include "io.h"
@@ -18,6 +19,8 @@
#include "p3io/sate.h"
#include "p3io/usbmem.h"
#include "p4io/p4io.h"
using namespace acioemu;
namespace games::ddr {
@@ -25,6 +28,8 @@ namespace games::ddr {
// settings
bool SDMODE = false;
uint8_t DDR_TAPELEDS[TAPELED_DEVICE_COUNT][50][3] {};
static decltype(SendMessage) *SendMessage_real = nullptr;
static SHORT WINAPI GetAsyncKeyState_hook(int vKey) {
@@ -47,6 +52,43 @@ namespace games::ddr {
DDRGame::DDRGame() : Game("Dance Dance Revolution") {
}
void DDRGame::pre_attach() {
if (!cfg::CONFIGURATOR_STANDALONE && avs::game::is_model("TDX")) {
log_fatal(
"ddr",
"BAD MODEL NAME ERROR\n\n\n"
"!!! model name set to TDX, this is WRONG and will break your game !!!\n"
"!!! !!!\n"
"!!! !!!\n"
"!!! spice2x does not yet support TDX, use MDX instead. !!!\n"
"!!! !!!\n"
"!!! !!!\n"
"!!! model name set to TDX, this is WRONG and will break your game !!!\n\n\n"
);
}
if (!cfg::CONFIGURATOR_STANDALONE && avs::game::DEST[0] == 'U') {
log_warning(
"ddr",
"U-REGION WARNING\n\n\n"
"!!! !!!\n"
"!!! !!!\n"
"!!! !!!\n"
"!!! !!!\n"
"!!! <dest> is set to U region !!!\n"
"!!! !!!\n"
"!!! While this is legal, unless you have compatible data, this !!!\n"
"!!! will most likely crash your game or fail to boot. !!!\n"
"!!! !!!\n"
"!!! It is recommended that you stick with J region. !!!\n"
"!!! !!!\n"
"!!! !!!\n"
"!!! !!!\n"
"!!! !!!\n\n\n"
);
}
}
void DDRGame::attach() {
Game::attach();
@@ -60,6 +102,8 @@ namespace games::ddr {
// add fake devices
if (avs::game::DLL_NAME == "arkmdxbio2.dll") {
devicehook_add(new acioemu::ACIOHandle(L"COM1"));
} else if(avs::game::DLL_NAME == "arkmdxp4.dll") {
devicehook_add(new DDRP4IOHandle());
} else {
devicehook_add(new DDRFOOTHandle());
devicehook_add(new DDRSATEHandle());
@@ -89,6 +133,17 @@ namespace games::ddr {
memcpy(settings2.property_devicedesc, settings_property, strlen(settings_property) + 1);
memcpy(settings2.interface_detail, settings_detail, sizeof(settings_detail));
const char settings_detail_p4io[] = R"(\\.\P4IO)";
// settings p4io
SETUPAPI_SETTINGS settingsp4io {};
settingsp4io.class_guid[0] = 0x8B7250A5;
settingsp4io.class_guid[1] = 0x46C94F61;
settingsp4io.class_guid[2] = 0x68E63A84;
settingsp4io.class_guid[3] = 0x206A4706;
memcpy(settingsp4io.property_devicedesc, settings_property, strlen(settings_property) + 1);
memcpy(settingsp4io.interface_detail, settings_detail_p4io, sizeof(settings_detail_p4io));
// init SETUP API
setupapihook_init(avs::game::DLL_INSTANCE);
@@ -100,6 +155,7 @@ namespace games::ddr {
// add settings
setupapihook_add(settings1);
setupapihook_add(settings2);
setupapihook_add(settingsp4io);
// misc hooks
detour::iat_try("GetAsyncKeyState", GetAsyncKeyState_hook, avs::game::DLL_INSTANCE);
+6
View File
@@ -1,15 +1,21 @@
#pragma once
#include "games/game.h"
#include <cstdint>
namespace games::ddr {
// settings
extern bool SDMODE;
// Buffers to store RGB data for tape LEDs on gold cabinets
const size_t TAPELED_DEVICE_COUNT = 11;
extern uint8_t DDR_TAPELEDS[TAPELED_DEVICE_COUNT][50][3];
class DDRGame : public games::Game {
public:
DDRGame();
virtual void pre_attach() override;
virtual void attach() override;
virtual void detach() override;
};
+92 -1
View File
@@ -79,7 +79,98 @@ std::vector<Light> &games::ddr::get_lights() {
"HD P2 Speaker F B",
"HD P2 Speaker W R",
"HD P2 Speaker W G",
"HD P2 Speaker W B"
"HD P2 Speaker W B",
"WHITE Speaker Top R",
"WHITE Speaker Top G",
"WHITE Speaker Top B",
"WHITE Speaker Bottom R",
"WHITE Speaker Bottom G",
"WHITE Speaker Bottom B",
"WHITE Woofer R",
"WHITE Woofer G",
"WHITE Woofer B",
"GOLD P1 Menu Start",
"GOLD P1 Menu Up",
"GOLD P1 Menu Down",
"GOLD P1 Menu Left",
"GOLD P1 Menu Right",
"GOLD P2 Menu Start",
"GOLD P2 Menu Up",
"GOLD P2 Menu Down",
"GOLD P2 Menu Left",
"GOLD P2 Menu Right",
"GOLD Title Panel Left",
"GOLD Title Panel Center",
"GOLD Title Panel Right",
"GOLD P1 Woofer Corner",
"GOLD P2 Woofer Corner",
"GOLD P1 Card Unit R",
"GOLD P1 Card Unit G",
"GOLD P1 Card Unit B",
"GOLD P2 Card Unit R",
"GOLD P2 Card Unit G",
"GOLD P2 Card Unit B",
"GOLD Top Panel Avg R",
"GOLD Top Panel Avg G",
"GOLD Top Panel Avg B",
"GOLD Monitor Side Left Avg R",
"GOLD Monitor Side Left Avg G",
"GOLD Monitor Side Left Avg B",
"GOLD Monitor Side Right Avg R",
"GOLD Monitor Side Right Avg G",
"GOLD Monitor Side Right Avg B",
"GOLD P1 Foot Up Avg R",
"GOLD P1 Foot Up Avg G",
"GOLD P1 Foot Up Avg B",
"GOLD P1 Foot Down Avg R",
"GOLD P1 Foot Down Avg G",
"GOLD P1 Foot Down Avg B",
"GOLD P1 Foot Left Avg R",
"GOLD P1 Foot Left Avg G",
"GOLD P1 Foot Left Avg B",
"GOLD P1 Foot Right Avg R",
"GOLD P1 Foot Right Avg G",
"GOLD P1 Foot Right Avg B",
"GOLD P2 Foot Up Avg R",
"GOLD P2 Foot Up Avg G",
"GOLD P2 Foot Up Avg B",
"GOLD P2 Foot Down Avg R",
"GOLD P2 Foot Down Avg G",
"GOLD P2 Foot Down Avg B",
"GOLD P2 Foot Left Avg R",
"GOLD P2 Foot Left Avg G",
"GOLD P2 Foot Left Avg B",
"GOLD P2 Foot Right Avg R",
"GOLD P2 Foot Right Avg G",
"GOLD P2 Foot Right Avg B",
"GOLD P1 Stage Corner Up-Left",
"GOLD P1 Stage Corner Up-Right",
"GOLD P1 Stage Corner Down-Left",
"GOLD P1 Stage Corner Down-Right",
"GOLD P2 Stage Corner Up-Left",
"GOLD P2 Stage Corner Up-Right",
"GOLD P2 Stage Corner Down-Left",
"GOLD P2 Stage Corner Down-Right"
);
}
+99
View File
@@ -40,39 +40,138 @@ namespace games::ddr {
P1_FOOT_UP,
P1_FOOT_RIGHT,
P1_FOOT_DOWN,
P2_FOOT_LEFT,
P2_FOOT_UP,
P2_FOOT_RIGHT,
P2_FOOT_DOWN,
SPOT_RED,
SPOT_BLUE,
TOP_SPOT_RED,
TOP_SPOT_BLUE,
P1_HALOGEN_UPPER,
P1_HALOGEN_LOWER,
P2_HALOGEN_UPPER,
P2_HALOGEN_LOWER,
P1_BUTTON,
P2_BUTTON,
NEON,
HD_P1_START,
HD_P1_LEFT_RIGHT,
HD_P1_UP_DOWN,
HD_P2_START,
HD_P2_LEFT_RIGHT,
HD_P2_UP_DOWN,
HD_P1_SPEAKER_F_R,
HD_P1_SPEAKER_F_G,
HD_P1_SPEAKER_F_B,
HD_P1_SPEAKER_W_R,
HD_P1_SPEAKER_W_G,
HD_P1_SPEAKER_W_B,
HD_P2_SPEAKER_F_R,
HD_P2_SPEAKER_F_G,
HD_P2_SPEAKER_F_B,
HD_P2_SPEAKER_W_R,
HD_P2_SPEAKER_W_G,
HD_P2_SPEAKER_W_B,
WHITE_SPEAKER_TOP_R,
WHITE_SPEAKER_TOP_G,
WHITE_SPEAKER_TOP_B,
WHITE_SPEAKER_BOTTOM_R,
WHITE_SPEAKER_BOTTOM_G,
WHITE_SPEAKER_BOTTOM_B,
WHITE_WOOFER_R,
WHITE_WOOFER_G,
WHITE_WOOFER_B,
GOLD_P1_MENU_START,
GOLD_P1_MENU_UP,
GOLD_P1_MENU_DOWN,
GOLD_P1_MENU_LEFT,
GOLD_P1_MENU_RIGHT,
GOLD_P2_MENU_START,
GOLD_P2_MENU_UP,
GOLD_P2_MENU_DOWN,
GOLD_P2_MENU_LEFT,
GOLD_P2_MENU_RIGHT,
GOLD_TITLE_PANEL_LEFT,
GOLD_TITLE_PANEL_CENTER,
GOLD_TITLE_PANEL_RIGHT,
GOLD_P1_WOOFER_CORNER,
GOLD_P2_WOOFER_CORNER,
GOLD_P1_CARD_UNIT_R,
GOLD_P1_CARD_UNIT_G,
GOLD_P1_CARD_UNIT_B,
GOLD_P2_CARD_UNIT_R,
GOLD_P2_CARD_UNIT_G,
GOLD_P2_CARD_UNIT_B,
GOLD_TOP_PANEL_AVG_R,
GOLD_TOP_PANEL_AVG_G,
GOLD_TOP_PANEL_AVG_B,
GOLD_MONITOR_SIDE_LEFT_AVG_R,
GOLD_MONITOR_SIDE_LEFT_AVG_G,
GOLD_MONITOR_SIDE_LEFT_AVG_B,
GOLD_MONITOR_SIDE_RIGHT_AVG_R,
GOLD_MONITOR_SIDE_RIGHT_AVG_G,
GOLD_MONITOR_SIDE_RIGHT_AVG_B,
GOLD_P1_FOOT_UP_AVG_R,
GOLD_P1_FOOT_UP_AVG_G,
GOLD_P1_FOOT_UP_AVG_B,
GOLD_P1_FOOT_DOWN_AVG_R,
GOLD_P1_FOOT_DOWN_AVG_G,
GOLD_P1_FOOT_DOWN_AVG_B,
GOLD_P1_FOOT_LEFT_AVG_R,
GOLD_P1_FOOT_LEFT_AVG_G,
GOLD_P1_FOOT_LEFT_AVG_B,
GOLD_P1_FOOT_RIGHT_AVG_R,
GOLD_P1_FOOT_RIGHT_AVG_G,
GOLD_P1_FOOT_RIGHT_AVG_B,
GOLD_P2_FOOT_UP_AVG_R,
GOLD_P2_FOOT_UP_AVG_G,
GOLD_P2_FOOT_UP_AVG_B,
GOLD_P2_FOOT_DOWN_AVG_R,
GOLD_P2_FOOT_DOWN_AVG_G,
GOLD_P2_FOOT_DOWN_AVG_B,
GOLD_P2_FOOT_LEFT_AVG_R,
GOLD_P2_FOOT_LEFT_AVG_G,
GOLD_P2_FOOT_LEFT_AVG_B,
GOLD_P2_FOOT_RIGHT_AVG_R,
GOLD_P2_FOOT_RIGHT_AVG_G,
GOLD_P2_FOOT_RIGHT_AVG_B,
GOLD_P1_STAGE_UP_LEFT,
GOLD_P1_STAGE_UP_RIGHT,
GOLD_P1_STAGE_DOWN_LEFT,
GOLD_P1_STAGE_DOWN_RIGHT,
GOLD_P2_STAGE_UP_LEFT,
GOLD_P2_STAGE_UP_RIGHT,
GOLD_P2_STAGE_DOWN_LEFT,
GOLD_P2_STAGE_DOWN_RIGHT,
};
}
+352
View File
@@ -0,0 +1,352 @@
#include "p4io.h"
#include "rawinput/rawinput.h"
#include "util/logging.h"
#include "util/utils.h"
#include "../io.h"
#include <algorithm>
#ifndef FILE_DEVICE_UNKNOWN
#define FILE_DEVICE_UNKNOWN 0x00000022
#endif
// Packet header seems to be
// AA cmdId Seq maybe_length?
namespace {
#pragma pack(push, 1)
enum P4IOIoCtl : uint16_t {
P4IO_IOCTL_GET_INPUTS = 0x801,
P4IO_IOCTL_GET_VERSION_FUNC = 0x803,
};
enum class P4IOCmd : uint8_t {
Nop = 0x00,
GetTypeVerProd = 0x01,
UpdateLights = 0x12,
CoinHandler = 0x18,
Unk_1C = 0x1C,
IoSciOpen = 0x20,
SciTransfer = 0x21,
IoSciClose = 0x24,
ReadSecPlug_01 = 0x40,
ReadSecPlug_02 = 0x41,
};
struct P4IOHeader {
uint8_t magic;
P4IOCmd cmd;
uint8_t seq;
uint8_t length;
};
#pragma pack(pop)
const uint8_t blackPlugData[0x20] = {
0xC9, 0xFE, 0xC1, 0x5B, 0x8D, 0x8A, 0xE7, 0xA8,
0x92, 0xB8, 0x1A, 0x86, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77
};
const uint8_t whitePlugData[0x20] = {
0x18, 0x98, 0x12, 0x71, 0xB3, 0xA2, 0x20, 0x08,
0x82, 0x20, 0x08, 0x82, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDA
};
}
namespace games::ddr {
bool DDRP4IOHandle::open(LPCWSTR lpFileName) {
if (wcscmp(lpFileName, L"\\\\.\\P4IO\\p4io") != 0) {
return false;
}
if (!m_acio_emu) {
m_acio_emu = new acioemu::ACIOEmu();
m_acio_emu->add_device(new acioemu::ICCADevice(false, true, 2));
m_acio_emu->add_device(new HDXSDevice());
}
log_info("ddr", "Opened P4IO");
return true;
}
int DDRP4IOHandle::read(LPVOID lpBuffer, DWORD nNumberOfBytesToRead) {
DWORD transferSize = std::min(nNumberOfBytesToRead, (DWORD)m_read_buf.size());
memcpy(lpBuffer, m_read_buf.data(), transferSize);
m_read_buf.erase(m_read_buf.begin(), m_read_buf.begin()+transferSize);
return transferSize;
}
int DDRP4IOHandle::write(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite) {
const P4IOHeader *header = reinterpret_cast<const P4IOHeader*>(lpBuffer);
const uint8_t *data = reinterpret_cast<const uint8_t*>(reinterpret_cast<const uint8_t*>(lpBuffer)+sizeof(P4IOHeader));
if(nNumberOfBytesToWrite < sizeof(P4IOHeader)
|| header->magic != 0xAA
|| nNumberOfBytesToWrite < sizeof(P4IOHeader)+header->length)
{
log_warning("ddr", "p4io has the wrong header: {}", bin2hex(reinterpret_cast<const uint8_t*>(lpBuffer),
(int)nNumberOfBytesToWrite));
return 0;
}
std::vector<uint8_t> responseBuffer(64);
P4IOHeader *respHeader = reinterpret_cast<P4IOHeader*>(responseBuffer.data());
respHeader->magic = 0xAA;
respHeader->cmd = header->cmd;
respHeader->seq = header->seq;
uint8_t *respData = responseBuffer.data()+sizeof(P4IOHeader);
switch(header->cmd)
{
case P4IOCmd::Nop:
case P4IOCmd::Unk_1C:
case P4IOCmd::IoSciOpen:
case P4IOCmd::IoSciClose:
{
m_read_buf.insert(m_read_buf.end(), responseBuffer.begin(), responseBuffer.end());
return nNumberOfBytesToWrite;
}
break;
case P4IOCmd::GetTypeVerProd: {
respHeader->length = 0x2C;
// type
memcpy(&respData[0], "JDX", 4);
// version
respData[5] = 69;
respData[6] = 69;
respData[7] = 69;
// prod
memcpy(&respData[8], "prod", 4);
// date
memcpy(&respData[0xC], "2024-03-12", 10);
// time
memcpy(&respData[0x1C], "06:39:21", 8);
m_read_buf_mutex.lock();
m_read_buf.insert(m_read_buf.end(), responseBuffer.begin(), responseBuffer.end());
m_read_buf_mutex.unlock();
return nNumberOfBytesToWrite;
}
break;
case P4IOCmd::UpdateLights: {
static const size_t lightMapping[] = {
Lights::WHITE_SPEAKER_TOP_G,
Lights::WHITE_SPEAKER_TOP_R,
Lights::WHITE_SPEAKER_TOP_B,
Lights::WHITE_SPEAKER_BOTTOM_G,
Lights::WHITE_SPEAKER_BOTTOM_R,
Lights::WHITE_SPEAKER_BOTTOM_B,
Lights::WHITE_WOOFER_G,
Lights::WHITE_WOOFER_R,
Lights::WHITE_WOOFER_B,
Lights::HD_P1_START,
Lights::HD_P1_UP_DOWN,
Lights::HD_P1_LEFT_RIGHT
};
auto &lights = get_lights();
for(size_t i = 0; i < std::size(lightMapping); ++i) {
GameAPI::Lights::writeLight(RI_MGR, lights[lightMapping[i]], data[i] == 0 ? 0.f : 1.f);
}
RI_MGR->devices_flush_output();
m_read_buf_mutex.lock();
m_read_buf.insert(m_read_buf.end(), responseBuffer.begin(), responseBuffer.end());
m_read_buf_mutex.unlock();
return nNumberOfBytesToWrite;
}
break;
case P4IOCmd::CoinHandler: {
respHeader->length = 0x04;
// TODO:
m_read_buf_mutex.lock();
m_read_buf.insert(m_read_buf.end(), responseBuffer.begin(), responseBuffer.end());
m_read_buf_mutex.unlock();
return nNumberOfBytesToWrite;
}
break;
case P4IOCmd::SciTransfer: {
// request is 1 byte port #, followed by data
if(header->length > 1 && data[0] == 0) {
for(size_t i = 0; i < header->length-1u; ++i) {
m_acio_emu->write(data[1+i]);
}
}
respHeader->length = 2;
//response is 1 byte port #, 1 byte error flag, followed by data
if(header->length >= 1 && data[0] == 0) {
uint8_t readBytes = 0;
while(readBytes < 58) {
const auto b = m_acio_emu->read();
if(!b.has_value()) {
break;
}
respData[2+readBytes] = b.value();
++readBytes;
}
respHeader->length = 2+readBytes;
}
m_read_buf_mutex.lock();
m_read_buf.insert(m_read_buf.end(), responseBuffer.begin(), responseBuffer.end());
m_read_buf_mutex.unlock();
return nNumberOfBytesToWrite;
}
break;
case P4IOCmd::ReadSecPlug_01: {
// maybe just a presense check
respHeader->length = 0x09;
memset(&respData[1], 0xAA, 8);
m_read_buf_mutex.lock();
m_read_buf.insert(m_read_buf.end(), responseBuffer.begin(), responseBuffer.end());
m_read_buf_mutex.unlock();
return nNumberOfBytesToWrite;
}
break;
case P4IOCmd::ReadSecPlug_02: {
respHeader->length = 0x21;
if(data[0] == 0) {
memcpy(&respData[1], blackPlugData, sizeof(blackPlugData));
} else {
memcpy(&respData[1], whitePlugData, sizeof(whitePlugData));
}
m_read_buf_mutex.lock();
m_read_buf.insert(m_read_buf.end(), responseBuffer.begin(), responseBuffer.end());
m_read_buf_mutex.unlock();
return nNumberOfBytesToWrite;
}
break;
}
return 0;
}
int DDRP4IOHandle::device_io(DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer,
DWORD nOutBufferSize) {
if(((dwIoControlCode>>16)&0xFFFF) == FILE_DEVICE_UNKNOWN) {
switch((dwIoControlCode>>2)&0x3FFF) {
case P4IO_IOCTL_GET_INPUTS: {
memset(lpOutBuffer, 0, 16);
auto controls = (uint32_t*) lpOutBuffer;
const std::pair<size_t, uint8_t> buttonMapping[] =
{
{Buttons::SERVICE, 25}, //Good
{Buttons::TEST, 28}, //Good
{Buttons::COIN_MECH, 24}, //Good
{Buttons::P1_START, 0}, //Good
{Buttons::P1_PANEL_UP, 5}, //Good
{Buttons::P1_PANEL_DOWN, 6}, //Good
{Buttons::P1_PANEL_LEFT, 7}, //Goood
{Buttons::P1_PANEL_RIGHT, 16}, //Good
{Buttons::P1_MENU_UP, 1}, //Good
{Buttons::P1_MENU_DOWN, 2}, //Good
{Buttons::P1_MENU_LEFT, 3}, //Good
{Buttons::P1_MENU_RIGHT, 4}, //Good
{Buttons::P2_START, 8}, //Good
{Buttons::P2_PANEL_UP, 13}, //Good
{Buttons::P2_PANEL_DOWN, 14}, //Good
{Buttons::P2_PANEL_LEFT, 15}, //Good
{Buttons::P2_PANEL_RIGHT, 20}, //Good
{Buttons::P2_MENU_UP, 9}, //Good
{Buttons::P2_MENU_DOWN, 10}, //Good
{Buttons::P2_MENU_LEFT, 11}, //Good
{Buttons::P2_MENU_RIGHT, 12}, //Good
};
auto &buttons = get_buttons();
for(const auto &mapping : buttonMapping)
{
if(GameAPI::Buttons::getState(RI_MGR, buttons[mapping.first]))
{
controls[mapping.second/32] |= 1<<(mapping.second%32);
}
}
return 16;
}
break;
case P4IO_IOCTL_GET_VERSION_FUNC: {
if(nOutBufferSize > strlen("spicy p4io") + 1) {
strcpy((char*)lpOutBuffer, "spicy p4io");
return 11;
}
}
break;
}
}
return 0;
}
bool DDRP4IOHandle::close() {
log_info("ddr", "Closed P4IO");
return true;
}
DDRP4IOHandle::HDXSDevice::HDXSDevice() {
this->node_count = 1;
}
bool DDRP4IOHandle::HDXSDevice::parse_msg(
acioemu::MessageData* msg_in,
circular_buffer<uint8_t> *response_buffer) {
switch(msg_in->cmd.code)
{
case acioemu::ACIO_CMD_GET_VERSION: {
auto msg = this->create_msg(msg_in, acioemu::MSG_VERSION_SIZE);
this->set_version(msg, 0x204, 0, 1, 6, 0, "HDXS");
write_msg(msg, response_buffer);
delete msg;
}
break;
case acioemu::ACIO_CMD_KEEPALIVE: {
auto msg = this->create_msg(msg_in, 0);
write_msg(msg, response_buffer);
delete msg;
break;
}
break;
case acioemu::ACIO_CMD_STARTUP:
case acioemu::ACIO_CMD_CLEAR:
case 0x110:
case 0x128:
{
auto msg = this->create_msg_status(msg_in, 0x00);
write_msg(msg, response_buffer);
delete msg;
}
break;
default:
log_info("ddr", "HDXS unhandled {:03X}", msg_in->cmd.code);
}
return true;
}
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include "acioemu/acioemu.h"
#include "hooks/devicehook.h"
#include <mutex>
namespace games::ddr {
class DDRP4IOHandle : public CustomHandle {
private:
acioemu::ACIOEmu *m_acio_emu;
std::vector<uint8_t> m_read_buf;
std::mutex m_read_buf_mutex;
class HDXSDevice : public acioemu::ACIODeviceEmu {
public:
HDXSDevice();
bool parse_msg(
acioemu::MessageData* msg_in,
circular_buffer<uint8_t> *response_buffer
) override;
};
public:
bool open(LPCWSTR lpFileName) override;
int read(LPVOID lpBuffer, DWORD nNumberOfBytesToRead) override;
int write(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite) override;
int device_io(DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer,
DWORD nOutBufferSize) override;
bool close() override;
};
}