Files
PDModdingCommunity_PD-Loader/source-code/source/plugins/TLAC/dllmain.cpp
T

442 lines
12 KiB
C++

#include <iostream>
#include <vector>
#include <Windows.h>
#include <Dbt.h>
#include <stdio.h>
#include "Constants.h"
#include "framework.h"
#include "pluginconfig.h"
#include "Input/Mouse/Mouse.h"
#include "Input/Xinput/Xinput.h"
#include "Input/Keyboard/Keyboard.h"
#include "Input/DirectInput/DirectInput.h"
#include "Input/DirectInput/Ds4/DualShock4.h"
#include "Input/DirectInput/GenericUsb/GenericUsbInput.h"
#include "Input/Divaller/Divaller.h"
#include "Components/ComponentsManager.h"
#include <tchar.h>
#include <GL/freeglut.h>
#include <detours.h>
#include <fstream>
#pragma comment(lib, "detours.lib")
void(__cdecl* divaEngineUpdate)() = (void(__cdecl*)())0x14018CC40;
void(__cdecl* divaEngineStageDispShadow)() = (void(__cdecl*)())ENGINE_STAGE_DISP_SHADOW_ADDRESS;
LRESULT CALLBACK MessageWindowProcessCallback(HWND, UINT, WPARAM, LPARAM);
DWORD WINAPI WindowMessageDispatcher(LPVOID);
VOID RegisterMessageWindowClass();
struct
{
DWORD ID = NULL;
HANDLE Handle = NULL;
} MessageThread;
const wchar_t* MessageWindowClassName = TEXT("MessageWindowClass");
const wchar_t* MessageWindowName = TEXT("MessageWindowTitle");
namespace TLAC
{
Components::ComponentsManager ComponentsManager;
bool DeviceConnected = true;
bool FirstUpdateTick = true;
bool HasWindowFocus, HadWindowFocus;
void InitializeTick()
{
RegisterMessageWindowClass();
if ((MessageThread.Handle = CreateThread(0, 0, WindowMessageDispatcher, 0, 0, 0)) == NULL)
printf("[TLAC] InitializeTick(): CreateThread() Error: %d\n", GetLastError());
framework::DivaWindowHandle = WindowFromDC(wglGetCurrentDC());
HRESULT diInitResult = Input::InitializeDirectInput(framework::Module);
if (FAILED(diInitResult))
printf("[TLAC] InitializeTick(): Failed to initialize DirectInput. Error: 0x%08X\n", diInitResult);
ComponentsManager.Initialize();
}
void UpdateTick()
{
if (FirstUpdateTick)
{
FirstUpdateTick = false;
InitializeTick();
}
if (DeviceConnected)
{
DeviceConnected = false;
if (!Input::DualShock4::InstanceInitialized())
{
if (Input::DualShock4::TryInitializeInstance())
printf("[TLAC] UpdateTick(): DualShock4 connected and initialized\n");
}
if (!Input::GenericUsbInput::InstanceInitialized())
{
if (Input::GenericUsbInput::TryInitializeInstance())
printf("[TLAC] UpdateTick(): GenericUsbInput connected and initialized\n");
}
if (!Input::Divaller::InstanceInitialized())
{
if (Input::Divaller::TryInitializeInstance())
printf("[TLAC] UpdateTick(): Divaller connected and initialized\n");
}
}
ComponentsManager.Update();
HadWindowFocus = HasWindowFocus;
HasWindowFocus = framework::DivaWindowHandle == NULL || GetForegroundWindow() == framework::DivaWindowHandle;
if ((HasWindowFocus) && (!framework::inputDisable))
{
Input::Keyboard::GetInstance()->PollInput();
Input::Mouse::GetInstance()->PollInput();
Input::Xinput::GetInstance()->PollInput();
if (Input::DualShock4::GetInstance() != nullptr)
{
if (!Input::DualShock4::GetInstance()->PollInput())
{
Input::DualShock4::DeleteInstance();
printf("[TLAC] UpdateTick(): DualShock4 connection lost\n");
}
}
if (Input::GenericUsbInput::GetInstance() != nullptr)
{
if (!Input::GenericUsbInput::GetInstance()->PollInput())
{
Input::GenericUsbInput::DeleteInstance();
printf("[TLAC] UpdateTick(): GenericUsbInput connection lost\n");
}
}
if (Input::Divaller::GetInstance() != nullptr)
{
if (!Input::Divaller::GetInstance()->PollInput())
{
Input::Divaller::DeleteInstance();
printf("[TLAC] UpdateTick(): Divaller connection lost\n");
}
}
ComponentsManager.UpdateInput();
}
ComponentsManager.UpdatePostInput();
if ((framework::inputDisable))
{
Input::Keyboard::GetInstance()->PollInput();
Input::Mouse::GetInstance()->PollInput();
Input::Xinput::GetInstance()->PollInput();
if (Input::DualShock4::GetInstance() != nullptr)
{
if (!Input::DualShock4::GetInstance()->PollInput())
{
Input::DualShock4::DeleteInstance();
printf("[TLAC] UpdateTick(): DualShock4 connection lost\n");
}
}
if (Input::GenericUsbInput::GetInstance() != nullptr)
{
if (!Input::GenericUsbInput::GetInstance()->PollInput())
{
Input::GenericUsbInput::DeleteInstance();
printf("[TLAC] UpdateTick(): GenericUsbInput connection lost\n");
}
}
if (Input::Divaller::GetInstance() != nullptr)
{
if (!Input::Divaller::GetInstance()->PollInput())
{
Input::Divaller::DeleteInstance();
printf("[TLAC] UpdateTick(): Divaller connection lost\n");
}
}
}
if (HasWindowFocus && !HadWindowFocus)
ComponentsManager.OnFocusGain();
if (!HasWindowFocus && HadWindowFocus)
ComponentsManager.OnFocusLost();
}
void UpdateDraw2D()
{
ComponentsManager.UpdateDraw2D();
}
/*void InitializeExtraSettings()
{
const LPCTSTR RESOLUTION_CONFIG_FILE_NAME = _T(".\\config.ini");
auto nTAA = GetPrivateProfileIntW(L"graphics", L"taa", TRUE, RESOLUTION_CONFIG_FILE_NAME);
auto nMLAA = GetPrivateProfileIntW(L"graphics", L"mlaa", TRUE, RESOLUTION_CONFIG_FILE_NAME);
if (!nTAA)
{
{
// set TAA var (shouldn't be needed but whatever)
*(byte*)0x00000001411AB67C = 0;
}
{
// make constructor/init not set TAA
DWORD oldProtect, bck;
VirtualProtect((BYTE*)0x00000001404AB11D, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
*((byte*)0x00000001404AB11D + 0) = 0x90;
*((byte*)0x00000001404AB11D + 1) = 0x90;
*((byte*)0x00000001404AB11D + 2) = 0x90;
VirtualProtect((BYTE*)0x00000001404AB11D, 3, oldProtect, &bck);
}
{
// not sure, but it's somewhere in TaskPvGame init
// just make it set TAA to 0 instead of 1 to avoid possible issues
DWORD oldProtect, bck;
VirtualProtect((BYTE*)0x00000001401063CE, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
*((byte*)0x00000001401063CE + 0) = 0x00;
VirtualProtect((BYTE*)0x00000001401063CE, 1, oldProtect, &bck);
}
{
// prevent re-enabling after taking photos
DWORD oldProtect, bck;
VirtualProtect((BYTE*)0x000000014048FBA9, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
*((byte*)0x000000014048FBA9 + 0) = 0x00;
VirtualProtect((BYTE*)0x000000014048FBA9, 1, oldProtect, &bck);
}
printf("[TLAC] TAA disabled\n");
}
if (!nMLAA)
{
{
// set MLAA var (shouldn't be needed but whatever)
*(byte*)0x00000001411AB680 = 0;
}
{
// make constructor/init not set MLAA
DWORD oldProtect, bck;
VirtualProtect((BYTE*)0x00000001404AB11A, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
*((byte*)0x00000001404AB11A + 0) = 0x90;
*((byte*)0x00000001404AB11A + 1) = 0x90;
*((byte*)0x00000001404AB11A + 2) = 0x90;
VirtualProtect((BYTE*)0x00000001404AB11A, 3, oldProtect, &bck);
}
printf("[TLAC] MLAA disabled\n");
}
/*if (nMagFilter > -1)
{
{
// set MAG filter var
*(byte*)0x00000001411AC518 = nMagFilter;
}
{
// make constructor/init not set MAG filter (1)
DWORD oldProtect, bck;
VirtualProtect((BYTE*)0x00000001404AB13C, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
*((byte*)0x00000001404AB13C + 0) = 0x90;
*((byte*)0x00000001404AB13C + 1) = 0x90;
*((byte*)0x00000001404AB13C + 2) = 0x90;
*((byte*)0x00000001404AB13C + 3) = 0x90;
*((byte*)0x00000001404AB13C + 4) = 0x90;
*((byte*)0x00000001404AB13C + 5) = 0x90;
VirtualProtect((BYTE*)0x00000001404AB13C, 6, oldProtect, &bck);
}
{
// make constructor/init not set MAG filter (2)
DWORD oldProtect, bck;
VirtualProtect((BYTE*)0x00000001404A863F, 10, PAGE_EXECUTE_READWRITE, &oldProtect);
*((byte*)0x00000001404A863F + 0) = 0x90;
*((byte*)0x00000001404A863F + 1) = 0x90;
*((byte*)0x00000001404A863F + 2) = 0x90;
*((byte*)0x00000001404A863F + 3) = 0x90;
*((byte*)0x00000001404A863F + 4) = 0x90;
*((byte*)0x00000001404A863F + 5) = 0x90;
*((byte*)0x00000001404A863F + 6) = 0x90;
*((byte*)0x00000001404A863F + 7) = 0x90;
*((byte*)0x00000001404A863F + 8) = 0x90;
*((byte*)0x00000001404A863F + 9) = 0x90;
VirtualProtect((BYTE*)0x00000001404A863F, 10, oldProtect, &bck);
}
printf("[TLAC] MAG Filter set to %d\n", nMagFilter);
}*
}*/
void Dispose()
{
ComponentsManager.Dispose();
delete Input::Keyboard::GetInstance();
delete Input::Mouse::GetInstance();
delete Input::DualShock4::GetInstance();
delete Input::GenericUsbInput::GetInstance();
Input::DisposeDirectInput();
PostThreadMessage(MessageThread.ID, WM_QUIT, 0, 0);
}
}
DWORD WINAPI WindowMessageDispatcher(LPVOID lpParam)
{
HWND windowHandle = CreateWindowW(
MessageWindowClassName,
MessageWindowName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL,
TLAC::framework::Module,
NULL);
if (!windowHandle)
{
printf("[TLAC] WindowMessageDispatcher(): CreateWindowW() Error: %d\n", GetLastError());
return 1;
}
MessageThread.ID = GetCurrentThreadId();
MSG message;
DWORD returnValue;
printf("[TLAC] WindowMessageDispatcher(): Entering message loop...\n");
while (1)
{
returnValue = GetMessage(&message, NULL, 0, 0);
if (returnValue != -1)
{
TranslateMessage(&message);
DispatchMessage(&message);
}
else
{
printf("[TLAC] WindowMessageDispatcher(): GetMessage() Error: %d\n", returnValue);
}
}
DestroyWindow(windowHandle);
return 0;
}
BOOL RegisterDeviceInterface(HWND hWnd, HDEVNOTIFY* hDeviceNotify)
{
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter = {};
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
*hDeviceNotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
return *hDeviceNotify != NULL;
}
LRESULT CALLBACK MessageWindowProcessCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
HDEVNOTIFY hDevNotify = NULL;
if (!RegisterDeviceInterface(hWnd, &hDevNotify))
printf("[TLAC] MessageWindowProcessCallback(): RegisterDeviceInterface() Error: %d\n", GetLastError());
break;
}
case WM_DEVICECHANGE:
{
switch (wParam)
{
case DBT_DEVICEARRIVAL:
TLAC::DeviceConnected = true;
break;
default:
break;
}
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
VOID RegisterMessageWindowClass()
{
WNDCLASS windowClass = { };
windowClass.lpfnWndProc = MessageWindowProcessCallback;
windowClass.hInstance = TLAC::framework::Module;
windowClass.lpszClassName = MessageWindowClassName;
RegisterClass(&windowClass);
}
void hookedEngineUpdate()
{
TLAC::UpdateTick();
//divaEngineUpdate();
}
void hookedEngineStageDispShadow()
{
divaEngineStageDispShadow();
TLAC::UpdateDraw2D();
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
HWND consoleHandle = GetConsoleWindow();
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
// Are you a dev and want to debug? Want to always be able to watch the console upon game initialization? Comment this.
ShowWindow(consoleHandle, SW_HIDE);
printf("[TLAC] DllMain(): Installing hooks...\n");
//InstallHook((void*)ENGINE_UPDATE_HOOK_TARGET_ADDRESS, (void*)UpdateTick, 0xE);
DisableThreadLibraryCalls(hModule);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)divaEngineUpdate, hookedEngineUpdate);
DetourTransactionCommit();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)divaEngineStageDispShadow, hookedEngineStageDispShadow);
DetourTransactionCommit();
//TLAC::InitializeExtraSettings();
TLAC::framework::Module = hModule;
break;
case DLL_PROCESS_DETACH:
TLAC::Dispose();
break;
}
return TRUE;
}