#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); }