mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-21 19:45:10 +00:00
Prevent the game from caching downloaded WIP mods (#69)
* don't tmp or cache wip mods * update
This commit is contained in:
parent
69cb215219
commit
c4214ed2da
10 changed files with 351 additions and 56 deletions
|
@ -9,6 +9,7 @@ extern "C" {
|
|||
#include "engine/math_util.h"
|
||||
#include "game/moving_texture.h"
|
||||
#include "pc/djui/djui_console.h"
|
||||
#include "pc/fs/fmem.h"
|
||||
}
|
||||
|
||||
#define FUNCTION_CODE (u32) 0x434E5546
|
||||
|
@ -95,16 +96,16 @@ public:
|
|||
|
||||
public:
|
||||
static BinFile *OpenR(const char *aFilename) {
|
||||
FILE *f = fopen(aFilename, "rb");
|
||||
FILE *f = f_open_r(aFilename);
|
||||
if (f) {
|
||||
fseek(f, 0, SEEK_END);
|
||||
f_seek(f, 0, SEEK_END);
|
||||
BinFile *_BinFile = (BinFile *) calloc(1, sizeof(BinFile));
|
||||
_BinFile->mFilename = (const char *) memcpy(calloc(strlen(aFilename) + 1, 1), aFilename, strlen(aFilename));
|
||||
_BinFile->mReadOnly = true;
|
||||
_BinFile->Grow(ftell(f));
|
||||
rewind(f);
|
||||
fread(_BinFile->mData, 1, _BinFile->mSize, f);
|
||||
fclose(f);
|
||||
_BinFile->Grow(f_tell(f));
|
||||
f_rewind(f);
|
||||
f_read(_BinFile->mData, 1, _BinFile->mSize, f);
|
||||
f_close(f);
|
||||
return _BinFile;
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -17,7 +17,7 @@ static inline void DynOS_Bin_Compress_Init() {
|
|||
}
|
||||
|
||||
static inline void DynOS_Bin_Compress_Close() {
|
||||
if (sFile) fclose(sFile);
|
||||
if (sFile) f_close(sFile);
|
||||
sFile = NULL;
|
||||
}
|
||||
|
||||
|
@ -159,14 +159,14 @@ BinFile *DynOS_Bin_Decompress(const SysPath &aFilename) {
|
|||
|
||||
// Open input file
|
||||
if (!DynOS_Bin_Compress_Check(
|
||||
(sFile = fopen(aFilename.c_str(), "rb")) != NULL,
|
||||
(sFile = f_open_r(aFilename.c_str())) != NULL,
|
||||
__FUNCTION__, aFilename.c_str(), "Cannot open file"
|
||||
)) return NULL;
|
||||
|
||||
// Read magic
|
||||
u64 _Magic = 0;
|
||||
if (!DynOS_Bin_Compress_Check(
|
||||
fread(&_Magic, sizeof(u64), 1, sFile) == 1,
|
||||
f_read(&_Magic, sizeof(u64), 1, sFile) == 1,
|
||||
__FUNCTION__, aFilename.c_str(), "Cannot read magic"
|
||||
)) return NULL;
|
||||
|
||||
|
@ -180,20 +180,20 @@ BinFile *DynOS_Bin_Decompress(const SysPath &aFilename) {
|
|||
|
||||
// Read expected uncompressed file size
|
||||
if (!DynOS_Bin_Compress_Check(
|
||||
fread(&sLengthUncompressed, sizeof(u64), 1, sFile) == 1,
|
||||
f_read(&sLengthUncompressed, sizeof(u64), 1, sFile) == 1,
|
||||
__FUNCTION__, aFilename.c_str(), "Cannot read uncompressed file size"
|
||||
)) return NULL;
|
||||
|
||||
// Retrieve file length
|
||||
if (!DynOS_Bin_Compress_Check(
|
||||
fseek(sFile, 0, SEEK_END) == 0,
|
||||
f_seek(sFile, 0, SEEK_END) == 0,
|
||||
__FUNCTION__, aFilename.c_str(), "Cannot retrieve file length"
|
||||
)) return NULL;
|
||||
|
||||
// Check file length
|
||||
u64 _LengthHeader = (u64) (sizeof(u64) + sizeof(u64));
|
||||
if (!DynOS_Bin_Compress_Check(
|
||||
(sLengthCompressed = (u64) ftell(sFile)) >= _LengthHeader,
|
||||
(sLengthCompressed = (u64) f_tell(sFile)) >= _LengthHeader,
|
||||
__FUNCTION__, aFilename.c_str(), "Empty file"
|
||||
)) return NULL;
|
||||
|
||||
|
@ -201,11 +201,11 @@ BinFile *DynOS_Bin_Decompress(const SysPath &aFilename) {
|
|||
if (!DynOS_Bin_Compress_Check(
|
||||
(sBufferCompressed = (u8 *) calloc(sLengthCompressed - _LengthHeader, sizeof(u8))) != NULL,
|
||||
__FUNCTION__, aFilename.c_str(), "Cannot allocate memory for decompression"
|
||||
)) return NULL; else fseek(sFile, _LengthHeader, SEEK_SET);
|
||||
)) return NULL; else f_seek(sFile, _LengthHeader, SEEK_SET);
|
||||
|
||||
// Read input data
|
||||
if (!DynOS_Bin_Compress_Check(
|
||||
fread(sBufferCompressed, sizeof(u8), sLengthCompressed - _LengthHeader, sFile) == sLengthCompressed - _LengthHeader,
|
||||
f_read(sBufferCompressed, sizeof(u8), sLengthCompressed - _LengthHeader, sFile) == sLengthCompressed - _LengthHeader,
|
||||
__FUNCTION__, aFilename.c_str(), "Cannot read compressed data"
|
||||
)) return NULL; else DynOS_Bin_Compress_Close();
|
||||
|
||||
|
|
164
src/pc/fs/fmem.c
Normal file
164
src/pc/fs/fmem.c
Normal file
|
@ -0,0 +1,164 @@
|
|||
#include "fmem.h"
|
||||
#include "pc/platform.h"
|
||||
#include "engine/math_util.h"
|
||||
|
||||
typedef struct file_t {
|
||||
char filename[SYS_MAX_PATH];
|
||||
void *data;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
bool readonly;
|
||||
} file_t;
|
||||
|
||||
typedef struct file_node_t {
|
||||
file_t file;
|
||||
struct file_node_t *prev;
|
||||
struct file_node_t *next;
|
||||
} file_node_t;
|
||||
|
||||
static file_node_t *sMemoryFiles = NULL;
|
||||
|
||||
static file_t *f_get_file_from_handle(FILE *f) {
|
||||
for (file_node_t *node = sMemoryFiles; node; node = node->prev) {
|
||||
if (node == (void *) f) {
|
||||
return &node->file;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static file_t *f_get_file_from_name(const char *filename) {
|
||||
for (file_node_t *node = sMemoryFiles; node; node = node->prev) {
|
||||
if (strcmp(node->file.filename, filename) == 0) {
|
||||
return &node->file;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static file_t *f_create_file(const char *filename) {
|
||||
file_node_t *node = calloc(1, sizeof(file_node_t));
|
||||
if (sMemoryFiles) {
|
||||
sMemoryFiles->next = node;
|
||||
node->prev = sMemoryFiles;
|
||||
}
|
||||
sMemoryFiles = node;
|
||||
strncpy(node->file.filename, filename, sizeof(node->file.filename) - 1);
|
||||
return &node->file;
|
||||
}
|
||||
|
||||
static void f_remove_file(file_t *file) {
|
||||
file_node_t *node = (file_node_t *) file;
|
||||
if (node->prev) {
|
||||
node->prev->next = node->next;
|
||||
}
|
||||
if (node->next) {
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
if (node == sMemoryFiles) {
|
||||
sMemoryFiles = node->prev;
|
||||
}
|
||||
if (file->data) {
|
||||
free(file->data);
|
||||
}
|
||||
free(node);
|
||||
}
|
||||
|
||||
FILE *f_open_r(const char *filename) {
|
||||
file_t *file = f_get_file_from_name(filename);
|
||||
if (!file) return fopen(filename, "rb");
|
||||
file->pos = 0;
|
||||
file->readonly = true;
|
||||
return (FILE *) file;
|
||||
}
|
||||
|
||||
FILE *f_open_w(const char *filename) {
|
||||
file_t *file = f_create_file(filename);
|
||||
return (FILE *) file;
|
||||
}
|
||||
|
||||
int f_close(FILE *f) {
|
||||
file_t *file = f_get_file_from_handle(f);
|
||||
if (!file) return fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void f_delete(FILE *f) {
|
||||
file_t *file = f_get_file_from_handle(f);
|
||||
if (!file) return;
|
||||
f_remove_file(file);
|
||||
}
|
||||
|
||||
size_t f_read(void *dst, size_t size, size_t count, FILE *f) {
|
||||
file_t *file = f_get_file_from_handle(f);
|
||||
if (!file) return fread(dst, size, count, f);
|
||||
if (file->pos >= file->size) return 0;
|
||||
count = min(count, ((file->size - file->pos) / size));
|
||||
memcpy(dst, file->data + file->pos, count * size);
|
||||
file->pos += count * size;
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t f_write(const void *str, size_t size, size_t count, FILE *f) {
|
||||
file_t *file = f_get_file_from_handle(f);
|
||||
if (!file) return fwrite(str, size, count, f);
|
||||
if (file->readonly) return 0;
|
||||
size_t newsize = file->pos + size * count;
|
||||
if (newsize > file->size) {
|
||||
void *buffer = malloc(newsize);
|
||||
if (!buffer) {
|
||||
return 0;
|
||||
}
|
||||
if (file->data) {
|
||||
memcpy(buffer, file->data, file->size);
|
||||
free(file->data);
|
||||
}
|
||||
file->data = buffer;
|
||||
file->size = newsize;
|
||||
}
|
||||
memcpy(file->data + file->pos, str, size * count);
|
||||
file->pos += size * count;
|
||||
return count;
|
||||
}
|
||||
|
||||
int f_seek(FILE *f, long offset, int origin) {
|
||||
file_t *file = f_get_file_from_handle(f);
|
||||
if (!file) return fseek(f, offset, origin);
|
||||
switch (origin) {
|
||||
case SEEK_SET: file->pos = offset; break;
|
||||
case SEEK_CUR: file->pos += offset; break;
|
||||
case SEEK_END: file->pos = file->size + offset; break;
|
||||
default: return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long f_tell(FILE *f) {
|
||||
file_t *file = f_get_file_from_handle(f);
|
||||
if (!file) return ftell(f);
|
||||
return file->pos;
|
||||
}
|
||||
|
||||
void f_rewind(FILE *f) {
|
||||
file_t *file = f_get_file_from_handle(f);
|
||||
if (!file) return rewind(f);
|
||||
file->pos = 0;
|
||||
}
|
||||
|
||||
int f_flush(FILE *f) {
|
||||
file_t *file = f_get_file_from_handle(f);
|
||||
if (!file) return fflush(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void f_shutdown() {
|
||||
for (file_node_t *node = sMemoryFiles; node;) {
|
||||
if (node->file.data) {
|
||||
free(node->file.data);
|
||||
}
|
||||
file_node_t *prev = node->prev;
|
||||
free(node);
|
||||
node = prev;
|
||||
}
|
||||
sMemoryFiles = NULL;
|
||||
}
|
18
src/pc/fs/fmem.h
Normal file
18
src/pc/fs/fmem.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef FMEM_H
|
||||
#define FMEM_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
FILE *f_open_r (const char *filename);
|
||||
FILE *f_open_w (const char *filename);
|
||||
int f_close (FILE *f);
|
||||
void f_delete (FILE *f);
|
||||
size_t f_read (void *dst, size_t size, size_t count, FILE *f);
|
||||
size_t f_write (const void *str, size_t size, size_t count, FILE *f);
|
||||
int f_seek (FILE *f, long offset, int origin);
|
||||
long f_tell (FILE *f);
|
||||
void f_rewind (FILE *f);
|
||||
int f_flush (FILE *f);
|
||||
void f_shutdown ();
|
||||
|
||||
#endif
|
|
@ -9,6 +9,7 @@
|
|||
#include "pc/lua/utils/smlua_level_utils.h"
|
||||
#include "pc/lua/utils/smlua_anim_utils.h"
|
||||
#include "pc/djui/djui.h"
|
||||
#include "pc/fs/fmem.h"
|
||||
|
||||
lua_State* gLuaState = NULL;
|
||||
u8 gLuaInitializingScript = 0;
|
||||
|
@ -81,28 +82,30 @@ void smlua_exec_str(const char* str) {
|
|||
#define LUA_BOM_19 0x4077280000000000llu
|
||||
|
||||
static bool smlua_check_binary_header(struct ModFile *file) {
|
||||
FILE *f = fopen(file->cachedPath, "rb");
|
||||
FILE *f = f_open_r(file->cachedPath);
|
||||
if (f) {
|
||||
|
||||
// Read signature
|
||||
char signature[sizeof(LUA_SIGNATURE)] = { 0 };
|
||||
if (fread(signature, 1, sizeof(LUA_SIGNATURE) - 1, f) != sizeof(LUA_SIGNATURE) - 1) {
|
||||
if (f_read(signature, 1, sizeof(LUA_SIGNATURE) - 1, f) != sizeof(LUA_SIGNATURE) - 1) {
|
||||
LOG_LUA("Failed to load lua script '%s': File too short.", file->cachedPath);
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check signature
|
||||
if (strcmp(signature, LUA_SIGNATURE) != 0) {
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
return true; // Not a binary lua
|
||||
}
|
||||
|
||||
// Read version number
|
||||
u8 version;
|
||||
if (fread(&version, 1, 1, f) != 1) {
|
||||
if (f_read(&version, 1, 1, f) != 1) {
|
||||
LOG_LUA("Failed to load lua script '%s': File too short.", file->cachedPath);
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -110,15 +113,17 @@ static bool smlua_check_binary_header(struct ModFile *file) {
|
|||
u8 expectedVersion = strtoul(LUA_VERSION_MAJOR LUA_VERSION_MINOR, NULL, 16);
|
||||
if (version != expectedVersion) {
|
||||
LOG_LUA("Failed to load lua script '%s': Lua versions don't match (%X, expected %X).", file->cachedPath, version, expectedVersion);
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the rest of the header
|
||||
u8 header[28];
|
||||
if (fread(header, 1, 28, f) != 28) {
|
||||
if (f_read(header, 1, 28, f) != 28) {
|
||||
LOG_LUA("Failed to load lua script '%s': File too short.", file->cachedPath);
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -129,12 +134,14 @@ static bool smlua_check_binary_header(struct ModFile *file) {
|
|||
u64 bom19 = *((u64 *) (header + 20));
|
||||
if (bom11 != LUA_BOM_11) {
|
||||
LOG_ERROR("Failed to load lua script '%s': BOM at offset 0x11 don't match (%016llX, expected %016llX).", file->cachedPath, bom11, LUA_BOM_11);
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
return false;
|
||||
}
|
||||
if (bom19 != LUA_BOM_19) {
|
||||
LOG_ERROR("Failed to load lua script '%s': BOM at offset 0x19 don't match (%016llX, expected %016llX).", file->cachedPath, bom19, LUA_BOM_19);
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -146,33 +153,37 @@ static bool smlua_check_binary_header(struct ModFile *file) {
|
|||
u8 sizeOfLuaNumber = header[11];
|
||||
if (sizeOfCInteger != sizeof(int)) {
|
||||
LOG_ERROR("Failed to load lua script '%s': sizes of C Integer don't match (%d, expected %llu).", file->cachedPath, sizeOfCInteger, (long long unsigned)sizeof(int));
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
return false;
|
||||
}
|
||||
if (sizeOfCPointer != sizeof(void *)) { // 4 for 32-bit architectures, 8 for 64-bit
|
||||
LOG_ERROR("Failed to load lua script '%s': sizes of C Pointer don't match (%d, expected %llu).", file->cachedPath, sizeOfCPointer, (long long unsigned)sizeof(void *));
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
return false;
|
||||
}
|
||||
if (sizeOfCFloat != sizeof(float)) {
|
||||
LOG_ERROR("Failed to load lua script '%s': sizes of C Float don't match (%d, expected %llu).", file->cachedPath, sizeOfCFloat, (long long unsigned)sizeof(float));
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
return false;
|
||||
}
|
||||
if (sizeOfLuaInteger != sizeof(LUA_INTEGER)) {
|
||||
LOG_ERROR("Failed to load lua script '%s': sizes of Lua Integer don't match (%d, expected %llu).", file->cachedPath, sizeOfLuaInteger, (long long unsigned)sizeof(LUA_INTEGER));
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
return false;
|
||||
}
|
||||
if (sizeOfLuaNumber != sizeof(LUA_NUMBER)) {
|
||||
LOG_ERROR("Failed to load lua script '%s': sizes of Lua Number don't match (%d, expected %llu).", file->cachedPath, sizeOfLuaNumber, (long long unsigned)sizeof(LUA_NUMBER));
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
// All's good
|
||||
LOG_INFO("Loading lua script '%s'", file->cachedPath);
|
||||
fclose(f);
|
||||
f_close(f);
|
||||
return true;
|
||||
}
|
||||
LOG_LUA("Failed to load lua script '%s': File not found.", file->cachedPath);
|
||||
|
@ -190,13 +201,40 @@ static void smlua_load_script(struct Mod* mod, struct ModFile* file, u16 remoteI
|
|||
gLuaInitializingScript = 1;
|
||||
LOG_INFO("Loading lua script '%s'", file->cachedPath);
|
||||
|
||||
if (luaL_loadfile(L, file->cachedPath) != LUA_OK) { // only run on success
|
||||
LOG_LUA("Failed to load lua script '%s'.", file->cachedPath);
|
||||
LOG_LUA("%s", smlua_to_string(L, lua_gettop(L)));
|
||||
FILE *f = f_open_r(file->cachedPath);
|
||||
if (!f) {
|
||||
LOG_LUA("Failed to load lua script '%s': File not found.", file->cachedPath);
|
||||
gLuaInitializingScript = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
f_seek(f, 0, SEEK_END);
|
||||
size_t length = f_tell(f);
|
||||
char *buffer = calloc(length + 1, 1);
|
||||
if (!buffer) {
|
||||
LOG_LUA("Failed to load lua script '%s': Cannot allocate buffer.", file->cachedPath);
|
||||
gLuaInitializingScript = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
f_rewind(f);
|
||||
if (f_read(buffer, 1, length, f) < length) {
|
||||
LOG_LUA("Failed to load lua script '%s': Unexpected early end of file.", file->cachedPath);
|
||||
gLuaInitializingScript = 0;
|
||||
return;
|
||||
}
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
|
||||
if (luaL_loadstring(L, buffer) != LUA_OK) { // only run on success
|
||||
LOG_LUA("Failed to load lua script '%s'.", file->cachedPath);
|
||||
LOG_LUA("%s", smlua_to_string(L, lua_gettop(L)));
|
||||
gLuaInitializingScript = 0;
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
free(buffer);
|
||||
|
||||
// check if this is the first time this mod has been loaded
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath);
|
||||
bool firstInit = (lua_type(L, -1) == LUA_TNIL);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "pc/utils/misc.h"
|
||||
#include "pc/debuglog.h"
|
||||
#include "pc/pc_main.h"
|
||||
#include "pc/fs/fmem.h"
|
||||
#include "audio/external.h"
|
||||
|
||||
struct AudioOverride {
|
||||
|
@ -81,22 +82,24 @@ bool smlua_audio_utils_override(u8 sequenceId, s32* bankId, void** seqData) {
|
|||
static u8* buffer = NULL;
|
||||
static long int length = 0;
|
||||
|
||||
FILE* fp = fopen(override->filename, "rb");
|
||||
FILE* fp = f_open_r(override->filename);
|
||||
if (!fp) { return false; }
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
length = ftell(fp);
|
||||
f_seek(fp, 0L, SEEK_END);
|
||||
length = f_tell(fp);
|
||||
|
||||
buffer = malloc(length+1);
|
||||
if (buffer == NULL) {
|
||||
LOG_ERROR("Failed to malloc m64 sound file");
|
||||
fclose(fp);
|
||||
f_close(fp);
|
||||
f_delete(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
fread(buffer, length, 1, fp);
|
||||
f_seek(fp, 0L, SEEK_SET);
|
||||
f_read(buffer, length, 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
f_close(fp);
|
||||
f_delete(fp);
|
||||
|
||||
// cache
|
||||
override->loaded = true;
|
||||
|
@ -251,12 +254,53 @@ struct ModAudio* audio_load_internal(const char* filename, bool isStream) {
|
|||
audio->file = modFile;
|
||||
|
||||
// load audio
|
||||
ma_result result = ma_sound_init_from_file(
|
||||
&gModAudioEngine, modFile->cachedPath,
|
||||
FILE *f = f_open_r(modFile->cachedPath);
|
||||
if (!f) {
|
||||
LOG_ERROR("failed to load audio file '%s': file not found", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f_seek(f, 0, SEEK_END);
|
||||
u32 size = f_tell(f);
|
||||
f_rewind(f);
|
||||
void *buffer = calloc(size, 1);
|
||||
if (!buffer) {
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
LOG_ERROR("failed to load audio file '%s': cannot allocate buffer of size: %d", filename, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// read the audio buffer
|
||||
if (f_read(buffer, 1, size, f) < size) {
|
||||
free(buffer);
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
LOG_ERROR("failed to load audio file '%s': cannot read audio buffer of size: %d", filename, size);
|
||||
return NULL;
|
||||
}
|
||||
f_close(f);
|
||||
f_delete(f);
|
||||
|
||||
// decode the audio buffer
|
||||
// note: buffer and decoder are not freed after a successful call, because ma_decoder_init_memory() does not make copies of them
|
||||
ma_decoder *decoder = calloc(1, sizeof(ma_decoder));
|
||||
ma_result result = ma_decoder_init_memory(buffer, size, NULL, decoder);
|
||||
if (result != MA_SUCCESS) {
|
||||
free(decoder);
|
||||
free(buffer);
|
||||
LOG_ERROR("failed to load audio file '%s': failed to decode raw audio: %d", filename, result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = ma_sound_init_from_data_source(
|
||||
&gModAudioEngine, decoder,
|
||||
isStream ? MA_SOUND_STREAM_FLAGS : MA_SOUND_SAMPLE_FLAGS,
|
||||
NULL, NULL, &audio->sound
|
||||
NULL, &audio->sound
|
||||
);
|
||||
if (result != MA_SUCCESS) {
|
||||
free(decoder);
|
||||
free(buffer);
|
||||
LOG_ERROR("failed to load audio file '%s': %d", filename, result);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "pc/utils/misc.h"
|
||||
#include "pc/utils/md5.h"
|
||||
#include "pc/debuglog.h"
|
||||
#include "pc/fs/fmem.h"
|
||||
|
||||
size_t mod_get_lua_size(struct Mod* mod) {
|
||||
if (!mod) { return 0; }
|
||||
|
@ -171,7 +172,8 @@ void mod_clear(struct Mod* mod) {
|
|||
for (int j = 0; j < mod->fileCount; j++) {
|
||||
struct ModFile* file = &mod->files[j];
|
||||
if (file->fp != NULL) {
|
||||
fclose(file->fp);
|
||||
f_close(file->fp);
|
||||
f_delete(file->fp);
|
||||
file->fp = NULL;
|
||||
}
|
||||
if (file->cachedPath != NULL) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "data/dynos.c.h"
|
||||
#include "pc/debuglog.h"
|
||||
#include "pc/loading.h"
|
||||
#include "pc/fs/fmem.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
|
@ -322,7 +323,8 @@ void mods_clear(struct Mods* mods) {
|
|||
for (int j = 0; j < mod->fileCount; j++) {
|
||||
struct ModFile* file = &mod->files[j];
|
||||
if (file->fp != NULL) {
|
||||
fclose(file->fp);
|
||||
f_close(file->fp);
|
||||
f_delete(file->fp);
|
||||
file->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "pc/debuglog.h"
|
||||
#include "pc/pc_main.h"
|
||||
#include "pc/gfx/gfx_pc.h"
|
||||
#include "pc/fs/fmem.h"
|
||||
#include "game/camera.h"
|
||||
#include "game/skybox.h"
|
||||
#include "game/object_list_processor.h"
|
||||
|
@ -726,6 +727,7 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect
|
|||
save_file_load_all(TRUE);
|
||||
extern void save_file_set_using_backup_slot(bool usingBackupSlot);
|
||||
save_file_set_using_backup_slot(false);
|
||||
f_shutdown();
|
||||
|
||||
extern s16 gMenuMode;
|
||||
gMenuMode = -1;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "pc/djui/djui_panel_join_message.h"
|
||||
//#define DISABLE_MODULE_LOG 1
|
||||
#include "pc/debuglog.h"
|
||||
#include "pc/fs/fmem.h"
|
||||
|
||||
#define CHUNK_SIZE 800
|
||||
#define OFFSET_COUNT 50
|
||||
|
@ -191,8 +192,8 @@ static void network_update_offset_groups(void) {
|
|||
for (u64 fileIndex = 0; fileIndex < mod->fileCount; fileIndex++) {
|
||||
struct ModFile* modFile = &mod->files[fileIndex];
|
||||
if (modFile->fp == NULL) { continue; }
|
||||
fflush(modFile->fp);
|
||||
fclose(modFile->fp);
|
||||
f_flush(modFile->fp);
|
||||
f_close(modFile->fp);
|
||||
modFile->fp = NULL;
|
||||
}
|
||||
mod->enabled = true;
|
||||
|
@ -315,6 +316,18 @@ after_filled:;
|
|||
//LOG_INFO("Sent chunk: offset %llu, length %llu", requestOffset, chunkFill);
|
||||
}
|
||||
|
||||
// Cache any mod that doesn't have "(wip)" or "[wip]" in its name (case-insensitive)
|
||||
static bool should_cache_mod(struct Mod *mod) {
|
||||
char *modName = sys_strdup(mod->name);
|
||||
sys_strlwr(modName);
|
||||
bool shouldCache = (
|
||||
!strstr(modName, "(wip)") &&
|
||||
!strstr(modName, "[wip]")
|
||||
);
|
||||
free(modName);
|
||||
return shouldCache;
|
||||
}
|
||||
|
||||
static void open_mod_file(struct Mod* mod, struct ModFile* file) {
|
||||
if (file->fp != NULL) {
|
||||
return;
|
||||
|
@ -326,10 +339,13 @@ static void open_mod_file(struct Mod* mod, struct ModFile* file) {
|
|||
return;
|
||||
}
|
||||
|
||||
mod_file_create_directories(mod, file);
|
||||
|
||||
file->wroteBytes = 0;
|
||||
file->fp = fopen(fullPath, "wb");
|
||||
if (should_cache_mod(mod)) {
|
||||
mod_file_create_directories(mod, file);
|
||||
file->fp = fopen(fullPath, "wb");
|
||||
} else {
|
||||
file->fp = f_open_w(fullPath);
|
||||
}
|
||||
if (file->fp == NULL) {
|
||||
LOG_ERROR("unable to open for write: '%s' - '%s'", fullPath, strerror(errno));
|
||||
return;
|
||||
|
@ -430,14 +446,22 @@ after_group:;
|
|||
LOG_ERROR("Failed to open file for download write: %s", modFile->cachedPath);
|
||||
return;
|
||||
}
|
||||
fseek(modFile->fp, fileWriteOffset, SEEK_SET);
|
||||
fwrite(&chunk[chunkPour], sizeof(u8), fileWriteLength, modFile->fp);
|
||||
f_seek(modFile->fp, fileWriteOffset, SEEK_SET);
|
||||
f_write(&chunk[chunkPour], sizeof(u8), fileWriteLength, modFile->fp);
|
||||
modFile->wroteBytes += fileWriteLength;
|
||||
|
||||
if (modFile->wroteBytes >= modFile->size) {
|
||||
fflush(modFile->fp);
|
||||
fclose(modFile->fp);
|
||||
f_flush(modFile->fp);
|
||||
f_close(modFile->fp);
|
||||
modFile->fp = NULL;
|
||||
|
||||
// Write cachedPath here so the file doesn't end up in mod.cache
|
||||
if (!should_cache_mod(mod)) {
|
||||
char modFilePath[SYS_MAX_PATH] = { 0 };
|
||||
concat_path(modFilePath, mod->basePath, modFile->relativePath);
|
||||
normalize_path(modFilePath);
|
||||
modFile->cachedPath = strdup(modFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
wroteBytes += fileWriteLength;
|
||||
|
|
Loading…
Reference in a new issue