refactor: Renderer (#694)

* Simplified SwapCHain, Device and DeviceContext pointers
* Added DX and WndProc callback registration
* Cleaned up GUI code
* Optimised Mouse Toggle
This commit is contained in:
Yimura 2022-12-16 18:55:55 +01:00 committed by GitHub
parent 0e6547b519
commit d624f1aaa1
15 changed files with 219 additions and 131 deletions

View File

@ -10,7 +10,7 @@ namespace big
{ {
if (g->weapons.rapid_fire) if (g->weapons.rapid_fire)
{ {
if(!HUD::IS_PAUSE_MENU_ACTIVE() && !g_gui.m_opened && !PED::IS_PED_DEAD_OR_DYING(self::ped, true)) if(!HUD::IS_PAUSE_MENU_ACTIVE() && !g_gui->is_open() && !PED::IS_PED_DEAD_OR_DYING(self::ped, true))
{ {
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_ATTACK)) if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_ATTACK))
{ {

View File

@ -17,7 +17,7 @@ namespace big
const auto elapsed_time_in_ms = std::chrono::duration_cast<std::chrono::milliseconds>(time_now - last_time).count(); const auto elapsed_time_in_ms = std::chrono::duration_cast<std::chrono::milliseconds>(time_now - last_time).count();
if (is_vehicle_gun_selected && if (is_vehicle_gun_selected &&
!g_gui.m_opened && !g_gui->is_open() &&
elapsed_time_in_ms >= 100 && elapsed_time_in_ms >= 100 &&
PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_ATTACK)) PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_ATTACK))
{ {

View File

@ -5,7 +5,6 @@
#include <winsock2.h> #include <winsock2.h>
#include <windows.h> #include <windows.h>
#include <d3d11.h> #include <d3d11.h>
#include <wrl/client.h>
#include <cinttypes> #include <cinttypes>
#include <cstddef> #include <cstddef>
@ -61,9 +60,6 @@
namespace big namespace big
{ {
using namespace std::chrono_literals; using namespace std::chrono_literals;
template <typename T>
using comptr = Microsoft::WRL::ComPtr<T>;
inline HMODULE g_hmodule{}; inline HMODULE g_hmodule{};
inline HANDLE g_main_thread{}; inline HANDLE g_main_thread{};

View File

@ -3,20 +3,60 @@
#include "gui.hpp" #include "gui.hpp"
#include "natives.hpp" #include "natives.hpp"
#include "script.hpp" #include "script.hpp"
#include "renderer.hpp"
#include <imgui.h> #include <imgui.h>
#include "widgets/imgui_hotkey.hpp"
#include "views/view.hpp" #include "views/view.hpp"
namespace big namespace big
{ {
gui::gui() :
m_is_open(false)
{
g_renderer->add_dx_callback(view::gta_data, -1); // -1 highest priority of drawing
g_renderer->add_dx_callback(view::notifications, -2); // second highest priority
g_renderer->add_dx_callback([this]
{
dx_on_tick();
}, -3); // 3rd highest priority
g_renderer->add_wndproc_callback([this](HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
wndproc(hwnd, msg, wparam, lparam);
});
g_renderer->add_dx_callback(esp::draw, 2); // TODO: move to ESP service
g_renderer->add_dx_callback(view::context_menu, 1);
dx_init();
g_gui = this;
}
gui::~gui()
{
g_gui = nullptr;
}
bool gui::is_open()
{
return m_is_open;
}
void gui::toggle(bool toggle)
{
m_is_open = toggle;
toggle_mouse();
}
void gui::dx_init() void gui::dx_init()
{ {
static ImVec4 bgColor = ImVec4(0.09f, 0.094f, 0.129f, .9f); static auto bgColor = ImVec4(0.09f, 0.094f, 0.129f, .9f);
static ImVec4 primary = ImVec4(0.172f, 0.380f, 0.909f, 1.f); static auto primary = ImVec4(0.172f, 0.380f, 0.909f, 1.f);
static ImVec4 secondary = ImVec4(0.443f, 0.654f, 0.819f, 1.f); static auto secondary = ImVec4(0.443f, 0.654f, 0.819f, 1.f);
static ImVec4 whiteBroken = ImVec4(0.792f, 0.784f, 0.827f, 1.f); static auto whiteBroken = ImVec4(0.792f, 0.784f, 0.827f, 1.f);
auto& style = ImGui::GetStyle(); auto& style = ImGui::GetStyle();
style.WindowPadding = ImVec2(15, 15); style.WindowPadding = ImVec2(15, 15);
@ -73,61 +113,89 @@ namespace big
void gui::dx_on_tick() void gui::dx_on_tick()
{ {
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGui::ColorConvertU32ToFloat4(g->window.color)); if (m_is_open)
view::root(); {
ImGui::PopStyleColor(); ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGui::ColorConvertU32ToFloat4(g->window.color));
} view::root();
ImGui::PopStyleColor();
void gui::always_draw() }
{
view::always();
} }
void gui::script_on_tick() void gui::script_on_tick()
{ {
TRY_CLAUSE if (g_gui->m_is_open)
{ {
if (g_gui.m_opened) for (uint8_t i = 0; i <= 6; i++)
{ PAD::DISABLE_CONTROL_ACTION(2, i, true);
for (uint8_t i = 0; i <= 6; i++) PAD::DISABLE_CONTROL_ACTION(2, 106, true);
PAD::DISABLE_CONTROL_ACTION(2, i, true); PAD::DISABLE_CONTROL_ACTION(2, 329, true);
PAD::DISABLE_CONTROL_ACTION(2, 106, true); PAD::DISABLE_CONTROL_ACTION(2, 330, true);
PAD::DISABLE_CONTROL_ACTION(2, 329, true);
PAD::DISABLE_CONTROL_ACTION(2, 330, true);
PAD::DISABLE_CONTROL_ACTION(2, 14, true); PAD::DISABLE_CONTROL_ACTION(2, 14, true);
PAD::DISABLE_CONTROL_ACTION(2, 15, true); PAD::DISABLE_CONTROL_ACTION(2, 15, true);
PAD::DISABLE_CONTROL_ACTION(2, 16, true); PAD::DISABLE_CONTROL_ACTION(2, 16, true);
PAD::DISABLE_CONTROL_ACTION(2, 17, true); PAD::DISABLE_CONTROL_ACTION(2, 17, true);
PAD::DISABLE_CONTROL_ACTION(2, 24, true); PAD::DISABLE_CONTROL_ACTION(2, 24, true);
PAD::DISABLE_CONTROL_ACTION(2, 69, true); PAD::DISABLE_CONTROL_ACTION(2, 69, true);
PAD::DISABLE_CONTROL_ACTION(2, 70, true); PAD::DISABLE_CONTROL_ACTION(2, 70, true);
PAD::DISABLE_CONTROL_ACTION(2, 84, true); PAD::DISABLE_CONTROL_ACTION(2, 84, true);
PAD::DISABLE_CONTROL_ACTION(2, 85, true); PAD::DISABLE_CONTROL_ACTION(2, 85, true);
PAD::DISABLE_CONTROL_ACTION(2, 99, true); PAD::DISABLE_CONTROL_ACTION(2, 99, true);
PAD::DISABLE_CONTROL_ACTION(2, 92, true); PAD::DISABLE_CONTROL_ACTION(2, 92, true);
PAD::DISABLE_CONTROL_ACTION(2, 100, true); PAD::DISABLE_CONTROL_ACTION(2, 100, true);
PAD::DISABLE_CONTROL_ACTION(2, 114, true); PAD::DISABLE_CONTROL_ACTION(2, 114, true);
PAD::DISABLE_CONTROL_ACTION(2, 115, true); PAD::DISABLE_CONTROL_ACTION(2, 115, true);
PAD::DISABLE_CONTROL_ACTION(2, 121, true); PAD::DISABLE_CONTROL_ACTION(2, 121, true);
PAD::DISABLE_CONTROL_ACTION(2, 142, true); PAD::DISABLE_CONTROL_ACTION(2, 142, true);
PAD::DISABLE_CONTROL_ACTION(2, 241, true); PAD::DISABLE_CONTROL_ACTION(2, 241, true);
PAD::DISABLE_CONTROL_ACTION(2, 261, true); PAD::DISABLE_CONTROL_ACTION(2, 261, true);
PAD::DISABLE_CONTROL_ACTION(2, 257, true); PAD::DISABLE_CONTROL_ACTION(2, 257, true);
PAD::DISABLE_CONTROL_ACTION(2, 262, true); PAD::DISABLE_CONTROL_ACTION(2, 262, true);
PAD::DISABLE_CONTROL_ACTION(2, 331, true); PAD::DISABLE_CONTROL_ACTION(2, 331, true);
}
} }
EXCEPT_CLAUSE
} }
void gui::script_func() void gui::script_func()
{ {
g_notification_service->push("Welcome", std::format("Loaded YimMenu. Press {} to open", ImGui::key_names[g->settings.hotkeys.menu_toggle]));
while (true) while (true)
{ {
g_gui.script_on_tick(); g_gui->script_on_tick();
script::get_current()->yield(); script::get_current()->yield();
} }
} }
void gui::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if (msg == WM_KEYUP && wparam == g->settings.hotkeys.menu_toggle)
{
//Persist and restore the cursor position between menu instances.
static POINT cursor_coords{};
if (g_gui->m_is_open)
{
GetCursorPos(&cursor_coords);
}
else if (cursor_coords.x + cursor_coords.y != 0)
{
SetCursorPos(cursor_coords.x, cursor_coords.y);
}
toggle(g->settings.hotkeys.editing_menu_toggle || !m_is_open);
if (g->settings.hotkeys.editing_menu_toggle)
g->settings.hotkeys.editing_menu_toggle = false;
}
}
void gui::toggle_mouse()
{
if (m_is_open)
{
ImGui::GetIO().MouseDrawCursor = true;
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouse;
}
else
{
ImGui::GetIO().MouseDrawCursor = false;
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouse;
}
}
} }

View File

@ -6,15 +6,31 @@ namespace big
class gui class gui
{ {
public: public:
gui();
virtual ~gui();
gui(const gui&) = delete;
gui(gui&&) noexcept = delete;
gui& operator=(const gui&) = delete;
gui& operator=(gui&&) noexcept = delete;
bool is_open();
void toggle(bool toggle);
void dx_init(); void dx_init();
void dx_on_tick(); void dx_on_tick();
void always_draw();
void script_on_tick(); void script_on_tick();
static void script_func(); static void script_func();
public:
bool m_opened{}; void wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
private:
void toggle_mouse();
private:
bool m_is_open;
}; };
inline gui g_gui; inline gui* g_gui;
} }

View File

@ -1,7 +1,6 @@
#include "hooking.hpp" #include "hooking.hpp"
#include "renderer.hpp" #include "renderer.hpp"
#include "script.hpp" #include "script.hpp"
#include "services/hotkey/hotkey_service.hpp"
namespace big namespace big
{ {
@ -12,7 +11,6 @@ namespace big
if (g_running) if (g_running)
{ {
g_renderer->wndproc(hwnd, msg, wparam, lparam); g_renderer->wndproc(hwnd, msg, wparam, lparam);
g_hotkey_service->wndproc(static_cast<eKeyState>(msg), wparam);
} }
return CallWindowProcW(g_hooking->m_og_wndproc, hwnd, msg, wparam, lparam); return CallWindowProcW(g_hooking->m_og_wndproc, hwnd, msg, wparam, lparam);

View File

@ -69,6 +69,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
auto renderer_instance = std::make_unique<renderer>(); auto renderer_instance = std::make_unique<renderer>();
LOG(INFO) << "Renderer initialized."; LOG(INFO) << "Renderer initialized.";
auto gui_instance = std::make_unique<gui>();
auto fiber_pool_instance = std::make_unique<fiber_pool>(11); auto fiber_pool_instance = std::make_unique<fiber_pool>(11);
LOG(INFO) << "Fiber pool initialized."; LOG(INFO) << "Fiber pool initialized.";

View File

@ -16,17 +16,11 @@ namespace big
renderer::renderer() : renderer::renderer() :
m_dxgi_swapchain(*g_pointers->m_swapchain) m_dxgi_swapchain(*g_pointers->m_swapchain)
{ {
void* d3d_device{}; if (m_dxgi_swapchain->GetDevice(__uuidof(ID3D11Device), reinterpret_cast<void**>(&m_d3d_device)) < 0)
if (SUCCEEDED(m_dxgi_swapchain->GetDevice(__uuidof(ID3D11Device), &d3d_device)))
{
m_d3d_device.Attach(static_cast<ID3D11Device*>(d3d_device));
}
else
{ {
throw std::runtime_error("Failed to get D3D device."); throw std::runtime_error("Failed to get D3D device.");
} }
m_d3d_device->GetImmediateContext(&m_d3d_device_context);
m_d3d_device->GetImmediateContext(m_d3d_device_context.GetAddressOf());
auto file_path = g_file_manager->get_project_file("./imgui.ini").get_path(); auto file_path = g_file_manager->get_project_file("./imgui.ini").get_path();
@ -35,7 +29,7 @@ namespace big
static std::string path = file_path.make_preferred().string(); static std::string path = file_path.make_preferred().string();
ctx->IO.IniFilename = path.c_str(); ctx->IO.IniFilename = path.c_str();
ImGui_ImplDX11_Init(m_d3d_device.Get(), m_d3d_device_context.Get()); ImGui_ImplDX11_Init(m_d3d_device, m_d3d_device_context);
ImGui_ImplWin32_Init(g_pointers->m_hwnd); ImGui_ImplWin32_Init(g_pointers->m_hwnd);
folder windows_fonts( folder windows_fonts(
@ -112,46 +106,40 @@ namespace big
rescale(g->window.gui_scale); rescale(g->window.gui_scale);
g_gui.dx_init();
g_renderer = this; g_renderer = this;
} }
renderer::~renderer() renderer::~renderer()
{ {
g_renderer = nullptr;
ImGui_ImplWin32_Shutdown(); ImGui_ImplWin32_Shutdown();
ImGui_ImplDX11_Shutdown(); ImGui_ImplDX11_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
}
g_renderer = nullptr; bool renderer::add_dx_callback(dx_callback callback, std::uint32_t priority)
{
if (!m_dx_callbacks.insert({ priority, callback }).second)
{
LOG(WARNING) << "Duplicate priority given on DX Callback!";
return false;
}
return true;
}
void renderer::add_wndproc_callback(wndproc_callback callback)
{
m_wndproc_callbacks.emplace_back(callback);
} }
void renderer::on_present() void renderer::on_present()
{ {
if (g_gui.m_opened) new_frame();
{ for (const auto& cb : m_dx_callbacks | std::views::values)
ImGui::GetIO().MouseDrawCursor = true; cb();
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouse; end_frame();
}
else
{
ImGui::GetIO().MouseDrawCursor = false;
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouse;
}
ImGui_ImplDX11_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
g_gui.always_draw();
if (g_gui.m_opened)
{
g_gui.dx_on_tick();
}
ImGui::Render();
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
} }
void renderer::rescale(float rel_size) void renderer::rescale(float rel_size)
@ -174,27 +162,25 @@ namespace big
void renderer::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) void renderer::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{ {
if (msg == WM_KEYUP && wparam == g->settings.hotkeys.menu_toggle) for (const auto& cb : m_wndproc_callbacks)
{ cb(hwnd, msg, wparam, lparam);
//Persist and restore the cursor position between menu instances.
static POINT cursor_coords{};
if (g_gui.m_opened)
{
GetCursorPos(&cursor_coords);
}
else if (cursor_coords.x + cursor_coords.y != 0)
{
SetCursorPos(cursor_coords.x, cursor_coords.y);
}
g_gui.m_opened = g->settings.hotkeys.editing_menu_toggle || !g_gui.m_opened; if (g_gui->is_open())
if (g->settings.hotkeys.editing_menu_toggle)
g->settings.hotkeys.editing_menu_toggle = false;
}
if (g_gui.m_opened)
{ {
ImGui_ImplWin32_WndProcHandler(hwnd, msg, wparam, lparam); ImGui_ImplWin32_WndProcHandler(hwnd, msg, wparam, lparam);
} }
} }
void renderer::new_frame()
{
ImGui_ImplDX11_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
}
void renderer::end_frame()
{
ImGui::Render();
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
}
} }

View File

@ -1,15 +1,33 @@
#pragma once #pragma once
#include "common.hpp" #include "common.hpp"
#include <imgui.h>
namespace big namespace big
{ {
class renderer using dx_callback = std::function<void()>;
using wndproc_callback = std::function<void(HWND, UINT, WPARAM, LPARAM)>;
class renderer final
{ {
public: public:
explicit renderer(); explicit renderer();
~renderer(); ~renderer();
/**
* @brief Add a callback function to draw your ImGui content in
*
* @param callback Function
* @param priority The higher the priority the value the later it gets drawn on top
* @return true
* @return false
*/
bool add_dx_callback(dx_callback callback, std::uint32_t priority);
/**
* @brief Add a callback function on wndproc
*
* @param callback Function
*/
void add_wndproc_callback(wndproc_callback callback);
void on_present(); void on_present();
void rescale(float rel_size); void rescale(float rel_size);
@ -20,9 +38,16 @@ namespace big
void wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); void wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
private: private:
comptr<IDXGISwapChain> m_dxgi_swapchain; static void new_frame();
comptr<ID3D11Device> m_d3d_device; static void end_frame();
comptr<ID3D11DeviceContext> m_d3d_device_context;
private:
IDXGISwapChain* m_dxgi_swapchain;
ID3D11Device* m_d3d_device;
ID3D11DeviceContext* m_d3d_device_context;
std::map<std::uint32_t, dx_callback> m_dx_callbacks;
std::vector<wndproc_callback> m_wndproc_callbacks;
}; };
inline renderer* g_renderer{}; inline renderer* g_renderer{};

View File

@ -300,7 +300,7 @@ namespace big
continue; continue;
} }
if (g_gui.m_opened) if (g_gui->is_open())
{ {
script::get_current()->yield(); script::get_current()->yield();
continue; continue;

View File

@ -2,6 +2,7 @@
#include "fiber_pool.hpp" #include "fiber_pool.hpp"
#include "util/teleport.hpp" #include "util/teleport.hpp"
#include "hotkey_functions.hpp" #include "hotkey_functions.hpp"
#include "renderer.hpp"
#include "network/ChatData.hpp" #include "network/ChatData.hpp"
#include "pointers.hpp" #include "pointers.hpp"
@ -14,6 +15,11 @@ namespace big
register_hotkey("objective", g->settings.hotkeys.teleport_objective, teleport::to_objective); register_hotkey("objective", g->settings.hotkeys.teleport_objective, teleport::to_objective);
register_hotkey("noclip", g->settings.hotkeys.noclip, hotkey_funcs::toggle_noclip); register_hotkey("noclip", g->settings.hotkeys.noclip, hotkey_funcs::toggle_noclip);
g_renderer->add_wndproc_callback([this](HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
wndproc(static_cast<eKeyState>(msg), wparam);
});
g_hotkey_service = this; g_hotkey_service = this;
} }

View File

@ -115,7 +115,7 @@ namespace big
m_loop_running = true; m_loop_running = true;
while ( while (
g_running && m_running && g_gui.m_opened && g_running && m_running && g_gui->is_open() &&
(m_ped_model_hash|| m_veh_model_hash) (m_ped_model_hash|| m_veh_model_hash)
) { ) {
Vector3 location; Vector3 location;

View File

@ -1,9 +1,12 @@
#include "notification_service.hpp" #include "notification_service.hpp"
#include "widgets/imgui_hotkey.hpp"
namespace big namespace big
{ {
notification_service::notification_service() notification_service::notification_service()
{ {
push("Welcome", std::format("Loaded YimMenu. Press {} to open", ImGui::key_names[g->settings.hotkeys.menu_toggle]));
g_notification_service = this; g_notification_service = this;
} }

View File

@ -52,16 +52,5 @@ namespace big
static void player_kick(); static void player_kick();
static void player_toxic(); static void player_toxic();
static void player_misc(); static void player_misc();
// later calls will be drawn over earlier calls
static void always()
{
esp::draw();
context_menu();
gta_data();
notifications();
}
}; };
} }

View File

@ -12,7 +12,7 @@ namespace big
if (g_gta_data_service->cache_needs_update()) if (g_gta_data_service->cache_needs_update())
{ {
g_gui.m_opened = true; g_gui->toggle(true);
ImGui::OpenPopup("Game Cache"); ImGui::OpenPopup("Game Cache");
} }