spicetools/acio/pix/pix.cpp

521 lines
18 KiB
C++

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