/* ========================== * * 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_res_tar(); 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 res = ZI; struct tar_entry *entry = tar_get(&G.archive, name); res._data = entry->data; res._name = entry->file_name; res._exists = entry->valid; return res; #else R_Resource res = ZI; if (name.len < countof(res._name_text)) { u8 path_text[RESOURCE_NAME_LEN_MAX + (sizeof("res/") - 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); } res._exists = file.valid && file_map.valid; res._data = data; res._file = file; res._file_map = file_map; res._name_len = name.len; CopyBytes(res._name_text, name.text, name.len); } else { Assert(0); } return res; #endif } #if !RESOURCES_EMBEDDED void resource_close(R_Resource *res_ptr) { P_CloseFileMap(res_ptr->_file_map); P_CloseFIle(res_ptr->_file); } #endif