mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 06:40:42 -07:00
iidx: detect ldj/tdj I/O mismatch (#470)
## Link to GitHub Issue, if one exists #345 ## Description of change For IIDX31+, detect if BI2A or BI2X I/O emulation becomes active, and see if there is a mismatch between the -iidxtdj setting. Right now a mismatch results in warning in log + deferred error log, but in the future we could turn this into a fatal error and crash the game to make it more obvious. ## Testing Tested 4 combinations: 1. DLL in LDJ mode + -iidxtdj off (pass) 2. DLL in LDJ mode + -iidxtdj on (error) 3. DLL in TDJ mode + -iidxtdj off (error) 4. DLL in TDJ mode + -iidxtdj on (pass)
This commit is contained in:
@@ -195,11 +195,11 @@ bool games::iidx::IIDXFMSerialHandle::open(LPCWSTR lpFileName) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("iidx", "Opened COM2 (FM DEVICE)");
|
log_info("iidx", "Opened COM2 (FM DEVICE / bi2a)");
|
||||||
|
games::iidx::update_io_emulation_state(games::iidx::iidx_aio_emulation_state::bi2a_com2);
|
||||||
|
|
||||||
// ACIO device
|
// ACIO device
|
||||||
acio_emu.add_device(new FMSerialDevice());
|
acio_emu.add_device(new FMSerialDevice());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ int games::iidx::IIDXFMSerialHandle::device_io(DWORD dwIoControlCode, LPVOID lpI
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool games::iidx::IIDXFMSerialHandle::close() {
|
bool games::iidx::IIDXFMSerialHandle::close() {
|
||||||
log_info("iidx", "Closed COM2 (FM DEVICE)");
|
log_info("iidx", "Closed COM2 (FM DEVICE / bi2a)");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,11 @@ namespace games::iidx {
|
|||||||
|
|
||||||
static AIO_IOB2_BI2X_TDJ* __fastcall aioIob2Bi2xTDJ_Create(AIO_NMGR_IOB2 *nmgr, int a2) {
|
static AIO_IOB2_BI2X_TDJ* __fastcall aioIob2Bi2xTDJ_Create(AIO_NMGR_IOB2 *nmgr, int a2) {
|
||||||
if (!BI2X_PASSTHROUGH) {
|
if (!BI2X_PASSTHROUGH) {
|
||||||
|
|
||||||
|
log_info("bi2x_hook", "aioIob2Bi2xTDJ_Create called (TDJ I/O emulation active)");
|
||||||
|
games::iidx::update_io_emulation_state(
|
||||||
|
games::iidx::iidx_aio_emulation_state::bi2x_hook);
|
||||||
|
|
||||||
custom_node = new AIO_IOB2_BI2X_TDJ;
|
custom_node = new AIO_IOB2_BI2X_TDJ;
|
||||||
memset(&custom_node->data, 0, sizeof(custom_node->data));
|
memset(&custom_node->data, 0, sizeof(custom_node->data));
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ namespace games::iidx {
|
|||||||
bool IIDXIO_LED_TICKER_READONLY = false;
|
bool IIDXIO_LED_TICKER_READONLY = false;
|
||||||
std::mutex IIDX_LED_TICKER_LOCK;
|
std::mutex IIDX_LED_TICKER_LOCK;
|
||||||
|
|
||||||
|
// io
|
||||||
|
static bool HAS_LIBAIO; // this is how we detect iidx27+
|
||||||
|
|
||||||
tapeledutils::tape_led TAPELED_MAPPING[IIDX_TAPELED_TOTAL] = {
|
tapeledutils::tape_led TAPELED_MAPPING[IIDX_TAPELED_TOTAL] = {
|
||||||
{ 19, Lights::StageLeftAvgR, Lights::StageLeftAvgG, Lights::StageLeftAvgB, "Stage Left" },
|
{ 19, Lights::StageLeftAvgR, Lights::StageLeftAvgG, Lights::StageLeftAvgB, "Stage Left" },
|
||||||
{ 19, Lights::StageRightAvgR, Lights::StageRightAvgG, Lights::StageRightAvgB, "Stage Right" },
|
{ 19, Lights::StageRightAvgR, Lights::StageRightAvgG, Lights::StageRightAvgB, "Stage Right" },
|
||||||
@@ -311,13 +314,14 @@ namespace games::iidx {
|
|||||||
memcpy(settings2.interface_detail, interface_detail2, sizeof(interface_detail2));
|
memcpy(settings2.interface_detail, interface_detail2, sizeof(interface_detail2));
|
||||||
setupapihook_add(settings2);
|
setupapihook_add(settings2);
|
||||||
|
|
||||||
// IIDX 25-27 BIO2 BI2A input device
|
// IIDX 25+ BIO2 BI2A input device
|
||||||
devicehook_add(new IIDXFMSerialHandle());
|
devicehook_add(new IIDXFMSerialHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for new I/O DLL
|
// check for new I/O DLL
|
||||||
auto aio = libutils::try_library("libaio.dll");
|
auto aio = libutils::try_library("libaio.dll");
|
||||||
if (aio != nullptr) {
|
if (aio != nullptr) {
|
||||||
|
HAS_LIBAIO = true;
|
||||||
|
|
||||||
// check TDJ mode
|
// check TDJ mode
|
||||||
TDJ_MODE |= fileutils::text_read("C:\\000rom.txt") == "TDJ-JA";
|
TDJ_MODE |= fileutils::text_read("C:\\000rom.txt") == "TDJ-JA";
|
||||||
@@ -895,4 +899,52 @@ namespace games::iidx {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_io_emulation_state(iidx_aio_emulation_state state) {
|
||||||
|
// <iidx27, don't care, since tdj wasn't a thing before
|
||||||
|
// this is also how we detect that iidx module is attached
|
||||||
|
if (!HAS_LIBAIO) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// in iidx27-30, most DLL types can handle both, caching things in nvram and possibly end
|
||||||
|
// up with wrong i/o (temporarily until nvram is initialized again)
|
||||||
|
// to avoid false positives, only do this for iidx31+, since we know for sure that iidx31
|
||||||
|
// has a clean 010/012 split
|
||||||
|
if (avs::game::is_ext(0, 2023101000)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// log_warning below could be turned into log_fatal in the future once we gain confidence
|
||||||
|
// that this isn't triggering when it's not supposed to
|
||||||
|
if (state == iidx_aio_emulation_state::bi2a_com2 && TDJ_MODE) {
|
||||||
|
deferredlogs::defer_error_messages({
|
||||||
|
"IIDX I/O mode conflict",
|
||||||
|
" game is currently configured to use LDJ I/O;",
|
||||||
|
" however, you turned on IIDX TDJ Mode (-iidxtdj)",
|
||||||
|
" two options to fix this:",
|
||||||
|
" For TDJ mode (120Hz): import patches and enable Force TDJ Mode patch",
|
||||||
|
" For LDJ mode (60Hz): turn off IIDX TDJ Mode option",
|
||||||
|
});
|
||||||
|
log_warning(
|
||||||
|
"iidx",
|
||||||
|
"game is using LDJ I/O but spice TDJ mode is turned on! "
|
||||||
|
"enable Force TDJ I/O patch, OR turn off -iidxtdj");
|
||||||
|
} else if (state == iidx_aio_emulation_state::bi2x_hook && !TDJ_MODE) {
|
||||||
|
deferredlogs::defer_error_messages({
|
||||||
|
"IIDX I/O mode conflict",
|
||||||
|
" game is currently configured to use TDJ I/O;",
|
||||||
|
" however, you turned off IIDX TDJ Mode (-iidxtdj)",
|
||||||
|
" two options to fix this:",
|
||||||
|
" For TDJ mode (120Hz): turn on IIDX TDJ Mode option",
|
||||||
|
" For LDJ mode (60Hz): import patches and enable Force LDJ Mode patch",
|
||||||
|
});
|
||||||
|
log_warning(
|
||||||
|
"iidx",
|
||||||
|
"game is using TDJ I/O but spice TDJ mode is turned off! "
|
||||||
|
"turn on -iidxtdj, OR enable Force LDJ I/O patch");
|
||||||
|
} else {
|
||||||
|
log_misc("iidx", "i/o mode validation passed");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,4 +62,10 @@ namespace games::iidx {
|
|||||||
const char* get_16seg();
|
const char* get_16seg();
|
||||||
bool is_tdj_fhd();
|
bool is_tdj_fhd();
|
||||||
void apply_audio_hacks();
|
void apply_audio_hacks();
|
||||||
|
|
||||||
|
enum class iidx_aio_emulation_state {
|
||||||
|
bi2a_com2,
|
||||||
|
bi2x_hook
|
||||||
|
};
|
||||||
|
void update_io_emulation_state(iidx_aio_emulation_state state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -590,7 +590,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.category = "Game Options (Advanced)",
|
.category = "Game Options (Advanced)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "IIDX TDJ Mode",
|
.title = "IIDX TDJ Mode (Lightning Model)",
|
||||||
.name = "iidxtdj",
|
.name = "iidxtdj",
|
||||||
.desc = "Enables TDJ cabinet mode. Ensure you also set -iidxsounddevice to desired option",
|
.desc = "Enables TDJ cabinet mode. Ensure you also set -iidxsounddevice to desired option",
|
||||||
.type = OptionType::Bool,
|
.type = OptionType::Bool,
|
||||||
|
|||||||
Reference in New Issue
Block a user