siglus_scene_vm/
display_ffi.rs1use std::ffi::{CStr, CString, c_char};
4use std::path::PathBuf;
5
6use crate::runtime::game_display_info::{
7 resolve_game_cover_from_project_dir, resolve_game_name_from_project_dir,
8};
9
10unsafe fn path_from_cstr(ptr: *const c_char) -> Option<PathBuf> {
11 if ptr.is_null() {
12 return None;
13 }
14 let s = unsafe { CStr::from_ptr(ptr) }.to_string_lossy().to_string();
15 if s.is_empty() {
16 None
17 } else {
18 Some(PathBuf::from(s))
19 }
20}
21
22fn into_c_string_ptr(s: String) -> *mut c_char {
23 CString::new(s)
24 .unwrap_or_else(|_| CString::new("Siglus").unwrap())
25 .into_raw()
26}
27
28#[unsafe(no_mangle)]
37pub unsafe extern "C" fn siglus_string_free(ptr: *mut c_char) {
38 if ptr.is_null() {
39 return;
40 }
41 drop(unsafe { CString::from_raw(ptr) });
42}
43
44#[unsafe(no_mangle)]
53pub unsafe extern "C" fn siglus_game_name_from_dir(game_root_utf8: *const c_char) -> *mut c_char {
54 let Some(path) = (unsafe { path_from_cstr(game_root_utf8) }) else {
55 return into_c_string_ptr("Siglus".to_string());
56 };
57 into_c_string_ptr(resolve_game_name_from_project_dir(path))
58}
59
60#[unsafe(no_mangle)]
69pub unsafe extern "C" fn siglus_game_cover_path_from_dir(
70 game_root_utf8: *const c_char,
71) -> *mut c_char {
72 let Some(path) = (unsafe { path_from_cstr(game_root_utf8) }) else {
73 return std::ptr::null_mut();
74 };
75 let Some(cover) = resolve_game_cover_from_project_dir(path) else {
76 return std::ptr::null_mut();
77 };
78 into_c_string_ptr(cover.source_path.to_string_lossy().to_string())
79}
80
81#[unsafe(no_mangle)]
90pub unsafe extern "C" fn siglus_game_cover_mime_from_dir(
91 game_root_utf8: *const c_char,
92) -> *mut c_char {
93 let Some(path) = (unsafe { path_from_cstr(game_root_utf8) }) else {
94 return std::ptr::null_mut();
95 };
96 let Some(cover) = resolve_game_cover_from_project_dir(path) else {
97 return std::ptr::null_mut();
98 };
99 into_c_string_ptr(cover.mime)
100}