diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index 840e031e0..d30ac1f6f 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -4661,6 +4661,15 @@ GRAB_POS_BOWSER = 3 --- @type MarioGrabPosGSCId --- | `GRAB_POS_HEAVY_OBJ` --- | `GRAB_POS_BOWSER` +--- @type integer +MOD_FS_COMPRESSION_MIN = 0 + +--- @type integer +MOD_FS_COMPRESSION_MAX = 9 + +--- @type integer +MOD_FS_COMPRESSION_DEFAULT = 1 + --- @type integer MOD_FS_MAX_SIZE = 0x2000000 diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 92f9197a7..e8870f6c9 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -7763,6 +7763,14 @@ function mod_fs_file_set_public(file, pub) -- ... end +--- @param file ModFsFile +--- @param level integer +--- @return boolean +--- Sets the compression level of the provided modfs `file`. Must be between 0 (no compression) and 9 (most compression). Returns true on success. +function mod_fs_file_set_compression(file, level) + -- ... +end + --- @param hide boolean --- Hides script errors raised by `mod_fs` functions. Errors messages are still generated and can be retrieved with `mod_fs_get_last_error()` function mod_fs_hide_errors(hide) diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index 5441e7424..c39734496 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -1222,6 +1222,7 @@ --- @field public filepath string --- @field public size integer --- @field public offset integer +--- @field public compressionLevel integer --- @field public isText boolean --- @field public isPublic boolean --- @field public read_bool fun(file: ModFsFile): boolean @@ -1243,6 +1244,7 @@ --- @field public erase fun(file: ModFsFile, length: integer): boolean --- @field public set_text_mode fun(file: ModFsFile, text: boolean): boolean --- @field public set_public fun(file: ModFsFile, pub: boolean): boolean +--- @field public set_compression fun(file: ModFsFile, level: integer): boolean --- @class NametagsSettings --- @field public showHealth boolean diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index e0b699d9d..af15a4490 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -22,7 +22,8 @@ extern "C" { #define FUNCTION_BHV 2 #define FUNCTION_LVL 3 -#define MOD_PACK_INDEX 99 +#define MOD_PACK_INDEX -1 // the pack index for actors loaded from mods +#define PACK_MOD_INDEX -1 // the mod index for actors loaded from packs // // Enums diff --git a/data/dynos_bin_actor.cpp b/data/dynos_bin_actor.cpp index 7d521bc30..4443b1dc6 100644 --- a/data/dynos_bin_actor.cpp +++ b/data/dynos_bin_actor.cpp @@ -94,6 +94,9 @@ GfxData *DynOS_Actor_LoadFromBinary(const SysPath &aPackFolder, const char *aAct BinFile *_File = DynOS_Bin_Decompress(aFilename); if (_File) { _GfxData = New(); + if (aAddToPack) { + _GfxData->mModIndex = PACK_MOD_INDEX; + } for (bool _Done = false; !_Done;) { switch (_File->Read()) { case DATA_TYPE_LIGHT: DynOS_Lights_Load (_File, _GfxData); break; diff --git a/data/dynos_bin_pointer.cpp b/data/dynos_bin_pointer.cpp index e619d7631..5ece3facc 100644 --- a/data/dynos_bin_pointer.cpp +++ b/data/dynos_bin_pointer.cpp @@ -465,6 +465,10 @@ void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8 aFunc // LUAV if (aValue == LUA_VAR_CODE) { String token; token.Read(aFile); + if (aGfxData->mModIndex == PACK_MOD_INDEX) { + sys_fatal("Invalid use of Lua function in DynOS pack: %s", token.begin()); + return NULL; + } for (s32 i = 0; i < aGfxData->mLuaTokenList.Count(); i++) { if (token == aGfxData->mLuaTokenList[i]) { return (void*)(uintptr_t)(i+1); diff --git a/data/dynos_mgr_actor.cpp b/data/dynos_mgr_actor.cpp index 802a4ee37..e47ae6823 100644 --- a/data/dynos_mgr_actor.cpp +++ b/data/dynos_mgr_actor.cpp @@ -220,7 +220,7 @@ void DynOS_Actor_Override(struct Object* obj, void** aSharedChild) { obj->behavior == smlua_override_behavior(bhvMetalCap) || obj->behavior == smlua_override_behavior(bhvVanishCap))) { struct NetworkPlayer* np = network_player_from_global_index(obj->globalPlayerIndex); - if (np && np->localIndex > 0 && configDynosLocalPlayerModelOnly) { + if (np && np->localIndex > 0 && configDynosLocalPlayerModelOnly && it->second.mPackIndex != MOD_PACK_INDEX) { return; } } diff --git a/data/dynos_mgr_builtin.cpp b/data/dynos_mgr_builtin.cpp index f5ecde10e..bafcc8e3b 100644 --- a/data/dynos_mgr_builtin.cpp +++ b/data/dynos_mgr_builtin.cpp @@ -2037,7 +2037,6 @@ static const DynosBuiltinFunction sDynosBuiltinFuncs[] = { define_builtin_function(bhv_ambient_light_update, FUNCTION_BHV), define_builtin_function(bhv_point_light_init, FUNCTION_BHV), define_builtin_function(bhv_point_light_loop, FUNCTION_BHV), - define_builtin_function(geo_switch_character_type_ext, FUNCTION_GEO), }; static const char *sDynosBuiltinFuncTypeNames[] = { @@ -2088,7 +2087,7 @@ static String DynOS_Builtin_Func_CheckMisuse_Internal(s32 aIndex, const char* aD if (aFuncType != builtinFunc.type && ( aIndex == i || (aDataName && strcmp(aDataName, builtinFunc.name) == 0) || aData == builtinFunc.func)) { return String( - "Invalid use of function %s: trying to assign %s function to %s", + "Invalid use of %s function in %s: %s", builtinFunc.name, sDynosBuiltinFuncTypeNames[builtinFunc.type], sDynosBuiltinFuncTypeNames[aFuncType] diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 848b915fa..265f50742 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -2176,6 +2176,9 @@
## [mod_fs.h](#mod_fs.h) +- MOD_FS_COMPRESSION_MIN +- MOD_FS_COMPRESSION_MAX +- MOD_FS_COMPRESSION_DEFAULT - MOD_FS_MAX_SIZE - MOD_FS_MAX_FILES - MOD_FS_MAX_PATH diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md index fea3820bb..92990911d 100644 --- a/docs/lua/functions-5.md +++ b/docs/lua/functions-5.md @@ -2117,6 +2117,30 @@ Marks the provided modfs `file` as public (i.e. readable by other mods). Returns
+## [mod_fs_file_set_compression](#mod_fs_file_set_compression) + +### Description +Sets the compression level of the provided modfs `file`. Must be between 0 (no compression) and 9 (most compression). Returns true on success. + +### Lua Example +`local booleanValue = mod_fs_file_set_compression(file, level)` + +### Parameters +| Field | Type | +| ----- | ---- | +| file | [ModFsFile](structs.md#ModFsFile) | +| level | `integer` | + +### Returns +- `boolean` + +### C Prototype +`bool mod_fs_file_set_compression(struct ModFsFile *file, s32 level);` + +[:arrow_up_small:](#) + +
+ ## [mod_fs_hide_errors](#mod_fs_hide_errors) ### Description diff --git a/docs/lua/functions.md b/docs/lua/functions.md index cb99a187c..af8ec40a4 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -1399,6 +1399,7 @@ - [mod_fs_file_erase](functions-5.md#mod_fs_file_erase) - [mod_fs_file_set_text_mode](functions-5.md#mod_fs_file_set_text_mode) - [mod_fs_file_set_public](functions-5.md#mod_fs_file_set_public) + - [mod_fs_file_set_compression](functions-5.md#mod_fs_file_set_compression) - [mod_fs_hide_errors](functions-5.md#mod_fs_hide_errors) - [mod_fs_get_last_error](functions-5.md#mod_fs_get_last_error) diff --git a/docs/lua/guides/modfs.md b/docs/lua/guides/modfs.md index 41be978bb..5e840db63 100644 --- a/docs/lua/guides/modfs.md +++ b/docs/lua/guides/modfs.md @@ -126,6 +126,7 @@ print("The ModFS file " .. file.filepath .. " is " .. file.size .. " bytes long. | erase | [`mod_fs_file_erase`](../functions-5.md#mod_fs_file_erase) | | set_text_mode | [`mod_fs_file_set_text_mode`](../functions-5.md#mod_fs_file_set_text_mode) | | set_public | [`mod_fs_file_set_public`](../functions-5.md#mod_fs_file_set_public) | +| set_compression | [`mod_fs_file_set_compression`](../functions-5.md#mod_fs_file_set_compression) | Methods can be called in Lua with the colon `:` character: ```lua @@ -270,3 +271,16 @@ The mod has to explicitly call the method `save` to save its ModFS on the disk. ```lua modFs:save() ``` + +
+ +## Compression + +ModFS files can each have their compression level explicitly set. By default this is set to 1 for minimal compression.
+Although it makes no difference to the total size limit, changing the compression level can be useful if you are trying to optimize for CPU time.
+The compression level can be any integer between 0-9.
+```lua +file:set_compression(MOD_FS_COMPRESSION_MIN) -- no compression, good for small data that changes frequently + +file:set_compression(MOD_FS_COMPRESSION_MAX) -- max compression, good for large data that is read infrequently +``` \ No newline at end of file diff --git a/docs/lua/structs.md b/docs/lua/structs.md index 79c6d19ff..8fc531350 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -1789,6 +1789,7 @@ | filepath | `string` | read-only | | size | `integer` | read-only | | offset | `integer` | read-only | +| compressionLevel | `integer` | read-only | | isText | `boolean` | read-only | | isPublic | `boolean` | read-only | @@ -1815,6 +1816,7 @@ | erase | [`mod_fs_file_erase`](functions-5.md#mod_fs_file_erase) | | set_text_mode | [`mod_fs_file_set_text_mode`](functions-5.md#mod_fs_file_set_text_mode) | | set_public | [`mod_fs_file_set_public`](functions-5.md#mod_fs_file_set_public) | +| set_compression | [`mod_fs_file_set_compression`](functions-5.md#mod_fs_file_set_compression) | [:arrow_up_small:](#) diff --git a/dynos/packs/Coop Cafe Pipe/warp_pipe_geo.bin b/dynos/packs/Coop Cafe Pipe/warp_pipe_geo.bin deleted file mode 100644 index 6e88dc161..000000000 Binary files a/dynos/packs/Coop Cafe Pipe/warp_pipe_geo.bin and /dev/null differ diff --git a/mods/faster-swimming.lua b/mods/faster-swimming.lua index 7b76cb9ef..cd0d65359 100644 --- a/mods/faster-swimming.lua +++ b/mods/faster-swimming.lua @@ -8,7 +8,12 @@ function mario_before_phys_step(m) -- faster swimming if (m.action & ACT_FLAG_SWIMMING) ~= 0 then hScale = hScale * 2.0 - if m.action ~= ACT_WATER_PLUNGE then + if + m.action ~= ACT_WATER_PLUNGE + and m.action ~= ACT_BACKWARD_WATER_KB + and m.action ~= ACT_FORWARD_WATER_KB + and m.action ~= ACT_DROWNING + then vScale = vScale * 2.0 end end diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index f48aa1f43..ff35fe280 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -187,21 +187,6 @@ Gfx *geo_switch_anim_state(s32 callContext, struct GraphNode *node) { return NULL; } -Gfx *geo_switch_character_type_ext(s32 callContext, struct GraphNode *node, UNUSED void *context) { - struct GraphNodeSwitchCase *switchCase; - - if (callContext == GEO_CONTEXT_RENDER) { - // move to a local var because GraphNodes are passed in all geo functions. - // cast the pointer. - switchCase = (struct GraphNodeSwitchCase *) node; - - // assign the case number for execution. - switchCase->selectedCase = gMarioState->character->type; - } - - return NULL; -} - s16 gRoomOverride = -1; /* |description|Overrides the current room Mario is in. Set to -1 to reset override|descriptionEnd| */ diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h index 9e8ef665c..d004ecbeb 100644 --- a/src/game/object_helpers.h +++ b/src/game/object_helpers.h @@ -71,7 +71,6 @@ Gfx *geo_switch_area(s32 callContext, struct GraphNode *node, UNUSED void *conte Gfx *geo_switch_anim_state(s32 callContext, struct GraphNode *node); Gfx *geo_switch_area(s32 callContext, struct GraphNode *node); #endif -Gfx *geo_switch_character_type_ext(s32 callContext, struct GraphNode *node, UNUSED void *context); Gfx *geo_choose_area_ext(s32 callContext, UNUSED struct GraphNode *node, Mat4 mtx); void obj_update_pos_from_parent_transformation(Mat4 a0, struct Object *a1); void obj_apply_scale_to_matrix(struct Object *obj, VEC_OUT Mat4 dst, Mat4 src); diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index 35a3ce52d..694fc800f 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -1509,33 +1509,35 @@ static struct LuaObjectField sModFsFields[LUA_MOD_FS_FIELD_COUNT] = { { "totalSize", LVT_U32, offsetof(struct ModFs, totalSize), true, LOT_NONE, 1, sizeof(u32) }, }; -#define LUA_MOD_FS_FILE_FIELD_COUNT 25 +#define LUA_MOD_FS_FILE_FIELD_COUNT 27 static struct LuaObjectField sModFsFileFields[LUA_MOD_FS_FILE_FIELD_COUNT] = { - { "erase", LVT_FUNCTION, (size_t) "mod_fs_file_erase", true, LOT_NONE, 1, sizeof(const char *) }, - { "filepath", LVT_STRING, offsetof(struct ModFsFile, filepath), true, LOT_NONE, 1, sizeof(char) }, - { "fill", LVT_FUNCTION, (size_t) "mod_fs_file_fill", true, LOT_NONE, 1, sizeof(const char *) }, - { "isPublic", LVT_BOOL, offsetof(struct ModFsFile, isPublic), true, LOT_NONE, 1, sizeof(bool) }, - { "isText", LVT_BOOL, offsetof(struct ModFsFile, isText), true, LOT_NONE, 1, sizeof(bool) }, - { "is_eof", LVT_FUNCTION, (size_t) "mod_fs_file_is_eof", true, LOT_NONE, 1, sizeof(const char *) }, - { "modFs", LVT_COBJECT_P, offsetof(struct ModFsFile, modFs), true, LOT_MODFS, 1, sizeof(struct ModFs*) }, - { "offset", LVT_U32, offsetof(struct ModFsFile, offset), true, LOT_NONE, 1, sizeof(u32) }, - { "read_bool", LVT_FUNCTION, (size_t) "mod_fs_file_read_bool", true, LOT_NONE, 1, sizeof(const char *) }, - { "read_bytes", LVT_FUNCTION, (size_t) "mod_fs_file_read_bytes", true, LOT_NONE, 1, sizeof(const char *) }, - { "read_integer", LVT_FUNCTION, (size_t) "mod_fs_file_read_integer", true, LOT_NONE, 1, sizeof(const char *) }, - { "read_line", LVT_FUNCTION, (size_t) "mod_fs_file_read_line", true, LOT_NONE, 1, sizeof(const char *) }, - { "read_number", LVT_FUNCTION, (size_t) "mod_fs_file_read_number", true, LOT_NONE, 1, sizeof(const char *) }, - { "read_string", LVT_FUNCTION, (size_t) "mod_fs_file_read_string", true, LOT_NONE, 1, sizeof(const char *) }, - { "rewind", LVT_FUNCTION, (size_t) "mod_fs_file_rewind", true, LOT_NONE, 1, sizeof(const char *) }, - { "seek", LVT_FUNCTION, (size_t) "mod_fs_file_seek", true, LOT_NONE, 1, sizeof(const char *) }, - { "set_public", LVT_FUNCTION, (size_t) "mod_fs_file_set_public", true, LOT_NONE, 1, sizeof(const char *) }, - { "set_text_mode", LVT_FUNCTION, (size_t) "mod_fs_file_set_text_mode", true, LOT_NONE, 1, sizeof(const char *) }, - { "size", LVT_U32, offsetof(struct ModFsFile, size), true, LOT_NONE, 1, sizeof(u32) }, - { "write_bool", LVT_FUNCTION, (size_t) "mod_fs_file_write_bool", true, LOT_NONE, 1, sizeof(const char *) }, - { "write_bytes", LVT_FUNCTION, (size_t) "mod_fs_file_write_bytes", true, LOT_NONE, 1, sizeof(const char *) }, - { "write_integer", LVT_FUNCTION, (size_t) "mod_fs_file_write_integer", true, LOT_NONE, 1, sizeof(const char *) }, - { "write_line", LVT_FUNCTION, (size_t) "mod_fs_file_write_line", true, LOT_NONE, 1, sizeof(const char *) }, - { "write_number", LVT_FUNCTION, (size_t) "mod_fs_file_write_number", true, LOT_NONE, 1, sizeof(const char *) }, - { "write_string", LVT_FUNCTION, (size_t) "mod_fs_file_write_string", true, LOT_NONE, 1, sizeof(const char *) }, + { "compressionLevel", LVT_S32, offsetof(struct ModFsFile, compressionLevel), true, LOT_NONE, 1, sizeof(s32) }, + { "erase", LVT_FUNCTION, (size_t) "mod_fs_file_erase", true, LOT_NONE, 1, sizeof(const char *) }, + { "filepath", LVT_STRING, offsetof(struct ModFsFile, filepath), true, LOT_NONE, 1, sizeof(char) }, + { "fill", LVT_FUNCTION, (size_t) "mod_fs_file_fill", true, LOT_NONE, 1, sizeof(const char *) }, + { "isPublic", LVT_BOOL, offsetof(struct ModFsFile, isPublic), true, LOT_NONE, 1, sizeof(bool) }, + { "isText", LVT_BOOL, offsetof(struct ModFsFile, isText), true, LOT_NONE, 1, sizeof(bool) }, + { "is_eof", LVT_FUNCTION, (size_t) "mod_fs_file_is_eof", true, LOT_NONE, 1, sizeof(const char *) }, + { "modFs", LVT_COBJECT_P, offsetof(struct ModFsFile, modFs), true, LOT_MODFS, 1, sizeof(struct ModFs*) }, + { "offset", LVT_U32, offsetof(struct ModFsFile, offset), true, LOT_NONE, 1, sizeof(u32) }, + { "read_bool", LVT_FUNCTION, (size_t) "mod_fs_file_read_bool", true, LOT_NONE, 1, sizeof(const char *) }, + { "read_bytes", LVT_FUNCTION, (size_t) "mod_fs_file_read_bytes", true, LOT_NONE, 1, sizeof(const char *) }, + { "read_integer", LVT_FUNCTION, (size_t) "mod_fs_file_read_integer", true, LOT_NONE, 1, sizeof(const char *) }, + { "read_line", LVT_FUNCTION, (size_t) "mod_fs_file_read_line", true, LOT_NONE, 1, sizeof(const char *) }, + { "read_number", LVT_FUNCTION, (size_t) "mod_fs_file_read_number", true, LOT_NONE, 1, sizeof(const char *) }, + { "read_string", LVT_FUNCTION, (size_t) "mod_fs_file_read_string", true, LOT_NONE, 1, sizeof(const char *) }, + { "rewind", LVT_FUNCTION, (size_t) "mod_fs_file_rewind", true, LOT_NONE, 1, sizeof(const char *) }, + { "seek", LVT_FUNCTION, (size_t) "mod_fs_file_seek", true, LOT_NONE, 1, sizeof(const char *) }, + { "set_compression", LVT_FUNCTION, (size_t) "mod_fs_file_set_compression", true, LOT_NONE, 1, sizeof(const char *) }, + { "set_public", LVT_FUNCTION, (size_t) "mod_fs_file_set_public", true, LOT_NONE, 1, sizeof(const char *) }, + { "set_text_mode", LVT_FUNCTION, (size_t) "mod_fs_file_set_text_mode", true, LOT_NONE, 1, sizeof(const char *) }, + { "size", LVT_U32, offsetof(struct ModFsFile, size), true, LOT_NONE, 1, sizeof(u32) }, + { "write_bool", LVT_FUNCTION, (size_t) "mod_fs_file_write_bool", true, LOT_NONE, 1, sizeof(const char *) }, + { "write_bytes", LVT_FUNCTION, (size_t) "mod_fs_file_write_bytes", true, LOT_NONE, 1, sizeof(const char *) }, + { "write_integer", LVT_FUNCTION, (size_t) "mod_fs_file_write_integer", true, LOT_NONE, 1, sizeof(const char *) }, + { "write_line", LVT_FUNCTION, (size_t) "mod_fs_file_write_line", true, LOT_NONE, 1, sizeof(const char *) }, + { "write_number", LVT_FUNCTION, (size_t) "mod_fs_file_write_number", true, LOT_NONE, 1, sizeof(const char *) }, + { "write_string", LVT_FUNCTION, (size_t) "mod_fs_file_write_string", true, LOT_NONE, 1, sizeof(const char *) }, }; #define LUA_NAMETAGS_SETTINGS_FIELD_COUNT 2 diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index 5e48e92aa..239f20edd 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -2308,6 +2308,9 @@ char gSmluaConstants[] = "" "GRAB_POS_LIGHT_OBJ=1\n" "GRAB_POS_HEAVY_OBJ=2\n" "GRAB_POS_BOWSER=3\n" +"MOD_FS_COMPRESSION_MIN=0\n" +"MOD_FS_COMPRESSION_MAX=9\n" +"MOD_FS_COMPRESSION_DEFAULT=1\n" "MOD_FS_MAX_SIZE=0x2000000\n" "MOD_FS_MAX_FILES=0x200\n" "MOD_FS_MAX_PATH=0x100\n" diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 2ce8d630a..25877b2b0 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -23049,6 +23049,25 @@ int smlua_func_mod_fs_file_set_public(lua_State* L) { return 1; } +int smlua_func_mod_fs_file_set_compression(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_file_set_compression", 2, top); + return 0; + } + + struct ModFsFile* file = (struct ModFsFile*)smlua_to_cobject(L, 1, LOT_MODFSFILE); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mod_fs_file_set_compression"); return 0; } + s32 level = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "mod_fs_file_set_compression"); return 0; } + + lua_pushboolean(L, mod_fs_file_set_compression(file, level)); + + return 1; +} + int smlua_func_mod_fs_hide_errors(lua_State* L) { if (L == NULL) { return 0; } @@ -38223,6 +38242,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "mod_fs_file_erase", smlua_func_mod_fs_file_erase); smlua_bind_function(L, "mod_fs_file_set_text_mode", smlua_func_mod_fs_file_set_text_mode); smlua_bind_function(L, "mod_fs_file_set_public", smlua_func_mod_fs_file_set_public); + smlua_bind_function(L, "mod_fs_file_set_compression", smlua_func_mod_fs_file_set_compression); smlua_bind_function(L, "mod_fs_hide_errors", smlua_func_mod_fs_hide_errors); smlua_bind_function(L, "mod_fs_get_last_error", smlua_func_mod_fs_get_last_error); diff --git a/src/pc/mods/mod_fs.cpp b/src/pc/mods/mod_fs.cpp index 1dcfb4305..e8df7b2fb 100644 --- a/src/pc/mods/mod_fs.cpp +++ b/src/pc/mods/mod_fs.cpp @@ -309,6 +309,14 @@ bool mod_fs_get_property_value(const json &property, const bool &defaultValue) { return defaultValue; } +template<> +s32 mod_fs_get_property_value(const json &property, const s32 &defaultValue) { + if (property.is_number_integer()) { + return (s32) property; + } + return defaultValue; +} + const json &mod_fs_get_properties_at(const json &properties, const std::vector &propertyPath) { const json *current = &properties; for (const auto &key : propertyPath) { @@ -380,7 +388,8 @@ static json mod_fs_get_properties_json(struct ModFs *modFs) { struct ModFsFile *file = modFs->files[i]; properties["files"][file->filepath] = { { "isText", file->isText }, - { "isPublic", file->isPublic } + { "isPublic", file->isPublic }, + { "compressionLevel", file->compressionLevel } }; } return properties; @@ -625,6 +634,9 @@ static bool mod_fs_read(const char *modPath, struct ModFs *modFs, bool checkExis "modPath: %s, filepath: %s - Invalid file data", modFs->modPath, file->filepath ); } + + // read compressionLevel property + file->compressionLevel = mod_fs_read_property(fileProperties, { "compressionLevel" }, MOD_FS_COMPRESSION_DEFAULT); } if (modFs->files) { @@ -673,14 +685,14 @@ static bool mod_fs_write(struct ModFs *modFs) { ); } - if (!mz_zip_writer_add_mem(zip, file->filepath, file->data.bin, file->size, MZ_BEST_COMPRESSION)) { + if (!mz_zip_writer_add_mem(zip, file->filepath, file->data.bin, file->size, file->compressionLevel)) { mod_fs_write_raise_error_zip(); } } // write properties file std::string properties = mod_fs_get_properties_json(modFs).dump(4, ' ', true); - if (!mz_zip_writer_add_mem(zip, MOD_FS_PROPERTIES, properties.c_str(), properties.length(), MZ_BEST_COMPRESSION)) { + if (!mz_zip_writer_add_mem(zip, MOD_FS_PROPERTIES, properties.c_str(), properties.length(), MZ_BEST_SPEED)) { mod_fs_write_raise_error_zip(); } @@ -947,6 +959,7 @@ C_DEFINE struct ModFsFile *mod_fs_create_file(struct ModFs *modFs, const char *f file->offset = 0; file->isText = text; file->isPublic = MOD_FS_FILE_IS_PUBLIC_DEFAULT; + file->compressionLevel = MOD_FS_COMPRESSION_DEFAULT; file->modFs = modFs; // add file and sort by filename @@ -1710,6 +1723,29 @@ C_DEFINE bool mod_fs_file_set_public(struct ModFsFile *file, bool pub) { return true; } +C_DEFINE bool mod_fs_file_set_compression(struct ModFsFile *file, s32 level) { + mod_fs_reset_last_error(); + + if (!mod_fs_check_pointer(file, "modfs file")) { + return false; + } + + // cannot change compress level to files in other mods modfs + if (!mod_fs_file_check_write(file)) { + return false; + } + + if (level < MOD_FS_COMPRESSION_MIN || level > MOD_FS_COMPRESSION_MAX) { + mod_fs_raise_error( + "compress level must be between %d and %d inclusive", MOD_FS_COMPRESSION_MIN, MOD_FS_COMPRESSION_MAX + ); + return false; + } + + file->compressionLevel = level; + return true; +} + // // Errors // diff --git a/src/pc/mods/mod_fs.h b/src/pc/mods/mod_fs.h index 8cd45794f..078106593 100644 --- a/src/pc/mods/mod_fs.h +++ b/src/pc/mods/mod_fs.h @@ -4,6 +4,9 @@ #include "types.h" #include "src/pc/lua/smlua.h" +#define MOD_FS_COMPRESSION_MIN 0 +#define MOD_FS_COMPRESSION_MAX 9 +#define MOD_FS_COMPRESSION_DEFAULT 1 #define MOD_FS_MAX_SIZE 0x2000000 // 32 MB #define MOD_FS_MAX_FILES 0x200 #define MOD_FS_MAX_PATH 0x100 @@ -52,6 +55,7 @@ struct ModFsFile { u32 size; u32 capacity; u32 offset; + s32 compressionLevel; bool isText; bool isPublic; @@ -74,6 +78,7 @@ struct ModFsFile { FUNCTION(erase, mod_fs_file_erase); FUNCTION(set_text_mode, mod_fs_file_set_text_mode); FUNCTION(set_public, mod_fs_file_set_public); + FUNCTION(set_compression, mod_fs_file_set_compression); }; struct ModFs { @@ -266,6 +271,11 @@ Marks the provided modfs `file` as public (i.e. readable by other mods). Returns |descriptionEnd| */ bool mod_fs_file_set_public(struct ModFsFile *file, bool pub); +/* |description| +Sets the compression level of the provided modfs `file`. Must be between 0 (no compression) and 9 (most compression). Returns true on success. +|descriptionEnd| */ +bool mod_fs_file_set_compression(struct ModFsFile *file, s32 level); + /* |description| Hides script errors raised by `mod_fs` functions. Errors messages are still generated and can be retrieved with `mod_fs_get_last_error()` |descriptionEnd| */ diff --git a/textures/custom_font/custom_font_hud_recolor.rgba32.png b/textures/custom_font/custom_font_hud_recolor.rgba32.png index 3f1bf60be..76f9df1fa 100644 Binary files a/textures/custom_font/custom_font_hud_recolor.rgba32.png and b/textures/custom_font/custom_font_hud_recolor.rgba32.png differ