feat: Add Windows-only terrain SVG export functionality via FFI with configurable rendering options.
This commit is contained in:
parent
4d7e3520eb
commit
2dbcb98817
@ -12,19 +12,11 @@ mod windows_ffi {
|
|||||||
#[link(name = "kernel32")]
|
#[link(name = "kernel32")]
|
||||||
unsafe extern "system" {
|
unsafe extern "system" {
|
||||||
pub(super) fn GetModuleHandleA(lpModuleName: *const u8) -> *mut c_void;
|
pub(super) fn GetModuleHandleA(lpModuleName: *const u8) -> *mut c_void;
|
||||||
pub(super) fn LoadLibraryA(lpLibFileName: *const u8) -> *mut c_void;
|
|
||||||
pub(super) fn GetProcAddress(hModule: *mut c_void, lpProcName: *const u8) -> *mut c_void;
|
pub(super) fn GetProcAddress(hModule: *mut c_void, lpProcName: *const u8) -> *mut c_void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mangled C++ name for the ExportSVG function.
|
|
||||||
/// Format: `?ExportSVG@@YAXPEBD_N11111@Z` matches signature:
|
|
||||||
/// `void ExportSVG(const char*, bool, bool, bool, bool, bool, bool)`
|
|
||||||
pub(super) const EXPORT_SVG_PROC_NAME: &[u8] = b"?ExportSVG@@YAXPEBD_N11111@Z\0";
|
pub(super) const EXPORT_SVG_PROC_NAME: &[u8] = b"?ExportSVG@@YAXPEBD_N11111@Z\0";
|
||||||
|
|
||||||
/// Name of the DLL containing the ExportSVG function.
|
|
||||||
/// Update this to match your actual DLL name.
|
|
||||||
pub(super) const TERRAIN_DLL_NAME: &[u8] = b"TerrainExport.dll\0";
|
|
||||||
|
|
||||||
pub(super) type FnExportSVG =
|
pub(super) type FnExportSVG =
|
||||||
extern "system" fn(*const c_char, bool, bool, bool, bool, bool, bool) -> *const c_void;
|
extern "system" fn(*const c_char, bool, bool, bool, bool, bool, bool) -> *const c_void;
|
||||||
}
|
}
|
||||||
@ -63,35 +55,20 @@ pub fn export_terrain_svg(
|
|||||||
unsafe {
|
unsafe {
|
||||||
use windows_ffi::*;
|
use windows_ffi::*;
|
||||||
|
|
||||||
// Try to get already loaded module, or load the DLL
|
let module = GetModuleHandleA(std::ptr::null());
|
||||||
let module = GetModuleHandleA(TERRAIN_DLL_NAME.as_ptr());
|
if module.is_null() {
|
||||||
let module = if module.is_null() {
|
return Err("Failed to get game engine module handle".to_string());
|
||||||
let loaded = LoadLibraryA(TERRAIN_DLL_NAME.as_ptr());
|
|
||||||
if loaded.is_null() {
|
|
||||||
return Err(format!(
|
|
||||||
"Failed to load DLL: {}",
|
|
||||||
std::str::from_utf8_unchecked(&TERRAIN_DLL_NAME[..TERRAIN_DLL_NAME.len() - 1])
|
|
||||||
));
|
|
||||||
}
|
|
||||||
loaded
|
|
||||||
} else {
|
|
||||||
module
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the ExportSVG function address
|
|
||||||
let export_svg_proc = GetProcAddress(module, EXPORT_SVG_PROC_NAME.as_ptr());
|
|
||||||
if export_svg_proc.is_null() {
|
|
||||||
return Err("Failed to find ExportSVG function in DLL".to_string());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to function pointer
|
let export_svg_proc = GetProcAddress(module, EXPORT_SVG_PROC_NAME.as_ptr());
|
||||||
let export_svg: FnExportSVG = std::mem::transmute(export_svg_proc);
|
if export_svg_proc.is_null() {
|
||||||
|
return Err("Failed to find ExportSVG function in game engine".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
// Convert file path to C string
|
let export_svg: FnExportSVG = std::mem::transmute(export_svg_proc);
|
||||||
let file_path_cstr =
|
let file_path_cstr =
|
||||||
std::ffi::CString::new(file_path).map_err(|e| format!("Invalid file path: {}", e))?;
|
std::ffi::CString::new(file_path).map_err(|e| format!("Invalid file path: {}", e))?;
|
||||||
|
|
||||||
// Call the export function
|
|
||||||
export_svg(
|
export_svg(
|
||||||
file_path_cstr.as_ptr(),
|
file_path_cstr.as_ptr(),
|
||||||
draw_location_names,
|
draw_location_names,
|
||||||
@ -164,7 +141,6 @@ struct ExportSvgOptions {
|
|||||||
/// ["terrain:exportSVG", [toJSON _options]] call forge_x_extension_fnc_extCall;
|
/// ["terrain:exportSVG", [toJSON _options]] call forge_x_extension_fnc_extCall;
|
||||||
/// ```
|
/// ```
|
||||||
fn export_svg(options_json: String) -> String {
|
fn export_svg(options_json: String) -> String {
|
||||||
// Parse options from JSON
|
|
||||||
let options: ExportSvgOptions = match serde_json::from_str(&options_json) {
|
let options: ExportSvgOptions = match serde_json::from_str(&options_json) {
|
||||||
Ok(opts) => opts,
|
Ok(opts) => opts,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user