Initial re-upload of spice2x-24-08-24
This commit is contained in:
301
games/qma/ezusb.cpp
Normal file
301
games/qma/ezusb.cpp
Normal file
@@ -0,0 +1,301 @@
|
||||
#include "ezusb.h"
|
||||
|
||||
#include "cfg/api.h"
|
||||
#include "cfg/button.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "touch/touch.h"
|
||||
#include "util/detour.h"
|
||||
#include "util/libutils.h"
|
||||
#include "util/logging.h"
|
||||
|
||||
#include "io.h"
|
||||
|
||||
namespace games::qma {
|
||||
|
||||
static long DISPLAY_SIZE_X = 1360L;
|
||||
static long DISPLAY_SIZE_Y = 768L;
|
||||
|
||||
std::array<bool, 39> TOUCH_STATUS = {};
|
||||
std::array<int, 39> TOUCH_X_COORD = {230, 277, 323, 369, 417, 463, 510, 555, 601, 647, 695, 250, 296, 344, 389, 435, 483, 528, 575, 621, 667, 259, 308, 353, 398, 444, 491, 537, 582, 638, 280, 324, 370, 422, 465, 510, 557, 760, 759};
|
||||
std::array<int, 39> TOUCH_Y_COORD = {642, 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 813, 813, 813, 813, 813, 813, 813, 813, 813, 894, 894, 894, 894, 894, 894, 894, 771, 886};
|
||||
|
||||
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();
|
||||
|
||||
// mapping
|
||||
static const size_t bits[] = {
|
||||
0x20, 0x40, 0x80,
|
||||
0x08, 0x10, 0x20
|
||||
};
|
||||
static const size_t vals[] = {
|
||||
Lights::LampRed, Lights::LampGreen, Lights::LampBlue,
|
||||
Lights::ButtonLeft, Lights::ButtonRight, Lights::ButtonOK
|
||||
};
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
float value = (lamp_bits & bits[i]) ? 1.f : 0.f;
|
||||
GameAPI::Lights::writeLight(RI_MGR, lights.at(vals[i]), value);
|
||||
}
|
||||
|
||||
// return no error
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbPadRead(unsigned int *pad_bits) {
|
||||
|
||||
// get buttons
|
||||
auto &buttons = get_buttons();
|
||||
|
||||
// reset
|
||||
*pad_bits = 0;
|
||||
|
||||
// mappings
|
||||
static const struct {
|
||||
size_t button, shift;
|
||||
} mappings[] = {
|
||||
{ Buttons::Service, 19 },
|
||||
{ Buttons::Test, 18 },
|
||||
{ Buttons::Select, 17 },
|
||||
{ Buttons::CoinMech, 16 },
|
||||
{ Buttons::Select1, 0 },
|
||||
{ Buttons::Select2, 1 },
|
||||
{ Buttons::OK, 2 },
|
||||
{ Buttons::Left, 6 },
|
||||
{ Buttons::Right, 7 },
|
||||
{ Buttons::TouchKey1, 100 },
|
||||
{ Buttons::TouchKey2, 101 },
|
||||
{ Buttons::TouchKey3, 102 },
|
||||
{ Buttons::TouchKey4, 103 },
|
||||
{ Buttons::TouchKey5, 104 },
|
||||
{ Buttons::TouchKey6, 105 },
|
||||
{ Buttons::TouchKey7, 106 },
|
||||
{ Buttons::TouchKey8, 107 },
|
||||
{ Buttons::TouchKey9, 108 },
|
||||
{ Buttons::TouchKey0, 109 },
|
||||
{ Buttons::TouchKeyDash, 110 },
|
||||
{ Buttons::TouchKeyQ, 111 },
|
||||
{ Buttons::TouchKeyW, 112 },
|
||||
{ Buttons::TouchKeyE, 113 },
|
||||
{ Buttons::TouchKeyR, 114 },
|
||||
{ Buttons::TouchKeyT, 115 },
|
||||
{ Buttons::TouchKeyY, 116 },
|
||||
{ Buttons::TouchKeyU, 117 },
|
||||
{ Buttons::TouchKeyI, 118 },
|
||||
{ Buttons::TouchKeyO, 119 },
|
||||
{ Buttons::TouchKeyP, 120 },
|
||||
{ Buttons::TouchKeyA, 121 },
|
||||
{ Buttons::TouchKeyS, 122 },
|
||||
{ Buttons::TouchKeyD, 123 },
|
||||
{ Buttons::TouchKeyF, 124 },
|
||||
{ Buttons::TouchKeyG, 125 },
|
||||
{ Buttons::TouchKeyH, 126 },
|
||||
{ Buttons::TouchKeyJ, 127 },
|
||||
{ Buttons::TouchKeyK, 128 },
|
||||
{ Buttons::TouchKeyL, 129 },
|
||||
{ Buttons::TouchKeyZ, 130 },
|
||||
{ Buttons::TouchKeyX, 131 },
|
||||
{ Buttons::TouchKeyC, 132 },
|
||||
{ Buttons::TouchKeyV, 133 },
|
||||
{ Buttons::TouchKeyB, 134 },
|
||||
{ Buttons::TouchKeyN, 135 },
|
||||
{ Buttons::TouchKeyM, 136 },
|
||||
{ Buttons::TouchKeyBackspace, 137 },
|
||||
{ Buttons::TouchKeyEnter, 138 }
|
||||
};
|
||||
|
||||
// set buttons
|
||||
for (auto &mapping : mappings) {
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(mapping.button))) {
|
||||
if (mapping.shift > 99) {
|
||||
if (!TOUCH_STATUS[mapping.shift - 100]) {
|
||||
|
||||
static RECT display_rect;
|
||||
GetWindowRect(GetDesktopWindow(), &display_rect);
|
||||
DISPLAY_SIZE_X = display_rect.right - display_rect.left;
|
||||
DISPLAY_SIZE_Y = display_rect.bottom - display_rect.top;
|
||||
|
||||
std::vector<TouchPoint> touch_write;
|
||||
std::vector<DWORD> touch_point_ids;
|
||||
TouchPoint tp {
|
||||
.id = 0,
|
||||
.x = (long)(TOUCH_X_COORD[mapping.shift - 100] * DISPLAY_SIZE_X / 1000),
|
||||
.y = (long)(TOUCH_Y_COORD[mapping.shift - 100] * DISPLAY_SIZE_Y / 1000),
|
||||
.mouse = false,
|
||||
};
|
||||
TOUCH_STATUS[mapping.shift - 100] = true;
|
||||
touch_write.emplace_back(tp);
|
||||
touch_write_points(&touch_write);
|
||||
|
||||
touch_point_ids.emplace_back(0);
|
||||
touch_remove_points(&touch_point_ids);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
*pad_bits |= 1 << mapping.shift;
|
||||
}
|
||||
} else {
|
||||
if (mapping.shift > 99) {
|
||||
TOUCH_STATUS[mapping.shift - 100] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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() {
|
||||
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 int __cdecl usbCoinBlocker(int a1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbMute(int a1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl usbIsHiSpeed() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ezusb_init() {
|
||||
|
||||
TOUCH_STATUS.fill(false);
|
||||
// load the library
|
||||
HINSTANCE ezusb = libutils::try_library("ezusb.dll");
|
||||
|
||||
// insert hooks
|
||||
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"));
|
||||
detour::inline_hook((void *) usbCoinBlocker,
|
||||
libutils::try_proc(ezusb, "?usbCoinBlocker@@YAHH@Z"));
|
||||
detour::inline_hook((void *) usbMute,
|
||||
libutils::try_proc(ezusb, "?usbMute@@YAHH@Z"));
|
||||
detour::inline_hook((void *) usbIsHiSpeed,
|
||||
libutils::try_proc(ezusb, "?usbIsHiSpeed@@YAHXZ"));
|
||||
}
|
||||
}
|
||||
}
|
||||
6
games/qma/ezusb.h
Normal file
6
games/qma/ezusb.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace games::qma {
|
||||
|
||||
void ezusb_init();
|
||||
}
|
||||
83
games/qma/io.cpp
Normal file
83
games/qma/io.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "io.h"
|
||||
|
||||
std::vector<Button> &games::qma::get_buttons() {
|
||||
static std::vector<Button> buttons;
|
||||
|
||||
if (buttons.empty()) {
|
||||
buttons = GameAPI::Buttons::getButtons("Quiz Magic Academy");
|
||||
|
||||
GameAPI::Buttons::sortButtons(
|
||||
&buttons,
|
||||
"Service",
|
||||
"Test",
|
||||
"Select",
|
||||
"Coin Mech",
|
||||
"Select 1",
|
||||
"Select 2",
|
||||
"Left",
|
||||
"Right",
|
||||
"OK",
|
||||
"Touch Keyboard - 1",
|
||||
"Touch Keyboard - 2",
|
||||
"Touch Keyboard - 3",
|
||||
"Touch Keyboard - 4",
|
||||
"Touch Keyboard - 5",
|
||||
"Touch Keyboard - 6",
|
||||
"Touch Keyboard - 7",
|
||||
"Touch Keyboard - 8",
|
||||
"Touch Keyboard - 9",
|
||||
"Touch Keyboard - 0",
|
||||
"Touch Keyboard - -",
|
||||
"Touch Keyboard - Q",
|
||||
"Touch Keyboard - W",
|
||||
"Touch Keyboard - E",
|
||||
"Touch Keyboard - R",
|
||||
"Touch Keyboard - T",
|
||||
"Touch Keyboard - Y",
|
||||
"Touch Keyboard - U",
|
||||
"Touch Keyboard - I",
|
||||
"Touch Keyboard - O",
|
||||
"Touch Keyboard - P",
|
||||
"Touch Keyboard - A",
|
||||
"Touch Keyboard - S",
|
||||
"Touch Keyboard - D",
|
||||
"Touch Keyboard - F",
|
||||
"Touch Keyboard - G",
|
||||
"Touch Keyboard - H",
|
||||
"Touch Keyboard - J",
|
||||
"Touch Keyboard - K",
|
||||
"Touch Keyboard - L",
|
||||
"Touch Keyboard - Z",
|
||||
"Touch Keyboard - X",
|
||||
"Touch Keyboard - C",
|
||||
"Touch Keyboard - V",
|
||||
"Touch Keyboard - B",
|
||||
"Touch Keyboard - N",
|
||||
"Touch Keyboard - M",
|
||||
"Touch Keyboard - Backspace",
|
||||
"Touch Keyboard - Enter"
|
||||
);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
std::vector<Light> &games::qma::get_lights() {
|
||||
static std::vector<Light> lights;
|
||||
|
||||
if (lights.empty()) {
|
||||
lights = GameAPI::Lights::getLights("Quiz Magic Academy");
|
||||
|
||||
GameAPI::Lights::sortLights(
|
||||
&lights,
|
||||
"Lamp Red",
|
||||
"Lamp Green",
|
||||
"Lamp Blue",
|
||||
"Button Left",
|
||||
"Button Right",
|
||||
"Button OK"
|
||||
);
|
||||
}
|
||||
|
||||
return lights;
|
||||
}
|
||||
77
games/qma/io.h
Normal file
77
games/qma/io.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "cfg/api.h"
|
||||
|
||||
namespace games::qma {
|
||||
|
||||
// all buttons in correct order
|
||||
namespace Buttons {
|
||||
enum {
|
||||
Service,
|
||||
Test,
|
||||
Select,
|
||||
CoinMech,
|
||||
Select1,
|
||||
Select2,
|
||||
Left,
|
||||
Right,
|
||||
OK,
|
||||
TouchKey1,
|
||||
TouchKey2,
|
||||
TouchKey3,
|
||||
TouchKey4,
|
||||
TouchKey5,
|
||||
TouchKey6,
|
||||
TouchKey7,
|
||||
TouchKey8,
|
||||
TouchKey9,
|
||||
TouchKey0,
|
||||
TouchKeyDash,
|
||||
TouchKeyQ,
|
||||
TouchKeyW,
|
||||
TouchKeyE,
|
||||
TouchKeyR,
|
||||
TouchKeyT,
|
||||
TouchKeyY,
|
||||
TouchKeyU,
|
||||
TouchKeyI,
|
||||
TouchKeyO,
|
||||
TouchKeyP,
|
||||
TouchKeyA,
|
||||
TouchKeyS,
|
||||
TouchKeyD,
|
||||
TouchKeyF,
|
||||
TouchKeyG,
|
||||
TouchKeyH,
|
||||
TouchKeyJ,
|
||||
TouchKeyK,
|
||||
TouchKeyL,
|
||||
TouchKeyZ,
|
||||
TouchKeyX,
|
||||
TouchKeyC,
|
||||
TouchKeyV,
|
||||
TouchKeyB,
|
||||
TouchKeyN,
|
||||
TouchKeyM,
|
||||
TouchKeyBackspace,
|
||||
TouchKeyEnter
|
||||
};
|
||||
}
|
||||
|
||||
// all lights in correct order
|
||||
namespace Lights {
|
||||
enum {
|
||||
LampRed,
|
||||
LampGreen,
|
||||
LampBlue,
|
||||
ButtonLeft,
|
||||
ButtonRight,
|
||||
ButtonOK
|
||||
};
|
||||
}
|
||||
|
||||
// getters
|
||||
std::vector<Button> &get_buttons();
|
||||
std::vector<Light> &get_lights();
|
||||
}
|
||||
135
games/qma/qma.cpp
Normal file
135
games/qma/qma.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include "qma.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "games/shared/lcdhandle.h"
|
||||
#include "games/shared/twtouch.h"
|
||||
#include "hooks/graphics/graphics.h"
|
||||
#include "hooks/devicehook.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "util/detour.h"
|
||||
#include "util/fileutils.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
#include "ezusb.h"
|
||||
|
||||
namespace games::qma {
|
||||
|
||||
/**
|
||||
* Overridden touchscreen for attaching the touch hooks to the window.
|
||||
*/
|
||||
class QMATouchDevice : public games::shared::TwTouchDevice {
|
||||
public:
|
||||
bool open(LPCWSTR lpFileName) override {
|
||||
|
||||
// check if device was opened
|
||||
auto result = TwTouchDevice::open(lpFileName);
|
||||
if (result) {
|
||||
if (GRAPHICS_WINDOWED) {
|
||||
|
||||
// get game window
|
||||
HWND wnd = GetForegroundWindow();
|
||||
if (!string_begins_with(GetActiveWindowTitle(), "QMA")) {
|
||||
wnd = FindWindowBeginsWith("QMA");
|
||||
}
|
||||
|
||||
if (wnd != nullptr) {
|
||||
|
||||
// get client area
|
||||
RECT rect {};
|
||||
GetClientRect(wnd, &rect);
|
||||
|
||||
// remove style borders
|
||||
LONG lStyle = GetWindowLong(wnd, GWL_STYLE);
|
||||
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
|
||||
SetWindowLongPtr(wnd, GWL_STYLE, lStyle);
|
||||
|
||||
// remove ex style borders
|
||||
LONG lExStyle = GetWindowLong(wnd, GWL_EXSTYLE);
|
||||
lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
|
||||
SetWindowLongPtr(wnd, GWL_EXSTYLE, lExStyle);
|
||||
|
||||
// update window
|
||||
AdjustWindowRect(&rect, lStyle, FALSE);
|
||||
SetWindowPos(wnd, nullptr,
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
||||
SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
}
|
||||
}
|
||||
|
||||
// attach touch
|
||||
touch_attach_dx_hook();
|
||||
|
||||
// cursor
|
||||
if (!is_touch_available()) {
|
||||
ShowCursor(true);
|
||||
}
|
||||
}
|
||||
|
||||
// return result
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* The game likes to crash if E:\LMA\quiz13 does not exist.
|
||||
* Therefore we create it when the game tries to access E:\LMA the first time.
|
||||
*/
|
||||
namespace dirfix {
|
||||
|
||||
static decltype(CreateFileW) *CreateFileW_real = nullptr;
|
||||
|
||||
static HANDLE WINAPI CreateFileW_Hook(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
|
||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
|
||||
DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) {
|
||||
|
||||
// create quiz directory
|
||||
static bool dirs_created = false;
|
||||
if (!dirs_created && _wcsnicmp(lpFileName, L"E:\\LMA", 6) == 0) {
|
||||
fileutils::dir_create_recursive("E:\\LMA\\quiz11");
|
||||
fileutils::dir_create_recursive("E:\\LMA\\quiz13");
|
||||
fileutils::dir_create_recursive("E:\\LMA\\quiz15");
|
||||
dirs_created = true;
|
||||
}
|
||||
|
||||
// return result
|
||||
return CreateFileW_real(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
|
||||
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
|
||||
}
|
||||
|
||||
void apply() {
|
||||
CreateFileW_real = detour::iat_try("CreateFileW", CreateFileW_Hook);
|
||||
}
|
||||
}
|
||||
|
||||
QMAGame::QMAGame() : Game("Quiz Magic Academy") {
|
||||
}
|
||||
|
||||
void QMAGame::pre_attach() {
|
||||
Game::pre_attach();
|
||||
|
||||
// load without resolving references
|
||||
// makes game not trigger DLLMain since that does some EZUSB device stuff
|
||||
LoadLibraryExW((MODULE_PATH / "ezusb.dll").c_str(), nullptr, DONT_RESOLVE_DLL_REFERENCES);
|
||||
}
|
||||
|
||||
void QMAGame::attach() {
|
||||
Game::attach();
|
||||
|
||||
// init device hooks
|
||||
devicehook_init();
|
||||
devicehook_add(new games::shared::LCDHandle());
|
||||
devicehook_add(new games::qma::QMATouchDevice());
|
||||
|
||||
// EZUSB for button input
|
||||
ezusb_init();
|
||||
|
||||
// disable multi-head mode
|
||||
D3D9_BEHAVIOR_DISABLE = D3DCREATE_ADAPTERGROUP_DEVICE;
|
||||
|
||||
// directory fix
|
||||
dirfix::apply();
|
||||
}
|
||||
}
|
||||
13
games/qma/qma.h
Normal file
13
games/qma/qma.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "games/game.h"
|
||||
|
||||
namespace games::qma {
|
||||
|
||||
class QMAGame : public games::Game {
|
||||
public:
|
||||
QMAGame();
|
||||
virtual void pre_attach() override;
|
||||
virtual void attach() override;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user