spicetools/acio/klpa/klpa.cpp

239 lines
6.4 KiB
C++

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