Skip to content

Commit

Permalink
move UI rendering to hudhook
Browse files Browse the repository at this point in the history
  • Loading branch information
super-continent committed Dec 9, 2024
1 parent e557881 commit baeacf7
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 316 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ default = ["websockets"]

[dependencies]
sigscan = { git = "https://github.com/super-continent/sigscan" }
imgui-impl-win32-rs = { git = "https://github.com/super-continent/imgui-impl-win32-rs" }
imgui-dx9-renderer = "0"
winapi = { version = "0", features = [
"minwindef",
"consoleapi",
Expand All @@ -26,8 +24,9 @@ winapi = { version = "0", features = [
"d3d9types",
"ntdef",
"psapi",
"winuser",
"processthreadsapi",
] }
imgui = "0.8"
retour = { version = "0.3", features = ["static-detour", "thiscall-abi"] }
parking_lot = "0"
log = { version = "0", features = ["serde"] }
Expand All @@ -47,3 +46,4 @@ tokio = { version = "1.39.1", features = [
tokio-tungstenite = { version = "0.24.0", optional = true }
steamworks-sys = "0.11.0"
futures-util = "0.3.31"
hudhook = "0.8.0"
30 changes: 14 additions & 16 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ use std::thread;
#[macro_use]
extern crate log;

use hudhook::windows::Win32::Foundation::{BOOL, HINSTANCE, MAX_PATH, TRUE};
use once_cell::sync::OnceCell;
use simplelog::*;
use winapi::shared::minwindef::{DWORD, HINSTANCE__, LPVOID};
use winapi::{
ctypes::c_void,
shared::guiddef::REFIID,
shared::minwindef::*,
shared::ntdef::HRESULT,
shared::winerror,
um::libloaderapi,
Expand All @@ -35,18 +36,16 @@ use winapi::{
#[allow(non_snake_case)]
pub unsafe extern "stdcall" fn DllMain(
hinst_dll: HINSTANCE,
attach_reason: DWORD,
_: c_void,
attach_reason: u32,
_: *mut (),
) -> BOOL {
libloaderapi::DisableThreadLibraryCalls(hinst_dll);

if attach_reason == DLL_PROCESS_ATTACH {
// if websockets are enabled we set up the message passing state
#[cfg(feature = "websockets")]
{
let (tx, rx) = tokio::sync::mpsc::channel(8);
global::MESSAGE_SENDER.get_or_init(move || tx);
thread::spawn(|| unsafe { initialize() });
thread::spawn(move || unsafe { initialize(hinst_dll) });

thread::spawn(move || {
let runtime = tokio::runtime::Builder::new_current_thread()
Expand All @@ -60,14 +59,14 @@ pub unsafe extern "stdcall" fn DllMain(
}
#[cfg(not(feature = "websockets"))]
{
thread::spawn(|| unsafe { initialize() });
thread::spawn(|| unsafe { initialize(hinst_dll) });
}
};

TRUE
}

unsafe fn initialize() {
unsafe fn initialize(module: HINSTANCE) {
let log_level = global::CONFIG.lock().log_level;
// let log_level = LevelFilter::Trace;
if let Ok(logfile) = File::create("rev2mod.log") {
Expand Down Expand Up @@ -111,13 +110,12 @@ unsafe fn initialize() {

debug!("UI hooks initializing...");

let mut ui_result = ui::ui_hooks::init_ui();
while let Err(e) = ui_result {
error!("Initializing UI failed: {}", e);
thread::sleep(std::time::Duration::from_secs(5));
ui_result = ui::ui_hooks::init_ui();
let ui_result = ui::ui_hooks::init_ui(module);
if let Err(e) = ui_result {
info!("Failed to hook UI: {:?}", e);
} else {
info!("UI hook success!");
}
info!("UI hook success!");

info!("Initializing game hooks...");
let game_result = game::hooks::init_game_hooks();
Expand Down Expand Up @@ -145,7 +143,7 @@ pub unsafe extern "stdcall" fn DirectInput8Create(

// Load real dinput8.dll if not already loaded

let real_dinput8 = *REAL_DINPUT8_HANDLE.get_or_init(|| get_dinput8_handle()) as HINSTANCE;
let real_dinput8 = *REAL_DINPUT8_HANDLE.get_or_init(|| get_dinput8_handle()) as *mut HINSTANCE__;

let dinput8create_fn_name =
CString::new("DirectInput8Create").expect("CString::new(`DirectInput8Create`) failed");
Expand All @@ -161,7 +159,7 @@ pub unsafe extern "stdcall" fn DirectInput8Create(
}

unsafe fn get_dinput8_handle() -> u32 {
let mut buffer = [0u16; MAX_PATH];
let mut buffer = [0u16; MAX_PATH as usize];
let written_wchars = GetSystemDirectoryW(buffer.as_mut_ptr(), MAX_PATH as u32);

let system_directory = if written_wchars == 0 {
Expand Down
30 changes: 18 additions & 12 deletions src/ui/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ use std::borrow::Cow;
use std::path::PathBuf;
use std::sync::atomic::Ordering;

use imgui::*;
use hudhook::imgui::*;
use hudhook::ImguiRenderLoop;
use once_cell::sync::Lazy;
use std::sync::atomic::{AtomicBool, AtomicUsize};
use winapi::um::winuser::*;

// this should work because we initialize the config
// before ever accessing DISPLAY_UI through the UI loop
Expand All @@ -30,21 +30,29 @@ fn save_config(config: global::ModConfig) {
.unwrap_or_else(|e| error!("writing config: {}", e));
}

pub fn ui_loop(ui: Ui) -> Ui {
pub struct XrdModUi;

impl ImguiRenderLoop for XrdModUi {
fn render(&mut self, ui: &mut Ui) {
ui_loop(ui);
}
}

pub fn ui_loop(ui: &mut Ui) {
let display_ui = DISPLAY_UI.load(Ordering::SeqCst);
let mut config = global::CONFIG.lock();

if ui.is_key_index_pressed(VK_F1) {
if ui.is_key_pressed(Key::F1) {
DISPLAY_UI.store(!display_ui, Ordering::SeqCst);
}

if !display_ui {
return ui;
return;
}

Window::new("Pangaea's Rev2 Mod")
ui.window("Pangaea's Rev2 Mod")
.size([300., 400.], Condition::FirstUseEver)
.build(&ui, || {
.build(|| {
TabBar::new("Mods and Config").build(&ui, || {
TabItem::new("Config").build(&ui, || {
let mut mods_on = config.mods_enabled;
Expand Down Expand Up @@ -94,7 +102,7 @@ pub fn ui_loop(ui: Ui) -> Ui {
config.dump_scripts = dump_scripts
};

Slider::new("Online delay", 0, 4).build(&ui, &mut config.online_input_delay);
ui.slider("Online delay", 0, 4, &mut config.online_input_delay);

unsafe {
let rollback_manager = *(ROLLBACK_MANAGER.get_address() as *mut *mut u8);
Expand Down Expand Up @@ -133,12 +141,12 @@ pub fn ui_loop(ui: Ui) -> Ui {
let gamestate = *(GAMESTATE_PTR.get_address() as *mut *mut u8);

if gamestate.is_null() {
return ui;
return;
}

let gamestate = GameState(gamestate);

Window::new("Game State").build(&ui, || {
ui.window("Game State").build(|| {
ui.text("P1 Tension Pulse");
ProgressBar::new(
(gamestate.player_1().tension_pulse() as f32 + 25000.0) / (25000.0 + 25000.0),
Expand All @@ -154,6 +162,4 @@ pub fn ui_loop(ui: Ui) -> Ui {
.build(&ui);
});
}

ui
}
Loading

0 comments on commit baeacf7

Please sign in to comment.