Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions SharpPluginLoader.Core/InternalCalls.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

using SharpPluginLoader.Core.Resources;
using SharpPluginLoader.Core.Resources.Animation;
using SharpPluginLoader.Core.Rendering;

namespace SharpPluginLoader.Core
{
Expand Down Expand Up @@ -41,6 +42,8 @@ internal static unsafe class InternalCalls
public static delegate* unmanaged<nint, void> UnloadTexturePtr;
public static delegate* unmanaged<nint, nint> RegisterTexturePtr;

public static delegate* unmanaged<LoaderGuiConfig*, void> SaveGuiConfigPtr;

public static delegate* unmanaged<string, nint> GetRepositoryAddressPtr;
public static delegate* unmanaged<sbyte*> GetGameRevisionPtr;
#pragma warning restore CS0649
Expand Down Expand Up @@ -118,6 +121,8 @@ public static bool TimelineTrack(string label, Span<float> keyFrames, out int se

public static nint RegisterTexture(nint texture) => RegisterTexturePtr(texture);

public static void SaveGuiConfig(LoaderGuiConfig* config) => SaveGuiConfigPtr(config);

public static nint GetRepositoryAddress(string name) => GetRepositoryAddressPtr(name);

public static string GetGameRevision()
Expand Down
109 changes: 89 additions & 20 deletions SharpPluginLoader.Core/Rendering/Renderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,22 +198,33 @@ internal static unsafe void ResolveCustomFonts()
_fontsSubmitted = true;
}

private static unsafe void SaveConfig()
{
LoaderGuiConfig* config = MemoryUtil.Alloc<LoaderGuiConfig>();
config->MenuKey = Utf8StringMarshaller.ConvertToUnmanaged(_menuKey.ToString());
var io = ImGui.GetIO();
config->KeyboardNavigation = (io.ConfigFlags & ImGuiConfigFlags.NavEnableKeyboard) != 0;
config->FontScale = io.FontGlobalScale;
config->WindowTransparency = _baseAlpha;
InternalCalls.SaveGuiConfig(config);
Utf8StringMarshaller.Free(config->MenuKey);
MemoryUtil.Free(config);
}

[UnmanagedCallersOnly]
internal static nint Initialize(Size viewportSize, Size windowSize, byte d3d12, nint menuKey)
internal static unsafe nint Initialize(Size viewportSize, Size windowSize, byte d3d12, LoaderGuiConfig* config)
{
IsDirectX12 = d3d12 != 0;

if (menuKey != 0)
string? keyStr = Utf8StringMarshaller.ConvertToManaged(config->MenuKey);
if (keyStr != null && Enum.TryParse<Key>(keyStr, out var key))
{
var keyStr = MemoryUtil.ReadString(menuKey);
if (Enum.TryParse<Key>(keyStr, out var key))
{
_menuKey = key;
}
else
{
Log.Warn($"Invalid menu key: {keyStr}, falling back to {DefaultMenuKey}");
}
_menuKey = key;
_menuKeyStr = keyStr;
}
else
{
Log.Warn($"Invalid menu key: {keyStr}, falling back to {DefaultMenuKey}");
}

_viewportSize = new Vector2(viewportSize.Width, viewportSize.Height);
Expand Down Expand Up @@ -241,6 +252,13 @@ Initializing Renderer with
// Currently causes a freeze when dragging a window outside of the main window.
// Most likely the WndProc doesn't process events anymore which causes windows to think it's frozen.
// io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable;
if (config->KeyboardNavigation)
{
io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard;
}

io.FontGlobalScale = config->FontScale;
_baseAlpha = config->WindowTransparency;

SetupImGuiStyle();

Expand Down Expand Up @@ -322,6 +340,11 @@ Initializing Renderer with
if (Input.IsDown(_menuKey))
{
_showMenu = !_showMenu;
if (!_showMenu && _optionsChanged)
{
SaveConfig();
_optionsChanged = false;
}
_waitForRelease = _menuKey;
}
#if DEBUG
Expand Down Expand Up @@ -387,7 +410,7 @@ internal static unsafe nint ImGuiRender()
io.DisplaySize = _viewportSize;

if (_showMenu)
ImGui.GetStyle().Alpha = anyFocused ? 1.0f : 0.5f;
ImGui.GetStyle().Alpha = anyFocused ? _baseAlpha : Math.Max(_baseAlpha - 0.5f, 0.25f);

ImGui.NewFrame();
if (_showMenu)
Expand All @@ -398,6 +421,25 @@ internal static unsafe nint ImGuiRender()
{
if (ImGui.BeginMenu("Options"))
{
Key parsedKey;
bool typedKeyValid = Enum.TryParse<Key>(_menuKeyStr, true, out parsedKey);
if (!typedKeyValid)
{
ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0000FF);
}
if (ImGui.InputText("Menu Key", ref _menuKeyStr, 12, ImGuiInputTextFlags.EnterReturnsTrue))
{
if (Enum.TryParse<Key>(_menuKeyStr, true, out parsedKey))
{
_menuKey = parsedKey;
_optionsChanged = true;
}
}
if (!typedKeyValid)
{
ImGui.PopStyleColor();
}

bool keyboardNav = (io.ConfigFlags & ImGuiConfigFlags.NavEnableKeyboard) != 0;
if (ImGui.Checkbox("Keyboard Navigation", ref keyboardNav))
{
Expand All @@ -409,6 +451,22 @@ internal static unsafe nint ImGuiRender()
{
io.ConfigFlags &= ~ImGuiConfigFlags.NavEnableKeyboard;
}
_optionsChanged = true;
}

if (ImGui.SliderFloat("Font Scale",
ref io.FontGlobalScale,
0.5f, 2.0f, null, ImGuiSliderFlags.NoRoundToFormat))
{
_optionsChanged = true;
}

if (ImGui.SliderFloat("Window Transparency",
ref _baseAlpha,
0.25f, 1.0f, null, ImGuiSliderFlags.NoRoundToFormat))
{
ImGui.GetStyle().DisabledAlpha = _baseAlpha;
_optionsChanged = true;
}

ImGui.Checkbox("Draw Primitives as Wireframe",
Expand All @@ -418,16 +476,15 @@ internal static unsafe nint ImGuiRender()
ref MemoryUtil.AsRef(_renderingOptionPointers.LineThickness),
1.0f, 10.0f);

ImGui.SliderFloat("Font Scale", ref io.FontGlobalScale, 0.5f, 2.0f);

ImGui.EndMenu();
}
ImGui.EndMenuBar();

if (ImGui.IsItemDeactivated())
else if (_optionsChanged)
{
// TODO: Save settings
SaveConfig();
_optionsChanged = false;
}

ImGui.EndMenuBar();
}

foreach (var plugin in PluginManager.Instance.GetPlugins(pluginData => pluginData.OnImGuiRender))
Expand Down Expand Up @@ -485,8 +542,8 @@ private static void SetupImGuiStyle()
{
var style = ImGui.GetStyle();

style.Alpha = 1.0f;
style.DisabledAlpha = 1.0f;
style.Alpha = _baseAlpha;
style.DisabledAlpha = _baseAlpha;
style.WindowPadding = new Vector2(12.0f, 12.0f);
style.WindowRounding = 2.0f;
style.WindowBorderSize = 1.0f;
Expand Down Expand Up @@ -598,11 +655,14 @@ private static nint GetCursorPositionHook(nint app, out Point pos)
private static Key? _waitForRelease = null;
private static bool _showMenu = false;
private static Key _menuKey = DefaultMenuKey;
private static string _menuKeyStr = DefaultMenuKey.ToString();
#if DEBUG
private static bool _showDemo = false;
private static Key _demoKey = DefaultDemoKey;
#endif
private static float _baseAlpha = 1.0f;
private static RenderingOptionPointers _renderingOptionPointers;
private static bool _optionsChanged = false;
private static Vector2 _viewportSize;
private static Vector2 _windowSize;
private static Vector2 _mousePos;
Expand Down Expand Up @@ -646,4 +706,13 @@ internal unsafe struct CustomFontNative
public ushort* GlyphRanges;
public ImFont* Font;
}

[StructLayout(LayoutKind.Sequential)]
public unsafe struct LoaderGuiConfig
{
public byte* MenuKey;
public bool KeyboardNavigation;
public float FontScale;
public float WindowTransparency;
}
}
8 changes: 4 additions & 4 deletions mhw-cs-plugin-loader/AddressRepository.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@
#include "Config.h"
#include "Log.h"
#include "PatternScan.h"
#include "Json.h"

#include <nlohmann/json.hpp>
#include "picosha2/picosha2.h"
using json = nlohmann::json;

std::unordered_map<std::string, uintptr_t> scan_for_address_records(json records_json);
std::string get_game_revision();
Expand All @@ -25,8 +24,9 @@ void AddressRepository::initialize() {
auto& contents_raw = address_records->Contents;
std::string contents(contents_raw.begin(), contents_raw.end());

// Parse the json
json records_json = json::parse(contents);
// Parse the json.
json records_json = json::parse(contents, nullptr, false);
assert(!records_json.is_discarded());

// Get game version/revision and hash of the current address records json file.
std::string game_revision = get_game_revision();
Expand Down
2 changes: 1 addition & 1 deletion mhw-cs-plugin-loader/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,4 @@ static constexpr const char* SPL_DEFAULT_CHUNK_PATH = "nativePC/plugins/CSharp/L

// The path of the address repository cache file
static constexpr const char* SPL_ADDRESS_REPOSITORY_CACHE_PATH = "nativePC/plugins/CSharp/Loader/NativeAddressCache.json";
}
}
8 changes: 5 additions & 3 deletions mhw-cs-plugin-loader/D3DModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void D3DModule::initialize(CoreClr* coreclr) {
L"SharpPluginLoader.Core.Rendering.Renderer",
L"ImGuiRender"
);
m_core_initialize_imgui = coreclr->get_method<ImGuiContext*(MtSize, MtSize, bool, const char*)>(
m_core_initialize_imgui = coreclr->get_method<ImGuiContext*(MtSize, MtSize, bool, const preloader::LoaderGuiConfig*)>(
config::SPL_CORE_ASSEMBLY_NAME,
L"SharpPluginLoader.Core.Rendering.Renderer",
L"Initialize"
Expand All @@ -71,6 +71,8 @@ void D3DModule::initialize(CoreClr* coreclr) {
coreclr->add_internal_call("LoadTexture", (void*)load_texture);
coreclr->add_internal_call("UnloadTexture", (void*)unload_texture);
coreclr->add_internal_call("RegisterTexture", (void*)register_texture);

coreclr->add_internal_call("SaveGuiConfig", preloader::LoaderConfig::save_gui_config);
}

void D3DModule::shutdown() {
Expand Down Expand Up @@ -493,7 +495,7 @@ void D3DModule::d3d12_initialize_imgui(IDXGISwapChain* swap_chain) {
};

const auto& config = preloader::LoaderConfig::get();
const auto context = m_core_initialize_imgui(viewport_size, window_size, true, config.get_menu_key().c_str());
const auto context = m_core_initialize_imgui(viewport_size, window_size, true, config.get_gui_config());

igSetCurrentContext(context);

Expand Down Expand Up @@ -626,7 +628,7 @@ void D3DModule::d3d11_initialize_imgui(IDXGISwapChain* swap_chain) {
};

const auto& config = preloader::LoaderConfig::get();
const auto context = m_core_initialize_imgui(viewport_size, window_size, false, config.get_menu_key().c_str());
const auto context = m_core_initialize_imgui(viewport_size, window_size, false, config.get_gui_config());
igSetCurrentContext(context);

imgui_load_fonts();
Expand Down
3 changes: 2 additions & 1 deletion mhw-cs-plugin-loader/D3DModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "NativeModule.h"
#include "TextureManager.h"
#include "PrimitiveRenderingModule.h"
#include "LoaderConfig.h"

#include <d3d11.h>
#include <d3d12.h>
Expand Down Expand Up @@ -121,7 +122,7 @@ class D3DModule final : public NativeModule {
HWND m_temp_window = nullptr;
WNDCLASSEX* m_temp_window_class = nullptr;

ImGuiContext*(*m_core_initialize_imgui)(MtSize viewport_size, MtSize window_size, bool d3d12, const char* menu_key) = nullptr;
ImGuiContext*(*m_core_initialize_imgui)(MtSize viewport_size, MtSize window_size, bool d3d12, const preloader::LoaderGuiConfig* config) = nullptr;
ImDrawData*(*m_core_imgui_render)() = nullptr;
void(*m_core_render)() = nullptr;
int(*m_core_get_custom_fonts)(CustomFont** out_fonts) = nullptr;
Expand Down
6 changes: 6 additions & 0 deletions mhw-cs-plugin-loader/Json.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

#define JSON_NOEXCEPTION 1
#include <nlohmann/json.hpp>

using json = nlohmann::ordered_json;
Loading
Loading