Initial re-upload of spice2x-24-08-24

This commit is contained in:
2024-08-28 11:10:34 -04:00
commit caa9e02285
1181 changed files with 380065 additions and 0 deletions

83
games/we/io.cpp Normal file
View File

@@ -0,0 +1,83 @@
#include "io.h"
std::vector<Button> &games::we::get_buttons() {
static std::vector<Button> buttons;
if (buttons.empty()) {
buttons = GameAPI::Buttons::getButtons("Winning Eleven");
GameAPI::Buttons::sortButtons(
&buttons,
"Service",
"Test",
"Coin Mech",
"Start",
"Up",
"Down",
"Left",
"Right",
"Button A",
"Button B",
"Button C",
"Button D",
"Button E",
"Button F",
"Pad Start",
"Pad Select",
"Pad Up",
"Pad Down",
"Pad Left",
"Pad Right",
"Pad Triangle",
"Pad Cross",
"Pad Square",
"Pad Circle",
"Pad L1",
"Pad L2",
"Pad L3",
"Pad R1",
"Pad R2",
"Pad R3"
);
}
return buttons;
}
std::vector<Analog> &games::we::get_analogs() {
static std::vector<Analog> analogs;
if (analogs.empty()) {
analogs = GameAPI::Analogs::getAnalogs("Winning Eleven");
GameAPI::Analogs::sortAnalogs(
&analogs,
"Pad Stick Left X",
"Pad Stick Left Y",
"Pad Stick Right X",
"Pad Stick Right Y"
);
}
return analogs;
}
std::vector<Light> &games::we::get_lights() {
static std::vector<Light> lights;
if (lights.empty()) {
lights = GameAPI::Lights::getLights("Winning Eleven");
GameAPI::Lights::sortLights(
&lights,
"Left Red",
"Left Green",
"Left Blue",
"Right Red",
"Right Green",
"Right Blue"
);
}
return lights;
}

70
games/we/io.h Normal file
View File

@@ -0,0 +1,70 @@
#pragma once
#include <vector>
#include "cfg/api.h"
namespace games::we {
// all buttons in correct order
namespace Buttons {
enum {
Service,
Test,
CoinMech,
Start,
Up,
Down,
Left,
Right,
ButtonA,
ButtonB,
ButtonC,
ButtonD,
ButtonE,
ButtonF,
PadStart,
PadSelect,
PadUp,
PadDown,
PadLeft,
PadRight,
PadTriangle,
PadCross,
PadSquare,
PadCircle,
PadL1,
PadL2,
PadL3,
PadR1,
PadR2,
PadR3,
};
}
// all analogs in correct order
namespace Analogs {
enum {
PadStickLeftX,
PadStickLeftY,
PadStickRightX,
PadStickRightY,
};
}
// all lights in correct order
namespace Lights {
enum {
LeftRed,
LeftGreen,
LeftBlue,
RightRed,
RightGreen,
RightBlue,
};
}
// getters
std::vector<Button> &get_buttons();
std::vector<Analog> &get_analogs();
std::vector<Light> &get_lights();
}

141
games/we/touchpanel.cpp Normal file
View File

@@ -0,0 +1,141 @@
#include "touchpanel.h"
#include <cstdint>
#include "hooks/graphics/graphics.h"
#include "util/detour.h"
#include "util/time.h"
namespace games::we {
struct TouchPanel {
int width, height;
uint8_t com_port;
uint64_t wait_receive_time;
};
static TouchPanel* __cdecl ac_touchpanel_new2(int width, int height, uint8_t com_port) {
auto tp = new TouchPanel();
tp->width = width;
tp->height = height;
tp->com_port = com_port;
tp->wait_receive_time = 0;
return tp;
}
static bool __cdecl ac_touchpanel_polling(TouchPanel *tp) {
return true;
}
static bool __cdecl ac_touchpanel_set_keepalive_mode(TouchPanel *tp, uint8_t a2, int a3, int a4) {
return true;
}
static bool __cdecl ac_touchpanel_renewal(TouchPanel *tp) {
return true;
}
static bool __cdecl ac_touchpanel_check_wait_receive(TouchPanel *tp) {
if (tp) {
return get_system_milliseconds() >= tp->wait_receive_time;
}
return false;
}
static bool __cdecl ac_touchpanel_delete(TouchPanel *tp) {
if (tp) {
delete tp;
return true;
}
return false;
}
static bool __cdecl ac_touchpanel_get_keepalive_error(TouchPanel *tp) {
return false;
}
static bool __cdecl ac_touchpanel_receive_check_diag(TouchPanel *tp, uint8_t *value) {
*value = 1;
return true;
}
static bool __cdecl ac_touchpanel_caribrate_set(TouchPanel *tp, int a2, int a3, int a4, int a5,
int width, int height, int a8, int a9) {
if (tp) {
tp->width = width;
tp->height = height;
return true;
}
return false;
}
static bool __cdecl ac_touchpanel_send_check_diag(TouchPanel *tp) {
if (tp) {
tp->wait_receive_time = get_system_milliseconds() + 128;
return true;
}
return false;
}
static void ac_touchpanel_translate(LPPOINT lpPoint) {
// try to find game window - the second window without title
static HWND target = 0;
if (target == 0) {
bool skip = false;
for (auto &hWnd : GRAPHICS_WINDOWS) {
char buffer[2] {};
auto len = GetWindowTextA(hWnd, buffer, sizeof(buffer));
if (len == 0) {
if (skip) {
target = hWnd;
break;
} else {
skip = true;
}
}
}
}
// translate screen coordinates to game window
if (target) {
ScreenToClient(target, lpPoint);
}
}
static bool __cdecl ac_touchpanel_read_on(TouchPanel *tp, int *x, int *y, int *z, bool *down) {
POINT pt {};
GetCursorPos(&pt);
ac_touchpanel_translate(&pt);
*x = pt.x;
*y = pt.y;
*z = 0xFF;
*down = GetKeyState(VK_LBUTTON) != 0;
return true;
}
static bool __cdecl ac_touchpanel_read_on_direct(TouchPanel *tp, int *x, int *y, int *z, bool *down) {
POINT pt {};
GetCursorPos(&pt);
ac_touchpanel_translate(&pt);
*x = pt.x;
*y = pt.y;
*z = 0xFF;
*down = GetKeyState(VK_LBUTTON) != 0;
return true;
}
void touchpanel_init() {
detour::iat_try("ac_touchpanel_new2", ac_touchpanel_new2);
detour::iat_try("ac_touchpanel_polling", ac_touchpanel_polling);
detour::iat_try("ac_touchpanel_set_keepalive_mode", ac_touchpanel_set_keepalive_mode);
detour::iat_try("ac_touchpanel_renewal", ac_touchpanel_renewal);
detour::iat_try("ac_touchpanel_check_wait_receive", ac_touchpanel_check_wait_receive);
detour::iat_try("ac_touchpanel_delete", ac_touchpanel_delete);
detour::iat_try("ac_touchpanel_get_keepalive_error", ac_touchpanel_get_keepalive_error);
detour::iat_try("ac_touchpanel_receive_check_diag", ac_touchpanel_receive_check_diag);
detour::iat_try("ac_touchpanel_caribrate_set", ac_touchpanel_caribrate_set);
detour::iat_try("ac_touchpanel_send_check_diag", ac_touchpanel_send_check_diag);
detour::iat_try("ac_touchpanel_read_on", ac_touchpanel_read_on);
detour::iat_try("ac_touchpanel_read_on_direct", ac_touchpanel_read_on_direct);
}
}

6
games/we/touchpanel.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
namespace games::we {
void touchpanel_init();
}

146
games/we/we.cpp Normal file
View File

@@ -0,0 +1,146 @@
#include "we.h"
#include "avs/game.h"
#include "hooks/sleephook.h"
#include "hooks/graphics/graphics.h"
#include "hooks/setupapihook.h"
#include "hooks/devicehook.h"
#include "launcher/launcher.h"
#include "util/libutils.h"
#include "util/sigscan.h"
#include "util/utils.h"
#include "util/detour.h"
#include "games/shared/lcdhandle.h"
#include "touchpanel.h"
/*
* Available Flags
* PRODUCT_TITLE -> WORLD SOCCER Winning Eleven ARCADE CHAMPIONSHIP 2012
* IS_FULLSCREEN -> 1
* SCREEN_W -> 1280
* SCREEN_H -> 1024
* WAIT_VSYNC -> 1
* IS_USE_IO -> 1
* IS_USE_TOUCH_PANEL -> 1
* IO_BOARD_COM_PORT -> 2
* TOUCH_PANEL_COM_PORT -> 1
* IS_LCD_CONTROLED -> 1
* TEST_CARDID -> 000000000000000 (15!)
* IS_USE_AUDIO -> 1
* IS_USE_AUDIO_EQ -> 1
* IS_LOCATION_TEST -> 0
* DISCONN -> 1
* UNFAIR_CHECK -> 1
* SCREEN_A -> 0
* READ_FONT -> 1
* MEM_DEBUG -> 0
* MG_TEST -> 0
* DEBUG_CHAINA_IO -> 0
* ONLINEUPDATE_QUICK -> 0
* UDP_COMM_CANCEL -> 0
* ENABLE_BALL_MOVE -> NONE
* WE2008AC_PASS_08 -> NONE
* DISCONN -> NONE
*/
static void set_flag(std::string flag, std::string value) {
auto module = avs::game::DLL_INSTANCE;
if (module) {
char flag_pad[32] {};
char value_pad[32] {};
strncpy(flag_pad, flag.data(), sizeof(flag_pad));
strncpy(value_pad, value.data(), sizeof(value_pad));
if (replace_pattern(
module,
fmt::format("{}{}",
bin2hex(flag_pad, sizeof(flag_pad)),
std::string(32, '?')
),
fmt::format("{}{}",
bin2hex(flag_pad, sizeof(flag_pad)),
bin2hex(value_pad, sizeof(value_pad))),
0, 0)) {
log_warning("we", "applied flag {}={}", flag, value);
} else {
log_warning("we", "couldn't apply flag {}={}", flag, value);
}
}
}
static BOOL WINAPI GetCursorPos_hook(LPPOINT lpPoint) {
// TODO: not sure why this is required for the cursor to be shown
if (GRAPHICS_SHOW_CURSOR) {
static auto cursor = ::LoadCursor(NULL, IDC_ARROW);
::SetCursor(cursor);
}
// get cursor position
auto result = GetCursorPos(lpPoint);
if (result) {
// try to find game window - the second window without title
static HWND target = 0;
if (target == 0) {
bool skip = false;
for (auto &hWnd : GRAPHICS_WINDOWS) {
char buffer[2] {};
auto len = GetWindowTextA(hWnd, buffer, sizeof(buffer));
if (len == 0) {
if (skip) {
target = hWnd;
break;
} else {
skip = true;
}
}
}
}
// translate screen coordinates to game window
if (target) {
ScreenToClient(target, lpPoint);
}
}
// return original result
return result;
}
games::we::WEGame::WEGame() : Game("Winning Eleven") {
}
void games::we::WEGame::attach() {
Game::attach();
// touchscreen device must just be present
SETUPAPI_SETTINGS touch_device {};
std::string touch_device_desc = "Elo TouchSystems 2700 IntelliTouch USB Touchmonitor Interface";
memcpy(touch_device.property_devicedesc, touch_device_desc.c_str(), touch_device_desc.length() + 1);
setupapihook_init(avs::game::DLL_INSTANCE);
setupapihook_add(touch_device);
// fix cursor position
detour::iat_try("GetCursorPos", GetCursorPos_hook);
// hooks for other touchscreen
touchpanel_init();
// make game not stretch window to main screen
if (GRAPHICS_WINDOWED) {
set_flag("IS_FULLSCREEN", "0");
}
// LCD handle
devicehook_init();
devicehook_add(new games::shared::LCDHandle());
// Winning Eleven 2014 sleeps for 60 seconds in gameMain
auto weac = libutils::try_library(MODULE_PATH / "weac.dll");
if (weac != nullptr) {
hooks::sleep::init(59999, 1, weac);
}
}
void games::we::WEGame::detach() {
Game::detach();
}

14
games/we/we.h Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#include "games/game.h"
namespace games::we {
class WEGame : public games::Game {
public:
WEGame();
virtual void attach() override;
virtual void detach() override;
};
}