#include "assets.h" #include "uidtab.h" #include "aio.h" #include "buffer_manager.h" #define RT_DEFINE_PACKAGE_FILE_STRUCTURES #include "packages.h" #include "lz4/lz4.h" rt_result DecompressAsset(void *compressed_buffer, size_t compressed_buffer_size, void **p_decompressed, size_t *p_decompressed_size) { const rt_package_asset_header *header = compressed_buffer; size_t compressed_size = (compressed_buffer_size) - sizeof(*header); XXH64_hash_t calculated_hash = XXH3_64bits((header + 1), compressed_size); XXH64_hash_t file_hash = XXH64_hashFromCanonical(&header->checksum); if (calculated_hash != file_hash) { rtLog("core", "Checksum mismatch for asset"); return RT_LOAD_FAILED; } size_t size = (size_t)header->decompressed_size; void *decompressed_buffer = rtAllocBuffer(size); if (!decompressed_buffer) { return RT_BUFFER_ALLOC_FAILED; } if (LZ4_decompress_safe((const char *)(header + 1), (char *)decompressed_buffer, (int)compressed_size, (int)size) < 0) { return RT_UNKNOWN_ERROR; } *p_decompressed = decompressed_buffer; *p_decompressed_size = size; return RT_SUCCESS; } RT_DLLEXPORT rt_result rtLoadAssetDirect(rt_uid uid, void **p_buffer, size_t *p_size) { const rt_uid_data *data = rtGetUIDData(uid); if (!data) return RT_UNKNOWN_ASSET; void *compressed_buffer = rtAllocBuffer(data->size); if (!compressed_buffer) { return RT_BUFFER_ALLOC_FAILED; } if (rtSubmitSingleLoadSync((rt_file_load) { .file = data->pkg_file, .offset = data->offset, .num_bytes = data->size, .dest = compressed_buffer, }) != RT_AIO_STATE_FINISHED) { rtReleaseBuffer(compressed_buffer, data->size); return RT_LOAD_FAILED; } void *decompressed_buffer; size_t decompressed_size; rt_result res = DecompressAsset(compressed_buffer, data->size, &decompressed_buffer, &decompressed_size); rtReleaseBuffer(compressed_buffer, data->size); *p_buffer = decompressed_buffer; *p_size = decompressed_size; return res; }