Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix various problems for Len'en series #5

Merged
merged 7 commits into from
Aug 13, 2024
8 changes: 7 additions & 1 deletion Common/Helper.Graphics.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include "framework.h"
#include "macro.h"
#include "Helper.Graphics.h"
#include "Helper.h"

namespace common::helper::graphics {
Dx11BackupState SaveDx11State(IDXGISwapChain* swapChain, ID3D11DeviceContext* context) {
Dx11BackupState state{};
context->OMGetRenderTargets(ARRAYSIZE(state.renderTargetViews), state.renderTargetViews, &state.depthStencilView);
context->IAGetIndexBuffer(&state.indexBuffer, &state.indexBufferFormat, &state.indexBufferOffset);
state.nViewPorts = ARRAYSIZE(state.viewPorts);
DXGI_SWAP_CHAIN_DESC desc{};
Expand All @@ -24,9 +26,13 @@ namespace common::helper::graphics {
}

void LoadDx11State(ID3D11DeviceContext* context, Dx11BackupState& state) {
context->OMSetRenderTargets(ARRAYSIZE(state.renderTargetViews), state.renderTargetViews, state.depthStencilView);
for (auto renderTargetView : state.renderTargetViews)
helper::SafeRelease(renderTargetView);
helper::SafeRelease(state.depthStencilView);
context->IASetIndexBuffer(state.indexBuffer, state.indexBufferFormat, state.indexBufferOffset);
helper::SafeRelease(state.indexBuffer);
if (state.needRestoreViewport)
context->RSSetViewports(state.nViewPorts, state.viewPorts);
SAFE_RELEASE(state.indexBuffer);
}
}
14 changes: 8 additions & 6 deletions Common/Helper.Graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

namespace common::helper::graphics {
struct Dx11BackupState {
ID3D11Buffer* indexBuffer;
DXGI_FORMAT indexBufferFormat;
UINT indexBufferOffset;
D3D11_VIEWPORT viewPorts[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
UINT nViewPorts;
bool needRestoreViewport;
ID3D11RenderTargetView* renderTargetViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
ID3D11DepthStencilView* depthStencilView;
ID3D11Buffer* indexBuffer;
DXGI_FORMAT indexBufferFormat;
UINT indexBufferOffset;
D3D11_VIEWPORT viewPorts[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
UINT nViewPorts;
bool needRestoreViewport;
};

Dx11BackupState SaveDx11State(IDXGISwapChain* swapChain, ID3D11DeviceContext* context);
Expand Down
29 changes: 29 additions & 0 deletions Common/Helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,4 +299,33 @@ namespace common::helper {
WM_KEYDOWN, [](auto _wParam, auto _vkCode) { return _wParam == _vkCode; }, nil
);
}

// If facility of hresult is win32 then return the lower 16bit, else return unchanged
HRESULT Win32FromHResult(HRESULT hr) {
if (SUCCEEDED(hr))
return ERROR_SUCCESS;
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
return HRESULT_CODE(hr);
return hr;
}

void SafeFreeLib(HMODULE& hLibModule) {
if (hLibModule) {
FreeLibrary(hLibModule);
hLibModule = nil;
}
}

wstring ExpandEnvStr(const wchar_t* str) {
auto chrCount = ExpandEnvironmentStringsW(str, nil, 0);
if (chrCount == 0)
return wstring();
wstring output(chrCount - 1, '\0');
ExpandEnvironmentStringsW(str, output.data(), chrCount);
return output;
}

wstring ExpandEnvStr(const wstring& str) {
return ExpandEnvStr(str.c_str());
}
}
25 changes: 25 additions & 0 deletions Common/Helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,29 @@ namespace common::helper {
BYTE MapVk2Dik(BYTE vkCode, PBYTE mappingTable, BYTE defaultDikCode = 0);
BYTE NormalizeLeftRightVkCode(BYTE vkCode);
VkCodeMessage ConvertVkCodeToMessage(BYTE vkCode);
HRESULT Win32FromHResult(HRESULT hr);
template<typename ComPtrT>
void SafeRelease(ComPtrT& p) {
if (p) {
p->Release();
p = nil;
}
}
template<typename PtrT>
void SafeDelete(PtrT& a) {
if (a) {
delete a;
a = nil;
}
}
template<typename PtrT>
void SafeDeleteArr(PtrT& arr) {
if (arr) {
delete[] arr;
arr = nil;
}
}
void SafeFreeLib(HMODULE& hLibModule);
std::wstring ExpandEnvStr(const wchar_t* str);
std::wstring ExpandEnvStr(const std::wstring& str);
}
4 changes: 3 additions & 1 deletion Common/NeoLua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
#include "Log.h"
#include "Variables.h"
#include "LuaApi.h"
#include "Helper.h"

namespace note = common::log;
namespace helper = common::helper;

using namespace std;
using namespace Microsoft::WRL;
Expand Down Expand Up @@ -50,7 +52,7 @@ namespace common::neolua {
for (auto i = 0; i < 5; i++) {
// It seems that EnumerateLoadedRuntimes call CreateToolhelp32Snapshot internally, which can fail with ERROR_BAD_LENGTH for no obvious reason. So, just retry if that's the case.
result = metaHost->EnumerateLoadedRuntimes(GetCurrentProcess(), &enumerator);
if (WIN32_FROM_HRESULT(result) != ERROR_BAD_LENGTH)
if (helper::Win32FromHResult(result) != ERROR_BAD_LENGTH)
break;
}
if (FAILED(result)) {
Expand Down
12 changes: 1 addition & 11 deletions Common/macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,4 @@ inline EnumName operator |=(EnumName& a, const EnumName b) { \
return b; \
} \
enum class EnumName: EnumType {
#define END_FLAG_ENUM() };

// If facility of hresult is win32 then return the lower 16bit, else return unchanged
#define WIN32_FROM_HRESULT(hr) \
(SUCCEEDED(hr) ? ERROR_SUCCESS : \
(HRESULT_FACILITY(hr) == FACILITY_WIN32 ? HRESULT_CODE(hr) : (hr)))

#define SAFE_RELEASE(p) if ((p)) { (p)->Release(); (p) = 0; }0
#define SAFE_DELETE(a) if ((a)) { delete (a); (a) = nil; }0
#define SAFE_DELETE_ARR(a) if ((a)) { delete[] (a); (a) = nil; }0
#define SAFE_FREE_LIB(h) if ((h)) { FreeLibrary(h); h = nil; }0
#define END_FLAG_ENUM() };
2 changes: 1 addition & 1 deletion ThMouseX/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static bool IniTryGetWstrPath(const inipp::Ini<char>::Section& section, WCHAR(&o
MessageBoxA(nil, msg.data, APP_NAME, MB_OK | MB_ICONERROR);
return false;
}
auto wStr = encoding::ConvertToUtf16(input.c_str());
auto wStr = helper::ExpandEnvStr(encoding::ConvertToUtf16(input.c_str()));
GetFullPathNameW(wStr.c_str(), output_len, output, nil);
}
return true;
Expand Down
56 changes: 31 additions & 25 deletions ThMouseX/Direct3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ using ID3D11RenderTargetViewPtr = ID3D11RenderTargetView*;
using SpriteBatchPtr = SpriteBatch*;
using ID3D11PixelShaderPtr = ID3D11PixelShader*;
using ID3D11ShaderResourceViewPtr = ID3D11ShaderResourceView*;
using ID3D11DepthStencilViewPtr = ID3D11DepthStencilView*;

namespace core::directx11 {
HRESULT WINAPI D3DResizeBuffers(IDXGISwapChain* swapChain, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags);
Expand Down Expand Up @@ -95,22 +96,28 @@ namespace core::directx11 {
float imGuiMousePosScaleX = 1.f;
float imGuiMousePosScaleY = 1.f;

HMODULE d3d11;

static void CleanUp(bool forReal = false) {
ImGui_ImplDX11_InvalidateDeviceObjects();
SAFE_RELEASE(pixelShader);
SAFE_DELETE(spriteBatch);
SAFE_RELEASE(cursorTexture);
SAFE_RELEASE(renderTargetView);
SAFE_RELEASE(context);
SAFE_RELEASE(device);
if (imGuiPrepared)
ImGui_ImplDX11_InvalidateDeviceObjects();
helper::SafeRelease(pixelShader);
helper::SafeDelete(spriteBatch);
helper::SafeRelease(cursorTexture);
helper::SafeRelease(renderTargetView);
helper::SafeRelease(context);
helper::SafeRelease(device);
firstStepPrepared = false;
measurementPrepared = false;
cursorStatePrepared = false;
imGuiConfigured = false;
if (forReal && imGuiPrepared) {
ImGui_ImplDX11_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
if (forReal) {
if (imGuiPrepared) {
ImGui_ImplDX11_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
}
helper::SafeFreeLib(d3d11);
}
}

Expand All @@ -123,12 +130,11 @@ namespace core::directx11 {
void Initialize() {
static bool initialized = false;
static mutex mtx;
HMODULE d3d11{};
{
const lock_guard lock(mtx);
if (initialized)
return;
d3d11 = GetModuleHandleW((g_systemDirPath + wstring(L"\\d3d11.dll")).c_str());
GetModuleHandleExW(0, (g_systemDirPath + wstring(L"\\d3d11.dll")).c_str(), &d3d11);
if (!d3d11)
return;
initialized = true;
Expand Down Expand Up @@ -190,20 +196,28 @@ namespace core::directx11 {
return;
}

device->GetImmediateContext(&context);

DXGI_SWAP_CHAIN_DESC desc{};
rs = swapChain->GetDesc(&desc);
if (FAILED(rs)) {
note::DxErrToFile(TAG "PrepareFirstStep: swapChain->GetDesc failed", rs);
return;
}

ComPtr<ID3D11Texture2D> pBackBuffer;
rs = swapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
if (FAILED(rs)) {
note::DxErrToFile(TAG "PrepareFirstStep: swapChain->GetBuffer failed", rs);
return;
}

rs = device->CreateRenderTargetView(pBackBuffer.Get(), nil, &renderTargetView);
if (FAILED(rs)) {
note::DxErrToFile(TAG "PrepareFirstStep: device->CreateRenderTargetView failed", rs);
return;
}

device->GetImmediateContext(&context);

spriteBatch = new SpriteBatch(context);

rs = device->CreatePixelShader(additiveToneShaderBlob, ARRAYSIZE(additiveToneShaderBlob), nil, &pixelShader);
Expand All @@ -212,12 +226,6 @@ namespace core::directx11 {
return;
}

DXGI_SWAP_CHAIN_DESC desc{};
rs = swapChain->GetDesc(&desc);
if (FAILED(rs)) {
note::DxErrToFile(TAG "PrepareFirstStep: swapChain->GetDesc failed", rs);
return;
}
g_hFocusWindow = desc.OutputWindow;
g_isMinimized = IsIconic(g_hFocusWindow);

Expand Down Expand Up @@ -312,8 +320,6 @@ namespace core::directx11 {
if (!cursorTexture || !spriteBatch || !renderTargetView || !device || !context)
return;

auto dx11State = graphics::SaveDx11State(swapChain, context);

// scale mouse cursor's position from screen coordinate to D3D coordinate
auto pointerPosition = helper::GetPointerPosition();
XMVECTOR cursorPositionD3D = XMVECTORF32{ float(pointerPosition.x), float(pointerPosition.y) };
Expand Down Expand Up @@ -345,8 +351,6 @@ namespace core::directx11 {
auto color = g_inputEnabled ? ToneColor(tone) : RGBA(255, 200, 200, 128);
spriteBatch->Draw(cursorTexture, cursorPositionD3D, nil, color, 0, cursorPivot, 1, SpriteEffects_None);
spriteBatch->End();

graphics::LoadDx11State(context, dx11State);
}

static void PrepareImGui() {
Expand Down Expand Up @@ -404,8 +408,10 @@ namespace core::directx11 {
PrepareCursorState(swapChain);
PrepareImGui();
ConfigureImGui(swapChain);
auto dx11State = graphics::SaveDx11State(swapChain, context);
RenderCursor(swapChain);
RenderImGui(swapChain);
graphics::LoadDx11State(context, dx11State);
callbackstore::TriggerPostRenderCallbacks();
return OriPresent(swapChain, SyncInterval, Flags);
}
Expand Down
23 changes: 14 additions & 9 deletions ThMouseX/Direct3D8.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,24 @@ namespace core::directx8 {
float imGuiMousePosScaleX = 1.f;
float imGuiMousePosScaleY = 1.f;

HMODULE d3d8;

static void CleanUp(bool forReal = false) {
ImGui_ImplDX8_InvalidateDeviceObjects();
SAFE_RELEASE(cursorSprite);
SAFE_RELEASE(cursorTexture);
if (imGuiPrepared)
ImGui_ImplDX8_InvalidateDeviceObjects();
helper::SafeRelease(cursorSprite);
helper::SafeRelease(cursorTexture);
firstStepPrepared = false;
measurementPrepared = false;
cursorStatePrepared = false;
imGuiConfigured = false;
if (forReal && imGuiPrepared) {
ImGui_ImplDX8_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
if (forReal) {
if (imGuiPrepared) {
ImGui_ImplDX8_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
}
helper::SafeFreeLib(d3d8);
}
}

Expand All @@ -114,12 +120,11 @@ namespace core::directx8 {
void Initialize() {
static bool initialized = false;
static mutex mtx;
HMODULE d3d8{};
{
const lock_guard lock(mtx);
if (initialized)
return;
d3d8 = GetModuleHandleW((g_systemDirPath + wstring(L"\\d3d8.dll")).c_str());
GetModuleHandleExW(0, (g_systemDirPath + wstring(L"\\d3d8.dll")).c_str(), &d3d8);
if (!d3d8)
return;
initialized = true;
Expand Down
17 changes: 9 additions & 8 deletions ThMouseX/Direct3D9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,18 @@ namespace core::directx9 {
float imGuiMousePosScaleX = 1.f;
float imGuiMousePosScaleY = 1.f;

// d3dx9_43.dll
HMODULE d3d9;
HMODULE d3dx9_43;
bool d3dx9_43_failed = false;
decltype(&D3DXCreateSprite) _D3DXCreateSprite;
decltype(&D3DXCreateTextureFromFileW) _D3DXCreateTextureFromFileW;
decltype(&D3DXMatrixTransformation2D) _D3DXMatrixTransformation2D;

void CleanUp(bool forReal = false) {
ImGui_ImplDX9_InvalidateDeviceObjects();
SAFE_RELEASE(cursorSprite);
SAFE_RELEASE(cursorTexture);
static void CleanUp(bool forReal = false) {
if (imGuiPrepared)
ImGui_ImplDX9_InvalidateDeviceObjects();
helper::SafeRelease(cursorSprite);
helper::SafeRelease(cursorTexture);
firstStepPrepared = false;
measurementPrepared = false;
cursorStatePrepared = false;
Expand All @@ -104,7 +105,8 @@ namespace core::directx9 {
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
}
SAFE_FREE_LIB(d3dx9_43);
helper::SafeFreeLib(d3dx9_43);
helper::SafeFreeLib(d3d9);
}
}

Expand All @@ -122,12 +124,11 @@ namespace core::directx9 {
void Initialize() {
static bool initialized = false;
static mutex mtx;
HMODULE d3d9{};
{
const lock_guard lock(mtx);
if (initialized)
return;
d3d9 = GetModuleHandleW((g_systemDirPath + wstring(L"\\d3d9.dll")).c_str());
GetModuleHandleExW(0, (g_systemDirPath + wstring(L"\\d3d9.dll")).c_str(), &d3d9);
if (!d3d9)
return;
initialized = true;
Expand Down
Loading