From 21dd1ce81def53d835b0827353470d6e2313d9c0 Mon Sep 17 00:00:00 2001 From: jayden <46307433+kermeow@users.noreply.github.com> Date: Fri, 10 Apr 2026 22:25:58 +0100 Subject: [PATCH] Add `mod_fs_file_set_compression` (#1187) * add compression level to modfs files * document modfs compression * correction in modfs guide * undo text mode write check * compression level use s32 instead of int * fix missing s32 --- autogen/lua_definitions/constants.lua | 9 +++++ autogen/lua_definitions/functions.lua | 8 ++++ autogen/lua_definitions/structs.lua | 2 + docs/lua/constants.md | 3 ++ docs/lua/functions-5.md | 24 ++++++++++++ docs/lua/functions.md | 1 + docs/lua/guides/modfs.md | 14 +++++++ docs/lua/structs.md | 2 + src/pc/lua/smlua_cobject_autogen.c | 54 ++++++++++++++------------- src/pc/lua/smlua_constants_autogen.c | 3 ++ src/pc/lua/smlua_functions_autogen.c | 20 ++++++++++ src/pc/mods/mod_fs.cpp | 42 +++++++++++++++++++-- src/pc/mods/mod_fs.h | 10 +++++ 13 files changed, 163 insertions(+), 29 deletions(-) diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index 1d7dfb2dc..cbf769b73 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -4640,6 +4640,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 d489d82e6..a57d791ed 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/docs/lua/constants.md b/docs/lua/constants.md index cf00279f7..1fef94781 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -2155,6 +2155,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 15557e5cc..e787f6b42 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/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 de7da771c..b292ae5f3 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -2299,6 +2299,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 6cb7ab6f3..8ac087643 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; } @@ -38153,6 +38172,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| */