764 lines
28 KiB
C++
764 lines
28 KiB
C++
#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);
|
|
}
|