Initial re-upload of spice2x-24-08-24
This commit is contained in:
140
acio/acio.cpp
Normal file
140
acio/acio.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#include "acio.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "cfg/config.h"
|
||||
#include "cfg/api.h"
|
||||
#include "hooks/libraryhook.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/fileutils.h"
|
||||
#include "util/libutils.h"
|
||||
#include "util/logging.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
#include "bi2a/bi2a.h"
|
||||
#include "bmpu/bmpu.h"
|
||||
#include "core/core.h"
|
||||
#include "hbhi/hbhi.h"
|
||||
#include "hdxs/hdxs.h"
|
||||
#include "hgth/hgth.h"
|
||||
#include "i36g/i36g.h"
|
||||
#include "i36i/i36i.h"
|
||||
#include "icca/icca.h"
|
||||
#include "j32d/j32d.h"
|
||||
#include "kfca/kfca.h"
|
||||
#include "klpa/klpa.h"
|
||||
#include "mdxf/mdxf.h"
|
||||
#include "nddb/nddb.h"
|
||||
#include "panb/panb.h"
|
||||
#include "pix/pix.h"
|
||||
#include "pjec/pjec.h"
|
||||
#include "pjei/pjei.h"
|
||||
#include "la9a/la9a.h"
|
||||
|
||||
#include "module.h"
|
||||
|
||||
// globals
|
||||
namespace acio {
|
||||
HINSTANCE DLL_INSTANCE = nullptr;
|
||||
std::vector<acio::ACIOModule *> MODULES;
|
||||
}
|
||||
|
||||
/*
|
||||
* decide on hook mode used
|
||||
* libacio compiled using ICC64 sometimes doesn't leave enough space to insert the inline hooks
|
||||
* in this case, we want to use IAT instead
|
||||
*/
|
||||
static inline acio::HookMode get_hookmode() {
|
||||
#ifdef SPICE64
|
||||
return acio::HookMode::IAT;
|
||||
#else
|
||||
return acio::HookMode::INLINE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void acio::attach() {
|
||||
log_info("acio", "SpiceTools ACIO");
|
||||
|
||||
// load settings and instance
|
||||
acio::DLL_INSTANCE = LoadLibraryA("libacio.dll");
|
||||
|
||||
/*
|
||||
* library hook
|
||||
* some games have a second DLL laying around which gets loaded dynamically
|
||||
* we just give it the same instance as the normal one so the hooks still work
|
||||
*/
|
||||
libraryhook_hook_library("libacioex.dll", acio::DLL_INSTANCE);
|
||||
libraryhook_hook_library("libacio_ex.dll", acio::DLL_INSTANCE);
|
||||
libraryhook_hook_library("libacio_old.dll", acio::DLL_INSTANCE);
|
||||
// libacioEx.dll for Road Fighters 3D
|
||||
// needed as comparisons in LoadLibrary hooks are case-sensitive
|
||||
libraryhook_hook_library("libacioEx.dll", acio::DLL_INSTANCE);
|
||||
libraryhook_enable(avs::game::DLL_INSTANCE);
|
||||
|
||||
// get hook mode
|
||||
acio::HookMode hook_mode = get_hookmode();
|
||||
|
||||
// load modules
|
||||
MODULES.push_back(new acio::BI2AModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::BMPUModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::CoreModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::HBHIModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::HDXSModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::HGTHModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::I36GModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::I36IModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::ICCAModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::J32DModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::KFCAModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::KLPAModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::MDXFModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::NDDBModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::PANBModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::PJECModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::PJEIModule(acio::DLL_INSTANCE, hook_mode));
|
||||
MODULES.push_back(new acio::LA9AModule(acio::DLL_INSTANCE, hook_mode));
|
||||
|
||||
/*
|
||||
* PIX is special and needs another DLL.
|
||||
* we load that module only if the file exists.
|
||||
*/
|
||||
if (fileutils::file_exists(MODULE_PATH / "libacio_pix.dll")) {
|
||||
HINSTANCE pix_instance = libutils::load_library(MODULE_PATH / "libacio_pix.dll");
|
||||
MODULES.push_back(new acio::PIXModule(pix_instance, hook_mode));
|
||||
}
|
||||
|
||||
// apply modules
|
||||
for (auto &module : MODULES) {
|
||||
module->attach();
|
||||
}
|
||||
}
|
||||
|
||||
void acio::attach_icca() {
|
||||
log_info("acio", "SpiceTools ACIO ICCA");
|
||||
|
||||
// load instance if needed
|
||||
if (!acio::DLL_INSTANCE) {
|
||||
acio::DLL_INSTANCE = LoadLibraryA("libacio.dll");
|
||||
}
|
||||
|
||||
// get hook mode
|
||||
acio::HookMode hook_mode = get_hookmode();
|
||||
|
||||
// load single module
|
||||
auto icca_module = new acio::ICCAModule(acio::DLL_INSTANCE, hook_mode);
|
||||
icca_module->attach();
|
||||
MODULES.push_back(icca_module);
|
||||
}
|
||||
|
||||
void acio::detach() {
|
||||
|
||||
// clear modules
|
||||
while (!MODULES.empty()) {
|
||||
delete MODULES.back();
|
||||
MODULES.pop_back();
|
||||
}
|
||||
}
|
||||
18
acio/acio.h
Normal file
18
acio/acio.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
// globals
|
||||
extern HINSTANCE DLL_INSTANCE;
|
||||
extern std::vector<acio::ACIOModule *> MODULES;
|
||||
|
||||
void attach();
|
||||
void attach_icca();
|
||||
void detach();
|
||||
}
|
||||
763
acio/bi2a/bi2a.cpp
Normal file
763
acio/bi2a/bi2a.cpp
Normal file
@@ -0,0 +1,763 @@
|
||||
#include "bi2a.h"
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "games/ddr/io.h"
|
||||
#include "games/sdvx/sdvx.h"
|
||||
#include "games/sdvx/io.h"
|
||||
#include "games/drs/io.h"
|
||||
#include "games/drs/drs.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/logging.h"
|
||||
#include "util/utils.h"
|
||||
#include "util/tapeled.h"
|
||||
|
||||
using namespace GameAPI;
|
||||
|
||||
// state
|
||||
static uint8_t STATUS_BUFFER[272] {};
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
static unsigned int BI2A_VOLL = 0;
|
||||
static unsigned int BI2A_VOLR = 0;
|
||||
|
||||
|
||||
static bool __cdecl ac_io_bi2a_init_is_finished() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_get_control_status_buffer(void *buffer) {
|
||||
|
||||
// copy buffer
|
||||
memcpy(buffer, STATUS_BUFFER, std::size(STATUS_BUFFER));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_update_control_status_buffer() {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Sound Voltex
|
||||
if (avs::game::is_model("KFC")) {
|
||||
|
||||
// clear buffer
|
||||
memset(STATUS_BUFFER, 0, std::size(STATUS_BUFFER));
|
||||
STATUS_BUFFER[0] = 1;
|
||||
|
||||
/*
|
||||
* Unmapped Buttons
|
||||
*
|
||||
* Control Bit
|
||||
* EX BUTTON 1 93
|
||||
* EX BUTTON 2 92
|
||||
* EX ANALOG 1 170-183
|
||||
* EX ANALOG 2 186-199
|
||||
*/
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::sdvx::get_buttons();
|
||||
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::Test))) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 19);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::Service))) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 18);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::CoinMech))) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 17);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::Start))) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 85);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::BT_A))) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 84);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::BT_B))) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 83);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::BT_C))) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 82);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::BT_D))) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 81);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::FX_L))) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 80);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::FX_R))) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 95);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::Headphone))) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 87);
|
||||
}
|
||||
|
||||
// volume left
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::VOL_L_Left))) {
|
||||
BI2A_VOLL = (BI2A_VOLL - games::sdvx::DIGITAL_KNOB_SENS) & 1023;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::VOL_L_Right))) {
|
||||
BI2A_VOLL = (BI2A_VOLL + games::sdvx::DIGITAL_KNOB_SENS) & 1023;
|
||||
}
|
||||
|
||||
// volume right
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::VOL_R_Left))) {
|
||||
BI2A_VOLR = (BI2A_VOLR - games::sdvx::DIGITAL_KNOB_SENS) & 1023;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::VOL_R_Right))) {
|
||||
BI2A_VOLR = (BI2A_VOLR + games::sdvx::DIGITAL_KNOB_SENS) & 1023;
|
||||
}
|
||||
|
||||
// update volumes
|
||||
auto &analogs = games::sdvx::get_analogs();
|
||||
auto vol_left = BI2A_VOLL;
|
||||
auto vol_right = BI2A_VOLR;
|
||||
if (analogs.at(0).isSet() || analogs.at(1).isSet()) {
|
||||
vol_left += (unsigned int) (Analogs::getState(RI_MGR,
|
||||
analogs.at(games::sdvx::Analogs::VOL_L)) * 1023.99f);
|
||||
vol_right += (unsigned int) (Analogs::getState(RI_MGR,
|
||||
analogs.at(games::sdvx::Analogs::VOL_R)) * 1023.99f);
|
||||
}
|
||||
|
||||
// proper loops
|
||||
vol_left %= 1024;
|
||||
vol_right %= 1024;
|
||||
|
||||
// save volumes in buffer
|
||||
*((uint16_t*) &STATUS_BUFFER[17]) = (uint16_t) ((vol_left) << 2);
|
||||
*((uint16_t*) &STATUS_BUFFER[19]) = (uint16_t) ((vol_right) << 2);
|
||||
}
|
||||
|
||||
// DanceDanceRevolution
|
||||
if (avs::game::is_model("MDX")) {
|
||||
|
||||
// clear buffer
|
||||
memset(STATUS_BUFFER, 0, std::size(STATUS_BUFFER));
|
||||
STATUS_BUFFER[0] = 1;
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::ddr::get_buttons();
|
||||
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::COIN_MECH)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[2] |= 1 << 1;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::SERVICE)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[2] |= 1 << 2;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::TEST)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[2] |= 1 << 3;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::P1_START)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[10] |= 1 << 7;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::P1_MENU_UP)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[10] |= 1 << 6;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::P1_MENU_DOWN)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[10] |= 1 << 5;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::P1_MENU_LEFT)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[10] |= 1 << 4;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::P1_MENU_RIGHT)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[10] |= 1 << 3;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::P2_START)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[11] |= 1 << 5;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::P2_MENU_UP)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[11] |= 1 << 4;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::P2_MENU_DOWN)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[11] |= 1 << 3;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::P2_MENU_LEFT)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[11] |= 1 << 2;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ddr::Buttons::P2_MENU_RIGHT)) == Buttons::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[11] |= 1 << 1;
|
||||
}
|
||||
}
|
||||
|
||||
// DANCERUSH
|
||||
if (avs::game::is_model("REC")) {
|
||||
|
||||
// clear buffer
|
||||
memset(STATUS_BUFFER, 0, std::size(STATUS_BUFFER));
|
||||
STATUS_BUFFER[0] = 1;
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::drs::get_buttons();
|
||||
|
||||
// test
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::Test)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 19);
|
||||
}
|
||||
|
||||
// service
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::Service)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 18);
|
||||
}
|
||||
|
||||
// coin
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::CoinMech)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 17);
|
||||
}
|
||||
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::P1_Start)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 87);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::P1_Up)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 86);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::P1_Down)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 85);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::P1_Left)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 84);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::P1_Right)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 83);
|
||||
}
|
||||
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::P2_Start)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 93);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::P2_Up)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 92);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::P2_Down)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 91);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::P2_Left)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 90);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::drs::Buttons::P2_Right)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 89);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_current_coinstock(size_t index, DWORD *coins) {
|
||||
|
||||
// check index
|
||||
if (index > 1)
|
||||
return false;
|
||||
|
||||
// get coins and return success
|
||||
*coins = (DWORD) eamuse_coin_get_stock();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_consume_coinstock(size_t index, int amount) {
|
||||
|
||||
// check index
|
||||
if (index > 1)
|
||||
return false;
|
||||
|
||||
// calculate new stock
|
||||
auto stock = eamuse_coin_get_stock();
|
||||
auto stock_new = stock - amount;
|
||||
|
||||
// check new stock
|
||||
if (stock_new < 0)
|
||||
return false;
|
||||
|
||||
// apply new stock
|
||||
eamuse_coin_set_stock(stock_new);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_lock_coincounter(size_t index) {
|
||||
|
||||
// check index
|
||||
if (index > 1)
|
||||
return false;
|
||||
|
||||
// enable coin blocker
|
||||
eamuse_coin_set_block(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_unlock_coincounter(size_t index) {
|
||||
|
||||
// check index
|
||||
if (index > 1)
|
||||
return false;
|
||||
|
||||
// disable coin blocker
|
||||
eamuse_coin_set_block(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_bi2a_control_coin_blocker_close(size_t index) {
|
||||
|
||||
// check index
|
||||
if (index > 1)
|
||||
return;
|
||||
|
||||
// enable coin blocker
|
||||
eamuse_coin_set_block(true);
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_bi2a_control_coin_blocker_open(size_t index) {
|
||||
|
||||
// check index
|
||||
if (index > 1)
|
||||
return;
|
||||
|
||||
// disable coin blocker
|
||||
eamuse_coin_set_block(false);
|
||||
}
|
||||
|
||||
static long __cdecl ac_io_bi2a_control_led_bright(size_t index, uint8_t brightness) {
|
||||
|
||||
// Sound Voltex
|
||||
if (avs::game::is_model("KFC")) {
|
||||
|
||||
/*
|
||||
* Control R G B
|
||||
* =======================
|
||||
* WING UP 28 29 30
|
||||
* WING LOW 31 32 33
|
||||
* WOOFER 0 1 3
|
||||
* CONTROLLER 4 5 6
|
||||
*
|
||||
* Values go up to 255.
|
||||
*
|
||||
*
|
||||
* Control Index
|
||||
* ==================
|
||||
* START BUTTON 8
|
||||
* A BUTTON 9
|
||||
* B BUTTON 10
|
||||
* C BUTTON 11
|
||||
* D BUTTON 12
|
||||
* FX L BUTTON 13
|
||||
* FX R BUTTON 14
|
||||
* POP 24
|
||||
* TITLE LEFT 25
|
||||
* TITLE RIGHT 26
|
||||
*
|
||||
* Values go up to 127.
|
||||
*/
|
||||
|
||||
static const struct {
|
||||
int light1, light2;
|
||||
float max;
|
||||
} mapping[] = {
|
||||
{ games::sdvx::Lights::WOOFER_R, -1, 255 },
|
||||
{ games::sdvx::Lights::WOOFER_G, -1, 255 },
|
||||
{ -1, -1, 0 },
|
||||
{ games::sdvx::Lights::WOOFER_B, -1, 255 },
|
||||
{ games::sdvx::Lights::CONTROLLER_R, -1, 255 },
|
||||
{ games::sdvx::Lights::CONTROLLER_G, -1, 255 },
|
||||
{ games::sdvx::Lights::CONTROLLER_B, -1, 255 },
|
||||
{ -1, -1, 0 },
|
||||
{ games::sdvx::Lights::START, -1, 127 },
|
||||
{ games::sdvx::Lights::BT_A, -1, 127 },
|
||||
{ games::sdvx::Lights::BT_B, -1, 127 },
|
||||
{ games::sdvx::Lights::BT_C, -1, 127 },
|
||||
{ games::sdvx::Lights::BT_D, -1, 127 },
|
||||
{ games::sdvx::Lights::FX_L, -1, 127 },
|
||||
{ games::sdvx::Lights::FX_R, -1, 127 },
|
||||
{ -1, -1, 0 }, { -1, -1, 0 }, { -1, -1, 0 },
|
||||
{ games::sdvx::Lights::GENERATOR_R, -1, 255 },
|
||||
{ games::sdvx::Lights::GENERATOR_G, -1, 255 },
|
||||
{ games::sdvx::Lights::GENERATOR_B, -1, 255 },
|
||||
{ -1, -1, 0 }, { -1, -1, 0 }, { -1, -1, 0 },
|
||||
{ games::sdvx::Lights::POP, -1, 127 },
|
||||
{ games::sdvx::Lights::TITLE_LEFT, -1, 127 },
|
||||
{ games::sdvx::Lights::TITLE_RIGHT, -1, 127 },
|
||||
{ -1, -1, 0 },
|
||||
{ games::sdvx::Lights::WING_RIGHT_UP_R, games::sdvx::Lights::WING_LEFT_UP_R, 255 },
|
||||
{ games::sdvx::Lights::WING_RIGHT_UP_G, games::sdvx::Lights::WING_LEFT_UP_G, 255 },
|
||||
{ games::sdvx::Lights::WING_RIGHT_UP_B, games::sdvx::Lights::WING_LEFT_UP_B, 255 },
|
||||
{ games::sdvx::Lights::WING_RIGHT_LOW_R, games::sdvx::Lights::WING_LEFT_LOW_R, 255 },
|
||||
{ games::sdvx::Lights::WING_RIGHT_LOW_G, games::sdvx::Lights::WING_LEFT_LOW_G, 255 },
|
||||
{ games::sdvx::Lights::WING_RIGHT_LOW_B, games::sdvx::Lights::WING_LEFT_LOW_B, 255 },
|
||||
};
|
||||
|
||||
// ignore index out of range
|
||||
if (index > std::size(mapping)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// get lights
|
||||
auto &lights = games::sdvx::get_lights();
|
||||
|
||||
// get light from mapping
|
||||
auto light = mapping[index];
|
||||
|
||||
// write lights
|
||||
if (light.light1 >= 0) {
|
||||
Lights::writeLight(RI_MGR, lights[light.light1], brightness / light.max);
|
||||
} else {
|
||||
log_warning("sdvx", "light unset {} {}", index, (int) brightness);
|
||||
}
|
||||
if (light.light2 >= 0) {
|
||||
Lights::writeLight(RI_MGR, lights[light.light2], brightness / light.max);
|
||||
}
|
||||
|
||||
// DANCERUSH
|
||||
} else if (avs::game::is_model("REC")) {
|
||||
|
||||
/*
|
||||
* Control R G B
|
||||
* ==============================
|
||||
* CARD UNIT 13 14 15
|
||||
* TITLE PANEL 28 29 30
|
||||
* MONITOR SIDE LEFT (tape LED - see ac_io_bi2a_control_tapeled_bright)
|
||||
* MONITOR SIDE RIGHT (tape LED - see ac_io_bi2a_control_tapeled_bright)
|
||||
*
|
||||
* Values go up to 127.
|
||||
*
|
||||
* Control Index
|
||||
* ==================
|
||||
* 1P LEFT 11
|
||||
* 1P RIGHT 12
|
||||
* 1P UP 9
|
||||
* 1P DOWN 10
|
||||
* 1P START 8
|
||||
* 2P LEFT 19
|
||||
* 2P RIGHT 20
|
||||
* 2P UP 17
|
||||
* 2P DOWN 18
|
||||
* 2P START 16
|
||||
*
|
||||
* Values go up to 127.
|
||||
*/
|
||||
|
||||
static const struct {
|
||||
int light;
|
||||
float max;
|
||||
} mapping[] = {
|
||||
{ -1, 0 }, // 0
|
||||
{ -1, 0 }, // 1
|
||||
{ -1, 0 }, // 2
|
||||
{ -1, 0 }, // 3
|
||||
{ -1, 0 }, // 4
|
||||
{ -1, 0 }, // 5
|
||||
{ -1, 0 }, // 6
|
||||
{ -1, 0 }, // 7
|
||||
{ games::drs::Lights::P1_START, 127 }, // 8
|
||||
{ games::drs::Lights::P1_MENU_UP, 127 }, // 9
|
||||
{ games::drs::Lights::P1_MENU_DOWN, 127 }, // 10
|
||||
{ games::drs::Lights::P1_MENU_LEFT, 127 }, // 11
|
||||
{ games::drs::Lights::P1_MENU_RIGHT, 127 }, // 12
|
||||
{ games::drs::Lights::CARD_READER_R, 127 }, // 13
|
||||
{ games::drs::Lights::CARD_READER_G, 127 }, // 14
|
||||
{ games::drs::Lights::CARD_READER_B, 127 }, // 15
|
||||
{ games::drs::Lights::P2_START, 127 }, // 16
|
||||
{ games::drs::Lights::P2_MENU_UP, 127 }, // 17
|
||||
{ games::drs::Lights::P2_MENU_DOWN, 127 }, // 18
|
||||
{ games::drs::Lights::P2_MENU_LEFT, 127 }, // 19
|
||||
{ games::drs::Lights::P2_MENU_RIGHT, 127 }, // 20
|
||||
{ -1, 0 }, // 21
|
||||
{ -1, 0 }, // 22
|
||||
{ -1, 0 }, // 23
|
||||
{ -1, 0 }, // 24
|
||||
{ -1, 0 }, // 25
|
||||
{ -1, 0 }, // 26
|
||||
{ -1, 0 }, // 27
|
||||
{ games::drs::Lights::TITLE_PANEL_R, 127 }, // 28
|
||||
{ games::drs::Lights::TITLE_PANEL_G, 127 }, // 29
|
||||
{ games::drs::Lights::TITLE_PANEL_B, 127 }, // 30
|
||||
};
|
||||
|
||||
// ignore index out of range
|
||||
if (index > std::size(mapping)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// get lights
|
||||
auto &lights = games::drs::get_lights();
|
||||
|
||||
// get light from mapping
|
||||
auto light = mapping[index];
|
||||
|
||||
// write lights
|
||||
if (light.light >= 0) {
|
||||
Lights::writeLight(RI_MGR, lights[light.light], brightness / light.max);
|
||||
} else {
|
||||
log_warning("drs", "light unset {} {}", index, (int) brightness);
|
||||
}
|
||||
|
||||
// DanceDanceRevolution
|
||||
} else if (avs::game::is_model("MDX")) {
|
||||
|
||||
static const struct {
|
||||
int light;
|
||||
float max;
|
||||
} mapping[] = {
|
||||
{ -1, 0 }, // 0
|
||||
{ -1, 0 }, // 1
|
||||
{ -1, 0 }, // 2
|
||||
{ -1, 0 }, // 3
|
||||
{ -1, 0 }, // 4
|
||||
{ -1, 0 }, // 5
|
||||
{ -1, 0 }, // 6
|
||||
{ -1, 0 }, // 7
|
||||
{ games::ddr::Lights::GOLD_P1_MENU_START, 127 }, // 8
|
||||
{ games::ddr::Lights::GOLD_P1_MENU_UP, 127 }, // 9
|
||||
{ games::ddr::Lights::GOLD_P1_MENU_DOWN, 127 }, // 10
|
||||
{ games::ddr::Lights::GOLD_P1_MENU_LEFT, 127 }, // 11
|
||||
{ games::ddr::Lights::GOLD_P1_MENU_RIGHT, 127 }, // 12
|
||||
{ games::ddr::Lights::GOLD_P1_CARD_UNIT_R, 127 }, // 13
|
||||
{ games::ddr::Lights::GOLD_P1_CARD_UNIT_G, 127 }, // 14
|
||||
{ games::ddr::Lights::GOLD_P1_CARD_UNIT_B, 127 }, // 15
|
||||
{ games::ddr::Lights::GOLD_P2_MENU_START, 127 }, // 16
|
||||
{ games::ddr::Lights::GOLD_P2_MENU_UP, 127 }, // 17
|
||||
{ games::ddr::Lights::GOLD_P2_MENU_DOWN, 127 }, // 18
|
||||
{ games::ddr::Lights::GOLD_P2_MENU_LEFT, 127 }, // 19
|
||||
{ games::ddr::Lights::GOLD_P2_MENU_RIGHT, 127 }, // 20
|
||||
{ games::ddr::Lights::GOLD_P2_CARD_UNIT_R, 0 }, // 21
|
||||
{ games::ddr::Lights::GOLD_P2_CARD_UNIT_G, 0 }, // 22
|
||||
{ games::ddr::Lights::GOLD_P2_CARD_UNIT_B, 0 }, // 23
|
||||
{ -1, 0 }, // 24
|
||||
{ -1, 0 }, // 25
|
||||
{ -1, 0 }, // 26
|
||||
{ -1, 0 }, // 27
|
||||
{ games::ddr::Lights::GOLD_TITLE_PANEL_LEFT, 0 }, // 28
|
||||
{ games::ddr::Lights::GOLD_TITLE_PANEL_CENTER, 0 }, // 29
|
||||
{ games::ddr::Lights::GOLD_TITLE_PANEL_RIGHT, 0 }, // 30
|
||||
{ games::ddr::Lights::GOLD_P1_WOOFER_CORNER, 0 }, // 31
|
||||
{ games::ddr::Lights::GOLD_P2_WOOFER_CORNER, 0 } // 32
|
||||
};
|
||||
|
||||
// ignore index out of range
|
||||
if (index > std::size(mapping)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// get lights
|
||||
auto &lights = games::ddr::get_lights();
|
||||
|
||||
// get light from mapping
|
||||
auto light = mapping[index];
|
||||
|
||||
// write lights
|
||||
if (light.light >= 0) {
|
||||
Lights::writeLight(RI_MGR, lights[light.light], brightness / light.max);
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return true;
|
||||
}
|
||||
|
||||
static long __cdecl ac_io_bi2a_get_watchdog_time_min() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static long __cdecl ac_io_bi2a_get_watchdog_time_now() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_bi2a_watchdog_off() {
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_init(uint8_t param) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_set_watchdog_time(uint16_t time) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_get_watchdog_status() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_set_amp_volume(uint8_t a1, uint8_t a2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_tapeled_init(uint8_t a1, uint8_t a2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_tapeled_init_is_finished() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_control_tapeled_rec_set(uint8_t* data, size_t x_sz, size_t y_sz) {
|
||||
|
||||
// check dimensions
|
||||
if (x_sz != 38 || y_sz != 49) {
|
||||
log_fatal("drs", "DRS tapeled wrong dimensions");
|
||||
}
|
||||
|
||||
// copy data into our buffer - 4 bytes per pixel BGR
|
||||
for (size_t i = 0; i < x_sz * y_sz; i++) {
|
||||
games::drs::DRS_TAPELED[i][0] = data[i*4+2];
|
||||
games::drs::DRS_TAPELED[i][1] = data[i*4+1];
|
||||
games::drs::DRS_TAPELED[i][2] = data[i*4];
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: DRS tape lights
|
||||
static bool __cdecl ac_io_bi2a_control_tapeled_bright(size_t off1, size_t off2,
|
||||
uint8_t r, uint8_t g, uint8_t b, uint8_t bank) {
|
||||
|
||||
if (!tapeledutils::is_enabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (avs::game::is_model("MDX")) {
|
||||
|
||||
/*
|
||||
* r, g, b values range from [0-255]
|
||||
* bank always seems to be [0]
|
||||
*
|
||||
* [off1.off2] [LEDs] [tape name]
|
||||
* 0.0 25 P1 Foot Up (0.0 to 0.24, inclusive)
|
||||
* 0.25 25 P1 Foot Right
|
||||
* 1.0 25 P1 Foot Left
|
||||
* 1.25 25 P1 Foot Down
|
||||
*
|
||||
* 2.0 25 P2 Foot Up
|
||||
* 2.25 25 P2 Foot Right
|
||||
* 3.0 25 P2 Foot Left
|
||||
* 3.25 25 P2 Foot Down
|
||||
*
|
||||
* 5.0 50 Top Panel
|
||||
* 6.0 50 Monitor side left
|
||||
* 7.0 50 Monitor side right
|
||||
*/
|
||||
|
||||
static struct TapeLedMapping {
|
||||
bool split; // true == 50 LEDs for one light, false == 25 for two lights
|
||||
uint8_t index_r0, index_g0, index_b0;
|
||||
uint8_t index_r1, index_g1, index_b1;
|
||||
size_t index_for_avg0 = UINT8_MAX;
|
||||
size_t index_for_avg1 = UINT8_MAX;
|
||||
|
||||
TapeLedMapping(
|
||||
uint8_t index_r0, uint8_t index_g0, uint8_t index_b0,
|
||||
uint8_t index_r1, uint8_t index_g1, uint8_t index_b1)
|
||||
: index_r0(index_r0), index_g0(index_g0), index_b0(index_b0),
|
||||
index_r1(index_r1), index_g1(index_g1), index_b1(index_b1) {
|
||||
|
||||
split = (index_r1 != UINT8_MAX);
|
||||
if (split) {
|
||||
index_for_avg0 = tapeledutils::get_led_index_using_avg_algo(25);
|
||||
index_for_avg1 = index_for_avg0 + 25;
|
||||
} else {
|
||||
index_for_avg0 = tapeledutils::get_led_index_using_avg_algo(50);
|
||||
index_for_avg1 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
} mapping[] = {
|
||||
{
|
||||
games::ddr::Lights::GOLD_P1_FOOT_UP_AVG_R, games::ddr::Lights::GOLD_P1_FOOT_UP_AVG_G, games::ddr::Lights::GOLD_P1_FOOT_UP_AVG_B,
|
||||
games::ddr::Lights::GOLD_P1_FOOT_RIGHT_AVG_R, games::ddr::Lights::GOLD_P1_FOOT_RIGHT_AVG_G, games::ddr::Lights::GOLD_P1_FOOT_RIGHT_AVG_B
|
||||
},
|
||||
{
|
||||
games::ddr::Lights::GOLD_P1_FOOT_LEFT_AVG_R, games::ddr::Lights::GOLD_P1_FOOT_LEFT_AVG_G, games::ddr::Lights::GOLD_P1_FOOT_LEFT_AVG_B,
|
||||
games::ddr::Lights::GOLD_P1_FOOT_DOWN_AVG_R, games::ddr::Lights::GOLD_P1_FOOT_DOWN_AVG_G, games::ddr::Lights::GOLD_P1_FOOT_DOWN_AVG_B
|
||||
},
|
||||
{
|
||||
games::ddr::Lights::GOLD_P2_FOOT_UP_AVG_R, games::ddr::Lights::GOLD_P2_FOOT_UP_AVG_G, games::ddr::Lights::GOLD_P2_FOOT_UP_AVG_B,
|
||||
games::ddr::Lights::GOLD_P2_FOOT_RIGHT_AVG_R, games::ddr::Lights::GOLD_P2_FOOT_RIGHT_AVG_G, games::ddr::Lights::GOLD_P2_FOOT_RIGHT_AVG_B
|
||||
},
|
||||
{
|
||||
games::ddr::Lights::GOLD_P2_FOOT_LEFT_AVG_R, games::ddr::Lights::GOLD_P2_FOOT_LEFT_AVG_G, games::ddr::Lights::GOLD_P2_FOOT_LEFT_AVG_B,
|
||||
games::ddr::Lights::GOLD_P2_FOOT_DOWN_AVG_R, games::ddr::Lights::GOLD_P2_FOOT_DOWN_AVG_G, games::ddr::Lights::GOLD_P2_FOOT_DOWN_AVG_B
|
||||
},
|
||||
{
|
||||
games::ddr::Lights::GOLD_TOP_PANEL_AVG_R, games::ddr::Lights::GOLD_TOP_PANEL_AVG_G, games::ddr::Lights::GOLD_TOP_PANEL_AVG_B,
|
||||
UINT8_MAX, UINT8_MAX, UINT8_MAX
|
||||
},
|
||||
{
|
||||
UINT8_MAX, UINT8_MAX, UINT8_MAX,
|
||||
UINT8_MAX, UINT8_MAX, UINT8_MAX
|
||||
},
|
||||
{
|
||||
games::ddr::Lights::GOLD_MONITOR_SIDE_LEFT_AVG_R, games::ddr::Lights::GOLD_MONITOR_SIDE_LEFT_AVG_G, games::ddr::Lights::GOLD_MONITOR_SIDE_LEFT_AVG_B,
|
||||
UINT8_MAX, UINT8_MAX, UINT8_MAX
|
||||
},
|
||||
{
|
||||
games::ddr::Lights::GOLD_MONITOR_SIDE_RIGHT_AVG_R, games::ddr::Lights::GOLD_MONITOR_SIDE_RIGHT_AVG_G, games::ddr::Lights::GOLD_MONITOR_SIDE_RIGHT_AVG_B,
|
||||
UINT8_MAX, UINT8_MAX, UINT8_MAX
|
||||
},
|
||||
};
|
||||
|
||||
if (off1 < std::size(mapping)) {
|
||||
auto &map = mapping[off1];
|
||||
|
||||
size_t off2_match = -1;
|
||||
if (!map.split || off2 < 25) {
|
||||
off2_match = map.index_for_avg0;
|
||||
} else {
|
||||
off2_match = map.index_for_avg1;
|
||||
}
|
||||
if (off2_match == off2 && map.index_r0 != UINT8_MAX) {
|
||||
auto &lights = games::ddr::get_lights();
|
||||
if (!map.split || off2 < 25) {
|
||||
Lights::writeLight(RI_MGR, lights[map.index_r0], r / 255.f);
|
||||
Lights::writeLight(RI_MGR, lights[map.index_g0], g / 255.f);
|
||||
Lights::writeLight(RI_MGR, lights[map.index_b0], b / 255.f);
|
||||
} else {
|
||||
Lights::writeLight(RI_MGR, lights[map.index_r1], r / 255.f);
|
||||
Lights::writeLight(RI_MGR, lights[map.index_g1], g / 255.f);
|
||||
Lights::writeLight(RI_MGR, lights[map.index_b1], b / 255.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bi2a_tapeled_send() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_bi2a_get_exbio2_status(uint8_t *info) {
|
||||
// surely this meme never gets old
|
||||
info[5] = 5;
|
||||
info[6] = 7;
|
||||
info[7] = 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
acio::BI2AModule::BI2AModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("BI2A", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::BI2AModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_init_is_finished);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_update_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_current_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_consume_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_lock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_unlock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_control_coin_blocker_close);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_control_coin_blocker_open);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_control_led_bright);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_get_watchdog_time_min);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_get_watchdog_time_now);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_watchdog_off);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_init);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_set_watchdog_time);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_get_watchdog_status);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_set_amp_volume);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_tapeled_init);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_tapeled_init_is_finished);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_get_exbio2_status);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_control_tapeled_rec_set);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_control_tapeled_bright);
|
||||
ACIO_MODULE_HOOK(ac_io_bi2a_tapeled_send);
|
||||
}
|
||||
13
acio/bi2a/bi2a.h
Normal file
13
acio/bi2a/bi2a.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class BI2AModule : public ACIOModule {
|
||||
public:
|
||||
BI2AModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
596
acio/bmpu/bmpu.cpp
Normal file
596
acio/bmpu/bmpu.cpp
Normal file
@@ -0,0 +1,596 @@
|
||||
#include "bmpu.h"
|
||||
|
||||
#include "acio/icca/icca.h"
|
||||
#include "avs/game.h"
|
||||
#include "cfg/api.h"
|
||||
#include "cfg/light.h"
|
||||
#include "games/bbc/io.h"
|
||||
#include "games/dea/io.h"
|
||||
#include "games/ftt/io.h"
|
||||
#include "games/museca/io.h"
|
||||
#include "games/silentscope/io.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "misc/eamuse.h"
|
||||
|
||||
using namespace GameAPI;
|
||||
|
||||
// state
|
||||
static uint8_t STATUS_BUFFER[64] {};
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static char __cdecl ac_io_bmpu_consume_coinstock(int a1, int a2) {
|
||||
eamuse_coin_consume_stock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_bmpu_control_1p_start_led_off() {
|
||||
|
||||
// dance evolution
|
||||
if (avs::game::is_model("KDM")) {
|
||||
auto &lights = games::dea::get_lights();
|
||||
Lights::writeLight(RI_MGR, lights.at(games::dea::Lights::P1Start), 0.f);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_bmpu_control_1p_start_led_on() {
|
||||
|
||||
// dance evolution
|
||||
if (avs::game::is_model("KDM")) {
|
||||
auto &lights = games::dea::get_lights();
|
||||
Lights::writeLight(RI_MGR, lights.at(games::dea::Lights::P1Start), 1.f);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_bmpu_control_2p_start_led_off() {
|
||||
|
||||
// dance evolution
|
||||
if (avs::game::is_model("KDM")) {
|
||||
auto &lights = games::dea::get_lights();
|
||||
Lights::writeLight(RI_MGR, lights.at(games::dea::Lights::P2Start), 0.f);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_bmpu_control_2p_start_led_on() {
|
||||
|
||||
// dance evolution
|
||||
if (avs::game::is_model("KDM")) {
|
||||
auto &lights = games::dea::get_lights();
|
||||
Lights::writeLight(RI_MGR, lights.at(games::dea::Lights::P2Start), 1.f);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_bmpu_control_coin_blocker_close() {
|
||||
eamuse_coin_set_block(true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_bmpu_control_coin_blocker_open() {
|
||||
eamuse_coin_set_block(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bmpu_control_led_bright(uint32_t led_field, uint8_t brightness) {
|
||||
|
||||
// MUSECA
|
||||
if (avs::game::is_model("PIX")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::museca::get_lights();
|
||||
|
||||
// control mapping
|
||||
static const int mapping[] = {
|
||||
games::museca::Lights::UnderLED3G,
|
||||
games::museca::Lights::UnderLED3R,
|
||||
games::museca::Lights::UnderLED2B,
|
||||
games::museca::Lights::UnderLED2G,
|
||||
games::museca::Lights::UnderLED2R,
|
||||
games::museca::Lights::UnderLED1B,
|
||||
games::museca::Lights::UnderLED1G,
|
||||
games::museca::Lights::UnderLED1R,
|
||||
-1, -1, -1, -1,
|
||||
games::museca::Lights::SideB,
|
||||
games::museca::Lights::SideG,
|
||||
games::museca::Lights::SideR,
|
||||
games::museca::Lights::UnderLED3B,
|
||||
};
|
||||
|
||||
// write light
|
||||
float value = brightness > 127.f ? 1.f : brightness / 127.f;
|
||||
for (size_t i = 0; i < std::size(mapping); i++) {
|
||||
if (mapping[i] >= 0 && led_field & (1 << i)) {
|
||||
Lights::writeLight(RI_MGR, lights.at((size_t) mapping[i]), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BISHI BASHI CHANNEL
|
||||
if (avs::game::is_model("R66")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::bbc::get_lights();
|
||||
|
||||
// control mapping
|
||||
static int mapping[] = {
|
||||
games::bbc::Lights::UNDER_LED3_G,
|
||||
games::bbc::Lights::UNDER_LED3_R,
|
||||
games::bbc::Lights::UNDER_LED2_B,
|
||||
games::bbc::Lights::UNDER_LED2_G,
|
||||
games::bbc::Lights::UNDER_LED2_R,
|
||||
games::bbc::Lights::UNDER_LED1_B,
|
||||
games::bbc::Lights::UNDER_LED1_G,
|
||||
games::bbc::Lights::UNDER_LED1_R,
|
||||
-1, -1, -1, -1,
|
||||
games::bbc::Lights::IC_CARD_B,
|
||||
games::bbc::Lights::IC_CARD_G,
|
||||
games::bbc::Lights::IC_CARD_R,
|
||||
games::bbc::Lights::UNDER_LED3_B,
|
||||
};
|
||||
|
||||
// write light
|
||||
float value = brightness > 127.f ? 1.f : brightness / 127.f;
|
||||
for (size_t i = 0; i < std::size(mapping); i++) {
|
||||
if (mapping[i] >= 0 && led_field & (1 << i)) {
|
||||
Lights::writeLight(RI_MGR, lights.at((size_t) mapping[i]), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FutureTomTom
|
||||
if (avs::game::is_model("MMD")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::ftt::get_lights();
|
||||
|
||||
// control mapping
|
||||
static int mapping[] = {
|
||||
games::ftt::Lights::Pad3_G,
|
||||
games::ftt::Lights::Pad3_R,
|
||||
games::ftt::Lights::Pad2_B,
|
||||
games::ftt::Lights::Pad2_G,
|
||||
games::ftt::Lights::Pad2_R,
|
||||
games::ftt::Lights::Pad1_B,
|
||||
games::ftt::Lights::Pad1_G,
|
||||
games::ftt::Lights::Pad1_R,
|
||||
-1, -1, -1, -1,
|
||||
games::ftt::Lights::Pad4_B,
|
||||
games::ftt::Lights::Pad4_G,
|
||||
games::ftt::Lights::Pad4_R,
|
||||
games::ftt::Lights::Pad3_B,
|
||||
};
|
||||
|
||||
// write light
|
||||
float value = brightness > 127.f ? 1.f : brightness / 127.f;
|
||||
for (size_t i = 0; i < std::size(mapping); i++) {
|
||||
if (mapping[i] >= 0 && led_field & (1 << i)) {
|
||||
Lights::writeLight(RI_MGR, lights.at((size_t) mapping[i]), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dance Evolution
|
||||
if (avs::game::is_model("KDM")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::dea::get_lights();
|
||||
|
||||
// control mapping
|
||||
static int mapping[] = {
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
games::dea::Lights::P2LRButton,
|
||||
games::dea::Lights::P1LRButton,
|
||||
-1,
|
||||
games::dea::Lights::TitleB,
|
||||
games::dea::Lights::TitleR,
|
||||
games::dea::Lights::TitleG,
|
||||
-1,
|
||||
};
|
||||
|
||||
// write light
|
||||
float value = brightness > 128.f ? 1.f : brightness / 128.f;
|
||||
for (size_t i = 0; i < std::size(mapping); i++)
|
||||
if (mapping[i] >= 0 && led_field & (1 << i)) {
|
||||
Lights::writeLight(RI_MGR, lights.at((size_t) mapping[i]), value);
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bmpu_control_led_bright_pack(int a1, int a2, int a3) {
|
||||
// TODO(felix): NDD lights
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bmpu_create_get_status_thread() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_bmpu_current_coinstock(int a1, int *a2) {
|
||||
*a2 = eamuse_coin_get_stock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bmpu_destroy_get_status_thread() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_bmpu_get_control_status_buffer(void *buffer) {
|
||||
size_t buffer_len = 0;
|
||||
|
||||
if (avs::game::is_model({ "KDM", "MMD" })) {
|
||||
buffer_len = sizeof(STATUS_BUFFER);
|
||||
} else if (avs::game::is_model("PIX")) {
|
||||
buffer_len = 16;
|
||||
} else if (avs::game::is_model("R66")) {
|
||||
buffer_len = 56;
|
||||
} else if (avs::game::is_model("NDD")) {
|
||||
buffer_len = 56;
|
||||
}
|
||||
|
||||
if (buffer_len > 0) {
|
||||
memcpy(buffer, &STATUS_BUFFER, buffer_len);
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
static char *__cdecl ac_io_bmpu_get_softwareid(char *a1) {
|
||||
*a1 = 0;
|
||||
return a1;
|
||||
}
|
||||
|
||||
static char *__cdecl ac_io_bmpu_get_systemid(char *a1) {
|
||||
*a1 = 0;
|
||||
return a1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_bmpu_init_outport() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_bmpu_lock_coincounter(signed int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_bmpu_req_secplug_check_isfinished(DWORD *a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_bmpu_req_secplug_check_softwareplug(char *a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_bmpu_req_secplug_check_systemplug() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_bmpu_req_secplug_missing_check() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_bmpu_req_secplug_missing_check_isfinished(DWORD *a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_bmpu_set_outport_led(uint8_t *data1, uint8_t *data2) {
|
||||
|
||||
// dance evolution
|
||||
if (avs::game::is_model("KDM")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::dea::get_lights();
|
||||
|
||||
// mapping
|
||||
static const size_t mapping[] {
|
||||
games::dea::Lights::SideUpperLeftR,
|
||||
games::dea::Lights::SideUpperLeftG,
|
||||
games::dea::Lights::SideUpperLeftB,
|
||||
games::dea::Lights::SideLowerLeft1R,
|
||||
games::dea::Lights::SideLowerLeft1G,
|
||||
games::dea::Lights::SideLowerLeft1B,
|
||||
games::dea::Lights::SideLowerLeft2R,
|
||||
games::dea::Lights::SideLowerLeft2G,
|
||||
games::dea::Lights::SideLowerLeft2B,
|
||||
games::dea::Lights::SideLowerLeft3R,
|
||||
games::dea::Lights::SideLowerLeft3G,
|
||||
games::dea::Lights::SideLowerLeft3B,
|
||||
games::dea::Lights::SideUpperRightR,
|
||||
games::dea::Lights::SideUpperRightG,
|
||||
games::dea::Lights::SideUpperRightB,
|
||||
games::dea::Lights::SideLowerRight1R,
|
||||
games::dea::Lights::SideLowerRight1G,
|
||||
games::dea::Lights::SideLowerRight1B,
|
||||
games::dea::Lights::SideLowerRight2R,
|
||||
games::dea::Lights::SideLowerRight2G,
|
||||
games::dea::Lights::SideLowerRight2B,
|
||||
games::dea::Lights::SideLowerRight3R,
|
||||
games::dea::Lights::SideLowerRight3G,
|
||||
games::dea::Lights::SideLowerRight3B,
|
||||
};
|
||||
|
||||
// write lights
|
||||
for (size_t i = 0; i < std::size(mapping); i++) {
|
||||
float brightness = data1[i * 2] / 255.f;
|
||||
Lights::writeLight(RI_MGR, lights.at(mapping[i]), brightness);
|
||||
}
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_bmpu_set_output_mode(__int16 a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_bmpu_unlock_coincounter(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bmpu_update_control_status_buffer() {
|
||||
unsigned int control_data = 0;
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// DEA
|
||||
if (avs::game::is_model("KDM")) {
|
||||
|
||||
// keypad mirror fix
|
||||
acio::ICCA_FLIP_ROWS = true;
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::dea::get_buttons();
|
||||
|
||||
// get control data
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::dea::Buttons::Test))) {
|
||||
control_data |= 0xF0000000;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::dea::Buttons::Service))) {
|
||||
control_data |= 0x0F000000;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::dea::Buttons::P1Start))) {
|
||||
control_data |= 0x00000001;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::dea::Buttons::P1Left))) {
|
||||
control_data |= 0x00000008;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::dea::Buttons::P1Right))) {
|
||||
control_data |= 0x00000010;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::dea::Buttons::P2Start))) {
|
||||
control_data |= 0x00000100;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::dea::Buttons::P2Left))) {
|
||||
control_data |= 0x00000800;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::dea::Buttons::P2Right))) {
|
||||
control_data |= 0x00001000;
|
||||
}
|
||||
|
||||
// set control data
|
||||
auto buffer = reinterpret_cast<unsigned int *>(STATUS_BUFFER);
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
buffer[i] = control_data;
|
||||
}
|
||||
}
|
||||
|
||||
// FutureTomTom
|
||||
if (avs::game::is_model("MMD")) {
|
||||
|
||||
// keypad mirror fix
|
||||
acio::ICCA_FLIP_ROWS = true;
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::ftt::get_buttons();
|
||||
|
||||
// get control data
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ftt::Buttons::Service))) {
|
||||
control_data |= 0x0F000000;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ftt::Buttons::Test))) {
|
||||
control_data |= 0xF0000000;
|
||||
}
|
||||
|
||||
// set control data
|
||||
auto buffer = reinterpret_cast<unsigned int *>(STATUS_BUFFER);
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
buffer[i] = control_data;
|
||||
}
|
||||
}
|
||||
|
||||
// MUSECA
|
||||
if (avs::game::is_model("PIX")) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::museca::get_buttons();
|
||||
|
||||
// get control data
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Service))) {
|
||||
control_data |= 0x0F000000;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Test))) {
|
||||
control_data |= 0xF0000000;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Start))) {
|
||||
control_data |= 0x00000001;
|
||||
}
|
||||
|
||||
// set control data
|
||||
auto buffer = reinterpret_cast<unsigned int *>(STATUS_BUFFER);
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
buffer[i] = control_data;
|
||||
}
|
||||
}
|
||||
|
||||
// BISHI BASHI CHANNEL
|
||||
if (avs::game::is_model("R66")) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::bbc::get_buttons();
|
||||
|
||||
// get control data
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::Service))) {
|
||||
control_data |= 0x0F000000;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::Test))) {
|
||||
control_data |= 0xF0000000;
|
||||
}
|
||||
|
||||
// set control data
|
||||
auto buffer = reinterpret_cast<unsigned int *>(STATUS_BUFFER);
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
buffer[i] = control_data;
|
||||
}
|
||||
}
|
||||
|
||||
// Silent Scope Bone Eater
|
||||
if (avs::game::is_model("NDD")) {
|
||||
|
||||
// clear state
|
||||
memset(STATUS_BUFFER, 0, 56);
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::silentscope::get_buttons();
|
||||
|
||||
// get control data
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::silentscope::Buttons::TEST))) {
|
||||
STATUS_BUFFER[7] |= 0x10;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::silentscope::Buttons::SERVICE))) {
|
||||
STATUS_BUFFER[7] |= 0x2;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::silentscope::Buttons::COIN_MECH))) {
|
||||
STATUS_BUFFER[7] |= 0x1;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::silentscope::Buttons::START))) {
|
||||
STATUS_BUFFER[5] |= 0x1;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::silentscope::Buttons::UP))) {
|
||||
STATUS_BUFFER[5] |= 0x2;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::silentscope::Buttons::DOWN))) {
|
||||
STATUS_BUFFER[5] |= 0x4;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::silentscope::Buttons::LEFT))) {
|
||||
STATUS_BUFFER[5] |= 0x8;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::silentscope::Buttons::RIGHT))) {
|
||||
STATUS_BUFFER[5] |= 0x10;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::silentscope::Buttons::SCOPE_RIGHT))) {
|
||||
STATUS_BUFFER[4] |= 0x80;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::silentscope::Buttons::SCOPE_LEFT))) {
|
||||
STATUS_BUFFER[4] |= 0x40;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::silentscope::Buttons::GUN_PRESSED))) {
|
||||
STATUS_BUFFER[4] |= 0x20;
|
||||
}
|
||||
|
||||
// joy stick raw input
|
||||
auto &analogs = games::silentscope::get_analogs();
|
||||
unsigned short joy_x = 0x7FFF;
|
||||
unsigned short joy_y = 0x7FFF;
|
||||
if (analogs.at(games::silentscope::Analogs::GUN_X).isSet()) {
|
||||
joy_x = (unsigned short) (Analogs::getState(RI_MGR, analogs.at(games::silentscope::Analogs::GUN_X)) * USHRT_MAX);
|
||||
}
|
||||
if (analogs.at(games::silentscope::Analogs::GUN_Y).isSet()) {
|
||||
joy_y = (unsigned short) (Analogs::getState(RI_MGR, analogs.at(games::silentscope::Analogs::GUN_Y)) * USHRT_MAX);
|
||||
}
|
||||
|
||||
// invert X axis
|
||||
joy_x = USHRT_MAX - joy_x;
|
||||
|
||||
STATUS_BUFFER[8] = HIBYTE(joy_x);
|
||||
STATUS_BUFFER[9] = LOBYTE(joy_x);
|
||||
STATUS_BUFFER[10] = HIBYTE(joy_y);
|
||||
STATUS_BUFFER[11] = LOBYTE(joy_y);
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_bmpu_set_watchdog_time(char a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_bmpu_get_watchdog_time_min() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_bmpu_get_watchdog_time_now() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_bmpu_watchdog_off() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::BMPUModule::BMPUModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("BMPU", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::BMPUModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_consume_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_control_1p_start_led_off);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_control_1p_start_led_on);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_control_2p_start_led_off);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_control_2p_start_led_on);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_control_coin_blocker_close);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_control_coin_blocker_open);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_control_led_bright);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_control_led_bright_pack);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_create_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_current_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_destroy_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_get_softwareid);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_get_systemid);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_init_outport);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_lock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_req_secplug_check_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_req_secplug_check_softwareplug);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_req_secplug_check_systemplug);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_req_secplug_missing_check);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_req_secplug_missing_check_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_set_outport_led);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_set_output_mode);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_unlock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_update_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_set_watchdog_time);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_get_watchdog_time_min);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_get_watchdog_time_now);
|
||||
ACIO_MODULE_HOOK(ac_io_bmpu_watchdog_off);
|
||||
}
|
||||
13
acio/bmpu/bmpu.h
Normal file
13
acio/bmpu/bmpu.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class BMPUModule : public ACIOModule {
|
||||
public:
|
||||
BMPUModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
190
acio/core/core.cpp
Normal file
190
acio/core/core.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
#include "core.h"
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "misc/wintouchemu.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
|
||||
// static stuff
|
||||
static int ACIO_WARMUP = 0;
|
||||
static HHOOK ACIO_KB_HOOK = nullptr;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
// needed for some games to make GetAsyncKeyState() working
|
||||
static LRESULT CALLBACK ac_io_kb_hook_callback(int nCode, WPARAM wParam, LPARAM lParam) {
|
||||
CallNextHookEx(ACIO_KB_HOOK, nCode, wParam, lParam);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_begin(
|
||||
size_t dev,
|
||||
const char *ver,
|
||||
unsigned int *val,
|
||||
size_t flags,
|
||||
void *ptr,
|
||||
size_t baud)
|
||||
{
|
||||
if (ACIO_KB_HOOK == nullptr) {
|
||||
ACIO_KB_HOOK = SetWindowsHookEx(WH_KEYBOARD_LL, ac_io_kb_hook_callback, GetModuleHandle(nullptr), 0);
|
||||
}
|
||||
|
||||
// always return success
|
||||
if (val && avs::game::is_model("KFC")) {
|
||||
*val = 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_begin_get_status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_end(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_end_get_status(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *__cdecl ac_io_get_rs232c_status(char *a1, int a2) {
|
||||
return memset(a1, 0, 88);
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_get_version(uint8_t *a1, int a2) {
|
||||
|
||||
// some games have version checks
|
||||
// pop'n music only accepts versions bigger than 1.X.X (check yourself), anything starting with 2 works though
|
||||
memset(a1 + 5, 2, 1);
|
||||
memset(a1 + 6, 0, 1);
|
||||
memset(a1 + 7, 0, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *__cdecl ac_io_get_version_string() {
|
||||
static const char *version = "1.25.0";
|
||||
return version;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_is_active(int a1, int a2) {
|
||||
if (a1 == 1 && avs::game::is_model("JMA")) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return (char) (++ACIO_WARMUP > 601 ? 1 : 0);
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_is_active2(int a1, int *a2, int a3) {
|
||||
ACIO_WARMUP = 601;
|
||||
*a2 = 6;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_is_active_device(int index, int a2) {
|
||||
|
||||
// for scotto
|
||||
static bool CHECKED_24 = false;
|
||||
|
||||
// dance evolution
|
||||
if (avs::game::is_model("KDM")) {
|
||||
|
||||
// disable mysterious LED devices
|
||||
if (index >= 12 && index <= 15)
|
||||
return false;
|
||||
}
|
||||
|
||||
// scotto
|
||||
if (avs::game::is_model("NSC") && index == 24) {
|
||||
|
||||
// scotto expects device index 24 to come online after
|
||||
// it initializes device index 22
|
||||
if (!CHECKED_24) {
|
||||
CHECKED_24 = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// dunno for what game we did this again
|
||||
return (char) (index != 5);
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_reset(int a1) {
|
||||
return a1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_secplug_set_encodedpasswd(void *a1, int a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_set_soft_watch_dog(int a1, int a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_soft_watch_dog_on(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_soft_watch_dog_off() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_update(int a1) {
|
||||
|
||||
// flush device output
|
||||
RI_MGR->devices_flush_output();
|
||||
|
||||
// update wintouchemu
|
||||
wintouchemu::update();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_get_firmware_update_device_index() {
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_go_firmware_update() {
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_set_get_status_device(int a1) {
|
||||
return a1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::CoreModule::CoreModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("Core", module, hookMode) {
|
||||
}
|
||||
|
||||
void acio::CoreModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_begin);
|
||||
ACIO_MODULE_HOOK(ac_io_begin_get_status);
|
||||
ACIO_MODULE_HOOK(ac_io_end);
|
||||
ACIO_MODULE_HOOK(ac_io_end_get_status);
|
||||
ACIO_MODULE_HOOK(ac_io_get_rs232c_status);
|
||||
ACIO_MODULE_HOOK(ac_io_get_version);
|
||||
ACIO_MODULE_HOOK(ac_io_get_version_string);
|
||||
ACIO_MODULE_HOOK(ac_io_is_active);
|
||||
ACIO_MODULE_HOOK(ac_io_is_active2);
|
||||
ACIO_MODULE_HOOK(ac_io_is_active_device);
|
||||
ACIO_MODULE_HOOK(ac_io_reset);
|
||||
ACIO_MODULE_HOOK(ac_io_secplug_set_encodedpasswd);
|
||||
ACIO_MODULE_HOOK(ac_io_set_soft_watch_dog);
|
||||
ACIO_MODULE_HOOK(ac_io_soft_watch_dog_on);
|
||||
ACIO_MODULE_HOOK(ac_io_soft_watch_dog_off);
|
||||
ACIO_MODULE_HOOK(ac_io_update);
|
||||
ACIO_MODULE_HOOK(ac_io_get_firmware_update_device_index);
|
||||
ACIO_MODULE_HOOK(ac_io_go_firmware_update);
|
||||
ACIO_MODULE_HOOK(ac_io_set_get_status_device);
|
||||
}
|
||||
13
acio/core/core.h
Normal file
13
acio/core/core.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class CoreModule : public ACIOModule {
|
||||
public:
|
||||
CoreModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
565
acio/hbhi/hbhi.cpp
Normal file
565
acio/hbhi/hbhi.cpp
Normal file
@@ -0,0 +1,565 @@
|
||||
#include "hbhi.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "games/rf3d/io.h"
|
||||
#include "games/sc/io.h"
|
||||
#include "games/hpm/io.h"
|
||||
#include "avs/game.h"
|
||||
#include "util/logging.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
using namespace GameAPI;
|
||||
|
||||
// state
|
||||
static uint8_t STATUS_BUFFER[64] {};
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static int __cdecl ac_io_hbhi_add_coin(int a1, int a2) {
|
||||
eamuse_coin_add();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_consume_coinstock(int a1, int a2) {
|
||||
eamuse_coin_consume_stock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_control_coin_blocker_close(int a1) {
|
||||
eamuse_coin_set_block(true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_control_coin_blocker_open(int a1) {
|
||||
eamuse_coin_set_block(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper method, not a real ACIO one
|
||||
*/
|
||||
static inline int __cdecl ac_io_hbhi_control_lamp_set(uint32_t lamp_bits, float value) {
|
||||
|
||||
// steel chronicle
|
||||
if (avs::game::is_model("KGG")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::sc::get_lights();
|
||||
|
||||
// write lights
|
||||
if (lamp_bits & 0x01) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::sc::Lights::SideRed), value);
|
||||
}
|
||||
if (lamp_bits & 0x02) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::sc::Lights::SideGreen), value);
|
||||
}
|
||||
if (lamp_bits & 0x04) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::sc::Lights::SideBlue), value);
|
||||
}
|
||||
if (lamp_bits & 0x08) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::sc::Lights::CenterRed), value);
|
||||
}
|
||||
if (lamp_bits & 0x10) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::sc::Lights::CenterGreen), value);
|
||||
}
|
||||
if (lamp_bits & 0x20) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::sc::Lights::CenterBlue), value);
|
||||
}
|
||||
if (lamp_bits & 0x40) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::sc::Lights::ControllerRed), value);
|
||||
}
|
||||
if (lamp_bits & 0x80) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::sc::Lights::ControllerBlue), value);
|
||||
}
|
||||
}
|
||||
|
||||
// hello popn music
|
||||
if (avs::game::is_model("JMP")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::hpm::get_lights();
|
||||
|
||||
// write lights
|
||||
if (lamp_bits & 0x01) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::P1_RED_P2_GREEN), value);
|
||||
}
|
||||
if (lamp_bits & 0x02) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::P1_BLUE), value);
|
||||
}
|
||||
if (lamp_bits & 0x04) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::P1_YELLOW), value);
|
||||
}
|
||||
if (lamp_bits & 0x08) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::P1_GREEN), value);
|
||||
}
|
||||
if (lamp_bits & 0x10) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::P2_RED), value);
|
||||
}
|
||||
if (lamp_bits & 0x20) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::P2_BLUE), value);
|
||||
}
|
||||
if (lamp_bits & 0x40) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::P2_YELLOW), value);
|
||||
}
|
||||
if (lamp_bits & 0x80) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::P2_START), value);
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_hbhi_control_lamp_bright(uint32_t lamp_bits, uint8_t value) {
|
||||
ac_io_hbhi_control_lamp_set(lamp_bits, value / 31.f);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_control_lamp_mode(uint32_t mode) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_control_lamp_off(uint8_t lamp_bits) {
|
||||
return ac_io_hbhi_control_lamp_set(lamp_bits, 0.f);
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_control_lamp_on(uint8_t lamp_bits) {
|
||||
return ac_io_hbhi_control_lamp_set(lamp_bits, 1.f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper method, not a real ACIO one
|
||||
*/
|
||||
static inline int __cdecl ac_io_hbhi_control_parallel_set(uint8_t lamp_bits, float value) {
|
||||
|
||||
// hello popn music
|
||||
if (avs::game::is_model("JMP")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::hpm::get_lights();
|
||||
|
||||
// write lights
|
||||
if (lamp_bits & 0x01) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::P1_START), value);
|
||||
}
|
||||
if (lamp_bits & 0x02) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::SPEAKER_BLUE), value);
|
||||
}
|
||||
if (lamp_bits & 0x04) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::SPEAKER_ORANGE), value);
|
||||
}
|
||||
if (lamp_bits & 0x08) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(games::hpm::Lights::SPEAKER_RED), value);
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_control_parallel_off(uint8_t lamp_bits) {
|
||||
return ac_io_hbhi_control_parallel_set(lamp_bits, 0.f);
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_control_parallel_on(uint8_t lamp_bits) {
|
||||
return ac_io_hbhi_control_parallel_set(lamp_bits, 1.f);
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_control_reset() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_hbhi_create_get_status_thread(void *a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_current_coinstock(int a1, int *coinstock) {
|
||||
*coinstock = eamuse_coin_get_stock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_destroy_get_status_thread() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_get_coin_input_wave_buffer(int *a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *__cdecl ac_io_hbhi_get_control_status_buffer(uint8_t *buffer) {
|
||||
|
||||
// return buffer
|
||||
memcpy(buffer, STATUS_BUFFER, std::size(STATUS_BUFFER));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_get_softwareid(char *a1) {
|
||||
memset(a1, 'F', 16);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_get_systemid(char *a1) {
|
||||
memset(a1, 'F', 16);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_hbhi_get_watchdog_status() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static short __cdecl ac_io_hbhi_get_watchdog_time_min() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short __cdecl ac_io_hbhi_get_watchdog_time_now() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_lock_coincounter(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_req_carddispenser_disburse() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_hbhi_req_carddispenser_disburse_isfinished(int *a1) {
|
||||
*a1 += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_req_carddispenser_get_status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_req_carddispenser_get_status_isfinished(int *a1) {
|
||||
*a1 += 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_req_carddispenser_init() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_hbhi_req_carddispenser_init_isfinished(int *a1) {
|
||||
*a1 += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_req_coin_input_wave() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_req_get_control_status(int *a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_req_secplug_check(char *a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_hbhi_req_secplug_check_isfinished(int *a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_req_secplug_check_softwareplug(char *a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_req_secplug_check_systemplug() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_req_secplug_missing_check() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_hbhi_req_secplug_missing_check_isfinished(int *a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_hbhi_req_volume_control(char a1, char a2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_hbhi_req_volume_control_isfinished(int *a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_reset_coin_slot_noise_flag(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hbhi_set_framing_err_packet_send_interval(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_hbhi_set_watchdog_time(short a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_unlock_coincounter(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hbhi_update_control_status_buffer() {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// steel chronicle
|
||||
if (avs::game::is_model("KGG")) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::sc::get_buttons();
|
||||
|
||||
// reset
|
||||
memset(STATUS_BUFFER, 0, 64);
|
||||
|
||||
// check buttons
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sc::Buttons::Service))) {
|
||||
STATUS_BUFFER[5] |= 1 << 4;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sc::Buttons::Test))) {
|
||||
STATUS_BUFFER[5] |= 1 << 5;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sc::Buttons::LButton))) {
|
||||
STATUS_BUFFER[12] |= 1;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sc::Buttons::L1))) {
|
||||
STATUS_BUFFER[12] |= 1 << 1;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sc::Buttons::L2))) {
|
||||
STATUS_BUFFER[12] |= 1 << 2;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sc::Buttons::JogLeft))) {
|
||||
STATUS_BUFFER[12] |= 1 << 3;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sc::Buttons::JogRight))) {
|
||||
STATUS_BUFFER[12] |= 1 << 4;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sc::Buttons::RButton))) {
|
||||
STATUS_BUFFER[12] |= 1 << 5;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sc::Buttons::R1))) {
|
||||
STATUS_BUFFER[12] |= 1 << 6;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sc::Buttons::R2))) {
|
||||
STATUS_BUFFER[12] |= 1 << 7;
|
||||
}
|
||||
|
||||
// get analogs
|
||||
auto &analogs = games::sc::get_analogs();
|
||||
|
||||
auto joy_left_x = Analogs::getState(RI_MGR, analogs.at(games::sc::Analogs::LEFT_X)) * USHRT_MAX;
|
||||
auto joy_left_y = Analogs::getState(RI_MGR, analogs.at(games::sc::Analogs::LEFT_Y)) * USHRT_MAX;
|
||||
auto joy_right_x = Analogs::getState(RI_MGR, analogs.at(games::sc::Analogs::RIGHT_X)) * USHRT_MAX;
|
||||
auto joy_right_y = Analogs::getState(RI_MGR, analogs.at(games::sc::Analogs::RIGHT_Y)) * USHRT_MAX;
|
||||
|
||||
// because these are flight sticks, the X axis is inverted
|
||||
*((uint16_t *) &STATUS_BUFFER[20]) = USHRT_MAX - (uint16_t) joy_left_x;
|
||||
*((uint16_t *) &STATUS_BUFFER[22]) = (uint16_t) joy_left_y;
|
||||
*((uint16_t *) &STATUS_BUFFER[24]) = USHRT_MAX - (uint16_t) joy_right_x;
|
||||
*((uint16_t *) &STATUS_BUFFER[26]) = (uint16_t) joy_right_y;
|
||||
}
|
||||
|
||||
// hello popn music
|
||||
if (avs::game::is_model("JMP")) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::hpm::get_buttons();
|
||||
|
||||
// reset
|
||||
memset(STATUS_BUFFER, 0x00, 64);
|
||||
|
||||
// check buttons
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::Service))) {
|
||||
STATUS_BUFFER[5] |= 1 << 4;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::Test))) {
|
||||
STATUS_BUFFER[5] |= 1 << 5;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::CoinMech))) {
|
||||
STATUS_BUFFER[5] |= 1 << 2;
|
||||
}
|
||||
if (!Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::P1_Start))) {
|
||||
STATUS_BUFFER[4] |= 1;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::P1_1))) {
|
||||
STATUS_BUFFER[12] |= 1 << 0;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::P1_2))) {
|
||||
STATUS_BUFFER[12] |= 1 << 1;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::P1_3))) {
|
||||
STATUS_BUFFER[12] |= 1 << 2;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::P1_4))) {
|
||||
STATUS_BUFFER[12] |= 1 << 3;
|
||||
}
|
||||
if (!Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::P2_Start))) {
|
||||
STATUS_BUFFER[6] |= 1;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::P2_1))) {
|
||||
STATUS_BUFFER[12] |= 1 << 4;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::P2_2))) {
|
||||
STATUS_BUFFER[12] |= 1 << 5;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::P2_3))) {
|
||||
STATUS_BUFFER[12] |= 1 << 6;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::hpm::Buttons::P2_4))) {
|
||||
STATUS_BUFFER[12] |= 1 << 7;
|
||||
}
|
||||
}
|
||||
|
||||
// road fighters 3D
|
||||
if (avs::game::is_model("JGT")) {
|
||||
static int lever_state = 0;
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::rf3d::get_buttons();
|
||||
|
||||
// reset
|
||||
memset(STATUS_BUFFER, 0x00, 64);
|
||||
|
||||
// check buttons
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::Service))) {
|
||||
STATUS_BUFFER[5] |= 1 << 4;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::Test))) {
|
||||
STATUS_BUFFER[5] |= 1 << 5;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::CoinMech))) {
|
||||
STATUS_BUFFER[5] |= 1 << 2;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::View))) {
|
||||
STATUS_BUFFER[12] |= 1 << 2;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::Toggle2D3D))) {
|
||||
STATUS_BUFFER[12] |= 1 << 3;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::LeverUp))) {
|
||||
STATUS_BUFFER[12] |= 1 << 4;
|
||||
lever_state = 0;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::LeverDown))) {
|
||||
STATUS_BUFFER[12] |= 1 << 5;
|
||||
lever_state = 0;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::LeverLeft))) {
|
||||
STATUS_BUFFER[12] |= 1 << 6;
|
||||
lever_state = 0;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::LeverRight))) {
|
||||
STATUS_BUFFER[12] |= 1 << 7;
|
||||
lever_state = 0;
|
||||
}
|
||||
|
||||
// auto lever buttons
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::AutoLeverUp)) && lever_state < 6) {
|
||||
lever_state++;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::AutoLeverDown)) && lever_state > 0) {
|
||||
lever_state--;
|
||||
}
|
||||
|
||||
// auto lever logic
|
||||
switch (lever_state) {
|
||||
case 1:
|
||||
STATUS_BUFFER[12] |= 1 << 4 | 1 << 6;
|
||||
break;
|
||||
case 2:
|
||||
STATUS_BUFFER[12] |= 1 << 4 | 1 << 6;
|
||||
break;
|
||||
case 3:
|
||||
STATUS_BUFFER[12] |= 1 << 4;
|
||||
break;
|
||||
case 4:
|
||||
STATUS_BUFFER[12] |= 1 << 5;
|
||||
break;
|
||||
case 5:
|
||||
STATUS_BUFFER[12] |= 1 << 4 | 1 << 7;
|
||||
break;
|
||||
case 6:
|
||||
STATUS_BUFFER[12] |= 1 << 5 | 1 << 7;
|
||||
break;
|
||||
default:
|
||||
lever_state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_hbhi_watchdog_off() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::HBHIModule::HBHIModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("HBHI", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::HBHIModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_add_coin);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_consume_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_control_coin_blocker_close);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_control_coin_blocker_open);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_control_lamp_bright);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_control_lamp_mode);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_control_lamp_off);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_control_lamp_on);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_control_parallel_off);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_control_parallel_on);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_control_reset);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_create_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_current_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_destroy_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_get_coin_input_wave_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_get_softwareid);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_get_systemid);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_get_watchdog_status);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_get_watchdog_time_min);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_get_watchdog_time_now);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_lock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_carddispenser_disburse);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_carddispenser_disburse_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_carddispenser_get_status);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_carddispenser_get_status_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_carddispenser_init);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_carddispenser_init_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_coin_input_wave);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_get_control_status);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_secplug_check);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_secplug_check_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_secplug_check_softwareplug);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_secplug_check_systemplug);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_secplug_missing_check);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_secplug_missing_check_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_volume_control);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_req_volume_control_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_reset_coin_slot_noise_flag);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_set_framing_err_packet_send_interval);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_set_watchdog_time);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_unlock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_update_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_hbhi_watchdog_off);
|
||||
}
|
||||
13
acio/hbhi/hbhi.h
Normal file
13
acio/hbhi/hbhi.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class HBHIModule : public ACIOModule {
|
||||
public:
|
||||
HBHIModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
200
acio/hdxs/hdxs.cpp
Normal file
200
acio/hdxs/hdxs.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
#include "hdxs.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "games/popn/io.h"
|
||||
#include "games/rb/io.h"
|
||||
#include "games/dea/io.h"
|
||||
#include "avs/game.h"
|
||||
#include "util/logging.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
using namespace GameAPI;
|
||||
|
||||
// state
|
||||
static uint8_t STATUS_BUFFER[32] {};
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static int __cdecl ac_io_hdxs_get_control_status_buffer(int a1, void *a2) {
|
||||
|
||||
// copy buffer
|
||||
memcpy(a2, STATUS_BUFFER, sizeof(STATUS_BUFFER));
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hdxs_led_scroll(int a1, char a2, char a3, char a4, char a5, char a6, char a7, char a8, char a9,
|
||||
char a10, char a11, char a12, char a13) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hdxs_led_set_pattern(int index, char r, char g, char b, uint64_t led_bits) {
|
||||
|
||||
// reflec beat
|
||||
if (avs::game::is_model({"KBR", "LBR", "MBR"})) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::rb::get_lights();
|
||||
|
||||
// set values
|
||||
Lights::writeLight(RI_MGR, lights.at(games::rb::Lights::PoleR), r / 127.f);
|
||||
Lights::writeLight(RI_MGR, lights.at(games::rb::Lights::PoleG), g / 127.f);
|
||||
Lights::writeLight(RI_MGR, lights.at(games::rb::Lights::PoleB), b / 127.f);
|
||||
}
|
||||
|
||||
// dance evolution
|
||||
if (avs::game::is_model("KDM")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::dea::get_lights();
|
||||
|
||||
// decide on index
|
||||
switch (index) {
|
||||
case 12:
|
||||
Lights::writeLight(RI_MGR, lights.at(games::dea::Lights::SideUpperLeftR), r / 127.f);
|
||||
Lights::writeLight(RI_MGR, lights.at(games::dea::Lights::SideUpperLeftG), g / 127.f);
|
||||
Lights::writeLight(RI_MGR, lights.at(games::dea::Lights::SideUpperLeftB), b / 127.f);
|
||||
break;
|
||||
case 14:
|
||||
Lights::writeLight(RI_MGR, lights.at(games::dea::Lights::SideUpperRightR), r / 127.f);
|
||||
Lights::writeLight(RI_MGR, lights.at(games::dea::Lights::SideUpperRightG), g / 127.f);
|
||||
Lights::writeLight(RI_MGR, lights.at(games::dea::Lights::SideUpperRightB), b / 127.f);
|
||||
}
|
||||
}
|
||||
|
||||
// popn
|
||||
if (avs::game::is_model("M39")) {
|
||||
|
||||
// mappings
|
||||
static const uint64_t top_led_bits[] = {
|
||||
0x80000000000000,
|
||||
0x40000000000000,
|
||||
0x20000000000000,
|
||||
0x10000000000000,
|
||||
0x8000000000000,
|
||||
0x4000000000000,
|
||||
0x2000000000000,
|
||||
0x1000000000000,
|
||||
0x800000000000,
|
||||
0x400000000000,
|
||||
0x200000000000,
|
||||
0x100000000000,
|
||||
0x80000000000,
|
||||
0x40000000000,
|
||||
0x20000000000,
|
||||
0x10000000000,
|
||||
0x8000000000,
|
||||
0x4000000000,
|
||||
0x2000000000,
|
||||
0x1000000000,
|
||||
0x800000000,
|
||||
0x400000000,
|
||||
0x200000000,
|
||||
0x100000000,
|
||||
0x80000000,
|
||||
0x40000000,
|
||||
0x20000000,
|
||||
0x10000000,
|
||||
0x8000000,
|
||||
0x4000000,
|
||||
0x2000000,
|
||||
0x1000000,
|
||||
};
|
||||
static const size_t light_mapping[] {
|
||||
games::popn::Lights::TopLED1,
|
||||
games::popn::Lights::TopLED2,
|
||||
games::popn::Lights::TopLED3,
|
||||
games::popn::Lights::TopLED4,
|
||||
games::popn::Lights::TopLED5,
|
||||
games::popn::Lights::TopLED6,
|
||||
games::popn::Lights::TopLED7,
|
||||
games::popn::Lights::TopLED8,
|
||||
games::popn::Lights::TopLED9,
|
||||
games::popn::Lights::TopLED10,
|
||||
games::popn::Lights::TopLED11,
|
||||
games::popn::Lights::TopLED12,
|
||||
games::popn::Lights::TopLED13,
|
||||
games::popn::Lights::TopLED14,
|
||||
games::popn::Lights::TopLED15,
|
||||
games::popn::Lights::TopLED16,
|
||||
games::popn::Lights::TopLED17,
|
||||
games::popn::Lights::TopLED18,
|
||||
games::popn::Lights::TopLED19,
|
||||
games::popn::Lights::TopLED20,
|
||||
games::popn::Lights::TopLED21,
|
||||
games::popn::Lights::TopLED22,
|
||||
games::popn::Lights::TopLED23,
|
||||
games::popn::Lights::TopLED24,
|
||||
games::popn::Lights::TopLED25,
|
||||
games::popn::Lights::TopLED26,
|
||||
games::popn::Lights::TopLED27,
|
||||
games::popn::Lights::TopLED28,
|
||||
games::popn::Lights::TopLED29,
|
||||
games::popn::Lights::TopLED30,
|
||||
games::popn::Lights::TopLED31,
|
||||
games::popn::Lights::TopLED32,
|
||||
};
|
||||
|
||||
// get lights
|
||||
auto &lights = games::popn::get_lights();
|
||||
|
||||
// bit scan
|
||||
for (int i = 0; i < 32; i++) {
|
||||
bool value = (led_bits & top_led_bits[i]) > 0;
|
||||
Lights::writeLight(RI_MGR, lights.at(light_mapping[i]), value ? 1.f : 0.f);
|
||||
}
|
||||
|
||||
// write RGB
|
||||
auto value_r = r / 127.f;
|
||||
auto value_g = g / 127.f;
|
||||
auto value_b = b / 127.f;
|
||||
Lights::writeLight(RI_MGR, lights.at(games::popn::Lights::TopLED_R), value_r);
|
||||
Lights::writeLight(RI_MGR, lights.at(games::popn::Lights::TopLED_G), value_g);
|
||||
Lights::writeLight(RI_MGR, lights.at(games::popn::Lights::TopLED_B), value_b);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hdxs_led_set_rgb_mask(int a1, char a2, char a3, long a4) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hdxs_update_control_status_buffer(int a1) {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_hdxs_set_framing_err_packet_send_interval(int a1) {
|
||||
return a1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::HDXSModule::HDXSModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("HDXS", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::HDXSModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_hdxs_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_hdxs_led_scroll);
|
||||
ACIO_MODULE_HOOK(ac_io_hdxs_led_set_pattern);
|
||||
ACIO_MODULE_HOOK(ac_io_hdxs_led_set_rgb_mask);
|
||||
ACIO_MODULE_HOOK(ac_io_hdxs_update_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_hdxs_set_framing_err_packet_send_interval);
|
||||
}
|
||||
13
acio/hdxs/hdxs.h
Normal file
13
acio/hdxs/hdxs.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class HDXSModule : public ACIOModule {
|
||||
public:
|
||||
HDXSModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
122
acio/hgth/hgth.cpp
Normal file
122
acio/hgth/hgth.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "hgth.h"
|
||||
|
||||
#include "acio/icca/icca.h"
|
||||
#include "avs/game.h"
|
||||
#include "cfg/api.h"
|
||||
#include "games/rf3d/io.h"
|
||||
#include "launcher/launcher.h"
|
||||
|
||||
using namespace GameAPI;
|
||||
|
||||
// state
|
||||
static uint8_t STATUS_BUFFER[32] {};
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static int __cdecl ac_io_hgth_set_senddata(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hgth_update_recvdata() {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Road Fighters 3D
|
||||
if (avs::game::is_model("JGT")) {
|
||||
|
||||
// keypad mirror fix
|
||||
acio::ICCA_FLIP_ROWS = true;
|
||||
|
||||
// variables
|
||||
uint16_t wheel = 0x7FFF;
|
||||
uint16_t accelerator = 0x00;
|
||||
uint16_t brake = 0x00;
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::rf3d::get_buttons();
|
||||
|
||||
// check buttons
|
||||
bool wheel_button = false;
|
||||
bool accelerate_button = false;
|
||||
bool brake_button = false;
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::WheelLeft))) {
|
||||
wheel -= 0x7FFF;
|
||||
wheel_button = true;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::WheelRight))) {
|
||||
wheel += 0x8000;
|
||||
wheel_button = true;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::Accelerate))) {
|
||||
accelerator = 0xFFFF;
|
||||
accelerate_button = true;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::rf3d::Buttons::Brake))) {
|
||||
brake = 0xFFFF;
|
||||
brake_button = true;
|
||||
}
|
||||
|
||||
// analogs
|
||||
auto &analogs = games::rf3d::get_analogs();
|
||||
if (!wheel_button && analogs.at(games::rf3d::Analogs::Wheel).isSet()) {
|
||||
wheel = (uint16_t) (Analogs::getState(RI_MGR, analogs.at(games::rf3d::Analogs::Wheel)) * 0xFFFF);
|
||||
}
|
||||
if (!accelerate_button && analogs.at(games::rf3d::Analogs::Accelerate).isSet()) {
|
||||
accelerator = (uint16_t) (Analogs::getState(RI_MGR, analogs.at(games::rf3d::Analogs::Accelerate)) * 0xFFFF);
|
||||
}
|
||||
if (!brake_button && analogs.at(games::rf3d::Analogs::Brake).isSet()) {
|
||||
brake = (uint16_t) (Analogs::getState(RI_MGR, analogs.at(games::rf3d::Analogs::Brake)) * 0xFFFF);
|
||||
}
|
||||
|
||||
// write values
|
||||
*((uint16_t *) STATUS_BUFFER + 1) = wheel;
|
||||
*((uint16_t *) STATUS_BUFFER + 2) = accelerator;
|
||||
*((uint16_t *) STATUS_BUFFER + 3) = brake;
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_hgth_get_recvdata(void *buffer) {
|
||||
|
||||
// copy buffer
|
||||
memcpy(buffer, STATUS_BUFFER, sizeof(STATUS_BUFFER));
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_hgth_directreq_set_handle_limit(char a1, int *a2) {
|
||||
*a2 = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_hgth_directreq_set_handle_limit_isfinished(int *a1) {
|
||||
*a1 = 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::HGTHModule::HGTHModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("HGTH", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::HGTHModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_hgth_set_senddata);
|
||||
ACIO_MODULE_HOOK(ac_io_hgth_update_recvdata);
|
||||
ACIO_MODULE_HOOK(ac_io_hgth_get_recvdata);
|
||||
ACIO_MODULE_HOOK(ac_io_hgth_directreq_set_handle_limit);
|
||||
ACIO_MODULE_HOOK(ac_io_hgth_directreq_set_handle_limit_isfinished);
|
||||
}
|
||||
13
acio/hgth/hgth.h
Normal file
13
acio/hgth/hgth.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class HGTHModule : public ACIOModule {
|
||||
public:
|
||||
HGTHModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
375
acio/i36g/i36g.cpp
Normal file
375
acio/i36g/i36g.cpp
Normal file
@@ -0,0 +1,375 @@
|
||||
#include "i36g.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "avs/game.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "games/mga/io.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
using namespace GameAPI;
|
||||
|
||||
// static stuff
|
||||
static uint8_t STATUS_BUFFER[88 * 2] {};
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static int __cdecl ac_io_i36g_add_coin(int a1, int a2, int a3) {
|
||||
|
||||
// not so sure we want to add coins
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_consume_coinstock(int a1, int a2, int a3) {
|
||||
eamuse_coin_consume_stock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_i36g_control_coin_blocker_close(int a1, int a2) {
|
||||
eamuse_coin_set_block(true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_i36g_control_coin_blocker_open(int a1, int a2) {
|
||||
eamuse_coin_set_block(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_i36g_control_lamp_bright(uint32_t device, uint32_t lamp_bits, uint8_t brightness) {
|
||||
|
||||
// calculate value
|
||||
float value = (float) brightness / 255.f;
|
||||
|
||||
// get lights
|
||||
auto &lights = games::mga::get_lights();
|
||||
|
||||
// cabinet device
|
||||
if (device == 21) {
|
||||
if (lamp_bits & 1) {
|
||||
Lights::writeLight(RI_MGR, lights[games::mga::Lights::LeftR], value);
|
||||
}
|
||||
if (lamp_bits & 2) {
|
||||
Lights::writeLight(RI_MGR, lights[games::mga::Lights::LeftG], value);
|
||||
}
|
||||
if (lamp_bits & 4) {
|
||||
Lights::writeLight(RI_MGR, lights[games::mga::Lights::LeftB], value);
|
||||
}
|
||||
if (lamp_bits & 8) {
|
||||
Lights::writeLight(RI_MGR, lights[games::mga::Lights::RightR], value);
|
||||
}
|
||||
if (lamp_bits & 16) {
|
||||
Lights::writeLight(RI_MGR, lights[games::mga::Lights::RightG], value);
|
||||
}
|
||||
if (lamp_bits & 32) {
|
||||
Lights::writeLight(RI_MGR, lights[games::mga::Lights::RightB], value);
|
||||
}
|
||||
if (lamp_bits & 512) {
|
||||
Lights::writeLight(RI_MGR, lights[games::mga::Lights::Start], value);
|
||||
}
|
||||
}
|
||||
|
||||
// gun device
|
||||
if (device == 22) {
|
||||
if (lamp_bits & 1) {
|
||||
Lights::writeLight(RI_MGR, lights[games::mga::Lights::GunR], value);
|
||||
}
|
||||
if (lamp_bits & 2) {
|
||||
Lights::writeLight(RI_MGR, lights[games::mga::Lights::GunG], value);
|
||||
}
|
||||
if (lamp_bits & 4) {
|
||||
Lights::writeLight(RI_MGR, lights[games::mga::Lights::GunB], value);
|
||||
}
|
||||
}
|
||||
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_i36g_control_motor_power(int device, uint8_t strength) {
|
||||
|
||||
// gun device
|
||||
if (device == 22) {
|
||||
float value = (float) strength / 255.f;
|
||||
auto &lights = games::mga::get_lights();
|
||||
Lights::writeLight(RI_MGR, lights[games::mga::Lights::GunVibration], value);
|
||||
}
|
||||
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_current_coinstock(int a1, int a2, int *a3) {
|
||||
|
||||
// get coinstock
|
||||
*a3 = eamuse_coin_get_stock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_get_coin_input_wave_buffer(int a1, char *a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_i36g_get_control_status_buffer(int device, void *buffer) {
|
||||
|
||||
// cabinet buffer
|
||||
if (device == 21) {
|
||||
memcpy(buffer, &STATUS_BUFFER[0], 88);
|
||||
}
|
||||
|
||||
// gun buffer
|
||||
if (device == 22) {
|
||||
memcpy(buffer, &STATUS_BUFFER[88], 88);
|
||||
}
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_get_softwareid(int a1, int a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_get_systemid(int a1, int a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36g_get_watchdog_status(int a1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static short __cdecl ac_io_i36g_get_watchdog_time_min(int a1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short __cdecl ac_io_i36g_get_watchdog_time_now(int a1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_lock_coincounter(int a1, int a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_req_coin_input_wave(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_req_get_control_status(int a1, int *a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_req_secplug_check(int a1, char *a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36g_req_secplug_check_isfinished(int a1, int *a2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_req_secplug_check_softwareplug(int a1, char *a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_req_secplug_check_systemplug(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_req_secplug_missing_check(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36g_req_secplug_missing_check_isfinished(int a1, int *a2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36g_req_volume_control(int a1, char a2, char a3, char a4, char a5) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36g_req_volume_control_isfinished(int a1, int *ret_state) {
|
||||
*ret_state = 3;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_i36g_set_cmdmode(int a1, int a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_i36g_set_framing_err_packet_send_interval(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36g_set_watchdog_time(int a1, short a2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_i36g_unlock_coincounter(int a1, int a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36g_update_control_status_buffer(int node) {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Metal Gear Arcade
|
||||
if (avs::game::is_model("I36")) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::mga::get_buttons();
|
||||
|
||||
// cabinet device
|
||||
if (node == 21) {
|
||||
|
||||
// clear status buffer
|
||||
memset(&STATUS_BUFFER[0], 0, 88);
|
||||
|
||||
// update buttons
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::Service))) {
|
||||
ARRAY_SETB(&STATUS_BUFFER[0], 44);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::Test))) {
|
||||
ARRAY_SETB(&STATUS_BUFFER[0], 45);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::CoinMech))) {
|
||||
ARRAY_SETB(&STATUS_BUFFER[0], 42);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::Start))) {
|
||||
ARRAY_SETB(&STATUS_BUFFER[0], 124);
|
||||
}
|
||||
}
|
||||
|
||||
// gun device
|
||||
if (node == 22) {
|
||||
|
||||
// clear status buffer
|
||||
memset(&STATUS_BUFFER[88], 0, 88);
|
||||
|
||||
// update buttons
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::TriggerButton))
|
||||
|| (GetKeyState(VK_LBUTTON) & 0x100) != 0) { // mouse button
|
||||
ARRAY_SETB(&STATUS_BUFFER[88], 109);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::FrontTop))) {
|
||||
ARRAY_SETB(&STATUS_BUFFER[88], 108);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::FrontBottom))) {
|
||||
ARRAY_SETB(&STATUS_BUFFER[88], 106);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::SideLeft))) {
|
||||
ARRAY_SETB(&STATUS_BUFFER[88], 107);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::SideRight))) {
|
||||
ARRAY_SETB(&STATUS_BUFFER[88], 105);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::SideLever))) {
|
||||
ARRAY_SETB(&STATUS_BUFFER[88], 104);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::SwitchButton))) {
|
||||
ARRAY_SETB(&STATUS_BUFFER[88], 125);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::mga::Buttons::Top))) {
|
||||
ARRAY_SETB(&STATUS_BUFFER[88], 124);
|
||||
}
|
||||
|
||||
// joy stick
|
||||
unsigned short joy_x = 0x7FFF;
|
||||
unsigned short joy_y = 0x7FFF;
|
||||
bool joy_x_pressed = false;
|
||||
bool joy_y_pressed = false;
|
||||
if (Buttons::getState(RI_MGR, buttons[games::mga::Buttons::JoyForwards])) {
|
||||
joy_y -= 0x7FFF;
|
||||
joy_y_pressed = true;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons[games::mga::Buttons::JoyBackwards])) {
|
||||
joy_y += 0x7FFF;
|
||||
joy_y_pressed = true;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons[games::mga::Buttons::JoyLeft])) {
|
||||
joy_x -= 0x7FFF;
|
||||
joy_x_pressed = true;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons[games::mga::Buttons::JoyRight])) {
|
||||
joy_x += 0x7FFF;
|
||||
joy_x_pressed = true;
|
||||
}
|
||||
|
||||
// joy stick raw input
|
||||
auto &analogs = games::mga::get_analogs();
|
||||
if (!joy_x_pressed && analogs[games::mga::Analogs::JoyX].isSet()) {
|
||||
joy_x = (unsigned short) (Analogs::getState(RI_MGR, analogs[games::mga::Analogs::JoyX]) * 0xFFFF);
|
||||
}
|
||||
if (!joy_y_pressed && analogs[games::mga::Analogs::JoyY].isSet()) {
|
||||
joy_y = (unsigned short) (Analogs::getState(RI_MGR, analogs[games::mga::Analogs::JoyY]) * 0xFFFF);
|
||||
}
|
||||
|
||||
// save joy stick
|
||||
STATUS_BUFFER[88 + 42] = LOBYTE(joy_y);
|
||||
STATUS_BUFFER[88 + 43] = HIBYTE(joy_y);
|
||||
STATUS_BUFFER[88 + 44] = LOBYTE(joy_x);
|
||||
STATUS_BUFFER[88 + 45] = HIBYTE(joy_x);
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_i36g_watchdog_off(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::I36GModule::I36GModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("I36G", module, hookMode) {
|
||||
this->status_buffer = &STATUS_BUFFER[0];
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::I36GModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_add_coin);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_consume_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_control_coin_blocker_close);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_control_coin_blocker_open);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_control_lamp_bright);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_control_motor_power);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_current_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_get_coin_input_wave_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_get_softwareid);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_get_systemid);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_get_watchdog_status);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_get_watchdog_time_min);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_get_watchdog_time_now);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_lock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_req_coin_input_wave);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_req_get_control_status);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_req_secplug_check);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_req_secplug_check_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_req_secplug_check_softwareplug);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_req_secplug_check_systemplug);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_req_secplug_missing_check);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_req_secplug_missing_check_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_req_volume_control);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_req_volume_control_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_set_cmdmode);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_set_framing_err_packet_send_interval);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_set_watchdog_time);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_unlock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_update_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_i36g_watchdog_off);
|
||||
|
||||
// I36S links
|
||||
this->hook((void *) ac_io_i36g_update_control_status_buffer,
|
||||
"ac_io_i36s_update_control_status_buffer");
|
||||
this->hook((void *) ac_io_i36g_get_control_status_buffer,
|
||||
"ac_io_i36s_get_control_status_buffer");
|
||||
this->hook((void *) ac_io_i36g_set_cmdmode,
|
||||
"ac_io_i36s_set_cmdmode");
|
||||
}
|
||||
13
acio/i36g/i36g.h
Normal file
13
acio/i36g/i36g.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class I36GModule : public ACIOModule {
|
||||
public:
|
||||
I36GModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
125
acio/i36i/i36i.cpp
Normal file
125
acio/i36i/i36i.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include "i36i.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "util/utils.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "avs/game.h"
|
||||
|
||||
//using namespace GameAPI;
|
||||
|
||||
// static stuff
|
||||
static uint8_t STATUS_BUFFER[48];
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static bool __cdecl ac_io_i36i_ps3_controller_pwr_on() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36i_ps3_controller_pwr_off() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36i_create_get_status_thread() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36i_destroy_get_status_thread() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36i_update_control_status_buffer() {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// clear buffer
|
||||
memset(STATUS_BUFFER, 0, sizeof(STATUS_BUFFER));
|
||||
|
||||
// Winning Eleven
|
||||
if (avs::game::is_model({ "KCK", "NCK" })) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36i_get_control_status_buffer(uint8_t *buffer) {
|
||||
memcpy(buffer, STATUS_BUFFER, sizeof(STATUS_BUFFER));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36i_usb_controller_bus_IO() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36i_usb_controller_bus_PC() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36i_req_get_usb_desc(int a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_i36i_req_get_usb_desc_isfinished(
|
||||
int a1, uint32_t *a2, int a3, uint32_t *out_size, uint8_t *in_data, unsigned int in_size) {
|
||||
|
||||
// DualShock 3 device descriptor
|
||||
static uint8_t DS3_DESC[] {
|
||||
0x12, // bLength
|
||||
0x01, // bDescriptorType (Device)
|
||||
0x00, 0x02, // bcdUSB 2.00
|
||||
0x00, // bDeviceClass (Use class information in the Interface Descriptors)
|
||||
0x00, // bDeviceSubClass
|
||||
0x00, // bDeviceProtocol
|
||||
0x40, // bMaxPacketSize0 64
|
||||
0x4C, 0x05, // idVendor 0x054C
|
||||
0x68, 0x02, // idProduct 0x0268
|
||||
0x00, 0x01, // bcdDevice 1.00
|
||||
0x01, // iManufacturer (String Index)
|
||||
0x02, // iProduct (String Index)
|
||||
0x00, // iSerialNumber (String Index)
|
||||
0x01, // bNumConfigurations 1
|
||||
};
|
||||
|
||||
// copy descriptor to buffer
|
||||
*out_size = MIN(sizeof(DS3_DESC), in_size);
|
||||
memcpy(in_data, DS3_DESC, *out_size);
|
||||
|
||||
// we apparently need this too
|
||||
*a2 = 3;
|
||||
|
||||
// return success
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
acio::I36IModule::I36IModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("I36I", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::I36IModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_i36i_ps3_controller_pwr_on);
|
||||
ACIO_MODULE_HOOK(ac_io_i36i_ps3_controller_pwr_off);
|
||||
ACIO_MODULE_HOOK(ac_io_i36i_create_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_i36i_destroy_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_i36i_update_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_i36i_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_i36i_usb_controller_bus_IO);
|
||||
ACIO_MODULE_HOOK(ac_io_i36i_usb_controller_bus_PC);
|
||||
ACIO_MODULE_HOOK(ac_io_i36i_req_get_usb_desc);
|
||||
ACIO_MODULE_HOOK(ac_io_i36i_req_get_usb_desc_isfinished);
|
||||
}
|
||||
13
acio/i36i/i36i.h
Normal file
13
acio/i36i/i36i.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class I36IModule : public ACIOModule {
|
||||
public:
|
||||
I36IModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
472
acio/icca/icca.cpp
Normal file
472
acio/icca/icca.cpp
Normal file
@@ -0,0 +1,472 @@
|
||||
#include <cmath>
|
||||
#include "icca.h"
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/time.h"
|
||||
|
||||
// settings
|
||||
namespace acio {
|
||||
bool ICCA_FLIP_ROWS = false;
|
||||
bool ICCA_COMPAT_ACTIVE = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
struct ICCA_STATUS {
|
||||
uint8_t status_code;
|
||||
uint8_t solenoid;
|
||||
uint8_t front_sensor;
|
||||
uint8_t rear_sensor;
|
||||
uint8_t uid[8];
|
||||
int32_t error;
|
||||
uint32_t key_edge;
|
||||
uint32_t key_level;
|
||||
};
|
||||
struct ICCA_STATUS_LA9 {
|
||||
uint8_t status_code;
|
||||
uint8_t card_in;
|
||||
uint8_t uid[8];
|
||||
uint8_t error;
|
||||
uint8_t uid2[8];
|
||||
};
|
||||
static_assert(sizeof(struct ICCA_STATUS) == 24, "ICCA_STATUS must be 24 bytes");
|
||||
|
||||
enum ICCA_WORKFLOW {
|
||||
STEP,
|
||||
SLEEP,
|
||||
START,
|
||||
INIT,
|
||||
READY,
|
||||
GET_USERID,
|
||||
ACTIVE,
|
||||
EJECT,
|
||||
EJECT_CHECK,
|
||||
END,
|
||||
CLOSE_EJECT,
|
||||
CLOSE_E_CHK,
|
||||
CLOSE_END,
|
||||
ERR_GETUID = -2
|
||||
};
|
||||
struct ICCA_UNIT {
|
||||
struct ICCA_STATUS status {};
|
||||
enum ICCA_WORKFLOW state = STEP;
|
||||
bool card_cmd_pressed = false;
|
||||
bool card_in = false;
|
||||
double card_in_time = 0.0;
|
||||
char key_serial = 0;
|
||||
bool uid_skip = false;
|
||||
bool initialized = false;
|
||||
};
|
||||
static ICCA_UNIT ICCA_UNITS[2] {};
|
||||
static bool IS_LAST_CARD_FELICA = false;
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
static double CARD_TIMEOUT = 2.0;
|
||||
|
||||
static inline int icca_get_active_count() {
|
||||
int active_count = 0;
|
||||
for (auto unit : ICCA_UNITS) {
|
||||
active_count += unit.initialized;
|
||||
}
|
||||
return active_count;
|
||||
}
|
||||
|
||||
static inline int icca_get_unit_id(int unit_id) {
|
||||
if (icca_get_active_count() < 2)
|
||||
return 1;
|
||||
else {
|
||||
if (unit_id > 1) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void update_card(int unit_id) {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// eamio keypress
|
||||
int index = unit_id > 0 && icca_get_active_count() > 1 ? 1 : 0;
|
||||
bool kb_insert_press = (eamuse_get_keypad_state(index) & (1 << EAM_IO_INSERT)) > 0;
|
||||
|
||||
// get unit
|
||||
ICCA_UNIT *unit = &ICCA_UNITS[unit_id];
|
||||
|
||||
// check for card insert
|
||||
static bool kb_insert_press_old[2] = {false, false};
|
||||
if (eamuse_card_insert_consume(icca_get_active_count(), unit_id) ||
|
||||
(kb_insert_press && !kb_insert_press_old[unit_id])) {
|
||||
if (!unit->card_cmd_pressed) {
|
||||
unit->card_cmd_pressed = true;
|
||||
if (unit->state == GET_USERID || unit->state == CLOSE_EJECT || unit->state == STEP) {
|
||||
if (unit->uid_skip || eamuse_get_card(icca_get_active_count(), unit_id, unit->status.uid)) {
|
||||
IS_LAST_CARD_FELICA = is_card_uid_felica(unit->status.uid);
|
||||
|
||||
unit->state = acio::ICCA_COMPAT_ACTIVE ? START : ACTIVE;
|
||||
unit->status.error = 0;
|
||||
} else {
|
||||
unit->state = ERR_GETUID;
|
||||
memset(unit->status.uid, 0, 8);
|
||||
}
|
||||
unit->card_in = true;
|
||||
unit->card_in_time = get_performance_seconds();
|
||||
} else if (unit->state == EJECT_CHECK) {
|
||||
unit->state = SLEEP;
|
||||
unit->card_in = false;
|
||||
}
|
||||
} else {
|
||||
unit->state = acio::ICCA_COMPAT_ACTIVE ? START : ACTIVE;
|
||||
unit->status.error = 0;
|
||||
unit->card_in = true;
|
||||
unit->card_in_time = get_performance_seconds();
|
||||
}
|
||||
} else {
|
||||
unit->card_cmd_pressed = false;
|
||||
unit->state = CLOSE_EJECT;
|
||||
if (fabs(get_performance_seconds() - unit->card_in_time) > CARD_TIMEOUT) {
|
||||
unit->card_in = false;
|
||||
}
|
||||
}
|
||||
|
||||
// save state
|
||||
kb_insert_press_old[unit_id] = kb_insert_press;
|
||||
}
|
||||
|
||||
static bool KEYPAD_LAST[2][12];
|
||||
static uint32_t KEYPAD_EAMUSE_MAPPING[] = {
|
||||
0, 1, 5, 9, 2, 6, 10, 3, 7, 11, 8, 4
|
||||
};
|
||||
static uint32_t KEYPAD_KEY_CODES[] = {
|
||||
0x100,
|
||||
0x200,
|
||||
0x2000,
|
||||
2,
|
||||
0x400,
|
||||
0x4000,
|
||||
4,
|
||||
0x800,
|
||||
0x8000,
|
||||
8,
|
||||
1,
|
||||
0x1000
|
||||
};
|
||||
static uint32_t KEYPAD_KEY_CODE_NUMS[] = {
|
||||
0, 1, 5, 9, 2, 6, 10, 3, 7, 11, 8, 4
|
||||
};
|
||||
|
||||
static inline void keypad_update(int unit_id) {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// reset unit
|
||||
struct ICCA_UNIT *unit = &ICCA_UNITS[unit_id];
|
||||
unit->status.key_level = 0;
|
||||
unit->status.error = 0;
|
||||
|
||||
// get eamu state
|
||||
int index = unit_id > 0 && icca_get_active_count() > 1 ? 1 : 0;
|
||||
uint16_t eamu_state = eamuse_get_keypad_state(index);
|
||||
|
||||
// iterate keypad
|
||||
for (int n = 0; n < 12; n++) {
|
||||
int i = n;
|
||||
|
||||
// flip 123 with 789
|
||||
if (acio::ICCA_FLIP_ROWS) {
|
||||
if (!n)
|
||||
i = 11;
|
||||
else if (n < 4)
|
||||
i = n + 6;
|
||||
else if (n > 6 && n < 10)
|
||||
i = n - 6;
|
||||
else if (n == 11)
|
||||
i = 0;
|
||||
}
|
||||
|
||||
// check if pressed
|
||||
if ((eamu_state & (1 << KEYPAD_EAMUSE_MAPPING[i])))
|
||||
{
|
||||
unit->status.key_level |= KEYPAD_KEY_CODES[i];
|
||||
|
||||
if (!KEYPAD_LAST[unit_id][i]) {
|
||||
unit->status.key_edge = KEYPAD_KEY_CODES[n] << 16;
|
||||
unit->status.key_edge |= 0x80 | (unit->key_serial << 4) | KEYPAD_KEY_CODE_NUMS[n];
|
||||
|
||||
unit->key_serial += 1;
|
||||
unit->key_serial &= 0x07;
|
||||
}
|
||||
KEYPAD_LAST[unit_id][i] = true;
|
||||
} else {
|
||||
unit->status.key_edge &= ~(KEYPAD_KEY_CODES[n] << 16);
|
||||
|
||||
KEYPAD_LAST[unit_id][i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static bool __cdecl ac_io_icca_cardunit_init(int unit_id) {
|
||||
unit_id = icca_get_unit_id(unit_id);
|
||||
|
||||
// dirty workaround code
|
||||
if (icca_get_active_count() < 1)
|
||||
ICCA_UNITS[unit_id].initialized = true;
|
||||
else {
|
||||
ICCA_UNITS[0].initialized = true;
|
||||
ICCA_UNITS[1].initialized = true;
|
||||
}
|
||||
|
||||
// initial poll
|
||||
eamuse_get_keypad_state(unit_id);
|
||||
|
||||
// return success
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_icca_cardunit_init_isfinished(int unit_id, DWORD *status) {
|
||||
*status = READY;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_icca_crypt_init(int unit_id) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_icca_device_control_iccard_power_supply_off(int unit_id) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_icca_device_control_iccard_power_supply_on(int unit_id) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_icca_device_control_isfinished(int unit_id, DWORD *a2) {
|
||||
if (a2 && avs::game::is_model("KFC")) {
|
||||
*a2 = 6;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_icca_get_keep_alive_error(int unit_id, DWORD *a2) {
|
||||
*a2 = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_icca_get_status(void *a1, void *a2) {
|
||||
|
||||
// Metal Gear Arcade and Charge Machine had the args swapped so we need to check for valid pointers!
|
||||
if (reinterpret_cast<uintptr_t>(a2) > 2) {
|
||||
std::swap(a1, a2);
|
||||
|
||||
// honestly this could be used to detect if compat mode should be active
|
||||
// but we are too lazy to check if all games still work with this change
|
||||
//acio::ICCA_COMPAT_ACTIVE = true;
|
||||
}
|
||||
|
||||
// and best just leave this casting mess alone unless something is wrong with it.
|
||||
// long long is required because casting to int loses precision on 64-bit
|
||||
void *status = a1;
|
||||
int unit_id = static_cast<int>(reinterpret_cast<long long>(a2));
|
||||
|
||||
// update state
|
||||
unit_id = icca_get_unit_id(unit_id);
|
||||
keypad_update(unit_id);
|
||||
update_card(unit_id);
|
||||
|
||||
// copy state to output buffer
|
||||
ICCA_UNIT *unit = &ICCA_UNITS[unit_id];
|
||||
unit->status.status_code = unit->state;
|
||||
memcpy(status, &unit->status, sizeof(struct ICCA_STATUS));
|
||||
|
||||
// funny workaround
|
||||
if (acio::ICCA_COMPAT_ACTIVE) {
|
||||
if (avs::game::is_model("LA9")) {
|
||||
auto p = (ICCA_STATUS*) status;
|
||||
|
||||
ICCA_STATUS_LA9 p_la9;
|
||||
p_la9.status_code = unit->state;
|
||||
p_la9.card_in = unit->card_in;
|
||||
memcpy(p_la9.uid, p->uid, sizeof(p_la9.uid));
|
||||
p_la9.error = p->error;
|
||||
memcpy(p_la9.uid2, p->uid, sizeof(p_la9.uid));
|
||||
|
||||
memcpy(status, &p_la9, sizeof(ICCA_STATUS_LA9));
|
||||
} else {
|
||||
// the struct is different (28 bytes instead of 24) but nobody ain't got time for that
|
||||
auto p = (ICCA_STATUS*) status;
|
||||
p->error = p->key_level << 16;
|
||||
p->front_sensor = p->uid[0];
|
||||
p->rear_sensor = p->uid[1];
|
||||
for (size_t i = 2; i < sizeof(p->uid); i++) {
|
||||
p->uid[i - 2] = p->uid[i];
|
||||
}
|
||||
p->uid[sizeof(p->uid) - 2] = 0;
|
||||
p->uid[sizeof(p->uid) - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_icca_get_uid(int unit_id, char *card) {
|
||||
unit_id = icca_get_unit_id(unit_id);
|
||||
ICCA_UNIT *unit = &ICCA_UNITS[unit_id];
|
||||
|
||||
// copy card
|
||||
memcpy(card, unit->status.uid, 8);
|
||||
|
||||
// set felica flag
|
||||
IS_LAST_CARD_FELICA = is_card_uid_felica(unit->status.uid);
|
||||
|
||||
// check for error
|
||||
return unit->state != ERR_GETUID;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_icca_get_uid_felica(int unit_id, char *card) {
|
||||
unit_id = icca_get_unit_id(unit_id);
|
||||
ICCA_UNIT *unit = &ICCA_UNITS[unit_id];
|
||||
|
||||
// copy card
|
||||
memcpy(card, unit->status.uid, 8);
|
||||
|
||||
// set felica flag
|
||||
bool felica = is_card_uid_felica(unit->status.uid);
|
||||
card[8] = (char) (felica ? 1 : 0);
|
||||
IS_LAST_CARD_FELICA = felica;
|
||||
|
||||
// check for error
|
||||
return unit->state != ERR_GETUID;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_icca_is_felica() {
|
||||
return IS_LAST_CARD_FELICA;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_icca_req_uid(int unit_id) {
|
||||
unit_id = icca_get_unit_id(unit_id);
|
||||
|
||||
ICCA_UNIT *unit = &ICCA_UNITS[unit_id];
|
||||
unit->state = GET_USERID;
|
||||
|
||||
update_card(unit_id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_icca_req_uid_isfinished(int unit_id, DWORD *read_state) {
|
||||
unit_id = icca_get_unit_id(unit_id);
|
||||
ICCA_UNIT *unit = &ICCA_UNITS[unit_id];
|
||||
if (unit->card_in) {
|
||||
if (fabs(get_performance_seconds() - unit->card_in_time) < CARD_TIMEOUT) {
|
||||
unit->state = END;
|
||||
} else {
|
||||
unit->state = ERR_GETUID;
|
||||
}
|
||||
unit->card_in = false;
|
||||
}
|
||||
*read_state = unit->state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_icca_send_keep_alive_packet(int a1, int a2, int a3) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_icca_workflow(int workflow, int unit_id) {
|
||||
|
||||
unit_id = icca_get_unit_id(unit_id);
|
||||
ICCA_UNIT *unit = &ICCA_UNITS[unit_id];
|
||||
switch (workflow) {
|
||||
case STEP:
|
||||
if (avs::game::is_model("JDZ"))
|
||||
unit->state = SLEEP;
|
||||
else
|
||||
unit->state = STEP;
|
||||
break;
|
||||
case SLEEP:
|
||||
unit->state = SLEEP;
|
||||
break;
|
||||
case INIT:
|
||||
unit->state = READY;
|
||||
break;
|
||||
case START:
|
||||
if (unit->card_in)
|
||||
unit->state = ACTIVE;
|
||||
else
|
||||
unit->state = READY;
|
||||
break;
|
||||
case EJECT:
|
||||
unit->card_in = false;
|
||||
break;
|
||||
case CLOSE_EJECT:
|
||||
unit->state = unit->card_in ? EJECT_CHECK : SLEEP;
|
||||
break;
|
||||
case CLOSE_END:
|
||||
unit->state = SLEEP;
|
||||
break;
|
||||
case GET_USERID:
|
||||
unit->state = GET_USERID;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return unit->state;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_icca_req_status(int a1, char a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_icca_req_status_isfinished(int a1, int *a2) {
|
||||
*a2 = 11;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::ICCAModule::ICCAModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("ICCA", module, hookMode) {
|
||||
this->status_buffer = (uint8_t*) &ICCA_UNITS[0];
|
||||
this->status_buffer_size = sizeof(ICCA_UNITS);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::ICCAModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_icca_cardunit_init);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_cardunit_init_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_crypt_init);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_device_control_iccard_power_supply_off);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_device_control_iccard_power_supply_on);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_device_control_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_get_keep_alive_error);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_get_status);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_get_uid);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_get_uid_felica);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_is_felica);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_req_uid);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_req_uid_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_send_keep_alive_packet);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_workflow);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_req_status);
|
||||
ACIO_MODULE_HOOK(ac_io_icca_req_status_isfinished);
|
||||
}
|
||||
21
acio/icca/icca.h
Normal file
21
acio/icca/icca.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
// settings
|
||||
extern bool ICCA_FLIP_ROWS;
|
||||
extern bool ICCA_COMPAT_ACTIVE;
|
||||
|
||||
class ICCAModule : public ACIOModule {
|
||||
public:
|
||||
ICCAModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
|
||||
static inline bool is_card_uid_felica(uint8_t *uid) {
|
||||
return uid[0] != 0xE0 && uid[1] != 0x04;
|
||||
}
|
||||
158
acio/j32d/j32d.cpp
Normal file
158
acio/j32d/j32d.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
#include "j32d.h"
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "games/ftt/io.h"
|
||||
#include "games/scotto/io.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "util/logging.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
using namespace GameAPI;
|
||||
|
||||
// static stuff
|
||||
static uint32_t STATUS_BUFFER[20] {};
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
static uint32_t STATUS_BUFFER_COUNTER = 1;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static bool __cdecl ac_io_j32d_get_control_status_buffer(size_t a1, void* buffer, int a3) {
|
||||
|
||||
// set counter
|
||||
STATUS_BUFFER[14] = STATUS_BUFFER_COUNTER++;
|
||||
|
||||
// copy buffer
|
||||
memcpy(buffer, STATUS_BUFFER, sizeof(STATUS_BUFFER));
|
||||
|
||||
// return success
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool __cdecl ac_io_j32d_update_control_status_buffer(size_t a1) {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// clear buffer
|
||||
memset(STATUS_BUFFER, 0, sizeof(STATUS_BUFFER));
|
||||
|
||||
// FutureTomTom
|
||||
if (avs::game::is_model("MMD")) {
|
||||
|
||||
// process buttons
|
||||
auto &buttons = games::ftt::get_buttons();
|
||||
float pad1_vel = Buttons::getVelocity(RI_MGR, buttons.at(games::ftt::Buttons::Pad1));
|
||||
float pad2_vel = Buttons::getVelocity(RI_MGR, buttons.at(games::ftt::Buttons::Pad2));
|
||||
float pad3_vel = Buttons::getVelocity(RI_MGR, buttons.at(games::ftt::Buttons::Pad3));
|
||||
float pad4_vel = Buttons::getVelocity(RI_MGR, buttons.at(games::ftt::Buttons::Pad4));
|
||||
// FIXME(felix): this logic seems wrong for analog handling but correct for digital inputs
|
||||
if (pad1_vel > 0.f) {
|
||||
STATUS_BUFFER[6] = (int) (51.f * pad1_vel + 0.5f);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ftt::Buttons::Pad2))) {
|
||||
STATUS_BUFFER[7] = (int) (51.f * pad2_vel + 0.5f);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ftt::Buttons::Pad3))) {
|
||||
STATUS_BUFFER[8] = (int) (51.f * pad3_vel + 0.5f);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::ftt::Buttons::Pad4))) {
|
||||
STATUS_BUFFER[9] = (int) (51.f * pad4_vel + 0.5f);
|
||||
}
|
||||
|
||||
// process analogs
|
||||
auto &analogs = games::ftt::get_analogs();
|
||||
auto pad1_analog = analogs.at(games::ftt::Analogs::Pad1);
|
||||
auto pad2_analog = analogs.at(games::ftt::Analogs::Pad2);
|
||||
auto pad3_analog = analogs.at(games::ftt::Analogs::Pad3);
|
||||
auto pad4_analog = analogs.at(games::ftt::Analogs::Pad4);
|
||||
if (pad1_analog.isSet()) {
|
||||
auto val = (uint32_t) (51.f * Analogs::getState(RI_MGR, pad1_analog) + 0.5f);
|
||||
STATUS_BUFFER[6] = MAX(STATUS_BUFFER[6], val);
|
||||
}
|
||||
if (pad2_analog.isSet()) {
|
||||
auto val = (uint32_t) (51.f * Analogs::getState(RI_MGR, pad2_analog) + 0.5f);
|
||||
STATUS_BUFFER[7] = MAX(STATUS_BUFFER[7], val);
|
||||
}
|
||||
if (pad3_analog.isSet()) {
|
||||
auto val = (uint32_t) (51.f * Analogs::getState(RI_MGR, pad3_analog) + 0.5f);
|
||||
STATUS_BUFFER[8] = MAX(STATUS_BUFFER[8], val);
|
||||
}
|
||||
if (pad4_analog.isSet()) {
|
||||
auto val = (uint32_t) (51.f * Analogs::getState(RI_MGR, pad4_analog) + 0.5f);
|
||||
STATUS_BUFFER[9] = MAX(STATUS_BUFFER[9], val);
|
||||
}
|
||||
}
|
||||
|
||||
// Scotto
|
||||
if (avs::game::is_model("NSC")) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::scotto::get_buttons();
|
||||
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::Cup1))) {
|
||||
STATUS_BUFFER[5] |= 0x1;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::Cup2))) {
|
||||
STATUS_BUFFER[5] |= 0x2;
|
||||
}
|
||||
|
||||
// process button emulation for pads
|
||||
float first_pad_vel = Buttons::getVelocity(RI_MGR, buttons.at(games::scotto::Buttons::FirstPad));
|
||||
float pad_a_vel = Buttons::getVelocity(RI_MGR, buttons.at(games::scotto::Buttons::PadA));
|
||||
float pad_b_vel = Buttons::getVelocity(RI_MGR, buttons.at(games::scotto::Buttons::PadB));
|
||||
float pad_c_vel = Buttons::getVelocity(RI_MGR, buttons.at(games::scotto::Buttons::PadC));
|
||||
float pad_d_vel = Buttons::getVelocity(RI_MGR, buttons.at(games::scotto::Buttons::PadD));
|
||||
float pad_e_vel = Buttons::getVelocity(RI_MGR, buttons.at(games::scotto::Buttons::PadE));
|
||||
float pad_f_vel = Buttons::getVelocity(RI_MGR, buttons.at(games::scotto::Buttons::PadF));
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::FirstPad))) {
|
||||
STATUS_BUFFER[6] = (int) (191.f * first_pad_vel + 0.5f);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::PadA))) {
|
||||
STATUS_BUFFER[7] = (int) (51.f * pad_a_vel + 0.5f);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::PadB))) {
|
||||
STATUS_BUFFER[8] = (int) (51.f * pad_b_vel + 0.5f);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::PadC))) {
|
||||
STATUS_BUFFER[9] = (int) (51.f * pad_c_vel + 0.5f);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::PadD))) {
|
||||
STATUS_BUFFER[10] = (int) (51.f * pad_d_vel + 0.5f);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::PadE))) {
|
||||
STATUS_BUFFER[11] = (int) (51.f * pad_e_vel + 0.5f);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::PadF))) {
|
||||
STATUS_BUFFER[12] = (int) (51.f * pad_f_vel + 0.5f);
|
||||
}
|
||||
|
||||
// TODO(felix): analogs
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::J32DModule::J32DModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("J32D", module, hookMode) {
|
||||
this->status_buffer = (uint8_t*) &STATUS_BUFFER[0];
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::J32DModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_j32d_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_j32d_update_control_status_buffer);
|
||||
}
|
||||
13
acio/j32d/j32d.h
Normal file
13
acio/j32d/j32d.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class J32DModule : public ACIOModule {
|
||||
public:
|
||||
J32DModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
484
acio/kfca/kfca.cpp
Normal file
484
acio/kfca/kfca.cpp
Normal file
@@ -0,0 +1,484 @@
|
||||
#include "kfca.h"
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "games/bs/io.h"
|
||||
#include "games/nost/io.h"
|
||||
#include "games/scotto/io.h"
|
||||
#include "games/sdvx/sdvx.h"
|
||||
#include "games/sdvx/io.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
using namespace GameAPI;
|
||||
|
||||
// globals
|
||||
uint8_t KFCA_VOL_SOUND = 96;
|
||||
uint8_t KFCA_VOL_HEADPHONE = 96;
|
||||
uint8_t KFCA_VOL_EXTERNAL = 96;
|
||||
uint8_t KFCA_VOL_WOOFER = 96;
|
||||
|
||||
// static stuff
|
||||
static uint8_t STATUS_BUFFER[64] {};
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
static unsigned int KFCA_VOLL = 0;
|
||||
static unsigned int KFCA_VOLR = 0;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static int __cdecl ac_io_kfca_control_button_led(unsigned int button, bool state) {
|
||||
|
||||
// Sound Voltex
|
||||
if (avs::game::is_model("KFC")) {
|
||||
|
||||
// control mapping
|
||||
static const size_t mapping[] = {
|
||||
games::sdvx::Lights::BT_A,
|
||||
games::sdvx::Lights::BT_B,
|
||||
games::sdvx::Lights::BT_C,
|
||||
games::sdvx::Lights::BT_D,
|
||||
games::sdvx::Lights::FX_L,
|
||||
games::sdvx::Lights::FX_R,
|
||||
games::sdvx::Lights::START,
|
||||
games::sdvx::Lights::GENERATOR_B,
|
||||
};
|
||||
|
||||
// check if button is mapped
|
||||
if (button < 8) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::sdvx::get_lights();
|
||||
|
||||
// write light
|
||||
float value = state ? 1.f : 0.f;
|
||||
Lights::writeLight(RI_MGR, lights.at(mapping[button]), value);
|
||||
}
|
||||
}
|
||||
|
||||
// Scotto
|
||||
if (avs::game::is_model("NSC")) {
|
||||
|
||||
// control mapping
|
||||
static const size_t mapping[] = {
|
||||
games::scotto::Lights::PAD_F_B,
|
||||
games::scotto::Lights::PAD_E_R,
|
||||
games::scotto::Lights::PAD_E_B,
|
||||
~0u,
|
||||
~0u,
|
||||
~0u,
|
||||
games::scotto::Lights::PAD_F_R,
|
||||
games::scotto::Lights::BUTTON,
|
||||
};
|
||||
|
||||
// check if button is mapped
|
||||
if (button < std::size(mapping) && button[mapping] != ~0u) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::scotto::get_lights();
|
||||
|
||||
// write light
|
||||
float value = state ? 1.f : 0.f;
|
||||
Lights::writeLight(RI_MGR, lights.at(mapping[button]), value);
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_kfca_control_coin_blocker_close(int a1) {
|
||||
eamuse_coin_set_block(true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_kfca_control_coin_blocker_open(int a1) {
|
||||
eamuse_coin_set_block(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_kfca_control_led_bright(uint32_t led_field, uint8_t brightness) {
|
||||
|
||||
// Sound Voltex
|
||||
if (avs::game::is_model("KFC")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::sdvx::get_lights();
|
||||
|
||||
// control mapping
|
||||
static const size_t mapping[] {
|
||||
games::sdvx::Lights::WING_LEFT_UP_R,
|
||||
games::sdvx::Lights::WING_LEFT_UP_G,
|
||||
games::sdvx::Lights::WING_LEFT_UP_B,
|
||||
games::sdvx::Lights::WING_RIGHT_UP_R,
|
||||
games::sdvx::Lights::WING_RIGHT_UP_G,
|
||||
games::sdvx::Lights::WING_RIGHT_UP_B,
|
||||
games::sdvx::Lights::WING_LEFT_LOW_R,
|
||||
games::sdvx::Lights::WING_LEFT_LOW_G,
|
||||
games::sdvx::Lights::WING_LEFT_LOW_B,
|
||||
games::sdvx::Lights::WING_RIGHT_LOW_R,
|
||||
games::sdvx::Lights::WING_RIGHT_LOW_G,
|
||||
games::sdvx::Lights::WING_RIGHT_LOW_B,
|
||||
games::sdvx::Lights::WOOFER_R,
|
||||
games::sdvx::Lights::WOOFER_G,
|
||||
games::sdvx::Lights::WOOFER_B,
|
||||
games::sdvx::Lights::CONTROLLER_R,
|
||||
games::sdvx::Lights::CONTROLLER_G,
|
||||
games::sdvx::Lights::CONTROLLER_B,
|
||||
games::sdvx::Lights::GENERATOR_R,
|
||||
games::sdvx::Lights::GENERATOR_G,
|
||||
};
|
||||
|
||||
// write light
|
||||
float value = brightness / 255.f;
|
||||
for (size_t i = 0; i < std::size(mapping); i++) {
|
||||
if (led_field & (1 << i)) {
|
||||
Lights::writeLight(RI_MGR, lights.at(mapping[i]), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BeatStream
|
||||
if (avs::game::is_model("NBT")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::bs::get_lights();
|
||||
|
||||
// mapping
|
||||
static const size_t mapping[] {
|
||||
~0u, ~0u, ~0u,
|
||||
games::bs::Lights::RightR,
|
||||
games::bs::Lights::RightG,
|
||||
games::bs::Lights::RightB,
|
||||
games::bs::Lights::LeftR,
|
||||
games::bs::Lights::LeftG,
|
||||
games::bs::Lights::LeftB,
|
||||
games::bs::Lights::BottomR,
|
||||
games::bs::Lights::BottomG,
|
||||
games::bs::Lights::BottomB,
|
||||
};
|
||||
|
||||
// write light
|
||||
float value = brightness / 127.f;
|
||||
for (size_t i = 0; i < std::size(mapping); i++) {
|
||||
if (mapping[i] != ~0u && led_field & (1 << i)) {
|
||||
Lights::writeLight(RI_MGR, lights.at(mapping[i]), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nostalgia
|
||||
if (avs::game::is_model("PAN")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::nost::get_lights();
|
||||
|
||||
// mapping
|
||||
static const size_t mapping[] {
|
||||
~0u, ~0u, ~0u,
|
||||
games::nost::Lights::TitleR,
|
||||
games::nost::Lights::TitleG,
|
||||
games::nost::Lights::TitleB,
|
||||
~0u, ~0u, ~0u,
|
||||
games::nost::Lights::BottomR,
|
||||
games::nost::Lights::BottomG,
|
||||
games::nost::Lights::BottomB,
|
||||
};
|
||||
|
||||
// write light
|
||||
float value = brightness / 127.f;
|
||||
for (size_t i = 0; i < std::size(mapping); i++) {
|
||||
if (mapping[i] != ~0u && led_field & (1 << i)) {
|
||||
Lights::writeLight(RI_MGR, lights.at(mapping[i]), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scotto
|
||||
if (avs::game::is_model("NSC")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::scotto::get_lights();
|
||||
|
||||
// mapping
|
||||
static const size_t mapping[] {
|
||||
games::scotto::Lights::CUP_R,
|
||||
games::scotto::Lights::CUP_G,
|
||||
games::scotto::Lights::CUP_B,
|
||||
games::scotto::Lights::PAD_A_R,
|
||||
games::scotto::Lights::PAD_A_G,
|
||||
games::scotto::Lights::PAD_A_B,
|
||||
games::scotto::Lights::PAD_B_R,
|
||||
games::scotto::Lights::PAD_B_G,
|
||||
games::scotto::Lights::PAD_B_B,
|
||||
games::scotto::Lights::PAD_C_R,
|
||||
games::scotto::Lights::PAD_C_G,
|
||||
games::scotto::Lights::PAD_C_B,
|
||||
games::scotto::Lights::PAD_D_R,
|
||||
games::scotto::Lights::PAD_D_G,
|
||||
games::scotto::Lights::PAD_D_B,
|
||||
games::scotto::Lights::FIRST_PAD_R,
|
||||
games::scotto::Lights::FIRST_PAD_G,
|
||||
games::scotto::Lights::FIRST_PAD_B,
|
||||
games::scotto::Lights::PAD_F_G,
|
||||
games::scotto::Lights::PAD_E_G,
|
||||
};
|
||||
|
||||
// write light
|
||||
float value = brightness / 255.f;
|
||||
for (size_t i = 0; i < std::size(mapping); i++) {
|
||||
if (led_field & (1 << i)) {
|
||||
Lights::writeLight(RI_MGR, lights.at(mapping[i]), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_kfca_current_coinstock(int a1, DWORD *a2) {
|
||||
*a2 = (DWORD) eamuse_coin_get_stock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *__cdecl ac_io_kfca_get_control_status_buffer(void *target_buffer) {
|
||||
|
||||
// copy buffer
|
||||
return memcpy(target_buffer, STATUS_BUFFER, 64);
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_kfca_lock_coincounter(int a1) {
|
||||
eamuse_coin_set_block(true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_kfca_req_volume_control(
|
||||
uint8_t vol_sound, uint8_t vol_headphone, uint8_t vol_external, uint8_t vol_woofer) {
|
||||
|
||||
// update globals
|
||||
KFCA_VOL_SOUND = vol_sound;
|
||||
KFCA_VOL_HEADPHONE = vol_headphone;
|
||||
KFCA_VOL_EXTERNAL = vol_external;
|
||||
KFCA_VOL_WOOFER = vol_woofer;
|
||||
|
||||
// Sound Voltex
|
||||
if (avs::game::is_model("KFC")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::sdvx::get_lights();
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[games::sdvx::Lights::VOLUME_SOUND],
|
||||
(100 - vol_sound) / 100.f);
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[games::sdvx::Lights::VOLUME_HEADPHONE],
|
||||
(100 - vol_headphone) / 100.f);
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[games::sdvx::Lights::VOLUME_EXTERNAL],
|
||||
(100 - vol_external) / 100.f);
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[games::sdvx::Lights::VOLUME_WOOFER],
|
||||
(100 - vol_woofer) / 100.f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_kfca_set_watchdog_time(short a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_kfca_unlock_coincounter(int a1) {
|
||||
eamuse_coin_set_block(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_kfca_update_control_status_buffer() {
|
||||
static const int input_offset = 4;
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// clear buffer
|
||||
memset(STATUS_BUFFER, 0, 64);
|
||||
|
||||
// SDVX
|
||||
if (avs::game::is_model("KFC")) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::sdvx::get_buttons();
|
||||
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::Test))) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x20;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::Service))) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x10;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::CoinMech))) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x04;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::Start))) {
|
||||
STATUS_BUFFER[input_offset + 9] |= 0x08;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::BT_A))) {
|
||||
STATUS_BUFFER[input_offset + 9] |= 0x04;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::BT_B))) {
|
||||
STATUS_BUFFER[input_offset + 9] |= 0x02;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::BT_C))) {
|
||||
STATUS_BUFFER[input_offset + 9] |= 0x01;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::BT_D))) {
|
||||
STATUS_BUFFER[input_offset + 11] |= 0x20;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::FX_L))) {
|
||||
STATUS_BUFFER[input_offset + 11] |= 0x10;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::FX_R))) {
|
||||
STATUS_BUFFER[input_offset + 11] |= 0x08;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::Headphone))) {
|
||||
STATUS_BUFFER[input_offset + 9] |= 0x20;
|
||||
}
|
||||
|
||||
// volume left
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::VOL_L_Left))) {
|
||||
KFCA_VOLL = (KFCA_VOLL - games::sdvx::DIGITAL_KNOB_SENS) & 1023;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::VOL_L_Right))) {
|
||||
KFCA_VOLL = (KFCA_VOLL + games::sdvx::DIGITAL_KNOB_SENS) & 1023;
|
||||
}
|
||||
|
||||
// volume right
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::VOL_R_Left))) {
|
||||
KFCA_VOLR = (KFCA_VOLR - games::sdvx::DIGITAL_KNOB_SENS) & 1023;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::sdvx::Buttons::VOL_R_Right))) {
|
||||
KFCA_VOLR = (KFCA_VOLR + games::sdvx::DIGITAL_KNOB_SENS) & 1023;
|
||||
}
|
||||
|
||||
// update volumes
|
||||
auto &analogs = games::sdvx::get_analogs();
|
||||
auto vol_left = KFCA_VOLL;
|
||||
auto vol_right = KFCA_VOLR;
|
||||
if (analogs.at(0).isSet() || analogs.at(1).isSet()) {
|
||||
vol_left += (unsigned int) (Analogs::getState(RI_MGR,
|
||||
analogs.at(games::sdvx::Analogs::VOL_L)) * 1023.99f);
|
||||
vol_right += (unsigned int) (Analogs::getState(RI_MGR,
|
||||
analogs.at(games::sdvx::Analogs::VOL_R)) * 1023.99f);
|
||||
}
|
||||
|
||||
// proper loops
|
||||
vol_left %= 1024;
|
||||
vol_right %= 1024;
|
||||
|
||||
// save volumes in buffer
|
||||
STATUS_BUFFER[input_offset + 16 + 0] |= (unsigned char) ((vol_left << 6) & 0xFF);
|
||||
STATUS_BUFFER[input_offset + 16 + 1] |= (unsigned char) ((vol_left >> 2) & 0xFF);
|
||||
STATUS_BUFFER[input_offset + 16 + 2] |= (unsigned char) ((vol_right << 6) & 0xFF);
|
||||
STATUS_BUFFER[input_offset + 16 + 3] |= (unsigned char) ((vol_right >> 2) & 0xFF);
|
||||
}
|
||||
|
||||
// Beatstream
|
||||
if (avs::game::is_model("NBT")) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::bs::get_buttons();
|
||||
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bs::Buttons::Test))) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x20;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bs::Buttons::Service))) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x10;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bs::Buttons::CoinMech))) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
// Nostalgia
|
||||
if (avs::game::is_model("PAN")) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::nost::get_buttons();
|
||||
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::nost::Buttons::Service))) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x10;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::nost::Buttons::Test))) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x20;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::nost::Buttons::CoinMech))) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
// Scotto
|
||||
if (avs::game::is_model("NSC")) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::scotto::get_buttons();
|
||||
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::Test)) == Buttons::State::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x20;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::Service)) == Buttons::State::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x10;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::CoinMech)) == Buttons::State::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[input_offset + 1] |= 0x04;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::Start)) == Buttons::State::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[input_offset + 9] |= 0x20;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::Up)) == Buttons::State::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[input_offset + 9] |= 0x10;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::scotto::Buttons::Down)) == Buttons::State::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[input_offset + 9] |= 0x08;
|
||||
}
|
||||
|
||||
// the code also checks `input_offset + 9` for 0x01 but that does not trigger any response
|
||||
// in the "I/O CHECK" scene
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_kfca_watchdog_off() {
|
||||
}
|
||||
|
||||
// yes this is spelled "marge" instead of "merge"
|
||||
static int __cdecl ac_io_kfca_set_status_marge_func(void *cb) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::KFCAModule::KFCAModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("KFCA", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::KFCAModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_control_button_led);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_control_coin_blocker_close);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_control_coin_blocker_open);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_control_led_bright);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_current_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_lock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_req_volume_control);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_set_watchdog_time);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_unlock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_update_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_watchdog_off);
|
||||
ACIO_MODULE_HOOK(ac_io_kfca_set_status_marge_func);
|
||||
}
|
||||
18
acio/kfca/kfca.h
Normal file
18
acio/kfca/kfca.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
extern uint8_t KFCA_VOL_SOUND;
|
||||
extern uint8_t KFCA_VOL_HEADPHONE;
|
||||
extern uint8_t KFCA_VOL_EXTERNAL;
|
||||
extern uint8_t KFCA_VOL_WOOFER;
|
||||
|
||||
class KFCAModule : public ACIOModule {
|
||||
public:
|
||||
KFCAModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
238
acio/klpa/klpa.cpp
Normal file
238
acio/klpa/klpa.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
#include "klpa.h"
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "games/loveplus/io.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
using namespace GameAPI;
|
||||
|
||||
static uint8_t STATUS_BUFFER[48];
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
static const size_t LOVEPLUS_LIGHTS_MAPPING[] = {
|
||||
games::loveplus::Lights::Red,
|
||||
games::loveplus::Lights::Green,
|
||||
games::loveplus::Lights::Blue,
|
||||
SIZE_MAX,
|
||||
games::loveplus::Lights::Right,
|
||||
games::loveplus::Lights::Left,
|
||||
};
|
||||
|
||||
static char __cdecl ac_io_klpa_consume_coinstock(int a1, DWORD *a2) {
|
||||
*a2 = (DWORD) eamuse_coin_get_stock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_klpa_control_coin_blocker_close(int a1) {
|
||||
eamuse_coin_set_block(true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_klpa_control_coin_blocker_open(int a1) {
|
||||
eamuse_coin_set_block(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_klpa_control_led_off(size_t index) {
|
||||
|
||||
// LovePlus
|
||||
if (avs::game::is_model("KLP") && index < std::size(LOVEPLUS_LIGHTS_MAPPING)) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::loveplus::get_lights();
|
||||
|
||||
if (LOVEPLUS_LIGHTS_MAPPING[index] != SIZE_MAX) {
|
||||
Lights::writeLight(RI_MGR, lights.at(LOVEPLUS_LIGHTS_MAPPING[index]), 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_klpa_control_led_on(size_t index) {
|
||||
|
||||
// LovePlus
|
||||
if (avs::game::is_model("KLP") && index < std::size(LOVEPLUS_LIGHTS_MAPPING)) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::loveplus::get_lights();
|
||||
|
||||
if (LOVEPLUS_LIGHTS_MAPPING[index] != SIZE_MAX) {
|
||||
Lights::writeLight(RI_MGR, lights.at(LOVEPLUS_LIGHTS_MAPPING[index]), 1.f);
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_klpa_create_get_status_thread() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_klpa_current_coinstock(int a1, DWORD *a2) {
|
||||
|
||||
// check bounds
|
||||
if (a1 < 0 || a1 >= 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*a2 = (DWORD) eamuse_coin_get_stock();
|
||||
|
||||
// return success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_klpa_destroy_get_status_thread() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void* __cdecl ac_io_klpa_get_control_status_buffer(void *a1) {
|
||||
|
||||
// copy buffer
|
||||
return memcpy(a1, STATUS_BUFFER, sizeof(STATUS_BUFFER));
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_klpa_get_io_command_mode(void *a1) {
|
||||
memset(a1, 0, 4);
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_klpa_led_reset() {
|
||||
if (avs::game::is_model("KLP")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::loveplus::get_lights();
|
||||
|
||||
for (const auto &mapping : LOVEPLUS_LIGHTS_MAPPING) {
|
||||
if (mapping != SIZE_MAX) {
|
||||
Lights::writeLight(RI_MGR, lights.at(mapping), 0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_klpa_lock_coincounter(int a1) {
|
||||
eamuse_coin_set_block(true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_klpa_set_io_command_mode(int a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_klpa_set_io_command_mode_is_finished(uint8_t *a1) {
|
||||
*a1 = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_klpa_set_led_bright(size_t index, uint8_t brightness) {
|
||||
|
||||
// LovePlus
|
||||
if (avs::game::is_model("KLP") && index < std::size(LOVEPLUS_LIGHTS_MAPPING)) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::loveplus::get_lights();
|
||||
|
||||
if (LOVEPLUS_LIGHTS_MAPPING[index] != SIZE_MAX) {
|
||||
Lights::writeLight(RI_MGR, lights.at(LOVEPLUS_LIGHTS_MAPPING[index]), brightness / 127.f);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_klpa_set_sound_mute(int a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_klpa_set_sound_mute_is_finished(int a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_klpa_set_watchdog_time(short a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_klpa_unlock_coincounter(int a1) {
|
||||
eamuse_coin_set_block(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_klpa_update_control_status_buffer() {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// reset buffer
|
||||
memset(STATUS_BUFFER, 0, sizeof(STATUS_BUFFER));
|
||||
|
||||
// LovePlus
|
||||
if (avs::game::is_model("KLP")) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::loveplus::get_buttons();
|
||||
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::loveplus::Buttons::Test)) == Buttons::State::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[5] |= 1 << 5;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::loveplus::Buttons::Service)) == Buttons::State::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[5] |= 1 << 4;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::loveplus::Buttons::Left)) == Buttons::State::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[12] |= 1 << 6;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::loveplus::Buttons::Right)) == Buttons::State::BUTTON_PRESSED) {
|
||||
STATUS_BUFFER[12] |= 1 << 7;
|
||||
}
|
||||
|
||||
// x[9] & 0x3F) = volume output level?
|
||||
// x[11] & 0x3F) = volume output level?
|
||||
// x[12] |= (1 << 4) = headphone jack
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::KLPAModule::KLPAModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("KLPA", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::KLPAModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_consume_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_control_coin_blocker_close);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_control_coin_blocker_open);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_control_led_off);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_control_led_on);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_create_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_current_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_destroy_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_get_io_command_mode);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_led_reset);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_lock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_set_io_command_mode);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_set_io_command_mode_is_finished);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_set_led_bright);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_set_sound_mute);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_set_sound_mute_is_finished);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_set_watchdog_time);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_unlock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_klpa_update_control_status_buffer);
|
||||
}
|
||||
13
acio/klpa/klpa.h
Normal file
13
acio/klpa/klpa.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class KLPAModule : public ACIOModule {
|
||||
public:
|
||||
KLPAModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
113
acio/la9a/la9a.cpp
Normal file
113
acio/la9a/la9a.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#include "la9a.h"
|
||||
|
||||
#include "games/pcm/io.h"
|
||||
#include "hooks/graphics/graphics.h"
|
||||
#include "touch/touch.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
namespace acio {
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct la9a_control_status {
|
||||
uint8_t p1 : 6;
|
||||
uint8_t service_button : 1;
|
||||
uint8_t test_button : 1;
|
||||
uint8_t p2[9];
|
||||
uint8_t lcd_counter;
|
||||
uint8_t p3[5];
|
||||
uint16_t touch_x;
|
||||
uint16_t touch_y;
|
||||
uint16_t touch_z;
|
||||
uint8_t p4[26];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static struct la9a_control_status CONTROL_STATUS {};
|
||||
static bool TOUCH_ATTACHED = false;
|
||||
|
||||
static bool __cdecl ac_io_la9a_set_error_message(int, unsigned int, int) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_la9a_update_control_status_buffer() {
|
||||
CONTROL_STATUS.touch_z = 0xFF;
|
||||
CONTROL_STATUS.test_button = 0;
|
||||
CONTROL_STATUS.service_button = 0;
|
||||
|
||||
// attach touch handler on the first call to this function
|
||||
if (!TOUCH_ATTACHED) {
|
||||
log_misc("la9a", "attach touch handler");
|
||||
|
||||
HWND hwnd = FindWindowBeginsWith("LA9");
|
||||
if (!hwnd) {
|
||||
log_fatal("la9a", "LA9 window not found");
|
||||
}
|
||||
touch_create_wnd(hwnd);
|
||||
graphics_hook_window(hwnd, nullptr);
|
||||
|
||||
if (GRAPHICS_SHOW_CURSOR) {
|
||||
ShowCursor(1);
|
||||
}
|
||||
|
||||
TOUCH_ATTACHED = true;
|
||||
}
|
||||
|
||||
// update touch
|
||||
std::vector<TouchPoint> touch_points;
|
||||
touch_get_points(touch_points);
|
||||
|
||||
if (!touch_points.empty()) {
|
||||
auto &touch_point = touch_points[0];
|
||||
|
||||
// TODO: `x` and `y` should be clamped [0, std::numeric_limits<uint16_t>::max())
|
||||
CONTROL_STATUS.touch_x = static_cast<uint16_t>(touch_point.x);
|
||||
CONTROL_STATUS.touch_y = static_cast<uint16_t>(touch_point.y);
|
||||
CONTROL_STATUS.touch_z = 0;
|
||||
}
|
||||
CONTROL_STATUS.lcd_counter++;
|
||||
|
||||
// update buttons
|
||||
auto &buttons = games::pcm::get_buttons();
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::pcm::Buttons::Test])) {
|
||||
CONTROL_STATUS.test_button = 1;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::pcm::Buttons::Service])) {
|
||||
CONTROL_STATUS.service_button = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_la9a_update_counter(int, int) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl ac_io_la9a_update_lcd(int) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_la9a_get_control_status_buffer(struct la9a_control_status *control_status) {
|
||||
*control_status = CONTROL_STATUS;
|
||||
}
|
||||
|
||||
LA9AModule::LA9AModule(HMODULE module, HookMode hookMode) : ACIOModule("LA9A", module, hookMode) {
|
||||
//this->status_buffer = STATUS_BUFFER;
|
||||
//this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
//this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void LA9AModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_la9a_set_error_message);
|
||||
ACIO_MODULE_HOOK(ac_io_la9a_update_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_la9a_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_la9a_update_lcd);
|
||||
ACIO_MODULE_HOOK(ac_io_la9a_update_counter);
|
||||
}
|
||||
}
|
||||
13
acio/la9a/la9a.h
Normal file
13
acio/la9a/la9a.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class LA9AModule : public ACIOModule {
|
||||
public:
|
||||
LA9AModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
209
acio/mdxf/mdxf.cpp
Normal file
209
acio/mdxf/mdxf.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
#include "mdxf.h"
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "games/ddr/io.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "util/logging.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
// constants
|
||||
const size_t STATUS_BUFFER_SIZE = 32;
|
||||
|
||||
// static stuff
|
||||
static uint8_t COUNTER = 0;
|
||||
|
||||
// buffers
|
||||
#pragma pack(push, 1)
|
||||
static struct {
|
||||
uint8_t STATUS_BUFFER_P1[7][STATUS_BUFFER_SIZE] {};
|
||||
uint8_t STATUS_BUFFER_P2[7][STATUS_BUFFER_SIZE] {};
|
||||
} BUFFERS {};
|
||||
#pragma pack(pop)
|
||||
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
typedef uint64_t (__cdecl *ARK_GET_TICK_TIME64_T)();
|
||||
|
||||
static uint64_t arkGetTickTime64() {
|
||||
static ARK_GET_TICK_TIME64_T getTickTime64 =
|
||||
(ARK_GET_TICK_TIME64_T)GetProcAddress(avs::game::DLL_INSTANCE, "arkGetTickTime64");
|
||||
if (getTickTime64 == nullptr) {
|
||||
// this works on 32-bit versions of avs, but not on 64.
|
||||
// it's better than nothing though.
|
||||
return timeGetTime();
|
||||
}
|
||||
return getTickTime64();
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static bool __cdecl ac_io_mdxf_get_control_status_buffer(int node, void *buffer, uint8_t a3, uint8_t a4) {
|
||||
|
||||
// Dance Dance Revolution
|
||||
if (avs::game::is_model("MDX")) {
|
||||
|
||||
// get buffer index
|
||||
auto i = (COUNTER + a3) % std::size(BUFFERS.STATUS_BUFFER_P1);
|
||||
|
||||
// copy buffer
|
||||
if (node == 17 || node == 25) {
|
||||
memcpy(buffer, BUFFERS.STATUS_BUFFER_P1[i], STATUS_BUFFER_SIZE);
|
||||
} else if (node == 18 || node == 26) {
|
||||
memcpy(buffer, BUFFERS.STATUS_BUFFER_P2[i], STATUS_BUFFER_SIZE);
|
||||
} else {
|
||||
|
||||
// fill with zeros on unknown node
|
||||
memset(buffer, 0, STATUS_BUFFER_SIZE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_mdxf_set_output_level(unsigned int a1, unsigned int a2, uint8_t value) {
|
||||
if (avs::game::is_model("MDX")) {
|
||||
static const struct {
|
||||
int a2[4];
|
||||
} mapping[] = {
|
||||
{
|
||||
// a1 == 17
|
||||
{
|
||||
games::ddr::Lights::GOLD_P1_STAGE_UP_RIGHT,
|
||||
games::ddr::Lights::GOLD_P1_STAGE_DOWN_LEFT,
|
||||
games::ddr::Lights::GOLD_P1_STAGE_UP_LEFT,
|
||||
games::ddr::Lights::GOLD_P1_STAGE_DOWN_RIGHT
|
||||
}
|
||||
},
|
||||
{
|
||||
// a1 == 18
|
||||
{
|
||||
games::ddr::Lights::GOLD_P2_STAGE_UP_RIGHT,
|
||||
games::ddr::Lights::GOLD_P2_STAGE_DOWN_LEFT,
|
||||
games::ddr::Lights::GOLD_P2_STAGE_UP_LEFT,
|
||||
games::ddr::Lights::GOLD_P2_STAGE_DOWN_RIGHT
|
||||
}
|
||||
}
|
||||
};
|
||||
if ((a1 == 17 || a1 == 18) && (a2 < 4)) {
|
||||
// get light from mapping
|
||||
const auto light = mapping[a1 - 17].a2[a2];
|
||||
|
||||
// get lights
|
||||
auto &lights = games::ddr::get_lights();
|
||||
|
||||
// write lights
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[light], value / 128.f);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_mdxf_update_control_status_buffer(int node) {
|
||||
|
||||
// increase counter
|
||||
COUNTER = (COUNTER + 1) % std::size(BUFFERS.STATUS_BUFFER_P1);
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// clear buffer
|
||||
uint8_t *buffer = nullptr;
|
||||
switch (node) {
|
||||
case 17:
|
||||
case 25:
|
||||
buffer = BUFFERS.STATUS_BUFFER_P1[COUNTER];
|
||||
break;
|
||||
case 18:
|
||||
case 26:
|
||||
buffer = BUFFERS.STATUS_BUFFER_P2[COUNTER];
|
||||
break;
|
||||
default:
|
||||
|
||||
// return failure on unknown node
|
||||
return false;
|
||||
}
|
||||
memset(buffer, 0, STATUS_BUFFER_SIZE);
|
||||
|
||||
// Dance Dance Revolution
|
||||
if (avs::game::is_model("MDX")) {
|
||||
|
||||
// Sensor Map (LDUR):
|
||||
// FOOT DOWN = bit 32-35 = byte 4, bit 0-3
|
||||
// FOOT UP = bit 36-39 = byte 4, bit 4-7
|
||||
// FOOT RIGHT = bit 40-43 = byte 5, bit 0-3
|
||||
// FOOT LEFT = bit 44-47 = byte 5, bit 4-7
|
||||
static const size_t buttons_p1[] = {
|
||||
games::ddr::Buttons::P1_PANEL_UP,
|
||||
games::ddr::Buttons::P1_PANEL_DOWN,
|
||||
games::ddr::Buttons::P1_PANEL_LEFT,
|
||||
games::ddr::Buttons::P1_PANEL_RIGHT,
|
||||
};
|
||||
static const size_t buttons_p2[] = {
|
||||
games::ddr::Buttons::P2_PANEL_UP,
|
||||
games::ddr::Buttons::P2_PANEL_DOWN,
|
||||
games::ddr::Buttons::P2_PANEL_LEFT,
|
||||
games::ddr::Buttons::P2_PANEL_RIGHT,
|
||||
};
|
||||
|
||||
// decide on button map
|
||||
const size_t *button_map = nullptr;
|
||||
switch (node) {
|
||||
case 17:
|
||||
case 25:
|
||||
button_map = &buttons_p1[0];
|
||||
break;
|
||||
case 18:
|
||||
case 26:
|
||||
button_map = &buttons_p2[0];
|
||||
break;
|
||||
}
|
||||
|
||||
*(uint64_t*)&buffer[0x18] = arkGetTickTime64();
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::ddr::get_buttons();
|
||||
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(button_map[0]))) {
|
||||
buffer[4] |= 0xF0;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(button_map[1]))) {
|
||||
buffer[4] |= 0x0F;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(button_map[2]))) {
|
||||
buffer[5] |= 0xF0;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(button_map[3]))) {
|
||||
buffer[5] |= 0x0F;
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::MDXFModule::MDXFModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("MDXF", module, hookMode) {
|
||||
this->status_buffer = (uint8_t*) &BUFFERS;
|
||||
this->status_buffer_size = sizeof(BUFFERS);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::MDXFModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_mdxf_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_mdxf_set_output_level);
|
||||
ACIO_MODULE_HOOK(ac_io_mdxf_update_control_status_buffer);
|
||||
}
|
||||
13
acio/mdxf/mdxf.h
Normal file
13
acio/mdxf/mdxf.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class MDXFModule : public ACIOModule {
|
||||
public:
|
||||
MDXFModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
39
acio/module.cpp
Normal file
39
acio/module.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "module.h"
|
||||
#include "util/logging.h"
|
||||
#include "util/detour.h"
|
||||
#include "util/libutils.h"
|
||||
#include "avs/game.h"
|
||||
|
||||
const char *acio::hook_mode_str(acio::HookMode hook_mode) {
|
||||
switch (hook_mode) {
|
||||
case HookMode::INLINE:
|
||||
return "Inline";
|
||||
case HookMode::IAT:
|
||||
return "IAT";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook functions depending on the specified mode.
|
||||
* We don't care about errors here since different versions of libacio contain different feature sets,
|
||||
* which means that not all hooks must/can succeed.
|
||||
*/
|
||||
void acio::ACIOModule::hook(void *func, const char *func_name) {
|
||||
switch (this->hook_mode) {
|
||||
case HookMode::INLINE:
|
||||
detour::inline_hook(func, libutils::try_proc(this->module, func_name));
|
||||
break;
|
||||
case HookMode::IAT:
|
||||
detour::iat_try(func_name, func);
|
||||
break;
|
||||
default:
|
||||
log_warning("acio", "unable to hook using mode {}", hook_mode_str(this->hook_mode));
|
||||
}
|
||||
}
|
||||
|
||||
void acio::ACIOModule::attach() {
|
||||
log_info("acio", "module attach: {} {}", this->name, hook_mode_str(this->hook_mode));
|
||||
this->attached = true;
|
||||
}
|
||||
56
acio/module.h
Normal file
56
acio/module.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
// macro for lazy typing of hooks
|
||||
#define ACIO_MODULE_HOOK(f) this->hook(reinterpret_cast<void *>(f), #f)
|
||||
|
||||
namespace acio {
|
||||
|
||||
/*
|
||||
* Hook Modes
|
||||
* Since some versions can't handle inline hooking
|
||||
*/
|
||||
enum class HookMode {
|
||||
INLINE,
|
||||
IAT
|
||||
};
|
||||
|
||||
// this makes logging easier
|
||||
const char *hook_mode_str(HookMode hook_mode);
|
||||
|
||||
/*
|
||||
* The ACIO module itself
|
||||
* Inherit this for extending our libacio implementation
|
||||
*/
|
||||
class ACIOModule {
|
||||
protected:
|
||||
|
||||
// the magic
|
||||
void hook(void* func, const char *func_name);
|
||||
|
||||
public:
|
||||
|
||||
ACIOModule(std::string name, HMODULE module, HookMode hook_mode) :
|
||||
name(std::move(name)),
|
||||
module(module),
|
||||
hook_mode(hook_mode) {};
|
||||
|
||||
virtual ~ACIOModule() = default;
|
||||
|
||||
virtual void attach();
|
||||
|
||||
// settings
|
||||
std::string name;
|
||||
HMODULE module;
|
||||
HookMode hook_mode;
|
||||
bool attached = false;
|
||||
|
||||
// buffer state (optional)
|
||||
uint8_t *status_buffer = nullptr;
|
||||
size_t status_buffer_size = 0;
|
||||
bool *status_buffer_freeze = nullptr;
|
||||
};
|
||||
}
|
||||
64
acio/nddb/nddb.cpp
Normal file
64
acio/nddb/nddb.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "nddb.h"
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
// static stuff
|
||||
static uint8_t STATUS_BUFFER[4] {};
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static void __cdecl ac_io_nddb_control_pwm(int a1, int a2) {
|
||||
log_misc("acio::nddb", "ac_io_nddb_control_pwm({}, {})", a1, a2);
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_nddb_control_solenoide(int a1, int a2) {
|
||||
log_misc("acio::nddb", "ac_io_nddb_control_solenoide({}, {})", a1, a2);
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_nddb_create_get_status_thread() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_nddb_destroy_get_status_thread() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_nddb_get_control_status_buffer(void *buffer) {
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_nddb_req_solenoide_control(uint8_t *buffer) {
|
||||
log_misc("acio::nddb", "ac_io_nddb_req_solenoide_control");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_nddb_update_control_status_buffer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::NDDBModule::NDDBModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("NDDB", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::NDDBModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
ACIO_MODULE_HOOK(ac_io_nddb_control_pwm);
|
||||
ACIO_MODULE_HOOK(ac_io_nddb_control_solenoide);
|
||||
ACIO_MODULE_HOOK(ac_io_nddb_create_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_nddb_destroy_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_nddb_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_nddb_req_solenoide_control);
|
||||
ACIO_MODULE_HOOK(ac_io_nddb_update_control_status_buffer);
|
||||
}
|
||||
13
acio/nddb/nddb.h
Normal file
13
acio/nddb/nddb.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class NDDBModule : public ACIOModule {
|
||||
public:
|
||||
NDDBModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
203
acio/panb/panb.cpp
Normal file
203
acio/panb/panb.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
#include "panb.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "games/nost/io.h"
|
||||
#include "games/nost/nost.h"
|
||||
#include "util/logging.h"
|
||||
#include "avs/game.h"
|
||||
|
||||
using namespace GameAPI;
|
||||
|
||||
// static stuff
|
||||
static uint8_t STATUS_BUFFER[277];
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static long __cdecl ac_io_panb_control_led_bright(size_t index, uint8_t value) {
|
||||
|
||||
// nostalgia
|
||||
if (avs::game::is_model("PAN")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::nost::get_lights();
|
||||
|
||||
// mapping
|
||||
static const size_t mapping[] {
|
||||
games::nost::Lights::Key1R, games::nost::Lights::Key1G, games::nost::Lights::Key1B,
|
||||
games::nost::Lights::Key2R, games::nost::Lights::Key2G, games::nost::Lights::Key2B,
|
||||
games::nost::Lights::Key3R, games::nost::Lights::Key3G, games::nost::Lights::Key3B,
|
||||
games::nost::Lights::Key4R, games::nost::Lights::Key4G, games::nost::Lights::Key4B,
|
||||
games::nost::Lights::Key5R, games::nost::Lights::Key5G, games::nost::Lights::Key5B,
|
||||
games::nost::Lights::Key6R, games::nost::Lights::Key6G, games::nost::Lights::Key6B,
|
||||
games::nost::Lights::Key7R, games::nost::Lights::Key7G, games::nost::Lights::Key7B,
|
||||
games::nost::Lights::Key8R, games::nost::Lights::Key8G, games::nost::Lights::Key8B,
|
||||
games::nost::Lights::Key9R, games::nost::Lights::Key9G, games::nost::Lights::Key9B,
|
||||
games::nost::Lights::Key10R, games::nost::Lights::Key10G, games::nost::Lights::Key10B,
|
||||
games::nost::Lights::Key11R, games::nost::Lights::Key11G, games::nost::Lights::Key11B,
|
||||
games::nost::Lights::Key12R, games::nost::Lights::Key12G, games::nost::Lights::Key12B,
|
||||
games::nost::Lights::Key13R, games::nost::Lights::Key13G, games::nost::Lights::Key13B,
|
||||
games::nost::Lights::Key14R, games::nost::Lights::Key14G, games::nost::Lights::Key14B,
|
||||
games::nost::Lights::Key15R, games::nost::Lights::Key15G, games::nost::Lights::Key15B,
|
||||
games::nost::Lights::Key16R, games::nost::Lights::Key16G, games::nost::Lights::Key16B,
|
||||
games::nost::Lights::Key17R, games::nost::Lights::Key17G, games::nost::Lights::Key17B,
|
||||
games::nost::Lights::Key18R, games::nost::Lights::Key18G, games::nost::Lights::Key18B,
|
||||
games::nost::Lights::Key19R, games::nost::Lights::Key19G, games::nost::Lights::Key19B,
|
||||
games::nost::Lights::Key20R, games::nost::Lights::Key20G, games::nost::Lights::Key20B,
|
||||
games::nost::Lights::Key21R, games::nost::Lights::Key21G, games::nost::Lights::Key21B,
|
||||
games::nost::Lights::Key22R, games::nost::Lights::Key22G, games::nost::Lights::Key22B,
|
||||
games::nost::Lights::Key23R, games::nost::Lights::Key23G, games::nost::Lights::Key23B,
|
||||
games::nost::Lights::Key24R, games::nost::Lights::Key24G, games::nost::Lights::Key24B,
|
||||
games::nost::Lights::Key25R, games::nost::Lights::Key25G, games::nost::Lights::Key25B,
|
||||
games::nost::Lights::Key26R, games::nost::Lights::Key26G, games::nost::Lights::Key26B,
|
||||
games::nost::Lights::Key27R, games::nost::Lights::Key27G, games::nost::Lights::Key27B,
|
||||
games::nost::Lights::Key28R, games::nost::Lights::Key28G, games::nost::Lights::Key28B,
|
||||
};
|
||||
|
||||
// write light
|
||||
if (index < std::size(mapping)) {
|
||||
Lights::writeLight(RI_MGR, lights.at(mapping[index]), value / 127.f);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static long __cdecl ac_io_panb_control_reset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void* __cdecl ac_io_panb_get_control_status_buffer(uint8_t* buffer) {
|
||||
|
||||
// copy buffer
|
||||
return memcpy(buffer, STATUS_BUFFER, sizeof(STATUS_BUFFER));
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_panb_start_auto_input() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_panb_update_control_status_buffer() {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// clear buffer
|
||||
memset(STATUS_BUFFER, 0, 277);
|
||||
|
||||
/*
|
||||
* first byte is number of input data
|
||||
* when it's set to 0 the game will not update it's key states
|
||||
* setting it too high will make the game read over the buffer
|
||||
*
|
||||
* unsure why you would send more than one set of data, so
|
||||
* we just set it to 1 and provide our current status
|
||||
*/
|
||||
STATUS_BUFFER[0] = 1;
|
||||
|
||||
// Nostalgia
|
||||
if (avs::game::is_model("PAN")) {
|
||||
|
||||
// get buttons/analogs
|
||||
auto &buttons = games::nost::get_buttons();
|
||||
auto &analogs = games::nost::get_analogs();
|
||||
|
||||
// mappings
|
||||
static const size_t button_mapping[] = {
|
||||
games::nost::Buttons::Key1, games::nost::Buttons::Key2,
|
||||
games::nost::Buttons::Key3, games::nost::Buttons::Key4,
|
||||
games::nost::Buttons::Key5, games::nost::Buttons::Key6,
|
||||
games::nost::Buttons::Key7, games::nost::Buttons::Key8,
|
||||
games::nost::Buttons::Key9, games::nost::Buttons::Key10,
|
||||
games::nost::Buttons::Key11, games::nost::Buttons::Key12,
|
||||
games::nost::Buttons::Key13, games::nost::Buttons::Key14,
|
||||
games::nost::Buttons::Key15, games::nost::Buttons::Key16,
|
||||
games::nost::Buttons::Key17, games::nost::Buttons::Key18,
|
||||
games::nost::Buttons::Key19, games::nost::Buttons::Key20,
|
||||
games::nost::Buttons::Key21, games::nost::Buttons::Key22,
|
||||
games::nost::Buttons::Key23, games::nost::Buttons::Key24,
|
||||
games::nost::Buttons::Key25, games::nost::Buttons::Key26,
|
||||
games::nost::Buttons::Key27, games::nost::Buttons::Key28,
|
||||
};
|
||||
static const size_t analog_mapping[] = {
|
||||
games::nost::Analogs::Key1, games::nost::Analogs::Key2,
|
||||
games::nost::Analogs::Key3, games::nost::Analogs::Key4,
|
||||
games::nost::Analogs::Key5, games::nost::Analogs::Key6,
|
||||
games::nost::Analogs::Key7, games::nost::Analogs::Key8,
|
||||
games::nost::Analogs::Key9, games::nost::Analogs::Key10,
|
||||
games::nost::Analogs::Key11, games::nost::Analogs::Key12,
|
||||
games::nost::Analogs::Key13, games::nost::Analogs::Key14,
|
||||
games::nost::Analogs::Key15, games::nost::Analogs::Key16,
|
||||
games::nost::Analogs::Key17, games::nost::Analogs::Key18,
|
||||
games::nost::Analogs::Key19, games::nost::Analogs::Key20,
|
||||
games::nost::Analogs::Key21, games::nost::Analogs::Key22,
|
||||
games::nost::Analogs::Key23, games::nost::Analogs::Key24,
|
||||
games::nost::Analogs::Key25, games::nost::Analogs::Key26,
|
||||
games::nost::Analogs::Key27, games::nost::Analogs::Key28,
|
||||
};
|
||||
|
||||
// iterate pairs of keys
|
||||
for (size_t key_pair = 0; key_pair < 28 / 2; key_pair++) {
|
||||
|
||||
// default states
|
||||
uint8_t state0 = 0;
|
||||
uint8_t state1 = 0;
|
||||
|
||||
// check analogs
|
||||
auto &analog0 = analogs.at(analog_mapping[key_pair * 2 + 0]);
|
||||
auto &analog1 = analogs.at(analog_mapping[key_pair * 2 + 1]);
|
||||
if (analog0.isSet()) {
|
||||
state0 = (uint8_t) (Analogs::getState(RI_MGR, analog0) * 15.999f);
|
||||
}
|
||||
if (analog1.isSet()) {
|
||||
state1 = (uint8_t) (Analogs::getState(RI_MGR, analog1) * 15.999f);
|
||||
}
|
||||
|
||||
// check buttons
|
||||
auto velocity0 = Buttons::getVelocity(RI_MGR, buttons.at(button_mapping[key_pair * 2 + 0]));
|
||||
auto velocity1 = Buttons::getVelocity(RI_MGR, buttons.at(button_mapping[key_pair * 2 + 1]));
|
||||
if (velocity0 > 0.f) {
|
||||
state0 = (uint8_t) (velocity0 * 15.999f);
|
||||
}
|
||||
if (velocity1 > 0.f) {
|
||||
state1 = (uint8_t) (velocity1 * 15.999f);
|
||||
}
|
||||
|
||||
// build value
|
||||
uint8_t value = 0;
|
||||
value |= state0 << 4;
|
||||
value |= state1 & 0xF;
|
||||
|
||||
// set value
|
||||
STATUS_BUFFER[key_pair + 3] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::PANBModule::PANBModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("PANB", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::PANBModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_panb_control_led_bright);
|
||||
ACIO_MODULE_HOOK(ac_io_panb_control_reset);
|
||||
ACIO_MODULE_HOOK(ac_io_panb_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_panb_start_auto_input);
|
||||
ACIO_MODULE_HOOK(ac_io_panb_update_control_status_buffer);
|
||||
}
|
||||
13
acio/panb/panb.h
Normal file
13
acio/panb/panb.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class PANBModule : public ACIOModule {
|
||||
public:
|
||||
PANBModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
520
acio/pix/pix.cpp
Normal file
520
acio/pix/pix.cpp
Normal file
@@ -0,0 +1,520 @@
|
||||
#include "pix.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "games/museca/io.h"
|
||||
#include "games/bbc/io.h"
|
||||
#include "util/utils.h"
|
||||
#include "avs/game.h"
|
||||
|
||||
using namespace GameAPI;
|
||||
|
||||
// static stuff
|
||||
static int ACIO_PIX_WARMUP = 0;
|
||||
static uint8_t STATUS_BUFFER[60];
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static char __cdecl ac_io_pix_begin(char a1, long long a2, int a3, int a4, int a5, int a6) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_begin_get_status(int a1, int a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_end(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_end_get_status(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_get_firmware_update_device_index(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_get_node_no(int a1, int a2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *__cdecl ac_io_pix_get_recv_log(long long a1, void *a2, int a3) {
|
||||
return a2;
|
||||
}
|
||||
|
||||
static void *__cdecl ac_io_pix_get_rs232c_status(void *a1, int a2) {
|
||||
return a1;
|
||||
}
|
||||
|
||||
static void *__cdecl ac_io_pix_get_send_log(long long a1, void *a2, int a3) {
|
||||
return a2;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_get_version(void *a1, int a2, int a3) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *__cdecl ac_io_pix_get_version_string() {
|
||||
static const char *version = "1.25.0";
|
||||
return version;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_go_firmware_update(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_is_active(int a1, int a2) {
|
||||
return (char) (++ACIO_PIX_WARMUP > 601 ? 1 : 0);
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_is_active2(int a1, int *a2, int a3) {
|
||||
ACIO_PIX_WARMUP = 601;
|
||||
*a2 = 6;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_is_active_device(int a1, int a2) {
|
||||
return (char) (a1 != 5);
|
||||
}
|
||||
|
||||
static long long __cdecl ac_io_pix_reset(int a1) {
|
||||
return a1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pix_rvol_change_expand_mode(char a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static long long __cdecl ac_io_pix_rvol_control_led_bright(uint32_t led_field, uint8_t brightness) {
|
||||
|
||||
// MUSECA
|
||||
if (avs::game::is_model("PIX")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::museca::get_lights();
|
||||
|
||||
// control mapping
|
||||
static int mapping[] = {
|
||||
games::museca::Lights::Spinner1R,
|
||||
games::museca::Lights::Spinner1G,
|
||||
games::museca::Lights::Spinner1B,
|
||||
games::museca::Lights::Spinner2R,
|
||||
games::museca::Lights::Spinner2G,
|
||||
games::museca::Lights::Spinner2B,
|
||||
games::museca::Lights::Spinner3R,
|
||||
games::museca::Lights::Spinner3G,
|
||||
games::museca::Lights::Spinner3B,
|
||||
games::museca::Lights::Spinner4R,
|
||||
games::museca::Lights::Spinner4G,
|
||||
games::museca::Lights::Spinner4B,
|
||||
games::museca::Lights::Spinner5R,
|
||||
games::museca::Lights::Spinner5G,
|
||||
games::museca::Lights::Spinner5B,
|
||||
games::museca::Lights::TitleR,
|
||||
games::museca::Lights::TitleG,
|
||||
games::museca::Lights::TitleB
|
||||
};
|
||||
|
||||
// write light
|
||||
float value = brightness > 127.f ? 1.f : brightness / 127.f;
|
||||
for (size_t i = 0; i < std::size(mapping); i++) {
|
||||
if (mapping[i] >= 0 && led_field & (1 << i)) {
|
||||
Lights::writeLight(RI_MGR, lights.at((size_t) mapping[i]), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BISHI BASHI CHANNEL
|
||||
if (avs::game::is_model("R66")) {
|
||||
|
||||
// get lights
|
||||
auto &lights = games::bbc::get_lights();
|
||||
|
||||
// control mapping
|
||||
static int mapping[] = {
|
||||
games::bbc::Lights::P1_DISC_R,
|
||||
games::bbc::Lights::P1_DISC_G,
|
||||
games::bbc::Lights::P1_DISC_B,
|
||||
games::bbc::Lights::P3_DISC_R,
|
||||
games::bbc::Lights::P3_DISC_G,
|
||||
games::bbc::Lights::P3_DISC_B,
|
||||
games::bbc::Lights::P2_DISC_R,
|
||||
games::bbc::Lights::P2_DISC_G,
|
||||
games::bbc::Lights::P2_DISC_B,
|
||||
games::bbc::Lights::P4_DISC_R,
|
||||
games::bbc::Lights::P4_DISC_G,
|
||||
games::bbc::Lights::P4_DISC_B,
|
||||
games::bbc::Lights::P1_R,
|
||||
games::bbc::Lights::P1_B,
|
||||
-1, -1, -1, -1, -1, -1,
|
||||
games::bbc::Lights::P2_R,
|
||||
games::bbc::Lights::P2_B,
|
||||
games::bbc::Lights::P3_R,
|
||||
games::bbc::Lights::P3_B,
|
||||
games::bbc::Lights::P4_R,
|
||||
games::bbc::Lights::P4_B,
|
||||
};
|
||||
|
||||
// write light
|
||||
float value = brightness / 255.f;
|
||||
for (size_t i = 0; i < std::size(mapping); i++) {
|
||||
if (mapping[i] >= 0 && led_field & (1 << i)) {
|
||||
Lights::writeLight(RI_MGR, lights.at((size_t) mapping[i]), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static long long __cdecl ac_io_pix_rvol_control_reset() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pix_rvol_create_get_status_thread() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static long long __cdecl ac_io_pix_rvol_destroy_get_status_thread() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *__cdecl ac_io_pix_rvol_get_control_status_buffer(void *a1) {
|
||||
|
||||
// copy buffer
|
||||
return memcpy(a1, STATUS_BUFFER, sizeof(STATUS_BUFFER));
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pix_rvol_get_watchdog_status() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static short __cdecl ac_io_pix_rvol_get_watchdog_time_min() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short __cdecl ac_io_pix_rvol_get_watchdog_time_now() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pix_rvol_modify_auto_input_get(long long a1, long long a2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_rvol_req_get_control_status(DWORD *a1) {
|
||||
*a1 = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pix_rvol_req_volume_control(char a1, char a2, char a3, char a4) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pix_rvol_req_volume_control_isfinished(DWORD *a1) {
|
||||
*a1 = 5;
|
||||
return true;
|
||||
}
|
||||
|
||||
static long long __cdecl ac_io_pix_rvol_set_framing_err_packet_send_interval(long long a1) {
|
||||
return a1;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pix_rvol_set_watchdog_time(short a1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pix_rvol_update_control_status_buffer() {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// clear buffer
|
||||
memset(STATUS_BUFFER, 0, sizeof(STATUS_BUFFER));
|
||||
|
||||
// MUSECA
|
||||
if (avs::game::is_model("PIX")) {
|
||||
|
||||
// get input
|
||||
auto &buttons = games::museca::get_buttons();
|
||||
|
||||
// get slowdown status
|
||||
bool slowdown = Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::AnalogSlowdown));
|
||||
|
||||
// update disk buttons
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk1Press)))
|
||||
ARRAY_SETB(STATUS_BUFFER, 107);
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk2Press)))
|
||||
ARRAY_SETB(STATUS_BUFFER, 104);
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk3Press)))
|
||||
ARRAY_SETB(STATUS_BUFFER, 123);
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk4Press)))
|
||||
ARRAY_SETB(STATUS_BUFFER, 42);
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk5Press)))
|
||||
ARRAY_SETB(STATUS_BUFFER, 44);
|
||||
|
||||
// foot pedal (inverted)
|
||||
if (!Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::FootPedal)))
|
||||
ARRAY_SETB(STATUS_BUFFER, 43);
|
||||
|
||||
// update analogs
|
||||
static uint8_t analogs[5] = { 0, 0, 0, 0, 0 };
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk1Minus))) {
|
||||
analogs[0] -= slowdown ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk1Plus))) {
|
||||
analogs[0] += slowdown ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk2Minus))) {
|
||||
analogs[1] -= slowdown ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk2Plus))) {
|
||||
analogs[1] += slowdown ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk3Minus))) {
|
||||
analogs[2] -= slowdown ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk3Plus))) {
|
||||
analogs[2] += slowdown ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk4Minus))) {
|
||||
analogs[3] -= slowdown ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk4Plus))) {
|
||||
analogs[3] += slowdown ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk5Minus))) {
|
||||
analogs[4] -= slowdown ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::museca::Buttons::Disk5Plus))) {
|
||||
analogs[4] += slowdown ? 3 : 12;
|
||||
}
|
||||
|
||||
// raw input analogs
|
||||
auto &analog_list = games::museca::get_analogs();
|
||||
size_t analog_mapping[] = {
|
||||
games::museca::Analogs::Disk1,
|
||||
games::museca::Analogs::Disk2,
|
||||
games::museca::Analogs::Disk3,
|
||||
games::museca::Analogs::Disk4,
|
||||
games::museca::Analogs::Disk5,
|
||||
};
|
||||
uint8_t set_values[5];
|
||||
std::copy(std::begin(analogs), std::end(analogs), std::begin(set_values));
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
auto &analog_item = analog_list.at(analog_mapping[i]);
|
||||
if (analog_item.isSet()) {
|
||||
set_values[i] = analogs[i] + (uint8_t) (Analogs::getState(RI_MGR, analog_item) * 255.99f);
|
||||
}
|
||||
}
|
||||
|
||||
// set analogs
|
||||
for (int i = 0; i < 5; i++)
|
||||
STATUS_BUFFER[20 + i] = set_values[i];
|
||||
}
|
||||
|
||||
// BISHI BASHI CHANNEL
|
||||
if (avs::game::is_model("R66")) {
|
||||
|
||||
// get input
|
||||
auto &buttons = games::bbc::get_buttons();
|
||||
auto &analogs = games::bbc::get_analogs();
|
||||
|
||||
// get slowdown status
|
||||
bool slowdown1 = Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P1_DiskSlowdown));
|
||||
bool slowdown2 = Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P2_DiskSlowdown));
|
||||
bool slowdown3 = Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P3_DiskSlowdown));
|
||||
bool slowdown4 = Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P4_DiskSlowdown));
|
||||
|
||||
// update buttons
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P1_R)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 44);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P1_G)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 107);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P1_B)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 41);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P2_R)) == Buttons::State::BUTTON_NOT_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 39);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P2_G)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 123);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P2_B)) == Buttons::State::BUTTON_NOT_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 55);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P3_R)) == Buttons::State::BUTTON_NOT_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 71);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P3_G)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 104);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P3_B)) == Buttons::State::BUTTON_NOT_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 87);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P4_R)) == Buttons::State::BUTTON_NOT_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 103);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P4_G)) == Buttons::State::BUTTON_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 42);
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P4_B)) == Buttons::State::BUTTON_NOT_PRESSED) {
|
||||
ARRAY_SETB(STATUS_BUFFER, 119);
|
||||
}
|
||||
|
||||
// update analogs
|
||||
static uint8_t analog_states[4] = { 0, 0, 0, 0 };
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P1_DiskMinus)) == Buttons::State::BUTTON_PRESSED) {
|
||||
analog_states[0] -= slowdown1 ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P1_DiskPlus)) == Buttons::State::BUTTON_PRESSED) {
|
||||
analog_states[0] += slowdown1 ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P2_DiskMinus)) == Buttons::State::BUTTON_PRESSED) {
|
||||
analog_states[1] -= slowdown2 ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P2_DiskPlus)) == Buttons::State::BUTTON_PRESSED) {
|
||||
analog_states[1] += slowdown2 ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P3_DiskMinus)) == Buttons::State::BUTTON_PRESSED) {
|
||||
analog_states[2] -= slowdown3 ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P3_DiskPlus)) == Buttons::State::BUTTON_PRESSED) {
|
||||
analog_states[2] += slowdown3 ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P4_DiskMinus)) == Buttons::State::BUTTON_PRESSED) {
|
||||
analog_states[3] -= slowdown4 ? 3 : 12;
|
||||
}
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::bbc::Buttons::P4_DiskPlus)) == Buttons::State::BUTTON_PRESSED) {
|
||||
analog_states[3] += slowdown4 ? 3 : 12;
|
||||
}
|
||||
|
||||
// raw input analogs
|
||||
uint8_t set_values[4];
|
||||
size_t analog_mappings[] = {
|
||||
games::bbc::Analogs::P1_Disk,
|
||||
games::bbc::Analogs::P2_Disk,
|
||||
games::bbc::Analogs::P3_Disk,
|
||||
games::bbc::Analogs::P4_Disk,
|
||||
};
|
||||
std::copy(std::begin(analog_states), std::end(analog_states), std::begin(set_values));
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
auto &analog_item = analogs.at(analog_mappings[i]);
|
||||
if (analog_item.isSet()) {
|
||||
set_values[i] = analog_states[i] + (uint8_t) (Analogs::getState(RI_MGR, analog_item) * 255.99f);
|
||||
}
|
||||
}
|
||||
|
||||
// flip disk 2/3
|
||||
set_values[1] ^= set_values[2];
|
||||
set_values[2] ^= set_values[1];
|
||||
set_values[1] ^= set_values[2];
|
||||
|
||||
// set analogs
|
||||
for (int i = 0; i < 4; i++) {
|
||||
STATUS_BUFFER[20 + i] = set_values[i];
|
||||
}
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_pix_rvol_watchdog_off() {
|
||||
}
|
||||
|
||||
static void *__cdecl ac_io_pix_secplug_set_encodedpasswd(void *a1, unsigned int a2) {
|
||||
return a1;
|
||||
}
|
||||
|
||||
static void *__cdecl ac_io_pix_set_get_status_device(void *a1, int a2) {
|
||||
return a1;
|
||||
}
|
||||
|
||||
static void *__cdecl ac_io_pix_set_soft_watch_dog(void *a1, int a2) {
|
||||
return a1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_soft_watch_dog_off(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_soft_watch_dog_on(int a1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char __cdecl ac_io_pix_update(long long a1) {
|
||||
|
||||
// flush outputs
|
||||
RI_MGR->devices_flush_output();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char* __cdecl ac_io_pix_version() {
|
||||
static const char *version = "Version: 1.25.0\nBuild Date: Sep 20 2016 15:16:13\nBuild Host: DEMETER\n";
|
||||
return version;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::PIXModule::PIXModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("PIX", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::PIXModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_pix_begin);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_begin_get_status);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_end);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_end_get_status);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_get_firmware_update_device_index);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_get_node_no);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_get_recv_log);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_get_rs232c_status);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_get_send_log);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_get_version);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_get_version_string);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_go_firmware_update);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_is_active);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_is_active2);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_is_active_device);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_reset);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_change_expand_mode);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_control_led_bright);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_control_reset);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_create_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_destroy_get_status_thread);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_get_watchdog_status);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_get_watchdog_time_min);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_get_watchdog_time_now);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_modify_auto_input_get);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_req_get_control_status);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_req_volume_control);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_req_volume_control_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_set_framing_err_packet_send_interval);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_set_watchdog_time);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_update_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_rvol_watchdog_off);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_secplug_set_encodedpasswd);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_set_get_status_device);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_set_soft_watch_dog);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_soft_watch_dog_off);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_soft_watch_dog_on);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_update);
|
||||
ACIO_MODULE_HOOK(ac_io_pix_version);
|
||||
}
|
||||
13
acio/pix/pix.h
Normal file
13
acio/pix/pix.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class PIXModule : public ACIOModule {
|
||||
public:
|
||||
PIXModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
156
acio/pjec/pjec.cpp
Normal file
156
acio/pjec/pjec.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
#include "pjec.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "util/utils.h"
|
||||
#include "avs/game.h"
|
||||
#include "games/we/io.h"
|
||||
|
||||
//using namespace GameAPI;
|
||||
|
||||
// static stuff
|
||||
static uint8_t STATUS_BUFFER[72];
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static bool __cdecl ac_io_pjec_get_ps2() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __cdecl ac_io_pjec_get_control_status_buffer(uint8_t *buffer) {
|
||||
memcpy(buffer, STATUS_BUFFER, sizeof(STATUS_BUFFER));
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjec_update_control_status_buffer() {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// clear buffer
|
||||
memset(STATUS_BUFFER, 0, sizeof(STATUS_BUFFER));
|
||||
|
||||
// Winning Eleven
|
||||
if (avs::game::is_model({ "KCK", "NCK" })) {
|
||||
auto &buttons = games::we::get_buttons();
|
||||
auto &analogs = games::we::get_analogs();
|
||||
|
||||
/*
|
||||
* Device Types
|
||||
* 0x00 - Unknown Device
|
||||
* 0x01 - Mouse
|
||||
* 0x02 - Rotate Controller
|
||||
* 0x03 - Gun Controller K
|
||||
* 0x04 - Digital Controller <- Accepted
|
||||
* 0x05 - Analog Joystick
|
||||
* 0x06 - Gun Controller N
|
||||
* 0x07 - Analog Controller <- Accepted
|
||||
* 0x08 - USB Analog Controller
|
||||
*/
|
||||
|
||||
// set device type
|
||||
STATUS_BUFFER[0] = 0x07;
|
||||
|
||||
// set device present
|
||||
STATUS_BUFFER[2] = 0x5A;
|
||||
|
||||
// reset analogs to center
|
||||
STATUS_BUFFER[8] = 0x7F;
|
||||
STATUS_BUFFER[9] = 0x7F;
|
||||
STATUS_BUFFER[10] = 0x7F;
|
||||
STATUS_BUFFER[11] = 0x7F;
|
||||
|
||||
// apply analogs
|
||||
if (analogs[games::we::Analogs::PadStickLeftX].isSet()) {
|
||||
STATUS_BUFFER[8] = (uint8_t) (GameAPI::Analogs::getState(RI_MGR,
|
||||
analogs[games::we::Analogs::PadStickLeftX]) * 255.9999f);
|
||||
}
|
||||
if (analogs[games::we::Analogs::PadStickLeftY].isSet()) {
|
||||
STATUS_BUFFER[9] = (uint8_t) (GameAPI::Analogs::getState(RI_MGR,
|
||||
analogs[games::we::Analogs::PadStickLeftY]) * 255.9999f);
|
||||
}
|
||||
if (analogs[games::we::Analogs::PadStickRightX].isSet()) {
|
||||
STATUS_BUFFER[10] = (uint8_t) (GameAPI::Analogs::getState(RI_MGR,
|
||||
analogs[games::we::Analogs::PadStickRightX]) * 255.9999f);
|
||||
}
|
||||
if (analogs[games::we::Analogs::PadStickRightY].isSet()) {
|
||||
STATUS_BUFFER[11] = (uint8_t) (GameAPI::Analogs::getState(RI_MGR,
|
||||
analogs[games::we::Analogs::PadStickRightY]) * 255.9999f);
|
||||
}
|
||||
|
||||
// apply buttons
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadStart])) {
|
||||
STATUS_BUFFER[4] |= 0x08;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadSelect])) {
|
||||
STATUS_BUFFER[4] |= 0x01;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadUp])) {
|
||||
STATUS_BUFFER[4] |= 0x10;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadDown])) {
|
||||
STATUS_BUFFER[4] |= 0x40;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadLeft])) {
|
||||
STATUS_BUFFER[4] |= 0x80;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadRight])) {
|
||||
STATUS_BUFFER[4] |= 0x20;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadTriangle])) {
|
||||
STATUS_BUFFER[5] |= 0x10;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadCross])) {
|
||||
STATUS_BUFFER[5] |= 0x40;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadSquare])) {
|
||||
STATUS_BUFFER[5] |= 0x80;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadCircle])) {
|
||||
STATUS_BUFFER[5] |= 0x20;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadL1])) {
|
||||
STATUS_BUFFER[5] |= 0x04;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadL2])) {
|
||||
STATUS_BUFFER[5] |= 0x01;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadL3])) {
|
||||
STATUS_BUFFER[4] |= 0x02;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadR1])) {
|
||||
STATUS_BUFFER[5] |= 0x08;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadR2])) {
|
||||
STATUS_BUFFER[5] |= 0x02;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::PadR3])) {
|
||||
STATUS_BUFFER[4] |= 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
||||
acio::PJECModule::PJECModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("PJEC", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::PJECModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_pjec_get_ps2);
|
||||
ACIO_MODULE_HOOK(ac_io_pjec_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_pjec_update_control_status_buffer);
|
||||
}
|
||||
13
acio/pjec/pjec.h
Normal file
13
acio/pjec/pjec.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class PJECModule : public ACIOModule {
|
||||
public:
|
||||
PJECModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
223
acio/pjei/pjei.cpp
Normal file
223
acio/pjei/pjei.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
#include "pjei.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "util/utils.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "games/we/io.h"
|
||||
#include "avs/game.h"
|
||||
|
||||
//using namespace GameAPI;
|
||||
|
||||
// static stuff
|
||||
static uint8_t STATUS_BUFFER[40];
|
||||
static bool STATUS_BUFFER_FREEZE = false;
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static bool __cdecl ac_io_pjei_current_coinstock(int a1, uint32_t *coinstock) {
|
||||
*coinstock = eamuse_coin_get_stock();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_consume_coinstock(int a1, uint32_t amount) {
|
||||
return eamuse_coin_consume(amount);
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_get_softwareid(char *dst) {
|
||||
static char DATA[] = "0140FFFFFFFFFFFFFFFF";
|
||||
memcpy(dst, DATA, sizeof(DATA));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_get_systemid(char *dst) {
|
||||
static char DATA[] = "0140FFFFFFFFFFFFFFFF";
|
||||
memcpy(dst, DATA, sizeof(DATA));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_update_control_status_buffer() {
|
||||
|
||||
// check freeze
|
||||
if (STATUS_BUFFER_FREEZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// clear buffer
|
||||
memset(STATUS_BUFFER, 0, sizeof(STATUS_BUFFER));
|
||||
|
||||
// Winning Eleven
|
||||
if (avs::game::is_model({ "KCK", "NCK" })) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::we::get_buttons();
|
||||
|
||||
// apply buttons
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::Service])) {
|
||||
STATUS_BUFFER[16] |= 0x10;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::Test])) {
|
||||
STATUS_BUFFER[16] |= 0x20;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::CoinMech])) {
|
||||
STATUS_BUFFER[16] |= 0x04;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::Start])) {
|
||||
STATUS_BUFFER[4] |= 0x80;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::Up])) {
|
||||
STATUS_BUFFER[4] |= 0x40;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::Down])) {
|
||||
STATUS_BUFFER[4] |= 0x20;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::Left])) {
|
||||
STATUS_BUFFER[4] |= 0x10;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::Right])) {
|
||||
STATUS_BUFFER[4] |= 0x08;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::ButtonA])) {
|
||||
STATUS_BUFFER[4] |= 0x04;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::ButtonB])) {
|
||||
STATUS_BUFFER[4] |= 0x02;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::ButtonC])) {
|
||||
STATUS_BUFFER[4] |= 0x01;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::ButtonD])) {
|
||||
STATUS_BUFFER[6] |= 0x80;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::ButtonE])) {
|
||||
STATUS_BUFFER[6] |= 0x40;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[games::we::Buttons::ButtonF])) {
|
||||
STATUS_BUFFER[6] |= 0x20;
|
||||
}
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ac_io_pjei_get_control_status_buffer(uint8_t *buffer) {
|
||||
memcpy(buffer, STATUS_BUFFER, sizeof(STATUS_BUFFER));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_req_secplug_check() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_req_secplug_check_isfinished() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_req_secplug_missing_check() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_req_secplug_missing_check_isfinished() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_lock_coincounter(int a1) {
|
||||
eamuse_coin_set_block(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_unlock_coincounter(int a1) {
|
||||
eamuse_coin_set_block(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_control_coin_blocker_on(bool a1) {
|
||||
eamuse_coin_set_block(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_control_coin_blocker_off(bool a1) {
|
||||
eamuse_coin_set_block(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper method for easily setting the light values
|
||||
*/
|
||||
static void ac_io_pjei_control_lamp_set(uint8_t lamp_bits, uint8_t brightness) {
|
||||
auto &lights = games::we::get_lights();
|
||||
float value = CLAMP(brightness / 31.f, 0.f, 1.f);
|
||||
if (lamp_bits & 0x20) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[games::we::Lights::LeftRed], value);
|
||||
}
|
||||
if (lamp_bits & 0x10) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[games::we::Lights::LeftGreen], value);
|
||||
}
|
||||
if (lamp_bits & 0x08) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[games::we::Lights::LeftBlue], value);
|
||||
}
|
||||
if (lamp_bits & 0x04) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[games::we::Lights::RightRed], value);
|
||||
}
|
||||
if (lamp_bits & 0x02) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[games::we::Lights::RightGreen], value);
|
||||
}
|
||||
if (lamp_bits & 0x01) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights[games::we::Lights::RightBlue], value);
|
||||
}
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_control_lamp_on(uint8_t lamp_bits) {
|
||||
ac_io_pjei_control_lamp_set(lamp_bits, 31);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_control_lamp_off(uint8_t lamp_bits) {
|
||||
ac_io_pjei_control_lamp_set(lamp_bits, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_control_lamp_bright(uint8_t lamp_bit, uint8_t brightness) {
|
||||
ac_io_pjei_control_lamp_set(lamp_bit, brightness);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __cdecl ac_io_pjei_control_lamp_mode(int mode) {
|
||||
// mode -> [0,1] (0 is static, 1 is brightness?)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
acio::PJEIModule::PJEIModule(HMODULE module, acio::HookMode hookMode) : ACIOModule("PJEI", module, hookMode) {
|
||||
this->status_buffer = STATUS_BUFFER;
|
||||
this->status_buffer_size = sizeof(STATUS_BUFFER);
|
||||
this->status_buffer_freeze = &STATUS_BUFFER_FREEZE;
|
||||
}
|
||||
|
||||
void acio::PJEIModule::attach() {
|
||||
ACIOModule::attach();
|
||||
|
||||
// hooks
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_current_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_consume_coinstock);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_get_softwareid);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_get_systemid);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_update_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_get_control_status_buffer);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_req_secplug_check);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_req_secplug_check_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_req_secplug_missing_check);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_req_secplug_missing_check_isfinished);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_lock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_unlock_coincounter);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_control_coin_blocker_on);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_control_coin_blocker_off);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_control_lamp_on);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_control_lamp_off);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_control_lamp_bright);
|
||||
ACIO_MODULE_HOOK(ac_io_pjei_control_lamp_mode);
|
||||
}
|
||||
13
acio/pjei/pjei.h
Normal file
13
acio/pjei/pjei.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
|
||||
namespace acio {
|
||||
|
||||
class PJEIModule : public ACIOModule {
|
||||
public:
|
||||
PJEIModule(HMODULE module, HookMode hookMode);
|
||||
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user