gmod-rs/gmod/src/msgc.rs

82 lines
2.6 KiB
Rust
Raw Normal View History

2021-09-09 16:50:58 -04:00
#![allow(non_upper_case_globals)]
use std::os::raw::c_char;
#[inline]
pub fn printf_escape<S: AsRef<str>>(str: S) -> String {
str.as_ref().replace('\\', "\\\\").replace('%', "%%")
}
#[repr(C)]
pub struct Color {
r: u8,
g: u8,
b: u8,
a: u8
}
impl Color {
#[inline]
pub const fn new(r: u8, g: u8, b: u8) -> Color {
Color { r, g, b, a: 255 }
}
}
lazy_static::lazy_static! {
pub static ref ConColorMsg: libloading::Symbol<'static, unsafe extern "C" fn(&Color, *const c_char, ...)> = unsafe {
#[cfg(all(target_os = "windows", target_pointer_width = "64"))]
let lib = libloading::Library::new("bin/win64/tier0.dll").expect("Failed to open tier0.dll");
#[cfg(all(target_os = "windows", target_pointer_width = "32"))]
let lib = libloading::Library::new("bin/tier0.dll").or_else(|_| libloading::Library::new("bin/win32/tier0.dll")).expect("Failed to open tier0.dll");
#[cfg(all(target_os = "linux", target_pointer_width = "64"))]
let lib = libloading::Library::new("bin/linux64/libtier0.so").expect("Failed to open libtier0.so");
#[cfg(all(target_os = "linux", target_pointer_width = "32"))]
let lib = libloading::Library::new("bin/libtier0_srv.so").or_else(|_| libloading::Library::new("bin/linux32/libtier0.so")).expect("Failed to open libtier0.so");
let lib = Box::leak(Box::new(lib));
{
#[cfg(all(target_os = "windows", target_pointer_width = "64"))] {
lib.get(b"?ConColorMsg@@YAXAEBVColor@@PEBDZZ\0")
}
#[cfg(all(target_os = "windows", target_pointer_width = "32"))] {
match lib.get(b"?ConColorMsg@@YAXABVColor@@PBDZZ\0") {
Ok(symbol) => Ok(symbol),
Err(_) => lib.get(b"?ConColorMsg@@YAXABVColor@@PBDZZ\0")
}
}
#[cfg(all(target_os = "linux", target_pointer_width = "64"))] {
lib.get(b"_Z11ConColorMsgRK5ColorPKcz\0")
}
#[cfg(all(target_os = "linux", target_pointer_width = "32"))] {
match lib.get(b"_Z11ConColorMsgRK5ColorPKcz\0") {
Ok(symbol) => Ok(symbol),
Err(_) => lib.get(b"_Z11ConColorMsgRK5ColorPKcz\0")
}
}
}
.expect("Failed to get ConColorMsg")
};
}
#[macro_export]
macro_rules! colormsg {
($($($arg:expr)+),+) => {
$(::gmod::msgc::colormsg!(@print $($arg)+));+
};
(@print [$r:literal, $g:literal, $b:literal] $fmt:literal % ($($arg:tt),+)) => {
::gmod::msgc::ConColorMsg(
&::gmod::msgc::Color::new($r, $g, $b),
::gmod::msgc::printf_escape(format!(concat!($fmt, '\0'), $($arg),+)).as_ptr() as *const _,
)
};
(@print [$r:literal, $g:literal, $b:literal] $str:literal) => {
::gmod::msgc::ConColorMsg(
&::gmod::msgc::Color::new($r, $g, $b),
::gmod::msgc::printf_escape(concat!($str, '\0')).as_ptr() as *const _,
)
};
}