siglus_scene_vm/
display_ffi.rs1use std::ffi::{c_char, CStr, CString};
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 = 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#[no_mangle]
29pub unsafe extern "C" fn siglus_string_free(ptr: *mut c_char) {
30 if ptr.is_null() {
31 return;
32 }
33 drop(CString::from_raw(ptr));
34}
35
36#[no_mangle]
37pub unsafe extern "C" fn siglus_game_name_from_dir(game_root_utf8: *const c_char) -> *mut c_char {
38 let Some(path) = path_from_cstr(game_root_utf8) else {
39 return into_c_string_ptr("Siglus".to_string());
40 };
41 into_c_string_ptr(resolve_game_name_from_project_dir(path))
42}
43
44#[no_mangle]
45pub unsafe extern "C" fn siglus_game_cover_path_from_dir(game_root_utf8: *const c_char) -> *mut c_char {
46 let Some(path) = path_from_cstr(game_root_utf8) else {
47 return std::ptr::null_mut();
48 };
49 let Some(cover) = resolve_game_cover_from_project_dir(path) else {
50 return std::ptr::null_mut();
51 };
52 into_c_string_ptr(cover.source_path.to_string_lossy().to_string())
53}
54
55#[no_mangle]
56pub unsafe extern "C" fn siglus_game_cover_mime_from_dir(game_root_utf8: *const c_char) -> *mut c_char {
57 let Some(path) = path_from_cstr(game_root_utf8) else {
58 return std::ptr::null_mut();
59 };
60 let Some(cover) = resolve_game_cover_from_project_dir(path) else {
61 return std::ptr::null_mut();
62 };
63 into_c_string_ptr(cover.mime)
64}