pause: move entire UI to in-engine sprites, make give up work, DrawText.h->Drawing.h, make framespeed modification robust

(code's still a mess tho)
This commit is contained in:
somewhatlurker
2019-10-20 17:35:51 +11:00
parent 10ac550fed
commit b0cefbe1d1
6 changed files with 166 additions and 137 deletions
@@ -65,17 +65,20 @@ namespace TLAC::Components
FontInfo*(*getFont)(FontInfo* fi, uint32_t id) = (FontInfo*(*)(FontInfo* fi, uint32_t id))0x140196510;
void(*fontSize)(FontInfo* fi, float width, float height) = (void(*)(FontInfo* fi, float width, float height))0x140199e60;
struct DrawTextParams
struct DrawParams
{
uint32_t textColour; // RGBA byte array?, so set as 0xAABBGGRR
uint32_t strokeColour; // ?? RGBA byte array?, so set as 0xAABBGGRR
uint32_t colour; // RGBA byte array?, so set as 0xAABBGGRR
uint32_t fillColour; // ?? RGBA byte array?, so set as 0xAABBGGRR
uint8_t unk08;
uint8_t padding09[0x3];
uint8_t unk09[0x3];
uint32_t unk0c;
uint32_t unk10;
uint32_t unk14;
uint32_t unk18;
uint64_t unk1c;
uint32_t layer; // 8 seems similar to default but higher
// 0x19 is startup screen
// I noticed some use different scaling
uint32_t unk20;
uint32_t unk24;
uint32_t unk28;
float xBegin; // ?
@@ -87,16 +90,17 @@ namespace TLAC::Components
FontInfo* font;
uint16_t unk50;
DrawTextParams(FontInfo* fi)
DrawParams(FontInfo* fi)
{
textColour = 0xffffffff;
strokeColour = 0xff808080;
colour = 0xffffffff;
fillColour = 0xff808080; // except it's not?
unk08 = 0;
unk0c = 0;
unk10 = 0;
unk14 = 0;
unk18 = 0;
unk1c = 0x7;
layer = 0x7;
unk20 = 0x0;
unk24 = 0xd;
unk28 = 0;
xBegin = 0;
@@ -108,9 +112,9 @@ namespace TLAC::Components
unk50 = 0x25a1;
}
DrawTextParams()
DrawParams()
{
DrawTextParams((FontInfo*)0x140eda860);
DrawParams((FontInfo*)0x140eda860);
}
};
@@ -176,20 +180,37 @@ namespace TLAC::Components
}
}; */
// flags aren't really known, but 1 == normal, 2 == right align?, 8 == centered
void drawText(DrawTextParams* dtParam, uint32_t flags, std::string str)
enum drawTextFlags : uint32_t
{
((void(*)(DrawTextParams*, uint32_t, const char*, int64_t))0x140198500)(dtParam, flags, str.c_str(), str.length());
DRAWTEXT_PARAGRAPH = 1, //?
DRAWTEXT_ALIGN_RIGHT = 2,
DRAWTEXT_ALIGN_CENTRE = 8,
DRAWTEXT_STROKE = 0x10000,
};
void drawText(DrawParams* dtParam, drawTextFlags flags, std::string str)
{
((void(*)(DrawParams*, uint32_t, const char*, int64_t))0x140198500)(dtParam, flags, str.c_str(), str.length());
}
void drawTextW(DrawTextParams* dtParam, uint32_t flags, std::wstring str)
void drawTextW(DrawParams* dtParam, drawTextFlags flags, std::wstring str)
{
const wchar_t* ptrs[2];
ptrs[0] = str.c_str();
ptrs[1] = (wchar_t*)((uint64_t)ptrs[0] + str.length() * 2);
((void(*)(DrawTextParams*, uint32_t, const wchar_t**))0x140198380)(dtParam, flags, &ptrs[0]);
((void(*)(DrawParams*, uint32_t, const wchar_t**))0x140198380)(dtParam, flags, &ptrs[0]);
}
//void(*drawTextW)(DrawTextParams* dtParam, uint32_t flags, MsStringW str) = (void(*)(DrawTextParams* dtParam, uint32_t flags, MsStringW str))0x140198380;
//void(*drawTextW)(DrawParams* dtParam, drawTextFlags flags, MsStringW str) = (void(*)(DrawParams* dtParam, drawTextFlags flags, MsStringW str))0x140198380;
struct RectangleBounds
{
float x;
float y;
float width;
float height;
};
void(*fillRectangle)(DrawParams* dtParam, RectangleBounds* rect) = (void(*)(DrawParams* dtParam, RectangleBounds* rect))0x140198d80;
void(*drawRectangle)(DrawParams* dtParam, RectangleBounds* rect) = (void(*)(DrawParams* dtParam, RectangleBounds* rect))0x140198320;
#pragma pack(pop)
}
@@ -1,17 +1,23 @@
#include "Pause.h"
#include "../Constants.h"
#include "GameState.h"
#include "DrawText.h"
#include "Drawing.h"
#include "Input/InputState.h"
#include "GL/glut.h"
#include "detours.h"
#include <windows.h>
#include <vector>
namespace TLAC::Components
{
bool Pause::isPaused = false;
bool Pause::giveUp = false;
bool Pause::showUI = true;
unsigned int Pause::menuPos = 0;
std::vector<uint8_t> Pause::origAetMovOp;
std::vector<uint8_t> Pause::origFramespeedOp;
std::vector<bool> Pause::streamPlayStates;
bool(*divaGiveUpFunc)(void*) = (bool(*)(void* cls))GIVEUP_FUNC_ADDRESS;
Pause::Pause()
{
@@ -30,6 +36,14 @@ namespace TLAC::Components
{
origAetMovOp.resize(8);
memcpy(&origAetMovOp[0], aetMovPatchAddress, 8);
origFramespeedOp.resize(4);
memcpy(&origFramespeedOp[0], framespeedPatchAddress, 4);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)divaGiveUpFunc, hookedGiveUpFunc);
DetourTransactionCommit();
}
void Pause::Update()
@@ -66,6 +80,7 @@ namespace TLAC::Components
if (inputState->Released.Buttons & JVS_CIRCLE)
menuItems[menuPos].second();
// swallow all button inputs if paused
inputState->Tapped.Buttons = JVS_NONE;
inputState->DoubleTapped.Buttons = JVS_NONE;
@@ -92,11 +107,69 @@ namespace TLAC::Components
{
if (isPaused && showUI)
{
// setup draw objects
FontInfo fontInfo(0x11);
fontInfo.setSize(menuTextSize, menuTextSize);
DrawTextParams dtParams(&fontInfo);
DrawParams dtParams(&fontInfo);
dtParams.layer = 0x19; // same as startup screen
dtParams.strokeColour = 0xff000000;
// bg rect
RectangleBounds rect;
rect = { 0, 0, 1280, 720 };
dtParams.colour = 0x80000000;
dtParams.fillColour = 0x80000000;
fillRectangle(&dtParams, &rect);
// pause icon
const int pauseWidth = 80;
const int pauseHeight = 110;
const int pauseGap = 20;
const int pausePosX = 32;
const int pausePosY = 32;
const int pausePartWidth = (pauseWidth - pauseGap) / 2;
const int pauseX1 = pausePosX;
const int pauseX2 = pausePosX + pausePartWidth + pauseGap;
const int pauseY1 = pausePosY;
dtParams.colour = 0x80ffffff;
dtParams.fillColour = 0x80ffffff;
rect = { pauseX1, pauseY1, pausePartWidth, pauseHeight };
fillRectangle(&dtParams, &rect);
rect = { pauseX2, pauseY1, pausePartWidth, pauseHeight };
fillRectangle(&dtParams, &rect);
// selection cursor
int selectBoxOrigin = menuY - menuItemHeight * (menuItems.size() / 2.0) - (menuItemHeight - menuTextSize) / 2;
int selectBoxPos = selectBoxOrigin + menuItemHeight * menuPos;
const float selectBoxWidth = 200;
const float selectBoxHeight = menuItemHeight;
const float selectBoxThickness = 2;
const float selectBoxX1 = menuX - selectBoxWidth / 2;
const float selectBoxX2 = selectBoxX1 + selectBoxWidth - selectBoxThickness;
const float selectBoxY1 = selectBoxPos;
const float selectBoxY2 = selectBoxY1 + selectBoxThickness;
const float selectBoxY3 = selectBoxY1 + selectBoxHeight - selectBoxThickness;
const float selectBoxSideHeight = selectBoxHeight - 2 * selectBoxThickness;
// dirty hack using fillRectangle to get thickness (idk how to set it or it isn't possible to with drawRectangle)
dtParams.colour = 0xc0ffff00;
dtParams.fillColour = 0xc0ffff00;
rect = { selectBoxX1, selectBoxY1, selectBoxWidth, selectBoxThickness }; // top
fillRectangle(&dtParams, &rect);
rect = { selectBoxX1, selectBoxY3, selectBoxWidth, selectBoxThickness }; // bottom
fillRectangle(&dtParams, &rect);
rect = { selectBoxX1, selectBoxY2, selectBoxThickness, selectBoxSideHeight };
fillRectangle(&dtParams, &rect);
rect = { selectBoxX2, selectBoxY2, selectBoxThickness, selectBoxSideHeight };
fillRectangle(&dtParams, &rect);
// menu
fontInfo.setSize(menuTextSize, menuTextSize);
dtParams.xBegin = menuX;
dtParams.yBegin = menuY - menuItemHeight * (menuItems.size() / 2.0);
@@ -106,126 +179,26 @@ namespace TLAC::Components
std::pair<std::string, void(*)()> &item = menuItems[i];
if (i == menuPos)
dtParams.textColour = 0xffffff00;
dtParams.colour = 0xffffff00;
else
dtParams.textColour = 0xffffffff;
dtParams.colour = 0xffffffff;
dtParams.xCurrent = dtParams.xBegin;
dtParams.yCurrent = dtParams.yBegin;
drawText(&dtParams, 8, item.first);
drawText(&dtParams, (drawTextFlags)(DRAWTEXT_ALIGN_CENTRE), item.first);
dtParams.yBegin += menuItemHeight;
}
// key legend
fontInfo.setSize(18, 18);
dtParams.xBegin = menuX;
dtParams.yBegin = 600;
dtParams.xCurrent = dtParams.xBegin;
dtParams.yCurrent = dtParams.yBegin;
dtParams.textColour = 0xffffffff;
drawTextW(&dtParams, 8, L"○:Select ×:Close L/R:Move □:Hide Menu");
}
}
void Pause::UpdatePostDraw()
{
if (isPaused && showUI)
{
// this isn't imgui code, but I probably wouldn't have gotten this working properly if I didn't reference it, so... umm... yeah lol
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
int width = glutGet(GLUT_WINDOW_WIDTH);
int height = glutGet(GLUT_WINDOW_HEIGHT);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, 1280, 720, 0, -1.0f, +1.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glBegin(GL_QUADS);
glBindTexture(GL_TEXTURE_2D, 0);
glColor4ub(0, 0, 0, 64);
glVertex2i(0, 0);
glVertex2i(1280, 0);
glVertex2i(1280, 720);
glVertex2i(0, 720);
const int pauseWidth = 80;
const int pauseHeight = 110;
const int pauseGap = 20;
const int pausePosX = 32;
const int pausePosY = 32;
const int pauseX1 = pausePosX;
const int pauseX2 = pauseX1 + (pauseWidth - pauseGap) / 2;
const int pauseX3 = pauseX2 + pauseGap;
const int pauseX4 = pauseX1 + pauseWidth;
const int pauseY1 = pausePosY;
const int pauseY2 = pauseY1 + pauseHeight;
glColor4ub(255, 255, 255, 127);
glVertex2i(pauseX1, pauseY1);
glVertex2i(pauseX2, pauseY1);
glVertex2i(pauseX2, pauseY2);
glVertex2i(pauseX1, pauseY2);
glVertex2i(pauseX3, pauseY1);
glVertex2i(pauseX4, pauseY1);
glVertex2i(pauseX4, pauseY2);
glVertex2i(pauseX3, pauseY2);
glEnd();
glBegin(GL_QUAD_STRIP);
int selectBoxOrigin = menuY - menuItemHeight * (menuItems.size() / 2.0) - (menuItemHeight - menuTextSize) / 2;
int selectBoxPos = selectBoxOrigin + menuItemHeight * menuPos;
const int selectBoxWidth = 200;
const int selectBoxHeight = menuItemHeight;
const int selectBoxThickness = 2;
const int selectBoxX1 = menuX - selectBoxWidth / 2;
const int selectBoxX4 = selectBoxX1 + selectBoxWidth;
const int selectBoxX2 = selectBoxX1 + selectBoxThickness;
const int selectBoxX3 = selectBoxX4 - selectBoxThickness;
const int selectBoxY1 = selectBoxPos;
const int selectBoxY4 = selectBoxY1 + selectBoxHeight;
const int selectBoxY2 = selectBoxY1 + selectBoxThickness;
const int selectBoxY3 = selectBoxY4 - selectBoxThickness;
glColor4ub(0, 255, 255, 127);
glVertex2i(selectBoxX2, selectBoxY2);
glVertex2i(selectBoxX1, selectBoxY1);
glVertex2i(selectBoxX3, selectBoxY2);
glVertex2i(selectBoxX4, selectBoxY1);
glVertex2i(selectBoxX3, selectBoxY3);
glVertex2i(selectBoxX4, selectBoxY4);
glVertex2i(selectBoxX2, selectBoxY3);
glVertex2i(selectBoxX1, selectBoxY4);
glVertex2i(selectBoxX2, selectBoxY2);
glVertex2i(selectBoxX1, selectBoxY1);
glEnd();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
dtParams.colour = 0xffffffff;
drawTextW(&dtParams, (drawTextFlags)(DRAWTEXT_ALIGN_CENTRE), L"○:Select ×:Close L/R:Move □:Hide Menu");
}
}
@@ -249,10 +222,10 @@ namespace TLAC::Components
if (pause)
{
*(float*)FRAME_SPEED_ADDRESS = 0.0f; // todo: hook getFrameSpeed so this can't be screwed up
((void(*)())DSC_PAUSE_FUNC_ADDRESS)();
InjectCode(aetMovPatchAddress, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 });
InjectCode(framespeedPatchAddress, { 0x0f, 0x57, 0xc0, 0xc3 }); // XORPS XMM0,XMM0; RET
for (int i = 0; i < nAudioStreams; i++)
{
@@ -264,13 +237,16 @@ namespace TLAC::Components
*playstate = 0;
}
menuPos = 0;
showUI = true;
}
else
{
*(float*)FRAME_SPEED_ADDRESS = 1.0f;
((void(*)())DSC_UNPAUSE_FUNC_ADDRESS)();
InjectCode(aetMovPatchAddress, origAetMovOp);
InjectCode(framespeedPatchAddress, origFramespeedOp);
for (int i = 0; i < nAudioStreams; i++)
{
@@ -283,6 +259,25 @@ namespace TLAC::Components
isPaused = pause;
}
bool Pause::hookedGiveUpFunc(void* cls)
{
if (giveUp)
{
giveUp = false;
setPaused(false);
return true;
}
else
{
if (divaGiveUpFunc(cls))
{
setPaused(false);
return true;
}
}
return false;
}
void Pause::InjectCode(void* address, const std::vector<uint8_t> data)
{
const size_t byteCount = data.size() * sizeof(uint8_t);
@@ -1,4 +1,5 @@
#pragma once
#include "../Constants.h"
#include "EmulatorComponent.h"
#include <vector>
@@ -16,31 +17,39 @@ namespace TLAC::Components
virtual void Update() override;
virtual void UpdatePostInput() override;
virtual void UpdateDrawSprites() override;
virtual void UpdatePostDraw() override;
static bool isPaused;
static bool giveUp;
static void setPaused(bool pause);
private:
// this is a mess of static so that menuItems can work
static bool isPauseKeyTapped();
static bool isUnpauseKeyTapped();
static void setPaused(bool pause);
static std::vector<bool> streamPlayStates;
static void InjectCode(void* address, const std::vector<uint8_t> data);
static std::vector<uint8_t> origAetMovOp;
static constexpr uint8_t* aetMovPatchAddress = (uint8_t*)0x1401703b3;
static std::vector<uint8_t> origFramespeedOp;
static constexpr uint8_t* framespeedPatchAddress = (uint8_t*)0x140192D50;
static bool hookedGiveUpFunc(void* cls);
static const int menuX = 640;
static const int menuY = 360;
static const int menuItemHeight = 36;
static const int menuTextSize = 24;
bool showUI = true;
unsigned int menuPos = 0;
static bool showUI;
static unsigned int menuPos;
static void unpause() { setPaused(false); };
static void giveup() { giveUp = true; };
std::vector<std::pair<std::string, void(*)()>> menuItems = {
std::pair<std::string, void(*)()>(std::string("RESUME"), &unpause),
//std::pair<std::string, void(*)()>(std::string("GIVE UP"), &unpause),
std::pair<std::string, void(*)()>(std::string("GIVE UP"), &giveup),
};
};
}
@@ -111,6 +111,10 @@ constexpr uint64_t DSC_START_SYS_TIME_ADDRESS_2 = 0x0000000140D0B568;
constexpr uint64_t DSC_PAUSE_FUNC_ADDRESS = 0x00000001401295C0;
constexpr uint64_t DSC_UNPAUSE_FUNC_ADDRESS = 0x0000000140129590;
constexpr uint64_t PV_GAME_BASE_ADDRESS = 0x0000000140C94380;
constexpr uint64_t GIVEUP_FUNC_ADDRESS = 0x000000014010EF00;
#define XINPUT_A 0x00
#define XINPUT_B 0x01
#define XINPUT_X 0x02
+1 -1
View File
@@ -111,7 +111,7 @@
<ClInclude Include="Components\ComponentsManager.h" />
<ClInclude Include="Components\CustomPlayerData.h" />
<ClInclude Include="Components\DebugComponent.h" />
<ClInclude Include="Components\DrawText.h" />
<ClInclude Include="Components\Drawing.h" />
<ClInclude Include="Components\EmulatorComponent.h" />
<ClInclude Include="Components\FastLoader.h" />
<ClInclude Include="Components\FrameRateManager.h" />
@@ -198,7 +198,7 @@
<ClInclude Include="Components\Pause.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Components\DrawText.h">
<ClInclude Include="Components\Drawing.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>