Initial re-upload of spice2x-24-08-24
This commit is contained in:
97
games/popn/io.cpp
Normal file
97
games/popn/io.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "io.h"
|
||||
|
||||
std::vector<Button> &games::popn::get_buttons() {
|
||||
static std::vector<Button> buttons;
|
||||
|
||||
if (buttons.empty()) {
|
||||
buttons = GameAPI::Buttons::getButtons("Pop'n Music");
|
||||
|
||||
GameAPI::Buttons::sortButtons(
|
||||
&buttons,
|
||||
"Service",
|
||||
"Test",
|
||||
"Coin Mech",
|
||||
"Button 1",
|
||||
"Button 2",
|
||||
"Button 3",
|
||||
"Button 4",
|
||||
"Button 5",
|
||||
"Button 6",
|
||||
"Button 7",
|
||||
"Button 8",
|
||||
"Button 9"
|
||||
);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
std::vector<Light> &games::popn::get_lights() {
|
||||
static std::vector<Light> lights;
|
||||
|
||||
if (lights.empty()) {
|
||||
lights = GameAPI::Lights::getLights("Pop'n Music");
|
||||
|
||||
GameAPI::Lights::sortLights(
|
||||
&lights,
|
||||
"Button 1",
|
||||
"Button 2",
|
||||
"Button 3",
|
||||
"Button 4",
|
||||
"Button 5",
|
||||
"Button 6",
|
||||
"Button 7",
|
||||
"Button 8",
|
||||
"Button 9",
|
||||
"Top LED 1",
|
||||
"Top LED 2",
|
||||
"Top LED 3",
|
||||
"Top LED 4",
|
||||
"Top LED 5",
|
||||
"Top LED 6",
|
||||
"Top LED 7",
|
||||
"Top LED 8",
|
||||
"Top LED 9",
|
||||
"Top LED 10",
|
||||
"Top LED 11",
|
||||
"Top LED 12",
|
||||
"Top LED 13",
|
||||
"Top LED 14",
|
||||
"Top LED 15",
|
||||
"Top LED 16",
|
||||
"Top LED 17",
|
||||
"Top LED 18",
|
||||
"Top LED 19",
|
||||
"Top LED 20",
|
||||
"Top LED 21",
|
||||
"Top LED 22",
|
||||
"Top LED 23",
|
||||
"Top LED 24",
|
||||
"Top LED 25",
|
||||
"Top LED 26",
|
||||
"Top LED 27",
|
||||
"Top LED 28",
|
||||
"Top LED 29",
|
||||
"Top LED 30",
|
||||
"Top LED 31",
|
||||
"Top LED 32",
|
||||
"Top LED R",
|
||||
"Top LED G",
|
||||
"Top LED B",
|
||||
"Hi Lamp 1",
|
||||
"Hi Lamp 2",
|
||||
"Hi Lamp 3",
|
||||
"Hi Lamp 4",
|
||||
"Hi Lamp 5",
|
||||
"Left Lamp 1",
|
||||
"Left Lamp 2",
|
||||
"Right Lamp 1",
|
||||
"Right Lamp 2",
|
||||
"Woofer LED R",
|
||||
"Woofer LED G",
|
||||
"Woofer LED B"
|
||||
);
|
||||
}
|
||||
|
||||
return lights;
|
||||
}
|
||||
91
games/popn/io.h
Normal file
91
games/popn/io.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "cfg/api.h"
|
||||
|
||||
namespace games::popn {
|
||||
|
||||
// all buttons in correct order
|
||||
namespace Buttons {
|
||||
enum {
|
||||
Service,
|
||||
Test,
|
||||
CoinMech,
|
||||
Button1,
|
||||
Button2,
|
||||
Button3,
|
||||
Button4,
|
||||
Button5,
|
||||
Button6,
|
||||
Button7,
|
||||
Button8,
|
||||
Button9,
|
||||
};
|
||||
}
|
||||
|
||||
// all lights in correct order
|
||||
namespace Lights {
|
||||
enum {
|
||||
Button1,
|
||||
Button2,
|
||||
Button3,
|
||||
Button4,
|
||||
Button5,
|
||||
Button6,
|
||||
Button7,
|
||||
Button8,
|
||||
Button9,
|
||||
TopLED1,
|
||||
TopLED2,
|
||||
TopLED3,
|
||||
TopLED4,
|
||||
TopLED5,
|
||||
TopLED6,
|
||||
TopLED7,
|
||||
TopLED8,
|
||||
TopLED9,
|
||||
TopLED10,
|
||||
TopLED11,
|
||||
TopLED12,
|
||||
TopLED13,
|
||||
TopLED14,
|
||||
TopLED15,
|
||||
TopLED16,
|
||||
TopLED17,
|
||||
TopLED18,
|
||||
TopLED19,
|
||||
TopLED20,
|
||||
TopLED21,
|
||||
TopLED22,
|
||||
TopLED23,
|
||||
TopLED24,
|
||||
TopLED25,
|
||||
TopLED26,
|
||||
TopLED27,
|
||||
TopLED28,
|
||||
TopLED29,
|
||||
TopLED30,
|
||||
TopLED31,
|
||||
TopLED32,
|
||||
TopLED_R,
|
||||
TopLED_G,
|
||||
TopLED_B,
|
||||
HiLamp1,
|
||||
HiLamp2,
|
||||
HiLamp3,
|
||||
HiLamp4,
|
||||
HiLamp5,
|
||||
LeftLamp1,
|
||||
LeftLamp2,
|
||||
RightLamp1,
|
||||
RightLamp2,
|
||||
WooferLED_R,
|
||||
WooferLED_G,
|
||||
WooferLED_B,
|
||||
};
|
||||
}
|
||||
|
||||
// getters
|
||||
std::vector<Button> &get_buttons();
|
||||
std::vector<Light> &get_lights();
|
||||
}
|
||||
324
games/popn/popn.cpp
Normal file
324
games/popn/popn.cpp
Normal file
@@ -0,0 +1,324 @@
|
||||
#include "avs/game.h"
|
||||
#include "popn.h"
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "util/detour.h"
|
||||
#include "util/fileutils.h"
|
||||
#include "util/libutils.h"
|
||||
#include "util/utils.h"
|
||||
#include "cfg/button.h"
|
||||
#include "cfg/api.h"
|
||||
#include "hooks/sleephook.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "launcher/logger.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "io.h"
|
||||
|
||||
namespace games::popn {
|
||||
|
||||
static int __cdecl usbCheckAlive() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __cdecl usbCheckSecurityNew() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbCoinGet() {
|
||||
return eamuse_coin_get_stock();
|
||||
}
|
||||
|
||||
static int __cdecl usbCoinMode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbEnd() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbFirmResult() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbGetKEYID() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbGetSecurity() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbLamp(uint32_t lamp_bits) {
|
||||
|
||||
// get lights
|
||||
auto &lights = get_lights();
|
||||
|
||||
// bit scan
|
||||
static const size_t mapping[] = {
|
||||
Lights::Button1,
|
||||
Lights::Button2,
|
||||
Lights::Button3,
|
||||
Lights::Button4,
|
||||
Lights::Button5,
|
||||
Lights::Button6,
|
||||
Lights::Button7,
|
||||
Lights::Button8,
|
||||
Lights::Button9,
|
||||
Lights::HiLamp1,
|
||||
Lights::HiLamp2,
|
||||
Lights::HiLamp3,
|
||||
Lights::HiLamp4,
|
||||
Lights::HiLamp5,
|
||||
Lights::LeftLamp1,
|
||||
Lights::LeftLamp2,
|
||||
Lights::RightLamp1,
|
||||
Lights::RightLamp2,
|
||||
};
|
||||
|
||||
// sw lamps
|
||||
for (size_t i = 0; i < 9; i++) {
|
||||
float value = (lamp_bits & (1 << (i + 23))) ? 1.f : 0.f;
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(mapping[i]), value);
|
||||
}
|
||||
// neon lamps
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
float value = (lamp_bits & (1 << i)) ? 1.f : 0.f;
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(mapping[i + 9]), value);
|
||||
}
|
||||
// screen lamps
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
float value = (lamp_bits & (1 << (i + 8))) ? 1.f : 0.f;
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(mapping[i + 14]), value);
|
||||
}
|
||||
|
||||
// flush output
|
||||
RI_MGR->devices_flush_output();
|
||||
|
||||
// return no error
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbPadRead(unsigned int *pad_bits) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = get_buttons();
|
||||
|
||||
// reset
|
||||
*pad_bits = 0;
|
||||
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(Buttons::Service))) {
|
||||
*pad_bits |= 1 << 6;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(Buttons::Test))) {
|
||||
*pad_bits |= 1 << 7;
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(Buttons::CoinMech))) {
|
||||
*pad_bits |= 1 << 22;
|
||||
}
|
||||
|
||||
// buttons
|
||||
static const size_t mapping[] = {
|
||||
Buttons::Button1,
|
||||
Buttons::Button2,
|
||||
Buttons::Button3,
|
||||
Buttons::Button4,
|
||||
Buttons::Button5,
|
||||
Buttons::Button6,
|
||||
Buttons::Button7,
|
||||
Buttons::Button8,
|
||||
Buttons::Button9,
|
||||
};
|
||||
for (size_t i = 0; i < 9; i++) {
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(mapping[i]))) {
|
||||
*pad_bits |= 1 << (8 + i);
|
||||
}
|
||||
}
|
||||
|
||||
// return no error
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbPadReadLast(uint8_t *a1) {
|
||||
memset(a1, 0, 40);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbSecurityInit() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbSecurityInitDone() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbSecuritySearch() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbSecuritySearchDone() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbSecuritySelect() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbSecuritySelectDone() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbSetExtIo(uint32_t rgb_bits) {
|
||||
|
||||
// get lights
|
||||
auto &lights = get_lights();
|
||||
|
||||
// bit scan
|
||||
static const size_t mapping[] = {
|
||||
Lights::WooferLED_R,
|
||||
Lights::WooferLED_G,
|
||||
Lights::WooferLED_B,
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
float value = (rgb_bits & (1 << (i + 1)));
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(mapping[i]), value);
|
||||
}
|
||||
|
||||
// flush output
|
||||
RI_MGR->devices_flush_output();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbStart() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbWdtReset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbWdtStart() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbWdtStartDone() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static decltype(DeleteFileA)* DeleteFileA_real = nullptr;
|
||||
|
||||
static BOOL WINAPI DeleteFileA_hook(LPCSTR lpFileName) {
|
||||
|
||||
// fantasia deletes a bunch of drmfs files in dll_entry_init
|
||||
if (string_begins_with(lpFileName, "D:\\L39\\contents")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return DeleteFileA_real(lpFileName);
|
||||
}
|
||||
|
||||
static decltype(mixerSetControlDetails)* mixerSetControlDetails_real = nullptr;
|
||||
|
||||
static MMRESULT WINAPI mixerSetControlDetails_hook(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails) {
|
||||
|
||||
mixerSetControlDetails_real(hmxobj, pmxcd, fdwDetails);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
static bool log_hook(void *user, const std::string &data, logger::Style style, std::string &out) {
|
||||
|
||||
// get rid of the log spam
|
||||
if (data.find(" I:CabinetSettingFile: label:") != std::string::npos) {
|
||||
out.clear();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
POPNGame::POPNGame() : Game("Pop'n Music") {
|
||||
logger::hook_add(log_hook, this);
|
||||
}
|
||||
|
||||
POPNGame::~POPNGame() {
|
||||
logger::hook_remove(log_hook, this);
|
||||
}
|
||||
|
||||
void POPNGame::pre_attach() {
|
||||
Game::pre_attach();
|
||||
|
||||
// only needed for older versions (19-21, inclusive) but create them anyway since 21 and above are all M39
|
||||
fileutils::dir_create_recursive_log("popn", "dev\\raw\\bookkeeping");
|
||||
fileutils::dir_create_recursive_log("popn", "dev\\raw\\ranking");
|
||||
fileutils::dir_create_recursive_log("popn", "dev\\raw\\settings");
|
||||
|
||||
// load without resolving references
|
||||
// makes game not trigger DLLMain which results in an error due to missing EZUSB device
|
||||
LoadLibraryExW((MODULE_PATH / "ezusb.dll").c_str(), nullptr, DONT_RESOLVE_DLL_REFERENCES);
|
||||
}
|
||||
|
||||
void POPNGame::attach() {
|
||||
Game::attach();
|
||||
|
||||
/*
|
||||
* Fast Boot (TM) Patch
|
||||
* Game tries to create some directories and if it fails it will sleep for 1 second
|
||||
* We make it sleep 1ms each time instead
|
||||
*/
|
||||
hooks::sleep::init(999, 1);
|
||||
|
||||
DeleteFileA_real = detour::iat_try("DeleteFileA", DeleteFileA_hook, avs::game::DLL_INSTANCE);
|
||||
mixerSetControlDetails_real = detour::iat_try("mixerSetControlDetails", mixerSetControlDetails_hook, avs::game::DLL_INSTANCE);
|
||||
|
||||
// EZUSB hooks
|
||||
HINSTANCE ezusb = libutils::try_library("ezusb.dll");
|
||||
if (ezusb) {
|
||||
detour::inline_hook((void *) usbCheckAlive,
|
||||
libutils::try_proc(ezusb, "?usbCheckAlive@@YAHXZ"));
|
||||
detour::inline_hook((void *) usbCheckSecurityNew,
|
||||
libutils::try_proc(ezusb, "?usbCheckSecurityNew@@YAHH@Z"));
|
||||
detour::inline_hook((void *) usbCoinGet,
|
||||
libutils::try_proc(ezusb, "?usbCoinGet@@YAHH@Z"));
|
||||
detour::inline_hook((void *) usbCoinMode,
|
||||
libutils::try_proc(ezusb, "?usbCoinMode@@YAHH@Z"));
|
||||
detour::inline_hook((void *) usbEnd,
|
||||
libutils::try_proc(ezusb, "?usbEnd@@YAHXZ"));
|
||||
detour::inline_hook((void *) usbFirmResult,
|
||||
libutils::try_proc(ezusb, "?usbFirmResult@@YAHXZ"));
|
||||
detour::inline_hook((void *) usbGetKEYID,
|
||||
libutils::try_proc(ezusb, "?usbGetKEYID@@YAHPAEH@Z"));
|
||||
detour::inline_hook((void *) usbGetSecurity,
|
||||
libutils::try_proc(ezusb, "?usbGetSecurity@@YAHHPAE@Z"));
|
||||
detour::inline_hook((void *) usbLamp,
|
||||
libutils::try_proc(ezusb, "?usbLamp@@YAHH@Z"));
|
||||
detour::inline_hook((void *) usbPadRead,
|
||||
libutils::try_proc(ezusb, "?usbPadRead@@YAHPAK@Z"));
|
||||
detour::inline_hook((void *) usbPadReadLast,
|
||||
libutils::try_proc(ezusb, "?usbPadReadLast@@YAHPAE@Z"));
|
||||
detour::inline_hook((void *) usbSecurityInit,
|
||||
libutils::try_proc(ezusb, "?usbSecurityInit@@YAHXZ"));
|
||||
detour::inline_hook((void *) usbSecurityInitDone,
|
||||
libutils::try_proc(ezusb, "?usbSecurityInitDone@@YAHXZ"));
|
||||
detour::inline_hook((void *) usbSecuritySearch,
|
||||
libutils::try_proc(ezusb, "?usbSecuritySearch@@YAHXZ"));
|
||||
detour::inline_hook((void *) usbSecuritySearchDone,
|
||||
libutils::try_proc(ezusb, "?usbSecuritySearchDone@@YAHXZ"));
|
||||
detour::inline_hook((void *) usbSecuritySelect,
|
||||
libutils::try_proc(ezusb, "?usbSecuritySelect@@YAHH@Z"));
|
||||
detour::inline_hook((void *) usbSecuritySelectDone,
|
||||
libutils::try_proc(ezusb, "?usbSecuritySelectDone@@YAHXZ"));
|
||||
detour::inline_hook((void *) usbSetExtIo,
|
||||
libutils::try_proc(ezusb, "?usbSetExtIo@@YAHH@Z"));
|
||||
detour::inline_hook((void *) usbStart,
|
||||
libutils::try_proc(ezusb, "?usbStart@@YAHH@Z"));
|
||||
detour::inline_hook((void *) usbWdtReset,
|
||||
libutils::try_proc(ezusb, "?usbWdtReset@@YAHXZ"));
|
||||
detour::inline_hook((void *) usbWdtStart,
|
||||
libutils::try_proc(ezusb, "?usbWdtStart@@YAHH@Z"));
|
||||
detour::inline_hook((void *) usbWdtStartDone,
|
||||
libutils::try_proc(ezusb, "?usbWdtStartDone@@YAHXZ"));
|
||||
}
|
||||
}
|
||||
}
|
||||
14
games/popn/popn.h
Normal file
14
games/popn/popn.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "games/game.h"
|
||||
|
||||
namespace games::popn {
|
||||
|
||||
class POPNGame : public games::Game {
|
||||
public:
|
||||
POPNGame();
|
||||
~POPNGame() override;
|
||||
virtual void pre_attach() override;
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user