spicetools/acio/hdxs/hdxs.cpp

201 lines
6.5 KiB
C++

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