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);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
constexpr uint8_t NOP_OPCODE = 0x90;
|
||||
constexpr uint8_t RET_OPCODE = 0xC3;
|
||||
constexpr uint8_t JMP_OPCODE = 0xE9;
|
||||
constexpr uint8_t JNE_OPCODE = 0x85;
|
||||
|
||||
//constexpr uint64_t ENGINE_UPDATE_HOOK_TARGET_ADDRESS = 0x000000014018CC40;
|
||||
constexpr uint64_t ENGINE_UPDATE_INPUT_ADDRESS = 0x000000014018CBB0;
|
||||
|
||||
constexpr uint64_t CURRENT_GAME_STATE_ADDRESS = 0x0000000140EDA810;
|
||||
constexpr uint64_t RESOLUTION_WIDTH_ADDRESS = 0x0000000140EDA8BC;
|
||||
constexpr uint64_t RESOLUTION_HEIGHT_ADDRESS = 0x0000000140EDA8C0;
|
||||
|
||||
constexpr uint64_t SYSTEM_WARNING_ELAPSED_ADDRESS = (0x00000001411A1430 + 0x68);
|
||||
constexpr uint64_t DATA_INIT_STATE_ADDRESS = 0x0000000140EDA7A8;
|
||||
|
||||
constexpr uint64_t AET_FRAME_DURATION_ADDRESS = 0x00000001409A0A58;
|
||||
constexpr uint64_t PV_FRAME_RATE_ADDRESS = 0x0000000140EDA7CC;
|
||||
constexpr uint64_t FRAME_SPEED_ADDRESS = 0x0000000140EDA798;
|
||||
constexpr uint64_t FRAME_RATE_ADDRESS = 0x0000000140EDA6D0;
|
||||
|
||||
constexpr uint64_t DW_GUI_DISPLAY_INSTANCE_PTR_ADDRESS = 0x0000000141190108;
|
||||
constexpr uint64_t INPUT_STATE_PTR_ADDRESS = 0x0000000140EDA330;
|
||||
constexpr uint64_t SLIDER_CTRL_TASK_ADDRESS = 0x000000014CC5DE40;
|
||||
constexpr uint64_t TASK_TOUCH_ADDRESS = 0x000000014CC9EC30;
|
||||
constexpr uint64_t SEL_PV_TIME_ADDRESS = 0x000000014CC12498;
|
||||
constexpr uint64_t PLAYER_DATA_ADDRESS = 0x00000001411A8850;
|
||||
constexpr uint64_t SET_DEFAULT_PLAYER_DATA_ADDRESS = 0x00000001404A7370;
|
||||
constexpr uint64_t PLAYS_PER_SESSION_GETTER_ADDRESS = 0x000000014038AEE0;
|
||||
constexpr uint64_t PV_SEL_SLOTS_TO_SCROLL = 0x000000014CC12470;
|
||||
constexpr uint64_t PV_SEL_SLOTS_CONST = 0x000000014CC119C8;
|
||||
constexpr uint64_t MODULE_SEL_SLOTS_TO_SCROLL = 0x00000001418047EC;
|
||||
constexpr uint64_t MODULE_IS_RECOMMENDED = 0x00000001418047E0;
|
||||
|
||||
constexpr uint64_t CAMERA_ADDRESS = 0x0000000140FBC2C0;
|
||||
constexpr uint64_t CAMERA_POS_SETTER_ADDRESS = 0x00000001401F9460;
|
||||
constexpr uint64_t CAMERA_INTR_SETTER_ADDRESS = 0x00000001401F93F0;
|
||||
constexpr uint64_t CAMERA_ROT_SETTER_ADDRESS = 0x00000001401F9480;
|
||||
constexpr uint64_t CAMERA_PERS_SETTER_ADDRESS = 0x00000001401F9430;
|
||||
|
||||
constexpr uint64_t UPDATE_TASKS_ADDRESS = 0x000000014019B980;
|
||||
constexpr uint64_t GLUT_SET_CURSOR_ADDRESS = 0x00000001408B68E6;
|
||||
constexpr uint64_t CHANGE_MODE_ADDRESS = 0x00000001401953D0;
|
||||
constexpr uint64_t CHANGE_SUB_MODE_ADDRESS = 0x0000000140195260;
|
||||
|
||||
constexpr uint64_t TGT_TYPE_BASE_ADDRESS = 0x0000000140D0B69C;
|
||||
constexpr uint64_t TGT_REMAINING_DURATION_BASE_ADDRESS = 0x0000000140D0B6A0;
|
||||
constexpr uint64_t TGT_HIT_STATE_BASE_ADDRESS = 0x0000000140D0BAE4;
|
||||
constexpr uint64_t TGT_ON_SCREEN_ADDRESS = 0x0000000140D0B678;
|
||||
|
||||
constexpr uint64_t HOLD_STATE_ADDRESS = 0x0000000140D1E20C;
|
||||
constexpr uint64_t MAX_HOLD_STATE_ADDRESS = 0x0000000140D1E234;
|
||||
|
||||
constexpr uint64_t CHECK_SOMETHING_SET_MODULE_ADDRESS = 0x0000000140581C78;
|
||||
constexpr uint64_t MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS = 0x00000001405869AD;
|
||||
constexpr uint64_t MODSELECTOR_CLOSE_AFTER_MODULE = 0x0000000140583B45;
|
||||
constexpr uint64_t MODSELECTOR_CLOSE_AFTER_CUSTOMIZE = 0x0000000140583C8C;
|
||||
constexpr uint64_t MODULE_TABLE_START = PLAYER_DATA_ADDRESS + 0x140;
|
||||
constexpr uint64_t MODULE_TABLE_END = MODULE_TABLE_START + 128;
|
||||
constexpr uint64_t ITEM_TABLE_START = PLAYER_DATA_ADDRESS + 0x2B8;
|
||||
constexpr uint64_t ITEM_TABLE_END = ITEM_TABLE_START + 128;
|
||||
|
||||
constexpr uint64_t FB_WIDTH_ADDRESS = 0x00000001411ABCA8;
|
||||
constexpr uint64_t FB_HEIGHT_ADDRESS = 0x00000001411ABCAC;
|
||||
constexpr uint64_t FB1_WIDTH_ADDRESS = 0x00000001411AD5F8;
|
||||
constexpr uint64_t FB1_HEIGHT_ADDRESS = 0x00000001411AD5FC;
|
||||
constexpr uint64_t FB2_WIDTH_ADDRESS = 0x0000000140EDA8E4;
|
||||
constexpr uint64_t FB2_HEIGHT_ADDRESS = 0x0000000140EDA8E8;
|
||||
|
||||
constexpr uint64_t FB_RESOLUTION_WIDTH_ADDRESS = 0x00000001411ABB50;
|
||||
constexpr uint64_t FB_RESOLUTION_HEIGHT_ADDRESS = 0x00000001411ABB54;
|
||||
|
||||
constexpr uint64_t UI_WIDTH_ADDRESS = 0x000000014CC621E4;
|
||||
constexpr uint64_t UI_HEIGHT_ADDRESS = 0x000000014CC621E8;
|
||||
|
||||
constexpr uint64_t FB_ASPECT_RATIO = 0x0000000140FBC2E8;
|
||||
constexpr uint64_t UI_ASPECT_RATIO = 0x000000014CC621D0;
|
||||
|
||||
#define XINPUT_A 0x00
|
||||
#define XINPUT_B 0x01
|
||||
#define XINPUT_X 0x02
|
||||
#define XINPUT_Y 0x03
|
||||
#define XINPUT_UP 0x10
|
||||
#define XINPUT_DOWN 0x11
|
||||
#define XINPUT_LEFT 0x12
|
||||
#define XINPUT_RIGHT 0x13
|
||||
#define XINPUT_LS 0x20
|
||||
#define XINPUT_RS 0x21
|
||||
#define XINPUT_LT 0x22
|
||||
#define XINPUT_RT 0x23
|
||||
#define XINPUT_LSB 0x24
|
||||
#define XINPUT_RSB 0x25
|
||||
#define XINPUT_START 0x30
|
||||
#define XINPUT_BACK 0x31
|
||||
#define XINPUT_LUP 0x40
|
||||
#define XINPUT_LDOWN 0x41
|
||||
#define XINPUT_LLEFT 0x42
|
||||
#define XINPUT_LRIGHT 0x43
|
||||
#define XINPUT_RUP 0x50
|
||||
#define XINPUT_RDOWN 0x51
|
||||
#define XINPUT_RLEFT 0x52
|
||||
#define XINPUT_RRIGHT 0x53
|
||||
@@ -0,0 +1,72 @@
|
||||
#include <stdio.h>
|
||||
#include "ConfigFile.h"
|
||||
#include "../Utilities/Operations.h"
|
||||
|
||||
namespace TLAC::FileSystem
|
||||
{
|
||||
ConfigFile::ConfigFile(const std::string &path) : TextFile(path)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigFile::ConfigFile(const std::string &directory, const std::string &file) : TextFile(directory, file)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool ConfigFile::TryGetValue(const std::string &key, std::string **value)
|
||||
{
|
||||
auto pair = ConfigMap.find(key);
|
||||
bool found = pair != ConfigMap.end();
|
||||
|
||||
*value = found ? new std::string(pair->second) : nullptr;
|
||||
return found;
|
||||
}
|
||||
|
||||
int ConfigFile::GetIntegerValue(const std::string& key)
|
||||
{
|
||||
auto pair = ConfigMap.find(key);
|
||||
bool found = pair != ConfigMap.end();
|
||||
|
||||
return found ? atoi(pair->second.c_str()) : 0;
|
||||
}
|
||||
|
||||
bool ConfigFile::GetBooleanValue(const std::string& key)
|
||||
{
|
||||
auto pair = ConfigMap.find(key);
|
||||
bool found = pair != ConfigMap.end();
|
||||
|
||||
return found ? pair->second == "true" : false;
|
||||
}
|
||||
|
||||
float ConfigFile::GetFloatValue(const std::string & key)
|
||||
{
|
||||
auto pair = ConfigMap.find(key);
|
||||
bool found = pair != ConfigMap.end();
|
||||
|
||||
return found ? (float)atof(pair->second.c_str()) : 0.0f;
|
||||
}
|
||||
|
||||
void ConfigFile::Parse(std::ifstream &fileStream)
|
||||
{
|
||||
std::string line;
|
||||
|
||||
while (std::getline(fileStream, line))
|
||||
{
|
||||
if (IsComment(line))
|
||||
continue;
|
||||
|
||||
auto splitline = Utilities::Split(line, "=");
|
||||
|
||||
for (auto &line : splitline)
|
||||
Utilities::Trim(line);
|
||||
|
||||
ConfigMap.insert(std::make_pair(splitline[0], splitline[1]));
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigFile::IsComment(const std::string &line)
|
||||
{
|
||||
return line.size() <= 0 || line[0] == '#' || line[0] == '[' || line._Starts_with("//");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "TextFile.h"
|
||||
#include <unordered_map>
|
||||
|
||||
namespace TLAC::FileSystem
|
||||
{
|
||||
class ConfigFile : public TextFile
|
||||
{
|
||||
public:
|
||||
ConfigFile(const std::string &path);
|
||||
ConfigFile(const std::string &directory, const std::string &file);
|
||||
|
||||
std::unordered_map<std::string, std::string> ConfigMap;
|
||||
|
||||
bool TryGetValue(const std::string &key, std::string **value);
|
||||
int GetIntegerValue(const std::string& key);
|
||||
bool GetBooleanValue(const std::string& key);
|
||||
float GetFloatValue(const std::string& key);
|
||||
|
||||
protected:
|
||||
virtual void Parse(std::ifstream &fileStream) override;
|
||||
|
||||
private:
|
||||
bool IsComment(const std::string &line);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "TextFile.h"
|
||||
#include <filesystem>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace TLAC::FileSystem
|
||||
{
|
||||
TextFile::TextFile(const std::string &path)
|
||||
{
|
||||
FileName = path;
|
||||
}
|
||||
|
||||
TextFile::TextFile(const std::string &directory, const std::string &file)
|
||||
{
|
||||
auto fullPath = directory + "/" + file;
|
||||
FileName = fullPath;
|
||||
}
|
||||
|
||||
TextFile::~TextFile()
|
||||
{
|
||||
}
|
||||
|
||||
bool TextFile::OpenRead()
|
||||
{
|
||||
fs::path configPath = fs::u8path(FileName);
|
||||
|
||||
if (!fs::exists(configPath))
|
||||
return false;
|
||||
|
||||
std::ifstream fileStream(configPath.wstring().c_str());
|
||||
|
||||
if (!fileStream.is_open())
|
||||
return false;
|
||||
|
||||
Parse(fileStream);
|
||||
|
||||
fileStream.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
namespace TLAC::FileSystem
|
||||
{
|
||||
class TextFile
|
||||
{
|
||||
public:
|
||||
std::string FileName;
|
||||
|
||||
TextFile(const std::string &path);
|
||||
TextFile(const std::string &directory, const std::string &file);
|
||||
~TextFile();
|
||||
|
||||
bool OpenRead();
|
||||
|
||||
protected:
|
||||
virtual void Parse(std::ifstream &fileStream) = 0;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "Binding.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Binding::Binding()
|
||||
{
|
||||
}
|
||||
|
||||
Binding::~Binding()
|
||||
{
|
||||
for (auto& binding : InputBindings)
|
||||
delete binding;
|
||||
}
|
||||
|
||||
void Binding::AddBinding(IInputBinding* inputBinding)
|
||||
{
|
||||
InputBindings.push_back(inputBinding);
|
||||
}
|
||||
|
||||
bool Binding::AnyDown()
|
||||
{
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsDown())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Binding::AnyTapped()
|
||||
{
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsTapped())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Binding::AnyReleased()
|
||||
{
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsReleased())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int Binding::GetDownCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsDown())
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int Binding::GetTappedCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsTapped())
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int Binding::GetReleasedCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsReleased())
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "IInputBinding.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class Binding
|
||||
{
|
||||
public:
|
||||
std::vector<IInputBinding*> InputBindings;
|
||||
|
||||
Binding();
|
||||
~Binding();
|
||||
|
||||
void AddBinding(IInputBinding* inputBinding);
|
||||
|
||||
bool AnyDown();
|
||||
bool AnyTapped();
|
||||
bool AnyReleased();
|
||||
|
||||
int GetDownCount();
|
||||
int GetTappedCount();
|
||||
int GetReleasedCount();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "Ds4Binding.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
#define Ds4InstanceCheckDefault(checkFunc) (DualShock4::InstanceInitialized() ? DualShock4::GetInstance()->checkFunc : false)
|
||||
|
||||
Ds4Binding::Ds4Binding(Ds4Button button) : Button(button)
|
||||
{
|
||||
}
|
||||
|
||||
Ds4Binding::~Ds4Binding()
|
||||
{
|
||||
}
|
||||
|
||||
bool Ds4Binding::IsDown()
|
||||
{
|
||||
return Ds4InstanceCheckDefault(IsDown(Button));
|
||||
}
|
||||
|
||||
bool Ds4Binding::IsTapped()
|
||||
{
|
||||
return Ds4InstanceCheckDefault(IsTapped(Button));
|
||||
}
|
||||
|
||||
bool Ds4Binding::IsReleased()
|
||||
{
|
||||
return Ds4InstanceCheckDefault(IsReleased(Button));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "IInputBinding.h"
|
||||
#include "../DirectInput/Ds4/DualShock4.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class Ds4Binding : public IInputBinding
|
||||
{
|
||||
public:
|
||||
Ds4Button Button;
|
||||
|
||||
Ds4Binding(Ds4Button button);
|
||||
~Ds4Binding();
|
||||
|
||||
bool IsDown() override;
|
||||
bool IsTapped() override;
|
||||
bool IsReleased() override;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class IInputBinding
|
||||
{
|
||||
public:
|
||||
virtual bool IsDown() = 0;
|
||||
virtual bool IsTapped() = 0;
|
||||
virtual bool IsReleased() = 0;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "KeyboardBinding.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
KeyboardBinding::KeyboardBinding(BYTE keycode) : Keycode(keycode)
|
||||
{
|
||||
}
|
||||
|
||||
KeyboardBinding::~KeyboardBinding()
|
||||
{
|
||||
}
|
||||
|
||||
bool KeyboardBinding::IsDown()
|
||||
{
|
||||
return Keyboard::GetInstance()->IsDown(Keycode);
|
||||
}
|
||||
|
||||
bool KeyboardBinding::IsTapped()
|
||||
{
|
||||
return Keyboard::GetInstance()->IsTapped(Keycode);
|
||||
}
|
||||
|
||||
bool KeyboardBinding::IsReleased()
|
||||
{
|
||||
return Keyboard::GetInstance()->IsReleased(Keycode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "IInputBinding.h"
|
||||
#include "../Keyboard/Keyboard.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class KeyboardBinding : public IInputBinding
|
||||
{
|
||||
public:
|
||||
BYTE Keycode;
|
||||
|
||||
KeyboardBinding(BYTE keycode);
|
||||
~KeyboardBinding();
|
||||
|
||||
bool IsDown() override;
|
||||
bool IsTapped() override;
|
||||
bool IsReleased() override;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "MouseBinding.h"
|
||||
#include "../Keyboard/Keyboard.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
MouseBinding::MouseBinding(MouseAction action) : Action(action)
|
||||
{
|
||||
}
|
||||
|
||||
MouseBinding::~MouseBinding()
|
||||
{
|
||||
}
|
||||
|
||||
bool MouseBinding::IsDown()
|
||||
{
|
||||
switch (Action)
|
||||
{
|
||||
case MouseAction_LeftButton:
|
||||
return Keyboard::GetInstance()->IsDown(MK_LBUTTON);
|
||||
case MouseAction_RightButton:
|
||||
return Keyboard::GetInstance()->IsDown(MK_RBUTTON);
|
||||
case MouseAction_MiddleButton:
|
||||
return Keyboard::GetInstance()->IsDown(MK_MBUTTON);
|
||||
case MouseAction_ScrollUp:
|
||||
return Mouse::GetInstance()->GetIsScrolledUp();
|
||||
case MouseAction_ScrollDown:
|
||||
return Mouse::GetInstance()->GetIsScrolledDown();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MouseBinding::IsTapped()
|
||||
{
|
||||
switch (Action)
|
||||
{
|
||||
case MouseAction_LeftButton:
|
||||
return Keyboard::GetInstance()->IsTapped(MK_LBUTTON);
|
||||
case MouseAction_RightButton:
|
||||
return Keyboard::GetInstance()->IsTapped(MK_RBUTTON);
|
||||
case MouseAction_MiddleButton:
|
||||
return Keyboard::GetInstance()->IsTapped(MK_MBUTTON);
|
||||
case MouseAction_ScrollUp:
|
||||
return Mouse::GetInstance()->GetIsScrolledUp();
|
||||
case MouseAction_ScrollDown:
|
||||
return Mouse::GetInstance()->GetIsScrolledDown();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MouseBinding::IsReleased()
|
||||
{
|
||||
switch (Action)
|
||||
{
|
||||
case MouseAction_LeftButton:
|
||||
return Keyboard::GetInstance()->IsReleased(MK_LBUTTON);
|
||||
case MouseAction_RightButton:
|
||||
return Keyboard::GetInstance()->IsReleased(MK_RBUTTON);
|
||||
case MouseAction_MiddleButton:
|
||||
return Keyboard::GetInstance()->IsReleased(MK_MBUTTON);
|
||||
case MouseAction_ScrollUp:
|
||||
return Mouse::GetInstance()->GetWasScrolledUp();
|
||||
case MouseAction_ScrollDown:
|
||||
return Mouse::GetInstance()->GetWasScrolledDown();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include "IInputBinding.h"
|
||||
#include "../Mouse/Mouse.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
enum MouseAction
|
||||
{
|
||||
MouseAction_LeftButton,
|
||||
MouseAction_RightButton,
|
||||
MouseAction_MiddleButton,
|
||||
MouseAction_ScrollUp,
|
||||
MouseAction_ScrollDown,
|
||||
};
|
||||
|
||||
class MouseBinding : public IInputBinding
|
||||
{
|
||||
public:
|
||||
MouseAction Action;
|
||||
|
||||
MouseBinding(MouseAction action);
|
||||
~MouseBinding();
|
||||
|
||||
bool IsDown() override;
|
||||
bool IsTapped() override;
|
||||
bool IsReleased() override;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "XinputBinding.h"
|
||||
#include "..\Xinput\Xinput.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
XinputBinding::XinputBinding(BYTE keycode) : Keycode(keycode)
|
||||
{
|
||||
}
|
||||
|
||||
XinputBinding::~XinputBinding()
|
||||
{
|
||||
}
|
||||
|
||||
bool XinputBinding::IsDown()
|
||||
{
|
||||
return Xinput::GetInstance()->IsDown(Keycode);
|
||||
}
|
||||
|
||||
bool XinputBinding::IsTapped()
|
||||
{
|
||||
return Xinput::GetInstance()->IsTapped(Keycode);
|
||||
}
|
||||
|
||||
bool XinputBinding::IsReleased()
|
||||
{
|
||||
return Xinput::GetInstance()->IsReleased(Keycode);
|
||||
}
|
||||
|
||||
bool XinputBinding::IsDoubleTapped()
|
||||
{
|
||||
return Xinput::GetInstance()->IsDoubleTapped(Keycode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "IInputBinding.h"
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class XinputBinding : public IInputBinding
|
||||
{
|
||||
public:
|
||||
BYTE Keycode;
|
||||
|
||||
XinputBinding(BYTE keycode);
|
||||
~XinputBinding();
|
||||
|
||||
bool IsDown() override;
|
||||
bool IsTapped() override;
|
||||
bool IsReleased() override;
|
||||
bool IsDoubleTapped();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "Controller.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Controller::Controller()
|
||||
{
|
||||
}
|
||||
|
||||
Controller::~Controller()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "DirectInputDevice.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class Controller : public DirectInputDevice
|
||||
{
|
||||
protected:
|
||||
Controller();
|
||||
~Controller();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "DirectInput.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
IDirectInput8 *IDirectInputInstance = nullptr;
|
||||
|
||||
HRESULT InitializeDirectInput(HMODULE module)
|
||||
{
|
||||
HRESULT result = DirectInput8Create(module, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&IDirectInputInstance, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DirectInputInitialized()
|
||||
{
|
||||
return IDirectInputInstance != nullptr;
|
||||
}
|
||||
|
||||
void DisposeDirectInput()
|
||||
{
|
||||
if (IDirectInputInstance == nullptr)
|
||||
return;
|
||||
|
||||
IDirectInputInstance->Release();
|
||||
IDirectInputInstance = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <dinput.h>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
extern IDirectInput8 *IDirectInputInstance;
|
||||
|
||||
HRESULT InitializeDirectInput(HMODULE module);
|
||||
bool DirectInputInitialized();
|
||||
void DisposeDirectInput();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#include "DirectInputDevice.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
HRESULT DirectInputDevice::DI_CreateDevice(const GUID &guid)
|
||||
{
|
||||
if (!DirectInputInitialized())
|
||||
return DIERR_NOTINITIALIZED;
|
||||
|
||||
HRESULT result = IDirectInputInstance->CreateDevice(guid, &directInputdevice, NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_SetDataFormat(LPCDIDATAFORMAT dataFormat)
|
||||
{
|
||||
HRESULT result = directInputdevice->SetDataFormat(dataFormat);
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_SetCooperativeLevel(HWND windowHandle, DWORD flags)
|
||||
{
|
||||
HRESULT result = directInputdevice->SetCooperativeLevel(windowHandle, flags);
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_Acquire()
|
||||
{
|
||||
HRESULT result = directInputdevice->Acquire();
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_Unacquire()
|
||||
{
|
||||
HRESULT result = directInputdevice->Unacquire();
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_Release()
|
||||
{
|
||||
HRESULT result = directInputdevice->Release();
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_Poll()
|
||||
{
|
||||
HRESULT result = directInputdevice->Poll();
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_GetDeviceState(DWORD size, LPVOID data)
|
||||
{
|
||||
HRESULT result = directInputdevice->GetDeviceState(size, data);
|
||||
return result;
|
||||
}
|
||||
|
||||
void DirectInputDevice::DI_Dispose()
|
||||
{
|
||||
if (directInputdevice == nullptr)
|
||||
return;
|
||||
|
||||
HRESULT result = NULL;
|
||||
|
||||
result = DI_Unacquire();
|
||||
result = DI_Release();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "DirectInput.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class DirectInputDevice
|
||||
{
|
||||
protected:
|
||||
IDirectInputDevice8 *directInputdevice;
|
||||
|
||||
HRESULT DI_CreateDevice(const GUID& guid);
|
||||
HRESULT DI_SetDataFormat(LPCDIDATAFORMAT dataFormat);
|
||||
HRESULT DI_SetCooperativeLevel(HWND windowHandle, DWORD flags);
|
||||
HRESULT DI_Acquire();
|
||||
HRESULT DI_Unacquire();
|
||||
HRESULT DI_Release();
|
||||
HRESULT DI_Poll();
|
||||
HRESULT DI_GetDeviceState(DWORD size, LPVOID data);
|
||||
|
||||
void DI_Dispose();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "DirectInputMouse.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
DirectInputMouse::DirectInputMouse()
|
||||
{
|
||||
HRESULT result = NULL;
|
||||
|
||||
result = DI_CreateDevice(GUID_SysMouse);
|
||||
|
||||
if (FAILED(result))
|
||||
return;
|
||||
|
||||
result = DI_SetDataFormat(&c_dfDIMouse);
|
||||
result = DI_Acquire();
|
||||
}
|
||||
|
||||
DirectInputMouse::~DirectInputMouse()
|
||||
{
|
||||
DI_Dispose();
|
||||
}
|
||||
|
||||
bool DirectInputMouse::Poll()
|
||||
{
|
||||
if (!DirectInputInitialized())
|
||||
return FALSE;
|
||||
|
||||
HRESULT result = NULL;
|
||||
|
||||
result = DI_Poll();
|
||||
result = DI_GetDeviceState(sizeof(mouseState), &mouseState);
|
||||
|
||||
return !FAILED(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "DirectInputDevice.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class DirectInputMouse : public DirectInputDevice
|
||||
{
|
||||
public:
|
||||
DirectInputMouse();
|
||||
~DirectInputMouse();
|
||||
|
||||
bool Poll();
|
||||
|
||||
inline long GetXPosition() { return mouseState.lX; };
|
||||
inline long GetYPosition() { return mouseState.lY; };
|
||||
inline long GetMouseWheel() { return mouseState.lZ; };
|
||||
|
||||
private:
|
||||
DIMOUSESTATE mouseState;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
enum Direction
|
||||
{
|
||||
DIR_UP,
|
||||
DIR_RIGHT,
|
||||
DIR_DOWN,
|
||||
DIR_LEFT
|
||||
};
|
||||
|
||||
enum Ds4Button : int
|
||||
{
|
||||
DS4_SQUARE = 0,
|
||||
DS4_CROSS = 1,
|
||||
DS4_CIRCLE = 2,
|
||||
DS4_TRIANGLE = 3,
|
||||
|
||||
DS4_L1 = 4,
|
||||
DS4_R1 = 5,
|
||||
|
||||
DS4_L_TRIGGER = 6,
|
||||
DS4_R_TRIGGER = 7,
|
||||
|
||||
DS4_SHARE = 8,
|
||||
DS4_OPTIONS = 9,
|
||||
|
||||
DS4_L3 = 10,
|
||||
DS4_R3 = 11,
|
||||
|
||||
DS4_PS = 12,
|
||||
DS4_TOUCH = 13,
|
||||
|
||||
DS4_DPAD_UP,
|
||||
DS4_DPAD_RIGHT,
|
||||
DS4_DPAD_DOWN,
|
||||
DS4_DPAD_LEFT,
|
||||
|
||||
DS4_L_STICK_UP,
|
||||
DS4_L_STICK_RIGHT,
|
||||
DS4_L_STICK_DOWN,
|
||||
DS4_L_STICK_LEFT,
|
||||
|
||||
DS4_R_STICK_UP,
|
||||
DS4_R_STICK_RIGHT,
|
||||
DS4_R_STICK_DOWN,
|
||||
DS4_R_STICK_LEFT,
|
||||
|
||||
DS4_BUTTON_MAX,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "Ds4State.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Joystick::Joystick() : XAxis(0.0f), YAxis(0.0f)
|
||||
{
|
||||
return;
|
||||
};
|
||||
|
||||
Joystick::Joystick(float xAxis, float yAxis) : XAxis(xAxis), YAxis(yAxis)
|
||||
{
|
||||
return;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#include "../DirectInput.h"
|
||||
#include "Ds4Button.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
struct Joystick
|
||||
{
|
||||
FLOAT XAxis, YAxis;
|
||||
|
||||
Joystick();
|
||||
Joystick(float xAxis, float yAxis);
|
||||
};
|
||||
|
||||
struct Dpad
|
||||
{
|
||||
BOOL IsDown;
|
||||
FLOAT Angle;
|
||||
Joystick Stick;
|
||||
};
|
||||
|
||||
struct Trigger
|
||||
{
|
||||
FLOAT Axis;
|
||||
};
|
||||
|
||||
struct Ds4State
|
||||
{
|
||||
DIJOYSTATE2 DI_JoyState;
|
||||
|
||||
BYTE Buttons[DS4_BUTTON_MAX];
|
||||
|
||||
Dpad Dpad;
|
||||
Joystick LeftStick;
|
||||
Joystick RightStick;
|
||||
Trigger LeftTrigger;
|
||||
Trigger RightTrigger;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
#include "DualShock4.h"
|
||||
#include "../../../Utilities/Math.h"
|
||||
#include "../../../framework.h"
|
||||
#include <stdio.h>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
DualShock4* DualShock4::instance;
|
||||
|
||||
DualShock4::DualShock4()
|
||||
{
|
||||
}
|
||||
|
||||
DualShock4::~DualShock4()
|
||||
{
|
||||
DI_Dispose();
|
||||
}
|
||||
|
||||
bool DualShock4::TryInitializeInstance()
|
||||
{
|
||||
if (InstanceInitialized())
|
||||
return true;
|
||||
|
||||
if (!DirectInputInitialized())
|
||||
return false;
|
||||
|
||||
DualShock4 *dualShock4 = new DualShock4();
|
||||
|
||||
bool success = dualShock4->Initialize();
|
||||
instance = success ? dualShock4 : nullptr;
|
||||
|
||||
if (!success)
|
||||
delete dualShock4;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool DualShock4::Initialize()
|
||||
{
|
||||
HRESULT result = NULL;
|
||||
|
||||
const size_t guidCount = sizeof(GUID_Ds4) / sizeof(GUID);
|
||||
for (size_t i = 0; i < guidCount; i++)
|
||||
{
|
||||
result = DI_CreateDevice(GUID_Ds4[i]);
|
||||
|
||||
if (!FAILED(result))
|
||||
break;
|
||||
else if (i == guidCount - 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(result = DI_SetDataFormat(&c_dfDIJoystick2)))
|
||||
return false;
|
||||
|
||||
result = DI_Acquire();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DualShock4::PollInput()
|
||||
{
|
||||
lastState = currentState;
|
||||
|
||||
HRESULT result = NULL;
|
||||
result = DI_Poll();
|
||||
result = DI_GetDeviceState(sizeof(DIJOYSTATE2), ¤tState.DI_JoyState);
|
||||
|
||||
if (result != DI_OK)
|
||||
return false;
|
||||
|
||||
UpdateInternalDs4State(currentState);
|
||||
|
||||
for (int button = 0; button < DS4_BUTTON_MAX; button++)
|
||||
currentState.Buttons[button] = GetButtonState(currentState, (Ds4Button)button);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DualShock4::UpdateInternalDs4State(Ds4State &state)
|
||||
{
|
||||
if (state.Dpad.IsDown = state.DI_JoyState.rgdwPOV[0] != -1)
|
||||
{
|
||||
state.Dpad.Angle = (state.DI_JoyState.rgdwPOV[0] / 100.0f);
|
||||
|
||||
auto direction = Utilities::GetDirection(state.Dpad.Angle);
|
||||
state.Dpad.Stick = { direction.Y, -direction.X };
|
||||
}
|
||||
else
|
||||
{
|
||||
state.Dpad.Angle = 0;
|
||||
state.Dpad.Stick = Joystick();
|
||||
}
|
||||
|
||||
state.LeftStick = NormalizeStick(state.DI_JoyState.lX, state.DI_JoyState.lY);
|
||||
state.RightStick = NormalizeStick(state.DI_JoyState.lZ, state.DI_JoyState.lRz);
|
||||
|
||||
state.LeftTrigger = { NormalizeTrigger(state.DI_JoyState.lRx) };
|
||||
state.RightTrigger = { NormalizeTrigger(state.DI_JoyState.lRy) };
|
||||
}
|
||||
|
||||
bool DualShock4::IsDown(Ds4Button button)
|
||||
{
|
||||
return currentState.Buttons[button];
|
||||
}
|
||||
|
||||
bool DualShock4::IsUp(Ds4Button button)
|
||||
{
|
||||
return !IsDown(button);
|
||||
}
|
||||
|
||||
bool DualShock4::IsTapped(Ds4Button button)
|
||||
{
|
||||
return IsDown(button) && WasUp(button);
|
||||
}
|
||||
|
||||
bool DualShock4::IsReleased(Ds4Button button)
|
||||
{
|
||||
return IsUp(button) && WasDown(button);
|
||||
}
|
||||
|
||||
bool DualShock4::WasDown(Ds4Button button)
|
||||
{
|
||||
return lastState.Buttons[button];
|
||||
}
|
||||
|
||||
bool DualShock4::WasUp(Ds4Button button)
|
||||
{
|
||||
return !WasDown(button);
|
||||
}
|
||||
|
||||
bool DualShock4::MatchesDirection(Joystick joystick, Direction directionEnum, float threshold)
|
||||
{
|
||||
switch (directionEnum)
|
||||
{
|
||||
case TLAC::Input::DIR_UP:
|
||||
return joystick.YAxis <= -threshold;
|
||||
|
||||
case TLAC::Input::DIR_RIGHT:
|
||||
return joystick.XAxis >= +threshold;
|
||||
|
||||
case TLAC::Input::DIR_DOWN:
|
||||
return joystick.YAxis >= +threshold;
|
||||
|
||||
case TLAC::Input::DIR_LEFT:
|
||||
return joystick.XAxis <= -threshold;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DualShock4::GetButtonState(Ds4State &state, Ds4Button button)
|
||||
{
|
||||
if (button >= DS4_SQUARE && button <= DS4_TOUCH)
|
||||
return state.DI_JoyState.rgbButtons[button];
|
||||
|
||||
if (button >= DS4_DPAD_UP && button <= DS4_DPAD_LEFT)
|
||||
return state.Dpad.IsDown ? MatchesDirection(state.Dpad.Stick, (Direction)(button - DS4_DPAD_UP), dpadThreshold) : false;
|
||||
|
||||
if (button >= DS4_L_STICK_UP && button <= DS4_L_STICK_LEFT)
|
||||
return MatchesDirection(state.LeftStick, (Direction)(button - DS4_L_STICK_UP), joystickThreshold);
|
||||
|
||||
if (button >= DS4_R_STICK_UP && button <= DS4_R_STICK_LEFT)
|
||||
return MatchesDirection(state.RightStick, (Direction)(button - DS4_R_STICK_UP), joystickThreshold);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
#include "../Controller.h"
|
||||
#include "../../IInputDevice.h"
|
||||
#include "Ds4State.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
// DualShock 4 Wireless Controller Product GUIDs:
|
||||
const GUID GUID_Ds4[2] =
|
||||
{
|
||||
// First Generation: {05C4054C-0000-0000-0000-504944564944}
|
||||
{ 0x05C4054C, 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
|
||||
// Second Generation: {09CC054C-0000-0000-0000-504944564944}
|
||||
{ 0x09CC054C, 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
|
||||
};
|
||||
|
||||
class DualShock4 : public Controller, public IInputDevice
|
||||
{
|
||||
public:
|
||||
DualShock4();
|
||||
~DualShock4();
|
||||
|
||||
static bool TryInitializeInstance();
|
||||
|
||||
bool Initialize();
|
||||
bool PollInput() override;
|
||||
|
||||
bool IsDown(Ds4Button button);
|
||||
bool IsUp(Ds4Button button);
|
||||
bool IsTapped(Ds4Button button);
|
||||
bool IsReleased(Ds4Button button);
|
||||
bool WasDown(Ds4Button button);
|
||||
bool WasUp(Ds4Button button);
|
||||
|
||||
inline Joystick GetLeftStick() { return currentState.LeftStick; };
|
||||
inline Joystick GetRightStick() { return currentState.RightStick; };
|
||||
inline Joystick GetDpad() { return currentState.Dpad.Stick; };
|
||||
|
||||
static inline bool InstanceInitialized() { return instance != nullptr; };
|
||||
static inline DualShock4* GetInstance() { return instance; };
|
||||
static inline void DeleteInstance() { delete instance; instance = nullptr; };
|
||||
|
||||
private:
|
||||
static DualShock4* instance;
|
||||
|
||||
Ds4State lastState;
|
||||
Ds4State currentState;
|
||||
|
||||
const float triggerThreshold = 0.5f;
|
||||
const float joystickThreshold = 0.5f;
|
||||
const float dpadThreshold = 0.5f;
|
||||
|
||||
inline float NormalizeTrigger(long value) { return (float)value / USHRT_MAX; };
|
||||
inline float NormalizeStick(long value) { return (float)value / USHRT_MAX * 2.0f - 1.0f; };
|
||||
inline Joystick NormalizeStick(long x, long y) { return Joystick(NormalizeStick(x), NormalizeStick(y)); };
|
||||
|
||||
void UpdateInternalDs4State(Ds4State &state);
|
||||
|
||||
bool MatchesDirection(Joystick joystick, Direction directionEnum, float threshold);
|
||||
bool GetButtonState(Ds4State &state, Ds4Button button);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class IInputDevice
|
||||
{
|
||||
public:
|
||||
virtual bool PollInput() = 0;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
#include "Config.h"
|
||||
#include "windows.h"
|
||||
#include "../Bindings/KeyboardBinding.h"
|
||||
#include "../Bindings/Ds4Binding.h"
|
||||
#include "../../Utilities/Operations.h"
|
||||
#include "../Bindings/XinputBinding.h"
|
||||
#include "../../Constants.h"
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
KeycodeMap Config::Keymap =
|
||||
{
|
||||
// NumPad Keys
|
||||
{ "NumPad0", VK_NUMPAD0 },
|
||||
{ "NumPad1", VK_NUMPAD1 },
|
||||
{ "NumPad2", VK_NUMPAD2 },
|
||||
{ "NumPad3", VK_NUMPAD3 },
|
||||
{ "NumPad4", VK_NUMPAD4 },
|
||||
{ "NumPad5", VK_NUMPAD5 },
|
||||
{ "NumPad6", VK_NUMPAD6 },
|
||||
{ "NumPad7", VK_NUMPAD7 },
|
||||
{ "NumPad8", VK_NUMPAD8 },
|
||||
{ "NumPad9", VK_NUMPAD9 },
|
||||
{ "Plus", VK_ADD },
|
||||
{ "Minus", VK_SUBTRACT },
|
||||
{ "Divide", VK_DIVIDE },
|
||||
{ "Multiply", VK_MULTIPLY },
|
||||
{ "Comma", VK_OEM_COMMA },
|
||||
{ "Period", VK_OEM_PERIOD },
|
||||
{ "Slash", VK_OEM_2 },
|
||||
// F-Keys
|
||||
{ "F1", VK_F1 },
|
||||
{ "F2", VK_F2 },
|
||||
{ "F3", VK_F3 },
|
||||
{ "F4", VK_F4 },
|
||||
{ "F5", VK_F5 },
|
||||
{ "F6", VK_F6 },
|
||||
{ "F7", VK_F7 },
|
||||
{ "F8", VK_F8 },
|
||||
{ "F9", VK_F9 },
|
||||
{ "F10", VK_F10 },
|
||||
{ "F11", VK_F11 },
|
||||
{ "F12", VK_F12 },
|
||||
{ "F13", VK_F13 },
|
||||
{ "F14", VK_F14 },
|
||||
{ "F15", VK_F15 },
|
||||
{ "F16", VK_F16 },
|
||||
{ "F17", VK_F17 },
|
||||
{ "F18", VK_F18 },
|
||||
{ "F19", VK_F19 },
|
||||
{ "F20", VK_F20 },
|
||||
{ "F21", VK_F21 },
|
||||
{ "F22", VK_F22 },
|
||||
{ "F23", VK_F23 },
|
||||
{ "F24", VK_F24 },
|
||||
// Shift Keys
|
||||
{ "LeftShift", VK_LSHIFT },
|
||||
{ "LShift", VK_LSHIFT },
|
||||
{ "RightShift", VK_RSHIFT },
|
||||
{ "RShift", VK_RSHIFT },
|
||||
// Control Keys
|
||||
{ "LeftControl", VK_LCONTROL },
|
||||
{ "LControl", VK_LCONTROL },
|
||||
{ "LCtrl", VK_LCONTROL },
|
||||
{ "RightControl", VK_RCONTROL },
|
||||
{ "RControl", VK_RCONTROL },
|
||||
{ "RCtrl", VK_RCONTROL },
|
||||
// Arrow Keys
|
||||
{ "Up", VK_UP },
|
||||
{ "Down", VK_DOWN },
|
||||
{ "Left", VK_LEFT },
|
||||
{ "Right", VK_RIGHT },
|
||||
// Special Keys
|
||||
{ "Enter", VK_RETURN },
|
||||
{ "Return", VK_RETURN },
|
||||
{ "Tab", VK_TAB },
|
||||
{ "Back", VK_BACK },
|
||||
{ "Backspace", VK_BACK },
|
||||
{ "Insert", VK_INSERT },
|
||||
{ "Ins", VK_INSERT },
|
||||
{ "Delete", VK_DELETE },
|
||||
{ "Del", VK_DELETE },
|
||||
{ "Home", VK_HOME },
|
||||
{ "End", VK_END },
|
||||
{ "PageUp", VK_PRIOR },
|
||||
{ "PageDown", VK_NEXT },
|
||||
{ "ESC", VK_ESCAPE },
|
||||
{ "Escape", VK_ESCAPE },
|
||||
{ "Comma", VK_OEM_COMMA },
|
||||
{ "Period", VK_OEM_PERIOD },
|
||||
{ "Slash", VK_OEM_2 },
|
||||
// Mouse buttons
|
||||
{ "MouseLeft", VK_LBUTTON },
|
||||
{ "MouseMiddle", VK_MBUTTON },
|
||||
{ "MouseRight", VK_RBUTTON },
|
||||
{ "MouseX1", VK_XBUTTON1 },
|
||||
{ "MouseX2", VK_XBUTTON2 },
|
||||
};
|
||||
|
||||
KeycodeMap Config::XinputMap =
|
||||
{
|
||||
//XINPUT
|
||||
{ "XINPUT_A", XINPUT_A},
|
||||
{ "XINPUT_B", XINPUT_B},
|
||||
{ "XINPUT_X", XINPUT_X},
|
||||
{ "XINPUT_Y", XINPUT_Y},
|
||||
{ "XINPUT_UP", XINPUT_UP},
|
||||
{ "XINPUT_DOWN", XINPUT_DOWN},
|
||||
{ "XINPUT_LEFT", XINPUT_LEFT},
|
||||
{ "XINPUT_RIGHT", XINPUT_RIGHT},
|
||||
{ "XINPUT_START", XINPUT_START},
|
||||
{ "XINPUT_BACK", XINPUT_BACK},
|
||||
{ "XINPUT_LS", XINPUT_LS},
|
||||
{ "XINPUT_RS", XINPUT_RS},
|
||||
{ "XINPUT_LB", XINPUT_LS},
|
||||
{ "XINPUT_RB", XINPUT_RS},
|
||||
{ "XINPUT_LT", XINPUT_LT},
|
||||
{ "XINPUT_RT", XINPUT_RT},
|
||||
{ "XINPUT_LSB", XINPUT_LSB},
|
||||
{ "XINPUT_RSB", XINPUT_RSB},
|
||||
{ "XINPUT_LLEFT", XINPUT_LLEFT},
|
||||
{ "XINPUT_LRIGHT", XINPUT_LRIGHT},
|
||||
{ "XINPUT_RLEFT", XINPUT_RLEFT},
|
||||
{ "XINPUT_RRIGHT", XINPUT_RRIGHT},
|
||||
};
|
||||
|
||||
Ds4ButtonMap Config::Ds4Map =
|
||||
{
|
||||
// Face Buttons
|
||||
{ "DS4_SQUARE", DS4_SQUARE },
|
||||
{ "Ds4_Square", DS4_SQUARE },
|
||||
|
||||
{ "DS4_CROSS", DS4_CROSS },
|
||||
{ "Ds4_Cross", DS4_CROSS },
|
||||
|
||||
{ "DS4_CIRCLE", DS4_CIRCLE },
|
||||
{ "Ds4_Circle", DS4_CIRCLE },
|
||||
|
||||
{ "DS4_TRIANGLE", DS4_TRIANGLE },
|
||||
{ "Ds4_Triangle", DS4_TRIANGLE },
|
||||
|
||||
// Standard Buttons
|
||||
{ "DS4_SHARE", DS4_SHARE },
|
||||
{ "Ds4_Share", DS4_SHARE },
|
||||
|
||||
{ "DS4_OPTIONS", DS4_OPTIONS },
|
||||
{ "Ds4_Options", DS4_OPTIONS },
|
||||
|
||||
{ "DS4_PS", DS4_PS },
|
||||
{ "Ds4_PS", DS4_PS },
|
||||
|
||||
{ "DS4_TOUCH", DS4_TOUCH },
|
||||
{ "Ds4_Touch", DS4_TOUCH },
|
||||
|
||||
{ "DS4_L1", DS4_L1 },
|
||||
{ "Ds4_L1", DS4_L1 },
|
||||
|
||||
{ "DS4_R1", DS4_R1 },
|
||||
{ "Ds4_R1", DS4_R1 },
|
||||
|
||||
// D-Pad Directions
|
||||
{ "DS4_DPAD_UP", DS4_DPAD_UP },
|
||||
{ "Ds4_DPad_Up", DS4_DPAD_UP },
|
||||
|
||||
{ "DS4_DPAD_RIGHT", DS4_DPAD_RIGHT },
|
||||
{ "Ds4_DPad_Right", DS4_DPAD_RIGHT },
|
||||
|
||||
{ "DS4_DPAD_DOWN", DS4_DPAD_DOWN },
|
||||
{ "Ds4_DPad_Down", DS4_DPAD_DOWN },
|
||||
|
||||
{ "DS4_DPAD_LEFT", DS4_DPAD_LEFT },
|
||||
{ "Ds4_DPad_Left", DS4_DPAD_LEFT },
|
||||
|
||||
// Trigger Buttons
|
||||
{ "DS4_L_TRIGGER", DS4_L_TRIGGER },
|
||||
{ "Ds4_L_Trigger", DS4_L_TRIGGER },
|
||||
|
||||
{ "DS4_R_TRIGGER", DS4_R_TRIGGER },
|
||||
{ "Ds4_R_Trigger", DS4_R_TRIGGER },
|
||||
|
||||
// Joystick Buttons
|
||||
{ "DS4_L3", DS4_L3 },
|
||||
{ "Ds4_L3", DS4_L3 },
|
||||
|
||||
{ "DS4_R3", DS4_R3 },
|
||||
{ "Ds4_R3", DS4_R3 },
|
||||
|
||||
// Left Joystick
|
||||
{ "DS4_L_STICK_UP", DS4_L_STICK_UP },
|
||||
{ "Ds4_L_Stick_Up", DS4_L_STICK_UP },
|
||||
|
||||
{ "DS4_L_STICK_RIGHT", DS4_L_STICK_RIGHT },
|
||||
{ "Ds4_L_Stick_Right", DS4_L_STICK_RIGHT },
|
||||
|
||||
{ "DS4_L_STICK_DOWN", DS4_L_STICK_DOWN },
|
||||
{ "Ds4_L_Stick_Down", DS4_L_STICK_DOWN },
|
||||
|
||||
{ "DS4_L_STICK_LEFT", DS4_L_STICK_LEFT },
|
||||
{ "Ds4_L_Stick_Left", DS4_L_STICK_LEFT },
|
||||
|
||||
// Right Joystick
|
||||
{ "DS4_R_STICK_UP", DS4_R_STICK_UP },
|
||||
{ "Ds4_R_Stick_Up", DS4_R_STICK_UP },
|
||||
|
||||
{ "DS4_R_STICK_RIGHT", DS4_R_STICK_RIGHT },
|
||||
{ "Ds4_R_Stick_Right", DS4_R_STICK_RIGHT },
|
||||
|
||||
{ "DS4_R_STICK_DOWN", DS4_R_STICK_DOWN },
|
||||
{ "Ds4_R_Stick_Down", DS4_R_STICK_DOWN },
|
||||
|
||||
{ "DS4_R_STICK_LEFT", DS4_R_STICK_LEFT },
|
||||
{ "Ds4_R_Stick_Left", DS4_R_STICK_LEFT },
|
||||
};
|
||||
|
||||
void Config::BindConfigKeys(std::unordered_map<std::string, std::string> &configMap, const char *configKeyName, Binding &bindObj, std::vector<std::string> defaultKeys)
|
||||
{
|
||||
std::vector<std::string> keys;
|
||||
|
||||
auto configPair = configMap.find(configKeyName);
|
||||
|
||||
// config variable was found in the ini
|
||||
if (configPair != configMap.end())
|
||||
{
|
||||
keys = Utilities::Split(configPair->second, ",");
|
||||
}
|
||||
else
|
||||
{
|
||||
keys = defaultKeys;
|
||||
}
|
||||
|
||||
for (std::string key : keys)
|
||||
{
|
||||
Utilities::Trim(key);
|
||||
|
||||
// Applies only for Single-Character keys
|
||||
if (key.length() == 1)
|
||||
{
|
||||
bindObj.AddBinding(new KeyboardBinding(key[0]));
|
||||
}
|
||||
else // for special key names
|
||||
{
|
||||
auto keycode = Config::Keymap.find(key.c_str());
|
||||
|
||||
// name is known in the special keys map
|
||||
if (keycode != Config::Keymap.end())
|
||||
{
|
||||
bindObj.AddBinding(new KeyboardBinding(keycode->second));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto xinputBtn = Config::XinputMap.find(key.c_str());
|
||||
|
||||
if (xinputBtn != Config::XinputMap.end())
|
||||
{
|
||||
bindObj.AddBinding(new XinputBinding(xinputBtn->second));
|
||||
}
|
||||
else
|
||||
{
|
||||
// just gonna be lazy for now and put this inside an else statement
|
||||
auto ds4Button = Config::Ds4Map.find(key.c_str());
|
||||
|
||||
if (ds4Button != Config::Ds4Map.end())
|
||||
{
|
||||
bindObj.AddBinding(new Ds4Binding(ds4Button->second));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[TLAC] Config::BindConfigKeys(): Unable to parse key: '%s'\n", key.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include "KeyString.h"
|
||||
#include "KeyStringHash.h"
|
||||
#include "../Bindings/Binding.h"
|
||||
#include "../DirectInput/Ds4/Ds4Button.h"
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
typedef std::unordered_map<KeyString, uint8_t, KeyStringHash> KeycodeMap;
|
||||
typedef std::unordered_map<KeyString, Ds4Button, KeyStringHash> Ds4ButtonMap;
|
||||
|
||||
class Config
|
||||
{
|
||||
public:
|
||||
static KeycodeMap Keymap;
|
||||
static Ds4ButtonMap Ds4Map;
|
||||
static KeycodeMap XinputMap;
|
||||
|
||||
static void BindConfigKeys(std::unordered_map<std::string, std::string> &configMap, const char *configKeyName, Binding &bindObj, std::vector<std::string> defaultKeys);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "KeyString.h"
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
KeyString::KeyString(const char* str) : value(str)
|
||||
{
|
||||
}
|
||||
|
||||
bool KeyString::operator==(const KeyString& rsv) const
|
||||
{
|
||||
return !_strcmpi(value.c_str(), rsv.value.c_str());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
struct KeyString
|
||||
{
|
||||
std::string value;
|
||||
|
||||
KeyString(const char* str);
|
||||
bool operator==(const KeyString& rsv) const;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "KeyStringHash.h"
|
||||
#include <filesystem>
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
size_t KeyStringHash::operator()(const KeyString& key) const
|
||||
{
|
||||
std::string ret = key.value;
|
||||
std::transform(ret.begin(), ret.end(), ret.begin(),
|
||||
[](unsigned char c) { return std::tolower(c, std::locale()); });
|
||||
return std::hash<std::string>()(ret);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "KeyString.h"
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
struct KeyStringHash
|
||||
{
|
||||
size_t operator()(const KeyString& key) const;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
#include "Keyboard.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Keyboard* Keyboard::instance;
|
||||
|
||||
Keyboard::Keyboard()
|
||||
{
|
||||
}
|
||||
|
||||
Keyboard* Keyboard::GetInstance()
|
||||
{
|
||||
if (instance == nullptr)
|
||||
instance = new Keyboard();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool Keyboard::PollInput()
|
||||
{
|
||||
lastState = currentState;
|
||||
|
||||
float elapsed = keyIntervalWatch.Restart();
|
||||
|
||||
for (BYTE i = 0; i < KEYBOARD_KEYS; i++)
|
||||
{
|
||||
// DOWN
|
||||
bool isDown = GetAsyncKeyState(i) < 0;
|
||||
currentState.KeyStates[i] = isDown;
|
||||
|
||||
// DOUBLE TAPPED
|
||||
bool isTapped = IsTapped(i);
|
||||
keyDoubleTapStates[i] = isTapped ? keyDoubleTapWatches[i].Restart() <= DOUBLE_TAP_THRESHOLD : false;
|
||||
|
||||
// INTERVAL TAPPED
|
||||
keyIntervalTapStates[i] = isTapped;
|
||||
|
||||
if (isTapped)
|
||||
{
|
||||
keyIntervalTapTimes[i] = 0;
|
||||
keyIntervalInitials[i] = true;
|
||||
}
|
||||
else if (isDown)
|
||||
{
|
||||
float threshold = keyIntervalInitials[i] ? INTERVAL_TAP_DELAY_THRESHOLD : INTERVAL_TAP_THRESHOLD;
|
||||
|
||||
bool intervalTapped = (keyIntervalTapTimes[i] += elapsed) > threshold;
|
||||
keyIntervalTapStates[i] = intervalTapped;
|
||||
|
||||
if (intervalTapped)
|
||||
{
|
||||
keyIntervalTapTimes[i] = 0;
|
||||
keyIntervalInitials[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Keyboard::IsDown(BYTE keycode)
|
||||
{
|
||||
return currentState.IsDown(keycode);
|
||||
}
|
||||
|
||||
bool Keyboard::IsUp(BYTE keycode)
|
||||
{
|
||||
return !IsDown(keycode);
|
||||
}
|
||||
|
||||
bool Keyboard::IsTapped(BYTE keycode)
|
||||
{
|
||||
return IsDown(keycode) && WasUp(keycode);
|
||||
}
|
||||
|
||||
bool Keyboard::IsDoubleTapped(BYTE keycode)
|
||||
{
|
||||
return keyDoubleTapStates[keycode];
|
||||
}
|
||||
|
||||
bool Keyboard::IsReleased(BYTE keycode)
|
||||
{
|
||||
return IsUp(keycode) && WasDown(keycode);
|
||||
}
|
||||
|
||||
inline bool Keyboard::WasDown(BYTE keycode)
|
||||
{
|
||||
return lastState.IsDown(keycode);
|
||||
}
|
||||
|
||||
inline bool Keyboard::WasUp(BYTE keycode)
|
||||
{
|
||||
return !WasDown(keycode);
|
||||
}
|
||||
|
||||
bool Keyboard::IsIntervalTapped(BYTE keycode)
|
||||
{
|
||||
return keyIntervalTapStates[keycode];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include "../IInputDevice.h"
|
||||
#include "KeyboardState.h"
|
||||
#include "../../Utilities/Stopwatch.h"
|
||||
|
||||
using Stopwatch = TLAC::Utilities::Stopwatch;
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
constexpr float DOUBLE_TAP_THRESHOLD = 200.0f;
|
||||
constexpr float INTERVAL_TAP_DELAY_THRESHOLD = 500.0f;
|
||||
constexpr float INTERVAL_TAP_THRESHOLD = 75.0f;
|
||||
|
||||
class Keyboard : public IInputDevice
|
||||
{
|
||||
public:
|
||||
static Keyboard* GetInstance();
|
||||
|
||||
bool PollInput() override;
|
||||
bool IsDown(BYTE keycode);
|
||||
bool IsUp(BYTE keycode);
|
||||
bool IsTapped(BYTE keycode);
|
||||
bool IsDoubleTapped(BYTE keycode);
|
||||
bool IsReleased(BYTE keycode);
|
||||
bool IsIntervalTapped(BYTE keycode);
|
||||
|
||||
bool WasDown(BYTE keycode);
|
||||
bool WasUp(BYTE keycode);
|
||||
|
||||
private:
|
||||
Keyboard();
|
||||
KeyboardState lastState;
|
||||
KeyboardState currentState;
|
||||
|
||||
Stopwatch keyIntervalWatch;
|
||||
|
||||
BYTE keyDoubleTapStates[KEYBOARD_KEYS];
|
||||
Stopwatch keyDoubleTapWatches[KEYBOARD_KEYS];
|
||||
|
||||
BOOL keyIntervalInitials[KEYBOARD_KEYS];
|
||||
BYTE keyIntervalTapStates[KEYBOARD_KEYS];
|
||||
FLOAT keyIntervalTapTimes[KEYBOARD_KEYS];
|
||||
|
||||
static Keyboard* instance;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "KeyboardState.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
bool KeyboardState::IsDown(BYTE keycode)
|
||||
{
|
||||
return KeyStates[keycode];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
const int KEYBOARD_KEYS = 0xFF;
|
||||
|
||||
struct KeyboardState
|
||||
{
|
||||
BYTE KeyStates[KEYBOARD_KEYS];
|
||||
|
||||
bool IsDown(BYTE keycode);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
#include "Mouse.h"
|
||||
#include "../../framework.h"
|
||||
#include "../../Constants.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Mouse* Mouse::instance;
|
||||
|
||||
Mouse::Mouse()
|
||||
{
|
||||
directInputMouse = new DirectInputMouse();
|
||||
}
|
||||
|
||||
Mouse::~Mouse()
|
||||
{
|
||||
if (directInputMouse != nullptr)
|
||||
delete directInputMouse;
|
||||
}
|
||||
|
||||
Mouse* Mouse::GetInstance()
|
||||
{
|
||||
if (instance == nullptr)
|
||||
instance = new Mouse();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
POINT Mouse::GetPosition()
|
||||
{
|
||||
return currentState.Position;
|
||||
}
|
||||
|
||||
POINT Mouse::GetRelativePosition()
|
||||
{
|
||||
return currentState.RelativePosition;
|
||||
}
|
||||
|
||||
POINT Mouse::GetDeltaPosition()
|
||||
{
|
||||
return
|
||||
{
|
||||
currentState.Position.x - lastState.Position.x,
|
||||
currentState.Position.y - lastState.Position.y
|
||||
};
|
||||
}
|
||||
|
||||
long Mouse::GetMouseWheel()
|
||||
{
|
||||
return currentState.MouseWheel;
|
||||
}
|
||||
|
||||
long Mouse::GetDeltaMouseWheel()
|
||||
{
|
||||
return currentState.MouseWheel - lastState.MouseWheel;
|
||||
}
|
||||
|
||||
bool Mouse::HasMoved()
|
||||
{
|
||||
POINT delta = GetDeltaPosition();
|
||||
return delta.x != 0 || delta.y != 0;
|
||||
}
|
||||
|
||||
bool Mouse::GetIsScrolledUp()
|
||||
{
|
||||
return currentState.ScrolledUp;
|
||||
}
|
||||
|
||||
bool Mouse::GetIsScrolledDown()
|
||||
{
|
||||
return currentState.ScrolledDown;
|
||||
}
|
||||
|
||||
bool Mouse::GetWasScrolledUp()
|
||||
{
|
||||
return lastState.ScrolledUp;
|
||||
}
|
||||
|
||||
bool Mouse::GetWasScrolledDown()
|
||||
{
|
||||
return lastState.ScrolledDown;
|
||||
}
|
||||
|
||||
void Mouse::SetPosition(int x, int y)
|
||||
{
|
||||
lastState.Position.x = x;
|
||||
lastState.Position.y = y;
|
||||
SetCursorPos(x, y);
|
||||
}
|
||||
|
||||
bool Mouse::PollInput()
|
||||
{
|
||||
lastState = currentState;
|
||||
|
||||
GetCursorPos(¤tState.Position);
|
||||
currentState.RelativePosition = currentState.Position;
|
||||
|
||||
if (framework::DivaWindowHandle != NULL)
|
||||
ScreenToClient(framework::DivaWindowHandle, ¤tState.RelativePosition);
|
||||
|
||||
RECT hWindow;
|
||||
GetClientRect(TLAC::framework::DivaWindowHandle, &hWindow);
|
||||
|
||||
gameHeight = (int*)RESOLUTION_HEIGHT_ADDRESS;
|
||||
gameWidth = (int*)RESOLUTION_WIDTH_ADDRESS;
|
||||
fbWidth = (int*)FB_WIDTH_ADDRESS;
|
||||
fbHeight = (int*)FB_HEIGHT_ADDRESS;
|
||||
|
||||
if (directInputMouse != nullptr)
|
||||
{
|
||||
if (directInputMouse->Poll())
|
||||
currentState.MouseWheel += directInputMouse->GetMouseWheel();
|
||||
|
||||
currentState.ScrolledUp = (GetDeltaMouseWheel() > 0);
|
||||
currentState.ScrolledDown = (GetDeltaMouseWheel() < 0);
|
||||
}
|
||||
|
||||
if ((fbWidth != gameWidth) && (fbHeight != gameHeight)) {
|
||||
xoffset = ((float)16 / (float)9) * (hWindow.bottom - hWindow.top);
|
||||
if (xoffset != (hWindow.right - hWindow.left))
|
||||
{
|
||||
scale = xoffset / (hWindow.right - hWindow.left);
|
||||
xoffset = ((hWindow.right - hWindow.left) / 2) - (xoffset / 2);
|
||||
}
|
||||
else {
|
||||
xoffset = 0;
|
||||
scale = 1;
|
||||
}
|
||||
|
||||
currentState.RelativePosition.x = ((currentState.RelativePosition.x - round(xoffset)) * *gameWidth / (hWindow.right - hWindow.left)) / scale;
|
||||
currentState.RelativePosition.y = currentState.RelativePosition.y * *gameHeight / (hWindow.bottom - hWindow.top);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
#include "../IInputDevice.h"
|
||||
#include "../DirectInput/DirectInputMouse.h"
|
||||
#include "MouseState.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class Mouse : public IInputDevice
|
||||
{
|
||||
public:
|
||||
~Mouse();
|
||||
|
||||
static Mouse* GetInstance();
|
||||
|
||||
bool PollInput() override;
|
||||
|
||||
POINT GetPosition();
|
||||
POINT GetRelativePosition();
|
||||
POINT GetDeltaPosition();
|
||||
|
||||
long GetMouseWheel();
|
||||
long GetDeltaMouseWheel();
|
||||
|
||||
bool HasMoved();
|
||||
bool GetIsScrolledUp();
|
||||
bool GetIsScrolledDown();
|
||||
bool GetWasScrolledUp();
|
||||
bool GetWasScrolledDown();
|
||||
|
||||
void SetPosition(int x, int y);
|
||||
|
||||
private:
|
||||
Mouse();
|
||||
MouseState lastState;
|
||||
MouseState currentState;
|
||||
DirectInputMouse* directInputMouse = nullptr;
|
||||
|
||||
int* gameWidth;
|
||||
int* gameHeight;
|
||||
int* fbWidth;
|
||||
int* fbHeight;
|
||||
|
||||
float xoffset;
|
||||
float scale;
|
||||
|
||||
static Mouse* instance;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
struct MouseState
|
||||
{
|
||||
POINT Position;
|
||||
POINT RelativePosition;
|
||||
long MouseWheel;
|
||||
bool ScrolledUp;
|
||||
bool ScrolledDown;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
#include <windows.h>
|
||||
#include "Xinput.h"
|
||||
#include "../../Constants.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Xinput* Xinput::instance;
|
||||
|
||||
Xinput::Xinput()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Xinput* Xinput::GetInstance()
|
||||
{
|
||||
if (instance == nullptr)
|
||||
{
|
||||
instance = new Xinput();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
void Xinput::SetTapStates(BYTE keycode, float elapsed)
|
||||
{
|
||||
KeyDoubleTapStates[keycode] = IsTapped(keycode) ? KeyDoubleTapWatches[keycode].Restart() <= DOUBLE_TAP_THRESHOLD : false;
|
||||
|
||||
bool isDown = currentState.KeyStates[keycode];
|
||||
bool isTapped = IsTapped(keycode);
|
||||
|
||||
keyIntervalTapStates[keycode] = isTapped;
|
||||
|
||||
if (isTapped)
|
||||
{
|
||||
keyIntervalTapTimes[keycode] = 0;
|
||||
keyIntervalInitials[keycode] = true;
|
||||
}
|
||||
else if (isDown)
|
||||
{
|
||||
float threshold = keyIntervalInitials[keycode] ? INTERVAL_TAP_DELAY_THRESHOLD : INTERVAL_TAP_THRESHOLD;
|
||||
|
||||
bool intervalTapped = (keyIntervalTapTimes[keycode] += elapsed) > threshold;
|
||||
keyIntervalTapStates[keycode] = intervalTapped;
|
||||
|
||||
if (intervalTapped)
|
||||
{
|
||||
keyIntervalTapTimes[keycode] = 0;
|
||||
keyIntervalInitials[keycode] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Xinput::PollInput()
|
||||
{
|
||||
lastState = currentState;
|
||||
ZeroMemory(&state, sizeof(XINPUT_STATE));
|
||||
float elapsed = keyIntervalWatch.Restart();
|
||||
|
||||
if (XInputGetState(0, &state) == ERROR_SUCCESS)
|
||||
{
|
||||
BYTE i = XINPUT_A;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_DOWN;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_B;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_B)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_RIGHT;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_X;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_X)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_LEFT;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_Y;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_UP;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_LS;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_RS;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_LSB;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_RSB;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_START;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_START)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_BACK;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_LT;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.bLeftTrigger > 230)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_RT;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.bRightTrigger > 230)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
//float normLX = fmaxf(-1, (float)state.Gamepad.sThumbLX / 32767);
|
||||
i = XINPUT_LRIGHT;
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.sThumbLX > 10000)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
|
||||
i = XINPUT_LLEFT;
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.sThumbLX < -10000)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
{
|
||||
//float normLX = fmaxf(-1, (float)state.Gamepad.sThumbRX / 32767);
|
||||
i = XINPUT_RRIGHT;
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.sThumbRX > 10000)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
|
||||
i = XINPUT_RLEFT;
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.sThumbRX < -10000)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ZeroMemory(&state, sizeof(XINPUT_STATE));
|
||||
ZeroMemory(¤tState, sizeof(currentState));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
bool Xinput::IsDown(BYTE keycode)
|
||||
{
|
||||
return currentState.IsDown(keycode);
|
||||
}
|
||||
|
||||
bool Xinput::IsUp(BYTE keycode)
|
||||
{
|
||||
return !IsDown(keycode);
|
||||
}
|
||||
|
||||
bool Xinput::IsTapped(BYTE keycode)
|
||||
{
|
||||
return IsDown(keycode) && WasUp(keycode);
|
||||
}
|
||||
|
||||
bool Xinput::IsDoubleTapped(BYTE keycode)
|
||||
{
|
||||
return KeyDoubleTapStates[keycode];
|
||||
}
|
||||
|
||||
bool Xinput::IsReleased(BYTE keycode)
|
||||
{
|
||||
return IsUp(keycode) && WasDown(keycode);
|
||||
}
|
||||
|
||||
inline bool Xinput::WasDown(BYTE keycode)
|
||||
{
|
||||
return lastState.IsDown(keycode);
|
||||
}
|
||||
|
||||
inline bool Xinput::WasUp(BYTE keycode)
|
||||
{
|
||||
return !WasDown(keycode);
|
||||
}
|
||||
|
||||
bool Xinput::IsIntervalTapped(BYTE keycode)
|
||||
{
|
||||
return keyIntervalTapStates[keycode];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
#include "../IInputDevice.h"
|
||||
#include <xinput.h>
|
||||
#include "../../Utilities/Stopwatch.h"
|
||||
#include "XinputState.h"
|
||||
|
||||
using Stopwatch = TLAC::Utilities::Stopwatch;
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class Xinput : public IInputDevice
|
||||
{
|
||||
const float DOUBLE_TAP_THRESHOLD = 200.0f;
|
||||
const float INTERVAL_TAP_DELAY_THRESHOLD = 500.0f;
|
||||
const float INTERVAL_TAP_THRESHOLD = 75.0f;
|
||||
|
||||
public:
|
||||
static Xinput* GetInstance();
|
||||
|
||||
bool PollInput() override;
|
||||
bool IsDown(BYTE keycode);
|
||||
bool IsUp(BYTE keycode);
|
||||
bool IsTapped(BYTE keycode);
|
||||
bool IsReleased(BYTE keycode);
|
||||
bool IsDoubleTapped(BYTE keycode);
|
||||
bool IsIntervalTapped(BYTE keycode);
|
||||
|
||||
bool WasDown(BYTE keycode);
|
||||
bool WasUp(BYTE keycode);
|
||||
|
||||
private:
|
||||
Xinput();
|
||||
XinputState lastState;
|
||||
XinputState currentState;
|
||||
|
||||
XINPUT_STATE state;
|
||||
|
||||
BYTE KeyDoubleTapStates[0xFF];
|
||||
Utilities::Stopwatch KeyDoubleTapWatches[0xFF];
|
||||
|
||||
Stopwatch keyIntervalWatch;
|
||||
|
||||
BOOL keyIntervalInitials[0xFF];
|
||||
BYTE keyIntervalTapStates[0xFF];
|
||||
FLOAT keyIntervalTapTimes[0xFF];
|
||||
|
||||
static Xinput* instance;
|
||||
|
||||
void SetTapStates(BYTE keycode, float elapsed);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "XinputState.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
bool XinputState::IsDown(BYTE keycode)
|
||||
{
|
||||
return KeyStates[keycode];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
struct XinputState
|
||||
{
|
||||
bool KeyStates[0x8F];
|
||||
|
||||
bool IsDown(BYTE keycode);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{2B5533BB-04A1-424F-9BCA-1CA963B46B7F}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>TLAC</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>$(ProjectName)</TargetName>
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>$(ProjectName)</TargetName>
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;TLAC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\detours\include;..\..\..\dependencies\freeglut\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalDependencies>XINPUT9_1_0.LIB;dinput8.lib;dxguid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>Xinput.h</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;..\..\..\dependencies\freeglut\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;TLAC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;TLAC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\detours\include;..\..\..\dependencies\freeglut\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;..\..\..\dependencies\freeglut\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>XINPUT9_1_0.LIB;dinput8.lib;dxguid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>Xinput.h</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;TLAC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Components\CameraController.h" />
|
||||
<ClInclude Include="Components\ComponentsManager.h" />
|
||||
<ClInclude Include="Components\CustomPlayerData.h" />
|
||||
<ClInclude Include="Components\DebugComponent.h" />
|
||||
<ClInclude Include="Components\EmulatorComponent.h" />
|
||||
<ClInclude Include="Components\FastLoader.h" />
|
||||
<ClInclude Include="Components\FPSLimiter.h" />
|
||||
<ClInclude Include="Components\FrameRateManager.h" />
|
||||
<ClInclude Include="Components\GameState.h" />
|
||||
<ClInclude Include="Components\GameTargets\HoldState.h" />
|
||||
<ClInclude Include="Components\GameTargets\TargetHitStates.h" />
|
||||
<ClInclude Include="Components\GameTargets\TargetInspector.h" />
|
||||
<ClInclude Include="Components\GameTargets\TargetState.h" />
|
||||
<ClInclude Include="Components\GameTargets\TargetTypes.h" />
|
||||
<ClInclude Include="Components\Input\InputBufferType.h" />
|
||||
<ClInclude Include="Components\Input\InputEmulator.h" />
|
||||
<ClInclude Include="Components\Input\InputState.h" />
|
||||
<ClInclude Include="Components\Input\JvsButtons.h" />
|
||||
<ClInclude Include="Components\Input\TouchPanelEmulator.h" />
|
||||
<ClInclude Include="Components\Input\TouchPanelState.h" />
|
||||
<ClInclude Include="Components\Input\TouchSliderEmulator.h" />
|
||||
<ClInclude Include="Components\Input\TouchSliderState.h" />
|
||||
<ClInclude Include="Components\PlayerData.h" />
|
||||
<ClInclude Include="Components\PlayerDataManager.h" />
|
||||
<ClInclude Include="Components\ScaleComponent.h" />
|
||||
<ClInclude Include="Components\StageManager.h" />
|
||||
<ClInclude Include="Components\SysTimer.h" />
|
||||
<ClInclude Include="Constants.h" />
|
||||
<ClInclude Include="FileSystem\ConfigFile.h" />
|
||||
<ClInclude Include="FileSystem\TextFile.h" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="Input\Bindings\Binding.h" />
|
||||
<ClInclude Include="Input\Bindings\Ds4Binding.h" />
|
||||
<ClInclude Include="Input\Bindings\IInputBinding.h" />
|
||||
<ClInclude Include="Input\Bindings\KeyboardBinding.h" />
|
||||
<ClInclude Include="Input\Bindings\MouseBinding.h" />
|
||||
<ClInclude Include="Input\Bindings\XinputBinding.h" />
|
||||
<ClInclude Include="Input\DirectInput\Controller.h" />
|
||||
<ClInclude Include="Input\DirectInput\DirectInput.h" />
|
||||
<ClInclude Include="Input\DirectInput\DirectInputDevice.h" />
|
||||
<ClInclude Include="Input\DirectInput\DirectInputMouse.h" />
|
||||
<ClInclude Include="Input\DirectInput\Ds4\Ds4Button.h" />
|
||||
<ClInclude Include="Input\DirectInput\Ds4\Ds4State.h" />
|
||||
<ClInclude Include="Input\DirectInput\Ds4\DualShock4.h" />
|
||||
<ClInclude Include="Input\IInputDevice.h" />
|
||||
<ClInclude Include="Input\Keyboard\Keyboard.h" />
|
||||
<ClInclude Include="Input\Keyboard\KeyboardState.h" />
|
||||
<ClInclude Include="Input\KeyConfig\Config.h" />
|
||||
<ClInclude Include="Input\KeyConfig\KeyString.h" />
|
||||
<ClInclude Include="Input\KeyConfig\KeyStringHash.h" />
|
||||
<ClInclude Include="Input\Mouse\Mouse.h" />
|
||||
<ClInclude Include="Input\Mouse\MouseState.h" />
|
||||
<ClInclude Include="Input\Xinput\Xinput.h" />
|
||||
<ClInclude Include="Input\Xinput\XinputState.h" />
|
||||
<ClInclude Include="Utilities\EnumBitwiseOperations.h" />
|
||||
<ClInclude Include="Utilities\Math.h" />
|
||||
<ClInclude Include="Utilities\Operations.h" />
|
||||
<ClInclude Include="Utilities\Stopwatch.h" />
|
||||
<ClInclude Include="Utilities\Vec2.h" />
|
||||
<ClInclude Include="Utilities\Vec3.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Components\CameraController.cpp" />
|
||||
<ClCompile Include="Components\ComponentsManager.cpp" />
|
||||
<ClCompile Include="Components\DebugComponent.cpp" />
|
||||
<ClCompile Include="Components\EmulatorComponent.cpp" />
|
||||
<ClCompile Include="Components\FastLoader.cpp" />
|
||||
<ClCompile Include="Components\FPSLimiter.cpp" />
|
||||
<ClCompile Include="Components\FrameRateManager.cpp" />
|
||||
<ClCompile Include="Components\GameTargets\TargetInspector.cpp" />
|
||||
<ClCompile Include="Components\Input\InputEmulator.cpp" />
|
||||
<ClCompile Include="Components\Input\InputState.cpp" />
|
||||
<ClCompile Include="Components\Input\TouchPanelEmulator.cpp" />
|
||||
<ClCompile Include="Components\Input\TouchSliderEmulator.cpp" />
|
||||
<ClCompile Include="Components\Input\TouchSliderState.cpp" />
|
||||
<ClCompile Include="Components\PlayerDataManager.cpp" />
|
||||
<ClCompile Include="Components\ScaleComponent.cpp" />
|
||||
<ClCompile Include="Components\StageManager.cpp" />
|
||||
<ClCompile Include="Components\SysTimer.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="FileSystem\ConfigFile.cpp" />
|
||||
<ClCompile Include="FileSystem\TextFile.cpp" />
|
||||
<ClCompile Include="framework.cpp" />
|
||||
<ClCompile Include="Input\Bindings\Binding.cpp" />
|
||||
<ClCompile Include="Input\Bindings\Ds4Binding.cpp" />
|
||||
<ClCompile Include="Input\Bindings\KeyboardBinding.cpp" />
|
||||
<ClCompile Include="Input\Bindings\MouseBinding.cpp" />
|
||||
<ClCompile Include="Input\Bindings\XinputBinding.cpp" />
|
||||
<ClCompile Include="Input\DirectInput\Controller.cpp" />
|
||||
<ClCompile Include="Input\DirectInput\DirectInput.cpp" />
|
||||
<ClCompile Include="Input\DirectInput\DirectInputDevice.cpp" />
|
||||
<ClCompile Include="Input\DirectInput\DirectInputMouse.cpp" />
|
||||
<ClCompile Include="Input\DirectInput\Ds4\Ds4State.cpp" />
|
||||
<ClCompile Include="Input\DirectInput\Ds4\DualShock4.cpp" />
|
||||
<ClCompile Include="Input\Keyboard\Keyboard.cpp" />
|
||||
<ClCompile Include="Input\Keyboard\KeyboardState.cpp" />
|
||||
<ClCompile Include="Input\KeyConfig\Config.cpp" />
|
||||
<ClCompile Include="Input\KeyConfig\KeyString.cpp" />
|
||||
<ClCompile Include="Input\KeyConfig\KeyStringHash.cpp" />
|
||||
<ClCompile Include="Input\Mouse\Mouse.cpp" />
|
||||
<ClCompile Include="Input\Xinput\Xinput.cpp" />
|
||||
<ClCompile Include="Input\Xinput\XinputState.cpp" />
|
||||
<ClCompile Include="Utilities\Math.cpp" />
|
||||
<ClCompile Include="Utilities\Operations.cpp" />
|
||||
<ClCompile Include="Utilities\Stopwatch.cpp" />
|
||||
<ClCompile Include="Utilities\Vec2.cpp" />
|
||||
<ClCompile Include="Utilities\Vec3.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,336 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Constants.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\CameraController.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\ComponentsManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\CustomPlayerData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\DebugComponent.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\EmulatorComponent.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\FastLoader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\FrameRateManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\GameState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\PlayerData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\PlayerDataManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\StageManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\SysTimer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Input\InputBufferType.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Input\InputEmulator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Input\InputState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Input\JvsButtons.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Input\TouchPanelEmulator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Input\TouchPanelState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Input\TouchSliderEmulator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Input\TouchSliderState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FileSystem\ConfigFile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FileSystem\TextFile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Bindings\Binding.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Bindings\Ds4Binding.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Bindings\IInputBinding.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Bindings\KeyboardBinding.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Bindings\MouseBinding.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\DirectInput\Ds4\Ds4Button.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\DirectInput\Ds4\Ds4State.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\DirectInput\Ds4\DualShock4.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\DirectInput\Controller.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\DirectInput\DirectInput.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\DirectInput\DirectInputDevice.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\DirectInput\DirectInputMouse.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Keyboard\Keyboard.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Keyboard\KeyboardState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\KeyConfig\Config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\KeyConfig\KeyString.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\KeyConfig\KeyStringHash.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Mouse\Mouse.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Mouse\MouseState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\IInputDevice.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utilities\EnumBitwiseOperations.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utilities\Math.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utilities\Operations.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utilities\Stopwatch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utilities\Vec2.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utilities\Vec3.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\ScaleComponent.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Bindings\XinputBinding.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Xinput\Xinput.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Input\Xinput\XinputState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\FPSLimiter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\GameTargets\HoldState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\GameTargets\TargetHitStates.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\GameTargets\TargetInspector.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\GameTargets\TargetState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\GameTargets\TargetTypes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="framework.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\CameraController.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\ComponentsManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\DebugComponent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\EmulatorComponent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\FastLoader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\FrameRateManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\PlayerDataManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\StageManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\SysTimer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\Input\InputEmulator.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\Input\InputState.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\Input\TouchPanelEmulator.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\Input\TouchSliderEmulator.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\Input\TouchSliderState.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FileSystem\ConfigFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FileSystem\TextFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\Bindings\Binding.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\Bindings\Ds4Binding.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\Bindings\KeyboardBinding.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\Bindings\MouseBinding.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\DirectInput\Ds4\Ds4State.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\DirectInput\Ds4\DualShock4.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\DirectInput\Controller.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\DirectInput\DirectInput.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\DirectInput\DirectInputDevice.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\DirectInput\DirectInputMouse.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\Keyboard\Keyboard.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\Keyboard\KeyboardState.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\KeyConfig\Config.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\KeyConfig\KeyString.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\KeyConfig\KeyStringHash.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\Mouse\Mouse.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utilities\Math.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utilities\Operations.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utilities\Stopwatch.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utilities\Vec2.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utilities\Vec3.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\ScaleComponent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\Bindings\XinputBinding.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\Xinput\Xinput.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Input\Xinput\XinputState.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\FPSLimiter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\GameTargets\TargetInspector.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Utilities
|
||||
{
|
||||
template<class T> inline T operator~ (T a) { return (T)~(int)a; }
|
||||
template<class T> inline T operator| (T a, T b) { return (T)((int)a | (int)b); }
|
||||
template<class T> inline T operator& (T a, T b) { return (T)((int)a & (int)b); }
|
||||
template<class T> inline T operator^ (T a, T b) { return (T)((int)a ^ (int)b); }
|
||||
template<class T> inline T& operator|= (T& a, T b) { return (T&)((int&)a |= (int)b); }
|
||||
template<class T> inline T& operator&= (T& a, T b) { return (T&)((int&)a &= (int)b); }
|
||||
template<class T> inline T& operator^= (T& a, T b) { return (T&)((int&)a ^= (int)b); }
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#define _USE_MATH_DEFINES
|
||||
#include "Math.h"
|
||||
|
||||
namespace TLAC::Utilities
|
||||
{
|
||||
float ToDegrees(float radians)
|
||||
{
|
||||
return radians * (180.0f / M_PI);
|
||||
}
|
||||
|
||||
float ToRadians(float degrees)
|
||||
{
|
||||
return (degrees * M_PI) / 180.0f;
|
||||
}
|
||||
|
||||
Vec2 GetDirection(float degrees)
|
||||
{
|
||||
float radians = ToRadians(degrees);
|
||||
return Vec2(cos(radians), sin(radians));
|
||||
}
|
||||
|
||||
Vec2 PointFromAngle(float degrees, float distance)
|
||||
{
|
||||
float radians = ToRadians(degrees + 90.0f);
|
||||
return Vec2(-1 * std::cos(radians) * distance, -1 * std::sin(radians) * distance);
|
||||
}
|
||||
|
||||
float AngleFromPoints(Vec2 p0, Vec2 p1)
|
||||
{
|
||||
return (float)(std::atan2(p1.Y - p0.Y, p1.X - p0.X) * 180.0 / M_PI) + 90.0f;
|
||||
}
|
||||
|
||||
float ConvertRange(float originalStart, float originalEnd, float newStart, float newEnd, float value)
|
||||
{
|
||||
return newStart + ((value - originalStart) * (newEnd - newStart) / (originalEnd - originalStart));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <cmath>
|
||||
#include "Vec2.h"
|
||||
#include "Vec3.h"
|
||||
|
||||
namespace TLAC::Utilities
|
||||
{
|
||||
float ToDegrees(float radians);
|
||||
float ToRadians(float degrees);
|
||||
|
||||
Vec2 GetDirection(float degrees);
|
||||
Vec2 PointFromAngle(float degrees, float distance);
|
||||
float AngleFromPoints(Vec2 p0, Vec2 p1);
|
||||
float ConvertRange(float originalStart, float originalEnd, float newStart, float newEnd, float value);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
#include "Operations.h"
|
||||
|
||||
namespace TLAC::Utilities
|
||||
{
|
||||
std::vector<std::string> Split(const std::string& str, const std::string& delim)
|
||||
{
|
||||
std::vector<std::string> tokens;
|
||||
size_t prev = 0, pos = 0;
|
||||
do
|
||||
{
|
||||
pos = str.find(delim, prev);
|
||||
if (pos == std::string::npos)
|
||||
pos = str.length();
|
||||
|
||||
std::string token = str.substr(prev, pos - prev);
|
||||
|
||||
if (!token.empty())
|
||||
tokens.push_back(token);
|
||||
|
||||
prev = pos + delim.length();
|
||||
} while (pos < str.length() && prev < str.length());
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
void LeftTrim(std::string &s)
|
||||
{
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch)
|
||||
{
|
||||
return !std::isspace(ch);
|
||||
}));
|
||||
}
|
||||
|
||||
void RightTrim(std::string &s)
|
||||
{
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch)
|
||||
{
|
||||
return !std::isspace(ch);
|
||||
}).base(), s.end());
|
||||
}
|
||||
|
||||
void Trim(std::string &s)
|
||||
{
|
||||
s = trim(s);
|
||||
}
|
||||
|
||||
std::string trim(const std::string& str, const std::string& whitespace)
|
||||
{
|
||||
const size_t strBegin = str.find_first_not_of(whitespace);
|
||||
|
||||
if (strBegin == std::string::npos)
|
||||
return "";
|
||||
|
||||
const size_t strEnd = str.find_last_not_of(whitespace);
|
||||
const size_t strRange = strEnd - strBegin + 1;
|
||||
|
||||
return str.substr(strBegin, strRange);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <locale>
|
||||
#include <vector>
|
||||
|
||||
namespace TLAC::Utilities
|
||||
{
|
||||
std::vector<std::string> Split(const std::string& str, const std::string& delim);
|
||||
|
||||
void LeftTrim(std::string &s);
|
||||
void RightTrim(std::string &s);
|
||||
void Trim(std::string &s);
|
||||
|
||||
std::string trim(const std::string& str, const std::string& whitespace = " \t");
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "Stopwatch.h"
|
||||
|
||||
namespace TLAC::Utilities
|
||||
{
|
||||
Stopwatch::Stopwatch()
|
||||
{
|
||||
}
|
||||
|
||||
Stopwatch::~Stopwatch()
|
||||
{
|
||||
}
|
||||
|
||||
void Stopwatch::Start()
|
||||
{
|
||||
start = high_resolution_clock::now();
|
||||
}
|
||||
|
||||
float Stopwatch::Stop()
|
||||
{
|
||||
end = high_resolution_clock::now();
|
||||
return GetElapsed();
|
||||
}
|
||||
|
||||
float Stopwatch::Restart()
|
||||
{
|
||||
float elapsed = Stop();
|
||||
Start();
|
||||
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
float Stopwatch::GetElapsed()
|
||||
{
|
||||
return (float)(chrono::duration_cast<std::chrono::microseconds>(end - start).count() / TIME_FACTOR);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <chrono>
|
||||
|
||||
namespace chrono = std::chrono;
|
||||
|
||||
typedef chrono::time_point<chrono::steady_clock> steady_clock;
|
||||
typedef chrono::high_resolution_clock high_resolution_clock;
|
||||
|
||||
namespace TLAC::Utilities
|
||||
{
|
||||
class Stopwatch
|
||||
{
|
||||
const float TIME_FACTOR = 1000.0f;
|
||||
|
||||
public:
|
||||
Stopwatch();
|
||||
~Stopwatch();
|
||||
|
||||
void Start();
|
||||
float Stop();
|
||||
float Restart();
|
||||
|
||||
float GetElapsed();
|
||||
|
||||
private:
|
||||
steady_clock start;
|
||||
steady_clock end;
|
||||
};
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user