Initial re-upload of spice2x-24-08-24
This commit is contained in:
66
games/sc/io.cpp
Normal file
66
games/sc/io.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "io.h"
|
||||
|
||||
std::vector<Button> &games::sc::get_buttons() {
|
||||
static std::vector<Button> buttons;
|
||||
|
||||
if (buttons.empty()) {
|
||||
buttons = GameAPI::Buttons::getButtons("Steel Chronicle");
|
||||
|
||||
GameAPI::Buttons::sortButtons(
|
||||
&buttons,
|
||||
"Service",
|
||||
"Test",
|
||||
"Coin Mech",
|
||||
"L1 Button",
|
||||
"L2 Button",
|
||||
"L Stick Button",
|
||||
"R1 Button",
|
||||
"R2 Button",
|
||||
"R Stick Button",
|
||||
"Jog Switch Left",
|
||||
"Jog Switch Right"
|
||||
);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
std::vector<Analog> &games::sc::get_analogs() {
|
||||
static std::vector<Analog> analogs;
|
||||
|
||||
if (analogs.empty()) {
|
||||
analogs = GameAPI::Analogs::getAnalogs("Steel Chronicle");
|
||||
|
||||
GameAPI::Analogs::sortAnalogs(
|
||||
&analogs,
|
||||
"Left Stick X",
|
||||
"Left Stick Y",
|
||||
"Right Stick X",
|
||||
"Right Stick Y"
|
||||
);
|
||||
}
|
||||
|
||||
return analogs;
|
||||
}
|
||||
|
||||
std::vector<Light> &games::sc::get_lights() {
|
||||
static std::vector<Light> lights;
|
||||
|
||||
if (lights.empty()) {
|
||||
lights = GameAPI::Lights::getLights("Steel Chronicle");
|
||||
|
||||
GameAPI::Lights::sortLights(
|
||||
&lights,
|
||||
"Center Red",
|
||||
"Center Green",
|
||||
"Center Blue",
|
||||
"Side Red",
|
||||
"Side Green",
|
||||
"Side Blue",
|
||||
"Controller Red",
|
||||
"Controller Blue"
|
||||
);
|
||||
}
|
||||
|
||||
return lights;
|
||||
}
|
||||
53
games/sc/io.h
Normal file
53
games/sc/io.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "cfg/api.h"
|
||||
|
||||
namespace games::sc {
|
||||
|
||||
// all buttons in correct order
|
||||
namespace Buttons {
|
||||
enum {
|
||||
Service,
|
||||
Test,
|
||||
CoinMech,
|
||||
L1,
|
||||
L2,
|
||||
LButton,
|
||||
R1,
|
||||
R2,
|
||||
RButton,
|
||||
JogLeft,
|
||||
JogRight,
|
||||
};
|
||||
}
|
||||
|
||||
// all analogs in correct order
|
||||
namespace Analogs {
|
||||
enum {
|
||||
LEFT_X,
|
||||
LEFT_Y,
|
||||
RIGHT_X,
|
||||
RIGHT_Y,
|
||||
};
|
||||
}
|
||||
|
||||
// all lights in correct order
|
||||
namespace Lights {
|
||||
enum {
|
||||
CenterRed,
|
||||
CenterGreen,
|
||||
CenterBlue,
|
||||
SideRed,
|
||||
SideGreen,
|
||||
SideBlue,
|
||||
ControllerRed,
|
||||
ControllerBlue,
|
||||
};
|
||||
}
|
||||
|
||||
// getters
|
||||
std::vector<Button> &get_buttons();
|
||||
std::vector<Analog> &get_analogs();
|
||||
std::vector<Light> &get_lights();
|
||||
}
|
||||
149
games/sc/sc.cpp
Normal file
149
games/sc/sc.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#include "sc.h"
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "hooks/devicehook.h"
|
||||
#include "hooks/graphics/graphics.h"
|
||||
#include "hooks/lang.h"
|
||||
#include "hooks/libraryhook.h"
|
||||
#include "games/shared/lcdhandle.h"
|
||||
#include "games/shared/twtouch.h"
|
||||
#include "util/detour.h"
|
||||
#include "util/libutils.h"
|
||||
#include "util/logging.h"
|
||||
#include "util/utils.h"
|
||||
#include "launcher/shutdown.h"
|
||||
|
||||
/**
|
||||
* Overridden touchscreen for attaching the touch hooks to the window.
|
||||
*/
|
||||
class SCTouchDevice : public games::shared::TwTouchDevice {
|
||||
public:
|
||||
|
||||
SCTouchDevice() {
|
||||
|
||||
// match factory calibration setting
|
||||
this->offset_x = -1500;
|
||||
this->offset_y = 3100;
|
||||
this->scale_x = (65535.f + 2500) / 1920.f;
|
||||
this->scale_y = (65535.f - 5800) / 1080.f;
|
||||
this->flip_x = true;
|
||||
this->flip_y = true;
|
||||
}
|
||||
|
||||
bool open(LPCWSTR lpFileName) override {
|
||||
|
||||
// check if device was opened
|
||||
auto result = TwTouchDevice::open(lpFileName);
|
||||
if (result) {
|
||||
|
||||
// attach touch module
|
||||
HWND hWnd = GetForegroundWindow();
|
||||
if (!string_begins_with(GetActiveWindowTitle(), "Graphics")) {
|
||||
hWnd = FindWindowBeginsWith("Graphics");
|
||||
}
|
||||
|
||||
// check window
|
||||
if (hWnd != nullptr) {
|
||||
|
||||
// check if windowed
|
||||
if (GRAPHICS_WINDOWED) {
|
||||
|
||||
// remove style borders
|
||||
LONG lStyle = GetWindowLong(hWnd, GWL_STYLE);
|
||||
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
|
||||
SetWindowLongPtr(hWnd, GWL_STYLE, lStyle);
|
||||
|
||||
// remove ex style borders
|
||||
LONG lExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
|
||||
lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
|
||||
SetWindowLongPtr(hWnd, GWL_EXSTYLE, lExStyle);
|
||||
|
||||
// update/move window (Steel Chronicle runs at 1920x1080)
|
||||
SetWindowPos(hWnd, nullptr, 0, 0, 1920, 1080,
|
||||
SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
} else {
|
||||
|
||||
// show game window because it lost focus
|
||||
ShowWindow(hWnd, SW_SHOW);
|
||||
}
|
||||
}
|
||||
|
||||
// use DirectX window for touch events, otherwise game window loses focus and runs at 10 FPS
|
||||
touch_attach_dx_hook();
|
||||
|
||||
// cursor
|
||||
if (!is_touch_available()) {
|
||||
ShowCursor(true);
|
||||
}
|
||||
}
|
||||
|
||||
// return result
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
static int __cdecl setvolume_stub(const char *set_volume_file) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static decltype(GetFileAttributesA)* GetFileAttributesA_orig;
|
||||
|
||||
static DWORD __stdcall GetFileAttributesA_hook(LPCSTR lpFileName) {
|
||||
|
||||
if (strcmp(lpFileName, "C:\\WERUNTIME.INI") == 0) {
|
||||
return INVALID_FILE_ATTRIBUTES;
|
||||
}
|
||||
|
||||
return GetFileAttributesA_orig(lpFileName);
|
||||
}
|
||||
|
||||
games::sc::SCGame::SCGame() : Game("Steel Chronicle") {
|
||||
}
|
||||
|
||||
void games::sc::SCGame::attach() {
|
||||
Game::attach();
|
||||
|
||||
/*
|
||||
* Since there are still some problems when the locale is non-japanese,
|
||||
* we want to warn the user about it.
|
||||
*/
|
||||
if (!hooks::lang::is_native_shiftjis()) {
|
||||
switch (MessageBoxA(
|
||||
NULL,
|
||||
"System locale for non-unicode programs not set to Japanese.\n"
|
||||
"This is unsupported and the game will crash at some point.\n"
|
||||
"Google: \"windows japanese non-unicode\"",
|
||||
"Warning",
|
||||
MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON1))
|
||||
{
|
||||
case IDCANCEL:
|
||||
launcher::kill();
|
||||
break;
|
||||
case IDOK:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// add devices
|
||||
devicehook_init();
|
||||
devicehook_add(new games::shared::LCDHandle());
|
||||
devicehook_add(new SCTouchDevice());
|
||||
|
||||
// game code resides in another DLL
|
||||
auto gamekgg = libutils::load_library("gamekgg.dll");
|
||||
devicehook_init(gamekgg);
|
||||
libraryhook_enable(gamekgg);
|
||||
|
||||
// set volume hook - default function causes access violation on some setups
|
||||
auto setvolume_module = libutils::load_library("setvolume.dll");
|
||||
detour::inline_hook((void *) setvolume_stub, libutils::get_proc(setvolume_module, "?setvolume@@YAHPAD@Z"));
|
||||
|
||||
// game changes power configurations if C:\WERUNTIME.INI exists
|
||||
GetFileAttributesA_orig = detour::iat_try("GetFileAttributesA", GetFileAttributesA_hook, avs::game::DLL_INSTANCE);
|
||||
}
|
||||
|
||||
void games::sc::SCGame::detach() {
|
||||
Game::detach();
|
||||
devicehook_dispose();
|
||||
}
|
||||
14
games/sc/sc.h
Normal file
14
games/sc/sc.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "games/game.h"
|
||||
|
||||
namespace games::sc {
|
||||
|
||||
class SCGame : public games::Game {
|
||||
public:
|
||||
SCGame();
|
||||
|
||||
virtual void attach() override;
|
||||
virtual void detach() override;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user