Clean up
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
#include "CameraController.h"
|
||||
#include <algorithm>
|
||||
#include "Input/InputState.h"
|
||||
#include "ComponentsManager.h"
|
||||
#include "../framework.h"
|
||||
#include "../Input/Mouse/Mouse.h"
|
||||
#include "../Input/Keyboard/Keyboard.h"
|
||||
#include "../Input/Bindings/KeyboardBinding.h"
|
||||
|
||||
#define GLUT_CURSOR_RIGHT_ARROW 0x0000
|
||||
#define GLUT_CURSOR_NONE 0x0065
|
||||
|
||||
using namespace TLAC::Input;
|
||||
using namespace TLAC::Utilities;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
CameraController::CameraController()
|
||||
{
|
||||
}
|
||||
|
||||
CameraController::~CameraController()
|
||||
{
|
||||
delete ToggleBinding;
|
||||
|
||||
delete ForwardBinding;
|
||||
delete BackwardBinding;
|
||||
delete LeftBinding;
|
||||
delete RightBinding;
|
||||
|
||||
delete UpBinding;
|
||||
delete DownBinding;
|
||||
delete ClockwiseBinding;
|
||||
delete CounterClockwiseBinding;
|
||||
delete ZoomInBinding;
|
||||
delete ZoomOutBinding;
|
||||
|
||||
delete FastBinding;
|
||||
delete SlowBinding;
|
||||
}
|
||||
|
||||
const char* CameraController::GetDisplayName()
|
||||
{
|
||||
return "camera_controller";
|
||||
}
|
||||
|
||||
void CameraController::Initialize(ComponentsManager* manager)
|
||||
{
|
||||
componentsManager = manager;
|
||||
|
||||
printf("[TLAC] CameraController::Initialize(): Initialized\n");
|
||||
|
||||
for (int i = 0; i < sizeof(cameraSetterAddresses) / sizeof(void*); i++)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)cameraSetterAddresses[i], sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
originalSetterBytes[i] = *(uint8_t*)cameraSetterAddresses[i];
|
||||
}
|
||||
|
||||
ToggleBinding = new Binding();
|
||||
ToggleBinding->AddBinding(new KeyboardBinding(VK_F3));
|
||||
|
||||
ForwardBinding = new Binding();
|
||||
ForwardBinding->AddBinding(new KeyboardBinding('W'));
|
||||
BackwardBinding = new Binding();
|
||||
BackwardBinding->AddBinding(new KeyboardBinding('S'));
|
||||
LeftBinding = new Binding();
|
||||
LeftBinding->AddBinding(new KeyboardBinding('A'));
|
||||
RightBinding = new Binding();
|
||||
RightBinding->AddBinding(new KeyboardBinding('D'));
|
||||
|
||||
UpBinding = new Binding();
|
||||
UpBinding->AddBinding(new KeyboardBinding(VK_SPACE));
|
||||
DownBinding = new Binding();
|
||||
DownBinding->AddBinding(new KeyboardBinding(VK_CONTROL));
|
||||
|
||||
ClockwiseBinding = new Binding();
|
||||
ClockwiseBinding->AddBinding(new KeyboardBinding('E'));
|
||||
CounterClockwiseBinding = new Binding();
|
||||
CounterClockwiseBinding->AddBinding(new KeyboardBinding('Q'));
|
||||
|
||||
ZoomInBinding = new Binding();
|
||||
ZoomInBinding->AddBinding(new KeyboardBinding('R'));
|
||||
ZoomOutBinding = new Binding();
|
||||
ZoomOutBinding->AddBinding(new KeyboardBinding('F'));
|
||||
|
||||
FastBinding = new Binding();
|
||||
FastBinding->AddBinding(new KeyboardBinding(VK_SHIFT));
|
||||
SlowBinding = new Binding();
|
||||
SlowBinding->AddBinding(new KeyboardBinding(VK_MENU));
|
||||
|
||||
camera = (Camera*)CAMERA_ADDRESS;
|
||||
}
|
||||
|
||||
void CameraController::Update()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void CameraController::UpdateInput()
|
||||
{
|
||||
if (ToggleBinding->AnyTapped())
|
||||
{
|
||||
SetControls(!GetIsEnabled());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetIsEnabled())
|
||||
return;
|
||||
|
||||
auto keyboard = Keyboard::GetInstance();
|
||||
auto mouse = Mouse::GetInstance();
|
||||
|
||||
bool forward = ForwardBinding->AnyDown();
|
||||
bool backward = BackwardBinding->AnyDown();
|
||||
bool left = LeftBinding->AnyDown();
|
||||
bool right = RightBinding->AnyDown();
|
||||
|
||||
bool up = UpBinding->AnyDown();
|
||||
bool down = DownBinding->AnyDown();
|
||||
|
||||
bool fast = FastBinding->AnyDown();
|
||||
bool slow = SlowBinding->AnyDown();
|
||||
|
||||
bool clockwise = ClockwiseBinding->AnyDown();
|
||||
bool counterclockwise = CounterClockwiseBinding->AnyDown();
|
||||
|
||||
bool zoomin = ZoomInBinding->AnyDown();
|
||||
bool zoomout = ZoomOutBinding->AnyDown();
|
||||
|
||||
float speed = GetElapsedTime() * (fast ? fastSpeed : slow ? slowSpeed : normalSpeed);
|
||||
|
||||
if (forward ^ backward)
|
||||
camera->Position += PointFromAngle(verticalRotation + (forward ? +0.0f : -180.0f), speed);
|
||||
|
||||
if (left ^ right)
|
||||
camera->Position += PointFromAngle(verticalRotation + (right ? +90.0f : -90.0f), speed);
|
||||
|
||||
if (up ^ down)
|
||||
camera->Position.Y += speed * (up ? +0.25f : -0.25f);
|
||||
|
||||
if (clockwise ^ counterclockwise)
|
||||
camera->Rotation += speed * (clockwise ? -1.0f : +1.0f);
|
||||
|
||||
if (zoomin ^ zoomout)
|
||||
{
|
||||
camera->HorizontalFov += speed * (zoomin ? -1.0f : +1.0f);
|
||||
camera->HorizontalFov = std::clamp(camera->HorizontalFov, +1.0f, +170.0f);
|
||||
}
|
||||
|
||||
if (mouse->HasMoved())
|
||||
{
|
||||
SetMouseWindowCenter();
|
||||
|
||||
auto delta = mouse->GetDeltaPosition();
|
||||
|
||||
verticalRotation += delta.x * sensitivity;
|
||||
horizontalRotation -= delta.y * (sensitivity / 5.0f);
|
||||
|
||||
horizontalRotation = std::clamp(horizontalRotation, -75.0f, +75.0f);
|
||||
}
|
||||
|
||||
((InputState*)*(uint64_t*)INPUT_STATE_PTR_ADDRESS)->HideCursor();
|
||||
|
||||
Vec2 focus = PointFromAngle(verticalRotation, 1.0f);
|
||||
camera->Focus.X = camera->Position.X + focus.X;
|
||||
camera->Focus.Z = camera->Position.Z + focus.Y;
|
||||
|
||||
camera->Focus.Y = camera->Position.Y + PointFromAngle(horizontalRotation, 5.0f).X;
|
||||
}
|
||||
|
||||
void CameraController::SetControls(bool value)
|
||||
{
|
||||
if (GetIsEnabled() == value)
|
||||
return;
|
||||
|
||||
SetIsEnabled(value);
|
||||
componentsManager->SetUpdateGameInput(!value);
|
||||
|
||||
printf("[TLAC] CameraController::SetControls(): enabled = %s\n", GetIsEnabled() ? "true" : "false");
|
||||
|
||||
typedef void __stdcall _glutSetCursor(int);
|
||||
auto glutSetCursor = (_glutSetCursor*)GLUT_SET_CURSOR_ADDRESS;
|
||||
|
||||
// hide cursor
|
||||
glutSetCursor(value ? GLUT_CURSOR_NONE : GLUT_CURSOR_RIGHT_ARROW);
|
||||
|
||||
if (value)
|
||||
{
|
||||
// disable camera setters
|
||||
for (int i = 0; i < sizeof(cameraSetterAddresses) / sizeof(void*); i++)
|
||||
*(uint8_t*)cameraSetterAddresses[i] = RET_OPCODE;
|
||||
|
||||
// set initial camera angle
|
||||
Vec2 camXz = Vec2(camera->Position.X, camera->Position.Z);
|
||||
Vec2 focusXz = Vec2(camera->Focus.X, camera->Focus.Z);
|
||||
verticalRotation = AngleFromPoints(camXz, focusXz);
|
||||
|
||||
horizontalRotation = 0;
|
||||
camera->Rotation = defaultRotation;
|
||||
camera->HorizontalFov = defaultFov;
|
||||
}
|
||||
else
|
||||
{
|
||||
// restore camera setters
|
||||
for (int i = 0; i < sizeof(cameraSetterAddresses) / sizeof(void*); i++)
|
||||
*(uint8_t*)cameraSetterAddresses[i] = originalSetterBytes[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CameraController::SetMouseWindowCenter()
|
||||
{
|
||||
RECT windowRect = framework::GetWindowBounds();
|
||||
|
||||
int centerX = windowRect.left + (windowRect.right - windowRect.left) / 2;
|
||||
int centerY = windowRect.top + (windowRect.bottom - windowRect.top) / 2;
|
||||
|
||||
Mouse::GetInstance()->SetPosition(centerX, centerY);
|
||||
}
|
||||
|
||||
bool CameraController::GetIsEnabled()
|
||||
{
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
void CameraController::SetIsEnabled(bool value)
|
||||
{
|
||||
isEnabled = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "../Constants.h"
|
||||
#include "../Input/Bindings/Binding.h"
|
||||
#include "../Utilities/Math.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct Camera
|
||||
{
|
||||
Utilities::Vec3 Position;
|
||||
Utilities::Vec3 Focus;
|
||||
float Rotation;
|
||||
float HorizontalFov;
|
||||
float VerticalFov;
|
||||
};
|
||||
|
||||
class CameraController : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
Input::Binding* ToggleBinding;
|
||||
|
||||
Input::Binding* ForwardBinding;
|
||||
Input::Binding* BackwardBinding;
|
||||
Input::Binding* LeftBinding;
|
||||
Input::Binding* RightBinding;
|
||||
|
||||
Input::Binding* UpBinding;
|
||||
Input::Binding* DownBinding;
|
||||
Input::Binding* FastBinding;
|
||||
Input::Binding* SlowBinding;
|
||||
|
||||
Input::Binding* ClockwiseBinding;
|
||||
Input::Binding* CounterClockwiseBinding;
|
||||
|
||||
Input::Binding* ZoomInBinding;
|
||||
Input::Binding* ZoomOutBinding;
|
||||
|
||||
CameraController();
|
||||
~CameraController();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
void SetControls(bool value);
|
||||
|
||||
bool GetIsEnabled();
|
||||
|
||||
private:
|
||||
const float fastSpeed = 0.1f;
|
||||
const float slowSpeed = 0.0005f;
|
||||
const float normalSpeed = 0.005f;
|
||||
|
||||
const float defaultRotation = 0.0f;
|
||||
const float defaultFov = 70.0f;
|
||||
const float sensitivity = 0.25f;
|
||||
|
||||
ComponentsManager* componentsManager;
|
||||
float verticalRotation;
|
||||
float horizontalRotation;
|
||||
|
||||
bool isEnabled;
|
||||
Camera* camera;
|
||||
|
||||
uint8_t originalSetterBytes[4];
|
||||
void* cameraSetterAddresses[4] =
|
||||
{
|
||||
(void*)CAMERA_POS_SETTER_ADDRESS,
|
||||
(void*)CAMERA_INTR_SETTER_ADDRESS,
|
||||
(void*)CAMERA_ROT_SETTER_ADDRESS,
|
||||
(void*)CAMERA_PERS_SETTER_ADDRESS,
|
||||
};
|
||||
|
||||
void SetMouseWindowCenter();
|
||||
void SetIsEnabled(bool value);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
#include "ComponentsManager.h"
|
||||
#include "../FileSystem/ConfigFile.h"
|
||||
#include "../framework.h"
|
||||
#include "Input/InputEmulator.h"
|
||||
#include "Input/TouchSliderEmulator.h"
|
||||
#include "Input/TouchPanelEmulator.h"
|
||||
#include "SysTimer.h"
|
||||
#include "PlayerDataManager.h"
|
||||
#include "FrameRateManager.h"
|
||||
#include "FastLoader.h"
|
||||
#include "StageManager.h"
|
||||
#include "CameraController.h"
|
||||
#include "DebugComponent.h"
|
||||
#include "ScaleComponent.h"
|
||||
#include "FPSLimiter.h"
|
||||
#include "GameTargets/TargetInspector.h"
|
||||
|
||||
using ConfigFile = TLAC::FileSystem::ConfigFile;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
typedef void EngineUpdateInput(void*);
|
||||
|
||||
ComponentsManager::ComponentsManager()
|
||||
{
|
||||
}
|
||||
|
||||
ComponentsManager::~ComponentsManager()
|
||||
{
|
||||
}
|
||||
|
||||
void ComponentsManager::ParseAddComponents()
|
||||
{
|
||||
EmulatorComponent* allComponents[]
|
||||
{
|
||||
new TargetInspector(),
|
||||
new InputEmulator(),
|
||||
new TouchSliderEmulator(),
|
||||
new TouchPanelEmulator(),
|
||||
new SysTimer(),
|
||||
new PlayerDataManager(),
|
||||
new FrameRateManager(),
|
||||
new FastLoader(),
|
||||
new ScaleComponent(),
|
||||
new FPSLimiter(),
|
||||
new StageManager(),
|
||||
new CameraController(),
|
||||
new DebugComponent(),
|
||||
};
|
||||
|
||||
ConfigFile componentsConfig(framework::GetModuleDirectory(), COMPONENTS_CONFIG_FILE_NAME);
|
||||
bool success = componentsConfig.OpenRead();
|
||||
|
||||
if (!success)
|
||||
{
|
||||
printf("ComponentsManager::ParseAddComponents(): Unable to parse %s\n", COMPONENTS_CONFIG_FILE_NAME.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
size_t componentCount = sizeof(allComponents) / sizeof(EmulatorComponent*);
|
||||
components.reserve(componentCount);
|
||||
|
||||
std::string trueString = "true", falseString = "false";
|
||||
|
||||
for (int i = 0; i < componentCount; i++)
|
||||
{
|
||||
std::string* value;
|
||||
|
||||
auto name = allComponents[i]->GetDisplayName();
|
||||
//printf("ComponentsManager::ParseAddComponents(): searching name: %s\n", name);
|
||||
|
||||
if (componentsConfig.TryGetValue(name, &value))
|
||||
{
|
||||
//printf("ComponentsManager::ParseAddComponents(): %s found\n", name);
|
||||
|
||||
if (*value == trueString)
|
||||
{
|
||||
//printf("ComponentsManager::ParseAddComponents(): enabling %s...\n", name);
|
||||
components.push_back(allComponents[i]);
|
||||
}
|
||||
else if (*value == falseString)
|
||||
{
|
||||
//printf("ComponentsManager::ParseAddComponents(): disabling %s...\n", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("ComponentsManager::ParseAddComponents(): invalid value %s for component %s\n", value, name);
|
||||
}
|
||||
|
||||
delete value;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("ParseAddComponents(): component %s not found\n", name);
|
||||
delete allComponents[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ComponentsManager::Initialize()
|
||||
{
|
||||
dwGuiDisplay = (DwGuiDisplay*) * (uint64_t*)DW_GUI_DISPLAY_INSTANCE_PTR_ADDRESS;
|
||||
|
||||
ParseAddComponents();
|
||||
updateStopwatch.Start();
|
||||
|
||||
for (auto& component : components)
|
||||
component->Initialize(this);
|
||||
}
|
||||
|
||||
void ComponentsManager::Update()
|
||||
{
|
||||
elpasedTime = updateStopwatch.Restart();
|
||||
|
||||
for (auto& component : components)
|
||||
{
|
||||
component->SetElapsedTime(elpasedTime);
|
||||
component->Update();
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentsManager::UpdateInput()
|
||||
{
|
||||
if (!GetIsInputEmulatorUsed())
|
||||
{
|
||||
uint64_t* inputStatePtr = (uint64_t*)INPUT_STATE_PTR_ADDRESS;
|
||||
|
||||
// poll input using the original PollInput function we overwrote with the update hook instead
|
||||
if (inputStatePtr != nullptr)
|
||||
((EngineUpdateInput*)ENGINE_UPDATE_INPUT_ADDRESS)((void*)* inputStatePtr);
|
||||
}
|
||||
|
||||
for (auto& component : components)
|
||||
component->UpdateInput();
|
||||
}
|
||||
|
||||
void ComponentsManager::OnFocusGain()
|
||||
{
|
||||
for (auto& component : components)
|
||||
component->OnFocusGain();
|
||||
}
|
||||
|
||||
void ComponentsManager::OnFocusLost()
|
||||
{
|
||||
for (auto& component : components)
|
||||
component->OnFocusLost();
|
||||
}
|
||||
|
||||
void ComponentsManager::Dispose()
|
||||
{
|
||||
for (auto& component : components)
|
||||
delete component;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "../Utilities/Stopwatch.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
const std::string COMPONENTS_CONFIG_FILE_NAME = "components.ini";
|
||||
|
||||
// Incomplete type
|
||||
struct DwGuiDisplay
|
||||
{
|
||||
void* vftable;
|
||||
void* active;
|
||||
void* cap;
|
||||
void* on;
|
||||
void* move;
|
||||
void* widget;
|
||||
};
|
||||
|
||||
class ComponentsManager
|
||||
{
|
||||
public:
|
||||
ComponentsManager();
|
||||
~ComponentsManager();
|
||||
void Initialize();
|
||||
void Update();
|
||||
void UpdateInput();
|
||||
void OnFocusGain();
|
||||
void OnFocusLost();
|
||||
void Dispose();
|
||||
|
||||
inline bool GetIsInputEmulatorUsed() { return isInputEmulatorUsed; };
|
||||
inline void SetIsInputEmulatorUsed(bool value) { isInputEmulatorUsed = value; };
|
||||
|
||||
inline bool GetUpdateGameInput() { return updateGameInput; };
|
||||
inline void SetUpdateGameInput(bool value) { updateGameInput = value; }
|
||||
|
||||
inline bool IsDwGuiActive() { return dwGuiDisplay->active != nullptr; };
|
||||
inline bool IsDwGuiHovered() { return dwGuiDisplay->on != nullptr; };
|
||||
|
||||
private:
|
||||
DwGuiDisplay* dwGuiDisplay;
|
||||
|
||||
bool isInputEmulatorUsed = false;
|
||||
bool updateGameInput = true;
|
||||
|
||||
float elpasedTime;
|
||||
Utilities::Stopwatch updateStopwatch;
|
||||
std::vector<EmulatorComponent*> components;
|
||||
|
||||
void ParseAddComponents();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct CustomPlayerData
|
||||
{
|
||||
std::string *PlayerName;
|
||||
std::string* LevelName;
|
||||
int LevelPlateId;
|
||||
int SkinEquip;
|
||||
int BtnSeEquip;
|
||||
int SlideSeEquip;
|
||||
int ChainslideSeEquip;
|
||||
bool ShowGreatClearBorder;
|
||||
bool ShowExcellentClearBorder;
|
||||
bool UseCard;
|
||||
bool GameModifierOptions;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
#include "DebugComponent.h"
|
||||
#include "../Constants.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
const char* GameStateNames[] =
|
||||
{
|
||||
"STARTUP",
|
||||
"ADVERTISE",
|
||||
"GAME",
|
||||
"DATA_TEST",
|
||||
"TEST_MODE",
|
||||
"APP_ERROR",
|
||||
"MAX",
|
||||
};
|
||||
|
||||
const char* SubGameStateNames[] =
|
||||
{
|
||||
"DATA_INITIALIZE",
|
||||
"SYSTEM_STARTUP",
|
||||
"SYSTEM_STARTUP_ERROR",
|
||||
"WARNING",
|
||||
"LOGO",
|
||||
"RATING",
|
||||
"DEMO",
|
||||
"TITLE",
|
||||
"RANKING",
|
||||
"SCORE_RANKING",
|
||||
"CM",
|
||||
"PHOTO_MODE_DEMO",
|
||||
"SELECTOR",
|
||||
"GAME_MAIN",
|
||||
"GAME_SEL",
|
||||
"STAGE_RESULT",
|
||||
"SCREEN_SHOT_SEL",
|
||||
"SCREEN_SHOT_RESULT",
|
||||
"GAME_OVER",
|
||||
"DATA_TEST_MAIN",
|
||||
"DATA_TEST_MISC",
|
||||
"DATA_TEST_OBJ",
|
||||
"DATA_TEST_STG",
|
||||
"DATA_TEST_MOT",
|
||||
"DATA_TEST_COLLISION",
|
||||
"DATA_TEST_SPR",
|
||||
"DATA_TEST_AET",
|
||||
"DATA_TEST_AUTH_3D",
|
||||
"DATA_TEST_CHR",
|
||||
"DATA_TEST_ITEM",
|
||||
"DATA_TEST_PERF",
|
||||
"DATA_TEST_PVSCRIPT",
|
||||
"DATA_TEST_PRINT",
|
||||
"DATA_TEST_CARD",
|
||||
"DATA_TEST_OPD",
|
||||
"DATA_TEST_SLIDER",
|
||||
"DATA_TEST_GLITTER",
|
||||
"DATA_TEST_GRAPHICS",
|
||||
"DATA_TEST_COLLECTION_CARD",
|
||||
"TEST_MODE_MAIN",
|
||||
"APP_ERROR",
|
||||
"MAX",
|
||||
};
|
||||
|
||||
const char* DataTestNames[] =
|
||||
{
|
||||
"MAIN TEST",
|
||||
"MISC TEST",
|
||||
"OBJECT TEST",
|
||||
"STAGE TEST",
|
||||
"MOTION TEST",
|
||||
"COLLISION TEST",
|
||||
"SPRITE TEST",
|
||||
"2DAUTH TEST",
|
||||
"3DAUTH TEST",
|
||||
"CHARA TEST",
|
||||
"ITEM TEST",
|
||||
"PERFORMANCE TEST",
|
||||
"PVSCRIPT TEST",
|
||||
"PRINT TEST",
|
||||
"CARD TEST",
|
||||
"OPD TEST",
|
||||
"SLIDER TEST",
|
||||
"GLITTER TEST",
|
||||
"GRAPHICS TEST",
|
||||
"COLLECTION CARD TEST",
|
||||
};
|
||||
|
||||
typedef void ChangeGameState(GameState);
|
||||
ChangeGameState* changeGameState = (ChangeGameState*)CHANGE_MODE_ADDRESS;
|
||||
|
||||
typedef void ChangeSubState(GameState, SubGameState);
|
||||
ChangeSubState* changeSubState = (ChangeSubState*)CHANGE_SUB_MODE_ADDRESS;
|
||||
|
||||
DebugComponent::DebugComponent()
|
||||
{
|
||||
}
|
||||
|
||||
DebugComponent::~DebugComponent()
|
||||
{
|
||||
}
|
||||
|
||||
const char* DebugComponent::GetDisplayName()
|
||||
{
|
||||
return "debug_component";
|
||||
}
|
||||
|
||||
void DebugComponent::Initialize(ComponentsManager*)
|
||||
{
|
||||
printf("[TLAC] DebugComponent::Initialize(): Initialized\n");
|
||||
|
||||
InjectPatches();
|
||||
|
||||
HWND consoleHandle = GetConsoleWindow();
|
||||
ShowWindow(consoleHandle, SW_SHOW);
|
||||
|
||||
// In case the FrameRateManager isn't enabled
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)AET_FRAME_DURATION_ADDRESS, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
}
|
||||
|
||||
void DebugComponent::Update()
|
||||
{
|
||||
if (dataTestMain)
|
||||
{
|
||||
Input::Keyboard::GetInstance()->PollInput();
|
||||
UpdateDataTestMain();
|
||||
}
|
||||
}
|
||||
|
||||
void DebugComponent::UpdateInput()
|
||||
{
|
||||
auto keyboard = Input::Keyboard::GetInstance();
|
||||
|
||||
// fast forward menus
|
||||
if (keyboard->IsDown(VK_SHIFT))
|
||||
{
|
||||
float* frameDuration = (float*)AET_FRAME_DURATION_ADDRESS;
|
||||
|
||||
if (keyboard->IsDown(VK_TAB))
|
||||
*frameDuration = 1.0f / (GetGameFrameRate() / aetSpeedUpFactor);
|
||||
else if (keyboard->IsReleased(VK_TAB))
|
||||
*frameDuration = 1.0f / 60.0f;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _countof(gameStateKeyMappings); i++)
|
||||
{
|
||||
if (keyboard->IsTapped(gameStateKeyMappings[i].KeyCode))
|
||||
InternalChangeGameState(gameStateKeyMappings[i].State);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugComponent::InjectPatches()
|
||||
{
|
||||
const struct { void* Address; std::initializer_list<uint8_t> Data; } patches[] =
|
||||
{
|
||||
// Prevent the DATA_TEST game state from exiting on the first frame
|
||||
{ (void*)0x0000000140284B01, { 0x00 } },
|
||||
// Enable dw_gui sprite draw calls
|
||||
{ (void*)0x0000000140192601, { 0x00 } },
|
||||
// Update the dw_gui display
|
||||
{ (void*)0x0000000140302600, { 0xB0, 0x01 } },
|
||||
// Draw the dw_gui display
|
||||
{ (void*)0x0000000140302610, { 0xB0, 0x01 } },
|
||||
// Enable the dw_gui widgets
|
||||
{ (void*)0x0000000140192D00, { 0xB8, 0x01, 0x00, 0x00, 0x00, 0xC3 } },
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < _countof(patches); i++)
|
||||
InjectCode(patches[i].Address, patches[i].Data);
|
||||
}
|
||||
|
||||
void DebugComponent::SetConsoleForeground()
|
||||
{
|
||||
HWND consoleHandle = GetConsoleWindow();
|
||||
ShowWindow(consoleHandle, SW_SHOW);
|
||||
|
||||
if (consoleHandle == NULL)
|
||||
return;
|
||||
|
||||
WINDOWPLACEMENT place = { sizeof(WINDOWPLACEMENT) };
|
||||
GetWindowPlacement(consoleHandle, &place);
|
||||
|
||||
switch (place.showCmd)
|
||||
{
|
||||
case SW_SHOWMAXIMIZED:
|
||||
ShowWindow(consoleHandle, SW_SHOWMAXIMIZED);
|
||||
break;
|
||||
case SW_SHOWMINIMIZED:
|
||||
ShowWindow(consoleHandle, SW_RESTORE);
|
||||
break;
|
||||
default:
|
||||
ShowWindow(consoleHandle, SW_NORMAL);
|
||||
break;
|
||||
}
|
||||
|
||||
SetWindowPos(0, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
|
||||
SetForegroundWindow(consoleHandle);
|
||||
}
|
||||
|
||||
void DebugComponent::PrintDataTestMain()
|
||||
{
|
||||
system("cls");
|
||||
printf(" DATA TEST MAIN:\n\n");
|
||||
|
||||
for (int i = SUB_DATA_TEST_MISC; i <= SUB_DATA_TEST_COLLECTION_CARD; i++)
|
||||
printf("%s %s\n", i == selectionIndex ? "->" : " ", DataTestNames[i - SUB_DATA_TEST_MAIN]);
|
||||
|
||||
printf("\n");
|
||||
SetConsoleForeground();
|
||||
}
|
||||
|
||||
void DebugComponent::InternalChangeGameState(GameState state)
|
||||
{
|
||||
changeGameState(state);
|
||||
printDataTestMain = dataTestMain = (state == GS_DATA_TEST);
|
||||
}
|
||||
|
||||
void DebugComponent::UpdateDataTestMain()
|
||||
{
|
||||
auto keyboard = Input::Keyboard::GetInstance();
|
||||
|
||||
if (keyboard->IsIntervalTapped(VK_UP))
|
||||
{
|
||||
selectionIndex--;
|
||||
printDataTestMain = true;
|
||||
}
|
||||
|
||||
if (keyboard->IsIntervalTapped(VK_DOWN))
|
||||
{
|
||||
selectionIndex++;
|
||||
printDataTestMain = true;
|
||||
}
|
||||
|
||||
if (selectionIndex > SUB_DATA_TEST_COLLECTION_CARD)
|
||||
selectionIndex = SUB_DATA_TEST_MISC;
|
||||
|
||||
if (selectionIndex < SUB_DATA_TEST_MISC)
|
||||
selectionIndex = SUB_DATA_TEST_COLLECTION_CARD;
|
||||
|
||||
if (keyboard->IsTapped(VK_RETURN))
|
||||
{
|
||||
dataTestMain = false;
|
||||
|
||||
printf("[%s] -> [%s]\n", SubGameStateNames[SUB_DATA_TEST_MAIN], SubGameStateNames[selectionIndex]);
|
||||
changeSubState(GS_DATA_TEST, (SubGameState)selectionIndex);
|
||||
}
|
||||
|
||||
if (printDataTestMain)
|
||||
{
|
||||
PrintDataTestMain();
|
||||
printDataTestMain = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DebugComponent::InjectCode(void* address, const std::initializer_list<uint8_t> &data)
|
||||
{
|
||||
const size_t byteCount = data.size() * sizeof(uint8_t);
|
||||
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(address, byteCount, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
memcpy(address, data.begin(), byteCount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "GameState.h"
|
||||
#include "../Input/Keyboard/Keyboard.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class DebugComponent : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
DebugComponent();
|
||||
~DebugComponent();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
private:
|
||||
const float aetSpeedUpFactor = 4.0f;
|
||||
|
||||
bool dataTestMain = false;
|
||||
bool printDataTestMain = false;
|
||||
int selectionIndex = SUB_DATA_TEST_MISC;
|
||||
|
||||
const struct { BYTE KeyCode; GameState State; } gameStateKeyMappings[5] =
|
||||
{
|
||||
{ VK_F4, GS_ADVERTISE },
|
||||
{ VK_F5, GS_GAME },
|
||||
{ VK_F6, GS_DATA_TEST },
|
||||
{ VK_F7, GS_TEST_MODE },
|
||||
{ VK_F8, GS_APP_ERROR },
|
||||
};
|
||||
|
||||
void InjectPatches();
|
||||
void SetConsoleForeground();
|
||||
void PrintDataTestMain();
|
||||
void InternalChangeGameState(GameState state);
|
||||
void UpdateDataTestMain();
|
||||
void InjectCode(void* address, const std::initializer_list<uint8_t> &data);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "EmulatorComponent.h"
|
||||
#include "../Constants.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
EmulatorComponent::EmulatorComponent()
|
||||
{
|
||||
}
|
||||
|
||||
EmulatorComponent::~EmulatorComponent()
|
||||
{
|
||||
}
|
||||
|
||||
void EmulatorComponent::SetElapsedTime(float value)
|
||||
{
|
||||
elapsedTime = value;
|
||||
}
|
||||
|
||||
float EmulatorComponent::GetElapsedTime()
|
||||
{
|
||||
return elapsedTime == 0.0f ? (1000.0f / 60.0f) : elapsedTime;
|
||||
}
|
||||
|
||||
float EmulatorComponent::GetFrameRate()
|
||||
{
|
||||
return 1000.0f / GetElapsedTime();
|
||||
}
|
||||
|
||||
float EmulatorComponent::GetGameFrameRate()
|
||||
{
|
||||
return *(float*)FRAME_RATE_ADDRESS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class ComponentsManager;
|
||||
|
||||
class EmulatorComponent
|
||||
{
|
||||
public:
|
||||
EmulatorComponent();
|
||||
~EmulatorComponent();
|
||||
|
||||
virtual const char* GetDisplayName() = 0;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) = 0;
|
||||
virtual void Update() = 0;
|
||||
|
||||
virtual void UpdateInput() {};
|
||||
virtual void OnFocusGain() {};
|
||||
virtual void OnFocusLost() {};
|
||||
|
||||
void SetElapsedTime(float value);
|
||||
float GetElapsedTime();
|
||||
float GetFrameRate();
|
||||
float GetGameFrameRate();
|
||||
|
||||
private:
|
||||
float elapsedTime;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "FPSLimiter.h"
|
||||
#include <Windows.h>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <tchar.h>
|
||||
|
||||
using dsec = std::chrono::duration<double>;
|
||||
using seconds = std::chrono::seconds;
|
||||
|
||||
// this is pretty much just lybxlpsv's limiter, but removed from GLComponent
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
static std::chrono::time_point mBeginFrame = system_clock::now();
|
||||
static std::chrono::time_point prevTimeInSeconds = time_point_cast<seconds>(mBeginFrame);
|
||||
|
||||
const LPCTSTR config_file_name = _T(".\\config.ini");
|
||||
int fpsLimit = GetPrivateProfileIntW(L"graphics", L"fps.limit", 0, config_file_name);
|
||||
|
||||
FPSLimiter::FPSLimiter()
|
||||
{
|
||||
}
|
||||
|
||||
FPSLimiter::~FPSLimiter()
|
||||
{
|
||||
}
|
||||
|
||||
const char* FPSLimiter::GetDisplayName()
|
||||
{
|
||||
return "fps_limiter";
|
||||
}
|
||||
|
||||
void FPSLimiter::Initialize(ComponentsManager* manager)
|
||||
{
|
||||
mBeginFrame = std::chrono::system_clock::now();
|
||||
prevTimeInSeconds = std::chrono::time_point_cast<seconds>(mBeginFrame);
|
||||
frameCountPerSecond = 0;
|
||||
if(fpsLimit != 0)
|
||||
printf("FPSLimiter fpsLimit: %d\n", fpsLimit);
|
||||
}
|
||||
|
||||
// I assume this gets called once per frame... if not this won't work
|
||||
void FPSLimiter::Update()
|
||||
{
|
||||
auto invFpsLimit = round<std::chrono::system_clock::duration>(dsec{ 1. / fpsLimit });
|
||||
auto mEndFrame = mBeginFrame + invFpsLimit;
|
||||
auto timeInSeconds = std::chrono::time_point_cast<seconds>(std::chrono::system_clock::now());
|
||||
|
||||
++frameCountPerSecond;
|
||||
if (timeInSeconds > prevTimeInSeconds)
|
||||
{
|
||||
//printf("FPSLimiter::Update(): FPS: %d\n", frameCountPerSecond);
|
||||
frameCountPerSecond = 0;
|
||||
prevTimeInSeconds = timeInSeconds;
|
||||
}
|
||||
|
||||
// This part keeps the frame rate.
|
||||
if (fpsLimit > 19) // not sure why lyb used 19 here
|
||||
std::this_thread::sleep_until(mEndFrame);
|
||||
mBeginFrame = mEndFrame;
|
||||
mEndFrame = mBeginFrame + invFpsLimit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include <chrono>
|
||||
|
||||
using seconds = std::chrono::seconds;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class FPSLimiter : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
FPSLimiter();
|
||||
~FPSLimiter();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
|
||||
private:
|
||||
int frameCountPerSecond;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "FastLoader.h"
|
||||
#include "../Constants.h"
|
||||
#include <stdio.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
FastLoader::FastLoader()
|
||||
{
|
||||
}
|
||||
|
||||
FastLoader::~FastLoader()
|
||||
{
|
||||
}
|
||||
|
||||
const char* FastLoader::GetDisplayName()
|
||||
{
|
||||
return "fast_loader";
|
||||
}
|
||||
|
||||
void FastLoader::Initialize(ComponentsManager*)
|
||||
{
|
||||
}
|
||||
|
||||
void FastLoader::Update()
|
||||
{
|
||||
if (dataInitialized)
|
||||
return;
|
||||
|
||||
previousGameState = currentGameState;
|
||||
currentGameState = *(GameState*)CURRENT_GAME_STATE_ADDRESS;
|
||||
|
||||
if (currentGameState == GS_STARTUP)
|
||||
{
|
||||
typedef void UpdateTask();
|
||||
UpdateTask* updateTask = (UpdateTask*)UPDATE_TASKS_ADDRESS;
|
||||
|
||||
// speed up TaskSystemStartup
|
||||
for (int i = 0; i < updatesPerFrame; i++)
|
||||
updateTask();
|
||||
|
||||
constexpr int DATA_INITIALIZED = 3;
|
||||
|
||||
// skip TaskDataInit
|
||||
*(int*)(DATA_INIT_STATE_ADDRESS) = DATA_INITIALIZED;
|
||||
|
||||
// skip TaskWarning
|
||||
*(int*)(SYSTEM_WARNING_ELAPSED_ADDRESS) = 3939;
|
||||
}
|
||||
else if (previousGameState == GS_STARTUP)
|
||||
{
|
||||
dataInitialized = true;
|
||||
printf("[TLAC] FastLoader::Update(): Data Initialized\n");
|
||||
}
|
||||
}
|
||||
|
||||
void FastLoader::UpdateInput()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "GameState.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class FastLoader : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
FastLoader();
|
||||
~FastLoader();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
private:
|
||||
const int updatesPerFrame = 39;
|
||||
|
||||
GameState currentGameState;
|
||||
GameState previousGameState;
|
||||
bool dataInitialized = false;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "FrameRateManager.h"
|
||||
#include "../Constants.h"
|
||||
#include "GameState.h"
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "../framework.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
FrameRateManager::FrameRateManager()
|
||||
{
|
||||
}
|
||||
|
||||
FrameRateManager::~FrameRateManager()
|
||||
{
|
||||
}
|
||||
|
||||
const char* FrameRateManager::GetDisplayName()
|
||||
{
|
||||
return "frame_rate_manager";
|
||||
}
|
||||
|
||||
void FrameRateManager::Initialize(ComponentsManager*)
|
||||
{
|
||||
pvFrameRate = (float*)PV_FRAME_RATE_ADDRESS;
|
||||
frameSpeed = (float*)FRAME_SPEED_ADDRESS;
|
||||
aetFrameDuration = (float*)AET_FRAME_DURATION_ADDRESS;
|
||||
|
||||
// The default is expected to be 1.0 / 60.0
|
||||
defaultAetFrameDuration = *aetFrameDuration;
|
||||
|
||||
// This const variable is stored inside a data segment so we don't want to throw any access violations
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)AET_FRAME_DURATION_ADDRESS, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
}
|
||||
|
||||
void FrameRateManager::Update()
|
||||
{
|
||||
float frameRate = 0.0f;
|
||||
frameRate = RoundFrameRate(GetGameFrameRate());
|
||||
|
||||
*aetFrameDuration = 1.0f / frameRate;
|
||||
*pvFrameRate = frameRate;
|
||||
|
||||
bool inGame = *(GameState*)CURRENT_GAME_STATE_ADDRESS == GS_GAME;
|
||||
|
||||
if (inGame)
|
||||
{
|
||||
// During the GAME state the frame rate will be handled by the PvFrameRate instead
|
||||
|
||||
constexpr float defaultFrameSpeed = 1.0f;
|
||||
constexpr float defaultFrameRate = 60.0f;
|
||||
|
||||
// This PV struct creates a copy of the PvFrameRate & PvFrameSpeed during the loading screen
|
||||
// so we'll make sure to keep updating it as well.
|
||||
// Each new motion also creates its own copy of these values but keeping track of the active motions is annoying
|
||||
// and they usually change multiple times per PV anyway so this should suffice for now
|
||||
float* pvStructPvFrameRate = (float*)(0x0000000140CDD978 + 0x2BF98);
|
||||
float* pvStructPvFrameSpeed = (float*)(0x0000000140CDD978 + 0x2BF9C);
|
||||
|
||||
*pvStructPvFrameRate = *pvFrameRate;
|
||||
*pvStructPvFrameSpeed = (defaultFrameRate / *pvFrameRate);
|
||||
|
||||
*frameSpeed = defaultFrameSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
*frameSpeed = *aetFrameDuration / defaultAetFrameDuration;
|
||||
}
|
||||
}
|
||||
|
||||
float FrameRateManager::RoundFrameRate(float frameRate)
|
||||
{
|
||||
constexpr float roundingThreshold = 4.0f;
|
||||
|
||||
for (int i = 0; i < sizeof(commonRefreshRates) / sizeof(float); i++)
|
||||
{
|
||||
float refreshRate = commonRefreshRates[i];
|
||||
|
||||
if (frameRate > refreshRate - roundingThreshold && frameRate < refreshRate + roundingThreshold)
|
||||
frameRate = refreshRate;
|
||||
}
|
||||
|
||||
return frameRate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class FrameRateManager : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
FrameRateManager();
|
||||
~FrameRateManager();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
|
||||
private:
|
||||
float *pvFrameRate;
|
||||
float *frameSpeed;
|
||||
float *aetFrameDuration;
|
||||
float defaultAetFrameDuration;
|
||||
|
||||
float commonRefreshRates[5]
|
||||
{
|
||||
60.0f,
|
||||
75.0f,
|
||||
120.0f,
|
||||
144.0f,
|
||||
240.0f,
|
||||
};
|
||||
|
||||
float RoundFrameRate(float frameRate);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum GameState : uint32_t
|
||||
{
|
||||
GS_STARTUP,
|
||||
GS_ADVERTISE,
|
||||
GS_GAME,
|
||||
GS_DATA_TEST,
|
||||
GS_TEST_MODE,
|
||||
GS_APP_ERROR,
|
||||
GS_MAX,
|
||||
};
|
||||
|
||||
enum SubGameState : uint32_t
|
||||
{
|
||||
SUB_DATA_INITIALIZE,
|
||||
SUB_SYSTEM_STARTUP,
|
||||
SUB_SYSTEM_STARTUP_ERROR,
|
||||
SUB_WARNING,
|
||||
SUB_LOGO,
|
||||
SUB_RATING,
|
||||
SUB_DEMO,
|
||||
SUB_TITLE,
|
||||
SUB_RANKING,
|
||||
SUB_SCORE_RANKING,
|
||||
SUB_CM,
|
||||
SUB_PHOTO_MODE_DEMO,
|
||||
SUB_SELECTOR,
|
||||
SUB_GAME_MAIN,
|
||||
SUB_GAME_SEL,
|
||||
SUB_STAGE_RESULT,
|
||||
SUB_SCREEN_SHOT_SEL,
|
||||
SUB_SCREEN_SHOT_RESULT,
|
||||
SUB_GAME_OVER,
|
||||
SUB_DATA_TEST_MAIN,
|
||||
SUB_DATA_TEST_MISC,
|
||||
SUB_DATA_TEST_OBJ,
|
||||
SUB_DATA_TEST_STG,
|
||||
SUB_DATA_TEST_MOT,
|
||||
SUB_DATA_TEST_COLLISION,
|
||||
SUB_DATA_TEST_SPR,
|
||||
SUB_DATA_TEST_AET,
|
||||
SUB_DATA_TEST_AUTH_3D,
|
||||
SUB_DATA_TEST_CHR,
|
||||
SUB_DATA_TEST_ITEM,
|
||||
SUB_DATA_TEST_PERF,
|
||||
SUB_DATA_TEST_PVSCRIPT,
|
||||
SUB_DATA_TEST_PRINT,
|
||||
SUB_DATA_TEST_CARD,
|
||||
SUB_DATA_TEST_OPD,
|
||||
SUB_DATA_TEST_SLIDER,
|
||||
SUB_DATA_TEST_GLITTER,
|
||||
SUB_DATA_TEST_GRAPHICS,
|
||||
SUB_DATA_TEST_COLLECTION_CARD,
|
||||
SUB_TEST_MODE_MAIN,
|
||||
SUB_APP_ERROR,
|
||||
SUB_MAX,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum HoldState
|
||||
{
|
||||
HOLD_NONE,
|
||||
HOLD_SANKAKU = 64,
|
||||
HOLD_MARU = 128,
|
||||
HOLD_BATSU = 256,
|
||||
HOLD_SHIKAKU = 512,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum TargetHitStates
|
||||
{
|
||||
COOL,
|
||||
FINE,
|
||||
SAFE,
|
||||
SAD,
|
||||
COOL_WRONG, // unsure
|
||||
FINE_WRONG, // unsure
|
||||
SAFE_WRONG, // unsure
|
||||
SAD_WRONG, // unsure
|
||||
WORST,
|
||||
NONE = 21,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "TargetInspector.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
bool TargetInspector::repressTbl[maxTargetSlots];
|
||||
|
||||
TargetInspector::TargetInspector()
|
||||
{
|
||||
}
|
||||
|
||||
TargetInspector::~TargetInspector()
|
||||
{
|
||||
}
|
||||
|
||||
void TargetInspector::Initialize(ComponentsManager*)
|
||||
{
|
||||
tgtTypePtr = (int*)TGT_TYPE_BASE_ADDRESS;
|
||||
tgtHitStatePtr = (int*)TGT_HIT_STATE_BASE_ADDRESS;
|
||||
tgtRemainingTimePtr = (float*)TGT_REMAINING_DURATION_BASE_ADDRESS;
|
||||
}
|
||||
|
||||
void TargetInspector::Update()
|
||||
{
|
||||
GetTargetStates();
|
||||
UpdateRepressTbl();
|
||||
}
|
||||
|
||||
const char* TargetInspector::GetDisplayName()
|
||||
{
|
||||
return "target_inspector";
|
||||
}
|
||||
|
||||
void TargetInspector::GetTargetStates()
|
||||
{
|
||||
for (int i = 0; i < maxTargetSlots; ++i)
|
||||
{
|
||||
tgtStates[i].tgtType = *((int*)((char*)tgtTypePtr + (i * offset)));
|
||||
tgtStates[i].tgtHitState = *((int*)((char*)tgtHitStatePtr + (i * offset)));
|
||||
tgtStates[i].tgtRemainingTime = *((float*)((char*)tgtRemainingTimePtr + (i * offset)));
|
||||
}
|
||||
}
|
||||
|
||||
void TargetInspector::UpdateRepressTbl()
|
||||
{
|
||||
for (int i = 0; i < maxTargetSlots; ++i)
|
||||
{
|
||||
repressTbl[i] = IsWithinRange(tgtStates[i].tgtRemainingTime)
|
||||
&& HasNotBeenHit(tgtStates[i].tgtHitState)
|
||||
&& !IsSlide(tgtStates[i].tgtType);
|
||||
}
|
||||
}
|
||||
|
||||
bool TargetInspector::IsWithinRange(float time)
|
||||
{
|
||||
return time < timingThreshold && time > -timingThreshold && time != 0;
|
||||
}
|
||||
|
||||
bool TargetInspector::HasNotBeenHit(int hitState)
|
||||
{
|
||||
return hitState == NONE;
|
||||
}
|
||||
|
||||
bool TargetInspector::IsSlide(int type)
|
||||
{
|
||||
return (type >= SLIDE_L && type <= SLIDE_LONG_R) || type >= SLIDE_L_CH;
|
||||
}
|
||||
|
||||
bool TargetInspector::IsAnyRepress()
|
||||
{
|
||||
for (int i = 0; i < maxTargetSlots; ++i)
|
||||
{
|
||||
if (repressTbl[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include "../EmulatorComponent.h"
|
||||
#include "../Input/InputEmulator.h"
|
||||
#include "../../Constants.h"
|
||||
#include "TargetHitStates.h"
|
||||
#include "TargetState.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
const int maxTargetSlots = 32;
|
||||
|
||||
class TargetInspector : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
TargetInspector();
|
||||
~TargetInspector();
|
||||
|
||||
static bool repressTbl[maxTargetSlots];
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
void GetTargetStates();
|
||||
static bool IsAnyRepress();
|
||||
|
||||
private:
|
||||
const uint64_t offset = 0x4A8;
|
||||
const float timingThreshold = 0.13f; // PS4 estimate
|
||||
|
||||
TargetState tgtStates[maxTargetSlots];
|
||||
|
||||
int* tgtTypePtr;
|
||||
int* tgtHitStatePtr;
|
||||
float* tgtRemainingTimePtr;
|
||||
|
||||
bool IsSlide(int);
|
||||
bool IsWithinRange(float);
|
||||
bool HasNotBeenHit(int);
|
||||
void UpdateRepressTbl();
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct TargetState
|
||||
{
|
||||
int tgtType;
|
||||
int tgtHitState;
|
||||
float tgtRemainingTime;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum TargetTypes
|
||||
{
|
||||
SANKAKU,
|
||||
MARU,
|
||||
BATSU,
|
||||
SHIKAKU,
|
||||
SANKAKU_H,
|
||||
MARU_H,
|
||||
BATSU_H,
|
||||
SHIKAKU_H,
|
||||
SLIDE_L = 12,
|
||||
SLIDE_R,
|
||||
SLIDE_LONG_L = 15,
|
||||
SLIDE_LONG_R,
|
||||
SANKAKU_CH = 18,
|
||||
MARU_CH,
|
||||
BATSU_CH,
|
||||
SHIKAKU_CH,
|
||||
SLIDE_L_CH = 23,
|
||||
SLIDE_R_CH,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum InputBufferType
|
||||
{
|
||||
InputBufferType_Tapped,
|
||||
InputBufferType_Released,
|
||||
InputBufferType_Down,
|
||||
InputBufferType_DoubleTapped,
|
||||
InputBufferType_IntervalTapped,
|
||||
InputBufferType_Max,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
#include <iostream>
|
||||
#include "windows.h"
|
||||
#include "InputEmulator.h"
|
||||
#include "../ComponentsManager.h"
|
||||
#include "../../Constants.h"
|
||||
#include "../../framework.h"
|
||||
#include "../../Input/Bindings/KeyboardBinding.h"
|
||||
#include "../../Input/Bindings/XinputBinding.h"
|
||||
#include "../../Input/Bindings/MouseBinding.h"
|
||||
#include "../../Input/Bindings/Ds4Binding.h"
|
||||
#include "../../Input/KeyConfig/Config.h"
|
||||
#include "../../Utilities/Operations.h"
|
||||
#include "../../Utilities/EnumBitwiseOperations.h"
|
||||
#include "../../FileSystem/ConfigFile.h"
|
||||
|
||||
const std::string KEY_CONFIG_FILE_NAME = "keyconfig.ini";
|
||||
|
||||
using namespace TLAC::Input;
|
||||
using namespace TLAC::Input::KeyConfig;
|
||||
using namespace TLAC::Utilities;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
|
||||
InputEmulator::InputEmulator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
InputEmulator::~InputEmulator()
|
||||
{
|
||||
delete TestBinding;
|
||||
delete ServiceBinding;
|
||||
|
||||
delete StartBinding;
|
||||
delete SankakuBinding;
|
||||
delete ShikakuBinding;
|
||||
delete BatsuBinding;
|
||||
delete MaruBinding;
|
||||
|
||||
delete LeftBinding;
|
||||
delete RightBinding;
|
||||
}
|
||||
|
||||
const char* InputEmulator::GetDisplayName()
|
||||
{
|
||||
return "input_emulator";
|
||||
}
|
||||
|
||||
void InputEmulator::Initialize(ComponentsManager* manager)
|
||||
{
|
||||
componentsManager = manager;
|
||||
componentsManager->SetIsInputEmulatorUsed(true);
|
||||
|
||||
inputState = GetInputStatePtr((void*)INPUT_STATE_PTR_ADDRESS);
|
||||
inputState->HideCursor();
|
||||
|
||||
TestBinding = new Binding();
|
||||
ServiceBinding = new Binding();
|
||||
StartBinding = new Binding();
|
||||
|
||||
SankakuBinding = new Binding();
|
||||
ShikakuBinding = new Binding();
|
||||
BatsuBinding = new Binding();
|
||||
MaruBinding = new Binding();
|
||||
|
||||
LeftBinding = new Binding();
|
||||
RightBinding = new Binding();
|
||||
|
||||
FileSystem::ConfigFile configFile(framework::GetModuleDirectory(), KEY_CONFIG_FILE_NAME);
|
||||
configFile.OpenRead();
|
||||
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_TEST", *TestBinding, { "F1" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_SERVICE", *ServiceBinding, { "F2" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_START", *StartBinding, { "Enter" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_TRIANGLE", *SankakuBinding, { "W", "I" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_SQUARE", *ShikakuBinding, { "A", "J" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_CROSS", *BatsuBinding, { "S", "K" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_CIRCLE", *MaruBinding, { "D", "L" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_LEFT", *LeftBinding, { "Q", "U" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_RIGHT", *RightBinding, { "E", "O" });
|
||||
|
||||
mouseScrollPvSelection = configFile.GetBooleanValue("mouse_scroll_pv_selection");
|
||||
}
|
||||
|
||||
void InputEmulator::Update()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void InputEmulator::OnFocusLost()
|
||||
{
|
||||
// to prevent buttons from being "stuck"
|
||||
inputState->ClearState();
|
||||
inputState->HideCursor();
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateInput()
|
||||
{
|
||||
if (!componentsManager->GetUpdateGameInput())
|
||||
return;
|
||||
|
||||
if (!componentsManager->IsDwGuiActive())
|
||||
{
|
||||
UpdateJvsInput();
|
||||
|
||||
if (mouseScrollPvSelection && !componentsManager->IsDwGuiHovered())
|
||||
UpdateMousePvScroll();
|
||||
}
|
||||
|
||||
UpdateDwGuiInput();
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateJvsInput()
|
||||
{
|
||||
auto tappedFunc = [](void* binding) { return ((Binding*)binding)->AnyTapped(); };
|
||||
auto releasedFunc = [](void* binding) { return ((Binding*)binding)->AnyReleased(); };
|
||||
auto downFunc = [](void* binding) { return ((Binding*)binding)->AnyDown(); };
|
||||
|
||||
lastDownState = inputState->Down.Buttons;
|
||||
|
||||
inputState->Tapped.Buttons = GetJvsButtonsState(tappedFunc);
|
||||
inputState->Released.Buttons = GetJvsButtonsState(releasedFunc);
|
||||
inputState->Down.Buttons = GetJvsButtonsState(downFunc);
|
||||
inputState->DoubleTapped.Buttons = GetJvsButtonsState(tappedFunc);
|
||||
inputState->IntervalTapped.Buttons = GetJvsButtonsState(tappedFunc);
|
||||
|
||||
UpdateHoldState();
|
||||
heldButtons = GetButtonFromHold();
|
||||
|
||||
if ((lastDownState &= inputState->Tapped.Buttons) != 0)
|
||||
{
|
||||
inputState->Down.Buttons ^= inputState->Tapped.Buttons;
|
||||
if (IsHold() && !TargetInspector::IsAnyRepress())
|
||||
inputState->Down.Buttons |= heldButtons;
|
||||
}
|
||||
|
||||
// repress held down buttons to not block input
|
||||
//inputState->Down.Buttons ^= inputState->Tapped.Buttons;
|
||||
}
|
||||
|
||||
HoldState InputEmulator::GetHoldState()
|
||||
{
|
||||
return (HoldState) * ((int*)HOLD_STATE_ADDRESS);
|
||||
}
|
||||
|
||||
int InputEmulator::GetMaxHoldState()
|
||||
{
|
||||
return *(int*)MAX_HOLD_STATE_ADDRESS;
|
||||
}
|
||||
|
||||
bool InputEmulator::IsHold()
|
||||
{
|
||||
return ((holdState != HOLD_NONE) && (GetMaxHoldState() != 1));
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateHoldState()
|
||||
{
|
||||
holdState = GetHoldState();
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
int holdId = 1 << (i + 6);
|
||||
|
||||
if ((holdId & holdState) != 0)
|
||||
holdTbl[i] = 1;
|
||||
else
|
||||
holdTbl[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateDwGuiInput()
|
||||
{
|
||||
auto keyboard = Keyboard::GetInstance();
|
||||
auto mouse = Mouse::GetInstance();
|
||||
|
||||
auto pos = mouse->GetRelativePosition();
|
||||
inputState->MouseX = (int)pos.x;
|
||||
inputState->MouseY = (int)pos.y;
|
||||
|
||||
auto deltaPos = mouse->GetDeltaPosition();
|
||||
inputState->MouseDeltaX = (int)deltaPos.x;
|
||||
inputState->MouseDeltaY = (int)deltaPos.y;
|
||||
|
||||
inputState->Key = GetKeyState();
|
||||
|
||||
for (int i = 0; i < sizeof(keyBits) / sizeof(KeyBit); i++)
|
||||
UpdateInputBit(keyBits[i].Bit, keyBits[i].KeyCode);
|
||||
|
||||
for (int i = InputBufferType_Tapped; i < InputBufferType_Max; i++)
|
||||
{
|
||||
inputState->SetBit(scrollUpBit, mouse->GetIsScrolledUp(), (InputBufferType)i);
|
||||
inputState->SetBit(scrollDownBit, mouse->GetIsScrolledDown(), (InputBufferType)i);
|
||||
}
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateMousePvScroll()
|
||||
{
|
||||
// I originally wanted to use a MouseBinding set to JVS_LEFT / JVS_RIGHT
|
||||
// but that ended up being too slow because a PV slot can only be scrolled to once the scroll animation has finished playing
|
||||
int* slotsToScroll = (int*)PV_SEL_SLOTS_TO_SCROLL;
|
||||
int* modulesToScroll = (int*)MODULE_SEL_SLOTS_TO_SCROLL;
|
||||
|
||||
auto mouse = Mouse::GetInstance();
|
||||
if (mouse->GetIsScrolledUp())
|
||||
{
|
||||
if (*(int*)PV_SEL_SLOTS_CONST < 26) *slotsToScroll -= 1;
|
||||
if (*(int*)MODULE_IS_RECOMMENDED == 0) *modulesToScroll -= 1;
|
||||
}
|
||||
if (mouse->GetIsScrolledDown())
|
||||
{
|
||||
if (*(int*)PV_SEL_SLOTS_CONST < 26) *slotsToScroll += 1;
|
||||
if (*(int*)MODULE_IS_RECOMMENDED == 0) *modulesToScroll += 1;
|
||||
}
|
||||
}
|
||||
|
||||
InputState* InputEmulator::GetInputStatePtr(void* address)
|
||||
{
|
||||
return (InputState*)(*(uint64_t*)address);
|
||||
}
|
||||
|
||||
JvsButtons InputEmulator::GetJvsButtonsState(bool(*buttonTestFunc)(void*))
|
||||
{
|
||||
JvsButtons buttons = JVS_NONE;
|
||||
|
||||
if (buttonTestFunc(TestBinding))
|
||||
buttons |= JVS_TEST;
|
||||
if (buttonTestFunc(ServiceBinding))
|
||||
buttons |= JVS_SERVICE;
|
||||
|
||||
if (buttonTestFunc(StartBinding))
|
||||
buttons |= JVS_START;
|
||||
|
||||
if (buttonTestFunc(SankakuBinding))
|
||||
buttons |= JVS_TRIANGLE;
|
||||
if (buttonTestFunc(ShikakuBinding))
|
||||
buttons |= JVS_SQUARE;
|
||||
if (buttonTestFunc(BatsuBinding))
|
||||
buttons |= JVS_CROSS;
|
||||
if (buttonTestFunc(MaruBinding))
|
||||
buttons |= JVS_CIRCLE;
|
||||
|
||||
if (buttonTestFunc(LeftBinding))
|
||||
buttons |= JVS_L;
|
||||
if (buttonTestFunc(RightBinding))
|
||||
buttons |= JVS_R;
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
JvsButtons InputEmulator::GetButtonFromHold()
|
||||
{
|
||||
JvsButtons buttons = JVS_NONE;
|
||||
|
||||
if (holdTbl[0])
|
||||
buttons |= JVS_TRIANGLE;
|
||||
if (holdTbl[1])
|
||||
buttons |= JVS_CIRCLE;
|
||||
if (holdTbl[2])
|
||||
buttons |= JVS_CROSS;
|
||||
if (holdTbl[3])
|
||||
buttons |= JVS_SQUARE;
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
char InputEmulator::GetKeyState()
|
||||
{
|
||||
auto keyboard = Keyboard::GetInstance();
|
||||
|
||||
bool upper = keyboard->IsDown(VK_SHIFT);
|
||||
constexpr char caseDifference = 'A' - 'a';
|
||||
|
||||
char inputKey = 0x00;
|
||||
|
||||
for (char key = '0'; key < 'Z'; key++)
|
||||
{
|
||||
if (keyboard->IsIntervalTapped(key))
|
||||
inputKey = (upper || key < 'A') ? key : (key - caseDifference);
|
||||
}
|
||||
|
||||
if (keyboard->IsIntervalTapped(VK_BACK))
|
||||
inputKey = 0x08;
|
||||
|
||||
if (keyboard->IsIntervalTapped(VK_TAB))
|
||||
inputKey = 0x09;
|
||||
|
||||
if (keyboard->IsIntervalTapped(VK_SPACE))
|
||||
inputKey = 0x20;
|
||||
|
||||
if (keyboard->IsIntervalTapped(VK_ESCAPE))
|
||||
exit(0);
|
||||
|
||||
return inputKey;
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateInputBit(uint32_t bit, uint8_t keycode)
|
||||
{
|
||||
auto keyboard = Keyboard::GetInstance();
|
||||
|
||||
inputState->SetBit(bit, keyboard->IsTapped(keycode), InputBufferType_Tapped);
|
||||
inputState->SetBit(bit, keyboard->IsReleased(keycode), InputBufferType_Released);
|
||||
inputState->SetBit(bit, keyboard->IsDown(keycode), InputBufferType_Down);
|
||||
inputState->SetBit(bit, keyboard->IsDoubleTapped(keycode), InputBufferType_DoubleTapped);
|
||||
inputState->SetBit(bit, keyboard->IsIntervalTapped(keycode), InputBufferType_IntervalTapped);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include <Windows.h>
|
||||
#include "InputState.h"
|
||||
#include "../EmulatorComponent.h"
|
||||
#include "../../Input/Bindings/Binding.h"
|
||||
#include "../GameTargets/TargetTypes.h"
|
||||
#include "../GameTargets/TargetHitStates.h"
|
||||
#include "../GameTargets/HoldState.h"
|
||||
#include "../GameTargets/TargetInspector.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct KeyBit
|
||||
{
|
||||
uint32_t Bit;
|
||||
uint8_t KeyCode;
|
||||
};
|
||||
|
||||
class InputEmulator : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
Input::Binding* TestBinding;
|
||||
Input::Binding* ServiceBinding;
|
||||
|
||||
Input::Binding* StartBinding;
|
||||
Input::Binding* SankakuBinding;
|
||||
Input::Binding* ShikakuBinding;
|
||||
Input::Binding* BatsuBinding;
|
||||
Input::Binding* MaruBinding;
|
||||
|
||||
Input::Binding* LeftBinding;
|
||||
Input::Binding* RightBinding;
|
||||
|
||||
InputEmulator();
|
||||
~InputEmulator();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
virtual void OnFocusLost() override;
|
||||
|
||||
private:
|
||||
ComponentsManager* componentsManager;
|
||||
|
||||
bool mouseScrollPvSelection = false;
|
||||
const uint32_t scrollUpBit = 99;
|
||||
const uint32_t scrollDownBit = 100;
|
||||
|
||||
KeyBit keyBits[20] =
|
||||
{
|
||||
{ 5, VK_LEFT },
|
||||
{ 6, VK_RIGHT },
|
||||
|
||||
{ 29, VK_SPACE },
|
||||
{ 39, 'A' },
|
||||
{ 43, 'E' },
|
||||
{ 42, 'D' },
|
||||
{ 55, 'Q' },
|
||||
{ 57, 'S' }, // unsure
|
||||
{ 61, 'W' },
|
||||
{ 63, 'Y' },
|
||||
{ 84, 'L' }, // unsure
|
||||
|
||||
{ 80, VK_RETURN },
|
||||
{ 81, VK_SHIFT },
|
||||
{ 82, VK_CONTROL },
|
||||
{ 83, VK_MENU },
|
||||
|
||||
{ 91, VK_UP },
|
||||
{ 93, VK_DOWN },
|
||||
|
||||
{ 96, MK_LBUTTON },
|
||||
{ 97, VK_MBUTTON },
|
||||
{ 98, MK_RBUTTON },
|
||||
};
|
||||
|
||||
InputState* inputState;
|
||||
JvsButtons lastDownState;
|
||||
JvsButtons heldButtons;
|
||||
|
||||
int holdTbl[4];
|
||||
HoldState holdState;
|
||||
|
||||
void UpdateJvsInput();
|
||||
void UpdateDwGuiInput();
|
||||
void UpdateMousePvScroll();
|
||||
void UpdateHoldState();
|
||||
InputState* GetInputStatePtr(void* address);
|
||||
JvsButtons GetJvsButtonsState(bool(*buttonTestFunc)(void*));
|
||||
JvsButtons GetButtonFromHold();
|
||||
char GetKeyState();
|
||||
HoldState GetHoldState();
|
||||
int GetMaxHoldState();
|
||||
bool IsHold();
|
||||
|
||||
void UpdateInputBit(uint32_t bit, uint8_t keycode);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "InputState.h"
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
void InputState::ClearState()
|
||||
{
|
||||
memset(this, 0, sizeof(InputState));
|
||||
}
|
||||
|
||||
void InputState::HideCursor()
|
||||
{
|
||||
MouseX = INT32_MIN;
|
||||
MouseY = INT32_MIN;
|
||||
MouseDeltaX = 0;
|
||||
MouseDeltaY = 0;
|
||||
}
|
||||
|
||||
void InputState::SetBit(uint32_t bit, bool value, InputBufferType inputType)
|
||||
{
|
||||
uint8_t* data = GetInputBuffer(inputType);
|
||||
|
||||
if (data == nullptr || bit < 0 || bit >= MAX_BUTTON_BIT)
|
||||
return;
|
||||
|
||||
int byteIndex = (bit / 8);
|
||||
int bitIndex = (bit % 8);
|
||||
|
||||
BYTE mask = (1 << bitIndex);
|
||||
|
||||
data[byteIndex] = value ? (data[byteIndex] | mask) : (data[byteIndex] & ~mask);
|
||||
}
|
||||
|
||||
uint8_t* InputState::GetInputBuffer(InputBufferType inputType)
|
||||
{
|
||||
switch (inputType)
|
||||
{
|
||||
case InputBufferType_Tapped:
|
||||
return (uint8_t*)&Tapped;
|
||||
|
||||
case InputBufferType_Released:
|
||||
return (uint8_t*)&Released;
|
||||
|
||||
case InputBufferType_Down:
|
||||
return (uint8_t*)&Down;
|
||||
|
||||
case InputBufferType_DoubleTapped:
|
||||
return (uint8_t*)&DoubleTapped;
|
||||
|
||||
case InputBufferType_IntervalTapped:
|
||||
return (uint8_t*)&IntervalTapped;
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include "JvsButtons.h"
|
||||
#include "InputBufferType.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
const int MAX_BUTTON_BIT = 0x6F;
|
||||
|
||||
// The button state is larger than the size of a register
|
||||
// but only the first 32 bits are used during normal gameplay
|
||||
// so this will provide the convenience of still being able to access them through a bit field
|
||||
union ButtonState
|
||||
{
|
||||
JvsButtons Buttons;
|
||||
uint32_t State[4];
|
||||
};
|
||||
|
||||
// total sizeof() == 0x20E0
|
||||
struct InputState
|
||||
{
|
||||
ButtonState Tapped;
|
||||
ButtonState Released;
|
||||
|
||||
ButtonState Down;
|
||||
uint32_t Padding_20[4];
|
||||
|
||||
ButtonState DoubleTapped;
|
||||
uint32_t Padding_30[4];
|
||||
|
||||
ButtonState IntervalTapped;
|
||||
uint32_t Padding_38[12];
|
||||
|
||||
int32_t MouseX;
|
||||
int32_t MouseY;
|
||||
int32_t MouseDeltaX;
|
||||
int32_t MouseDeltaY;
|
||||
|
||||
uint32_t Padding_AC[8];
|
||||
uint8_t Padding_D0[3];
|
||||
char Key;
|
||||
|
||||
void ClearState();
|
||||
void HideCursor();
|
||||
void SetBit(uint32_t bit, bool value, InputBufferType inputType);
|
||||
uint8_t* GetInputBuffer(InputBufferType inputType);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum JvsButtons : uint32_t
|
||||
{
|
||||
JVS_NONE = 0 << 0x00, // 0x0
|
||||
|
||||
JVS_TEST = 1 << 0x00, // 0x1
|
||||
JVS_SERVICE = 1 << 0x01, // 0x2
|
||||
|
||||
JVS_START = 1 << 0x02, // 0x4
|
||||
JVS_TRIANGLE = 1 << 0x07, // 0x80
|
||||
JVS_SQUARE = 1 << 0x08, // 0x100
|
||||
JVS_CROSS = 1 << 0x09, // 0x200
|
||||
JVS_CIRCLE = 1 << 0x0A, // 0x400
|
||||
JVS_L = 1 << 0x0B, // 0x800
|
||||
JVS_R = 1 << 0x0C, // 0x1000
|
||||
|
||||
JVS_SW1 = 1 << 0x12, // 0x40000
|
||||
JVS_SW2 = 1 << 0x13, // 0x80000
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "TouchPanelEmulator.h"
|
||||
#include <iostream>
|
||||
#include "../ComponentsManager.h"
|
||||
#include "../../Constants.h"
|
||||
#include "../../Input/Mouse/Mouse.h"
|
||||
#include "../../Input/Keyboard/Keyboard.h"
|
||||
|
||||
using namespace TLAC::Input;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
TouchPanelEmulator::TouchPanelEmulator()
|
||||
{
|
||||
}
|
||||
|
||||
TouchPanelEmulator::~TouchPanelEmulator()
|
||||
{
|
||||
}
|
||||
|
||||
const char* TouchPanelEmulator::GetDisplayName()
|
||||
{
|
||||
return "touch_panel_emulator";
|
||||
}
|
||||
|
||||
void TouchPanelEmulator::Initialize(ComponentsManager* manager)
|
||||
{
|
||||
componentsManager = manager;
|
||||
state = GetTouchStatePtr((void*)TASK_TOUCH_ADDRESS);
|
||||
}
|
||||
|
||||
void TouchPanelEmulator::Update()
|
||||
{
|
||||
state->ConnectionState = 1;
|
||||
}
|
||||
|
||||
void TouchPanelEmulator::UpdateInput()
|
||||
{
|
||||
if (!componentsManager->GetUpdateGameInput() || componentsManager->IsDwGuiActive() || componentsManager->IsDwGuiHovered())
|
||||
return;
|
||||
|
||||
// TODO: rescale TouchReaction aet position
|
||||
auto keyboard = Keyboard::GetInstance();
|
||||
auto pos = Mouse::GetInstance()->GetRelativePosition();
|
||||
|
||||
state->XPosition = (float)pos.x;
|
||||
state->YPosition = (float)pos.y;
|
||||
|
||||
bool down = keyboard->IsDown(VK_LBUTTON);
|
||||
bool released = keyboard->IsReleased(VK_LBUTTON);
|
||||
|
||||
state->ContactType = (down ? 0x2 : released ? 0x1 : 0x0);
|
||||
state->Pressure = (float)(state->ContactType != 0);
|
||||
}
|
||||
|
||||
TouchPanelState* TouchPanelEmulator::GetTouchStatePtr(void *address)
|
||||
{
|
||||
return (TouchPanelState*)address;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "../EmulatorComponent.h"
|
||||
#include "TouchPanelState.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class TouchPanelEmulator : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
TouchPanelEmulator();
|
||||
~TouchPanelEmulator();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
private:
|
||||
ComponentsManager* componentsManager;
|
||||
|
||||
TouchPanelState* state;
|
||||
TouchPanelState* GetTouchStatePtr(void *address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct TouchPanelState
|
||||
{
|
||||
int Padding00[0x1E];
|
||||
int ConnectionState;
|
||||
int Padding01[0x06];
|
||||
float XPosition;
|
||||
float YPosition;
|
||||
float Pressure;
|
||||
int ContactType;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
#include "TouchSliderEmulator.h"
|
||||
#include "../ComponentsManager.h"
|
||||
#include "../../Constants.h"
|
||||
#include "../../framework.h"
|
||||
#include "../../Input/Mouse/Mouse.h"
|
||||
#include "../../Input/Keyboard/Keyboard.h"
|
||||
#include "../../Input/Bindings/KeyboardBinding.h"
|
||||
#include "../../Input/KeyConfig/Config.h"
|
||||
#include "../../FileSystem/ConfigFile.h"
|
||||
#include "../../Utilities/Math.h"
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace TLAC::Input;
|
||||
using namespace TLAC::Input::KeyConfig;
|
||||
using namespace TLAC::Utilities;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
const std::string KEY_CONFIG_FILE_NAME = "keyconfig.ini";
|
||||
|
||||
TouchSliderEmulator::TouchSliderEmulator()
|
||||
{
|
||||
}
|
||||
|
||||
TouchSliderEmulator::~TouchSliderEmulator()
|
||||
{
|
||||
delete LeftSideSlideLeft;
|
||||
delete LeftSideSlideRight;
|
||||
|
||||
delete RightSideSlideLeft;
|
||||
delete RightSideSlideRight;
|
||||
}
|
||||
|
||||
const char* TouchSliderEmulator::GetDisplayName()
|
||||
{
|
||||
return "touch_slider_emulator";
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::Initialize(ComponentsManager* manager)
|
||||
{
|
||||
componentsManager = manager;
|
||||
sliderState = (TouchSliderState*)SLIDER_CTRL_TASK_ADDRESS;
|
||||
|
||||
LeftSideSlideLeft = new Binding();
|
||||
LeftSideSlideRight = new Binding();
|
||||
|
||||
RightSideSlideLeft = new Binding();
|
||||
RightSideSlideRight = new Binding();
|
||||
|
||||
FileSystem::ConfigFile configFile(framework::GetModuleDirectory(), KEY_CONFIG_FILE_NAME);
|
||||
configFile.OpenRead();
|
||||
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_LEFT", *LeftSideSlideLeft, { "Q" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_RIGHT", *LeftSideSlideRight, { "E" });
|
||||
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_LEFT", *RightSideSlideLeft, { "U" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_RIGHT", *RightSideSlideRight, { "O" });
|
||||
|
||||
float touchSliderEmulationSpeed = configFile.GetFloatValue("touch_slider_emulation_speed");
|
||||
|
||||
if (touchSliderEmulationSpeed != 0.0f)
|
||||
sliderSpeed = touchSliderEmulationSpeed;
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::Update()
|
||||
{
|
||||
sliderState->State = SLIDER_OK;
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::UpdateInput()
|
||||
{
|
||||
if (!componentsManager->GetUpdateGameInput() || componentsManager->IsDwGuiActive())
|
||||
return;
|
||||
|
||||
sliderIncrement = GetElapsedTime() / sliderSpeed;
|
||||
|
||||
constexpr float sensorStep = (1.0f / SLIDER_SENSORS);
|
||||
|
||||
EmulateSliderInput(LeftSideSlideLeft, LeftSideSlideRight, ContactPoints[0], 0.0f, 0.5f);
|
||||
EmulateSliderInput(RightSideSlideLeft, RightSideSlideRight, ContactPoints[1], 0.5f + sensorStep, 1.0f + sensorStep);
|
||||
|
||||
sliderState->ResetSensors();
|
||||
|
||||
for (int i = 0; i < CONTACT_POINTS; i++)
|
||||
ApplyContactPoint(ContactPoints[i], i);
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::OnFocusLost()
|
||||
{
|
||||
sliderState->ResetSensors();
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::EmulateSliderInput(Binding *leftBinding, Binding *rightBinding, ContactPoint &contactPoint, float start, float end)
|
||||
{
|
||||
bool leftDown = leftBinding->AnyDown();
|
||||
bool rightDown = rightBinding->AnyDown();
|
||||
|
||||
if (leftDown)
|
||||
contactPoint.Position -= sliderIncrement;
|
||||
else if (rightDown)
|
||||
contactPoint.Position += sliderIncrement;
|
||||
|
||||
if (contactPoint.Position < start)
|
||||
contactPoint.Position = end;
|
||||
|
||||
if (contactPoint.Position > end)
|
||||
contactPoint.Position = start;
|
||||
|
||||
bool leftTapped = leftBinding->AnyTapped();
|
||||
bool rightTapped = rightBinding->AnyTapped();
|
||||
|
||||
if (leftTapped || rightTapped)
|
||||
contactPoint.Position = (start + end) / 2.0f;
|
||||
|
||||
contactPoint.InContact = leftDown || rightDown;
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::ApplyContactPoint(ContactPoint &contactPoint, int section)
|
||||
{
|
||||
sliderState->SectionTouched[section] = contactPoint.InContact;
|
||||
|
||||
int pressure = contactPoint.InContact ? FULL_PRESSURE : NO_PRESSURE;
|
||||
float position = std::clamp(contactPoint.Position, 0.0f, 1.0f);
|
||||
|
||||
if (contactPoint.InContact)
|
||||
{
|
||||
int sensor = (int)(position * (SLIDER_SENSORS - 1));
|
||||
|
||||
sliderState->SetSensor(sensor, pressure);
|
||||
}
|
||||
|
||||
constexpr float startRange = -1.0f;
|
||||
constexpr float endRange = +1.0f;
|
||||
|
||||
sliderState->SectionPositions[section] = contactPoint.InContact ? (ConvertRange(0.0f, 1.0f, startRange, endRange, position)) : 0.0f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
#include "../EmulatorComponent.h"
|
||||
#include "TouchSliderState.h"
|
||||
#include "../../Input/Bindings/Binding.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
constexpr int SLIDER_INPUTS = 4;
|
||||
constexpr int CONTACT_POINTS = 2;
|
||||
|
||||
struct ContactPoint
|
||||
{
|
||||
float Position;
|
||||
bool InContact;
|
||||
};
|
||||
|
||||
class TouchSliderEmulator : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
Input::Binding* LeftSideSlideLeft;
|
||||
Input::Binding* LeftSideSlideRight;
|
||||
|
||||
Input::Binding* RightSideSlideLeft;
|
||||
Input::Binding* RightSideSlideRight;
|
||||
|
||||
TouchSliderEmulator();
|
||||
~TouchSliderEmulator();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
virtual void OnFocusLost() override;
|
||||
|
||||
private:
|
||||
ComponentsManager* componentsManager;
|
||||
float sliderSpeed = 750.0f;
|
||||
float sliderIncrement;
|
||||
|
||||
TouchSliderState *sliderState;
|
||||
ContactPoint ContactPoints[CONTACT_POINTS];
|
||||
|
||||
void EmulateSliderInput(Input::Binding *leftBinding, Input::Binding *rightBinding, ContactPoint &contactPoint, float start, float end);
|
||||
void ApplyContactPoint(ContactPoint &contactPoint, int section);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "TouchSliderState.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
void TouchSliderState::SetSensor(int index, int value)
|
||||
{
|
||||
if (index < 0 || index >= SLIDER_SENSORS)
|
||||
return;
|
||||
|
||||
SensorPressureLevels[index] = value;
|
||||
SensorTouched[index].IsTouched = value > 0;
|
||||
}
|
||||
|
||||
void TouchSliderState::ResetSensors()
|
||||
{
|
||||
for (int i = 0; i < SLIDER_SENSORS; i++)
|
||||
SetSensor(i, NO_PRESSURE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define SLIDER_OK 3
|
||||
#define SLIDER_SECTIONS 4
|
||||
#define SLIDER_SENSORS 32
|
||||
|
||||
#define NO_PRESSURE 0
|
||||
#define FULL_PRESSURE 180
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct TouchSliderState
|
||||
{
|
||||
uint8_t Padding0000[112];
|
||||
|
||||
int32_t State;
|
||||
|
||||
uint8_t Padding0074[20 + 12];
|
||||
|
||||
int32_t SensorPressureLevels[SLIDER_SENSORS];
|
||||
|
||||
uint8_t Padding0108[52 - 12];
|
||||
|
||||
float SectionPositions[SLIDER_SECTIONS];
|
||||
int SectionConnections[SLIDER_SECTIONS];
|
||||
uint8_t Padding015C[4];
|
||||
bool SectionTouched[SLIDER_SECTIONS];
|
||||
|
||||
uint8_t Padding013C[3128 - 52 - 40];
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t Padding00[2];
|
||||
bool IsTouched;
|
||||
uint8_t Padding[45];
|
||||
} SensorTouched[SLIDER_SENSORS];
|
||||
|
||||
void SetSensor(int index, int value);
|
||||
void ResetSensors();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,973 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
struct PlayerData
|
||||
{
|
||||
int8_t use_card;
|
||||
int8_t freeplay;
|
||||
int8_t field_2;
|
||||
int8_t field_3;
|
||||
int32_t card_type;
|
||||
int32_t field_8;
|
||||
int32_t field_C;
|
||||
int32_t field_10;
|
||||
int32_t field_14;
|
||||
int32_t field_18;
|
||||
int32_t field_1C;
|
||||
int32_t field_20;
|
||||
int32_t field_24;
|
||||
int32_t field_28;
|
||||
int32_t field_2C;
|
||||
int32_t field_30;
|
||||
int32_t field_34;
|
||||
int32_t field_38;
|
||||
int32_t field_3C;
|
||||
int32_t field_40;
|
||||
int32_t field_44;
|
||||
int32_t field_48;
|
||||
int32_t field_4C;
|
||||
int32_t field_50;
|
||||
int32_t field_54;
|
||||
int32_t field_58;
|
||||
int32_t field_5C;
|
||||
int32_t field_60;
|
||||
int32_t field_64;
|
||||
int32_t field_68;
|
||||
int32_t field_6C;
|
||||
int32_t field_70;
|
||||
int32_t field_74;
|
||||
int32_t field_78;
|
||||
int32_t field_7C;
|
||||
int32_t field_80;
|
||||
int32_t field_84;
|
||||
int32_t field_88;
|
||||
int32_t field_8C;
|
||||
int32_t field_90;
|
||||
int32_t field_94;
|
||||
int32_t field_98;
|
||||
int32_t field_9C;
|
||||
int32_t field_A0;
|
||||
int32_t field_A4;
|
||||
int32_t field_A8;
|
||||
int32_t field_AC;
|
||||
int32_t field_B0;
|
||||
int32_t field_B4;
|
||||
int32_t field_B8;
|
||||
int32_t field_BC;
|
||||
int32_t field_C0;
|
||||
int32_t field_C4;
|
||||
int32_t field_C8;
|
||||
int32_t field_CC;
|
||||
int32_t play_data_id;
|
||||
int32_t accept_index;
|
||||
int32_t start_index;
|
||||
int32_t field_DC;
|
||||
char* player_name;
|
||||
int32_t field_E8;
|
||||
int32_t field_EC;
|
||||
int32_t field_F0;
|
||||
int32_t field_F4;
|
||||
int32_t field_F8;
|
||||
int32_t field_FC;
|
||||
char* level_name;
|
||||
int32_t field_108;
|
||||
int32_t field_10C;
|
||||
int32_t field_110;
|
||||
int32_t field_114;
|
||||
int32_t field_118;
|
||||
int32_t field_11C;
|
||||
int32_t field_120;
|
||||
int32_t level_plate_id;
|
||||
int32_t field_128;
|
||||
int32_t vocaloid_point;
|
||||
int32_t hp_vol;
|
||||
int32_t act_toggle;
|
||||
int32_t act_vol;
|
||||
int32_t act_slide_vol;
|
||||
int32_t field_140;
|
||||
int32_t field_144;
|
||||
int32_t field_148;
|
||||
int32_t field_14C;
|
||||
int32_t field_150;
|
||||
int32_t field_154;
|
||||
int32_t field_158;
|
||||
int32_t field_15C;
|
||||
int32_t field_160;
|
||||
int32_t field_164;
|
||||
int32_t field_168;
|
||||
int32_t field_16C;
|
||||
int32_t field_170;
|
||||
int32_t field_174;
|
||||
int32_t field_178;
|
||||
int32_t field_17C;
|
||||
int32_t field_180;
|
||||
int32_t field_184;
|
||||
int32_t field_188;
|
||||
int32_t field_18C;
|
||||
int32_t field_190;
|
||||
int32_t field_194;
|
||||
int32_t field_198;
|
||||
int32_t field_19C;
|
||||
int32_t field_1A0;
|
||||
int32_t field_1A4;
|
||||
int32_t field_1A8;
|
||||
int32_t field_1AC;
|
||||
int32_t field_1B0;
|
||||
int32_t field_1B4;
|
||||
int32_t field_1B8;
|
||||
int32_t field_1BC;
|
||||
int32_t field_1C0;
|
||||
int32_t field_1C4;
|
||||
int32_t field_1C8;
|
||||
int32_t field_1CC;
|
||||
int32_t field_1D0;
|
||||
int32_t field_1D4;
|
||||
int32_t field_1D8;
|
||||
int32_t field_1DC;
|
||||
int32_t field_1E0;
|
||||
int32_t field_1E4;
|
||||
int32_t field_1E8;
|
||||
int32_t field_1EC;
|
||||
int32_t field_1F0;
|
||||
int32_t field_1F4;
|
||||
int32_t field_1F8;
|
||||
int32_t field_1FC;
|
||||
int32_t field_200;
|
||||
int32_t field_204;
|
||||
int32_t field_208;
|
||||
int32_t field_20C;
|
||||
int32_t field_210;
|
||||
int32_t field_214;
|
||||
int32_t field_218;
|
||||
int32_t field_21C;
|
||||
int32_t field_220;
|
||||
int32_t field_224;
|
||||
int32_t field_228;
|
||||
int32_t field_22C;
|
||||
int32_t field_230;
|
||||
int32_t field_234;
|
||||
int32_t field_238;
|
||||
int32_t field_23C;
|
||||
int32_t field_240;
|
||||
int32_t field_244;
|
||||
int32_t field_248;
|
||||
int32_t field_24C;
|
||||
int32_t field_250;
|
||||
int32_t field_254;
|
||||
int32_t field_258;
|
||||
int32_t field_25C;
|
||||
int32_t field_260;
|
||||
int32_t field_264;
|
||||
int32_t field_268;
|
||||
int32_t field_26C;
|
||||
int32_t field_270;
|
||||
int32_t field_274;
|
||||
int32_t field_278;
|
||||
int32_t field_27C;
|
||||
int32_t field_280;
|
||||
int32_t field_284;
|
||||
int32_t field_288;
|
||||
int32_t field_28C;
|
||||
int32_t field_290;
|
||||
int32_t field_294;
|
||||
int32_t field_298;
|
||||
int32_t field_29C;
|
||||
int32_t field_2A0;
|
||||
int32_t field_2A4;
|
||||
int32_t field_2A8;
|
||||
int32_t field_2AC;
|
||||
int8_t use_pv_module_equip;
|
||||
int8_t ch_pv_module_equip;
|
||||
int8_t field_2B2;
|
||||
int8_t field_2B3;
|
||||
int32_t module_filter_kind;
|
||||
int32_t field_2B8;
|
||||
int32_t field_2BC;
|
||||
int32_t field_2C0;
|
||||
int32_t field_2C4;
|
||||
int32_t field_2C8;
|
||||
int32_t field_2CC;
|
||||
int32_t field_2D0;
|
||||
int32_t field_2D4;
|
||||
int32_t field_2D8;
|
||||
int32_t field_2DC;
|
||||
int32_t field_2E0;
|
||||
int32_t field_2E4;
|
||||
int32_t field_2E8;
|
||||
int32_t field_2EC;
|
||||
int32_t field_2F0;
|
||||
int32_t field_2F4;
|
||||
int32_t field_2F8;
|
||||
int32_t field_2FC;
|
||||
int32_t field_300;
|
||||
int32_t field_304;
|
||||
int32_t field_308;
|
||||
int32_t field_30C;
|
||||
int32_t field_310;
|
||||
int32_t field_314;
|
||||
int32_t field_318;
|
||||
int32_t field_31C;
|
||||
int32_t field_320;
|
||||
int32_t field_324;
|
||||
int32_t field_328;
|
||||
int32_t field_32C;
|
||||
int32_t field_330;
|
||||
int32_t field_334;
|
||||
int32_t field_338;
|
||||
int32_t field_33C;
|
||||
int32_t field_340;
|
||||
int32_t field_344;
|
||||
int32_t field_348;
|
||||
int32_t field_34C;
|
||||
int32_t field_350;
|
||||
int32_t field_354;
|
||||
int32_t field_358;
|
||||
int32_t field_35C;
|
||||
int32_t field_360;
|
||||
int32_t field_364;
|
||||
int32_t field_368;
|
||||
int32_t field_36C;
|
||||
int32_t field_370;
|
||||
int32_t field_374;
|
||||
int32_t field_378;
|
||||
int32_t field_37C;
|
||||
int32_t field_380;
|
||||
int32_t field_384;
|
||||
int32_t field_388;
|
||||
int32_t field_38C;
|
||||
int32_t field_390;
|
||||
int32_t field_394;
|
||||
int32_t field_398;
|
||||
int32_t field_39C;
|
||||
int32_t field_3A0;
|
||||
int32_t field_3A4;
|
||||
int32_t field_3A8;
|
||||
int32_t field_3AC;
|
||||
int32_t field_3B0;
|
||||
int32_t field_3B4;
|
||||
int32_t field_3B8;
|
||||
int32_t field_3BC;
|
||||
int32_t field_3C0;
|
||||
int32_t field_3C4;
|
||||
int32_t field_3C8;
|
||||
int32_t field_3CC;
|
||||
int32_t field_3D0;
|
||||
int32_t field_3D4;
|
||||
int32_t field_3D8;
|
||||
int32_t field_3DC;
|
||||
int32_t field_3E0;
|
||||
int32_t field_3E4;
|
||||
int32_t field_3E8;
|
||||
int32_t field_3EC;
|
||||
int32_t field_3F0;
|
||||
int32_t field_3F4;
|
||||
int32_t field_3F8;
|
||||
int32_t field_3FC;
|
||||
int32_t field_400;
|
||||
int32_t field_404;
|
||||
int32_t field_408;
|
||||
int32_t field_40C;
|
||||
int32_t field_410;
|
||||
int32_t field_414;
|
||||
int32_t field_418;
|
||||
int32_t field_41C;
|
||||
int32_t field_420;
|
||||
int32_t field_424;
|
||||
int32_t field_428;
|
||||
int32_t field_42C;
|
||||
int32_t field_430;
|
||||
int32_t field_434;
|
||||
int32_t field_438;
|
||||
int32_t field_43C;
|
||||
int32_t field_440;
|
||||
int32_t field_444;
|
||||
int32_t field_448;
|
||||
int32_t field_44C;
|
||||
int32_t field_450;
|
||||
int32_t field_454;
|
||||
int32_t field_458;
|
||||
int32_t field_45C;
|
||||
int32_t field_460;
|
||||
int32_t field_464;
|
||||
int32_t field_468;
|
||||
int32_t field_46C;
|
||||
int32_t field_470;
|
||||
int32_t field_474;
|
||||
int32_t field_478;
|
||||
int32_t field_47C;
|
||||
int32_t field_480;
|
||||
int32_t field_484;
|
||||
int32_t field_488;
|
||||
int32_t field_48C;
|
||||
int32_t field_490;
|
||||
int32_t field_494;
|
||||
int32_t field_498;
|
||||
int32_t field_49C;
|
||||
int32_t field_4A0;
|
||||
int32_t field_4A4;
|
||||
int32_t field_4A8;
|
||||
int32_t field_4AC;
|
||||
int32_t field_4B0;
|
||||
int32_t field_4B4;
|
||||
int32_t field_4B8;
|
||||
int32_t field_4BC;
|
||||
int32_t field_4C0;
|
||||
int32_t field_4C4;
|
||||
int32_t field_4C8;
|
||||
int32_t field_4CC;
|
||||
int32_t field_4D0;
|
||||
int32_t field_4D4;
|
||||
int32_t field_4D8;
|
||||
int32_t field_4DC;
|
||||
int32_t field_4E0;
|
||||
int32_t field_4E4;
|
||||
int32_t field_4E8;
|
||||
int32_t field_4EC;
|
||||
int32_t field_4F0;
|
||||
int32_t field_4F4;
|
||||
int32_t field_4F8;
|
||||
int32_t field_4FC;
|
||||
int32_t field_500;
|
||||
int32_t field_504;
|
||||
int32_t field_508;
|
||||
int32_t field_50C;
|
||||
int32_t field_510;
|
||||
int32_t field_514;
|
||||
int32_t field_518;
|
||||
int32_t field_51C;
|
||||
int32_t field_520;
|
||||
int32_t field_524;
|
||||
int32_t field_528;
|
||||
int32_t field_52C;
|
||||
int32_t field_530;
|
||||
int32_t field_534;
|
||||
int32_t field_538;
|
||||
int32_t field_53C;
|
||||
int32_t field_540;
|
||||
int32_t field_544;
|
||||
int32_t skin_equip;
|
||||
int32_t skin_equip_cmn;
|
||||
int32_t use_pv_skin_equip;
|
||||
int32_t btn_se_equip;
|
||||
int32_t btn_se_equip_cmn;
|
||||
int32_t use_pv_btn_se_equip;
|
||||
int32_t slide_se_equip;
|
||||
int32_t slide_se_equip_cmn;
|
||||
int32_t use_pv_slide_se_equip;
|
||||
int32_t chainslide_se_equip;
|
||||
int32_t chainslide_se_equip_cmn;
|
||||
int32_t use_pv_chainslide_se_equip;
|
||||
int32_t slidertouch_se_equip;
|
||||
int32_t slidertouch_se_equip_cmn;
|
||||
int32_t use_pv_slidertouch_se_equip;
|
||||
int32_t field_584;
|
||||
int32_t field_588;
|
||||
int32_t field_58C;
|
||||
int32_t field_590;
|
||||
int32_t field_594;
|
||||
int32_t field_598;
|
||||
int32_t field_59C;
|
||||
int32_t field_5A0;
|
||||
int32_t field_5A4;
|
||||
int32_t field_5A8;
|
||||
int32_t field_5AC;
|
||||
int32_t field_5B0;
|
||||
int32_t field_5B4;
|
||||
int32_t field_5B8;
|
||||
int32_t field_5BC;
|
||||
int32_t field_5C0;
|
||||
int32_t field_5C4;
|
||||
int32_t field_5C8;
|
||||
int32_t field_5CC;
|
||||
int32_t field_5D0;
|
||||
int32_t field_5D4;
|
||||
int32_t field_5D8;
|
||||
int32_t field_5DC;
|
||||
int32_t field_5E0;
|
||||
int32_t field_5E4;
|
||||
int32_t field_5E8;
|
||||
int32_t field_5EC;
|
||||
int32_t field_5F0;
|
||||
int32_t field_5F4;
|
||||
int32_t field_5F8;
|
||||
int32_t field_5FC;
|
||||
int32_t field_600;
|
||||
int32_t field_604;
|
||||
int32_t field_608;
|
||||
int32_t field_60C;
|
||||
int32_t field_610;
|
||||
int32_t field_614;
|
||||
int32_t field_618;
|
||||
int32_t field_61C;
|
||||
int32_t field_620;
|
||||
int32_t field_624;
|
||||
int32_t field_628;
|
||||
int32_t field_62C;
|
||||
int32_t field_630;
|
||||
int32_t field_634;
|
||||
int32_t field_638;
|
||||
int32_t field_63C;
|
||||
int32_t field_640;
|
||||
int32_t field_644;
|
||||
int32_t field_648;
|
||||
int32_t field_64C;
|
||||
int32_t field_650;
|
||||
int32_t field_654;
|
||||
int32_t field_658;
|
||||
int32_t field_65C;
|
||||
int32_t field_660;
|
||||
int32_t field_664;
|
||||
int32_t field_668;
|
||||
int32_t field_66C;
|
||||
int32_t field_670;
|
||||
int32_t field_674;
|
||||
int32_t field_678;
|
||||
int32_t field_67C;
|
||||
int32_t field_680;
|
||||
int32_t field_684;
|
||||
int32_t field_688;
|
||||
int32_t field_68C;
|
||||
int32_t field_690;
|
||||
int32_t field_694;
|
||||
int32_t field_698;
|
||||
int32_t field_69C;
|
||||
int32_t field_6A0;
|
||||
int32_t field_6A4;
|
||||
int32_t field_6A8;
|
||||
int32_t field_6AC;
|
||||
int32_t field_6B0;
|
||||
int32_t field_6B4;
|
||||
int32_t field_6B8;
|
||||
int32_t field_6BC;
|
||||
int32_t field_6C0;
|
||||
int32_t field_6C4;
|
||||
int32_t field_6C8;
|
||||
int32_t field_6CC;
|
||||
int32_t field_6D0;
|
||||
int32_t field_6D4;
|
||||
int32_t field_6D8;
|
||||
int32_t field_6DC;
|
||||
int32_t field_6E0;
|
||||
int32_t field_6E4;
|
||||
int32_t field_6E8;
|
||||
int32_t field_6EC;
|
||||
int32_t field_6F0;
|
||||
int32_t field_6F4;
|
||||
int32_t field_6F8;
|
||||
int32_t field_6FC;
|
||||
int32_t field_700;
|
||||
int32_t field_704;
|
||||
int32_t field_708;
|
||||
int32_t field_70C;
|
||||
int32_t field_710;
|
||||
int32_t field_714;
|
||||
int32_t field_718;
|
||||
int32_t field_71C;
|
||||
int32_t field_720;
|
||||
int32_t field_724;
|
||||
int32_t field_728;
|
||||
int32_t field_72C;
|
||||
int32_t field_730;
|
||||
int32_t field_734;
|
||||
int32_t field_738;
|
||||
int32_t field_73C;
|
||||
int32_t field_740;
|
||||
int32_t field_744;
|
||||
int32_t field_748;
|
||||
int32_t field_74C;
|
||||
int32_t field_750;
|
||||
int32_t field_754;
|
||||
int32_t field_758;
|
||||
int32_t field_75C;
|
||||
int32_t field_760;
|
||||
int32_t field_764;
|
||||
int32_t field_768;
|
||||
int32_t field_76C;
|
||||
int32_t field_770;
|
||||
int32_t field_774;
|
||||
int32_t field_778;
|
||||
int32_t field_77C;
|
||||
int32_t field_780;
|
||||
int32_t field_784;
|
||||
int32_t field_788;
|
||||
int32_t field_78C;
|
||||
int32_t field_790;
|
||||
int32_t field_794;
|
||||
int32_t field_798;
|
||||
int32_t field_79C;
|
||||
int32_t field_7A0;
|
||||
int32_t field_7A4;
|
||||
int32_t field_7A8;
|
||||
int32_t field_7AC;
|
||||
int32_t field_7B0;
|
||||
int32_t field_7B4;
|
||||
int32_t field_7B8;
|
||||
int32_t field_7BC;
|
||||
int32_t field_7C0;
|
||||
int32_t field_7C4;
|
||||
int32_t field_7C8;
|
||||
int32_t field_7CC;
|
||||
int32_t field_7D0;
|
||||
int32_t field_7D4;
|
||||
int32_t field_7D8;
|
||||
int32_t field_7DC;
|
||||
int32_t field_7E0;
|
||||
int32_t field_7E4;
|
||||
int32_t field_7E8;
|
||||
int32_t field_7EC;
|
||||
int32_t field_7F0;
|
||||
int32_t field_7F4;
|
||||
int32_t field_7F8;
|
||||
int32_t field_7FC;
|
||||
int32_t field_800;
|
||||
int32_t field_804;
|
||||
int32_t field_808;
|
||||
int32_t field_80C;
|
||||
int32_t field_810;
|
||||
int32_t field_814;
|
||||
int32_t field_818;
|
||||
int32_t field_81C;
|
||||
int32_t field_820;
|
||||
int32_t field_824;
|
||||
int32_t field_828;
|
||||
int32_t field_82C;
|
||||
int32_t field_830;
|
||||
int32_t field_834;
|
||||
int32_t field_838;
|
||||
int32_t field_83C;
|
||||
int32_t field_840;
|
||||
int32_t field_844;
|
||||
int32_t field_848;
|
||||
int32_t field_84C;
|
||||
int32_t field_850;
|
||||
int32_t field_854;
|
||||
int32_t field_858;
|
||||
int32_t field_85C;
|
||||
int32_t field_860;
|
||||
int32_t field_864;
|
||||
int32_t field_868;
|
||||
int32_t field_86C;
|
||||
int32_t field_870;
|
||||
int32_t field_874;
|
||||
int32_t field_878;
|
||||
int32_t field_87C;
|
||||
int32_t field_880;
|
||||
int32_t field_884;
|
||||
int32_t field_888;
|
||||
int32_t field_88C;
|
||||
int32_t field_890;
|
||||
int32_t field_894;
|
||||
int32_t field_898;
|
||||
int32_t field_89C;
|
||||
int32_t field_8A0;
|
||||
int32_t field_8A4;
|
||||
int32_t field_8A8;
|
||||
int32_t field_8AC;
|
||||
int32_t field_8B0;
|
||||
int32_t field_8B4;
|
||||
int32_t field_8B8;
|
||||
int32_t field_8BC;
|
||||
int32_t field_8C0;
|
||||
int32_t field_8C4;
|
||||
int32_t field_8C8;
|
||||
int32_t field_8CC;
|
||||
int32_t field_8D0;
|
||||
int32_t field_8D4;
|
||||
int32_t field_8D8;
|
||||
int32_t field_8DC;
|
||||
int32_t field_8E0;
|
||||
int32_t field_8E4;
|
||||
int32_t field_8E8;
|
||||
int32_t field_8EC;
|
||||
int32_t field_8F0;
|
||||
int32_t field_8F4;
|
||||
int32_t field_8F8;
|
||||
int32_t field_8FC;
|
||||
int32_t field_900;
|
||||
int32_t field_904;
|
||||
int32_t field_908;
|
||||
int32_t field_90C;
|
||||
int32_t field_910;
|
||||
int32_t field_914;
|
||||
int32_t field_918;
|
||||
int32_t field_91C;
|
||||
int32_t field_920;
|
||||
int32_t field_924;
|
||||
int32_t field_928;
|
||||
int32_t field_92C;
|
||||
int32_t field_930;
|
||||
int32_t field_934;
|
||||
int32_t field_938;
|
||||
int32_t field_93C;
|
||||
int32_t field_940;
|
||||
int32_t field_944;
|
||||
int32_t field_948;
|
||||
int32_t field_94C;
|
||||
int32_t field_950;
|
||||
int32_t field_954;
|
||||
int32_t field_958;
|
||||
int32_t field_95C;
|
||||
int32_t field_960;
|
||||
int32_t field_964;
|
||||
int32_t field_968;
|
||||
int32_t field_96C;
|
||||
int32_t field_970;
|
||||
int32_t field_974;
|
||||
int32_t field_978;
|
||||
int32_t field_97C;
|
||||
int32_t field_980;
|
||||
int32_t field_984;
|
||||
int32_t field_988;
|
||||
int32_t field_98C;
|
||||
int32_t field_990;
|
||||
int32_t field_994;
|
||||
int32_t field_998;
|
||||
int32_t field_99C;
|
||||
int32_t field_9A0;
|
||||
int32_t field_9A4;
|
||||
int32_t field_9A8;
|
||||
int32_t field_9AC;
|
||||
int32_t field_9B0;
|
||||
int32_t field_9B4;
|
||||
int32_t field_9B8;
|
||||
int32_t field_9BC;
|
||||
int32_t field_9C0;
|
||||
int32_t field_9C4;
|
||||
int32_t field_9C8;
|
||||
int32_t field_9CC;
|
||||
int32_t field_9D0;
|
||||
int32_t field_9D4;
|
||||
int32_t field_9D8;
|
||||
int32_t field_9DC;
|
||||
int32_t field_9E0;
|
||||
int32_t field_9E4;
|
||||
int32_t field_9E8;
|
||||
int32_t field_9EC;
|
||||
int32_t field_9F0;
|
||||
int32_t field_9F4;
|
||||
int32_t field_9F8;
|
||||
int32_t field_9FC;
|
||||
int32_t field_A00;
|
||||
int32_t field_A04;
|
||||
int32_t field_A08;
|
||||
int32_t field_A0C;
|
||||
int32_t field_A10;
|
||||
int32_t field_A14;
|
||||
int32_t field_A18;
|
||||
int32_t field_A1C;
|
||||
int32_t field_A20;
|
||||
int32_t field_A24;
|
||||
int32_t field_A28;
|
||||
int32_t field_A2C;
|
||||
int32_t field_A30;
|
||||
int32_t field_A34;
|
||||
int32_t field_A38;
|
||||
int32_t field_A3C;
|
||||
int32_t field_A40;
|
||||
int32_t field_A44;
|
||||
int32_t field_A48;
|
||||
int32_t field_A4C;
|
||||
int32_t field_A50;
|
||||
int32_t field_A54;
|
||||
int32_t field_A58;
|
||||
int32_t field_A5C;
|
||||
int32_t field_A60;
|
||||
int32_t field_A64;
|
||||
int32_t field_A68;
|
||||
int32_t field_A6C;
|
||||
int32_t field_A70;
|
||||
int32_t field_A74;
|
||||
int32_t field_A78;
|
||||
int32_t field_A7C;
|
||||
int32_t field_A80;
|
||||
int32_t field_A84;
|
||||
int32_t field_A88;
|
||||
int32_t field_A8C;
|
||||
int32_t field_A90;
|
||||
int32_t field_A94;
|
||||
int32_t field_A98;
|
||||
int32_t field_A9C;
|
||||
int32_t field_AA0;
|
||||
int32_t field_AA4;
|
||||
int32_t field_AA8;
|
||||
int32_t field_AAC;
|
||||
int32_t field_AB0;
|
||||
int32_t field_AB4;
|
||||
int32_t field_AB8;
|
||||
int32_t field_ABC;
|
||||
int32_t field_AC0;
|
||||
int32_t field_AC4;
|
||||
int32_t field_AC8;
|
||||
int32_t field_ACC;
|
||||
int32_t field_AD0;
|
||||
int32_t field_AD4;
|
||||
int32_t field_AD8;
|
||||
int32_t field_ADC;
|
||||
int32_t field_AE0;
|
||||
int32_t field_AE4;
|
||||
int32_t field_AE8;
|
||||
int32_t field_AEC;
|
||||
int32_t field_AF0;
|
||||
int32_t field_AF4;
|
||||
int32_t field_AF8;
|
||||
int32_t field_AFC;
|
||||
int32_t field_B00;
|
||||
int32_t field_B04;
|
||||
int32_t field_B08;
|
||||
int32_t field_B0C;
|
||||
int32_t field_B10;
|
||||
int32_t field_B14;
|
||||
int32_t field_B18;
|
||||
int32_t field_B1C;
|
||||
int32_t field_B20;
|
||||
int32_t field_B24;
|
||||
int32_t field_B28;
|
||||
int32_t field_B2C;
|
||||
int32_t field_B30;
|
||||
int32_t field_B34;
|
||||
int32_t field_B38;
|
||||
int32_t field_B3C;
|
||||
int32_t field_B40;
|
||||
int32_t field_B44;
|
||||
int32_t field_B48;
|
||||
int32_t field_B4C;
|
||||
int32_t field_B50;
|
||||
int32_t field_B54;
|
||||
int32_t field_B58;
|
||||
int32_t field_B5C;
|
||||
int32_t field_B60;
|
||||
int32_t field_B64;
|
||||
int32_t field_B68;
|
||||
int32_t field_B6C;
|
||||
int32_t field_B70;
|
||||
int32_t field_B74;
|
||||
int32_t field_B78;
|
||||
int32_t field_B7C;
|
||||
int32_t field_B80;
|
||||
int32_t field_B84;
|
||||
int32_t field_B88;
|
||||
int32_t field_B8C;
|
||||
int32_t field_B90;
|
||||
int32_t field_B94;
|
||||
int32_t field_B98;
|
||||
int32_t field_B9C;
|
||||
int32_t field_BA0;
|
||||
int32_t field_BA4;
|
||||
int32_t field_BA8;
|
||||
int32_t field_BAC;
|
||||
int32_t field_BB0;
|
||||
int32_t field_BB4;
|
||||
int32_t field_BB8;
|
||||
int32_t field_BBC;
|
||||
int32_t field_BC0;
|
||||
int32_t field_BC4;
|
||||
int32_t field_BC8;
|
||||
int32_t field_BCC;
|
||||
int32_t field_BD0;
|
||||
int32_t field_BD4;
|
||||
int32_t field_BD8;
|
||||
int32_t field_BDC;
|
||||
int32_t field_BE0;
|
||||
int32_t field_BE4;
|
||||
int32_t field_BE8;
|
||||
int32_t field_BEC;
|
||||
int32_t field_BF0;
|
||||
int32_t field_BF4;
|
||||
int32_t field_BF8;
|
||||
int32_t field_BFC;
|
||||
int32_t field_C00;
|
||||
int32_t field_C04;
|
||||
int32_t field_C08;
|
||||
int32_t field_C0C;
|
||||
int32_t field_C10;
|
||||
int32_t field_C14;
|
||||
int32_t field_C18;
|
||||
int32_t field_C1C;
|
||||
int32_t field_C20;
|
||||
int32_t field_C24;
|
||||
int32_t field_C28;
|
||||
int32_t field_C2C;
|
||||
int32_t field_C30;
|
||||
int32_t field_C34;
|
||||
int32_t field_C38;
|
||||
int32_t field_C3C;
|
||||
int32_t field_C40;
|
||||
int32_t field_C44;
|
||||
int32_t field_C48;
|
||||
int32_t field_C4C;
|
||||
int32_t field_C50;
|
||||
int32_t field_C54;
|
||||
int32_t field_C58;
|
||||
int32_t field_C5C;
|
||||
int32_t field_C60;
|
||||
int32_t field_C64;
|
||||
int32_t field_C68;
|
||||
int32_t field_C6C;
|
||||
int32_t field_C70;
|
||||
int32_t field_C74;
|
||||
int32_t field_C78;
|
||||
int32_t field_C7C;
|
||||
int32_t field_C80;
|
||||
int32_t field_C84;
|
||||
int32_t field_C88;
|
||||
int32_t field_C8C;
|
||||
int32_t field_C90;
|
||||
int32_t field_C94;
|
||||
int32_t field_C98;
|
||||
int32_t field_C9C;
|
||||
int32_t field_CA0;
|
||||
int32_t field_CA4;
|
||||
int32_t field_CA8;
|
||||
int32_t field_CAC;
|
||||
int32_t field_CB0;
|
||||
int32_t field_CB4;
|
||||
int32_t field_CB8;
|
||||
int32_t field_CBC;
|
||||
int32_t field_CC0;
|
||||
int32_t field_CC4;
|
||||
int32_t field_CC8;
|
||||
int32_t field_CCC;
|
||||
int32_t field_CD0;
|
||||
int32_t field_CD4;
|
||||
int32_t field_CD8;
|
||||
int32_t field_CDC;
|
||||
int32_t field_CE0;
|
||||
int32_t field_CE4;
|
||||
int32_t field_CE8;
|
||||
int32_t field_CEC;
|
||||
int32_t field_CF0;
|
||||
int32_t field_CF4;
|
||||
int32_t field_CF8;
|
||||
int32_t field_CFC;
|
||||
int32_t field_D00;
|
||||
int32_t field_D04;
|
||||
int32_t field_D08;
|
||||
int32_t field_D0C;
|
||||
int32_t field_D10;
|
||||
int32_t field_D14;
|
||||
int32_t field_D18;
|
||||
int32_t field_D1C;
|
||||
int32_t field_D20;
|
||||
int32_t field_D24;
|
||||
int32_t field_D28;
|
||||
int32_t field_D2C;
|
||||
int32_t field_D30;
|
||||
int32_t field_D34;
|
||||
int32_t field_D38;
|
||||
int32_t field_D3C;
|
||||
int32_t field_D40;
|
||||
int32_t field_D44;
|
||||
int32_t field_D48;
|
||||
int32_t field_D4C;
|
||||
int32_t field_D50;
|
||||
int32_t field_D54;
|
||||
int32_t field_D58;
|
||||
int32_t field_D5C;
|
||||
int32_t field_D60;
|
||||
int32_t field_D64;
|
||||
int32_t field_D68;
|
||||
int32_t field_D6C;
|
||||
int32_t field_D70;
|
||||
int32_t field_D74;
|
||||
int32_t field_D78;
|
||||
int32_t field_D7C;
|
||||
int32_t field_D80;
|
||||
int32_t field_D84;
|
||||
int32_t field_D88;
|
||||
int32_t field_D8C;
|
||||
int32_t field_D90;
|
||||
int32_t field_D94;
|
||||
int32_t field_D98;
|
||||
int32_t field_D9C;
|
||||
int32_t field_DA0;
|
||||
int32_t field_DA4;
|
||||
int32_t field_DA8;
|
||||
int32_t field_DAC;
|
||||
int32_t field_DB0;
|
||||
int32_t field_DB4;
|
||||
int32_t field_DB8;
|
||||
int32_t field_DBC;
|
||||
int32_t field_DC0;
|
||||
int32_t field_DC4;
|
||||
int32_t field_DC8;
|
||||
int32_t field_DCC;
|
||||
int32_t field_DD0;
|
||||
int32_t field_DD4;
|
||||
int32_t field_DD8;
|
||||
int32_t field_DDC;
|
||||
int32_t field_DE0;
|
||||
int32_t field_DE4;
|
||||
int32_t field_DE8;
|
||||
int32_t field_DEC;
|
||||
int32_t field_DF0;
|
||||
int32_t field_DF4;
|
||||
int32_t field_DF8;
|
||||
int32_t field_DFC;
|
||||
int32_t field_E00;
|
||||
int32_t field_E04;
|
||||
int32_t field_E08;
|
||||
int32_t field_E0C;
|
||||
int32_t field_E10;
|
||||
int32_t field_E14;
|
||||
int32_t field_E18;
|
||||
int32_t field_E1C;
|
||||
int32_t field_E20;
|
||||
int32_t field_E24;
|
||||
int32_t field_E28;
|
||||
int32_t field_E2C;
|
||||
int32_t field_E30;
|
||||
int8_t field_E34;
|
||||
int8_t game_opts;
|
||||
int8_t field_E36;
|
||||
int8_t field_E37;
|
||||
int32_t field_E38;
|
||||
int32_t field_E3C;
|
||||
int32_t field_E40;
|
||||
int32_t field_E44;
|
||||
int32_t field_E48;
|
||||
int32_t field_E4C;
|
||||
int32_t field_E50;
|
||||
int32_t field_E54;
|
||||
int32_t field_E58;
|
||||
int32_t field_E5C;
|
||||
int32_t field_E60;
|
||||
int32_t field_E64;
|
||||
int32_t field_E68;
|
||||
int32_t field_E6C;
|
||||
int32_t field_E70;
|
||||
int32_t field_E74;
|
||||
int32_t field_E78;
|
||||
int32_t field_E7C;
|
||||
int32_t field_E80;
|
||||
int32_t field_E84;
|
||||
int32_t field_E88;
|
||||
int32_t field_E8C;
|
||||
int32_t field_E90;
|
||||
int32_t field_E94;
|
||||
int32_t field_E98;
|
||||
int32_t field_E9C;
|
||||
int32_t field_EA0;
|
||||
int32_t field_EA4;
|
||||
int32_t field_EA8;
|
||||
int32_t field_EAC;
|
||||
int32_t field_EB0;
|
||||
int32_t field_EB4;
|
||||
int32_t field_EB8;
|
||||
int32_t field_EBC;
|
||||
int32_t field_EC0;
|
||||
int32_t field_EC4;
|
||||
int32_t field_EC8;
|
||||
int32_t field_ECC;
|
||||
int32_t field_ED0;
|
||||
int32_t field_ED4;
|
||||
int32_t field_ED8;
|
||||
int32_t field_EDC;
|
||||
int32_t field_EE0;
|
||||
int32_t field_EE4;
|
||||
int32_t field_EE8;
|
||||
int32_t field_EEC;
|
||||
int32_t field_EF0;
|
||||
int32_t field_EF4;
|
||||
int32_t field_EF8;
|
||||
int32_t field_EFC;
|
||||
};
|
||||
@@ -0,0 +1,342 @@
|
||||
#include "PlayerDataManager.h"
|
||||
#include <string>
|
||||
#include "../framework.h"
|
||||
#include "../Constants.h"
|
||||
#include "../Input/Keyboard/Keyboard.h"
|
||||
#include "../FileSystem/ConfigFile.h"
|
||||
#include "../Constants.h"
|
||||
|
||||
const std::string PLAYER_DATA_FILE_NAME = "playerdata.ini";
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
PlayerDataManager::PlayerDataManager()
|
||||
{
|
||||
}
|
||||
|
||||
PlayerDataManager::~PlayerDataManager()
|
||||
{
|
||||
if (customPlayerData != nullptr)
|
||||
delete customPlayerData;
|
||||
}
|
||||
|
||||
const char* PlayerDataManager::GetDisplayName()
|
||||
{
|
||||
return "player_data_manager";
|
||||
}
|
||||
|
||||
void PlayerDataManager::Initialize(ComponentsManager*)
|
||||
{
|
||||
playerData = (PlayerData*)PLAYER_DATA_ADDRESS;
|
||||
|
||||
ApplyPatch();
|
||||
LoadConfig();
|
||||
ApplyCustomData();
|
||||
}
|
||||
|
||||
void PlayerDataManager::Update()
|
||||
{
|
||||
ApplyCustomData();
|
||||
|
||||
if (false && Input::Keyboard::GetInstance()->IsTapped(VK_F12))
|
||||
{
|
||||
printf("[TLAC] PlayerDataManager::Update(): Loading config...\n");
|
||||
LoadConfig();
|
||||
}
|
||||
if (moduleCardWorkaround) {
|
||||
int* pvId = (int*)0x00000001418054C4;
|
||||
int* modState = (int*)0x00000001411A9790;
|
||||
|
||||
if (!customPlayerData->UseCard)
|
||||
{
|
||||
if (*(char*)0x000000014CC5E270 == 32)
|
||||
{
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405BC8E6 + 0) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
|
||||
pvModuleLoaded = false;
|
||||
}
|
||||
else {
|
||||
if (!pvModuleLoaded)
|
||||
{
|
||||
pvModuleLoaded = true;
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405BC8E6 + 0) = 0x01;
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
|
||||
}
|
||||
}
|
||||
|
||||
if ((initPvId == false) || ((lastModState == 0) && (*modState == 1)))
|
||||
{
|
||||
if ((lastModState == 0) && (*modState == 1))
|
||||
{
|
||||
*(int*)0x00000001411A8A10 = *(int*)0x00000001411A8A28;
|
||||
*(int*)(0x00000001411A8A10 + 4) = *(int*)(0x00000001411A8A28 + 4);
|
||||
*(int*)(0x00000001411A8A10 + 8) = *(int*)(0x00000001411A8A28 + 8);
|
||||
*(int*)(0x00000001411A8A10 + 12) = *(int*)(0x00000001411A8A28 + 12);
|
||||
*(int*)(0x00000001411A8A10 + 16) = *(int*)(0x00000001411A8A28 + 16);
|
||||
*(int*)(0x00000001411A8A10 + 18) = *(int*)(0x00000001411A8A28 + 18);
|
||||
}
|
||||
|
||||
initPvId = true;
|
||||
lastModState = *modState;
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001405CBBA3, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405CBBA3 + 0) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 1) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 2) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 3) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 4) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 5) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 6) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 7) = 0x90;
|
||||
VirtualProtect((BYTE*)0x00000001405CBBA3, 8, oldProtect, &bck);
|
||||
}
|
||||
|
||||
if (((*modState == 0) && (*pvId != lastPvId)) || ((lastModState == 1) && (*modState == 0)))
|
||||
{
|
||||
if ((lastModState == 1) && (*modState == 0))
|
||||
{
|
||||
*(int*)0x00000001411A8A28 = *(int*)0x00000001411A8A10;
|
||||
*(int*)(0x00000001411A8A28 + 4) = *(int*)(0x00000001411A8A10 + 4);
|
||||
*(int*)(0x00000001411A8A28 + 8) = *(int*)(0x00000001411A8A10 + 8);
|
||||
*(int*)(0x00000001411A8A28 + 12) = *(int*)(0x00000001411A8A10 + 12);
|
||||
*(int*)(0x00000001411A8A28 + 16) = *(int*)(0x00000001411A8A10 + 16);
|
||||
*(int*)(0x00000001411A8A28 + 18) = *(int*)(0x00000001411A8A10 + 18);
|
||||
}
|
||||
|
||||
initPvId = false;
|
||||
lastPvId = *pvId;
|
||||
lastModState = *modState;
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001405CBBA3, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405CBBA3 + 0) = 0x42;
|
||||
*((BYTE*)0x00000001405CBBA3 + 1) = 0x89;
|
||||
*((BYTE*)0x00000001405CBBA3 + 2) = 0x84;
|
||||
*((BYTE*)0x00000001405CBBA3 + 3) = 0xb6;
|
||||
*((BYTE*)0x00000001405CBBA3 + 4) = 0xc0;
|
||||
*((BYTE*)0x00000001405CBBA3 + 5) = 0x01;
|
||||
*((BYTE*)0x00000001405CBBA3 + 6) = 0x00;
|
||||
*((BYTE*)0x00000001405CBBA3 + 7) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001405CBBA3, 8, oldProtect, &bck);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (*(char*)0x000000014CC5E270 == 32)
|
||||
{
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405BC8E6 + 0) = 0x01;
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
|
||||
|
||||
VirtualProtect((BYTE*)0x00000001405CBBA3, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405CBBA3 + 0) = 0x42;
|
||||
*((BYTE*)0x00000001405CBBA3 + 1) = 0x89;
|
||||
*((BYTE*)0x00000001405CBBA3 + 2) = 0x84;
|
||||
*((BYTE*)0x00000001405CBBA3 + 3) = 0xb6;
|
||||
*((BYTE*)0x00000001405CBBA3 + 4) = 0xc0;
|
||||
*((BYTE*)0x00000001405CBBA3 + 5) = 0x01;
|
||||
*((BYTE*)0x00000001405CBBA3 + 6) = 0x00;
|
||||
*((BYTE*)0x00000001405CBBA3 + 7) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001405CBBA3, 8, oldProtect, &bck);
|
||||
|
||||
VirtualProtect((BYTE*)0x00000001405BCBE3, 2, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405BCBE3 + 0) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001405BCBE3, 2, oldProtect, &bck);
|
||||
|
||||
pvModuleLoaded = false;
|
||||
}
|
||||
else {
|
||||
if (!pvModuleLoaded)
|
||||
{
|
||||
pvModuleLoaded = true;
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405BC8E6 + 0) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
|
||||
|
||||
VirtualProtect((BYTE*)0x00000001405CBBA3, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405CBBA3 + 0) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 1) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 2) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 3) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 4) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 5) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 6) = 0x90;
|
||||
*((BYTE*)0x00000001405CBBA3 + 7) = 0x90;
|
||||
VirtualProtect((BYTE*)0x00000001405CBBA3, 8, oldProtect, &bck);
|
||||
|
||||
VirtualProtect((BYTE*)0x00000001405BCBE3, 2, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405BCBE3 + 0) = 0x01;
|
||||
VirtualProtect((BYTE*)0x00000001405BCBE3, 2, oldProtect, &bck);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerDataManager::ApplyPatch()
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)SET_DEFAULT_PLAYER_DATA_ADDRESS, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
{
|
||||
// prevent the PlayerData from being reset
|
||||
*(uint8_t*)(SET_DEFAULT_PLAYER_DATA_ADDRESS) = RET_OPCODE;
|
||||
}
|
||||
VirtualProtect((void*)SET_DEFAULT_PLAYER_DATA_ADDRESS, sizeof(uint8_t), oldProtect, &oldProtect);
|
||||
|
||||
// allow player to select the module and extra item
|
||||
VirtualProtect((void*)MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS, sizeof(byte) * 2, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
{
|
||||
*(byte*)(MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS) = 0xB0; // xor al,al -> ld al,1
|
||||
*(byte*)(MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS + 0x1) = 0x01;
|
||||
}
|
||||
VirtualProtect((void*)MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS, sizeof(byte) * 2, oldProtect, &oldProtect);
|
||||
|
||||
// fix annoying behavior of closing after changing module or item (don't yet know the reason, maybe NW/Card checks)
|
||||
{
|
||||
VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_MODULE, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
{
|
||||
*(uint8_t*)(MODSELECTOR_CLOSE_AFTER_MODULE) = JNE_OPCODE;
|
||||
}
|
||||
VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_MODULE, sizeof(uint8_t), oldProtect, &oldProtect);
|
||||
VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_CUSTOMIZE, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
{
|
||||
*(uint8_t*)(MODSELECTOR_CLOSE_AFTER_CUSTOMIZE) = JNE_OPCODE;
|
||||
}
|
||||
VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_CUSTOMIZE, sizeof(uint8_t), oldProtect, &oldProtect);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerDataManager::LoadConfig()
|
||||
{
|
||||
if (playerData == nullptr)
|
||||
return;
|
||||
|
||||
FileSystem::ConfigFile config(framework::GetModuleDirectory(), PLAYER_DATA_FILE_NAME);
|
||||
|
||||
if (!config.OpenRead())
|
||||
return;
|
||||
|
||||
if (customPlayerData != nullptr)
|
||||
delete customPlayerData;
|
||||
|
||||
customPlayerData = new CustomPlayerData();
|
||||
config.TryGetValue("player_name", &customPlayerData->PlayerName);
|
||||
config.TryGetValue("level_name", &customPlayerData->LevelName);
|
||||
|
||||
customPlayerData->LevelPlateId = config.GetIntegerValue("level_plate_id");
|
||||
customPlayerData->SkinEquip = config.GetIntegerValue("skin_equip");
|
||||
customPlayerData->BtnSeEquip = config.GetIntegerValue("btn_se_equip");
|
||||
customPlayerData->SlideSeEquip = config.GetIntegerValue("slide_se_equip");
|
||||
customPlayerData->ChainslideSeEquip = config.GetIntegerValue("chainslide_se_equip");
|
||||
customPlayerData->ShowExcellentClearBorder = config.GetBooleanValue("border_excellent");
|
||||
customPlayerData->ShowGreatClearBorder = config.GetBooleanValue("border_great");
|
||||
customPlayerData->UseCard = config.GetBooleanValue("use_card");
|
||||
customPlayerData->GameModifierOptions = config.GetBooleanValue("gamemode_options");
|
||||
moduleCardWorkaround = config.GetBooleanValue("module_card_workaround");
|
||||
|
||||
if (moduleCardWorkaround) {
|
||||
if (!customPlayerData->UseCard)
|
||||
{
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x000000014010523F, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x0000000140105239 + 0) = 0x30;
|
||||
*((BYTE*)0x0000000140105239 + 1) = 0xC0;
|
||||
*((BYTE*)0x0000000140105239 + 2) = 0x90;
|
||||
VirtualProtect((BYTE*)0x0000000140105239, 3, oldProtect, &bck);
|
||||
|
||||
VirtualProtect((BYTE*)0x00000001405BCC48, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405BCC48 + 0) = 0x90;
|
||||
*((BYTE*)0x00000001405BCC48 + 1) = 0x90;
|
||||
*((BYTE*)0x00000001405BCC48 + 2) = 0x90;
|
||||
*((BYTE*)0x00000001405BCC48 + 3) = 0x90;
|
||||
*((BYTE*)0x00000001405BCC48 + 4) = 0x90;
|
||||
*((BYTE*)0x00000001405BCC48 + 5) = 0x90;
|
||||
VirtualProtect((BYTE*)0x00000001405BCC48, 6, oldProtect, &bck);
|
||||
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405BC8E6 + 0) = 0x01;
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
|
||||
|
||||
}
|
||||
else {
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405BC8E6 + 0) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
|
||||
|
||||
VirtualProtect((BYTE*)0x00000001405BCC48, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405BCC48 + 0) = 0xC7;
|
||||
*((BYTE*)0x00000001405BCC48 + 1) = 0x03;
|
||||
*((BYTE*)0x00000001405BCC48 + 2) = 0x00;
|
||||
*((BYTE*)0x00000001405BCC48 + 3) = 0x00;
|
||||
*((BYTE*)0x00000001405BCC48 + 4) = 0x00;
|
||||
*((BYTE*)0x00000001405BCC48 + 5) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001405BCC48, 6, oldProtect, &bck);
|
||||
|
||||
VirtualProtect((BYTE*)0x000000014010523F, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x0000000140105239 + 0) = 0x0F;
|
||||
*((BYTE*)0x0000000140105239 + 1) = 0x94;
|
||||
*((BYTE*)0x0000000140105239 + 2) = 0xC1;
|
||||
VirtualProtect((BYTE*)0x0000000140105239, 3, oldProtect, &bck);
|
||||
|
||||
//just incase the player is reloading
|
||||
VirtualProtect((BYTE*)0x00000001405CBBA3, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((BYTE*)0x00000001405CBBA3 + 0) = 0x42;
|
||||
*((BYTE*)0x00000001405CBBA3 + 1) = 0x89;
|
||||
*((BYTE*)0x00000001405CBBA3 + 2) = 0x84;
|
||||
*((BYTE*)0x00000001405CBBA3 + 3) = 0xb6;
|
||||
*((BYTE*)0x00000001405CBBA3 + 4) = 0xc0;
|
||||
*((BYTE*)0x00000001405CBBA3 + 5) = 0x01;
|
||||
*((BYTE*)0x00000001405CBBA3 + 6) = 0x00;
|
||||
*((BYTE*)0x00000001405CBBA3 + 7) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001405CBBA3, 8, oldProtect, &bck);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerDataManager::ApplyCustomData()
|
||||
{
|
||||
// don't want to overwrite the default values
|
||||
auto setIfNotEqual = [](int *target, int value, int comparison)
|
||||
{
|
||||
if (value != comparison)
|
||||
*target = value;
|
||||
};
|
||||
|
||||
setIfNotEqual(&playerData->level_plate_id, customPlayerData->LevelPlateId, 0);
|
||||
setIfNotEqual(&playerData->skin_equip, customPlayerData->SkinEquip, 0);
|
||||
setIfNotEqual(&playerData->btn_se_equip, customPlayerData->BtnSeEquip, -1);
|
||||
setIfNotEqual(&playerData->slide_se_equip, customPlayerData->SlideSeEquip, -1);
|
||||
setIfNotEqual(&playerData->chainslide_se_equip, customPlayerData->ChainslideSeEquip, -1);
|
||||
|
||||
// Display clear borders on the progress bar
|
||||
*(byte*)(PLAYER_DATA_ADDRESS + 0xD94) = (customPlayerData->ShowExcellentClearBorder << 1) | (customPlayerData->ShowGreatClearBorder);
|
||||
|
||||
if (customPlayerData->UseCard)
|
||||
playerData->use_card = 1; // required to allow for module selection
|
||||
|
||||
if (customPlayerData->GameModifierOptions)
|
||||
playerData->game_opts = 1; // hi-speed, etc..
|
||||
|
||||
memset((void*)MODULE_TABLE_START, 0xFF, 128);
|
||||
memset((void*)ITEM_TABLE_START, 0xFF, 128);
|
||||
|
||||
if (customPlayerData->PlayerName != nullptr)
|
||||
{
|
||||
playerData->field_DC = 0x10;
|
||||
playerData->player_name = (char*)customPlayerData->PlayerName->c_str();
|
||||
}
|
||||
|
||||
|
||||
if (customPlayerData->LevelName != nullptr)
|
||||
{
|
||||
playerData->level_name = (char*)customPlayerData->LevelName->c_str();
|
||||
playerData->field_110 = 0xFF;
|
||||
playerData->field_118 = 0x1F;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "PlayerData.h"
|
||||
#include "CustomPlayerData.h"
|
||||
#include <string>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class PlayerDataManager : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
PlayerDataManager();
|
||||
~PlayerDataManager();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
|
||||
private:
|
||||
PlayerData* playerData;
|
||||
CustomPlayerData* customPlayerData;
|
||||
int lastPvId = -1;
|
||||
bool initPvId = true;
|
||||
bool pvModuleLoaded = true;
|
||||
bool moduleCardWorkaround = true;
|
||||
int lastModState = 0;
|
||||
void ApplyPatch();
|
||||
void LoadConfig();
|
||||
void ApplyCustomData();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
#include "ScaleComponent.h"
|
||||
#include <iostream>
|
||||
#include <Windows.h>
|
||||
#include "../Constants.h"
|
||||
#include <stdio.h>
|
||||
#include "../framework.h"
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <tchar.h>
|
||||
#include <GL/freeglut.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
|
||||
ScaleComponent::ScaleComponent()
|
||||
{
|
||||
}
|
||||
|
||||
ScaleComponent::~ScaleComponent()
|
||||
{
|
||||
}
|
||||
|
||||
const char* ScaleComponent::GetDisplayName()
|
||||
{
|
||||
return "scale_component";
|
||||
}
|
||||
|
||||
void ScaleComponent::Initialize(ComponentsManager*)
|
||||
{
|
||||
{
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001404ACD24, 7, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((byte*)0x00000001404ACD24 + 0) = 0x44;
|
||||
*((byte*)0x00000001404ACD24 + 1) = 0x8B;
|
||||
*((byte*)0x00000001404ACD24 + 2) = 0x0D;
|
||||
*((byte*)0x00000001404ACD24 + 3) = 0xD1;
|
||||
*((byte*)0x00000001404ACD24 + 4) = 0x08;
|
||||
*((byte*)0x00000001404ACD24 + 5) = 0xD0;
|
||||
*((byte*)0x00000001404ACD24 + 6) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001404ACD24, 7, oldProtect, &bck);
|
||||
}
|
||||
{
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001404ACD2B, 7, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((byte*)0x00000001404ACD2B + 0) = 0x44;
|
||||
*((byte*)0x00000001404ACD2B + 1) = 0x8B;
|
||||
*((byte*)0x00000001404ACD2B + 2) = 0x05;
|
||||
*((byte*)0x00000001404ACD2B + 3) = 0xC6;
|
||||
*((byte*)0x00000001404ACD2B + 4) = 0x08;
|
||||
*((byte*)0x00000001404ACD2B + 5) = 0xD0;
|
||||
*((byte*)0x00000001404ACD2B + 6) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001404ACD2B, 7, oldProtect, &bck);
|
||||
}
|
||||
{
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001405030A0, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((byte*)0x00000001405030A0 + 0) = 0x90;
|
||||
*((byte*)0x00000001405030A0 + 1) = 0x90;
|
||||
*((byte*)0x00000001405030A0 + 2) = 0x90;
|
||||
*((byte*)0x00000001405030A0 + 3) = 0x90;
|
||||
*((byte*)0x00000001405030A0 + 4) = 0x90;
|
||||
*((byte*)0x00000001405030A0 + 5) = 0x90;
|
||||
VirtualProtect((BYTE*)0x00000001404ACD2B, 6, oldProtect, &bck);
|
||||
}
|
||||
}
|
||||
|
||||
void ScaleComponent::Update()
|
||||
{
|
||||
uiAspectRatio = (float*)UI_ASPECT_RATIO;
|
||||
uiWidth = (float*)UI_WIDTH_ADDRESS;
|
||||
uiHeight = (float*)UI_HEIGHT_ADDRESS;
|
||||
fb1Height = (int*)FB1_HEIGHT_ADDRESS;
|
||||
fb1Width = (int*)FB1_WIDTH_ADDRESS;
|
||||
//fb2Height = (int*)FB2_HEIGHT_ADDRESS;
|
||||
//fb2Width = (int*)FB2_WIDTH_ADDRESS;
|
||||
fbAspectRatio = (double*)FB_ASPECT_RATIO;
|
||||
RECT hWindow;
|
||||
GetClientRect(TLAC::framework::DivaWindowHandle, &hWindow);
|
||||
*uiAspectRatio = (float)(hWindow.right - hWindow.left) / (float)(hWindow.bottom - hWindow.top);
|
||||
*fbAspectRatio = (double)(hWindow.right - hWindow.left) / (double)(hWindow.bottom - hWindow.top);
|
||||
*uiWidth = hWindow.right - hWindow.left;
|
||||
*uiHeight = hWindow.bottom - hWindow.top;
|
||||
*fb1Width = hWindow.right - hWindow.left;
|
||||
*fb1Height = hWindow.bottom - hWindow.top;
|
||||
//*fb2Width = hWindow.right - hWindow.left;
|
||||
//*fb2Height = hWindow.bottom - hWindow.top;
|
||||
|
||||
*((int*)0x00000001411AD608) = 0;
|
||||
|
||||
*((int*)0x0000000140EDA8E4) = *(int*)0x0000000140EDA8BC;
|
||||
*((int*)0x0000000140EDA8E8) = *(int*)0x0000000140EDA8C0;
|
||||
|
||||
*(float*)0x00000001411A1900 = 0;
|
||||
*(float*)0x00000001411A1904 = (float)*(int*)0x0000000140EDA8BC;
|
||||
*(float*)0x00000001411A1908 = (float)*(int*)0x0000000140EDA8C0;
|
||||
//*((int*)0x00000001411AD5F8) = hWindow.right - hWindow.left;
|
||||
//*((int*)0x00000001411AD5FC) = hWindow.bottom - hWindow.top;
|
||||
|
||||
//*((int*)0x00000001411ABB48) = hWindow.right - hWindow.left;
|
||||
//*((int*)0x00000001411ABB4C) = hWindow.bottom - hWindow.top;
|
||||
|
||||
//*((int*)0x00000001411ABB5C) = (int)(*((int*)0x00000001411ABB54) * ((float)8 / (float)9)); //wtf??
|
||||
}
|
||||
|
||||
void ScaleComponent::UpdateInput()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "GameState.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class ScaleComponent : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
ScaleComponent();
|
||||
~ScaleComponent();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
const int updatesPerFrame = 39;
|
||||
|
||||
float* uiAspectRatio;
|
||||
float* uiWidth;
|
||||
float* uiHeight;
|
||||
|
||||
int* fb1Width;
|
||||
int* fb1Height;
|
||||
int* fb2Width;
|
||||
int* fb2Height;
|
||||
|
||||
double* fbAspectRatio;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "StageManager.h"
|
||||
#include "../Constants.h"
|
||||
#include <windows.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
StageManager::StageManager()
|
||||
{
|
||||
}
|
||||
|
||||
StageManager::~StageManager()
|
||||
{
|
||||
}
|
||||
|
||||
const char* StageManager::GetDisplayName()
|
||||
{
|
||||
return "stage_manager";
|
||||
}
|
||||
|
||||
void StageManager::Initialize(ComponentsManager*)
|
||||
{
|
||||
// add the offset between moving 2 into ebx and the start of the function
|
||||
int32_t* playCount = (int32_t*)(((uint8_t*)PLAYS_PER_SESSION_GETTER_ADDRESS) + 0x7);
|
||||
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(playCount, sizeof(int32_t), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
// set ’Ê�탂�[ƒh per session play count
|
||||
*playCount = GetPlayCount();
|
||||
}
|
||||
|
||||
void StageManager::Update()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t StageManager::GetPlayCount()
|
||||
{
|
||||
return INT32_MAX;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class StageManager : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
StageManager();
|
||||
~StageManager();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
|
||||
private:
|
||||
int32_t GetPlayCount();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "SysTimer.h"
|
||||
#include "../Constants.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
SysTimer::SysTimer()
|
||||
{
|
||||
}
|
||||
|
||||
SysTimer::~SysTimer()
|
||||
{
|
||||
}
|
||||
|
||||
const char* SysTimer::GetDisplayName()
|
||||
{
|
||||
return "sys_timer";
|
||||
}
|
||||
|
||||
void SysTimer::Initialize(ComponentsManager*)
|
||||
{
|
||||
selPvTime = GetSysTimePtr((void*)SEL_PV_TIME_ADDRESS);
|
||||
}
|
||||
|
||||
void SysTimer::Update()
|
||||
{
|
||||
// account for the decrement that occures during this frame
|
||||
*selPvTime = SEL_PV_FREEZE_TIME * SYS_TIME_FACTOR + 1;
|
||||
}
|
||||
|
||||
int* SysTimer::GetSysTimePtr(void *address)
|
||||
{
|
||||
return (int*)address;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class SysTimer : public EmulatorComponent
|
||||
{
|
||||
const int SYS_TIME_FACTOR = 60;
|
||||
const int SEL_PV_FREEZE_TIME = 39;
|
||||
|
||||
public:
|
||||
SysTimer();
|
||||
~SysTimer();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
|
||||
private:
|
||||
int* selPvTime;
|
||||
int* GetSysTimePtr(void *address);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user