power_play/src/resource/resource_core.c
2025-07-30 18:28:23 -05:00

104 lines
2.6 KiB
C

/* ========================== *
* Global data
* ========================== */
/* Add resource data to binary */
Global struct {
Arena *arena;
#if RESOURCES_EMBEDDED
struct tar_archive archive;
#endif
} G = ZI, DebugAlias(G, G_resource);
/* ========================== *
* Startup
* ========================== */
R_StartupReceipt resource_startup(void)
{
__prof;
G.arena = AllocArena(Gibi(64));
#if RESOURCES_EMBEDDED
String embedded_data = INC_GetResTar();
if (embedded_data.len <= 0) {
P_Panic(Lit("No embedded resources found"));
}
G.archive = tar_parse(G.arena, embedded_data, Lit(""));
#else
/* Ensure we have the right working directory */
if (!P_IsDir(Lit("res"))) {
P_Panic(Lit("Resource directory \"res\" not found. Make sure the executable is being launched from the correct working directory."));
}
#endif
return (R_StartupReceipt) { 0 };
}
/* ========================== *
* Open / close
* ========================== */
R_Resource resource_open(String name)
{
__prof;
#if RESOURCES_EMBEDDED
R_Resource result = ZI;
struct tar_entry *entry = tar_get(&G.archive, name);
result._data = entry->data;
result._name = entry->file_name;
result._exists = entry->valid;
return result;
#else
R_Resource result = ZI;
if (name.len < countof(result._name_text)) {
u8 path_text[RESOURCE_NAME_LEN_MAX + (sizeof("result/") - 1)];
String path = ZI;
{
path_text[0] = 'r';
path_text[1] = 'e';
path_text[2] = 's';
path_text[3] = '/';
u64 path_text_len = 4;
CopyBytes(path_text + path_text_len, name.text, name.len);
path_text_len += name.len;
path = STRING(path_text_len, path_text);
}
P_File file = P_OpenFileReadWait(path);
P_FileMap file_map = ZI;
String data = ZI;
if (file.valid) {
file_map = P_OpenFileMap(file);
if (file_map.valid) {
data = P_GetFileMapData(file_map);
} else {
P_CloseFileMap(file_map);
}
} else {
P_CloseFIle(file);
}
result._exists = file.valid && file_map.valid;
result._data = data;
result._file = file;
result._file_map = file_map;
result._name_len = name.len;
CopyBytes(result._name_text, name.text, name.len);
} else {
Assert(0);
}
return result;
#endif
}
#if !RESOURCES_EMBEDDED
void resource_close(R_Resource *res_ptr)
{
P_CloseFileMap(res_ptr->_file_map);
P_CloseFIle(res_ptr->_file);
}
#endif