diff --git a/autogen/autogen.sh b/autogen/autogen.sh index 9459f4d61..4036b217a 100755 --- a/autogen/autogen.sh +++ b/autogen/autogen.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash python3 ./autogen/gen_math.py $1 +python3 ./autogen/convert_functions.py $1 python3 ./autogen/convert_structs.py $1 python3 ./autogen/gen_hooks.py $1 -python3 ./autogen/convert_functions.py $1 python3 ./autogen/convert_constants.py $1 python3 ./autogen/extract_display_lists.py $1 diff --git a/autogen/common.py b/autogen/common.py index 2a76f2dd2..9f3ad5714 100644 --- a/autogen/common.py +++ b/autogen/common.py @@ -4,7 +4,8 @@ from vec_types import * usf_types = ['u8', 'u16', 'u32', 'u64', 's8', 's16', 's32', 's64', 'f32', 'f64'] vec_types = list(VEC_TYPES.keys()) -typedef_pointers = ['BehaviorScript', 'ObjectAnimPointer', 'Collision', 'LevelScript', 'Trajectory'] +typedef_pointers = ['BehaviorScript', 'ObjectAnimPointer', 'Collision', 'LevelScript', 'Trajectory', 'Texture'] +cobject_function_identifier = 'FUNCTION' type_mappings = { 'char': 's8', @@ -117,6 +118,12 @@ def translate_type_to_lvt(ptype, allowArrays=False): if ptype == "LuaFunction": return "LVT_LUAFUNCTION" + if ptype == "LuaTable": + return "LVT_LUATABLE" + + if ptype == cobject_function_identifier: + return "LVT_FUNCTION" + if "struct" in ptype: if pointerLvl > 1: return "LVT_???" @@ -194,6 +201,12 @@ def translate_type_to_lot(ptype, allowArrays=True): if ptype == 'LuaFunction': return 'LOT_NONE' + if ptype == 'LuaTable': + return 'LOT_NONE' + + if ptype == cobject_function_identifier: + return 'LOT_NONE' + if ptype in override_types: return 'LOT_' + ptype.upper() @@ -280,6 +293,12 @@ def translate_type_to_lua(ptype): if ptype == 'LuaFunction': return '`Lua Function` ()', None + if ptype == 'LuaTable': + return '`table`', None + + if ptype == cobject_function_identifier: + return cobject_function_identifier, None + if ptype.count('*') == 1 and '???' not in translate_type_to_lvt(ptype): ptype = ptype.replace('const', '').replace('*', '').strip() s = '`Pointer` <`%s`>' % translate_type_to_lua(ptype)[0].replace('`', '').strip() diff --git a/autogen/convert_constants.py b/autogen/convert_constants.py index 615b442fe..f3939d1cc 100644 --- a/autogen/convert_constants.py +++ b/autogen/convert_constants.py @@ -67,7 +67,7 @@ exclude_constants = { "src/pc/djui/djui_console.h": [ "CONSOLE_MAX_TMP_BUFFER" ], "src/pc/lua/smlua_hooks.h": [ "MAX_HOOKED_MOD_MENU_ELEMENTS", "^HOOK_RETURN_.*", "^ACTION_HOOK_.*", "^MOD_MENU_ELEMENT_.*" ], "src/pc/djui/djui_panel_menu.h": [ "RAINBOW_TEXT_LEN" ], - "src/pc/mods/mod_fs.h": [ "MOD_FS_DIRECTORY", "MOD_FS_EXTENSION", "MOD_FS_VERSION", "INT_TYPE_MAX", "FLOAT_TYPE_MAX", "FILE_SEEK_MAX" ], + "src/pc/mods/mod_fs.h": [ "INT_TYPE_MAX", "FLOAT_TYPE_MAX", "FILE_SEEK_MAX" ], } include_constants = { @@ -139,6 +139,7 @@ defined_values = { 'VERSION_JP': False, 'VERSION_SH': False, 'F3DEX_GBI_2': True, + 'DEVELOPMENT': False, } ############################################################################ @@ -255,15 +256,17 @@ def process_define(filename, line, inIfBlock): val = val.replace('(u8)', '') val = val.replace('(u64)', '') val = re.sub(r'\.\d+f', '', val) + val = val.strip() - for p in val.split(' '): - if p.startswith('0x'): - continue - p = re.sub(r'0x[a-fA-F0-9]+', '', p) - if re.search(r'[a-z]', p) != None and "VERSION_TEXT" not in line and "SM64COOPDX_VERSION" not in line: - if 'gCurrentObject' not in line and verbose: - print('UNRECOGNIZED DEFINE: ' + line) - return None + if not (val.startswith('"') and val.endswith('"') and '"' not in val[1:-1]): + for p in val.split(' '): + if p.startswith('0x'): + continue + p = re.sub(r'0x[a-fA-F0-9]+', '', p) + if re.search(r'[a-z]', p) != None and "VERSION_TEXT" not in line and "SM64COOPDX_VERSION" not in line: + if 'gCurrentObject' not in line and verbose: + print('UNRECOGNIZED DEFINE: ' + line) + return None if not allowed_identifier(filename, ident): return None diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index 8f0e8758a..f886f43e0 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -138,6 +138,8 @@ override_disallowed_functions = { "src/game/first_person_cam.h": [ "first_person_update" ], "src/pc/lua/utils/smlua_collision_utils.h": [ "collision_find_surface_on_ray" ], "src/engine/behavior_script.h": [ "stub_behavior_script_2", "cur_obj_update" ], + "src/pc/mods/mod_storage.h": [ "mod_storage_shutdown" ], + "src/pc/mods/mod_fs.h": [ "mod_fs_read_file_from_uri", "mod_fs_shutdown" ], "src/pc/utils/misc.h": [ "str_.*", "file_get_line", "delta_interpolate_(normal|rgba|mtx)", "detect_and_skip_mtx_interpolation", "precise_delay_f64" ], "src/engine/lighting_engine.h": [ "le_calculate_vertex_lighting", "le_clear", "le_shutdown" ], } @@ -813,6 +815,8 @@ def build_param(fid, param, i): return ' %s %s = smlua_to_bytestring(L, %d);\n' % (ptype, pid, i) elif ptype == 'LuaFunction': return ' %s %s = smlua_to_lua_function(L, %d);\n' % (ptype, pid, i) + elif ptype == 'LuaTable': + return ' %s %s = smlua_to_lua_table(L, %d);\n' % (ptype, pid, i) elif translate_type_to_lot(ptype) == 'LOT_POINTER': lvt = translate_type_to_lvt(ptype) return ' %s %s = (%s)smlua_to_cpointer(L, %d, %s);\n' % (ptype, pid, ptype, i, lvt) @@ -868,6 +872,8 @@ def build_call(function): lfunc = 'lua_pushstring' elif ftype == 'ByteString': lfunc = 'smlua_push_bytestring' + elif ftype == 'LuaTable': + lfunc = 'smlua_push_lua_table' elif translate_type_to_lot(ftype) == 'LOT_POINTER': lvt = translate_type_to_lvt(ftype) return ' smlua_push_pointer(L, %s, (void*)%s, NULL);\n' % (lvt, ccall) diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py index c8af5f8e1..eb5a2ced6 100644 --- a/autogen/convert_structs.py +++ b/autogen/convert_structs.py @@ -96,6 +96,7 @@ override_field_invisible = { "Object": [ "firstSurface" ], "Animation": [ "unusedBoneCount" ], "ModAudio": [ "sound", "decoder", "buffer", "bufferSize", "sampleCopiesTail" ], + "Painting": [ "normalDisplayList", "textureMaps", "rippleDisplayList", "ripples" ], "DialogEntry": [ "str" ], "ModFsFile": [ "data", "capacity" ], "ModFs": [ "files" ], @@ -141,6 +142,7 @@ override_field_immutable = { "DialogEntry": [ "unused", "linesPerBox", "leftOffset", "width", "str", "text", "replaced"], "ModFsFile": [ "*" ], "ModFs": [ "*" ], + "StaticObjectCollision": [ "*" ], } override_field_version_excludes = { @@ -321,6 +323,14 @@ def parse_struct(struct_str, sortFields = False): field['identifier'] = field_id.strip() field['field_str'] = field_str + # handle function members + if field['type'].startswith(cobject_function_identifier): + field_function = field['identifier'] + field_type, field_id = field['type'].split() + field['type'] = field_type.strip() + field['identifier'] = field_id.strip('"').strip() + field['function'] = field_function.strip() + struct['fields'].append(field) if identifier == 'Object': @@ -484,6 +494,9 @@ def get_struct_field_info(struct, field): if fid in override_field_mutable[sid] or '*' in override_field_mutable[sid]: fimmutable = 'false' + if ftype == cobject_function_identifier: + fimmutable = 'true' + if not ('char' in ftype and '[' in ftype and 'unsigned' not in ftype): array_match = re.search(r'\[([^\]]+)\]', ftype) if array_match: @@ -506,6 +519,7 @@ def build_struct(struct): # build up table and track column width field_table = [] + field_functions = [] for field in struct['fields']: fid, ftype, fimmutable, lvt, lot, size = get_struct_field_info(struct, field) @@ -531,22 +545,40 @@ def build_struct(struct): startStr += '#ifndef ' + override_field_version_excludes[fid] + '\n' endStr += '\n#endif' startStr += ' { ' - row.append(startStr ) - row.append('"%s", ' % fid ) - row.append('%s, ' % lvt ) - row.append('offsetof(%s%s, %s), ' % (struct_str, name, field['identifier'])) - row.append('%s, ' % fimmutable ) - row.append('%s, ' % lot ) - row.append('%s, ' % size ) - row.append('sizeof(%s)' % ftype ) - row.append(endStr ) + if ftype == cobject_function_identifier: + row.append(startStr ) + row.append('"%s", ' % fid ) + row.append('%s, ' % lvt ) + row.append('(size_t) FUNCTION__%s, ' % (field['function'])) + row.append('%s, ' % fimmutable ) + row.append('%s, ' % lot ) + row.append('%s, ' % size ) + row.append('sizeof(const char *)' ) + row.append(endStr ) + field_functions.append(field['function']) + else: + row.append(startStr ) + row.append('"%s", ' % fid ) + row.append('%s, ' % lvt ) + row.append('offsetof(%s%s, %s), ' % (struct_str, name, field['identifier'])) + row.append('%s, ' % fimmutable ) + row.append('%s, ' % lot ) + row.append('%s, ' % size ) + row.append('sizeof(%s)' % ftype ) + row.append(endStr ) field_table.append(row) field_table_str, field_count = table_to_string(field_table) field_count_define = 'LUA_%s_FIELD_COUNT' % identifier_to_caps(sid) struct_lot = 'LOT_%s' % sid.upper() - s = "#define %s $[STRUCTFIELDCOUNT]\n" % field_count_define + s = '' + if field_functions: + for field_function in field_functions: + s += 'static const char FUNCTION__%s[] = "%s";\n' % (field_function, field_function) + s += '\n' + + s += "#define %s $[STRUCTFIELDCOUNT]\n" % field_count_define s += "static struct LuaObjectField s%sFields[%s] = {\n" % (sid, field_count_define) s += field_table_str s += '};\n' @@ -646,6 +678,21 @@ def build_includes(): ############################################################################ +# HACK: Parse docs/functions.md to find the page where the function is documented +function_links = {} + +def doc_find_function_link(function): + if not function_links: + with open('docs/lua/functions.md') as f: + lines = f.readlines() + for line in lines: + line = line.replace(' ', '').strip() + res, n = re.subn(r'^-\[(.*)\]\((.*)\)', '\\1,\\2', line) + if n != 0: + fname, flink = res.split(',') + function_links[fname] = flink + return function_links.get(function, '') + def doc_struct_index(structs): s = '# Supported Structs\n' for struct in structs: @@ -662,26 +709,30 @@ def doc_struct_field(struct, field): sid = struct['identifier'] if sid in override_field_invisible: if fid in override_field_invisible[sid]: - return '' + return '', False if sid in override_field_deprecated: if fid in override_field_deprecated[sid]: - return '' + return '', False if '???' in lvt or '???' in lot: - return '' + return '', False ftype, flink = translate_type_to_lua(ftype) + if ftype == cobject_function_identifier: + flink = doc_find_function_link(field['function']) + return '| %s | [`%s`](%s) |\n' % (fid, field['function'], flink), True + restrictions = ('', 'read-only')[fimmutable == 'true'] global total_fields total_fields += 1 if flink: - return '| %s | [%s](%s) | %s |\n' % (fid, ftype, flink, restrictions) + return '| %s | [%s](%s) | %s |\n' % (fid, ftype, flink, restrictions), False - return '| %s | %s | %s |\n' % (fid, ftype, restrictions) + return '| %s | %s | %s |\n' % (fid, ftype, restrictions), False def doc_struct_object_fields(struct): @@ -696,7 +747,8 @@ def doc_struct_object_fields(struct): s += "| Field | Type | Access |\n" s += "| ----- | ---- | ------ |\n" - s += doc_struct_field(struct, field) + line, _ = doc_struct_field(struct, field) + s += line return s @@ -707,17 +759,27 @@ def doc_struct(struct): s += "| Field | Type | Access |\n" s += "| ----- | ---- | ------ |\n" - # build doc table - field_table = [] + field_functions = '' for field in struct['fields']: if 'object_field' in field and field['object_field'] == True: continue - s += doc_struct_field(struct, field) + line, isFunction = doc_struct_field(struct, field) + if isFunction: + field_functions += line + else: + s += line if sid == 'Object': s += doc_struct_object_fields(struct) + # functions + if field_functions: + s += '\n**Functions:**\n\n' + s += "| Name | Reference |\n" + s += "| ---- | --------- |\n" + s += field_functions + s += '\n[:arrow_up_small:](#)\n\n
\n' return s @@ -740,6 +802,32 @@ def doc_structs(structs): def_pointers = [] +# HACK: Parse autogen/lua_definitions/functions.lua to find the function signature +function_signatures = {} + +def get_function_signature(function): + if not function_signatures: + with open('autogen/lua_definitions/functions.lua') as f: + lines = f.readlines() + function_params = [] + function_return = None + for line in lines: + if line.startswith('--- @param'): + function_params.append(line.split()[2:4]) + elif line.startswith('--- @return'): + function_return = line.split()[2] + elif line.startswith('function'): + sig = 'fun(' + sig += ', '.join(['%s: %s' % (param_name, param_type) for param_name, param_type in function_params]) + sig += ')' + if function_return: + sig += ': %s' % (function_return) + function_name = line.replace('(', ' ').split()[1] + function_signatures[function_name] = sig + function_params.clear() + function_return = None + return function_signatures.get(function, 'function') + def def_struct(struct): sid = struct['identifier'] @@ -761,7 +849,12 @@ def def_struct(struct): ftype, flink = translate_type_to_lua(ftype) - ftype = translate_to_def(ftype) + # try to get the function signature + if ftype == cobject_function_identifier: + ftype = get_function_signature(field['function']) + else: + ftype = translate_to_def(ftype) + if ftype.startswith('Pointer_') and ftype not in def_pointers: def_pointers.append(ftype) diff --git a/autogen/extract_structs.py b/autogen/extract_structs.py index a2d65f1e9..5fb06c5ef 100644 --- a/autogen/extract_structs.py +++ b/autogen/extract_structs.py @@ -1,6 +1,7 @@ import os import re import sys +from common import cobject_function_identifier def extract_structs(filename): with open(filename) as file: @@ -36,6 +37,9 @@ def extract_structs(filename): while (' ' in txt): txt = txt.replace(' ', ' ') + # handle function members (NOT function pointers) + txt = re.sub(f'{cobject_function_identifier}\\((.*),(.*)\\)', f'{cobject_function_identifier} \\1 \\2', txt) + # strip macros txt = re.sub(r'[^a-zA-Z0-9_][A-Z0-9_]+\(.*\)', '', txt) diff --git a/autogen/gen_hooks.py b/autogen/gen_hooks.py index 98aea889b..73d74769f 100644 --- a/autogen/gen_hooks.py +++ b/autogen/gen_hooks.py @@ -309,17 +309,20 @@ def main(): name=input["name"] ) + n_outputs = len(hook_event["outputs"]) generated += SMLUA_CALL_EVENT_HOOKS_CALLBACK.format( n_inputs=len(hook_event["inputs"]) - mod_index_found, - n_outputs=len(hook_event["outputs"]), + n_outputs=n_outputs, hook_type=hook_event["type"], set_hook_result=set_hook_result ) + # Note: relative indexes for return values are reversed in the Lua stack + # -1 is the last value, -2 the penultimate, ... and -N the first for i, output in enumerate(hook_event["outputs"]): generated += SMLUA_TYPES[output["type"]]["output"].format( name=output["name"], - output_index=i+1, + output_index=n_outputs - i, return_on_output_set=return_on_output_set ) diff --git a/autogen/gen_math.py b/autogen/gen_math.py index 98da45c1a..e5ef37b6f 100644 --- a/autogen/gen_math.py +++ b/autogen/gen_math.py @@ -1,39 +1,70 @@ import sys - -VEC3X_TO_VEC3Y = """ +VECX_TO_VECY = """ /* |description| -Converts a 3D {{desc}} vector `a` into a 3D {{desc_2}} vector and stores the result in `dest` +Converts a {{size}}D {{desc}} vector `a` into a {{size}}D {{desc_2}} vector and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix_2}}p vec3{{suffix}}_to_vec3{{suffix_2}}(OUT Vec3{{suffix_2}} dest, Vec3{{suffix}} a) { - dest[0] = a[0]{{rounding_0}}; - dest[1] = a[1]{{rounding_1}}; - dest[2] = a[2]{{rounding_2}}; +INLINE OPTIMIZE_O3 Vec{{size}}{{suffix_2}}p vec{{size}}{{suffix}}_to_vec{{size}}{{suffix_2}}(OUT Vec{{size}}{{suffix_2}} dest, Vec{{size}}{{suffix}} a) { + {{body}} return dest; } """ -ROUNDING_FORMULA = " + ((a[%d] > 0) ? 0.5f : -0.5f)" +ROUNDING_FORMULA = " + ((a[{i}] > 0) ? 0.5f : -0.5f)" -def vec3_write_conversion_functions(generated: str, curr_template: dict, templates: list, size: int) -> str: +def vec_write_conversion_functions(generated: str, curr_template: dict, templates: list, size: int) -> str: for template in templates: if template["suffix"] == curr_template["suffix"]: continue - generated += VEC3X_TO_VEC3Y \ + body = "\n ".join([ + "dest[{i}] = a[{i}]{rounding};".format( + i=i, + rounding=ROUNDING_FORMULA.format(i=i) if curr_template["rounding"] else "" + ) for i in range(size) + ]) + + generated += VECX_TO_VECY \ + .replace("{{size}}", str(size)) \ .replace("{{desc}}", curr_template["desc"]) \ .replace("{{suffix}}", curr_template["suffix"]) \ .replace("{{desc_2}}", template["desc"]) \ - .replace("{{suffix_2}}", template["suffix"]) - - for i in range(size): - rounding_i = "{{rounding_%d}}" % (i) - generated = generated.replace(rounding_i, ROUNDING_FORMULA % (i) if curr_template["rounding"] else "") + .replace("{{suffix_2}}", template["suffix"]) \ + .replace("{{body}}", body) return generated TEMPLATES = { + "src/engine/math_util_vec2.tmpl": { + "size": 2, + "templates": [ + { + "desc": "floating-point", + "type": "f32", + "suffix": "f", + "rounding": True + }, + { + "desc": "integer", + "type": "s32", + "suffix": "i", + "rounding": False + }, + { + "desc": "short integer", + "type": "s16", + "suffix": "s", + "rounding": False + } + ], + "post-template": { + "function": vec_write_conversion_functions, + "args": { + "size": 2 + } + } + }, "src/engine/math_util_vec3.tmpl": { "size": 3, "templates": [ @@ -57,7 +88,7 @@ TEMPLATES = { } ], "post-template": { - "function": vec3_write_conversion_functions, + "function": vec_write_conversion_functions, "args": { "size": 3 } diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index 9626d3b75..5f9b76fa0 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -2999,6 +2999,9 @@ GRAPH_RENDER_PLAYER = (1 << 7) --- @type integer GRAPH_EXTRA_FORCE_3D = (1 << 0) +--- @type integer +GRAPH_EXTRA_ROTATE_HELD = (1 << 1) + --- @type integer GRAPH_NODE_TYPE_FUNCTIONAL = 0x100 @@ -4554,14 +4557,20 @@ GRAB_POS_BOWSER = 3 --- @type MarioGrabPosGSCId --- | `GRAB_POS_BOWSER` --- @type integer -MOD_FS_MAX_SIZE = 0x1000000 +MOD_FS_MAX_SIZE = 0x2000000 --- @type integer -MOD_FS_MAX_FILES = 0x100 +MOD_FS_MAX_FILES = 0x200 --- @type integer MOD_FS_MAX_PATH = 0x100 +--- @type string +MOD_FS_URI_PREFIX = "modfs:/" + +--- @type string +MOD_FS_URI_FORMAT = "modfs:/%s/%s" + INT_TYPE_U8 = 0 --- @type ModFsFileIntType INT_TYPE_U16 = 1 --- @type ModFsFileIntType INT_TYPE_U32 = 2 --- @type ModFsFileIntType @@ -6755,6 +6764,9 @@ R_CBUTTONS = CONT_F --- @type integer D_CBUTTONS = CONT_D +--- @type string +PALETTES_DIRECTORY = "palettes" + --- @type integer MAX_PRESET_PALETTES = 128 @@ -10953,6 +10965,9 @@ SURFACE_FLAG_DYNAMIC = (1 << 0) --- @type integer SURFACE_FLAG_NO_CAM_COLLISION = (1 << 1) +--- @type integer +SURFACE_FLAG_INTANGIBLE = (1 << 2) + --- @type integer SURFACE_FLAG_X_PROJECTION = (1 << 3) @@ -11163,5 +11178,11 @@ VERSION_NUMBER = 41 --- @type integer MINOR_VERSION_NUMBER = 0 +--- @type string +GAME_NAME = "sm64coopdx" + +--- @type string +WINDOW_NAME = "Super Mario 64 Coop Deluxe" + --- @type integer MAX_VERSION_LENGTH = 128 diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index bc9bbc883..3ba796772 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -7435,25 +7435,6 @@ function mod_fs_create() -- ... end ---- @return boolean ---- Deletes the modfs object of the active mod if it exists. Returns true on success -function mod_fs_delete() - -- ... -end - ---- @return boolean ---- Saves the modfs object of the active mod if it exists. Returns true on success -function mod_fs_save() - -- ... -end - ---- @param pub boolean ---- @return boolean ---- Marks the modfs object of the active mod as public (i.e. readable by other mods) if it exists. Returns true on success -function mod_fs_set_public(pub) - -- ... -end - --- @param modFs ModFs --- @param index integer --- @return string @@ -7514,6 +7495,28 @@ function mod_fs_clear(modFs) -- ... end +--- @param modFs ModFs +--- @return boolean +--- Saves the provided `modFs` to persistent storage. Returns true on success +function mod_fs_save(modFs) + -- ... +end + +--- @param modFs ModFs +--- @return boolean +--- Removes the provided `modFs` from persistent storage and deletes its object. Returns true on success +function mod_fs_delete(modFs) + -- ... +end + +--- @param modFs ModFs +--- @param pub boolean +--- @return boolean +--- Marks the provided `modFs` as public (i.e. readable by other mods). Returns true on success +function mod_fs_set_public(modFs, pub) + -- ... +end + --- @param file ModFsFile --- @return boolean --- Reads a boolean from a binary modfs `file` @@ -7618,6 +7621,13 @@ function mod_fs_file_seek(file, offset, origin) -- ... end +--- @param file ModFsFile +--- @return boolean +--- Sets the current position of a modfs `file` to its beginning. Returns true on success +function mod_fs_file_rewind(file) + -- ... +end + --- @param file ModFsFile --- @return boolean --- Returns true if the provided modfs `file` has reached its end of file @@ -7642,6 +7652,14 @@ function mod_fs_file_erase(file, length) -- ... end +--- @param file ModFsFile +--- @param text boolean +--- @return boolean +--- Marks the provided modfs `file` as text. Returns true on success +function mod_fs_file_set_text_mode(file, text) + -- ... +end + --- @param file ModFsFile --- @param pub boolean --- @return boolean @@ -7707,6 +7725,12 @@ function mod_storage_load_bool(key) -- ... end +--- @return table +--- Loads all keys and values in mod storage as strings and returns them as a table +function mod_storage_load_all() + -- ... +end + --- @param key string --- @return boolean --- Checks if a `key` is in mod storage @@ -10776,12 +10800,19 @@ function gfx_get_vertex_count(cmd) end --- @param cmd Pointer_Gfx ---- @return Pointer_integer +--- @return Pointer_Texture --- Gets the texture from a display list command if it has an image related op function gfx_get_texture(cmd) -- ... end +--- @param gfx Pointer_Gfx +--- @return string +--- Gets the name of a display list +function gfx_get_name(gfx) + -- ... +end + --- @param gfx Pointer_Gfx --- @return integer --- Gets the max length of a display list @@ -10838,6 +10869,13 @@ function gfx_delete_all() -- ... end +--- @param vtx Pointer_Vtx +--- @return string +--- Gets the name of a vertex buffer +function vtx_get_name(vtx) + -- ... +end + --- @param vtx Pointer_Vtx --- @return integer --- Gets the max count of vertices of a vertex buffer @@ -11514,12 +11552,19 @@ function geo_get_current_held_object() -- ... end ---- @param tex Pointer_integer ---- Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures. +--- @param tex Pointer_Texture +--- Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures function texture_to_lua_table(tex) -- ... end +--- @param tex Pointer_Texture +--- @return string +--- Gets the name of the provided texture pointer `tex` +function get_texture_name(tex) + -- ... +end + --- @param name string --- @return ModelExtendedId --- Gets the extended model ID for the `name` of a `GeoLayout` @@ -12274,6 +12319,27 @@ function load_object_collision_model() -- ... end +--- @return StaticObjectCollision +--- Loads the object's collision data into static collision. You may run this only once to capture the object's collision at that frame. +function load_static_object_collision() + -- ... +end + +--- @param col StaticObjectCollision +--- @param tangible boolean +--- Toggles a collection of static object surfaces +function toggle_static_object_collision(col, tangible) + -- ... +end + +--- @param col StaticObjectCollision +--- @param index integer +--- @return Surface +--- Gets a surface corresponding to `index` from the static object collision +function get_static_object_surface(col, index) + -- ... +end + --- @param o Object --- @param index integer --- @return Surface @@ -12318,6 +12384,7 @@ end --- @alias Pointer_Collision Collision --- @alias Pointer_Gfx Gfx --- @alias Pointer_Vtx Vtx +--- @alias Pointer_Texture Texture --- @alias Vec2fp Vec2f --- @alias Vec3fp Vec3f --- @alias Vec4fp Vec4f diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index eb545250c..95e263d89 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -1280,7 +1280,7 @@ --- @field public customBehaviorIndex integer --- @class ModAudio ---- @field public file ModFile +--- @field public filepath string --- @field public isStream boolean --- @field public baseVolume number --- @field public loaded boolean @@ -1304,6 +1304,16 @@ --- @field public numFiles integer --- @field public totalSize integer --- @field public isPublic boolean +--- @field public get_filename fun(modFs: ModFs, index: integer): string +--- @field public get_file fun(modFs: ModFs, filepath: string): ModFsFile +--- @field public create_file fun(modFs: ModFs, filepath: string, text: boolean): ModFsFile +--- @field public move_file fun(modFs: ModFs, oldpath: string, newpath: string, overwriteExisting: boolean): boolean +--- @field public copy_file fun(modFs: ModFs, srcpath: string, dstpath: string, overwriteExisting: boolean): boolean +--- @field public delete_file fun(modFs: ModFs, filepath: string): boolean +--- @field public clear fun(modFs: ModFs): boolean +--- @field public save fun(modFs: ModFs): boolean +--- @field public delete fun(modFs: ModFs): boolean +--- @field public set_public fun(modFs: ModFs, pub: boolean): boolean --- @class ModFsFile --- @field public modFs ModFs @@ -1312,6 +1322,25 @@ --- @field public offset integer --- @field public isText boolean --- @field public isPublic boolean +--- @field public read_bool fun(file: ModFsFile): boolean +--- @field public read_integer fun(file: ModFsFile, intType: ModFsFileIntType): integer +--- @field public read_number fun(file: ModFsFile, floatType: ModFsFileFloatType): number +--- @field public read_bytes fun(file: ModFsFile, length: integer): string +--- @field public read_string fun(file: ModFsFile): string +--- @field public read_line fun(file: ModFsFile): string +--- @field public write_bool fun(file: ModFsFile, value: boolean): boolean +--- @field public write_integer fun(file: ModFsFile, value: integer, intType: ModFsFileIntType): boolean +--- @field public write_number fun(file: ModFsFile, value: number, floatType: ModFsFileFloatType): boolean +--- @field public write_bytes fun(file: ModFsFile, bytestring: string): boolean +--- @field public write_string fun(file: ModFsFile, str: string): boolean +--- @field public write_line fun(file: ModFsFile, str: string): boolean +--- @field public seek fun(file: ModFsFile, offset: integer, origin: ModFsFileSeek): boolean +--- @field public rewind fun(file: ModFsFile): boolean +--- @field public is_eof fun(file: ModFsFile): boolean +--- @field public fill fun(file: ModFsFile, byte: integer, length: integer): boolean +--- @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 --- @class ModeTransitionInfo --- @field public newMode integer @@ -2176,10 +2205,9 @@ --- @field public rippleTimer number --- @field public rippleX number --- @field public rippleY number ---- @field public normalDisplayList Pointer_Gfx +--- @field public textureArray Pointer_Texture[] --- @field public textureWidth integer --- @field public textureHeight integer ---- @field public rippleDisplayList Pointer_Gfx --- @field public rippleTrigger integer --- @field public alpha integer --- @field public marioWasUnder integer @@ -2338,6 +2366,10 @@ --- @field public dialog5 integer --- @field public dialog6 integer +--- @class StaticObjectCollision +--- @field public index integer +--- @field public length integer + --- @class Surface --- @field public type integer --- @field public flags integer @@ -2357,7 +2389,7 @@ --- @field public object Object --- @class TextureInfo ---- @field public texture Pointer_integer +--- @field public texture Pointer_Texture --- @field public name string --- @field public width integer --- @field public height integer @@ -2528,3 +2560,5 @@ --- @alias Pointer_Mat4 Mat4 --- @alias Pointer_Vec4s Vec4s --- @alias Pointer_BehaviorScript BehaviorScript +--- @alias Pointer_Texture[] Texture[] +--- @alias Pointer_Texture Texture diff --git a/bin/custom_font.c b/bin/custom_font.c index 9988d772b..2075d57bc 100644 --- a/bin/custom_font.c +++ b/bin/custom_font.c @@ -67,7 +67,7 @@ const f32 font_aliased_widths[] = { /* 0 1 2 3 4 5 6 7 8 9 */ 14, 12, 13, 14, 14, 14, 14, 13, 14, 14, /* : ; < = > ? @ */ - 6, 8, 10, 12, 10, 11, 18, + 8, 8, 10, 12, 10, 11, 18, /* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */ 12, 12, 12, 12, 11, 10, 12, 12, 9, 12, 12, 10, 16, 16, 12, 11, 12, 12, 12, 10, 12, 10, 16, 14, 12, 12, /* [ \ ] ^ _ ` */ @@ -75,7 +75,7 @@ const f32 font_aliased_widths[] = { /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ 10, 10, 10, 10, 9, 8, 12, 10, 7, 9, 10, 4, 13, 10, 9, 9, 10, 9, 10, 9, 10, 9, 14, 12, 10, 10, /* { | } ~ DEL */ - 10, 8, 10, 16, 10, + 10, 8, 10, 16, 16, }; ////////////////////////////////////////////////////////// diff --git a/data/behavior_table.c b/data/behavior_table.c index 46c03b76c..6fbdf122b 100644 --- a/data/behavior_table.c +++ b/data/behavior_table.c @@ -558,6 +558,8 @@ const struct BehaviorTableEntry gBehaviorTable[id_bhv_max_count] = { enum BehaviorId get_id_from_behavior(const BehaviorScript* behavior) { if (behavior == NULL) { return id_bhv_max_count; } + if ((behavior[0] >> 24) != 0x00) { return id_bhv_max_count; } // check for BEGIN + if ((behavior[1] >> 24) != 0x39) { return id_bhv_max_count; } // check for ID return (enum BehaviorId)(behavior[1] & 0xFFFF); } diff --git a/data/dynos.c.h b/data/dynos.c.h index 9fd738463..419092eb1 100644 --- a/data/dynos.c.h +++ b/data/dynos.c.h @@ -37,17 +37,17 @@ void dynos_generate_packs(const char* directory); // -- geos -- // void dynos_actor_override(struct Object* obj, void** aSharedChild); -void dynos_add_actor_custom(s32 modIndex, s32 modFileIndex, const char *filePath, const char* geoName); +bool dynos_add_actor_custom(s32 modIndex, s32 modFileIndex, const char *filePath, const char* geoName); const void* dynos_geolayout_get(const char *name); bool dynos_actor_get_mod_index_and_token(struct GraphNode *graphNode, u32 tokenIndex, s32 *modIndex, s32 *modFileIndex, const char **token); void dynos_actor_register_modified_graph_node(struct GraphNode *node); // -- collisions -- // -void dynos_add_collision(const char *filePath, const char* collisionName); +bool dynos_add_collision(const char *filePath, const char* collisionName); Collision* dynos_collision_get(const char* collisionName); // -- textures -- // -void dynos_add_texture(const char *filePath, const char* textureName); +bool dynos_add_texture(const char *filePath, const char* textureName); bool dynos_texture_get(const char* textureName, struct TextureInfo* outTextureInfo); bool dynos_texture_get_from_data(const Texture *tex, struct TextureInfo* outTextureInfo); void dynos_texture_override_set(const char* textureName, struct TextureInfo* overrideTextureInfo); @@ -90,11 +90,13 @@ void dynos_model_clear_pool(enum ModelPool aModelPool); // -- gfx -- // Gfx *dynos_gfx_get_writable_display_list(Gfx* gfx); Gfx *dynos_gfx_get(const char *name, u32 *outLength); +const char *dynos_gfx_get_name(Gfx *gfx); Gfx *dynos_gfx_create(const char *name, u32 length); bool dynos_gfx_resize(Gfx *gfx, u32 newLength); bool dynos_gfx_delete(Gfx *gfx); void dynos_gfx_delete_all(); Vtx *dynos_vtx_get(const char *name, u32 *outCount); +const char *dynos_vtx_get_name(Vtx *vtx); Vtx *dynos_vtx_create(const char *name, u32 count); bool dynos_vtx_resize(Vtx *vtx, u32 newCount); bool dynos_vtx_delete(Vtx *vtx); diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index 763cec64b..3afdfb859 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -897,7 +897,7 @@ void DynOS_Pack_AddTex(PackData* aPackData, DataNode* aTexData); // std::map &DynOS_Actor_GetValidActors(); -void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFilename, const char *aActorName); +bool DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFilename, const char *aActorName); const void *DynOS_Actor_GetLayoutFromName(const char *aActorName); bool DynOS_Actor_GetModIndexAndToken(const GraphNode *aGraphNode, u32 aTokenIndex, s32 *outModIndex, s32 *outModFileIndex, const char **outToken); ActorGfx* DynOS_Actor_GetActorGfx(const GraphNode* aGraphNode); @@ -925,7 +925,7 @@ u8 *DynOS_Tex_ConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat, s32 aSi bool DynOS_Tex_Import(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, void **aHashMap, void *aPool, u32 *aPoolPos, u32 aPoolSize); void DynOS_Tex_Activate(DataNode* aNode, bool aCustomTexture); void DynOS_Tex_Deactivate(DataNode* aNode); -void DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName); +bool DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName); bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo); bool DynOS_Tex_GetFromData(const Texture *aTex, struct TextureInfo* aOutTexInfo); void DynOS_Tex_Override_Set(const char* textureName, struct TextureInfo* aOverrideTexInfo); @@ -963,7 +963,7 @@ void DynOS_Bhv_ModShutdown(); // Col Manager // -void DynOS_Col_Activate(const SysPath &aFilePath, const char *aCollisionName); +bool DynOS_Col_Activate(const SysPath &aFilePath, const char *aCollisionName); Collision* DynOS_Col_Get(const char* collisionName); void DynOS_Col_ModShutdown(); @@ -996,11 +996,13 @@ void DynOS_Model_ClearPool(enum ModelPool aModelPool); Gfx *DynOS_Gfx_GetWritableDisplayList(Gfx *aGfx); Gfx *DynOS_Gfx_Get(const char *aName, u32 *outLength); +const char *DynOS_Gfx_GetName(Gfx *aGfx); Gfx *DynOS_Gfx_Create(const char *aName, u32 aLength); bool DynOS_Gfx_Resize(Gfx *aGfx, u32 aNewLength); bool DynOS_Gfx_Delete(Gfx *aGfx); void DynOS_Gfx_DeleteAll(); Vtx *DynOS_Vtx_Get(const char *aName, u32 *outCount); +const char *DynOS_Vtx_GetName(Vtx *aVtx); Vtx *DynOS_Vtx_Create(const char *aName, u32 aCount); bool DynOS_Vtx_Resize(Vtx *aVtx, u32 aNewCount); bool DynOS_Vtx_Delete(Vtx *aVtx); diff --git a/data/dynos_bin_compress.cpp b/data/dynos_bin_compress.cpp index 02a3546a5..302c6c2b1 100644 --- a/data/dynos_bin_compress.cpp +++ b/data/dynos_bin_compress.cpp @@ -1,6 +1,10 @@ #include "dynos.cpp.h" #include +extern "C" { +#include "pc/mods/mod_fs.h" +} + static const u64 DYNOS_BIN_COMPRESS_MAGIC = 0x4E4942534F4E5944llu; static FILE *sFile = NULL; static u8 *sBufferUncompressed = NULL; @@ -154,9 +158,75 @@ bool DynOS_Bin_Compress(const SysPath &aFilename) { return true; } +static BinFile *DynOS_Bin_Decompress_ModFs(const SysPath &aFilename) { + DynOS_Bin_Compress_Init(); + + // Read file data + void *_Buffer = NULL; + u32 _Size = 0; + if (!mod_fs_read_file_from_uri(aFilename.c_str(), &_Buffer, &_Size)) { + DynOS_Bin_Compress_Free(); + return NULL; + } + sBufferCompressed = (u8 *) _Buffer; + sLengthCompressed = _Size; + + // Check file length + u64 _LengthHeader = (u64) (sizeof(u64) + sizeof(u64)); + if (!DynOS_Bin_Compress_Check( + sLengthCompressed >= _LengthHeader, + __FUNCTION__, aFilename.c_str(), "Empty file" + )) return NULL; + + // Compare with magic constant + // If not equal, it's not a compressed file + u64 _Magic = ((u64 *) _Buffer)[0]; + if (_Magic != DYNOS_BIN_COMPRESS_MAGIC) { + BinFile *_BinFile = BinFile::OpenB(sBufferCompressed, sLengthCompressed); + DynOS_Bin_Compress_Free(); + return _BinFile; + } + PrintNoNewLine("Decompressing file \"%s\"...", aFilename.c_str()); + + // Read expected uncompressed file size + sLengthUncompressed = ((u64 *) _Buffer)[1]; + sLengthCompressed -= _LengthHeader; + u8 *_BufferCompressed = sBufferCompressed + _LengthHeader; + + // Allocate memory for uncompressed buffer + if (!DynOS_Bin_Compress_Check( + (sBufferUncompressed = (u8 *) calloc(sLengthUncompressed, sizeof(u8))) != NULL, + __FUNCTION__, aFilename.c_str(), "Cannot allocate memory for decompression" + )) return NULL; + + // Uncompress data + uLongf _LengthUncompressed = (uLongf)sLengthUncompressed; + int uncompressRc = uncompress(sBufferUncompressed, &_LengthUncompressed, _BufferCompressed, sLengthCompressed); + sLengthUncompressed = _LengthUncompressed; + if (!DynOS_Bin_Compress_Check( + uncompressRc == Z_OK, + __FUNCTION__, aFilename.c_str(), "Cannot uncompress data" + )) { + PrintError("ERROR: uncompress rc: %d, length uncompressed: %lu, length compressed: %lu, length header: %lu", uncompressRc, sLengthUncompressed, sLengthCompressed, _LengthHeader); + return NULL; + } + Print("uncompress rc: %d, length uncompressed: %lu, length compressed: %lu, length header: %lu", uncompressRc, sLengthUncompressed, sLengthCompressed, _LengthHeader); + + // Return uncompressed data as a BinFile + BinFile *_BinFile = BinFile::OpenB(sBufferUncompressed, sLengthUncompressed); + DynOS_Bin_Compress_Free(); + Print(" Done."); + return _BinFile; +} + BinFile *DynOS_Bin_Decompress(const SysPath &aFilename) { DynOS_Bin_Compress_Init(); + // Check modfs + if (is_mod_fs_file(aFilename.c_str())) { + return DynOS_Bin_Decompress_ModFs(aFilename); + } + // Open input file if (!DynOS_Bin_Compress_Check( (sFile = f_open_r(aFilename.c_str())) != NULL, diff --git a/data/dynos_bin_gfx.cpp b/data/dynos_bin_gfx.cpp index 5d22cfe05..ae61971cc 100644 --- a/data/dynos_bin_gfx.cpp +++ b/data/dynos_bin_gfx.cpp @@ -405,6 +405,9 @@ s64 DynOS_Gfx_ParseGfxConstants(const String& _Arg, bool* found) { gfx_constant(G_LIGHT_MAP_EXT); gfx_constant(G_LIGHTING_ENGINE_EXT); gfx_constant(G_PACKED_NORMALS_EXT); + gfx_constant(G_CULL_INVERT_EXT); + gfx_constant(G_FRESNEL_COLOR_EXT); + gfx_constant(G_FRESNEL_ALPHA_EXT); gfx_constant(G_COL_PRIM); gfx_constant(G_COL_ENV); @@ -1211,7 +1214,7 @@ static String ResolveParam(lua_State *L, GfxData *aGfxData, u32 paramIndex, char case GFX_PARAM_TYPE_TEX: return ConvertParam( L, aGfxData, paramIndex, "Texture pointer", - [] (lua_State *L, u32 paramIndex) { return (Texture *) smlua_to_cpointer(L, paramIndex, LVT_U8_P); }, + [] (lua_State *L, u32 paramIndex) { return (Texture *) smlua_to_cpointer(L, paramIndex, LVT_TEXTURE_P); }, [&aGfxData] (Texture *texture) { return CreateRawPointerDataNode(aGfxData, texture); } ); diff --git a/data/dynos_bin_lvl.cpp b/data/dynos_bin_lvl.cpp index e3e9a27ed..ff20ede76 100644 --- a/data/dynos_bin_lvl.cpp +++ b/data/dynos_bin_lvl.cpp @@ -641,6 +641,15 @@ static LevelScript ParseLevelScriptSymbolArg(GfxData* aGfxData, DataNode* aNode, u64& aTokenIndex, u32 *luaParams, u32 luaParamFlag) { + bool foundParam = true; + LevelScript value = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundParam); + if (!foundParam) { + *luaParams |= luaParamFlag; + } + return value; +} + static void ParseLevelScriptSymbol(GfxData* aGfxData, DataNode* aNode, LevelScript*& aHead, u64& aTokenIndex, Array& aSwitchNodes) { const String& _Symbol = aNode->mTokens[aTokenIndex++]; @@ -711,7 +720,6 @@ static void ParseLevelScriptSymbol(GfxData* aGfxData, DataNode* aNo lvl_symbol_0(CMD2D); lvl_symbol_1(TERRAIN, 1); lvl_symbol_1(ROOMS, 1); - lvl_symbol_2(SHOW_DIALOG, 0, 0); lvl_symbol_1(TERRAIN_TYPE, 0); lvl_symbol_0(NOP); @@ -733,75 +741,75 @@ static void ParseLevelScriptSymbol(GfxData* aGfxData, DataNode* aNo lvl_symbol_0(ADV_DEMO); lvl_symbol_0(CLEAR_DEMO_PTR); - // object - if (_Symbol == "OBJECT") { + // dialog + if (_Symbol == "SHOW_DIALOG") { u64 topTokenIndex = aTokenIndex; + + u32 luaParams = 0; + LevelScript index = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, SHOW_DIALOG_EXT_LUA_INDEX); + LevelScript dialogId = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, SHOW_DIALOG_EXT_LUA_DIALOG); - bool foundModel = true; - bool foundBeh = true; - LevelScript model = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundModel); - LevelScript posX = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript posY = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript posZ = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript angleX = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript angleY = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript angleZ = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript behParam = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript beh = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); + if (luaParams != 0) { + LevelScript finalIndex = (luaParams & SHOW_DIALOG_EXT_LUA_INDEX) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]) : index; + LevelScript finalDialogId = (luaParams & SHOW_DIALOG_EXT_LUA_DIALOG) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 2, aNode->mTokens[topTokenIndex + 1]) : dialogId; - if (foundModel && foundBeh) { - aGfxData->mPointerList.Add(aHead + 5); - LevelScript _Ls[] = { OBJECT(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, beh) }; - memcpy(aHead, _Ls, sizeof(_Ls)); - aHead += (sizeof(_Ls) / sizeof(_Ls[0])); - } else if (foundModel) { - u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 5, aNode->mTokens[topTokenIndex + 8]); - LevelScript _Ls[] = { OBJECT_EXT(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, behIndex) }; + LevelScript _Ls[] = { SHOW_DIALOG_EXT(luaParams, finalIndex, finalDialogId) }; memcpy(aHead, _Ls, sizeof(_Ls)); aHead += (sizeof(_Ls) / sizeof(_Ls[0])); } else { - u32 modelIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 5, aNode->mTokens[topTokenIndex + 0]); - u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 6, aNode->mTokens[topTokenIndex + 8]); - LevelScript _Ls[] = { OBJECT_EXT2(modelIndex, posX, posY, posZ, angleX, angleY, angleZ, behParam, behIndex) }; + LevelScript _Ls[] = { SHOW_DIALOG(index, dialogId) }; memcpy(aHead, _Ls, sizeof(_Ls)); aHead += (sizeof(_Ls) / sizeof(_Ls[0])); } return; } - // object with acts - if (_Symbol == "OBJECT_WITH_ACTS") { + // object + if (_Symbol == "OBJECT" || _Symbol == "OBJECT_WITH_ACTS") { u64 topTokenIndex = aTokenIndex; - bool foundModel = true; - bool foundBeh = true; - LevelScript model = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundModel); - LevelScript posX = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript posY = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript posZ = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript angleX = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript angleY = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript angleZ = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript behParam = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); - LevelScript beh = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh); - LevelScript acts = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex); + u32 luaParams = 0; + LevelScript model = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_MODEL); + LevelScript posX = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_POS_X); + LevelScript posY = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_POS_Y); + LevelScript posZ = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_POS_Z); + LevelScript angleX = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_ANGLE_X); + LevelScript angleY = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_ANGLE_Y); + LevelScript angleZ = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_ANGLE_Z); + LevelScript behParam = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_BEH_PARAMS); + LevelScript beh = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_BEHAVIOR); + LevelScript acts = (_Symbol == "OBJECT_WITH_ACTS") ? ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_ACTS) : 0x1F; - if (foundModel && foundBeh) { + // At least one parameter is a Lua variable, use OBJECT_EXT_LUA_PARAMS + if (luaParams != 0) { + + // Remember behavior pointer if it's not a Lua param + if (!(luaParams & OBJECT_EXT_LUA_BEHAVIOR)) { + aGfxData->mPointerList.Add(aHead + 9); + } + + LevelScript finalModel = (luaParams & OBJECT_EXT_LUA_MODEL) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]) : model; + LevelScript finalPosX = (luaParams & OBJECT_EXT_LUA_POS_X) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 2, aNode->mTokens[topTokenIndex + 1]) : posX; + LevelScript finalPosY = (luaParams & OBJECT_EXT_LUA_POS_Y) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 3, aNode->mTokens[topTokenIndex + 2]) : posY; + LevelScript finalPosZ = (luaParams & OBJECT_EXT_LUA_POS_Z) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 4, aNode->mTokens[topTokenIndex + 3]) : posZ; + LevelScript finalAngleX = (luaParams & OBJECT_EXT_LUA_ANGLE_X) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 5, aNode->mTokens[topTokenIndex + 4]) : angleX; + LevelScript finalAngleY = (luaParams & OBJECT_EXT_LUA_ANGLE_Y) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 6, aNode->mTokens[topTokenIndex + 5]) : angleY; + LevelScript finalAngleZ = (luaParams & OBJECT_EXT_LUA_ANGLE_Z) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 7, aNode->mTokens[topTokenIndex + 6]) : angleZ; + LevelScript finalBehParam = (luaParams & OBJECT_EXT_LUA_BEH_PARAMS) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 8, aNode->mTokens[topTokenIndex + 7]) : behParam; + LevelScript finalBeh = (luaParams & OBJECT_EXT_LUA_BEHAVIOR) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 9, aNode->mTokens[topTokenIndex + 8]) : beh; + LevelScript finalActs = (luaParams & OBJECT_EXT_LUA_ACTS) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 10, aNode->mTokens[topTokenIndex + 9]) : acts; + + LevelScript _Ls[] = { OBJECT_EXT_LUA_PARAMS(luaParams, finalModel, finalPosX, finalPosY, finalPosZ, finalAngleX, finalAngleY, finalAngleZ, finalBehParam, finalBeh, finalActs) }; + memcpy(aHead, _Ls, sizeof(_Ls)); + aHead += (sizeof(_Ls) / sizeof(_Ls[0])); + } + + // No Lua parameter, use OBJECT_WITH_ACTS + else { aGfxData->mPointerList.Add(aHead + 5); LevelScript _Ls[] = { OBJECT_WITH_ACTS(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, beh, acts) }; memcpy(aHead, _Ls, sizeof(_Ls)); aHead += (sizeof(_Ls) / sizeof(_Ls[0])); - } else if (foundModel) { - u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 5, aNode->mTokens[topTokenIndex + 8]); - LevelScript _Ls[] = { OBJECT_WITH_ACTS_EXT(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, behIndex, acts) }; - memcpy(aHead, _Ls, sizeof(_Ls)); - aHead += (sizeof(_Ls) / sizeof(_Ls[0])); - } else { - u32 modelIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 5, aNode->mTokens[topTokenIndex + 0]); - u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 6, aNode->mTokens[topTokenIndex + 8]); - LevelScript _Ls[] = { OBJECT_WITH_ACTS_EXT2(modelIndex, posX, posY, posZ, angleX, angleY, angleZ, behParam, behIndex, acts) }; - memcpy(aHead, _Ls, sizeof(_Ls)); - aHead += (sizeof(_Ls) / sizeof(_Ls[0])); } return; } @@ -1063,12 +1071,12 @@ static DataNode* DynOS_Lvl_Load(BinFile *aFile, GfxData *aGfxData) void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, FUNCTION_LVL, &_Node->mFlags); if (_Ptr) { - if (!requirePointer) { + if (!requirePointer && _Value != LUA_VAR_CODE) { PrintError("Didn't expect a pointer while reading level script: %s, %u", _Node->mName.begin(), _Value); } _Node->mData[i] = (uintptr_t) _Ptr; } else { - if (requirePointer) { + if (requirePointer && _Value != LUA_VAR_CODE) { PrintError("Expected a pointer while reading level script: %s, %u", _Node->mName.begin(), _Value); _Node->mData[i] = 0; } else { diff --git a/data/dynos_bin_lvl_validate.cpp b/data/dynos_bin_lvl_validate.cpp index 422d26a37..e592036ed 100644 --- a/data/dynos_bin_lvl_validate.cpp +++ b/data/dynos_bin_lvl_validate.cpp @@ -134,6 +134,8 @@ static void LvlCmd_Init() { ADD_COMMAND(OBJECT_EXT2(POINTER, 0, 0, 0, 0, 0, 0, 0, POINTER)); ADD_COMMAND(LOAD_MODEL_FROM_GEO_EXT(0, POINTER)); ADD_COMMAND(JUMP_AREA_EXT(0, 0, POINTER)); + ADD_COMMAND(OBJECT_EXT_LUA_PARAMS(0, 0, 0, 0, 0, 0, 0, 0, 0, POINTER, 0)); + ADD_COMMAND(SHOW_DIALOG_EXT(0, 0, 0)) } void DynOS_Lvl_Validate_Begin() { diff --git a/data/dynos_bin_tex.cpp b/data/dynos_bin_tex.cpp index 7385726ae..858526d45 100644 --- a/data/dynos_bin_tex.cpp +++ b/data/dynos_bin_tex.cpp @@ -2,8 +2,11 @@ extern "C" { #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb/stb_image_write.h" +#include "pc/mods/mod_fs.h" } +#define PNG_SIGNATURE 0x0A1A0A0D474E5089llu + /////////// // Utils // /////////// @@ -304,46 +307,67 @@ DataNode* DynOS_Tex_LoadFromBinary(const SysPath &aPackFolder, const Sy // Load data from binary file DataNode* _TexNode = NULL; - BinFile *_File = BinFile::OpenR(aFilename.c_str()); + BinFile *_File = NULL; + if (is_mod_fs_file(aFilename.c_str())) { + void *_Buffer = NULL; + u32 _Size = 0; + if (mod_fs_read_file_from_uri(aFilename.c_str(), &_Buffer, &_Size)) { + _File = BinFile::OpenB((const u8 *) _Buffer, _Size); + free(_Buffer); + } + } else { + _File = BinFile::OpenR(aFilename.c_str()); + } if (!_File) { return NULL; } u8 type = _File->Read(); if (type == DATA_TYPE_TEXTURE) { + // load png-texture _TexNode = New>(); - _TexNode->mData = New(); - _TexNode->mName.Read(_File); + _TexNode->mData = New(); _TexNode->mData->mPngData.Read(_File); - BinFile::Close(_File); + + } else if (type == DATA_TYPE_TEXTURE_RAW) { + + // load raw-texture + _TexNode = New>(); + _TexNode->mName.Read(_File); + _TexNode->mData = New(); + _TexNode->mData->mRawFormat = _File->Read(); + _TexNode->mData->mRawSize = _File->Read(); + _TexNode->mData->mRawWidth = _File->Read(); + _TexNode->mData->mRawHeight = _File->Read(); + _TexNode->mData->mRawData.Read(_File); + + } else if ((_File->SetOffset(0), _File->Read() == PNG_SIGNATURE)) { + _File->SetOffset(0); + + // load PNG file + _TexNode = New>(); + _TexNode->mName = aFilename.c_str(); + _TexNode->mData = New(); + _TexNode->mData->mPngData.Resize(_File->Size()); + _File->Read(_TexNode->mData->mPngData.begin(), _File->Size()); + } + + BinFile::Close(_File); + + if (_TexNode) { + + // For some reason texture nodes are indexed to DynosCustomTexs by their node name, + // and not by `aTexName`, but DynOS_Tex_Get searches for `aTexName`... + // Normally, this doesn't cause any issue, but things go wrong when `aTexName` + // is not the same as the texture node name (which is the case for modfs files). + if (is_mod_fs_file(aFilename.c_str())) { + _TexNode->mName = aTexName; + } if (aAddToPack) { if (!_Pack) { _Pack = DynOS_Pack_Add(aPackFolder); } DynOS_Pack_AddTex(_Pack, _TexNode); } - - return _TexNode; - } else if (type != DATA_TYPE_TEXTURE_RAW) { - BinFile::Close(_File); - return NULL; - } - - // load raw-texture - _TexNode = New>(); - _TexNode->mData = New(); - - _TexNode->mName.Read(_File); - _TexNode->mData->mRawFormat = _File->Read(); - _TexNode->mData->mRawSize = _File->Read(); - _TexNode->mData->mRawWidth = _File->Read(); - _TexNode->mData->mRawHeight = _File->Read(); - _TexNode->mData->mRawData.Read(_File); - - BinFile::Close(_File); - - if (aAddToPack) { - if (!_Pack) { _Pack = DynOS_Pack_Add(aPackFolder); } - DynOS_Pack_AddTex(_Pack, _TexNode); } return _TexNode; diff --git a/data/dynos_c.cpp b/data/dynos_c.cpp index 850f4006d..0bbd25ed3 100644 --- a/data/dynos_c.cpp +++ b/data/dynos_c.cpp @@ -115,8 +115,8 @@ void dynos_actor_override(struct Object* obj, void** aSharedChild) { DynOS_Actor_Override(obj, aSharedChild); } -void dynos_add_actor_custom(s32 modIndex, s32 modFileIndex, const char *filePath, const char* geoName) { - DynOS_Actor_AddCustom(modIndex, modFileIndex, filePath, geoName); +bool dynos_add_actor_custom(s32 modIndex, s32 modFileIndex, const char *filePath, const char* geoName) { + return DynOS_Actor_AddCustom(modIndex, modFileIndex, filePath, geoName); } const void* dynos_geolayout_get(const char *name) { @@ -133,8 +133,8 @@ void dynos_actor_register_modified_graph_node(struct GraphNode *node) { // -- collisions -- // -void dynos_add_collision(const char *filePath, const char* collisionName) { - DynOS_Col_Activate(filePath, collisionName); +bool dynos_add_collision(const char *filePath, const char* collisionName) { + return DynOS_Col_Activate(filePath, collisionName); } Collision* dynos_collision_get(const char* collisionName) { @@ -143,9 +143,9 @@ Collision* dynos_collision_get(const char* collisionName) { // -- textures -- // -void dynos_add_texture(const char *filePath, const char* textureName) { +bool dynos_add_texture(const char *filePath, const char* textureName) { SysPath _FilePath = filePath; - DynOS_Tex_AddCustom(_FilePath, textureName); + return DynOS_Tex_AddCustom(_FilePath, textureName); } bool dynos_texture_get(const char* textureName, struct TextureInfo* outTextureInfo) { @@ -292,6 +292,10 @@ Gfx *dynos_gfx_get(const char *name, u32 *outLength) { return DynOS_Gfx_Get(name, outLength); } +const char *dynos_gfx_get_name(Gfx *gfx) { + return DynOS_Gfx_GetName(gfx); +} + Gfx *dynos_gfx_create(const char *name, u32 length) { return DynOS_Gfx_Create(name, length); } @@ -312,6 +316,10 @@ Vtx *dynos_vtx_get(const char *name, u32 *outCount) { return DynOS_Vtx_Get(name, outCount); } +const char *dynos_vtx_get_name(Vtx *vtx) { + return DynOS_Vtx_GetName(vtx); +} + Vtx *dynos_vtx_create(const char *name, u32 count) { return DynOS_Vtx_Create(name, count); } diff --git a/data/dynos_mgr_actor.cpp b/data/dynos_mgr_actor.cpp index 5aba16350..fda357d0c 100644 --- a/data/dynos_mgr_actor.cpp +++ b/data/dynos_mgr_actor.cpp @@ -9,6 +9,7 @@ extern "C" { #include "game/object_list_processor.h" #include "pc/configfile.h" #include "pc/lua/smlua_hooks.h" +#include "pc/mods/mod_fs.h" } // Static maps/arrays @@ -31,7 +32,7 @@ std::map &DynOS_Actor_GetValidActors() { return DynosValidActors(); } -void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFilename, const char *aActorName) { +bool DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFilename, const char *aActorName) { const void* georef = DynOS_Builtin_Actor_GetFromName(aActorName); u16 actorLen = strlen(aActorName); @@ -42,7 +43,7 @@ void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFil if (!_GfxData) { PrintError(" ERROR: Couldn't load Actor Binary \"%s\" from \"%s\"", actorName, aFilename.c_str()); free(actorName); - return; + return false; } _GfxData->mModIndex = aModIndex; _GfxData->mModFileIndex = aModFileIndex; @@ -51,7 +52,7 @@ void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFil if (!geoLayout) { PrintError(" ERROR: Couldn't load geo layout for \"%s\"", actorName); free(actorName); - return; + return false; } // Alloc and init the actors gfx list @@ -63,7 +64,7 @@ void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFil if (!actorGfx.mGraphNode) { PrintError(" ERROR: Couldn't load graph node for \"%s\"", actorName); free(actorName); - return; + return false; } actorGfx.mGraphNode->georef = georef; @@ -76,6 +77,7 @@ void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFil // Add to list DynOS_Actor_Valid(georef, actorGfx); free(actorName); + return true; } const void *DynOS_Actor_GetLayoutFromName(const char *aActorName) { @@ -115,6 +117,13 @@ const void *DynOS_Actor_GetLayoutFromName(const char *aActorName) { } } + // check modfs file + if (is_mod_fs_file(aActorName)) { + if (DynOS_Actor_AddCustom(gLuaActiveMod->index, -1, aActorName, aActorName)) { + return DynOS_Actor_GetLayoutFromName(aActorName); + } + } + return NULL; } @@ -222,7 +231,6 @@ void DynOS_Actor_Override(struct Object* obj, void** aSharedChild) { } } - *aSharedChild = (void*)it->second.mGraphNode; } diff --git a/data/dynos_mgr_col.cpp b/data/dynos_mgr_col.cpp index 9a6d5f4db..66bf497ae 100644 --- a/data/dynos_mgr_col.cpp +++ b/data/dynos_mgr_col.cpp @@ -1,17 +1,21 @@ #include "dynos.cpp.h" +extern "C" { +#include "pc/mods/mod_fs.h" +} + static Array*>>& DynosCollisions() { static Array*>> sDynosCollisions; return sDynosCollisions; } -void DynOS_Col_Activate(const SysPath &aFilename, const char *aCollisionName) { +bool DynOS_Col_Activate(const SysPath &aFilename, const char *aCollisionName) { auto& _DynosCollisions = DynosCollisions(); // check for duplicates for (s32 i = 0; i < _DynosCollisions.Count(); ++i) { if (!strcmp(_DynosCollisions[i].first, aCollisionName)) { - return; + return true; } } @@ -24,11 +28,12 @@ void DynOS_Col_Activate(const SysPath &aFilename, const char *aCollisionName) { DataNode* _Node = DynOS_Col_LoadFromBinary(aFilename, collisionName); if (!_Node) { free(collisionName); - return; + return false; } // Add to collisions _DynosCollisions.Add({ collisionName, _Node }); + return true; } Collision* DynOS_Col_Get(const char* collisionName) { @@ -51,6 +56,13 @@ Collision* DynOS_Col_Get(const char* collisionName) { } } + // check modfs file + if (is_mod_fs_file(collisionName)) { + if (DynOS_Col_Activate(collisionName, collisionName)) { + return DynOS_Col_Get(collisionName); + } + } + // check builtin collisions return (Collision*)DynOS_Builtin_Col_GetFromName(collisionName); } diff --git a/data/dynos_mgr_gfx.cpp b/data/dynos_mgr_gfx.cpp index 068cba698..99228d0d6 100644 --- a/data/dynos_mgr_gfx.cpp +++ b/data/dynos_mgr_gfx.cpp @@ -3,6 +3,7 @@ extern "C" { #include "pc/lua/smlua.h" #include "pc/lua/utils/smlua_gfx_utils.h" +#include "pc/mods/mods.h" } struct MapNode { @@ -13,6 +14,7 @@ struct MapNode { // Maps read-only Gfx and Vtx buffers to their writable duplicates static std::map sRomToRamGfxVtxMap; +static std::map sRamToRomGfxVtxMap; // Reverse map for duplicate to vanilla lookup static Vtx *DynOS_Vtx_Duplicate(Vtx *aVtx, u32 vtxCount, bool shouldDuplicate) { if (!aVtx) { return NULL; } @@ -29,6 +31,7 @@ static Vtx *DynOS_Vtx_Duplicate(Vtx *aVtx, u32 vtxCount, bool shouldDuplicate) { Vtx *vtxDuplicate = vtx_allocate_internal(NULL, vtxCount); memcpy(vtxDuplicate, aVtx, vtxSize); sRomToRamGfxVtxMap[aVtx] = { (void *) vtxDuplicate, vtxSize, NULL }; + sRamToRomGfxVtxMap[vtxDuplicate] = aVtx; return vtxDuplicate; } @@ -81,6 +84,7 @@ static Gfx *DynOS_Gfx_Duplicate(Gfx *aGfx, bool shouldDuplicate) { Gfx *gfxCopy = (Gfx *) malloc(gfxSize); memcpy(gfxCopy, gfxDuplicate, gfxSize); sRomToRamGfxVtxMap[aGfx] = { (void *) gfxDuplicate, gfxSize, gfxCopy }; + sRamToRomGfxVtxMap[gfxDuplicate] = aGfx; } return gfxDuplicate; @@ -136,24 +140,20 @@ Gfx *DynOS_Gfx_Get(const char *aName, u32 *outLength) { // Check levels for (auto &lvl : DynOS_Lvl_GetArray()) { - if (modIndex == -1 || lvl.second->mModIndex == modIndex) { - for (auto &gfx : lvl.second->mDisplayLists) { - if (gfx->mName == aName) { - *outLength = gfx->mSize; - return gfx->mData; - } + for (auto &gfx : lvl.second->mDisplayLists) { + if (gfx->mName == aName) { + *outLength = gfx->mSize; + return gfx->mData; } } } // Check loaded actors for (auto &actor : DynOS_Actor_GetValidActors()) { - if (modIndex == -1 || actor.second.mGfxData->mModIndex == modIndex) { - for (auto &gfx : actor.second.mGfxData->mDisplayLists) { - if (gfx->mName == aName) { - *outLength = gfx->mSize; - return gfx->mData; - } + for (auto &gfx : actor.second.mGfxData->mDisplayLists) { + if (gfx->mName == aName) { + *outLength = gfx->mSize; + return gfx->mData; } } } @@ -176,6 +176,42 @@ Gfx *DynOS_Gfx_Get(const char *aName, u32 *outLength) { return NULL; } +const char *DynOS_Gfx_GetName(Gfx *aGfx) { + if (!aGfx) { return NULL; } + s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1); + + // Check mod data + static std::string outName; + if (sModsDisplayLists.GetName(modIndex, aGfx, outName)) { + return outName.c_str(); + } + + // Check levels + for (auto &lvl : DynOS_Lvl_GetArray()) { + for (auto &gfx : lvl.second->mDisplayLists) { + if (gfx->mData == aGfx) { + return gfx->mName.begin(); + } + } + } + + // Check loaded actors + for (auto &actor : DynOS_Actor_GetValidActors()) { + for (auto &gfx : actor.second.mGfxData->mDisplayLists) { + if (gfx->mData == aGfx) { + return gfx->mName.begin(); + } + } + } + + // Check vanilla display lists + auto it = sRamToRomGfxVtxMap.find(aGfx); + if (it != sRamToRomGfxVtxMap.end()) { + return DynOS_Builtin_Gfx_GetFromData((const Gfx *) it->second); + } + return DynOS_Builtin_Gfx_GetFromData(aGfx); +} + Gfx *DynOS_Gfx_Create(const char *aName, u32 aLength) { s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1); return sModsDisplayLists.Create(modIndex, aName, aLength); @@ -240,24 +276,51 @@ Vtx *DynOS_Vtx_Get(const char *aName, u32 *outCount) { // Check levels for (auto &lvl : DynOS_Lvl_GetArray()) { - if (modIndex == -1 || lvl.second->mModIndex == modIndex) { - for (auto &vtx : lvl.second->mVertices) { - if (vtx->mName == aName) { - *outCount = vtx->mSize; - return vtx->mData; - } + for (auto &vtx : lvl.second->mVertices) { + if (vtx->mName == aName) { + *outCount = vtx->mSize; + return vtx->mData; } } } // Check loaded actors for (auto &actor : DynOS_Actor_GetValidActors()) { - if (modIndex == -1 || actor.second.mGfxData->mModIndex == modIndex) { - for (auto &vtx : actor.second.mGfxData->mVertices) { - if (vtx->mName == aName) { - *outCount = vtx->mSize; - return vtx->mData; - } + for (auto &vtx : actor.second.mGfxData->mVertices) { + if (vtx->mName == aName) { + *outCount = vtx->mSize; + return vtx->mData; + } + } + } + + return NULL; +} + +const char *DynOS_Vtx_GetName(Vtx *aVtx) { + if (!aVtx) { return NULL; } + s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1); + + // Check mod data + static std::string outName; + if (sModsVertexBuffers.GetName(modIndex, aVtx, outName)) { + return outName.c_str(); + } + + // Check levels + for (auto &lvl : DynOS_Lvl_GetArray()) { + for (auto &vtx : lvl.second->mVertices) { + if (vtx->mData == aVtx) { + return vtx->mName.begin(); + } + } + } + + // Check loaded actors + for (auto &actor : DynOS_Actor_GetValidActors()) { + for (auto &vtx : actor.second.mGfxData->mVertices) { + if (vtx->mData == aVtx) { + return vtx->mName.begin(); } } } diff --git a/data/dynos_mgr_moddata.hpp b/data/dynos_mgr_moddata.hpp index 56db167a5..c4d3721cf 100644 --- a/data/dynos_mgr_moddata.hpp +++ b/data/dynos_mgr_moddata.hpp @@ -135,7 +135,6 @@ public: mMapNameToItem.clear(); } -private: ModDataResult *> Find(T *aPointer, std::string &outName) { if (!aPointer) { return { NULL, DYNOS_MOD_DATA_ERROR_POINTER_IS_NULL }; @@ -151,6 +150,7 @@ private: return { NULL, 0 }; } +private: ModDataResult *> FindAvailableItem() { // Create pool if it doesn't exist yet @@ -212,6 +212,16 @@ public: return getResult.first->mBuffer; } + bool GetName(s32 aModIndex, T *aPointer, std::string &outName) { + ModDataT *modData = GetModData(aModIndex); + auto findResult = modData->Find(aPointer, outName); + if (!findResult.first) { + gDynosModDataLastError = findResult.second; + return false; + } + return true; + } + T *Create(s32 aModIndex, const char *aName, u32 aSize) { ModDataT *modData = GetModData(aModIndex); auto createResult = modData->Create(aName, aSize); diff --git a/data/dynos_mgr_tex.cpp b/data/dynos_mgr_tex.cpp index 5531c0710..5bc3bceb6 100644 --- a/data/dynos_mgr_tex.cpp +++ b/data/dynos_mgr_tex.cpp @@ -4,6 +4,7 @@ extern "C" { #include "pc/gfx/gfx.h" #include "pc/gfx/gfx_rendering_api.h" +#include "pc/mods/mod_fs.h" } struct OverrideTexture { @@ -423,13 +424,13 @@ void DynOS_Tex_Deactivate(DataNode* aNode) { _Schedule.Add(aNode); } -void DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName) { +bool DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName) { auto& _DynosCustomTexs = DynosCustomTexs(); // check for duplicates for (s32 i = 0; i < _DynosCustomTexs.Count(); ++i) { if (!strcmp(_DynosCustomTexs[i].first, aTexName)) { - return; + return true; } } @@ -444,7 +445,9 @@ void DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName) { free(_TexName); if (_Node) { DynOS_Tex_Activate(_Node, true); + return true; } + return false; } #define CONVERT_TEXINFO(texName) { \ @@ -488,6 +491,13 @@ bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) { } } + // check modfs file + if (is_mod_fs_file(aTexName)) { + if (DynOS_Tex_AddCustom(aTexName, aTexName)) { + return DynOS_Tex_Get(aTexName, aOutTexInfo); + } + } + // check builtin textures const struct BuiltinTexInfo* info = DynOS_Builtin_Tex_GetInfoFromName(aTexName); if (!info) { @@ -503,7 +513,7 @@ bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) { aOutTexInfo->bitSize = info->bitSize; aOutTexInfo->width = info->width; aOutTexInfo->height = info->height; - aOutTexInfo->texture = (u8*)info->pointer; + aOutTexInfo->texture = (Texture*)info->pointer; aOutTexInfo->name = aTexName; return true; } @@ -522,7 +532,7 @@ bool DynOS_Tex_GetFromData(const Texture *aTex, struct TextureInfo* aOutTexInfo) aOutTexInfo->bitSize = info->bitSize; aOutTexInfo->width = info->width; aOutTexInfo->height = info->height; - aOutTexInfo->texture = (u8*)info->pointer; + aOutTexInfo->texture = (Texture*)info->pointer; aOutTexInfo->name = info->identifier; return true; } diff --git a/developer/dir2modfs.py b/developer/dir2modfs.py deleted file mode 100644 index af41a2abd..000000000 --- a/developer/dir2modfs.py +++ /dev/null @@ -1,190 +0,0 @@ -import os, sys, re - - -MOD_FS_MAGIC = "MODFSSM64COOPDX" -MOD_FS_HEADER_SIZE = 32 -MOD_FS_EXTENSION = ".modfs" -MOD_FS_VERSION = 1 -MOD_FS_MAX_SIZE = 0x1000000 -MOD_FS_MAX_FILES = 0x100 -MOD_FS_MAX_PATH = 0x100 - - -def usage(): - print(""" -Directory to modfs: - - python dir2modfs.py [--set-public] [--set-file-public ...] - - Parameters: - dirpath Path to directory to turn into a .modfs file - - Options: - --set-public Set modfs file as public (readable by other mods) - --set-file-public Set the provided files as public (readable by other mods) - -modfs to directory: - - python dir2modfs.py --extract - - Parameters: - filepath Path to modfs file to extract files from -""") - exit(0) - - -def is_binary_file(bytes: bytes): - textchars = bytearray({0x07, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x1B} | set(range(0x20, 0x100)) - {0x7F}) - return bool(bytes.translate(None, textchars)) - - -def get_files(dirpath: str, public_files: list): - files = [] - for root, _, filenames in os.walk(dirpath): - for filename in filenames: - relpath = os.path.join(root, filename) - filepath = relpath.removeprefix(dirpath).strip("/\\").replace('\\', '/') - is_public = False - for public_file in public_files: - if re.match(public_file, relpath) or re.match(public_file, filepath): - is_public = True - break - files.append({ - "relpath": relpath, - "filepath": filepath, - "is_public": is_public, - "is_text": False, - "data": None - }) - return files - - -def convert(dirpath: str, set_public: bool, public_files: list): - dirpath = dirpath.rstrip("/\\") - files = sorted(get_files(dirpath, public_files), key=lambda file: file["filepath"]) - if len(files) > MOD_FS_MAX_FILES: - raise Exception(f"Max number of files exceeded: {len(files)} (max is: {MOD_FS_MAX_FILES})") - - total_size = 0 - for file in files: - filepath = file["filepath"] - if len(filepath) >= MOD_FS_MAX_PATH: - raise Exception(f"{filepath} - Exceeded filepath length: {len(filepath)} (max is: {MOD_FS_MAX_PATH-1})") - - with open(file["relpath"], "rb") as f: - data = f.read() - total_size += len(data) - if total_size > MOD_FS_MAX_SIZE: - raise Exception(f"{filepath} - Total size exceeded: {total_size} (max is: {MOD_FS_MAX_SIZE})") - - file["data"] = data - file["is_text"] = not is_binary_file(data) - - # write file - destpath = dirpath + MOD_FS_EXTENSION - with open(destpath, "wb") as f: - - # magic + version - f.write(MOD_FS_MAGIC.encode()) - f.write(MOD_FS_VERSION.to_bytes(1, byteorder="little", signed=False)) - - # header - f.write(len(files).to_bytes(2, byteorder="little", signed=False)) - f.write(set_public.to_bytes(1, byteorder="little", signed=False)) - - # padding (empty space for future versions) - padding = MOD_FS_HEADER_SIZE - f.tell() - f.write(b'\0' * padding) - - # files - for file in files: - - # filepath - f.write(len(file["filepath"]).to_bytes(2, byteorder="little", signed=False)) - f.write(file["filepath"].encode()) - - # data - f.write(len(file["data"]).to_bytes(4, byteorder="little", signed=False)) - f.write(file["is_public"].to_bytes(1, byteorder="little", signed=False)) - f.write(file["is_text"].to_bytes(1, byteorder="little", signed=False)) - f.write(file["data"]) - - # summary - print("") - print(f"Directory: {dirpath}") - print(f"Num files: {len(files)}") - print(f"Total size: {total_size}") - print(f"Is public: {set_public}") - - filepaths_max = max(8, len(max([file["filepath"] for file in files], key=len))) - sizes_max = max(4, len(max([str(len(file["data"])) for file in files], key=len))) - print("") - print(f"{'FILEPATH'.ljust(filepaths_max)} {'SIZE'.rjust(sizes_max)} {'TEXT'.rjust(5)} {'PUBLIC'.rjust(6)}") - print(f"{'--------'.ljust(filepaths_max)} {'----'.rjust(sizes_max)} {'----'.rjust(5)} {'------'.rjust(6)}") - for file in files: - filepath = file["filepath"] - size = str(len(file["data"])) - is_text = str(file["is_text"]) - is_public = str(file["is_public"]) - print(f"{filepath.ljust(filepaths_max)} {size.rjust(sizes_max)} {is_text.rjust(5)} {is_public.rjust(6)}") - - -def extract(filepath: str): - if not filepath.endswith(MOD_FS_EXTENSION): - raise Exception("Not a modfs file") - - with open(filepath, "rb") as f: - - # magic + version - magic = f.read(len(MOD_FS_MAGIC)).decode() - if magic != MOD_FS_MAGIC: - raise Exception("Not a modfs file") - version = int.from_bytes(f.read(1), byteorder="little", signed=False) - if version != MOD_FS_VERSION: - raise Exception("Version mismatch") - - # header - num_files = int.from_bytes(f.read(2), byteorder="little", signed=False) - is_public = bool.from_bytes(f.read(1), byteorder="little", signed=False) - - # padding (empty space for future versions) - f.seek(MOD_FS_HEADER_SIZE, 0) - - # create directory - dirpath = filepath.removesuffix(MOD_FS_EXTENSION) - os.makedirs(dirpath, exist_ok=True) - - # files - for _ in range(num_files): - - # filepath - filepath_len = int.from_bytes(f.read(2), byteorder="little", signed=False) - filepath = os.path.join(dirpath, f.read(filepath_len).decode()) - - # data - file_size = int.from_bytes(f.read(4), byteorder="little", signed=False) - file_is_public = bool.from_bytes(f.read(1), byteorder="little", signed=False) - file_is_text = bool.from_bytes(f.read(1), byteorder="little", signed=False) - file_data = f.read(file_size) - - # write file - os.makedirs(os.path.dirname(filepath), exist_ok=True) - with open(filepath, "wb") as g: - g.write(file_data) - print(f"Extracted file of size {file_size} to: {filepath}") - - -def main(argc: int, argv: list): - if argc < 2: - usage() - - if "--extract" in argv: - extract(argv[1]) - else: - set_public = "--set-public" in argv - set_file_public_index = argv.index("--set-file-public") if "--set-file-public" in argv else argc - convert(argv[1], set_public, argv[set_file_public_index+1:]) - - -if __name__ == "__main__": - main(len(sys.argv), sys.argv) diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 744db5da8..5c834b889 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -1335,6 +1335,7 @@ - GRAPH_RENDER_CYLBOARD - GRAPH_RENDER_PLAYER - GRAPH_EXTRA_FORCE_3D +- GRAPH_EXTRA_ROTATE_HELD - GRAPH_NODE_TYPE_FUNCTIONAL - GRAPH_NODE_TYPE_400 - GRAPH_NODE_TYPE_ROOT @@ -2143,6 +2144,8 @@ - MOD_FS_MAX_SIZE - MOD_FS_MAX_FILES - MOD_FS_MAX_PATH +- MOD_FS_URI_PREFIX +- MOD_FS_URI_FORMAT ### [enum ModFsFileIntType](#ModFsFileIntType) | Identifier | Value | @@ -2969,6 +2972,7 @@
## [player_palette.h](#player_palette.h) +- PALETTES_DIRECTORY - MAX_PRESET_PALETTES ### [enum PlayerPart](#PlayerPart) @@ -4619,6 +4623,7 @@ - SURFACE_CLASS_NOT_SLIPPERY - SURFACE_FLAG_DYNAMIC - SURFACE_FLAG_NO_CAM_COLLISION +- SURFACE_FLAG_INTANGIBLE - SURFACE_FLAG_X_PROJECTION - HAZARD_TYPE_LAVA_FLOOR - HAZARD_TYPE_LAVA_WALL @@ -4720,6 +4725,12 @@ - VERSION_TEXT - VERSION_NUMBER - MINOR_VERSION_NUMBER +- GAME_NAME +- WINDOW_NAME +- GAME_NAME +- WINDOW_NAME +- GAME_NAME +- WINDOW_NAME - MAX_VERSION_LENGTH [:arrow_up_small:](#) diff --git a/docs/lua/examples/gfx-vtx-demo/actors/shape/model.inc.c b/docs/lua/examples/gfx-vtx-demo/actors/shape/model.inc.c index e29ce377a..46f01d338 100644 --- a/docs/lua/examples/gfx-vtx-demo/actors/shape/model.inc.c +++ b/docs/lua/examples/gfx-vtx-demo/actors/shape/model.inc.c @@ -15,5 +15,6 @@ Gfx shape_template_dl[] = { /* [11] */ gsSPDisplayList(NULL), /* [12] */ gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF), /* [13] */ gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), -/* [14] */ gsSPEndDisplayList(), +/* [14] */ gsSPLoadGeometryMode(G_LIGHTING | G_CULL_BACK), +/* [15] */ gsSPEndDisplayList(), }; diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md index 53f109eba..a3ff14601 100644 --- a/docs/lua/functions-5.md +++ b/docs/lua/functions-5.md @@ -342,71 +342,6 @@ Creates a modfs object for the active mod if it doesn't exist. Returns the modfs
-## [mod_fs_delete](#mod_fs_delete) - -### Description -Deletes the modfs object of the active mod if it exists. Returns true on success - -### Lua Example -`local booleanValue = mod_fs_delete()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool mod_fs_delete();` - -[:arrow_up_small:](#) - -
- -## [mod_fs_save](#mod_fs_save) - -### Description -Saves the modfs object of the active mod if it exists. Returns true on success - -### Lua Example -`local booleanValue = mod_fs_save()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool mod_fs_save();` - -[:arrow_up_small:](#) - -
- -## [mod_fs_set_public](#mod_fs_set_public) - -### Description -Marks the modfs object of the active mod as public (i.e. readable by other mods) if it exists. Returns true on success - -### Lua Example -`local booleanValue = mod_fs_set_public(pub)` - -### Parameters -| Field | Type | -| ----- | ---- | -| pub | `boolean` | - -### Returns -- `boolean` - -### C Prototype -`bool mod_fs_set_public(bool pub);` - -[:arrow_up_small:](#) - -
- ## [mod_fs_get_filename](#mod_fs_get_filename) ### Description @@ -579,6 +514,76 @@ Deletes all files of the provided `modFs`. Returns true on success
+## [mod_fs_save](#mod_fs_save) + +### Description +Saves the provided `modFs` to persistent storage. Returns true on success + +### Lua Example +`local booleanValue = mod_fs_save(modFs)` + +### Parameters +| Field | Type | +| ----- | ---- | +| modFs | [ModFs](structs.md#ModFs) | + +### Returns +- `boolean` + +### C Prototype +`bool mod_fs_save(struct ModFs *modFs);` + +[:arrow_up_small:](#) + +
+ +## [mod_fs_delete](#mod_fs_delete) + +### Description +Removes the provided `modFs` from persistent storage and deletes its object. Returns true on success + +### Lua Example +`local booleanValue = mod_fs_delete(modFs)` + +### Parameters +| Field | Type | +| ----- | ---- | +| modFs | [ModFs](structs.md#ModFs) | + +### Returns +- `boolean` + +### C Prototype +`bool mod_fs_delete(struct ModFs *modFs);` + +[:arrow_up_small:](#) + +
+ +## [mod_fs_set_public](#mod_fs_set_public) + +### Description +Marks the provided `modFs` as public (i.e. readable by other mods). Returns true on success + +### Lua Example +`local booleanValue = mod_fs_set_public(modFs, pub)` + +### Parameters +| Field | Type | +| ----- | ---- | +| modFs | [ModFs](structs.md#ModFs) | +| pub | `boolean` | + +### Returns +- `boolean` + +### C Prototype +`bool mod_fs_set_public(struct ModFs *modFs, bool pub);` + +[:arrow_up_small:](#) + +
+ ## [mod_fs_file_read_bool](#mod_fs_file_read_bool) ### Description @@ -891,6 +896,29 @@ Sets the current position of a modfs `file`. If `origin` is `FILE_SEEK_SET`, fil
+## [mod_fs_file_rewind](#mod_fs_file_rewind) + +### Description +Sets the current position of a modfs `file` to its beginning. Returns true on success + +### Lua Example +`local booleanValue = mod_fs_file_rewind(file)` + +### Parameters +| Field | Type | +| ----- | ---- | +| file | [ModFsFile](structs.md#ModFsFile) | + +### Returns +- `boolean` + +### C Prototype +`bool mod_fs_file_rewind(struct ModFsFile *file);` + +[:arrow_up_small:](#) + +
+ ## [mod_fs_file_is_eof](#mod_fs_file_is_eof) ### Description @@ -963,6 +991,30 @@ Erases `length` bytes or characters from a modfs `file`. Returns true on success
+## [mod_fs_file_set_text_mode](#mod_fs_file_set_text_mode) + +### Description +Marks the provided modfs `file` as text. Returns true on success + +### Lua Example +`local booleanValue = mod_fs_file_set_text_mode(file, text)` + +### Parameters +| Field | Type | +| ----- | ---- | +| file | [ModFsFile](structs.md#ModFsFile) | +| text | `boolean` | + +### Returns +- `boolean` + +### C Prototype +`bool mod_fs_file_set_text_mode(struct ModFsFile *file, bool text);` + +[:arrow_up_small:](#) + +
+ ## [mod_fs_file_set_public](#mod_fs_file_set_public) ### Description @@ -1178,6 +1230,27 @@ Loads a bool `value` from a `key` in mod storage
+## [mod_storage_load_all](#mod_storage_load_all) + +### Description +Loads all keys and values in mod storage as strings and returns them as a table + +### Lua Example +`local tableValue = mod_storage_load_all()` + +### Parameters +- None + +### Returns +- `table` + +### C Prototype +`LuaTable mod_storage_load_all(void);` + +[:arrow_up_small:](#) + +
+ ## [mod_storage_exists](#mod_storage_exists) ### Description @@ -3625,4584 +3698,6 @@ Moves the current object for specifically one second (`oTimer` < 30) [:arrow_up_small:](#) -
- ---- -# functions from object_helpers.c - -
- - -## [clear_move_flag](#clear_move_flag) - -### Lua Example -`local integerValue = clear_move_flag(bitSet, flag)` - -### Parameters -| Field | Type | -| ----- | ---- | -| bitSet | `Pointer` <`integer`> | -| flag | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 clear_move_flag(u32 *bitSet, s32 flag);` - -[:arrow_up_small:](#) - -
- -## [set_room_override](#set_room_override) - -### Description -Overrides the current room Mario is in. Set to -1 to reset override - -### Lua Example -`set_room_override(room)` - -### Parameters -| Field | Type | -| ----- | ---- | -| room | `integer` | - -### Returns -- None - -### C Prototype -`void set_room_override(s16 room);` - -[:arrow_up_small:](#) - -
- -## [obj_update_pos_from_parent_transformation](#obj_update_pos_from_parent_transformation) - -### Lua Example -`obj_update_pos_from_parent_transformation(a0, a1)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a0 | [Mat4](structs.md#Mat4) | -| a1 | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_update_pos_from_parent_transformation(Mat4 a0, struct Object *a1);` - -[:arrow_up_small:](#) - -
- -## [obj_apply_scale_to_matrix](#obj_apply_scale_to_matrix) - -### Lua Example -`obj_apply_scale_to_matrix(obj, dst, src)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| dst | [Mat4](structs.md#Mat4) | -| src | [Mat4](structs.md#Mat4) | - -### Returns -- None - -### C Prototype -`void obj_apply_scale_to_matrix(struct Object *obj, OUT Mat4 dst, Mat4 src);` - -[:arrow_up_small:](#) - -
- -## [create_transformation_from_matrices](#create_transformation_from_matrices) - -### Lua Example -`create_transformation_from_matrices(a0, a1, a2)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a0 | [Mat4](structs.md#Mat4) | -| a1 | [Mat4](structs.md#Mat4) | -| a2 | [Mat4](structs.md#Mat4) | - -### Returns -- None - -### C Prototype -`void create_transformation_from_matrices(OUT Mat4 a0, Mat4 a1, Mat4 a2);` - -[:arrow_up_small:](#) - -
- -## [obj_set_held_state](#obj_set_held_state) - -### Lua Example -`obj_set_held_state(obj, heldBehavior)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| heldBehavior | `Pointer` <`BehaviorScript`> | - -### Returns -- None - -### C Prototype -`void obj_set_held_state(struct Object *obj, const BehaviorScript *heldBehavior);` - -[:arrow_up_small:](#) - -
- -## [lateral_dist_between_objects](#lateral_dist_between_objects) - -### Lua Example -`local numberValue = lateral_dist_between_objects(obj1, obj2)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj1 | [Object](structs.md#Object) | -| obj2 | [Object](structs.md#Object) | - -### Returns -- `number` - -### C Prototype -`f32 lateral_dist_between_objects(struct Object *obj1, struct Object *obj2);` - -[:arrow_up_small:](#) - -
- -## [dist_between_objects](#dist_between_objects) - -### Lua Example -`local numberValue = dist_between_objects(obj1, obj2)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj1 | [Object](structs.md#Object) | -| obj2 | [Object](structs.md#Object) | - -### Returns -- `number` - -### C Prototype -`f32 dist_between_objects(struct Object *obj1, struct Object *obj2);` - -[:arrow_up_small:](#) - -
- -## [dist_between_object_and_point](#dist_between_object_and_point) - -### Lua Example -`local numberValue = dist_between_object_and_point(obj, pointX, pointY, pointZ)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| pointX | `number` | -| pointY | `number` | -| pointZ | `number` | - -### Returns -- `number` - -### C Prototype -`f32 dist_between_object_and_point(struct Object *obj, f32 pointX, f32 pointY, f32 pointZ);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_forward_vel_approach_upward](#cur_obj_forward_vel_approach_upward) - -### Lua Example -`cur_obj_forward_vel_approach_upward(target, increment)` - -### Parameters -| Field | Type | -| ----- | ---- | -| target | `number` | -| increment | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_forward_vel_approach_upward(f32 target, f32 increment);` - -[:arrow_up_small:](#) - -
- -## [approach_f32_signed](#approach_f32_signed) - -### Lua Example -`local integerValue = approach_f32_signed(value, target, increment)` - -### Parameters -| Field | Type | -| ----- | ---- | -| value | `Pointer` <`number`> | -| target | `number` | -| increment | `number` | - -### Returns -- `integer` - -### C Prototype -`s32 approach_f32_signed(f32 *value, f32 target, f32 increment);` - -[:arrow_up_small:](#) - -
- -## [approach_f32_symmetric](#approach_f32_symmetric) - -### Lua Example -`local numberValue = approach_f32_symmetric(value, target, increment)` - -### Parameters -| Field | Type | -| ----- | ---- | -| value | `number` | -| target | `number` | -| increment | `number` | - -### Returns -- `number` - -### C Prototype -`f32 approach_f32_symmetric(f32 value, f32 target, f32 increment);` - -[:arrow_up_small:](#) - -
- -## [approach_s16_symmetric](#approach_s16_symmetric) - -### Lua Example -`local integerValue = approach_s16_symmetric(value, target, increment)` - -### Parameters -| Field | Type | -| ----- | ---- | -| value | `integer` | -| target | `integer` | -| increment | `integer` | - -### Returns -- `integer` - -### C Prototype -`s16 approach_s16_symmetric(s16 value, s16 target, s16 increment);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_rotate_yaw_toward](#cur_obj_rotate_yaw_toward) - -### Lua Example -`local integerValue = cur_obj_rotate_yaw_toward(target, increment)` - -### Parameters -| Field | Type | -| ----- | ---- | -| target | `integer` | -| increment | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_rotate_yaw_toward(s16 target, s16 increment);` - -[:arrow_up_small:](#) - -
- -## [obj_angle_to_object](#obj_angle_to_object) - -### Lua Example -`local integerValue = obj_angle_to_object(obj1, obj2)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj1 | [Object](structs.md#Object) | -| obj2 | [Object](structs.md#Object) | - -### Returns -- `integer` - -### C Prototype -`s16 obj_angle_to_object(struct Object *obj1, struct Object *obj2);` - -[:arrow_up_small:](#) - -
- -## [obj_pitch_to_object](#obj_pitch_to_object) - -### Lua Example -`local integerValue = obj_pitch_to_object(obj, target)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| target | [Object](structs.md#Object) | - -### Returns -- `integer` - -### C Prototype -`s16 obj_pitch_to_object(struct Object* obj, struct Object* target);` - -[:arrow_up_small:](#) - -
- -## [obj_angle_to_point](#obj_angle_to_point) - -### Lua Example -`local integerValue = obj_angle_to_point(obj, pointX, pointZ)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| pointX | `number` | -| pointZ | `number` | - -### Returns -- `integer` - -### C Prototype -`s16 obj_angle_to_point(struct Object *obj, f32 pointX, f32 pointZ);` - -[:arrow_up_small:](#) - -
- -## [obj_turn_toward_object](#obj_turn_toward_object) - -### Lua Example -`local integerValue = obj_turn_toward_object(obj, target, angleIndex, turnAmount)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| target | [Object](structs.md#Object) | -| angleIndex | `integer` | -| turnAmount | `integer` | - -### Returns -- `integer` - -### C Prototype -`s16 obj_turn_toward_object(struct Object *obj, struct Object *target, s16 angleIndex, s16 turnAmount);` - -[:arrow_up_small:](#) - -
- -## [obj_set_parent_relative_pos](#obj_set_parent_relative_pos) - -### Lua Example -`obj_set_parent_relative_pos(obj, relX, relY, relZ)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| relX | `integer` | -| relY | `integer` | -| relZ | `integer` | - -### Returns -- None - -### C Prototype -`void obj_set_parent_relative_pos(struct Object *obj, s16 relX, s16 relY, s16 relZ);` - -[:arrow_up_small:](#) - -
- -## [obj_set_pos](#obj_set_pos) - -### Lua Example -`obj_set_pos(obj, x, y, z)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| x | `integer` | -| y | `integer` | -| z | `integer` | - -### Returns -- None - -### C Prototype -`void obj_set_pos(struct Object *obj, s16 x, s16 y, s16 z);` - -[:arrow_up_small:](#) - -
- -## [obj_set_angle](#obj_set_angle) - -### Lua Example -`obj_set_angle(obj, pitch, yaw, roll)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| pitch | `integer` | -| yaw | `integer` | -| roll | `integer` | - -### Returns -- None - -### C Prototype -`void obj_set_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);` - -[:arrow_up_small:](#) - -
- -## [obj_set_move_angle](#obj_set_move_angle) - -### Lua Example -`obj_set_move_angle(obj, pitch, yaw, roll)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| pitch | `integer` | -| yaw | `integer` | -| roll | `integer` | - -### Returns -- None - -### C Prototype -`void obj_set_move_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);` - -[:arrow_up_small:](#) - -
- -## [obj_set_face_angle](#obj_set_face_angle) - -### Lua Example -`obj_set_face_angle(obj, pitch, yaw, roll)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| pitch | `integer` | -| yaw | `integer` | -| roll | `integer` | - -### Returns -- None - -### C Prototype -`void obj_set_face_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);` - -[:arrow_up_small:](#) - -
- -## [obj_set_gfx_angle](#obj_set_gfx_angle) - -### Lua Example -`obj_set_gfx_angle(obj, pitch, yaw, roll)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| pitch | `integer` | -| yaw | `integer` | -| roll | `integer` | - -### Returns -- None - -### C Prototype -`void obj_set_gfx_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);` - -[:arrow_up_small:](#) - -
- -## [obj_set_gfx_pos](#obj_set_gfx_pos) - -### Lua Example -`obj_set_gfx_pos(obj, x, y, z)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| x | `number` | -| y | `number` | -| z | `number` | - -### Returns -- None - -### C Prototype -`void obj_set_gfx_pos(struct Object *obj, f32 x, f32 y, f32 z);` - -[:arrow_up_small:](#) - -
- -## [obj_set_gfx_scale](#obj_set_gfx_scale) - -### Lua Example -`obj_set_gfx_scale(obj, x, y, z)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| x | `number` | -| y | `number` | -| z | `number` | - -### Returns -- None - -### C Prototype -`void obj_set_gfx_scale(struct Object *obj, f32 x, f32 y, f32 z);` - -[:arrow_up_small:](#) - -
- -## [spawn_water_droplet](#spawn_water_droplet) - -### Lua Example -`local ObjectValue = spawn_water_droplet(parent, params)` - -### Parameters -| Field | Type | -| ----- | ---- | -| parent | [Object](structs.md#Object) | -| params | [WaterDropletParams](structs.md#WaterDropletParams) | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *spawn_water_droplet(struct Object *parent, struct WaterDropletParams *params);` - -[:arrow_up_small:](#) - -
- -## [obj_build_relative_transform](#obj_build_relative_transform) - -### Lua Example -`obj_build_relative_transform(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_build_relative_transform(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_using_vel](#cur_obj_move_using_vel) - -### Lua Example -`cur_obj_move_using_vel()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_move_using_vel(void);` - -[:arrow_up_small:](#) - -
- -## [obj_copy_graph_y_offset](#obj_copy_graph_y_offset) - -### Lua Example -`obj_copy_graph_y_offset(dst, src)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dst | [Object](structs.md#Object) | -| src | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_copy_graph_y_offset(struct Object *dst, struct Object *src);` - -[:arrow_up_small:](#) - -
- -## [obj_copy_pos_and_angle](#obj_copy_pos_and_angle) - -### Lua Example -`obj_copy_pos_and_angle(dst, src)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dst | [Object](structs.md#Object) | -| src | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_copy_pos_and_angle(struct Object *dst, struct Object *src);` - -[:arrow_up_small:](#) - -
- -## [obj_copy_pos](#obj_copy_pos) - -### Lua Example -`obj_copy_pos(dst, src)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dst | [Object](structs.md#Object) | -| src | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_copy_pos(struct Object *dst, struct Object *src);` - -[:arrow_up_small:](#) - -
- -## [obj_copy_angle](#obj_copy_angle) - -### Lua Example -`obj_copy_angle(dst, src)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dst | [Object](structs.md#Object) | -| src | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_copy_angle(struct Object *dst, struct Object *src);` - -[:arrow_up_small:](#) - -
- -## [obj_set_gfx_pos_from_pos](#obj_set_gfx_pos_from_pos) - -### Lua Example -`obj_set_gfx_pos_from_pos(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_set_gfx_pos_from_pos(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [obj_init_animation](#obj_init_animation) - -### Lua Example -`obj_init_animation(obj, animIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| animIndex | `integer` | - -### Returns -- None - -### C Prototype -`void obj_init_animation(struct Object *obj, s32 animIndex);` - -[:arrow_up_small:](#) - -
- -## [linear_mtxf_mul_vec3f](#linear_mtxf_mul_vec3f) - -### Description -Multiplies a vector by a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ? ? 0 |` `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space - -### Lua Example -`linear_mtxf_mul_vec3f(m, dst, v)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [Mat4](structs.md#Mat4) | -| dst | [Vec3f](structs.md#Vec3f) | -| v | [Vec3f](structs.md#Vec3f) | - -### Returns -- None - -### C Prototype -`void linear_mtxf_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v);` - -[:arrow_up_small:](#) - -
- -## [linear_mtxf_transpose_mul_vec3f](#linear_mtxf_transpose_mul_vec3f) - -### Description -Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ? ? 0 |` `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space - -### Lua Example -`linear_mtxf_transpose_mul_vec3f(m, dst, v)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [Mat4](structs.md#Mat4) | -| dst | [Vec3f](structs.md#Vec3f) | -| v | [Vec3f](structs.md#Vec3f) | - -### Returns -- None - -### C Prototype -`void linear_mtxf_transpose_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v);` - -[:arrow_up_small:](#) - -
- -## [obj_apply_scale_to_transform](#obj_apply_scale_to_transform) - -### Lua Example -`obj_apply_scale_to_transform(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_apply_scale_to_transform(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [obj_copy_scale](#obj_copy_scale) - -### Lua Example -`obj_copy_scale(dst, src)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dst | [Object](structs.md#Object) | -| src | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_copy_scale(struct Object *dst, struct Object *src);` - -[:arrow_up_small:](#) - -
- -## [obj_scale_xyz](#obj_scale_xyz) - -### Lua Example -`obj_scale_xyz(obj, xScale, yScale, zScale)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| xScale | `number` | -| yScale | `number` | -| zScale | `number` | - -### Returns -- None - -### C Prototype -`void obj_scale_xyz(struct Object *obj, f32 xScale, f32 yScale, f32 zScale);` - -[:arrow_up_small:](#) - -
- -## [obj_scale](#obj_scale) - -### Lua Example -`obj_scale(obj, scale)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| scale | `number` | - -### Returns -- None - -### C Prototype -`void obj_scale(struct Object *obj, f32 scale);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_scale](#cur_obj_scale) - -### Lua Example -`cur_obj_scale(scale)` - -### Parameters -| Field | Type | -| ----- | ---- | -| scale | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_scale(f32 scale);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_init_animation](#cur_obj_init_animation) - -### Lua Example -`cur_obj_init_animation(animIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| animIndex | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_init_animation(s32 animIndex);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_init_animation_with_sound](#cur_obj_init_animation_with_sound) - -### Lua Example -`cur_obj_init_animation_with_sound(animIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| animIndex | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_init_animation_with_sound(s32 animIndex);` - -[:arrow_up_small:](#) - -
- -## [obj_init_animation_with_accel_and_sound](#obj_init_animation_with_accel_and_sound) - -### Lua Example -`obj_init_animation_with_accel_and_sound(obj, animIndex, accel)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| animIndex | `integer` | -| accel | `number` | - -### Returns -- None - -### C Prototype -`void obj_init_animation_with_accel_and_sound(struct Object *obj, s32 animIndex, f32 accel);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_init_animation_with_accel_and_sound](#cur_obj_init_animation_with_accel_and_sound) - -### Lua Example -`cur_obj_init_animation_with_accel_and_sound(animIndex, accel)` - -### Parameters -| Field | Type | -| ----- | ---- | -| animIndex | `integer` | -| accel | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_init_animation_with_accel_and_sound(s32 animIndex, f32 accel);` - -[:arrow_up_small:](#) - -
- -## [obj_init_animation_with_sound](#obj_init_animation_with_sound) - -### Lua Example -`obj_init_animation_with_sound(obj, animations, animIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| animations | [AnimationTable](structs.md#AnimationTable) | -| animIndex | `integer` | - -### Returns -- None - -### C Prototype -`void obj_init_animation_with_sound(struct Object *obj, const struct AnimationTable* animations, s32 animIndex);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_enable_rendering_and_become_tangible](#cur_obj_enable_rendering_and_become_tangible) - -### Lua Example -`cur_obj_enable_rendering_and_become_tangible(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void cur_obj_enable_rendering_and_become_tangible(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_enable_rendering](#cur_obj_enable_rendering) - -### Lua Example -`cur_obj_enable_rendering()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_enable_rendering(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_disable_rendering_and_become_intangible](#cur_obj_disable_rendering_and_become_intangible) - -### Lua Example -`cur_obj_disable_rendering_and_become_intangible(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void cur_obj_disable_rendering_and_become_intangible(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_disable_rendering](#cur_obj_disable_rendering) - -### Lua Example -`cur_obj_disable_rendering()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_disable_rendering(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_unhide](#cur_obj_unhide) - -### Lua Example -`cur_obj_unhide()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_unhide(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_hide](#cur_obj_hide) - -### Lua Example -`cur_obj_hide()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_hide(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_pos_relative](#cur_obj_set_pos_relative) - -### Lua Example -`cur_obj_set_pos_relative(other, dleft, dy, dforward)` - -### Parameters -| Field | Type | -| ----- | ---- | -| other | [Object](structs.md#Object) | -| dleft | `number` | -| dy | `number` | -| dforward | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_set_pos_relative(struct Object *other, f32 dleft, f32 dy, f32 dforward);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_pos_relative_to_parent](#cur_obj_set_pos_relative_to_parent) - -### Lua Example -`cur_obj_set_pos_relative_to_parent(dleft, dy, dforward)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dleft | `number` | -| dy | `number` | -| dforward | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_set_pos_relative_to_parent(f32 dleft, f32 dy, f32 dforward);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_enable_rendering_2](#cur_obj_enable_rendering_2) - -### Lua Example -`cur_obj_enable_rendering_2()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_enable_rendering_2(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_unused_init_on_floor](#cur_obj_unused_init_on_floor) - -### Lua Example -`cur_obj_unused_init_on_floor()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_unused_init_on_floor(void);` - -[:arrow_up_small:](#) - -
- -## [obj_set_face_angle_to_move_angle](#obj_set_face_angle_to_move_angle) - -### Lua Example -`obj_set_face_angle_to_move_angle(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_set_face_angle_to_move_angle(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [get_object_list_from_behavior](#get_object_list_from_behavior) - -### Lua Example -`local integerValue = get_object_list_from_behavior(behavior)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behavior | `Pointer` <`BehaviorScript`> | - -### Returns -- `integer` - -### C Prototype -`u32 get_object_list_from_behavior(const BehaviorScript *behavior);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_nearest_object_with_behavior](#cur_obj_nearest_object_with_behavior) - -### Lua Example -`local ObjectValue = cur_obj_nearest_object_with_behavior(behavior)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behavior | `Pointer` <`BehaviorScript`> | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *cur_obj_nearest_object_with_behavior(const BehaviorScript *behavior);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_dist_to_nearest_object_with_behavior](#cur_obj_dist_to_nearest_object_with_behavior) - -### Lua Example -`local numberValue = cur_obj_dist_to_nearest_object_with_behavior(behavior)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behavior | `Pointer` <`BehaviorScript`> | - -### Returns -- `number` - -### C Prototype -`f32 cur_obj_dist_to_nearest_object_with_behavior(const BehaviorScript *behavior);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_find_nearest_pole](#cur_obj_find_nearest_pole) - -### Lua Example -`local ObjectValue = cur_obj_find_nearest_pole()` - -### Parameters -- None - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object* cur_obj_find_nearest_pole(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_find_nearest_object_with_behavior](#cur_obj_find_nearest_object_with_behavior) - -### Lua Example -`local ObjectValue = cur_obj_find_nearest_object_with_behavior(behavior, dist)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behavior | `Pointer` <`BehaviorScript`> | -| dist | `Pointer` <`number`> | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, f32 *dist);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_count_objects_with_behavior](#cur_obj_count_objects_with_behavior) - -### Lua Example -`local integerValue = cur_obj_count_objects_with_behavior(behavior, dist)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behavior | `Pointer` <`BehaviorScript`> | -| dist | `number` | - -### Returns -- `integer` - -### C Prototype -`u16 cur_obj_count_objects_with_behavior(const BehaviorScript* behavior, f32 dist);` - -[:arrow_up_small:](#) - -
- -## [find_unimportant_object](#find_unimportant_object) - -### Lua Example -`local ObjectValue = find_unimportant_object()` - -### Parameters -- None - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *find_unimportant_object(void);` - -[:arrow_up_small:](#) - -
- -## [count_unimportant_objects](#count_unimportant_objects) - -### Lua Example -`local integerValue = count_unimportant_objects()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 count_unimportant_objects(void);` - -[:arrow_up_small:](#) - -
- -## [count_objects_with_behavior](#count_objects_with_behavior) - -### Lua Example -`local integerValue = count_objects_with_behavior(behavior)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behavior | `Pointer` <`BehaviorScript`> | - -### Returns -- `integer` - -### C Prototype -`s32 count_objects_with_behavior(const BehaviorScript *behavior);` - -[:arrow_up_small:](#) - -
- -## [find_object_with_behavior](#find_object_with_behavior) - -### Lua Example -`local ObjectValue = find_object_with_behavior(behavior)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behavior | `Pointer` <`BehaviorScript`> | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *find_object_with_behavior(const BehaviorScript *behavior);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_find_nearby_held_actor](#cur_obj_find_nearby_held_actor) - -### Lua Example -`local ObjectValue = cur_obj_find_nearby_held_actor(behavior, maxDist)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behavior | `Pointer` <`BehaviorScript`> | -| maxDist | `number` | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *cur_obj_find_nearby_held_actor(const BehaviorScript *behavior, f32 maxDist);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_reset_timer_and_subaction](#cur_obj_reset_timer_and_subaction) - -### Lua Example -`cur_obj_reset_timer_and_subaction()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_reset_timer_and_subaction(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_change_action](#cur_obj_change_action) - -### Lua Example -`cur_obj_change_action(action)` - -### Parameters -| Field | Type | -| ----- | ---- | -| action | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_change_action(s32 action);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_vel_from_mario_vel](#cur_obj_set_vel_from_mario_vel) - -### Lua Example -`cur_obj_set_vel_from_mario_vel(m, f12, f14)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | -| f12 | `number` | -| f14 | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_set_vel_from_mario_vel(struct MarioState* m, f32 f12, f32 f14);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_reverse_animation](#cur_obj_reverse_animation) - -### Lua Example -`cur_obj_reverse_animation()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_reverse_animation(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_extend_animation_if_at_end](#cur_obj_extend_animation_if_at_end) - -### Lua Example -`cur_obj_extend_animation_if_at_end()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_extend_animation_if_at_end(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_check_if_near_animation_end](#cur_obj_check_if_near_animation_end) - -### Lua Example -`local integerValue = cur_obj_check_if_near_animation_end()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_check_if_near_animation_end(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_check_if_at_animation_end](#cur_obj_check_if_at_animation_end) - -### Lua Example -`local integerValue = cur_obj_check_if_at_animation_end()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_check_if_at_animation_end(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_check_anim_frame](#cur_obj_check_anim_frame) - -### Lua Example -`local integerValue = cur_obj_check_anim_frame(frame)` - -### Parameters -| Field | Type | -| ----- | ---- | -| frame | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_check_anim_frame(s32 frame);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_check_anim_frame_in_range](#cur_obj_check_anim_frame_in_range) - -### Lua Example -`local integerValue = cur_obj_check_anim_frame_in_range(startFrame, rangeLength)` - -### Parameters -| Field | Type | -| ----- | ---- | -| startFrame | `integer` | -| rangeLength | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_check_anim_frame_in_range(s32 startFrame, s32 rangeLength);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_check_frame_prior_current_frame](#cur_obj_check_frame_prior_current_frame) - -### Lua Example -`local integerValue = cur_obj_check_frame_prior_current_frame(a0)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a0 | `Pointer` <`integer`> | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_check_frame_prior_current_frame(s16 *a0);` - -[:arrow_up_small:](#) - -
- -## [mario_is_in_air_action](#mario_is_in_air_action) - -### Lua Example -`local integerValue = mario_is_in_air_action(m)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | - -### Returns -- `integer` - -### C Prototype -`s32 mario_is_in_air_action(struct MarioState* m);` - -[:arrow_up_small:](#) - -
- -## [mario_is_dive_sliding](#mario_is_dive_sliding) - -### Lua Example -`local integerValue = mario_is_dive_sliding(m)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | - -### Returns -- `integer` - -### C Prototype -`s32 mario_is_dive_sliding(struct MarioState* m);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_y_vel_and_animation](#cur_obj_set_y_vel_and_animation) - -### Lua Example -`cur_obj_set_y_vel_and_animation(sp18, sp1C)` - -### Parameters -| Field | Type | -| ----- | ---- | -| sp18 | `number` | -| sp1C | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_set_y_vel_and_animation(f32 sp18, s32 sp1C);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_unrender_and_reset_state](#cur_obj_unrender_and_reset_state) - -### Lua Example -`cur_obj_unrender_and_reset_state(sp18, sp1C)` - -### Parameters -| Field | Type | -| ----- | ---- | -| sp18 | `integer` | -| sp1C | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_unrender_and_reset_state(s32 sp18, s32 sp1C);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_after_thrown_or_dropped](#cur_obj_move_after_thrown_or_dropped) - -### Lua Example -`cur_obj_move_after_thrown_or_dropped(forwardVel, velY)` - -### Parameters -| Field | Type | -| ----- | ---- | -| forwardVel | `number` | -| velY | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_move_after_thrown_or_dropped(f32 forwardVel, f32 velY);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_get_thrown_or_placed](#cur_obj_get_thrown_or_placed) - -### Lua Example -`cur_obj_get_thrown_or_placed(forwardVel, velY, thrownAction)` - -### Parameters -| Field | Type | -| ----- | ---- | -| forwardVel | `number` | -| velY | `number` | -| thrownAction | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_get_thrown_or_placed(f32 forwardVel, f32 velY, s32 thrownAction);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_get_dropped](#cur_obj_get_dropped) - -### Lua Example -`cur_obj_get_dropped()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_get_dropped(void);` - -[:arrow_up_small:](#) - -
- -## [mario_set_flag](#mario_set_flag) - -### Lua Example -`mario_set_flag(flag)` - -### Parameters -| Field | Type | -| ----- | ---- | -| flag | `integer` | - -### Returns -- None - -### C Prototype -`void mario_set_flag(s32 flag);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_clear_interact_status_flag](#cur_obj_clear_interact_status_flag) - -### Lua Example -`local integerValue = cur_obj_clear_interact_status_flag(flag)` - -### Parameters -| Field | Type | -| ----- | ---- | -| flag | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_clear_interact_status_flag(s32 flag);` - -[:arrow_up_small:](#) - -
- -## [obj_mark_for_deletion](#obj_mark_for_deletion) - -### Description -Marks an object to be unloaded at the end of the frame - -### Lua Example -`obj_mark_for_deletion(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_mark_for_deletion(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_disable](#cur_obj_disable) - -### Lua Example -`cur_obj_disable()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_disable(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_become_intangible](#cur_obj_become_intangible) - -### Lua Example -`cur_obj_become_intangible()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_become_intangible(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_become_tangible](#cur_obj_become_tangible) - -### Lua Example -`cur_obj_become_tangible()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_become_tangible(void);` - -[:arrow_up_small:](#) - -
- -## [obj_become_tangible](#obj_become_tangible) - -### Lua Example -`obj_become_tangible(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_become_tangible(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_update_floor_height](#cur_obj_update_floor_height) - -### Lua Example -`cur_obj_update_floor_height()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_update_floor_height(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_update_floor_height_and_get_floor](#cur_obj_update_floor_height_and_get_floor) - -### Lua Example -`local SurfaceValue = cur_obj_update_floor_height_and_get_floor()` - -### Parameters -- None - -### Returns -[Surface](structs.md#Surface) - -### C Prototype -`struct Surface *cur_obj_update_floor_height_and_get_floor(void);` - -[:arrow_up_small:](#) - -
- -## [apply_drag_to_value](#apply_drag_to_value) - -### Lua Example -`apply_drag_to_value(value, dragStrength)` - -### Parameters -| Field | Type | -| ----- | ---- | -| value | `Pointer` <`number`> | -| dragStrength | `number` | - -### Returns -- None - -### C Prototype -`void apply_drag_to_value(f32 *value, f32 dragStrength);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_apply_drag_xz](#cur_obj_apply_drag_xz) - -### Lua Example -`cur_obj_apply_drag_xz(dragStrength)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dragStrength | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_apply_drag_xz(f32 dragStrength);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_xz](#cur_obj_move_xz) - -### Lua Example -`local integerValue = cur_obj_move_xz(steepSlopeNormalY, careAboutEdgesAndSteepSlopes)` - -### Parameters -| Field | Type | -| ----- | ---- | -| steepSlopeNormalY | `number` | -| careAboutEdgesAndSteepSlopes | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_move_xz(f32 steepSlopeNormalY, s32 careAboutEdgesAndSteepSlopes);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_update_underwater_flags](#cur_obj_move_update_underwater_flags) - -### Lua Example -`cur_obj_move_update_underwater_flags()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_move_update_underwater_flags(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_update_ground_air_flags](#cur_obj_move_update_ground_air_flags) - -### Lua Example -`cur_obj_move_update_ground_air_flags(gravity, bounciness)` - -### Parameters -| Field | Type | -| ----- | ---- | -| gravity | `number` | -| bounciness | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_move_update_ground_air_flags(UNUSED f32 gravity, f32 bounciness);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_y_and_get_water_level](#cur_obj_move_y_and_get_water_level) - -### Lua Example -`local numberValue = cur_obj_move_y_and_get_water_level(gravity, buoyancy)` - -### Parameters -| Field | Type | -| ----- | ---- | -| gravity | `number` | -| buoyancy | `number` | - -### Returns -- `number` - -### C Prototype -`f32 cur_obj_move_y_and_get_water_level(f32 gravity, f32 buoyancy);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_y](#cur_obj_move_y) - -### Lua Example -`cur_obj_move_y(gravity, bounciness, buoyancy)` - -### Parameters -| Field | Type | -| ----- | ---- | -| gravity | `number` | -| bounciness | `number` | -| buoyancy | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_move_y(f32 gravity, f32 bounciness, f32 buoyancy);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_unused_resolve_wall_collisions](#cur_obj_unused_resolve_wall_collisions) - -### Lua Example -`cur_obj_unused_resolve_wall_collisions(offsetY, radius)` - -### Parameters -| Field | Type | -| ----- | ---- | -| offsetY | `number` | -| radius | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_unused_resolve_wall_collisions(f32 offsetY, f32 radius);` - -[:arrow_up_small:](#) - -
- -## [abs_angle_diff](#abs_angle_diff) - -### Lua Example -`local integerValue = abs_angle_diff(x0, x1)` - -### Parameters -| Field | Type | -| ----- | ---- | -| x0 | `integer` | -| x1 | `integer` | - -### Returns -- `integer` - -### C Prototype -`s16 abs_angle_diff(s16 x0, s16 x1);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_xz_using_fvel_and_yaw](#cur_obj_move_xz_using_fvel_and_yaw) - -### Lua Example -`cur_obj_move_xz_using_fvel_and_yaw()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_move_xz_using_fvel_and_yaw(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_y_with_terminal_vel](#cur_obj_move_y_with_terminal_vel) - -### Lua Example -`cur_obj_move_y_with_terminal_vel()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_move_y_with_terminal_vel(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_compute_vel_xz](#cur_obj_compute_vel_xz) - -### Lua Example -`cur_obj_compute_vel_xz()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_compute_vel_xz(void);` - -[:arrow_up_small:](#) - -
- -## [increment_velocity_toward_range](#increment_velocity_toward_range) - -### Lua Example -`local numberValue = increment_velocity_toward_range(value, center, zeroThreshold, increment)` - -### Parameters -| Field | Type | -| ----- | ---- | -| value | `number` | -| center | `number` | -| zeroThreshold | `number` | -| increment | `number` | - -### Returns -- `number` - -### C Prototype -`f32 increment_velocity_toward_range(f32 value, f32 center, f32 zeroThreshold, f32 increment);` - -[:arrow_up_small:](#) - -
- -## [obj_check_if_collided_with_object](#obj_check_if_collided_with_object) - -### Lua Example -`local integerValue = obj_check_if_collided_with_object(obj1, obj2)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj1 | [Object](structs.md#Object) | -| obj2 | [Object](structs.md#Object) | - -### Returns -- `integer` - -### C Prototype -`s32 obj_check_if_collided_with_object(struct Object *obj1, struct Object *obj2);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_behavior](#cur_obj_set_behavior) - -### Lua Example -`cur_obj_set_behavior(behavior)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behavior | `Pointer` <`BehaviorScript`> | - -### Returns -- None - -### C Prototype -`void cur_obj_set_behavior(const BehaviorScript *behavior);` - -[:arrow_up_small:](#) - -
- -## [obj_set_behavior](#obj_set_behavior) - -### Lua Example -`obj_set_behavior(obj, behavior)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| behavior | `Pointer` <`BehaviorScript`> | - -### Returns -- None - -### C Prototype -`void obj_set_behavior(struct Object *obj, const BehaviorScript *behavior);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_has_behavior](#cur_obj_has_behavior) - -### Lua Example -`local integerValue = cur_obj_has_behavior(behavior)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behavior | `Pointer` <`BehaviorScript`> | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_has_behavior(const BehaviorScript *behavior);` - -[:arrow_up_small:](#) - -
- -## [obj_has_behavior](#obj_has_behavior) - -### Lua Example -`local integerValue = obj_has_behavior(obj, behavior)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| behavior | `Pointer` <`BehaviorScript`> | - -### Returns -- `integer` - -### C Prototype -`s32 obj_has_behavior(struct Object *obj, const BehaviorScript *behavior);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_lateral_dist_from_obj_to_home](#cur_obj_lateral_dist_from_obj_to_home) - -### Lua Example -`local numberValue = cur_obj_lateral_dist_from_obj_to_home(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- `number` - -### C Prototype -`f32 cur_obj_lateral_dist_from_obj_to_home(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_lateral_dist_from_mario_to_home](#cur_obj_lateral_dist_from_mario_to_home) - -### Lua Example -`local numberValue = cur_obj_lateral_dist_from_mario_to_home()` - -### Parameters -- None - -### Returns -- `number` - -### C Prototype -`f32 cur_obj_lateral_dist_from_mario_to_home(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_lateral_dist_to_home](#cur_obj_lateral_dist_to_home) - -### Lua Example -`local numberValue = cur_obj_lateral_dist_to_home()` - -### Parameters -- None - -### Returns -- `number` - -### C Prototype -`f32 cur_obj_lateral_dist_to_home(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_outside_home_square](#cur_obj_outside_home_square) - -### Lua Example -`local integerValue = cur_obj_outside_home_square(halfLength)` - -### Parameters -| Field | Type | -| ----- | ---- | -| halfLength | `number` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_outside_home_square(f32 halfLength);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_outside_home_rectangle](#cur_obj_outside_home_rectangle) - -### Lua Example -`local integerValue = cur_obj_outside_home_rectangle(minX, maxX, minZ, maxZ)` - -### Parameters -| Field | Type | -| ----- | ---- | -| minX | `number` | -| maxX | `number` | -| minZ | `number` | -| maxZ | `number` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_outside_home_rectangle(f32 minX, f32 maxX, f32 minZ, f32 maxZ);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_pos_to_home](#cur_obj_set_pos_to_home) - -### Lua Example -`cur_obj_set_pos_to_home()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_set_pos_to_home(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_pos_to_home_and_stop](#cur_obj_set_pos_to_home_and_stop) - -### Lua Example -`cur_obj_set_pos_to_home_and_stop()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_set_pos_to_home_and_stop(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_shake_y](#cur_obj_shake_y) - -### Lua Example -`cur_obj_shake_y(amount)` - -### Parameters -| Field | Type | -| ----- | ---- | -| amount | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_shake_y(f32 amount);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_start_cam_event](#cur_obj_start_cam_event) - -### Lua Example -`cur_obj_start_cam_event(obj, cameraEvent)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| cameraEvent | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_start_cam_event(UNUSED struct Object *obj, s32 cameraEvent);` - -[:arrow_up_small:](#) - -
- -## [set_mario_interact_hoot_if_in_range](#set_mario_interact_hoot_if_in_range) - -### Lua Example -`set_mario_interact_hoot_if_in_range(sp0, sp4, sp8)` - -### Parameters -| Field | Type | -| ----- | ---- | -| sp0 | `integer` | -| sp4 | `integer` | -| sp8 | `number` | - -### Returns -- None - -### C Prototype -`void set_mario_interact_hoot_if_in_range(UNUSED s32 sp0, UNUSED s32 sp4, f32 sp8);` - -[:arrow_up_small:](#) - -
- -## [obj_set_billboard](#obj_set_billboard) - -### Lua Example -`obj_set_billboard(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_set_billboard(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [obj_set_cylboard](#obj_set_cylboard) - -### Lua Example -`obj_set_cylboard(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_set_cylboard(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_billboard_if_vanilla_cam](#cur_obj_set_billboard_if_vanilla_cam) - -### Lua Example -`cur_obj_set_billboard_if_vanilla_cam()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_set_billboard_if_vanilla_cam(void);` - -[:arrow_up_small:](#) - -
- -## [obj_set_hitbox_radius_and_height](#obj_set_hitbox_radius_and_height) - -### Lua Example -`obj_set_hitbox_radius_and_height(o, radius, height)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| radius | `number` | -| height | `number` | - -### Returns -- None - -### C Prototype -`void obj_set_hitbox_radius_and_height(struct Object *o, f32 radius, f32 height);` - -[:arrow_up_small:](#) - -
- -## [obj_set_hurtbox_radius_and_height](#obj_set_hurtbox_radius_and_height) - -### Lua Example -`obj_set_hurtbox_radius_and_height(o, radius, height)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| radius | `number` | -| height | `number` | - -### Returns -- None - -### C Prototype -`void obj_set_hurtbox_radius_and_height(struct Object *o, f32 radius, f32 height);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_hitbox_radius_and_height](#cur_obj_set_hitbox_radius_and_height) - -### Lua Example -`cur_obj_set_hitbox_radius_and_height(radius, height)` - -### Parameters -| Field | Type | -| ----- | ---- | -| radius | `number` | -| height | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_set_hitbox_radius_and_height(f32 radius, f32 height);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_hurtbox_radius_and_height](#cur_obj_set_hurtbox_radius_and_height) - -### Lua Example -`cur_obj_set_hurtbox_radius_and_height(radius, height)` - -### Parameters -| Field | Type | -| ----- | ---- | -| radius | `number` | -| height | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_set_hurtbox_radius_and_height(f32 radius, f32 height);` - -[:arrow_up_small:](#) - -
- -## [obj_spawn_loot_coins](#obj_spawn_loot_coins) - -### Lua Example -`obj_spawn_loot_coins(obj, numCoins, sp30, coinBehavior, posJitter, model)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| numCoins | `integer` | -| sp30 | `number` | -| coinBehavior | `Pointer` <`BehaviorScript`> | -| posJitter | `integer` | -| model | `integer` | - -### Returns -- None - -### C Prototype -`void obj_spawn_loot_coins(struct Object *obj, s32 numCoins, f32 sp30, const BehaviorScript *coinBehavior, s16 posJitter, s16 model);` - -[:arrow_up_small:](#) - -
- -## [obj_spawn_loot_blue_coins](#obj_spawn_loot_blue_coins) - -### Lua Example -`obj_spawn_loot_blue_coins(obj, numCoins, sp28, posJitter)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| numCoins | `integer` | -| sp28 | `number` | -| posJitter | `integer` | - -### Returns -- None - -### C Prototype -`void obj_spawn_loot_blue_coins(struct Object *obj, s32 numCoins, f32 sp28, s16 posJitter);` - -[:arrow_up_small:](#) - -
- -## [obj_spawn_loot_yellow_coins](#obj_spawn_loot_yellow_coins) - -### Lua Example -`obj_spawn_loot_yellow_coins(obj, numCoins, sp28)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| numCoins | `integer` | -| sp28 | `number` | - -### Returns -- None - -### C Prototype -`void obj_spawn_loot_yellow_coins(struct Object *obj, s32 numCoins, f32 sp28);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_spawn_loot_coin_at_mario_pos](#cur_obj_spawn_loot_coin_at_mario_pos) - -### Lua Example -`cur_obj_spawn_loot_coin_at_mario_pos(m)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | - -### Returns -- None - -### C Prototype -`void cur_obj_spawn_loot_coin_at_mario_pos(struct MarioState* m);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_abs_y_dist_to_home](#cur_obj_abs_y_dist_to_home) - -### Lua Example -`local numberValue = cur_obj_abs_y_dist_to_home()` - -### Parameters -- None - -### Returns -- `number` - -### C Prototype -`f32 cur_obj_abs_y_dist_to_home(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_advance_looping_anim](#cur_obj_advance_looping_anim) - -### Lua Example -`local integerValue = cur_obj_advance_looping_anim()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_advance_looping_anim(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_detect_steep_floor](#cur_obj_detect_steep_floor) - -### Lua Example -`local integerValue = cur_obj_detect_steep_floor(steepAngleDegrees)` - -### Parameters -| Field | Type | -| ----- | ---- | -| steepAngleDegrees | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_detect_steep_floor(s16 steepAngleDegrees);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_resolve_wall_collisions](#cur_obj_resolve_wall_collisions) - -### Lua Example -`local integerValue = cur_obj_resolve_wall_collisions()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_resolve_wall_collisions(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_update_floor](#cur_obj_update_floor) - -### Lua Example -`cur_obj_update_floor()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_update_floor(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_update_floor_and_resolve_wall_collisions](#cur_obj_update_floor_and_resolve_wall_collisions) - -### Lua Example -`cur_obj_update_floor_and_resolve_wall_collisions(steepSlopeDegrees)` - -### Parameters -| Field | Type | -| ----- | ---- | -| steepSlopeDegrees | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_update_floor_and_resolve_wall_collisions(s16 steepSlopeDegrees);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_update_floor_and_walls](#cur_obj_update_floor_and_walls) - -### Lua Example -`cur_obj_update_floor_and_walls()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_update_floor_and_walls(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_standard](#cur_obj_move_standard) - -### Lua Example -`cur_obj_move_standard(steepSlopeAngleDegrees)` - -### Parameters -| Field | Type | -| ----- | ---- | -| steepSlopeAngleDegrees | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_move_standard(s16 steepSlopeAngleDegrees);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_within_12k_bounds](#cur_obj_within_12k_bounds) - -### Lua Example -`local integerValue = cur_obj_within_12k_bounds()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_within_12k_bounds(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_using_vel_and_gravity](#cur_obj_move_using_vel_and_gravity) - -### Lua Example -`cur_obj_move_using_vel_and_gravity()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_move_using_vel_and_gravity(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_using_fvel_and_gravity](#cur_obj_move_using_fvel_and_gravity) - -### Lua Example -`cur_obj_move_using_fvel_and_gravity()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_move_using_fvel_and_gravity(void);` - -[:arrow_up_small:](#) - -
- -## [obj_set_pos_relative](#obj_set_pos_relative) - -### Lua Example -`obj_set_pos_relative(obj, other, dleft, dy, dforward)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| other | [Object](structs.md#Object) | -| dleft | `number` | -| dy | `number` | -| dforward | `number` | - -### Returns -- None - -### C Prototype -`void obj_set_pos_relative(struct Object *obj, struct Object *other, f32 dleft, f32 dy, f32 dforward);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_angle_to_home](#cur_obj_angle_to_home) - -### Lua Example -`local integerValue = cur_obj_angle_to_home()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s16 cur_obj_angle_to_home(void);` - -[:arrow_up_small:](#) - -
- -## [obj_set_gfx_pos_at_obj_pos](#obj_set_gfx_pos_at_obj_pos) - -### Lua Example -`obj_set_gfx_pos_at_obj_pos(obj1, obj2)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj1 | [Object](structs.md#Object) | -| obj2 | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_set_gfx_pos_at_obj_pos(struct Object *obj1, struct Object *obj2);` - -[:arrow_up_small:](#) - -
- -## [obj_translate_local](#obj_translate_local) - -### Description -Transforms the vector at `localTranslateIndex` into the object's local coordinates, and then adds it to the vector at `posIndex` - -### Lua Example -`obj_translate_local(obj, posIndex, localTranslateIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| posIndex | `integer` | -| localTranslateIndex | `integer` | - -### Returns -- None - -### C Prototype -`void obj_translate_local(struct Object *obj, s16 posIndex, s16 localTranslateIndex);` - -[:arrow_up_small:](#) - -
- -## [obj_build_transform_from_pos_and_angle](#obj_build_transform_from_pos_and_angle) - -### Lua Example -`obj_build_transform_from_pos_and_angle(obj, posIndex, angleIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| posIndex | `integer` | -| angleIndex | `integer` | - -### Returns -- None - -### C Prototype -`void obj_build_transform_from_pos_and_angle(struct Object *obj, s16 posIndex, s16 angleIndex);` - -[:arrow_up_small:](#) - -
- -## [obj_set_throw_matrix_from_transform](#obj_set_throw_matrix_from_transform) - -### Lua Example -`obj_set_throw_matrix_from_transform(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_set_throw_matrix_from_transform(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [obj_build_transform_relative_to_parent](#obj_build_transform_relative_to_parent) - -### Lua Example -`obj_build_transform_relative_to_parent(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_build_transform_relative_to_parent(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [obj_create_transform_from_self](#obj_create_transform_from_self) - -### Lua Example -`obj_create_transform_from_self(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_create_transform_from_self(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_rotate_move_angle_using_vel](#cur_obj_rotate_move_angle_using_vel) - -### Lua Example -`cur_obj_rotate_move_angle_using_vel()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_rotate_move_angle_using_vel(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_rotate_face_angle_using_vel](#cur_obj_rotate_face_angle_using_vel) - -### Lua Example -`cur_obj_rotate_face_angle_using_vel()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_rotate_face_angle_using_vel(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_face_angle_to_move_angle](#cur_obj_set_face_angle_to_move_angle) - -### Lua Example -`cur_obj_set_face_angle_to_move_angle()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_set_face_angle_to_move_angle(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_follow_path](#cur_obj_follow_path) - -### Lua Example -`local integerValue = cur_obj_follow_path(unusedArg)` - -### Parameters -| Field | Type | -| ----- | ---- | -| unusedArg | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_follow_path(UNUSED s32 unusedArg);` - -[:arrow_up_small:](#) - -
- -## [chain_segment_init](#chain_segment_init) - -### Lua Example -`chain_segment_init(segment)` - -### Parameters -| Field | Type | -| ----- | ---- | -| segment | [ChainSegment](structs.md#ChainSegment) | - -### Returns -- None - -### C Prototype -`void chain_segment_init(struct ChainSegment *segment);` - -[:arrow_up_small:](#) - -
- -## [random_f32_around_zero](#random_f32_around_zero) - -### Lua Example -`local numberValue = random_f32_around_zero(diameter)` - -### Parameters -| Field | Type | -| ----- | ---- | -| diameter | `number` | - -### Returns -- `number` - -### C Prototype -`f32 random_f32_around_zero(f32 diameter);` - -[:arrow_up_small:](#) - -
- -## [obj_scale_random](#obj_scale_random) - -### Lua Example -`obj_scale_random(obj, rangeLength, minScale)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| rangeLength | `number` | -| minScale | `number` | - -### Returns -- None - -### C Prototype -`void obj_scale_random(struct Object *obj, f32 rangeLength, f32 minScale);` - -[:arrow_up_small:](#) - -
- -## [obj_translate_xyz_random](#obj_translate_xyz_random) - -### Lua Example -`obj_translate_xyz_random(obj, rangeLength)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| rangeLength | `number` | - -### Returns -- None - -### C Prototype -`void obj_translate_xyz_random(struct Object *obj, f32 rangeLength);` - -[:arrow_up_small:](#) - -
- -## [obj_translate_xz_random](#obj_translate_xz_random) - -### Lua Example -`obj_translate_xz_random(obj, rangeLength)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| rangeLength | `number` | - -### Returns -- None - -### C Prototype -`void obj_translate_xz_random(struct Object *obj, f32 rangeLength);` - -[:arrow_up_small:](#) - -
- -## [obj_build_vel_from_transform](#obj_build_vel_from_transform) - -### Lua Example -`obj_build_vel_from_transform(a0)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a0 | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_build_vel_from_transform(struct Object *a0);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_pos_via_transform](#cur_obj_set_pos_via_transform) - -### Lua Example -`cur_obj_set_pos_via_transform()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_set_pos_via_transform(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_reflect_move_angle_off_wall](#cur_obj_reflect_move_angle_off_wall) - -### Lua Example -`local integerValue = cur_obj_reflect_move_angle_off_wall()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s16 cur_obj_reflect_move_angle_off_wall(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_spawn_particles](#cur_obj_spawn_particles) - -### Lua Example -`cur_obj_spawn_particles(info)` - -### Parameters -| Field | Type | -| ----- | ---- | -| info | [SpawnParticlesInfo](structs.md#SpawnParticlesInfo) | - -### Returns -- None - -### C Prototype -`void cur_obj_spawn_particles(struct SpawnParticlesInfo *info);` - -[:arrow_up_small:](#) - -
- -## [obj_set_hitbox](#obj_set_hitbox) - -### Lua Example -`obj_set_hitbox(obj, hitbox)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | -| hitbox | [ObjectHitbox](structs.md#ObjectHitbox) | - -### Returns -- None - -### C Prototype -`void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox);` - -[:arrow_up_small:](#) - -
- -## [signum_positive](#signum_positive) - -### Lua Example -`local integerValue = signum_positive(x)` - -### Parameters -| Field | Type | -| ----- | ---- | -| x | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 signum_positive(s32 x);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_wait_then_blink](#cur_obj_wait_then_blink) - -### Lua Example -`local integerValue = cur_obj_wait_then_blink(timeUntilBlinking, numBlinks)` - -### Parameters -| Field | Type | -| ----- | ---- | -| timeUntilBlinking | `integer` | -| numBlinks | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_wait_then_blink(s32 timeUntilBlinking, s32 numBlinks);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_is_mario_ground_pounding_platform](#cur_obj_is_mario_ground_pounding_platform) - -### Lua Example -`local integerValue = cur_obj_is_mario_ground_pounding_platform()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_is_mario_ground_pounding_platform(void);` - -[:arrow_up_small:](#) - -
- -## [obj_is_mario_ground_pounding_platform](#obj_is_mario_ground_pounding_platform) - -### Lua Example -`local integerValue = obj_is_mario_ground_pounding_platform(m, obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | -| obj | [Object](structs.md#Object) | - -### Returns -- `integer` - -### C Prototype -`s32 obj_is_mario_ground_pounding_platform(struct MarioState *m, struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [spawn_mist_particles](#spawn_mist_particles) - -### Lua Example -`spawn_mist_particles()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void spawn_mist_particles(void);` - -[:arrow_up_small:](#) - -
- -## [spawn_mist_particles_with_sound](#spawn_mist_particles_with_sound) - -### Lua Example -`spawn_mist_particles_with_sound(sp18)` - -### Parameters -| Field | Type | -| ----- | ---- | -| sp18 | `integer` | - -### Returns -- None - -### C Prototype -`void spawn_mist_particles_with_sound(u32 sp18);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_push_mario_away](#cur_obj_push_mario_away) - -### Lua Example -`cur_obj_push_mario_away(radius)` - -### Parameters -| Field | Type | -| ----- | ---- | -| radius | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_push_mario_away(f32 radius);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_push_mario_away_from_cylinder](#cur_obj_push_mario_away_from_cylinder) - -### Lua Example -`cur_obj_push_mario_away_from_cylinder(radius, extentY)` - -### Parameters -| Field | Type | -| ----- | ---- | -| radius | `number` | -| extentY | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_push_mario_away_from_cylinder(f32 radius, f32 extentY);` - -[:arrow_up_small:](#) - -
- -## [bhv_dust_smoke_loop](#bhv_dust_smoke_loop) - -### Lua Example -`bhv_dust_smoke_loop()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void bhv_dust_smoke_loop(void);` - -[:arrow_up_small:](#) - -
- -## [stub_obj_helpers_3](#stub_obj_helpers_3) - -### Lua Example -`stub_obj_helpers_3(sp0, sp4)` - -### Parameters -| Field | Type | -| ----- | ---- | -| sp0 | `integer` | -| sp4 | `integer` | - -### Returns -- None - -### C Prototype -`void stub_obj_helpers_3(UNUSED s32 sp0, UNUSED s32 sp4);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_scale_over_time](#cur_obj_scale_over_time) - -### Lua Example -`cur_obj_scale_over_time(a0, a1, sp10, sp14)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a0 | `integer` | -| a1 | `integer` | -| sp10 | `number` | -| sp14 | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_scale_over_time(s32 a0, s32 a1, f32 sp10, f32 sp14);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_pos_to_home_with_debug](#cur_obj_set_pos_to_home_with_debug) - -### Lua Example -`cur_obj_set_pos_to_home_with_debug()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_set_pos_to_home_with_debug(void);` - -[:arrow_up_small:](#) - -
- -## [stub_obj_helpers_4](#stub_obj_helpers_4) - -### Lua Example -`stub_obj_helpers_4()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void stub_obj_helpers_4(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_is_mario_on_platform](#cur_obj_is_mario_on_platform) - -### Lua Example -`local integerValue = cur_obj_is_mario_on_platform()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_is_mario_on_platform(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_is_any_player_on_platform](#cur_obj_is_any_player_on_platform) - -### Lua Example -`local integerValue = cur_obj_is_any_player_on_platform()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_is_any_player_on_platform(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_shake_y_until](#cur_obj_shake_y_until) - -### Lua Example -`local integerValue = cur_obj_shake_y_until(cycles, amount)` - -### Parameters -| Field | Type | -| ----- | ---- | -| cycles | `integer` | -| amount | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_shake_y_until(s32 cycles, s32 amount);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_move_up_and_down](#cur_obj_move_up_and_down) - -### Lua Example -`local integerValue = cur_obj_move_up_and_down(a0)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a0 | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_move_up_and_down(s32 a0);` - -[:arrow_up_small:](#) - -
- -## [spawn_star_with_no_lvl_exit](#spawn_star_with_no_lvl_exit) - -### Lua Example -`local ObjectValue = spawn_star_with_no_lvl_exit(sp20, sp24)` - -### Parameters -| Field | Type | -| ----- | ---- | -| sp20 | `integer` | -| sp24 | `integer` | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *spawn_star_with_no_lvl_exit(s32 sp20, s32 sp24);` - -[:arrow_up_small:](#) - -
- -## [spawn_base_star_with_no_lvl_exit](#spawn_base_star_with_no_lvl_exit) - -### Lua Example -`spawn_base_star_with_no_lvl_exit()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void spawn_base_star_with_no_lvl_exit(void);` - -[:arrow_up_small:](#) - -
- -## [bit_shift_left](#bit_shift_left) - -### Lua Example -`local integerValue = bit_shift_left(a0)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a0 | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 bit_shift_left(s32 a0);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_mario_far_away](#cur_obj_mario_far_away) - -### Lua Example -`local integerValue = cur_obj_mario_far_away()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_mario_far_away(void);` - -[:arrow_up_small:](#) - -
- -## [is_mario_moving_fast_or_in_air](#is_mario_moving_fast_or_in_air) - -### Lua Example -`local integerValue = is_mario_moving_fast_or_in_air(speedThreshold)` - -### Parameters -| Field | Type | -| ----- | ---- | -| speedThreshold | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 is_mario_moving_fast_or_in_air(s32 speedThreshold);` - -[:arrow_up_small:](#) - -
- -## [is_item_in_array](#is_item_in_array) - -### Lua Example -`local integerValue = is_item_in_array(item, array)` - -### Parameters -| Field | Type | -| ----- | ---- | -| item | `integer` | -| array | `Pointer` <`integer`> | - -### Returns -- `integer` - -### C Prototype -`s32 is_item_in_array(s8 item, s8 *array);` - -[:arrow_up_small:](#) - -
- -## [bhv_init_room](#bhv_init_room) - -### Lua Example -`bhv_init_room()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void bhv_init_room(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_enable_rendering_if_mario_in_room](#cur_obj_enable_rendering_if_mario_in_room) - -### Lua Example -`cur_obj_enable_rendering_if_mario_in_room()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_enable_rendering_if_mario_in_room(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_hitbox_and_die_if_attacked](#cur_obj_set_hitbox_and_die_if_attacked) - -### Lua Example -`local integerValue = cur_obj_set_hitbox_and_die_if_attacked(hitbox, deathSound, noLootCoins)` - -### Parameters -| Field | Type | -| ----- | ---- | -| hitbox | [ObjectHitbox](structs.md#ObjectHitbox) | -| deathSound | `integer` | -| noLootCoins | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deathSound, s32 noLootCoins);` - -[:arrow_up_small:](#) - -
- -## [obj_explode_and_spawn_coins](#obj_explode_and_spawn_coins) - -### Lua Example -`obj_explode_and_spawn_coins(sp18, sp1C)` - -### Parameters -| Field | Type | -| ----- | ---- | -| sp18 | `number` | -| sp1C | `integer` | - -### Returns -- None - -### C Prototype -`void obj_explode_and_spawn_coins(f32 sp18, s32 sp1C);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_if_hit_wall_bounce_away](#cur_obj_if_hit_wall_bounce_away) - -### Lua Example -`cur_obj_if_hit_wall_bounce_away()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_if_hit_wall_bounce_away(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_hide_if_mario_far_away_y](#cur_obj_hide_if_mario_far_away_y) - -### Lua Example -`local integerValue = cur_obj_hide_if_mario_far_away_y(distY)` - -### Parameters -| Field | Type | -| ----- | ---- | -| distY | `number` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_hide_if_mario_far_away_y(f32 distY);` - -[:arrow_up_small:](#) - -
- -## [obj_is_hidden](#obj_is_hidden) - -### Lua Example -`local integerValue = obj_is_hidden(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- `integer` - -### C Prototype -`s32 obj_is_hidden(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [enable_time_stop](#enable_time_stop) - -### Lua Example -`enable_time_stop()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void enable_time_stop(void);` - -[:arrow_up_small:](#) - -
- -## [enable_time_stop_if_alone](#enable_time_stop_if_alone) - -### Lua Example -`enable_time_stop_if_alone()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void enable_time_stop_if_alone(void);` - -[:arrow_up_small:](#) - -
- -## [disable_time_stop](#disable_time_stop) - -### Lua Example -`disable_time_stop()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void disable_time_stop(void);` - -[:arrow_up_small:](#) - -
- -## [set_time_stop_flags](#set_time_stop_flags) - -### Lua Example -`set_time_stop_flags(flags)` - -### Parameters -| Field | Type | -| ----- | ---- | -| flags | `integer` | - -### Returns -- None - -### C Prototype -`void set_time_stop_flags(s32 flags);` - -[:arrow_up_small:](#) - -
- -## [set_time_stop_flags_if_alone](#set_time_stop_flags_if_alone) - -### Lua Example -`set_time_stop_flags_if_alone(flags)` - -### Parameters -| Field | Type | -| ----- | ---- | -| flags | `integer` | - -### Returns -- None - -### C Prototype -`void set_time_stop_flags_if_alone(s32 flags);` - -[:arrow_up_small:](#) - -
- -## [clear_time_stop_flags](#clear_time_stop_flags) - -### Lua Example -`clear_time_stop_flags(flags)` - -### Parameters -| Field | Type | -| ----- | ---- | -| flags | `integer` | - -### Returns -- None - -### C Prototype -`void clear_time_stop_flags(s32 flags);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_can_mario_activate_textbox](#cur_obj_can_mario_activate_textbox) - -### Lua Example -`local integerValue = cur_obj_can_mario_activate_textbox(m, radius, height, unused)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | -| radius | `number` | -| height | `number` | -| unused | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_can_mario_activate_textbox(struct MarioState* m, f32 radius, f32 height, UNUSED s32 unused);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_can_mario_activate_textbox_2](#cur_obj_can_mario_activate_textbox_2) - -### Lua Example -`local integerValue = cur_obj_can_mario_activate_textbox_2(m, radius, height)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | -| radius | `number` | -| height | `number` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_can_mario_activate_textbox_2(struct MarioState* m, f32 radius, f32 height);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_end_dialog](#cur_obj_end_dialog) - -### Lua Example -`cur_obj_end_dialog(m, dialogFlags, dialogResult)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | -| dialogFlags | `integer` | -| dialogResult | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_end_dialog(struct MarioState* m, s32 dialogFlags, s32 dialogResult);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_has_model](#cur_obj_has_model) - -### Lua Example -`local integerValue = cur_obj_has_model(modelID)` - -### Parameters -| Field | Type | -| ----- | ---- | -| modelID | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_has_model(u16 modelID);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_align_gfx_with_floor](#cur_obj_align_gfx_with_floor) - -### Lua Example -`cur_obj_align_gfx_with_floor()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_align_gfx_with_floor(void);` - -[:arrow_up_small:](#) - -
- -## [mario_is_within_rectangle](#mario_is_within_rectangle) - -### Lua Example -`local integerValue = mario_is_within_rectangle(minX, maxX, minZ, maxZ)` - -### Parameters -| Field | Type | -| ----- | ---- | -| minX | `integer` | -| maxX | `integer` | -| minZ | `integer` | -| maxZ | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 mario_is_within_rectangle(s16 minX, s16 maxX, s16 minZ, s16 maxZ);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_shake_screen](#cur_obj_shake_screen) - -### Lua Example -`cur_obj_shake_screen(shake)` - -### Parameters -| Field | Type | -| ----- | ---- | -| shake | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_shake_screen(s32 shake);` - -[:arrow_up_small:](#) - -
- -## [obj_attack_collided_from_other_object](#obj_attack_collided_from_other_object) - -### Lua Example -`local integerValue = obj_attack_collided_from_other_object(obj)` - -### Parameters -| Field | Type | -| ----- | ---- | -| obj | [Object](structs.md#Object) | - -### Returns -- `integer` - -### C Prototype -`s32 obj_attack_collided_from_other_object(struct Object *obj);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_was_attacked_or_ground_pounded](#cur_obj_was_attacked_or_ground_pounded) - -### Lua Example -`local integerValue = cur_obj_was_attacked_or_ground_pounded()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_was_attacked_or_ground_pounded(void);` - -[:arrow_up_small:](#) - -
- -## [obj_copy_behavior_params](#obj_copy_behavior_params) - -### Lua Example -`obj_copy_behavior_params(dst, src)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dst | [Object](structs.md#Object) | -| src | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void obj_copy_behavior_params(struct Object *dst, struct Object *src);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_init_animation_and_anim_frame](#cur_obj_init_animation_and_anim_frame) - -### Lua Example -`cur_obj_init_animation_and_anim_frame(animIndex, animFrame)` - -### Parameters -| Field | Type | -| ----- | ---- | -| animIndex | `integer` | -| animFrame | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_init_animation_and_anim_frame(s32 animIndex, s32 animFrame);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_init_animation_and_check_if_near_end](#cur_obj_init_animation_and_check_if_near_end) - -### Lua Example -`local integerValue = cur_obj_init_animation_and_check_if_near_end(animIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| animIndex | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_init_animation_and_check_if_near_end(s32 animIndex);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_init_animation_and_extend_if_at_end](#cur_obj_init_animation_and_extend_if_at_end) - -### Lua Example -`cur_obj_init_animation_and_extend_if_at_end(animIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| animIndex | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_init_animation_and_extend_if_at_end(s32 animIndex);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_check_grabbed_mario](#cur_obj_check_grabbed_mario) - -### Lua Example -`local integerValue = cur_obj_check_grabbed_mario()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_check_grabbed_mario(void);` - -[:arrow_up_small:](#) - -
- -## [player_performed_grab_escape_action](#player_performed_grab_escape_action) - -### Lua Example -`local integerValue = player_performed_grab_escape_action()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 player_performed_grab_escape_action(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_unused_play_footstep_sound](#cur_obj_unused_play_footstep_sound) - -### Lua Example -`cur_obj_unused_play_footstep_sound(animFrame1, animFrame2, sound)` - -### Parameters -| Field | Type | -| ----- | ---- | -| animFrame1 | `integer` | -| animFrame2 | `integer` | -| sound | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_unused_play_footstep_sound(s32 animFrame1, s32 animFrame2, s32 sound);` - -[:arrow_up_small:](#) - -
- -## [enable_time_stop_including_mario](#enable_time_stop_including_mario) - -### Lua Example -`enable_time_stop_including_mario()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void enable_time_stop_including_mario(void);` - -[:arrow_up_small:](#) - -
- -## [disable_time_stop_including_mario](#disable_time_stop_including_mario) - -### Lua Example -`disable_time_stop_including_mario()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void disable_time_stop_including_mario(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_check_interacted](#cur_obj_check_interacted) - -### Lua Example -`local integerValue = cur_obj_check_interacted()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 cur_obj_check_interacted(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_spawn_loot_blue_coin](#cur_obj_spawn_loot_blue_coin) - -### Lua Example -`cur_obj_spawn_loot_blue_coin()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_spawn_loot_blue_coin(void);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_spawn_star_at_y_offset](#cur_obj_spawn_star_at_y_offset) - -### Lua Example -`cur_obj_spawn_star_at_y_offset(targetX, targetY, targetZ, offsetY)` - -### Parameters -| Field | Type | -| ----- | ---- | -| targetX | `number` | -| targetY | `number` | -| targetZ | `number` | -| offsetY | `number` | - -### Returns -- None - -### C Prototype -`void cur_obj_spawn_star_at_y_offset(f32 targetX, f32 targetY, f32 targetZ, f32 offsetY);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_set_home_once](#cur_obj_set_home_once) - -### Description -Sets the current object's home only the first time it's called - -### Lua Example -`cur_obj_set_home_once()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void cur_obj_set_home_once(void);` - -[:arrow_up_small:](#) - -
- -## [get_trajectory_length](#get_trajectory_length) - -### Description -Gets a trajectory's length - -### Lua Example -`local integerValue = get_trajectory_length(trajectory)` - -### Parameters -| Field | Type | -| ----- | ---- | -| trajectory | `Pointer` <`Trajectory`> | - -### Returns -- `integer` - -### C Prototype -`s32 get_trajectory_length(Trajectory* trajectory);` - -[:arrow_up_small:](#) -
--- diff --git a/docs/lua/functions-6.md b/docs/lua/functions-6.md index a9fd4062c..de205a965 100644 --- a/docs/lua/functions-6.md +++ b/docs/lua/functions-6.md @@ -5,6 +5,4584 @@ [< prev](functions-5.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | 6 | [7](functions-7.md) | [next >](functions-7.md)] +--- +# functions from object_helpers.c + +
+ + +## [clear_move_flag](#clear_move_flag) + +### Lua Example +`local integerValue = clear_move_flag(bitSet, flag)` + +### Parameters +| Field | Type | +| ----- | ---- | +| bitSet | `Pointer` <`integer`> | +| flag | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 clear_move_flag(u32 *bitSet, s32 flag);` + +[:arrow_up_small:](#) + +
+ +## [set_room_override](#set_room_override) + +### Description +Overrides the current room Mario is in. Set to -1 to reset override + +### Lua Example +`set_room_override(room)` + +### Parameters +| Field | Type | +| ----- | ---- | +| room | `integer` | + +### Returns +- None + +### C Prototype +`void set_room_override(s16 room);` + +[:arrow_up_small:](#) + +
+ +## [obj_update_pos_from_parent_transformation](#obj_update_pos_from_parent_transformation) + +### Lua Example +`obj_update_pos_from_parent_transformation(a0, a1)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a0 | [Mat4](structs.md#Mat4) | +| a1 | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_update_pos_from_parent_transformation(Mat4 a0, struct Object *a1);` + +[:arrow_up_small:](#) + +
+ +## [obj_apply_scale_to_matrix](#obj_apply_scale_to_matrix) + +### Lua Example +`obj_apply_scale_to_matrix(obj, dst, src)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| dst | [Mat4](structs.md#Mat4) | +| src | [Mat4](structs.md#Mat4) | + +### Returns +- None + +### C Prototype +`void obj_apply_scale_to_matrix(struct Object *obj, OUT Mat4 dst, Mat4 src);` + +[:arrow_up_small:](#) + +
+ +## [create_transformation_from_matrices](#create_transformation_from_matrices) + +### Lua Example +`create_transformation_from_matrices(a0, a1, a2)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a0 | [Mat4](structs.md#Mat4) | +| a1 | [Mat4](structs.md#Mat4) | +| a2 | [Mat4](structs.md#Mat4) | + +### Returns +- None + +### C Prototype +`void create_transformation_from_matrices(OUT Mat4 a0, Mat4 a1, Mat4 a2);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_held_state](#obj_set_held_state) + +### Lua Example +`obj_set_held_state(obj, heldBehavior)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| heldBehavior | `Pointer` <`BehaviorScript`> | + +### Returns +- None + +### C Prototype +`void obj_set_held_state(struct Object *obj, const BehaviorScript *heldBehavior);` + +[:arrow_up_small:](#) + +
+ +## [lateral_dist_between_objects](#lateral_dist_between_objects) + +### Lua Example +`local numberValue = lateral_dist_between_objects(obj1, obj2)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj1 | [Object](structs.md#Object) | +| obj2 | [Object](structs.md#Object) | + +### Returns +- `number` + +### C Prototype +`f32 lateral_dist_between_objects(struct Object *obj1, struct Object *obj2);` + +[:arrow_up_small:](#) + +
+ +## [dist_between_objects](#dist_between_objects) + +### Lua Example +`local numberValue = dist_between_objects(obj1, obj2)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj1 | [Object](structs.md#Object) | +| obj2 | [Object](structs.md#Object) | + +### Returns +- `number` + +### C Prototype +`f32 dist_between_objects(struct Object *obj1, struct Object *obj2);` + +[:arrow_up_small:](#) + +
+ +## [dist_between_object_and_point](#dist_between_object_and_point) + +### Lua Example +`local numberValue = dist_between_object_and_point(obj, pointX, pointY, pointZ)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| pointX | `number` | +| pointY | `number` | +| pointZ | `number` | + +### Returns +- `number` + +### C Prototype +`f32 dist_between_object_and_point(struct Object *obj, f32 pointX, f32 pointY, f32 pointZ);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_forward_vel_approach_upward](#cur_obj_forward_vel_approach_upward) + +### Lua Example +`cur_obj_forward_vel_approach_upward(target, increment)` + +### Parameters +| Field | Type | +| ----- | ---- | +| target | `number` | +| increment | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_forward_vel_approach_upward(f32 target, f32 increment);` + +[:arrow_up_small:](#) + +
+ +## [approach_f32_signed](#approach_f32_signed) + +### Lua Example +`local integerValue = approach_f32_signed(value, target, increment)` + +### Parameters +| Field | Type | +| ----- | ---- | +| value | `Pointer` <`number`> | +| target | `number` | +| increment | `number` | + +### Returns +- `integer` + +### C Prototype +`s32 approach_f32_signed(f32 *value, f32 target, f32 increment);` + +[:arrow_up_small:](#) + +
+ +## [approach_f32_symmetric](#approach_f32_symmetric) + +### Lua Example +`local numberValue = approach_f32_symmetric(value, target, increment)` + +### Parameters +| Field | Type | +| ----- | ---- | +| value | `number` | +| target | `number` | +| increment | `number` | + +### Returns +- `number` + +### C Prototype +`f32 approach_f32_symmetric(f32 value, f32 target, f32 increment);` + +[:arrow_up_small:](#) + +
+ +## [approach_s16_symmetric](#approach_s16_symmetric) + +### Lua Example +`local integerValue = approach_s16_symmetric(value, target, increment)` + +### Parameters +| Field | Type | +| ----- | ---- | +| value | `integer` | +| target | `integer` | +| increment | `integer` | + +### Returns +- `integer` + +### C Prototype +`s16 approach_s16_symmetric(s16 value, s16 target, s16 increment);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_rotate_yaw_toward](#cur_obj_rotate_yaw_toward) + +### Lua Example +`local integerValue = cur_obj_rotate_yaw_toward(target, increment)` + +### Parameters +| Field | Type | +| ----- | ---- | +| target | `integer` | +| increment | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_rotate_yaw_toward(s16 target, s16 increment);` + +[:arrow_up_small:](#) + +
+ +## [obj_angle_to_object](#obj_angle_to_object) + +### Lua Example +`local integerValue = obj_angle_to_object(obj1, obj2)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj1 | [Object](structs.md#Object) | +| obj2 | [Object](structs.md#Object) | + +### Returns +- `integer` + +### C Prototype +`s16 obj_angle_to_object(struct Object *obj1, struct Object *obj2);` + +[:arrow_up_small:](#) + +
+ +## [obj_pitch_to_object](#obj_pitch_to_object) + +### Lua Example +`local integerValue = obj_pitch_to_object(obj, target)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| target | [Object](structs.md#Object) | + +### Returns +- `integer` + +### C Prototype +`s16 obj_pitch_to_object(struct Object* obj, struct Object* target);` + +[:arrow_up_small:](#) + +
+ +## [obj_angle_to_point](#obj_angle_to_point) + +### Lua Example +`local integerValue = obj_angle_to_point(obj, pointX, pointZ)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| pointX | `number` | +| pointZ | `number` | + +### Returns +- `integer` + +### C Prototype +`s16 obj_angle_to_point(struct Object *obj, f32 pointX, f32 pointZ);` + +[:arrow_up_small:](#) + +
+ +## [obj_turn_toward_object](#obj_turn_toward_object) + +### Lua Example +`local integerValue = obj_turn_toward_object(obj, target, angleIndex, turnAmount)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| target | [Object](structs.md#Object) | +| angleIndex | `integer` | +| turnAmount | `integer` | + +### Returns +- `integer` + +### C Prototype +`s16 obj_turn_toward_object(struct Object *obj, struct Object *target, s16 angleIndex, s16 turnAmount);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_parent_relative_pos](#obj_set_parent_relative_pos) + +### Lua Example +`obj_set_parent_relative_pos(obj, relX, relY, relZ)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| relX | `integer` | +| relY | `integer` | +| relZ | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_parent_relative_pos(struct Object *obj, s16 relX, s16 relY, s16 relZ);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_pos](#obj_set_pos) + +### Lua Example +`obj_set_pos(obj, x, y, z)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| x | `integer` | +| y | `integer` | +| z | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_pos(struct Object *obj, s16 x, s16 y, s16 z);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_angle](#obj_set_angle) + +### Lua Example +`obj_set_angle(obj, pitch, yaw, roll)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| pitch | `integer` | +| yaw | `integer` | +| roll | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_move_angle](#obj_set_move_angle) + +### Lua Example +`obj_set_move_angle(obj, pitch, yaw, roll)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| pitch | `integer` | +| yaw | `integer` | +| roll | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_move_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_face_angle](#obj_set_face_angle) + +### Lua Example +`obj_set_face_angle(obj, pitch, yaw, roll)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| pitch | `integer` | +| yaw | `integer` | +| roll | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_face_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_gfx_angle](#obj_set_gfx_angle) + +### Lua Example +`obj_set_gfx_angle(obj, pitch, yaw, roll)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| pitch | `integer` | +| yaw | `integer` | +| roll | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_gfx_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_gfx_pos](#obj_set_gfx_pos) + +### Lua Example +`obj_set_gfx_pos(obj, x, y, z)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| x | `number` | +| y | `number` | +| z | `number` | + +### Returns +- None + +### C Prototype +`void obj_set_gfx_pos(struct Object *obj, f32 x, f32 y, f32 z);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_gfx_scale](#obj_set_gfx_scale) + +### Lua Example +`obj_set_gfx_scale(obj, x, y, z)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| x | `number` | +| y | `number` | +| z | `number` | + +### Returns +- None + +### C Prototype +`void obj_set_gfx_scale(struct Object *obj, f32 x, f32 y, f32 z);` + +[:arrow_up_small:](#) + +
+ +## [spawn_water_droplet](#spawn_water_droplet) + +### Lua Example +`local ObjectValue = spawn_water_droplet(parent, params)` + +### Parameters +| Field | Type | +| ----- | ---- | +| parent | [Object](structs.md#Object) | +| params | [WaterDropletParams](structs.md#WaterDropletParams) | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *spawn_water_droplet(struct Object *parent, struct WaterDropletParams *params);` + +[:arrow_up_small:](#) + +
+ +## [obj_build_relative_transform](#obj_build_relative_transform) + +### Lua Example +`obj_build_relative_transform(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_build_relative_transform(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_using_vel](#cur_obj_move_using_vel) + +### Lua Example +`cur_obj_move_using_vel()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_move_using_vel(void);` + +[:arrow_up_small:](#) + +
+ +## [obj_copy_graph_y_offset](#obj_copy_graph_y_offset) + +### Lua Example +`obj_copy_graph_y_offset(dst, src)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dst | [Object](structs.md#Object) | +| src | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_copy_graph_y_offset(struct Object *dst, struct Object *src);` + +[:arrow_up_small:](#) + +
+ +## [obj_copy_pos_and_angle](#obj_copy_pos_and_angle) + +### Lua Example +`obj_copy_pos_and_angle(dst, src)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dst | [Object](structs.md#Object) | +| src | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_copy_pos_and_angle(struct Object *dst, struct Object *src);` + +[:arrow_up_small:](#) + +
+ +## [obj_copy_pos](#obj_copy_pos) + +### Lua Example +`obj_copy_pos(dst, src)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dst | [Object](structs.md#Object) | +| src | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_copy_pos(struct Object *dst, struct Object *src);` + +[:arrow_up_small:](#) + +
+ +## [obj_copy_angle](#obj_copy_angle) + +### Lua Example +`obj_copy_angle(dst, src)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dst | [Object](structs.md#Object) | +| src | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_copy_angle(struct Object *dst, struct Object *src);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_gfx_pos_from_pos](#obj_set_gfx_pos_from_pos) + +### Lua Example +`obj_set_gfx_pos_from_pos(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_set_gfx_pos_from_pos(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [obj_init_animation](#obj_init_animation) + +### Lua Example +`obj_init_animation(obj, animIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| animIndex | `integer` | + +### Returns +- None + +### C Prototype +`void obj_init_animation(struct Object *obj, s32 animIndex);` + +[:arrow_up_small:](#) + +
+ +## [linear_mtxf_mul_vec3f](#linear_mtxf_mul_vec3f) + +### Description +Multiplies a vector by a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ? ? 0 |` `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space + +### Lua Example +`linear_mtxf_mul_vec3f(m, dst, v)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [Mat4](structs.md#Mat4) | +| dst | [Vec3f](structs.md#Vec3f) | +| v | [Vec3f](structs.md#Vec3f) | + +### Returns +- None + +### C Prototype +`void linear_mtxf_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v);` + +[:arrow_up_small:](#) + +
+ +## [linear_mtxf_transpose_mul_vec3f](#linear_mtxf_transpose_mul_vec3f) + +### Description +Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ? ? 0 |` `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space + +### Lua Example +`linear_mtxf_transpose_mul_vec3f(m, dst, v)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [Mat4](structs.md#Mat4) | +| dst | [Vec3f](structs.md#Vec3f) | +| v | [Vec3f](structs.md#Vec3f) | + +### Returns +- None + +### C Prototype +`void linear_mtxf_transpose_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v);` + +[:arrow_up_small:](#) + +
+ +## [obj_apply_scale_to_transform](#obj_apply_scale_to_transform) + +### Lua Example +`obj_apply_scale_to_transform(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_apply_scale_to_transform(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [obj_copy_scale](#obj_copy_scale) + +### Lua Example +`obj_copy_scale(dst, src)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dst | [Object](structs.md#Object) | +| src | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_copy_scale(struct Object *dst, struct Object *src);` + +[:arrow_up_small:](#) + +
+ +## [obj_scale_xyz](#obj_scale_xyz) + +### Lua Example +`obj_scale_xyz(obj, xScale, yScale, zScale)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| xScale | `number` | +| yScale | `number` | +| zScale | `number` | + +### Returns +- None + +### C Prototype +`void obj_scale_xyz(struct Object *obj, f32 xScale, f32 yScale, f32 zScale);` + +[:arrow_up_small:](#) + +
+ +## [obj_scale](#obj_scale) + +### Lua Example +`obj_scale(obj, scale)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| scale | `number` | + +### Returns +- None + +### C Prototype +`void obj_scale(struct Object *obj, f32 scale);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_scale](#cur_obj_scale) + +### Lua Example +`cur_obj_scale(scale)` + +### Parameters +| Field | Type | +| ----- | ---- | +| scale | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_scale(f32 scale);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_init_animation](#cur_obj_init_animation) + +### Lua Example +`cur_obj_init_animation(animIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| animIndex | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_init_animation(s32 animIndex);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_init_animation_with_sound](#cur_obj_init_animation_with_sound) + +### Lua Example +`cur_obj_init_animation_with_sound(animIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| animIndex | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_init_animation_with_sound(s32 animIndex);` + +[:arrow_up_small:](#) + +
+ +## [obj_init_animation_with_accel_and_sound](#obj_init_animation_with_accel_and_sound) + +### Lua Example +`obj_init_animation_with_accel_and_sound(obj, animIndex, accel)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| animIndex | `integer` | +| accel | `number` | + +### Returns +- None + +### C Prototype +`void obj_init_animation_with_accel_and_sound(struct Object *obj, s32 animIndex, f32 accel);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_init_animation_with_accel_and_sound](#cur_obj_init_animation_with_accel_and_sound) + +### Lua Example +`cur_obj_init_animation_with_accel_and_sound(animIndex, accel)` + +### Parameters +| Field | Type | +| ----- | ---- | +| animIndex | `integer` | +| accel | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_init_animation_with_accel_and_sound(s32 animIndex, f32 accel);` + +[:arrow_up_small:](#) + +
+ +## [obj_init_animation_with_sound](#obj_init_animation_with_sound) + +### Lua Example +`obj_init_animation_with_sound(obj, animations, animIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| animations | [AnimationTable](structs.md#AnimationTable) | +| animIndex | `integer` | + +### Returns +- None + +### C Prototype +`void obj_init_animation_with_sound(struct Object *obj, const struct AnimationTable* animations, s32 animIndex);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_enable_rendering_and_become_tangible](#cur_obj_enable_rendering_and_become_tangible) + +### Lua Example +`cur_obj_enable_rendering_and_become_tangible(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void cur_obj_enable_rendering_and_become_tangible(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_enable_rendering](#cur_obj_enable_rendering) + +### Lua Example +`cur_obj_enable_rendering()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_enable_rendering(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_disable_rendering_and_become_intangible](#cur_obj_disable_rendering_and_become_intangible) + +### Lua Example +`cur_obj_disable_rendering_and_become_intangible(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void cur_obj_disable_rendering_and_become_intangible(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_disable_rendering](#cur_obj_disable_rendering) + +### Lua Example +`cur_obj_disable_rendering()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_disable_rendering(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_unhide](#cur_obj_unhide) + +### Lua Example +`cur_obj_unhide()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_unhide(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_hide](#cur_obj_hide) + +### Lua Example +`cur_obj_hide()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_hide(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_pos_relative](#cur_obj_set_pos_relative) + +### Lua Example +`cur_obj_set_pos_relative(other, dleft, dy, dforward)` + +### Parameters +| Field | Type | +| ----- | ---- | +| other | [Object](structs.md#Object) | +| dleft | `number` | +| dy | `number` | +| dforward | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_set_pos_relative(struct Object *other, f32 dleft, f32 dy, f32 dforward);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_pos_relative_to_parent](#cur_obj_set_pos_relative_to_parent) + +### Lua Example +`cur_obj_set_pos_relative_to_parent(dleft, dy, dforward)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dleft | `number` | +| dy | `number` | +| dforward | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_set_pos_relative_to_parent(f32 dleft, f32 dy, f32 dforward);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_enable_rendering_2](#cur_obj_enable_rendering_2) + +### Lua Example +`cur_obj_enable_rendering_2()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_enable_rendering_2(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_unused_init_on_floor](#cur_obj_unused_init_on_floor) + +### Lua Example +`cur_obj_unused_init_on_floor()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_unused_init_on_floor(void);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_face_angle_to_move_angle](#obj_set_face_angle_to_move_angle) + +### Lua Example +`obj_set_face_angle_to_move_angle(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_set_face_angle_to_move_angle(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [get_object_list_from_behavior](#get_object_list_from_behavior) + +### Lua Example +`local integerValue = get_object_list_from_behavior(behavior)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behavior | `Pointer` <`BehaviorScript`> | + +### Returns +- `integer` + +### C Prototype +`u32 get_object_list_from_behavior(const BehaviorScript *behavior);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_nearest_object_with_behavior](#cur_obj_nearest_object_with_behavior) + +### Lua Example +`local ObjectValue = cur_obj_nearest_object_with_behavior(behavior)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behavior | `Pointer` <`BehaviorScript`> | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *cur_obj_nearest_object_with_behavior(const BehaviorScript *behavior);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_dist_to_nearest_object_with_behavior](#cur_obj_dist_to_nearest_object_with_behavior) + +### Lua Example +`local numberValue = cur_obj_dist_to_nearest_object_with_behavior(behavior)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behavior | `Pointer` <`BehaviorScript`> | + +### Returns +- `number` + +### C Prototype +`f32 cur_obj_dist_to_nearest_object_with_behavior(const BehaviorScript *behavior);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_find_nearest_pole](#cur_obj_find_nearest_pole) + +### Lua Example +`local ObjectValue = cur_obj_find_nearest_pole()` + +### Parameters +- None + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object* cur_obj_find_nearest_pole(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_find_nearest_object_with_behavior](#cur_obj_find_nearest_object_with_behavior) + +### Lua Example +`local ObjectValue = cur_obj_find_nearest_object_with_behavior(behavior, dist)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behavior | `Pointer` <`BehaviorScript`> | +| dist | `Pointer` <`number`> | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, f32 *dist);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_count_objects_with_behavior](#cur_obj_count_objects_with_behavior) + +### Lua Example +`local integerValue = cur_obj_count_objects_with_behavior(behavior, dist)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behavior | `Pointer` <`BehaviorScript`> | +| dist | `number` | + +### Returns +- `integer` + +### C Prototype +`u16 cur_obj_count_objects_with_behavior(const BehaviorScript* behavior, f32 dist);` + +[:arrow_up_small:](#) + +
+ +## [find_unimportant_object](#find_unimportant_object) + +### Lua Example +`local ObjectValue = find_unimportant_object()` + +### Parameters +- None + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *find_unimportant_object(void);` + +[:arrow_up_small:](#) + +
+ +## [count_unimportant_objects](#count_unimportant_objects) + +### Lua Example +`local integerValue = count_unimportant_objects()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 count_unimportant_objects(void);` + +[:arrow_up_small:](#) + +
+ +## [count_objects_with_behavior](#count_objects_with_behavior) + +### Lua Example +`local integerValue = count_objects_with_behavior(behavior)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behavior | `Pointer` <`BehaviorScript`> | + +### Returns +- `integer` + +### C Prototype +`s32 count_objects_with_behavior(const BehaviorScript *behavior);` + +[:arrow_up_small:](#) + +
+ +## [find_object_with_behavior](#find_object_with_behavior) + +### Lua Example +`local ObjectValue = find_object_with_behavior(behavior)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behavior | `Pointer` <`BehaviorScript`> | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *find_object_with_behavior(const BehaviorScript *behavior);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_find_nearby_held_actor](#cur_obj_find_nearby_held_actor) + +### Lua Example +`local ObjectValue = cur_obj_find_nearby_held_actor(behavior, maxDist)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behavior | `Pointer` <`BehaviorScript`> | +| maxDist | `number` | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *cur_obj_find_nearby_held_actor(const BehaviorScript *behavior, f32 maxDist);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_reset_timer_and_subaction](#cur_obj_reset_timer_and_subaction) + +### Lua Example +`cur_obj_reset_timer_and_subaction()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_reset_timer_and_subaction(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_change_action](#cur_obj_change_action) + +### Lua Example +`cur_obj_change_action(action)` + +### Parameters +| Field | Type | +| ----- | ---- | +| action | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_change_action(s32 action);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_vel_from_mario_vel](#cur_obj_set_vel_from_mario_vel) + +### Lua Example +`cur_obj_set_vel_from_mario_vel(m, f12, f14)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| f12 | `number` | +| f14 | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_set_vel_from_mario_vel(struct MarioState* m, f32 f12, f32 f14);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_reverse_animation](#cur_obj_reverse_animation) + +### Lua Example +`cur_obj_reverse_animation()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_reverse_animation(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_extend_animation_if_at_end](#cur_obj_extend_animation_if_at_end) + +### Lua Example +`cur_obj_extend_animation_if_at_end()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_extend_animation_if_at_end(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_check_if_near_animation_end](#cur_obj_check_if_near_animation_end) + +### Lua Example +`local integerValue = cur_obj_check_if_near_animation_end()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_check_if_near_animation_end(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_check_if_at_animation_end](#cur_obj_check_if_at_animation_end) + +### Lua Example +`local integerValue = cur_obj_check_if_at_animation_end()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_check_if_at_animation_end(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_check_anim_frame](#cur_obj_check_anim_frame) + +### Lua Example +`local integerValue = cur_obj_check_anim_frame(frame)` + +### Parameters +| Field | Type | +| ----- | ---- | +| frame | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_check_anim_frame(s32 frame);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_check_anim_frame_in_range](#cur_obj_check_anim_frame_in_range) + +### Lua Example +`local integerValue = cur_obj_check_anim_frame_in_range(startFrame, rangeLength)` + +### Parameters +| Field | Type | +| ----- | ---- | +| startFrame | `integer` | +| rangeLength | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_check_anim_frame_in_range(s32 startFrame, s32 rangeLength);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_check_frame_prior_current_frame](#cur_obj_check_frame_prior_current_frame) + +### Lua Example +`local integerValue = cur_obj_check_frame_prior_current_frame(a0)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a0 | `Pointer` <`integer`> | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_check_frame_prior_current_frame(s16 *a0);` + +[:arrow_up_small:](#) + +
+ +## [mario_is_in_air_action](#mario_is_in_air_action) + +### Lua Example +`local integerValue = mario_is_in_air_action(m)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | + +### Returns +- `integer` + +### C Prototype +`s32 mario_is_in_air_action(struct MarioState* m);` + +[:arrow_up_small:](#) + +
+ +## [mario_is_dive_sliding](#mario_is_dive_sliding) + +### Lua Example +`local integerValue = mario_is_dive_sliding(m)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | + +### Returns +- `integer` + +### C Prototype +`s32 mario_is_dive_sliding(struct MarioState* m);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_y_vel_and_animation](#cur_obj_set_y_vel_and_animation) + +### Lua Example +`cur_obj_set_y_vel_and_animation(sp18, sp1C)` + +### Parameters +| Field | Type | +| ----- | ---- | +| sp18 | `number` | +| sp1C | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_set_y_vel_and_animation(f32 sp18, s32 sp1C);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_unrender_and_reset_state](#cur_obj_unrender_and_reset_state) + +### Lua Example +`cur_obj_unrender_and_reset_state(sp18, sp1C)` + +### Parameters +| Field | Type | +| ----- | ---- | +| sp18 | `integer` | +| sp1C | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_unrender_and_reset_state(s32 sp18, s32 sp1C);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_after_thrown_or_dropped](#cur_obj_move_after_thrown_or_dropped) + +### Lua Example +`cur_obj_move_after_thrown_or_dropped(forwardVel, velY)` + +### Parameters +| Field | Type | +| ----- | ---- | +| forwardVel | `number` | +| velY | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_move_after_thrown_or_dropped(f32 forwardVel, f32 velY);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_get_thrown_or_placed](#cur_obj_get_thrown_or_placed) + +### Lua Example +`cur_obj_get_thrown_or_placed(forwardVel, velY, thrownAction)` + +### Parameters +| Field | Type | +| ----- | ---- | +| forwardVel | `number` | +| velY | `number` | +| thrownAction | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_get_thrown_or_placed(f32 forwardVel, f32 velY, s32 thrownAction);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_get_dropped](#cur_obj_get_dropped) + +### Lua Example +`cur_obj_get_dropped()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_get_dropped(void);` + +[:arrow_up_small:](#) + +
+ +## [mario_set_flag](#mario_set_flag) + +### Lua Example +`mario_set_flag(flag)` + +### Parameters +| Field | Type | +| ----- | ---- | +| flag | `integer` | + +### Returns +- None + +### C Prototype +`void mario_set_flag(s32 flag);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_clear_interact_status_flag](#cur_obj_clear_interact_status_flag) + +### Lua Example +`local integerValue = cur_obj_clear_interact_status_flag(flag)` + +### Parameters +| Field | Type | +| ----- | ---- | +| flag | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_clear_interact_status_flag(s32 flag);` + +[:arrow_up_small:](#) + +
+ +## [obj_mark_for_deletion](#obj_mark_for_deletion) + +### Description +Marks an object to be unloaded at the end of the frame + +### Lua Example +`obj_mark_for_deletion(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_mark_for_deletion(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_disable](#cur_obj_disable) + +### Lua Example +`cur_obj_disable()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_disable(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_become_intangible](#cur_obj_become_intangible) + +### Lua Example +`cur_obj_become_intangible()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_become_intangible(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_become_tangible](#cur_obj_become_tangible) + +### Lua Example +`cur_obj_become_tangible()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_become_tangible(void);` + +[:arrow_up_small:](#) + +
+ +## [obj_become_tangible](#obj_become_tangible) + +### Lua Example +`obj_become_tangible(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_become_tangible(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_update_floor_height](#cur_obj_update_floor_height) + +### Lua Example +`cur_obj_update_floor_height()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_update_floor_height(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_update_floor_height_and_get_floor](#cur_obj_update_floor_height_and_get_floor) + +### Lua Example +`local SurfaceValue = cur_obj_update_floor_height_and_get_floor()` + +### Parameters +- None + +### Returns +[Surface](structs.md#Surface) + +### C Prototype +`struct Surface *cur_obj_update_floor_height_and_get_floor(void);` + +[:arrow_up_small:](#) + +
+ +## [apply_drag_to_value](#apply_drag_to_value) + +### Lua Example +`apply_drag_to_value(value, dragStrength)` + +### Parameters +| Field | Type | +| ----- | ---- | +| value | `Pointer` <`number`> | +| dragStrength | `number` | + +### Returns +- None + +### C Prototype +`void apply_drag_to_value(f32 *value, f32 dragStrength);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_apply_drag_xz](#cur_obj_apply_drag_xz) + +### Lua Example +`cur_obj_apply_drag_xz(dragStrength)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dragStrength | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_apply_drag_xz(f32 dragStrength);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_xz](#cur_obj_move_xz) + +### Lua Example +`local integerValue = cur_obj_move_xz(steepSlopeNormalY, careAboutEdgesAndSteepSlopes)` + +### Parameters +| Field | Type | +| ----- | ---- | +| steepSlopeNormalY | `number` | +| careAboutEdgesAndSteepSlopes | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_move_xz(f32 steepSlopeNormalY, s32 careAboutEdgesAndSteepSlopes);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_update_underwater_flags](#cur_obj_move_update_underwater_flags) + +### Lua Example +`cur_obj_move_update_underwater_flags()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_move_update_underwater_flags(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_update_ground_air_flags](#cur_obj_move_update_ground_air_flags) + +### Lua Example +`cur_obj_move_update_ground_air_flags(gravity, bounciness)` + +### Parameters +| Field | Type | +| ----- | ---- | +| gravity | `number` | +| bounciness | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_move_update_ground_air_flags(UNUSED f32 gravity, f32 bounciness);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_y_and_get_water_level](#cur_obj_move_y_and_get_water_level) + +### Lua Example +`local numberValue = cur_obj_move_y_and_get_water_level(gravity, buoyancy)` + +### Parameters +| Field | Type | +| ----- | ---- | +| gravity | `number` | +| buoyancy | `number` | + +### Returns +- `number` + +### C Prototype +`f32 cur_obj_move_y_and_get_water_level(f32 gravity, f32 buoyancy);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_y](#cur_obj_move_y) + +### Lua Example +`cur_obj_move_y(gravity, bounciness, buoyancy)` + +### Parameters +| Field | Type | +| ----- | ---- | +| gravity | `number` | +| bounciness | `number` | +| buoyancy | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_move_y(f32 gravity, f32 bounciness, f32 buoyancy);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_unused_resolve_wall_collisions](#cur_obj_unused_resolve_wall_collisions) + +### Lua Example +`cur_obj_unused_resolve_wall_collisions(offsetY, radius)` + +### Parameters +| Field | Type | +| ----- | ---- | +| offsetY | `number` | +| radius | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_unused_resolve_wall_collisions(f32 offsetY, f32 radius);` + +[:arrow_up_small:](#) + +
+ +## [abs_angle_diff](#abs_angle_diff) + +### Lua Example +`local integerValue = abs_angle_diff(x0, x1)` + +### Parameters +| Field | Type | +| ----- | ---- | +| x0 | `integer` | +| x1 | `integer` | + +### Returns +- `integer` + +### C Prototype +`s16 abs_angle_diff(s16 x0, s16 x1);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_xz_using_fvel_and_yaw](#cur_obj_move_xz_using_fvel_and_yaw) + +### Lua Example +`cur_obj_move_xz_using_fvel_and_yaw()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_move_xz_using_fvel_and_yaw(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_y_with_terminal_vel](#cur_obj_move_y_with_terminal_vel) + +### Lua Example +`cur_obj_move_y_with_terminal_vel()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_move_y_with_terminal_vel(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_compute_vel_xz](#cur_obj_compute_vel_xz) + +### Lua Example +`cur_obj_compute_vel_xz()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_compute_vel_xz(void);` + +[:arrow_up_small:](#) + +
+ +## [increment_velocity_toward_range](#increment_velocity_toward_range) + +### Lua Example +`local numberValue = increment_velocity_toward_range(value, center, zeroThreshold, increment)` + +### Parameters +| Field | Type | +| ----- | ---- | +| value | `number` | +| center | `number` | +| zeroThreshold | `number` | +| increment | `number` | + +### Returns +- `number` + +### C Prototype +`f32 increment_velocity_toward_range(f32 value, f32 center, f32 zeroThreshold, f32 increment);` + +[:arrow_up_small:](#) + +
+ +## [obj_check_if_collided_with_object](#obj_check_if_collided_with_object) + +### Lua Example +`local integerValue = obj_check_if_collided_with_object(obj1, obj2)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj1 | [Object](structs.md#Object) | +| obj2 | [Object](structs.md#Object) | + +### Returns +- `integer` + +### C Prototype +`s32 obj_check_if_collided_with_object(struct Object *obj1, struct Object *obj2);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_behavior](#cur_obj_set_behavior) + +### Lua Example +`cur_obj_set_behavior(behavior)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behavior | `Pointer` <`BehaviorScript`> | + +### Returns +- None + +### C Prototype +`void cur_obj_set_behavior(const BehaviorScript *behavior);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_behavior](#obj_set_behavior) + +### Lua Example +`obj_set_behavior(obj, behavior)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| behavior | `Pointer` <`BehaviorScript`> | + +### Returns +- None + +### C Prototype +`void obj_set_behavior(struct Object *obj, const BehaviorScript *behavior);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_has_behavior](#cur_obj_has_behavior) + +### Lua Example +`local integerValue = cur_obj_has_behavior(behavior)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behavior | `Pointer` <`BehaviorScript`> | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_has_behavior(const BehaviorScript *behavior);` + +[:arrow_up_small:](#) + +
+ +## [obj_has_behavior](#obj_has_behavior) + +### Lua Example +`local integerValue = obj_has_behavior(obj, behavior)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| behavior | `Pointer` <`BehaviorScript`> | + +### Returns +- `integer` + +### C Prototype +`s32 obj_has_behavior(struct Object *obj, const BehaviorScript *behavior);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_lateral_dist_from_obj_to_home](#cur_obj_lateral_dist_from_obj_to_home) + +### Lua Example +`local numberValue = cur_obj_lateral_dist_from_obj_to_home(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- `number` + +### C Prototype +`f32 cur_obj_lateral_dist_from_obj_to_home(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_lateral_dist_from_mario_to_home](#cur_obj_lateral_dist_from_mario_to_home) + +### Lua Example +`local numberValue = cur_obj_lateral_dist_from_mario_to_home()` + +### Parameters +- None + +### Returns +- `number` + +### C Prototype +`f32 cur_obj_lateral_dist_from_mario_to_home(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_lateral_dist_to_home](#cur_obj_lateral_dist_to_home) + +### Lua Example +`local numberValue = cur_obj_lateral_dist_to_home()` + +### Parameters +- None + +### Returns +- `number` + +### C Prototype +`f32 cur_obj_lateral_dist_to_home(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_outside_home_square](#cur_obj_outside_home_square) + +### Lua Example +`local integerValue = cur_obj_outside_home_square(halfLength)` + +### Parameters +| Field | Type | +| ----- | ---- | +| halfLength | `number` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_outside_home_square(f32 halfLength);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_outside_home_rectangle](#cur_obj_outside_home_rectangle) + +### Lua Example +`local integerValue = cur_obj_outside_home_rectangle(minX, maxX, minZ, maxZ)` + +### Parameters +| Field | Type | +| ----- | ---- | +| minX | `number` | +| maxX | `number` | +| minZ | `number` | +| maxZ | `number` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_outside_home_rectangle(f32 minX, f32 maxX, f32 minZ, f32 maxZ);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_pos_to_home](#cur_obj_set_pos_to_home) + +### Lua Example +`cur_obj_set_pos_to_home()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_set_pos_to_home(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_pos_to_home_and_stop](#cur_obj_set_pos_to_home_and_stop) + +### Lua Example +`cur_obj_set_pos_to_home_and_stop()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_set_pos_to_home_and_stop(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_shake_y](#cur_obj_shake_y) + +### Lua Example +`cur_obj_shake_y(amount)` + +### Parameters +| Field | Type | +| ----- | ---- | +| amount | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_shake_y(f32 amount);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_start_cam_event](#cur_obj_start_cam_event) + +### Lua Example +`cur_obj_start_cam_event(obj, cameraEvent)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| cameraEvent | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_start_cam_event(UNUSED struct Object *obj, s32 cameraEvent);` + +[:arrow_up_small:](#) + +
+ +## [set_mario_interact_hoot_if_in_range](#set_mario_interact_hoot_if_in_range) + +### Lua Example +`set_mario_interact_hoot_if_in_range(sp0, sp4, sp8)` + +### Parameters +| Field | Type | +| ----- | ---- | +| sp0 | `integer` | +| sp4 | `integer` | +| sp8 | `number` | + +### Returns +- None + +### C Prototype +`void set_mario_interact_hoot_if_in_range(UNUSED s32 sp0, UNUSED s32 sp4, f32 sp8);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_billboard](#obj_set_billboard) + +### Lua Example +`obj_set_billboard(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_set_billboard(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_cylboard](#obj_set_cylboard) + +### Lua Example +`obj_set_cylboard(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_set_cylboard(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_billboard_if_vanilla_cam](#cur_obj_set_billboard_if_vanilla_cam) + +### Lua Example +`cur_obj_set_billboard_if_vanilla_cam()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_set_billboard_if_vanilla_cam(void);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_hitbox_radius_and_height](#obj_set_hitbox_radius_and_height) + +### Lua Example +`obj_set_hitbox_radius_and_height(o, radius, height)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| radius | `number` | +| height | `number` | + +### Returns +- None + +### C Prototype +`void obj_set_hitbox_radius_and_height(struct Object *o, f32 radius, f32 height);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_hurtbox_radius_and_height](#obj_set_hurtbox_radius_and_height) + +### Lua Example +`obj_set_hurtbox_radius_and_height(o, radius, height)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| radius | `number` | +| height | `number` | + +### Returns +- None + +### C Prototype +`void obj_set_hurtbox_radius_and_height(struct Object *o, f32 radius, f32 height);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_hitbox_radius_and_height](#cur_obj_set_hitbox_radius_and_height) + +### Lua Example +`cur_obj_set_hitbox_radius_and_height(radius, height)` + +### Parameters +| Field | Type | +| ----- | ---- | +| radius | `number` | +| height | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_set_hitbox_radius_and_height(f32 radius, f32 height);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_hurtbox_radius_and_height](#cur_obj_set_hurtbox_radius_and_height) + +### Lua Example +`cur_obj_set_hurtbox_radius_and_height(radius, height)` + +### Parameters +| Field | Type | +| ----- | ---- | +| radius | `number` | +| height | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_set_hurtbox_radius_and_height(f32 radius, f32 height);` + +[:arrow_up_small:](#) + +
+ +## [obj_spawn_loot_coins](#obj_spawn_loot_coins) + +### Lua Example +`obj_spawn_loot_coins(obj, numCoins, sp30, coinBehavior, posJitter, model)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| numCoins | `integer` | +| sp30 | `number` | +| coinBehavior | `Pointer` <`BehaviorScript`> | +| posJitter | `integer` | +| model | `integer` | + +### Returns +- None + +### C Prototype +`void obj_spawn_loot_coins(struct Object *obj, s32 numCoins, f32 sp30, const BehaviorScript *coinBehavior, s16 posJitter, s16 model);` + +[:arrow_up_small:](#) + +
+ +## [obj_spawn_loot_blue_coins](#obj_spawn_loot_blue_coins) + +### Lua Example +`obj_spawn_loot_blue_coins(obj, numCoins, sp28, posJitter)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| numCoins | `integer` | +| sp28 | `number` | +| posJitter | `integer` | + +### Returns +- None + +### C Prototype +`void obj_spawn_loot_blue_coins(struct Object *obj, s32 numCoins, f32 sp28, s16 posJitter);` + +[:arrow_up_small:](#) + +
+ +## [obj_spawn_loot_yellow_coins](#obj_spawn_loot_yellow_coins) + +### Lua Example +`obj_spawn_loot_yellow_coins(obj, numCoins, sp28)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| numCoins | `integer` | +| sp28 | `number` | + +### Returns +- None + +### C Prototype +`void obj_spawn_loot_yellow_coins(struct Object *obj, s32 numCoins, f32 sp28);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_spawn_loot_coin_at_mario_pos](#cur_obj_spawn_loot_coin_at_mario_pos) + +### Lua Example +`cur_obj_spawn_loot_coin_at_mario_pos(m)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | + +### Returns +- None + +### C Prototype +`void cur_obj_spawn_loot_coin_at_mario_pos(struct MarioState* m);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_abs_y_dist_to_home](#cur_obj_abs_y_dist_to_home) + +### Lua Example +`local numberValue = cur_obj_abs_y_dist_to_home()` + +### Parameters +- None + +### Returns +- `number` + +### C Prototype +`f32 cur_obj_abs_y_dist_to_home(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_advance_looping_anim](#cur_obj_advance_looping_anim) + +### Lua Example +`local integerValue = cur_obj_advance_looping_anim()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_advance_looping_anim(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_detect_steep_floor](#cur_obj_detect_steep_floor) + +### Lua Example +`local integerValue = cur_obj_detect_steep_floor(steepAngleDegrees)` + +### Parameters +| Field | Type | +| ----- | ---- | +| steepAngleDegrees | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_detect_steep_floor(s16 steepAngleDegrees);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_resolve_wall_collisions](#cur_obj_resolve_wall_collisions) + +### Lua Example +`local integerValue = cur_obj_resolve_wall_collisions()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_resolve_wall_collisions(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_update_floor](#cur_obj_update_floor) + +### Lua Example +`cur_obj_update_floor()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_update_floor(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_update_floor_and_resolve_wall_collisions](#cur_obj_update_floor_and_resolve_wall_collisions) + +### Lua Example +`cur_obj_update_floor_and_resolve_wall_collisions(steepSlopeDegrees)` + +### Parameters +| Field | Type | +| ----- | ---- | +| steepSlopeDegrees | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_update_floor_and_resolve_wall_collisions(s16 steepSlopeDegrees);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_update_floor_and_walls](#cur_obj_update_floor_and_walls) + +### Lua Example +`cur_obj_update_floor_and_walls()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_update_floor_and_walls(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_standard](#cur_obj_move_standard) + +### Lua Example +`cur_obj_move_standard(steepSlopeAngleDegrees)` + +### Parameters +| Field | Type | +| ----- | ---- | +| steepSlopeAngleDegrees | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_move_standard(s16 steepSlopeAngleDegrees);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_within_12k_bounds](#cur_obj_within_12k_bounds) + +### Lua Example +`local integerValue = cur_obj_within_12k_bounds()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_within_12k_bounds(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_using_vel_and_gravity](#cur_obj_move_using_vel_and_gravity) + +### Lua Example +`cur_obj_move_using_vel_and_gravity()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_move_using_vel_and_gravity(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_using_fvel_and_gravity](#cur_obj_move_using_fvel_and_gravity) + +### Lua Example +`cur_obj_move_using_fvel_and_gravity()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_move_using_fvel_and_gravity(void);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_pos_relative](#obj_set_pos_relative) + +### Lua Example +`obj_set_pos_relative(obj, other, dleft, dy, dforward)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| other | [Object](structs.md#Object) | +| dleft | `number` | +| dy | `number` | +| dforward | `number` | + +### Returns +- None + +### C Prototype +`void obj_set_pos_relative(struct Object *obj, struct Object *other, f32 dleft, f32 dy, f32 dforward);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_angle_to_home](#cur_obj_angle_to_home) + +### Lua Example +`local integerValue = cur_obj_angle_to_home()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s16 cur_obj_angle_to_home(void);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_gfx_pos_at_obj_pos](#obj_set_gfx_pos_at_obj_pos) + +### Lua Example +`obj_set_gfx_pos_at_obj_pos(obj1, obj2)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj1 | [Object](structs.md#Object) | +| obj2 | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_set_gfx_pos_at_obj_pos(struct Object *obj1, struct Object *obj2);` + +[:arrow_up_small:](#) + +
+ +## [obj_translate_local](#obj_translate_local) + +### Description +Transforms the vector at `localTranslateIndex` into the object's local coordinates, and then adds it to the vector at `posIndex` + +### Lua Example +`obj_translate_local(obj, posIndex, localTranslateIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| posIndex | `integer` | +| localTranslateIndex | `integer` | + +### Returns +- None + +### C Prototype +`void obj_translate_local(struct Object *obj, s16 posIndex, s16 localTranslateIndex);` + +[:arrow_up_small:](#) + +
+ +## [obj_build_transform_from_pos_and_angle](#obj_build_transform_from_pos_and_angle) + +### Lua Example +`obj_build_transform_from_pos_and_angle(obj, posIndex, angleIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| posIndex | `integer` | +| angleIndex | `integer` | + +### Returns +- None + +### C Prototype +`void obj_build_transform_from_pos_and_angle(struct Object *obj, s16 posIndex, s16 angleIndex);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_throw_matrix_from_transform](#obj_set_throw_matrix_from_transform) + +### Lua Example +`obj_set_throw_matrix_from_transform(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_set_throw_matrix_from_transform(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [obj_build_transform_relative_to_parent](#obj_build_transform_relative_to_parent) + +### Lua Example +`obj_build_transform_relative_to_parent(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_build_transform_relative_to_parent(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [obj_create_transform_from_self](#obj_create_transform_from_self) + +### Lua Example +`obj_create_transform_from_self(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_create_transform_from_self(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_rotate_move_angle_using_vel](#cur_obj_rotate_move_angle_using_vel) + +### Lua Example +`cur_obj_rotate_move_angle_using_vel()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_rotate_move_angle_using_vel(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_rotate_face_angle_using_vel](#cur_obj_rotate_face_angle_using_vel) + +### Lua Example +`cur_obj_rotate_face_angle_using_vel()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_rotate_face_angle_using_vel(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_face_angle_to_move_angle](#cur_obj_set_face_angle_to_move_angle) + +### Lua Example +`cur_obj_set_face_angle_to_move_angle()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_set_face_angle_to_move_angle(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_follow_path](#cur_obj_follow_path) + +### Lua Example +`local integerValue = cur_obj_follow_path(unusedArg)` + +### Parameters +| Field | Type | +| ----- | ---- | +| unusedArg | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_follow_path(UNUSED s32 unusedArg);` + +[:arrow_up_small:](#) + +
+ +## [chain_segment_init](#chain_segment_init) + +### Lua Example +`chain_segment_init(segment)` + +### Parameters +| Field | Type | +| ----- | ---- | +| segment | [ChainSegment](structs.md#ChainSegment) | + +### Returns +- None + +### C Prototype +`void chain_segment_init(struct ChainSegment *segment);` + +[:arrow_up_small:](#) + +
+ +## [random_f32_around_zero](#random_f32_around_zero) + +### Lua Example +`local numberValue = random_f32_around_zero(diameter)` + +### Parameters +| Field | Type | +| ----- | ---- | +| diameter | `number` | + +### Returns +- `number` + +### C Prototype +`f32 random_f32_around_zero(f32 diameter);` + +[:arrow_up_small:](#) + +
+ +## [obj_scale_random](#obj_scale_random) + +### Lua Example +`obj_scale_random(obj, rangeLength, minScale)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| rangeLength | `number` | +| minScale | `number` | + +### Returns +- None + +### C Prototype +`void obj_scale_random(struct Object *obj, f32 rangeLength, f32 minScale);` + +[:arrow_up_small:](#) + +
+ +## [obj_translate_xyz_random](#obj_translate_xyz_random) + +### Lua Example +`obj_translate_xyz_random(obj, rangeLength)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| rangeLength | `number` | + +### Returns +- None + +### C Prototype +`void obj_translate_xyz_random(struct Object *obj, f32 rangeLength);` + +[:arrow_up_small:](#) + +
+ +## [obj_translate_xz_random](#obj_translate_xz_random) + +### Lua Example +`obj_translate_xz_random(obj, rangeLength)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| rangeLength | `number` | + +### Returns +- None + +### C Prototype +`void obj_translate_xz_random(struct Object *obj, f32 rangeLength);` + +[:arrow_up_small:](#) + +
+ +## [obj_build_vel_from_transform](#obj_build_vel_from_transform) + +### Lua Example +`obj_build_vel_from_transform(a0)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a0 | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_build_vel_from_transform(struct Object *a0);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_pos_via_transform](#cur_obj_set_pos_via_transform) + +### Lua Example +`cur_obj_set_pos_via_transform()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_set_pos_via_transform(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_reflect_move_angle_off_wall](#cur_obj_reflect_move_angle_off_wall) + +### Lua Example +`local integerValue = cur_obj_reflect_move_angle_off_wall()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s16 cur_obj_reflect_move_angle_off_wall(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_spawn_particles](#cur_obj_spawn_particles) + +### Lua Example +`cur_obj_spawn_particles(info)` + +### Parameters +| Field | Type | +| ----- | ---- | +| info | [SpawnParticlesInfo](structs.md#SpawnParticlesInfo) | + +### Returns +- None + +### C Prototype +`void cur_obj_spawn_particles(struct SpawnParticlesInfo *info);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_hitbox](#obj_set_hitbox) + +### Lua Example +`obj_set_hitbox(obj, hitbox)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | +| hitbox | [ObjectHitbox](structs.md#ObjectHitbox) | + +### Returns +- None + +### C Prototype +`void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox);` + +[:arrow_up_small:](#) + +
+ +## [signum_positive](#signum_positive) + +### Lua Example +`local integerValue = signum_positive(x)` + +### Parameters +| Field | Type | +| ----- | ---- | +| x | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 signum_positive(s32 x);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_wait_then_blink](#cur_obj_wait_then_blink) + +### Lua Example +`local integerValue = cur_obj_wait_then_blink(timeUntilBlinking, numBlinks)` + +### Parameters +| Field | Type | +| ----- | ---- | +| timeUntilBlinking | `integer` | +| numBlinks | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_wait_then_blink(s32 timeUntilBlinking, s32 numBlinks);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_is_mario_ground_pounding_platform](#cur_obj_is_mario_ground_pounding_platform) + +### Lua Example +`local integerValue = cur_obj_is_mario_ground_pounding_platform()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_is_mario_ground_pounding_platform(void);` + +[:arrow_up_small:](#) + +
+ +## [obj_is_mario_ground_pounding_platform](#obj_is_mario_ground_pounding_platform) + +### Lua Example +`local integerValue = obj_is_mario_ground_pounding_platform(m, obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| obj | [Object](structs.md#Object) | + +### Returns +- `integer` + +### C Prototype +`s32 obj_is_mario_ground_pounding_platform(struct MarioState *m, struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [spawn_mist_particles](#spawn_mist_particles) + +### Lua Example +`spawn_mist_particles()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void spawn_mist_particles(void);` + +[:arrow_up_small:](#) + +
+ +## [spawn_mist_particles_with_sound](#spawn_mist_particles_with_sound) + +### Lua Example +`spawn_mist_particles_with_sound(sp18)` + +### Parameters +| Field | Type | +| ----- | ---- | +| sp18 | `integer` | + +### Returns +- None + +### C Prototype +`void spawn_mist_particles_with_sound(u32 sp18);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_push_mario_away](#cur_obj_push_mario_away) + +### Lua Example +`cur_obj_push_mario_away(radius)` + +### Parameters +| Field | Type | +| ----- | ---- | +| radius | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_push_mario_away(f32 radius);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_push_mario_away_from_cylinder](#cur_obj_push_mario_away_from_cylinder) + +### Lua Example +`cur_obj_push_mario_away_from_cylinder(radius, extentY)` + +### Parameters +| Field | Type | +| ----- | ---- | +| radius | `number` | +| extentY | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_push_mario_away_from_cylinder(f32 radius, f32 extentY);` + +[:arrow_up_small:](#) + +
+ +## [bhv_dust_smoke_loop](#bhv_dust_smoke_loop) + +### Lua Example +`bhv_dust_smoke_loop()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void bhv_dust_smoke_loop(void);` + +[:arrow_up_small:](#) + +
+ +## [stub_obj_helpers_3](#stub_obj_helpers_3) + +### Lua Example +`stub_obj_helpers_3(sp0, sp4)` + +### Parameters +| Field | Type | +| ----- | ---- | +| sp0 | `integer` | +| sp4 | `integer` | + +### Returns +- None + +### C Prototype +`void stub_obj_helpers_3(UNUSED s32 sp0, UNUSED s32 sp4);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_scale_over_time](#cur_obj_scale_over_time) + +### Lua Example +`cur_obj_scale_over_time(a0, a1, sp10, sp14)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a0 | `integer` | +| a1 | `integer` | +| sp10 | `number` | +| sp14 | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_scale_over_time(s32 a0, s32 a1, f32 sp10, f32 sp14);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_pos_to_home_with_debug](#cur_obj_set_pos_to_home_with_debug) + +### Lua Example +`cur_obj_set_pos_to_home_with_debug()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_set_pos_to_home_with_debug(void);` + +[:arrow_up_small:](#) + +
+ +## [stub_obj_helpers_4](#stub_obj_helpers_4) + +### Lua Example +`stub_obj_helpers_4()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void stub_obj_helpers_4(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_is_mario_on_platform](#cur_obj_is_mario_on_platform) + +### Lua Example +`local integerValue = cur_obj_is_mario_on_platform()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_is_mario_on_platform(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_is_any_player_on_platform](#cur_obj_is_any_player_on_platform) + +### Lua Example +`local integerValue = cur_obj_is_any_player_on_platform()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_is_any_player_on_platform(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_shake_y_until](#cur_obj_shake_y_until) + +### Lua Example +`local integerValue = cur_obj_shake_y_until(cycles, amount)` + +### Parameters +| Field | Type | +| ----- | ---- | +| cycles | `integer` | +| amount | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_shake_y_until(s32 cycles, s32 amount);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_move_up_and_down](#cur_obj_move_up_and_down) + +### Lua Example +`local integerValue = cur_obj_move_up_and_down(a0)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a0 | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_move_up_and_down(s32 a0);` + +[:arrow_up_small:](#) + +
+ +## [spawn_star_with_no_lvl_exit](#spawn_star_with_no_lvl_exit) + +### Lua Example +`local ObjectValue = spawn_star_with_no_lvl_exit(sp20, sp24)` + +### Parameters +| Field | Type | +| ----- | ---- | +| sp20 | `integer` | +| sp24 | `integer` | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *spawn_star_with_no_lvl_exit(s32 sp20, s32 sp24);` + +[:arrow_up_small:](#) + +
+ +## [spawn_base_star_with_no_lvl_exit](#spawn_base_star_with_no_lvl_exit) + +### Lua Example +`spawn_base_star_with_no_lvl_exit()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void spawn_base_star_with_no_lvl_exit(void);` + +[:arrow_up_small:](#) + +
+ +## [bit_shift_left](#bit_shift_left) + +### Lua Example +`local integerValue = bit_shift_left(a0)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a0 | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 bit_shift_left(s32 a0);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_mario_far_away](#cur_obj_mario_far_away) + +### Lua Example +`local integerValue = cur_obj_mario_far_away()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_mario_far_away(void);` + +[:arrow_up_small:](#) + +
+ +## [is_mario_moving_fast_or_in_air](#is_mario_moving_fast_or_in_air) + +### Lua Example +`local integerValue = is_mario_moving_fast_or_in_air(speedThreshold)` + +### Parameters +| Field | Type | +| ----- | ---- | +| speedThreshold | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 is_mario_moving_fast_or_in_air(s32 speedThreshold);` + +[:arrow_up_small:](#) + +
+ +## [is_item_in_array](#is_item_in_array) + +### Lua Example +`local integerValue = is_item_in_array(item, array)` + +### Parameters +| Field | Type | +| ----- | ---- | +| item | `integer` | +| array | `Pointer` <`integer`> | + +### Returns +- `integer` + +### C Prototype +`s32 is_item_in_array(s8 item, s8 *array);` + +[:arrow_up_small:](#) + +
+ +## [bhv_init_room](#bhv_init_room) + +### Lua Example +`bhv_init_room()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void bhv_init_room(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_enable_rendering_if_mario_in_room](#cur_obj_enable_rendering_if_mario_in_room) + +### Lua Example +`cur_obj_enable_rendering_if_mario_in_room()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_enable_rendering_if_mario_in_room(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_hitbox_and_die_if_attacked](#cur_obj_set_hitbox_and_die_if_attacked) + +### Lua Example +`local integerValue = cur_obj_set_hitbox_and_die_if_attacked(hitbox, deathSound, noLootCoins)` + +### Parameters +| Field | Type | +| ----- | ---- | +| hitbox | [ObjectHitbox](structs.md#ObjectHitbox) | +| deathSound | `integer` | +| noLootCoins | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deathSound, s32 noLootCoins);` + +[:arrow_up_small:](#) + +
+ +## [obj_explode_and_spawn_coins](#obj_explode_and_spawn_coins) + +### Lua Example +`obj_explode_and_spawn_coins(sp18, sp1C)` + +### Parameters +| Field | Type | +| ----- | ---- | +| sp18 | `number` | +| sp1C | `integer` | + +### Returns +- None + +### C Prototype +`void obj_explode_and_spawn_coins(f32 sp18, s32 sp1C);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_if_hit_wall_bounce_away](#cur_obj_if_hit_wall_bounce_away) + +### Lua Example +`cur_obj_if_hit_wall_bounce_away()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_if_hit_wall_bounce_away(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_hide_if_mario_far_away_y](#cur_obj_hide_if_mario_far_away_y) + +### Lua Example +`local integerValue = cur_obj_hide_if_mario_far_away_y(distY)` + +### Parameters +| Field | Type | +| ----- | ---- | +| distY | `number` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_hide_if_mario_far_away_y(f32 distY);` + +[:arrow_up_small:](#) + +
+ +## [obj_is_hidden](#obj_is_hidden) + +### Lua Example +`local integerValue = obj_is_hidden(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- `integer` + +### C Prototype +`s32 obj_is_hidden(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [enable_time_stop](#enable_time_stop) + +### Lua Example +`enable_time_stop()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void enable_time_stop(void);` + +[:arrow_up_small:](#) + +
+ +## [enable_time_stop_if_alone](#enable_time_stop_if_alone) + +### Lua Example +`enable_time_stop_if_alone()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void enable_time_stop_if_alone(void);` + +[:arrow_up_small:](#) + +
+ +## [disable_time_stop](#disable_time_stop) + +### Lua Example +`disable_time_stop()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void disable_time_stop(void);` + +[:arrow_up_small:](#) + +
+ +## [set_time_stop_flags](#set_time_stop_flags) + +### Lua Example +`set_time_stop_flags(flags)` + +### Parameters +| Field | Type | +| ----- | ---- | +| flags | `integer` | + +### Returns +- None + +### C Prototype +`void set_time_stop_flags(s32 flags);` + +[:arrow_up_small:](#) + +
+ +## [set_time_stop_flags_if_alone](#set_time_stop_flags_if_alone) + +### Lua Example +`set_time_stop_flags_if_alone(flags)` + +### Parameters +| Field | Type | +| ----- | ---- | +| flags | `integer` | + +### Returns +- None + +### C Prototype +`void set_time_stop_flags_if_alone(s32 flags);` + +[:arrow_up_small:](#) + +
+ +## [clear_time_stop_flags](#clear_time_stop_flags) + +### Lua Example +`clear_time_stop_flags(flags)` + +### Parameters +| Field | Type | +| ----- | ---- | +| flags | `integer` | + +### Returns +- None + +### C Prototype +`void clear_time_stop_flags(s32 flags);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_can_mario_activate_textbox](#cur_obj_can_mario_activate_textbox) + +### Lua Example +`local integerValue = cur_obj_can_mario_activate_textbox(m, radius, height, unused)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| radius | `number` | +| height | `number` | +| unused | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_can_mario_activate_textbox(struct MarioState* m, f32 radius, f32 height, UNUSED s32 unused);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_can_mario_activate_textbox_2](#cur_obj_can_mario_activate_textbox_2) + +### Lua Example +`local integerValue = cur_obj_can_mario_activate_textbox_2(m, radius, height)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| radius | `number` | +| height | `number` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_can_mario_activate_textbox_2(struct MarioState* m, f32 radius, f32 height);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_end_dialog](#cur_obj_end_dialog) + +### Lua Example +`cur_obj_end_dialog(m, dialogFlags, dialogResult)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| dialogFlags | `integer` | +| dialogResult | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_end_dialog(struct MarioState* m, s32 dialogFlags, s32 dialogResult);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_has_model](#cur_obj_has_model) + +### Lua Example +`local integerValue = cur_obj_has_model(modelID)` + +### Parameters +| Field | Type | +| ----- | ---- | +| modelID | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_has_model(u16 modelID);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_align_gfx_with_floor](#cur_obj_align_gfx_with_floor) + +### Lua Example +`cur_obj_align_gfx_with_floor()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_align_gfx_with_floor(void);` + +[:arrow_up_small:](#) + +
+ +## [mario_is_within_rectangle](#mario_is_within_rectangle) + +### Lua Example +`local integerValue = mario_is_within_rectangle(minX, maxX, minZ, maxZ)` + +### Parameters +| Field | Type | +| ----- | ---- | +| minX | `integer` | +| maxX | `integer` | +| minZ | `integer` | +| maxZ | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 mario_is_within_rectangle(s16 minX, s16 maxX, s16 minZ, s16 maxZ);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_shake_screen](#cur_obj_shake_screen) + +### Lua Example +`cur_obj_shake_screen(shake)` + +### Parameters +| Field | Type | +| ----- | ---- | +| shake | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_shake_screen(s32 shake);` + +[:arrow_up_small:](#) + +
+ +## [obj_attack_collided_from_other_object](#obj_attack_collided_from_other_object) + +### Lua Example +`local integerValue = obj_attack_collided_from_other_object(obj)` + +### Parameters +| Field | Type | +| ----- | ---- | +| obj | [Object](structs.md#Object) | + +### Returns +- `integer` + +### C Prototype +`s32 obj_attack_collided_from_other_object(struct Object *obj);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_was_attacked_or_ground_pounded](#cur_obj_was_attacked_or_ground_pounded) + +### Lua Example +`local integerValue = cur_obj_was_attacked_or_ground_pounded()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_was_attacked_or_ground_pounded(void);` + +[:arrow_up_small:](#) + +
+ +## [obj_copy_behavior_params](#obj_copy_behavior_params) + +### Lua Example +`obj_copy_behavior_params(dst, src)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dst | [Object](structs.md#Object) | +| src | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void obj_copy_behavior_params(struct Object *dst, struct Object *src);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_init_animation_and_anim_frame](#cur_obj_init_animation_and_anim_frame) + +### Lua Example +`cur_obj_init_animation_and_anim_frame(animIndex, animFrame)` + +### Parameters +| Field | Type | +| ----- | ---- | +| animIndex | `integer` | +| animFrame | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_init_animation_and_anim_frame(s32 animIndex, s32 animFrame);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_init_animation_and_check_if_near_end](#cur_obj_init_animation_and_check_if_near_end) + +### Lua Example +`local integerValue = cur_obj_init_animation_and_check_if_near_end(animIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| animIndex | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_init_animation_and_check_if_near_end(s32 animIndex);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_init_animation_and_extend_if_at_end](#cur_obj_init_animation_and_extend_if_at_end) + +### Lua Example +`cur_obj_init_animation_and_extend_if_at_end(animIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| animIndex | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_init_animation_and_extend_if_at_end(s32 animIndex);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_check_grabbed_mario](#cur_obj_check_grabbed_mario) + +### Lua Example +`local integerValue = cur_obj_check_grabbed_mario()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_check_grabbed_mario(void);` + +[:arrow_up_small:](#) + +
+ +## [player_performed_grab_escape_action](#player_performed_grab_escape_action) + +### Lua Example +`local integerValue = player_performed_grab_escape_action()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 player_performed_grab_escape_action(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_unused_play_footstep_sound](#cur_obj_unused_play_footstep_sound) + +### Lua Example +`cur_obj_unused_play_footstep_sound(animFrame1, animFrame2, sound)` + +### Parameters +| Field | Type | +| ----- | ---- | +| animFrame1 | `integer` | +| animFrame2 | `integer` | +| sound | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_unused_play_footstep_sound(s32 animFrame1, s32 animFrame2, s32 sound);` + +[:arrow_up_small:](#) + +
+ +## [enable_time_stop_including_mario](#enable_time_stop_including_mario) + +### Lua Example +`enable_time_stop_including_mario()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void enable_time_stop_including_mario(void);` + +[:arrow_up_small:](#) + +
+ +## [disable_time_stop_including_mario](#disable_time_stop_including_mario) + +### Lua Example +`disable_time_stop_including_mario()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void disable_time_stop_including_mario(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_check_interacted](#cur_obj_check_interacted) + +### Lua Example +`local integerValue = cur_obj_check_interacted()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 cur_obj_check_interacted(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_spawn_loot_blue_coin](#cur_obj_spawn_loot_blue_coin) + +### Lua Example +`cur_obj_spawn_loot_blue_coin()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_spawn_loot_blue_coin(void);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_spawn_star_at_y_offset](#cur_obj_spawn_star_at_y_offset) + +### Lua Example +`cur_obj_spawn_star_at_y_offset(targetX, targetY, targetZ, offsetY)` + +### Parameters +| Field | Type | +| ----- | ---- | +| targetX | `number` | +| targetY | `number` | +| targetZ | `number` | +| offsetY | `number` | + +### Returns +- None + +### C Prototype +`void cur_obj_spawn_star_at_y_offset(f32 targetX, f32 targetY, f32 targetZ, f32 offsetY);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_set_home_once](#cur_obj_set_home_once) + +### Description +Sets the current object's home only the first time it's called + +### Lua Example +`cur_obj_set_home_once()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void cur_obj_set_home_once(void);` + +[:arrow_up_small:](#) + +
+ +## [get_trajectory_length](#get_trajectory_length) + +### Description +Gets a trajectory's length + +### Lua Example +`local integerValue = get_trajectory_length(trajectory)` + +### Parameters +| Field | Type | +| ----- | ---- | +| trajectory | `Pointer` <`Trajectory`> | + +### Returns +- `integer` + +### C Prototype +`s32 get_trajectory_length(Trajectory* trajectory);` + +[:arrow_up_small:](#) + +
+ --- # functions from object_list_processor.h @@ -3446,10 +8024,33 @@ Gets the texture from a display list command if it has an image related op | cmd | `Pointer` <`Gfx`> | ### Returns -- `Pointer` <`integer`> +- `Pointer` <`Texture`> ### C Prototype -`u8 *gfx_get_texture(Gfx *cmd);` +`Texture *gfx_get_texture(Gfx *cmd);` + +[:arrow_up_small:](#) + +
+ +## [gfx_get_name](#gfx_get_name) + +### Description +Gets the name of a display list + +### Lua Example +`local stringValue = gfx_get_name(gfx)` + +### Parameters +| Field | Type | +| ----- | ---- | +| gfx | `Pointer` <`Gfx`> | + +### Returns +- `string` + +### C Prototype +`const char *gfx_get_name(Gfx *gfx);` [:arrow_up_small:](#) @@ -3642,6 +8243,29 @@ Deletes all display lists created by `gfx_create`
+## [vtx_get_name](#vtx_get_name) + +### Description +Gets the name of a vertex buffer + +### Lua Example +`local stringValue = vtx_get_name(vtx)` + +### Parameters +| Field | Type | +| ----- | ---- | +| vtx | `Pointer` <`Vtx`> | + +### Returns +- `string` + +### C Prototype +`const char *vtx_get_name(Vtx *vtx);` + +[:arrow_up_small:](#) + +
+ ## [vtx_get_count](#vtx_get_count) ### Description @@ -3827,4695 +8451,6 @@ Deletes all vertex buffers created by `vtx_create` [:arrow_up_small:](#) -
- ---- -# functions from smlua_level_utils.h - -
- - -## [smlua_level_util_change_area](#smlua_level_util_change_area) - -### Description -Instantly changes the current area to `areaIndex` - -### Lua Example -`smlua_level_util_change_area(areaIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| areaIndex | `integer` | - -### Returns -- None - -### C Prototype -`void smlua_level_util_change_area(s32 areaIndex);` - -[:arrow_up_small:](#) - -
- -## [smlua_level_util_get_info](#smlua_level_util_get_info) - -### Description -Gets information on a custom level from `levelNum` - -### Lua Example -`local CustomLevelInfoValue = smlua_level_util_get_info(levelNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| levelNum | `integer` | - -### Returns -[CustomLevelInfo](structs.md#CustomLevelInfo) - -### C Prototype -`struct CustomLevelInfo* smlua_level_util_get_info(s16 levelNum);` - -[:arrow_up_small:](#) - -
- -## [smlua_level_util_get_info_from_short_name](#smlua_level_util_get_info_from_short_name) - -### Description -Gets information on a custom level from `shortName` - -### Lua Example -`local CustomLevelInfoValue = smlua_level_util_get_info_from_short_name(shortName)` - -### Parameters -| Field | Type | -| ----- | ---- | -| shortName | `string` | - -### Returns -[CustomLevelInfo](structs.md#CustomLevelInfo) - -### C Prototype -`struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(const char* shortName);` - -[:arrow_up_small:](#) - -
- -## [smlua_level_util_get_info_from_course_num](#smlua_level_util_get_info_from_course_num) - -### Description -Gets information on a custom level from `courseNum` - -### Lua Example -`local CustomLevelInfoValue = smlua_level_util_get_info_from_course_num(courseNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | - -### Returns -[CustomLevelInfo](structs.md#CustomLevelInfo) - -### C Prototype -`struct CustomLevelInfo* smlua_level_util_get_info_from_course_num(u8 courseNum);` - -[:arrow_up_small:](#) - -
- -## [level_register](#level_register) - -### Description -Registers a fully custom level. Level ID begins at 50 - -### Lua Example -`local integerValue = level_register(scriptEntryName, courseNum, fullName, shortName, acousticReach, echoLevel1, echoLevel2, echoLevel3)` - -### Parameters -| Field | Type | -| ----- | ---- | -| scriptEntryName | `string` | -| courseNum | `integer` | -| fullName | `string` | -| shortName | `string` | -| acousticReach | `integer` | -| echoLevel1 | `integer` | -| echoLevel2 | `integer` | -| echoLevel3 | `integer` | - -### Returns -- `integer` - -### C Prototype -`s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3);` - -[:arrow_up_small:](#) - -
- -## [level_is_vanilla_level](#level_is_vanilla_level) - -### Description -Checks if `levelNum` is a vanilla level - -### Lua Example -`local booleanValue = level_is_vanilla_level(levelNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| levelNum | `integer` | - -### Returns -- `boolean` - -### C Prototype -`bool level_is_vanilla_level(s16 levelNum);` - -[:arrow_up_small:](#) - -
- -## [warp_to_warpnode](#warp_to_warpnode) - -### Description -Warps to `aWarpId` of `aArea` in `aLevel` during `aAct` - -### Lua Example -`local booleanValue = warp_to_warpnode(aLevel, aArea, aAct, aWarpId)` - -### Parameters -| Field | Type | -| ----- | ---- | -| aLevel | `integer` | -| aArea | `integer` | -| aAct | `integer` | -| aWarpId | `integer` | - -### Returns -- `boolean` - -### C Prototype -`bool warp_to_warpnode(s32 aLevel, s32 aArea, s32 aAct, s32 aWarpId);` - -[:arrow_up_small:](#) - -
- -## [warp_to_level](#warp_to_level) - -### Description -Warps to `aArea` of `aLevel` in `aAct` - -### Lua Example -`local booleanValue = warp_to_level(aLevel, aArea, aAct)` - -### Parameters -| Field | Type | -| ----- | ---- | -| aLevel | `integer` | -| aArea | `integer` | -| aAct | `integer` | - -### Returns -- `boolean` - -### C Prototype -`bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct);` - -[:arrow_up_small:](#) - -
- -## [warp_restart_level](#warp_restart_level) - -### Description -Restarts the current level - -### Lua Example -`local booleanValue = warp_restart_level()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool warp_restart_level(void);` - -[:arrow_up_small:](#) - -
- -## [warp_to_start_level](#warp_to_start_level) - -### Description -Warps to the start level (Castle Grounds by default) - -### Lua Example -`local booleanValue = warp_to_start_level()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool warp_to_start_level(void);` - -[:arrow_up_small:](#) - -
- -## [warp_exit_level](#warp_exit_level) - -### Description -Exits the current level after `aDelay` - -### Lua Example -`local booleanValue = warp_exit_level(aDelay)` - -### Parameters -| Field | Type | -| ----- | ---- | -| aDelay | `integer` | - -### Returns -- `boolean` - -### C Prototype -`bool warp_exit_level(s32 aDelay);` - -[:arrow_up_small:](#) - -
- -## [warp_to_castle](#warp_to_castle) - -### Description -Warps back to the castle from `aLevel` - -### Lua Example -`local booleanValue = warp_to_castle(aLevel)` - -### Parameters -| Field | Type | -| ----- | ---- | -| aLevel | `integer` | - -### Returns -- `boolean` - -### C Prototype -`bool warp_to_castle(s32 aLevel);` - -[:arrow_up_small:](#) - -
- ---- -# functions from smlua_misc_utils.h - -
- - -## [get_network_area_timer](#get_network_area_timer) - -### Description -Gets the current area's networked timer - -### Lua Example -`local integerValue = get_network_area_timer()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`u32 get_network_area_timer(void);` - -[:arrow_up_small:](#) - -
- -## [get_area_update_counter](#get_area_update_counter) - -### Description -Gets the area update counter incremented when objects are updated - -### Lua Example -`local integerValue = get_area_update_counter()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`u16 get_area_update_counter(void);` - -[:arrow_up_small:](#) - -
- -## [get_temp_s32_pointer](#get_temp_s32_pointer) - -### Description -Returns a temporary signed 32-bit integer pointer with its value set to `initialValue` - -### Lua Example -`local PointerValue = get_temp_s32_pointer(initialValue)` - -### Parameters -| Field | Type | -| ----- | ---- | -| initialValue | `integer` | - -### Returns -- `Pointer` <`integer`> - -### C Prototype -`s32* get_temp_s32_pointer(s32 initialValue);` - -[:arrow_up_small:](#) - -
- -## [deref_s32_pointer](#deref_s32_pointer) - -### Description -Gets the signed 32-bit integer value from `pointer` - -### Lua Example -`local integerValue = deref_s32_pointer(pointer)` - -### Parameters -| Field | Type | -| ----- | ---- | -| pointer | `Pointer` <`integer`> | - -### Returns -- `integer` - -### C Prototype -`s32 deref_s32_pointer(s32* pointer);` - -[:arrow_up_small:](#) - -
- -## [djui_popup_create_global](#djui_popup_create_global) - -### Description -Creates a DJUI popup that is broadcasted to every client - -### Lua Example -`djui_popup_create_global(message, lines)` - -### Parameters -| Field | Type | -| ----- | ---- | -| message | `string` | -| lines | `integer` | - -### Returns -- None - -### C Prototype -`void djui_popup_create_global(const char* message, int lines);` - -[:arrow_up_small:](#) - -
- -## [djui_is_popup_disabled](#djui_is_popup_disabled) - -### Description -Returns if popups are disabled - -### Lua Example -`local booleanValue = djui_is_popup_disabled()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool djui_is_popup_disabled(void);` - -[:arrow_up_small:](#) - -
- -## [djui_set_popup_disabled_override](#djui_set_popup_disabled_override) - -### Description -Sets if popups are disabled - -### Lua Example -`djui_set_popup_disabled_override(value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| value | `boolean` | - -### Returns -- None - -### C Prototype -`void djui_set_popup_disabled_override(bool value);` - -[:arrow_up_small:](#) - -
- -## [djui_reset_popup_disabled_override](#djui_reset_popup_disabled_override) - -### Description -Resets if popups are disabled - -### Lua Example -`djui_reset_popup_disabled_override()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void djui_reset_popup_disabled_override(void);` - -[:arrow_up_small:](#) - -
- -## [djui_is_playerlist_open](#djui_is_playerlist_open) - -### Description -Checks if the DJUI playerlist is open - -### Lua Example -`local booleanValue = djui_is_playerlist_open()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool djui_is_playerlist_open(void);` - -[:arrow_up_small:](#) - -
- -## [djui_attempting_to_open_playerlist](#djui_attempting_to_open_playerlist) - -### Description -Checks if the DJUI playerlist is attempting to be opened - -### Lua Example -`local booleanValue = djui_attempting_to_open_playerlist()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool djui_attempting_to_open_playerlist(void);` - -[:arrow_up_small:](#) - -
- -## [djui_get_playerlist_page_index](#djui_get_playerlist_page_index) - -### Description -Gets the DJUI playerlist's page index - -### Lua Example -`local integerValue = djui_get_playerlist_page_index()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`u8 djui_get_playerlist_page_index(void);` - -[:arrow_up_small:](#) - -
- -## [djui_menu_get_font](#djui_menu_get_font) - -### Description -Gets the DJUI menu font - -### Lua Example -`local enumValue = djui_menu_get_font()` - -### Parameters -- None - -### Returns -[enum DjuiFontType](constants.md#enum-DjuiFontType) - -### C Prototype -`enum DjuiFontType djui_menu_get_font(void);` - -[:arrow_up_small:](#) - -
- -## [djui_menu_get_theme](#djui_menu_get_theme) - -### Description -Gets the DJUI menu theme - -### Lua Example -`local DjuiThemeValue = djui_menu_get_theme()` - -### Parameters -- None - -### Returns -[DjuiTheme](structs.md#DjuiTheme) - -### C Prototype -`struct DjuiTheme* djui_menu_get_theme(void);` - -[:arrow_up_small:](#) - -
- -## [djui_is_playerlist_ping_visible](#djui_is_playerlist_ping_visible) - -### Description -Checks if the DJUI playerlist ping icon is visible - -### Lua Example -`local booleanValue = djui_is_playerlist_ping_visible()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool djui_is_playerlist_ping_visible(void);` - -[:arrow_up_small:](#) - -
- -## [get_dialog_box_state](#get_dialog_box_state) - -### Description -Gets the current state of the dialog box - -### Lua Example -`local integerValue = get_dialog_box_state()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s8 get_dialog_box_state(void);` - -[:arrow_up_small:](#) - -
- -## [get_dialog_id](#get_dialog_id) - -### Description -Gets the current dialog box ID - -### Lua Example -`local integerValue = get_dialog_id()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 get_dialog_id(void);` - -[:arrow_up_small:](#) - -
- -## [get_last_star_or_key](#get_last_star_or_key) - -### Description -Gets if the last objective collected was a star (0) or a key (1) - -### Lua Example -`local integerValue = get_last_star_or_key()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`u8 get_last_star_or_key(void);` - -[:arrow_up_small:](#) - -
- -## [set_last_star_or_key](#set_last_star_or_key) - -### Description -Sets if the last objective collected was a star (0) or a key (1) - -### Lua Example -`set_last_star_or_key(value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| value | `integer` | - -### Returns -- None - -### C Prototype -`void set_last_star_or_key(u8 value);` - -[:arrow_up_small:](#) - -
- -## [get_last_completed_course_num](#get_last_completed_course_num) - -### Description -Gets the last course a star or key was collected in - -### Lua Example -`local integerValue = get_last_completed_course_num()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`u8 get_last_completed_course_num(void);` - -[:arrow_up_small:](#) - -
- -## [set_last_completed_course_num](#set_last_completed_course_num) - -### Description -Sets the last course a star or key was collected in - -### Lua Example -`set_last_completed_course_num(courseNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | - -### Returns -- None - -### C Prototype -`void set_last_completed_course_num(u8 courseNum);` - -[:arrow_up_small:](#) - -
- -## [get_last_completed_star_num](#get_last_completed_star_num) - -### Description -Gets the last collected star's number (1-7) - -### Lua Example -`local integerValue = get_last_completed_star_num()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`u8 get_last_completed_star_num(void);` - -[:arrow_up_small:](#) - -
- -## [set_last_completed_star_num](#set_last_completed_star_num) - -### Description -Sets the last collected star's number (1-7) - -### Lua Example -`set_last_completed_star_num(starNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| starNum | `integer` | - -### Returns -- None - -### C Prototype -`void set_last_completed_star_num(u8 starNum);` - -[:arrow_up_small:](#) - -
- -## [get_got_file_coin_hi_score](#get_got_file_coin_hi_score) - -### Description -Checks if the save file's coin "HI SCORE" was obtained with the last star or key collection - -### Lua Example -`local booleanValue = get_got_file_coin_hi_score()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool get_got_file_coin_hi_score(void);` - -[:arrow_up_small:](#) - -
- -## [set_got_file_coin_hi_score](#set_got_file_coin_hi_score) - -### Description -Sets if the save file's coin "HI SCORE" was obtained with the last star or key collection - -### Lua Example -`set_got_file_coin_hi_score(value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| value | `boolean` | - -### Returns -- None - -### C Prototype -`void set_got_file_coin_hi_score(bool value);` - -[:arrow_up_small:](#) - -
- -## [get_save_file_modified](#get_save_file_modified) - -### Description -Checks if the save file has been modified without saving - -### Lua Example -`local booleanValue = get_save_file_modified()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool get_save_file_modified(void);` - -[:arrow_up_small:](#) - -
- -## [set_save_file_modified](#set_save_file_modified) - -### Description -Sets if the save file has been modified without saving - -### Lua Example -`set_save_file_modified(value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| value | `boolean` | - -### Returns -- None - -### C Prototype -`void set_save_file_modified(bool value);` - -[:arrow_up_small:](#) - -
- -## [hud_hide](#hud_hide) - -### Description -Hides the HUD - -### Lua Example -`hud_hide()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void hud_hide(void);` - -[:arrow_up_small:](#) - -
- -## [hud_show](#hud_show) - -### Description -Shows the HUD - -### Lua Example -`hud_show()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void hud_show(void);` - -[:arrow_up_small:](#) - -
- -## [hud_is_hidden](#hud_is_hidden) - -### Description -Checks if the HUD is hidden - -### Lua Example -`local booleanValue = hud_is_hidden()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool hud_is_hidden(void);` - -[:arrow_up_small:](#) - -
- -## [hud_get_value](#hud_get_value) - -### Description -Gets a HUD display value - -### Lua Example -`local integerValue = hud_get_value(type)` - -### Parameters -| Field | Type | -| ----- | ---- | -| type | [enum HudDisplayValue](constants.md#enum-HudDisplayValue) | - -### Returns -- `integer` - -### C Prototype -`s32 hud_get_value(enum HudDisplayValue type);` - -[:arrow_up_small:](#) - -
- -## [hud_set_value](#hud_set_value) - -### Description -Sets a HUD display value - -### Lua Example -`hud_set_value(type, value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| type | [enum HudDisplayValue](constants.md#enum-HudDisplayValue) | -| value | `integer` | - -### Returns -- None - -### C Prototype -`void hud_set_value(enum HudDisplayValue type, s32 value);` - -[:arrow_up_small:](#) - -
- -## [hud_render_power_meter](#hud_render_power_meter) - -### Description -Renders a power meter on the HUD - -### Lua Example -`hud_render_power_meter(health, x, y, width, height)` - -### Parameters -| Field | Type | -| ----- | ---- | -| health | `integer` | -| x | `number` | -| y | `number` | -| width | `number` | -| height | `number` | - -### Returns -- None - -### C Prototype -`void hud_render_power_meter(s32 health, f32 x, f32 y, f32 width, f32 height);` - -[:arrow_up_small:](#) - -
- -## [hud_render_power_meter_interpolated](#hud_render_power_meter_interpolated) - -### Description -Renders an interpolated power meter on the HUD - -### Lua Example -`hud_render_power_meter_interpolated(health, prevX, prevY, prevWidth, prevHeight, x, y, width, height)` - -### Parameters -| Field | Type | -| ----- | ---- | -| health | `integer` | -| prevX | `number` | -| prevY | `number` | -| prevWidth | `number` | -| prevHeight | `number` | -| x | `number` | -| y | `number` | -| width | `number` | -| height | `number` | - -### Returns -- None - -### C Prototype -`void hud_render_power_meter_interpolated(s32 health, f32 prevX, f32 prevY, f32 prevWidth, f32 prevHeight, f32 x, f32 y, f32 width, f32 height);` - -[:arrow_up_small:](#) - -
- -## [hud_get_flash](#hud_get_flash) - -### Description -Gets if the star counter on the HUD should flash - -### Lua Example -`local integerValue = hud_get_flash()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s8 hud_get_flash(void);` - -[:arrow_up_small:](#) - -
- -## [hud_set_flash](#hud_set_flash) - -### Description -Sets if the star counter on the HUD should flash - -### Lua Example -`hud_set_flash(value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| value | `integer` | - -### Returns -- None - -### C Prototype -`void hud_set_flash(s8 value);` - -[:arrow_up_small:](#) - -
- -## [act_select_hud_hide](#act_select_hud_hide) - -### Description -Hides part of the Act Select HUD - -### Lua Example -`act_select_hud_hide(part)` - -### Parameters -| Field | Type | -| ----- | ---- | -| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) | - -### Returns -- None - -### C Prototype -`void act_select_hud_hide(enum ActSelectHudPart part);` - -[:arrow_up_small:](#) - -
- -## [act_select_hud_show](#act_select_hud_show) - -### Description -Shows part of the Act Select HUD - -### Lua Example -`act_select_hud_show(part)` - -### Parameters -| Field | Type | -| ----- | ---- | -| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) | - -### Returns -- None - -### C Prototype -`void act_select_hud_show(enum ActSelectHudPart part);` - -[:arrow_up_small:](#) - -
- -## [act_select_hud_is_hidden](#act_select_hud_is_hidden) - -### Description -Checks if part of the Act Select HUD is hidden - -### Lua Example -`local booleanValue = act_select_hud_is_hidden(part)` - -### Parameters -| Field | Type | -| ----- | ---- | -| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) | - -### Returns -- `boolean` - -### C Prototype -`bool act_select_hud_is_hidden(enum ActSelectHudPart part);` - -[:arrow_up_small:](#) - -
- -## [is_game_paused](#is_game_paused) - -### Description -Checks if the game is paused - -### Lua Example -`local booleanValue = is_game_paused()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool is_game_paused(void);` - -[:arrow_up_small:](#) - -
- -## [is_transition_playing](#is_transition_playing) - -### Description -Checks if a screen transition is playing - -### Lua Example -`local booleanValue = is_transition_playing()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool is_transition_playing(void);` - -[:arrow_up_small:](#) - -
- -## [allocate_mario_action](#allocate_mario_action) - -### Description -Allocates an action ID with bitwise flags - -### Lua Example -`local integerValue = allocate_mario_action(actFlags)` - -### Parameters -| Field | Type | -| ----- | ---- | -| actFlags | `integer` | - -### Returns -- `integer` - -### C Prototype -`u32 allocate_mario_action(u32 actFlags);` - -[:arrow_up_small:](#) - -
- -## [get_hand_foot_pos_x](#get_hand_foot_pos_x) - -### Description -Gets the X coordinate of Mario's hand (0-1) or foot (2-3) but it is important to note that the positions are not updated off-screen - -### Lua Example -`local numberValue = get_hand_foot_pos_x(m, index)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | -| index | `integer` | - -### Returns -- `number` - -### C Prototype -`f32 get_hand_foot_pos_x(struct MarioState* m, u8 index);` - -[:arrow_up_small:](#) - -
- -## [get_hand_foot_pos_y](#get_hand_foot_pos_y) - -### Description -Gets the Y coordinate of Mario's hand (0-1) or foot (2-3) but It is important to note that the positions are not updated off-screen - -### Lua Example -`local numberValue = get_hand_foot_pos_y(m, index)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | -| index | `integer` | - -### Returns -- `number` - -### C Prototype -`f32 get_hand_foot_pos_y(struct MarioState* m, u8 index);` - -[:arrow_up_small:](#) - -
- -## [get_hand_foot_pos_z](#get_hand_foot_pos_z) - -### Description -Gets the Z coordinate of Mario's hand (0-1) or foot (2-3) but it is important to note that the positions are not updated off-screen - -### Lua Example -`local numberValue = get_hand_foot_pos_z(m, index)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | -| index | `integer` | - -### Returns -- `number` - -### C Prototype -`f32 get_hand_foot_pos_z(struct MarioState* m, u8 index);` - -[:arrow_up_small:](#) - -
- -## [get_mario_anim_part_pos](#get_mario_anim_part_pos) - -### Description -Retrieves the animated part position associated to `animPart` from the MarioState `m` and stores it into `pos`. Returns `true` on success or `false` on failure - -### Lua Example -`local booleanValue = get_mario_anim_part_pos(m, animPart, pos)` - -### Parameters -| Field | Type | -| ----- | ---- | -| m | [MarioState](structs.md#MarioState) | -| animPart | `integer` | -| pos | [Vec3f](structs.md#Vec3f) | - -### Returns -- `boolean` - -### C Prototype -`bool get_mario_anim_part_pos(struct MarioState *m, u32 animPart, OUT Vec3f pos);` - -[:arrow_up_small:](#) - -
- -## [get_current_save_file_num](#get_current_save_file_num) - -### Description -Gets the current save file number (1-indexed) - -### Lua Example -`local integerValue = get_current_save_file_num()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s16 get_current_save_file_num(void);` - -[:arrow_up_small:](#) - -
- -## [save_file_get_using_backup_slot](#save_file_get_using_backup_slot) - -### Description -Checks if the save file is using its backup slot - -### Lua Example -`local booleanValue = save_file_get_using_backup_slot()` - -### Parameters -- None - -### Returns -- `boolean` - -### C Prototype -`bool save_file_get_using_backup_slot(void);` - -[:arrow_up_small:](#) - -
- -## [save_file_set_using_backup_slot](#save_file_set_using_backup_slot) - -### Description -Sets if the save file should use its backup slot - -### Lua Example -`save_file_set_using_backup_slot(usingBackupSlot)` - -### Parameters -| Field | Type | -| ----- | ---- | -| usingBackupSlot | `boolean` | - -### Returns -- None - -### C Prototype -`void save_file_set_using_backup_slot(bool usingBackupSlot);` - -[:arrow_up_small:](#) - -
- -## [movtexqc_register](#movtexqc_register) - -### Description -Registers a custom moving texture entry (used for vanilla water boxes) - -### Lua Example -`movtexqc_register(name, level, area, type)` - -### Parameters -| Field | Type | -| ----- | ---- | -| name | `string` | -| level | `integer` | -| area | `integer` | -| type | `integer` | - -### Returns -- None - -### C Prototype -`void movtexqc_register(const char* name, s16 level, s16 area, s16 type);` - -[:arrow_up_small:](#) - -
- -## [get_water_level](#get_water_level) - -### Description -Gets the water level in an area corresponding to `index` (0-indexed) - -### Lua Example -`local integerValue = get_water_level(index)` - -### Parameters -| Field | Type | -| ----- | ---- | -| index | `integer` | - -### Returns -- `integer` - -### C Prototype -`s16 get_water_level(u8 index);` - -[:arrow_up_small:](#) - -
- -## [set_water_level](#set_water_level) - -### Description -Sets the water level in an area corresponding to `index` (0-indexed) - -### Lua Example -`set_water_level(index, height, sync)` - -### Parameters -| Field | Type | -| ----- | ---- | -| index | `integer` | -| height | `integer` | -| sync | `boolean` | - -### Returns -- None - -### C Prototype -`void set_water_level(u8 index, s16 height, bool sync);` - -[:arrow_up_small:](#) - -
- -## [course_is_main_course](#course_is_main_course) - -### Description -Checks if a course is a main course and not the castle or secret levels - -### Lua Example -`local booleanValue = course_is_main_course(courseNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | - -### Returns -- `boolean` - -### C Prototype -`bool course_is_main_course(u16 courseNum);` - -[:arrow_up_small:](#) - -
- -## [get_ttc_speed_setting](#get_ttc_speed_setting) - -### Description -Gets TTC's speed setting - -### Lua Example -`local integerValue = get_ttc_speed_setting()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s16 get_ttc_speed_setting(void);` - -[:arrow_up_small:](#) - -
- -## [set_ttc_speed_setting](#set_ttc_speed_setting) - -### Description -Sets TTC's speed setting (TTC_SPEED_*) - -### Lua Example -`set_ttc_speed_setting(speed)` - -### Parameters -| Field | Type | -| ----- | ---- | -| speed | `integer` | - -### Returns -- None - -### C Prototype -`void set_ttc_speed_setting(s16 speed);` - -[:arrow_up_small:](#) - -
- -## [get_time](#get_time) - -### Description -Gets the Unix Timestamp - -### Lua Example -`local integerValue = get_time()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s64 get_time(void);` - -[:arrow_up_small:](#) - -
- -## [get_date_and_time](#get_date_and_time) - -### Description -Gets the system clock's date and time - -### Lua Example -`local DateTimeValue = get_date_and_time()` - -### Parameters -- None - -### Returns -[DateTime](structs.md#DateTime) - -### C Prototype -`struct DateTime* get_date_and_time(void);` - -[:arrow_up_small:](#) - -
- -## [get_envfx](#get_envfx) - -### Description -Gets the non overridden environment effect (e.g. snow) - -### Lua Example -`local integerValue = get_envfx()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`u16 get_envfx(void);` - -[:arrow_up_small:](#) - -
- -## [set_override_envfx](#set_override_envfx) - -### Description -Sets the override environment effect (e.g. snow) - -### Lua Example -`set_override_envfx(envfx)` - -### Parameters -| Field | Type | -| ----- | ---- | -| envfx | `integer` | - -### Returns -- None - -### C Prototype -`void set_override_envfx(s32 envfx);` - -[:arrow_up_small:](#) - -
- -## [get_global_timer](#get_global_timer) - -### Description -Gets the global timer that has been ticking at 30 frames per second since game boot - -### Lua Example -`local integerValue = get_global_timer()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`u32 get_global_timer(void);` - -[:arrow_up_small:](#) - -
- -## [get_dialog_response](#get_dialog_response) - -### Description -Gets the choice selected inside of a dialog box (0-1) - -### Lua Example -`local integerValue = get_dialog_response()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 get_dialog_response(void);` - -[:arrow_up_small:](#) - -
- -## [get_local_discord_id](#get_local_discord_id) - -### Description -Gets the local discord ID if it isn't disabled, otherwise "0" is returned - -### Lua Example -`local stringValue = get_local_discord_id()` - -### Parameters -- None - -### Returns -- `string` - -### C Prototype -`const char* get_local_discord_id(void);` - -[:arrow_up_small:](#) - -
- -## [get_coopnet_id](#get_coopnet_id) - -### Description -Gets the CoopNet ID of a player with `localIndex` if CoopNet is being used and the player is connected, otherwise "-1" is returned - -### Lua Example -`local stringValue = get_coopnet_id(localIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| localIndex | `integer` | - -### Returns -- `string` - -### C Prototype -`const char* get_coopnet_id(s8 localIndex);` - -[:arrow_up_small:](#) - -
- -## [get_volume_master](#get_volume_master) - -### Description -Gets the master volume level - -### Lua Example -`local numberValue = get_volume_master()` - -### Parameters -- None - -### Returns -- `number` - -### C Prototype -`f32 get_volume_master(void);` - -[:arrow_up_small:](#) - -
- -## [get_volume_level](#get_volume_level) - -### Description -Gets the volume level of music - -### Lua Example -`local numberValue = get_volume_level()` - -### Parameters -- None - -### Returns -- `number` - -### C Prototype -`f32 get_volume_level(void);` - -[:arrow_up_small:](#) - -
- -## [get_volume_sfx](#get_volume_sfx) - -### Description -Gets the volume level of sound effects - -### Lua Example -`local numberValue = get_volume_sfx()` - -### Parameters -- None - -### Returns -- `number` - -### C Prototype -`f32 get_volume_sfx(void);` - -[:arrow_up_small:](#) - -
- -## [get_volume_env](#get_volume_env) - -### Description -Gets the volume level of environment sounds effects - -### Lua Example -`local numberValue = get_volume_env()` - -### Parameters -- None - -### Returns -- `number` - -### C Prototype -`f32 get_volume_env(void);` - -[:arrow_up_small:](#) - -
- -## [set_volume_master](#set_volume_master) - -### Description -Sets the master volume level - -### Lua Example -`set_volume_master(volume)` - -### Parameters -| Field | Type | -| ----- | ---- | -| volume | `number` | - -### Returns -- None - -### C Prototype -`void set_volume_master(f32 volume);` - -[:arrow_up_small:](#) - -
- -## [set_volume_level](#set_volume_level) - -### Description -Sets the volume level of music - -### Lua Example -`set_volume_level(volume)` - -### Parameters -| Field | Type | -| ----- | ---- | -| volume | `number` | - -### Returns -- None - -### C Prototype -`void set_volume_level(f32 volume);` - -[:arrow_up_small:](#) - -
- -## [set_volume_sfx](#set_volume_sfx) - -### Description -Sets the volume level of sound effects - -### Lua Example -`set_volume_sfx(volume)` - -### Parameters -| Field | Type | -| ----- | ---- | -| volume | `number` | - -### Returns -- None - -### C Prototype -`void set_volume_sfx(f32 volume);` - -[:arrow_up_small:](#) - -
- -## [set_volume_env](#set_volume_env) - -### Description -Sets the volume level of environment sounds effects - -### Lua Example -`set_volume_env(volume)` - -### Parameters -| Field | Type | -| ----- | ---- | -| volume | `number` | - -### Returns -- None - -### C Prototype -`void set_volume_env(f32 volume);` - -[:arrow_up_small:](#) - -
- -## [get_environment_region](#get_environment_region) - -### Description -Gets an environment region (gas/water boxes) height value - -### Lua Example -`local integerValue = get_environment_region(index)` - -### Parameters -| Field | Type | -| ----- | ---- | -| index | `integer` | - -### Returns -- `integer` - -### C Prototype -`s16 get_environment_region(u8 index);` - -[:arrow_up_small:](#) - -
- -## [set_environment_region](#set_environment_region) - -### Description -Sets an environment region (gas/water boxes) height value - -### Lua Example -`set_environment_region(index, value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| index | `integer` | -| value | `integer` | - -### Returns -- None - -### C Prototype -`void set_environment_region(u8 index, s16 value);` - -[:arrow_up_small:](#) - -
- -## [mod_file_exists](#mod_file_exists) - -### Description -Checks if a file exists inside of a mod - -### Lua Example -`local booleanValue = mod_file_exists(filename)` - -### Parameters -| Field | Type | -| ----- | ---- | -| filename | `string` | - -### Returns -- `boolean` - -### C Prototype -`bool mod_file_exists(const char* filename);` - -[:arrow_up_small:](#) - -
- -## [get_active_mod](#get_active_mod) - -### Description -Gets the mod currently being processed - -### Lua Example -`local ModValue = get_active_mod()` - -### Parameters -- None - -### Returns -[Mod](structs.md#Mod) - -### C Prototype -`struct Mod* get_active_mod(void);` - -[:arrow_up_small:](#) - -
- -## [set_window_title](#set_window_title) - -### Description -Sets the window title to a custom title - -### Lua Example -`set_window_title(title)` - -### Parameters -| Field | Type | -| ----- | ---- | -| title | `string` | - -### Returns -- None - -### C Prototype -`void set_window_title(const char* title);` - -[:arrow_up_small:](#) - -
- -## [reset_window_title](#reset_window_title) - -### Description -Resets the window title - -### Lua Example -`reset_window_title()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void reset_window_title(void);` - -[:arrow_up_small:](#) - -
- -## [get_os_name](#get_os_name) - -### Description -Gets the name of the operating system the game is running on - -### Lua Example -`local stringValue = get_os_name()` - -### Parameters -- None - -### Returns -- `string` - -### C Prototype -`const char* get_os_name(void);` - -[:arrow_up_small:](#) - -
- -## [geo_get_current_root](#geo_get_current_root) - -### Description -Gets the current GraphNodeRoot - -### Lua Example -`local GraphNodeRootValue = geo_get_current_root()` - -### Parameters -- None - -### Returns -[GraphNodeRoot](structs.md#GraphNodeRoot) - -### C Prototype -`struct GraphNodeRoot* geo_get_current_root(void);` - -[:arrow_up_small:](#) - -
- -## [geo_get_current_master_list](#geo_get_current_master_list) - -### Description -Gets the current GraphNodeMasterList - -### Lua Example -`local GraphNodeMasterListValue = geo_get_current_master_list()` - -### Parameters -- None - -### Returns -[GraphNodeMasterList](structs.md#GraphNodeMasterList) - -### C Prototype -`struct GraphNodeMasterList* geo_get_current_master_list(void);` - -[:arrow_up_small:](#) - -
- -## [geo_get_current_perspective](#geo_get_current_perspective) - -### Description -Gets the current GraphNodePerspective - -### Lua Example -`local GraphNodePerspectiveValue = geo_get_current_perspective()` - -### Parameters -- None - -### Returns -[GraphNodePerspective](structs.md#GraphNodePerspective) - -### C Prototype -`struct GraphNodePerspective* geo_get_current_perspective(void);` - -[:arrow_up_small:](#) - -
- -## [geo_get_current_camera](#geo_get_current_camera) - -### Description -Gets the current GraphNodeCamera - -### Lua Example -`local GraphNodeCameraValue = geo_get_current_camera()` - -### Parameters -- None - -### Returns -[GraphNodeCamera](structs.md#GraphNodeCamera) - -### C Prototype -`struct GraphNodeCamera* geo_get_current_camera(void);` - -[:arrow_up_small:](#) - -
- -## [geo_get_current_held_object](#geo_get_current_held_object) - -### Description -Gets the current GraphNodeHeldObject - -### Lua Example -`local GraphNodeHeldObjectValue = geo_get_current_held_object()` - -### Parameters -- None - -### Returns -[GraphNodeHeldObject](structs.md#GraphNodeHeldObject) - -### C Prototype -`struct GraphNodeHeldObject* geo_get_current_held_object(void);` - -[:arrow_up_small:](#) - -
- -## [texture_to_lua_table](#texture_to_lua_table) - -### Description -Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures. - -### Lua Example -`texture_to_lua_table(tex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| tex | `Pointer` <`integer`> | - -### Returns -- None - -### C Prototype -`void texture_to_lua_table(const u8 *tex);` - -[:arrow_up_small:](#) - -
- ---- -# functions from smlua_model_utils.h - -
- - -## [smlua_model_util_get_id](#smlua_model_util_get_id) - -### Description -Gets the extended model ID for the `name` of a `GeoLayout` - -### Lua Example -`local enumValue = smlua_model_util_get_id(name)` - -### Parameters -| Field | Type | -| ----- | ---- | -| name | `string` | - -### Returns -[enum ModelExtendedId](constants.md#enum-ModelExtendedId) - -### C Prototype -`enum ModelExtendedId smlua_model_util_get_id(const char* name);` - -[:arrow_up_small:](#) - -
- ---- -# functions from smlua_obj_utils.h - -
- - -## [spawn_sync_object](#spawn_sync_object) - -### Description -Spawns a synchronized object at `x`, `y`, and `z` as a child object of the local Mario with his rotation. You can change the fields of the object in `objSetupFunction` - -### Lua Example -`local ObjectValue = spawn_sync_object(behaviorId, modelId, x, y, z, objSetupFunction)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | -| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | -| x | `number` | -| y | `number` | -| z | `number` | -| objSetupFunction | `Lua Function` () | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object* spawn_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);` - -[:arrow_up_small:](#) - -
- -## [spawn_non_sync_object](#spawn_non_sync_object) - -### Description -Spawns a non-synchronized object at `x`, `y`, and `z` as a child object of the local Mario with his rotation. You can change the fields of the object in `objSetupFunction` - -### Lua Example -`local ObjectValue = spawn_non_sync_object(behaviorId, modelId, x, y, z, objSetupFunction)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | -| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | -| x | `number` | -| y | `number` | -| z | `number` | -| objSetupFunction | `Lua Function` () | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object* spawn_non_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);` - -[:arrow_up_small:](#) - -
- -## [obj_has_behavior_id](#obj_has_behavior_id) - -### Description -Checks if an object has `behaviorId` - -### Lua Example -`local integerValue = obj_has_behavior_id(o, behaviorId)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | - -### Returns -- `integer` - -### C Prototype -`s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId);` - -[:arrow_up_small:](#) - -
- -## [obj_has_model_extended](#obj_has_model_extended) - -### Description -Checks if an object's model is equal to `modelId` - -### Lua Example -`local integerValue = obj_has_model_extended(o, modelId)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | - -### Returns -- `integer` - -### C Prototype -`s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId);` - -[:arrow_up_small:](#) - -
- -## [obj_get_model_id_extended](#obj_get_model_id_extended) - -### Description -Returns an object's extended model id - -### Lua Example -`local enumValue = obj_get_model_id_extended(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -[enum ModelExtendedId](constants.md#enum-ModelExtendedId) - -### C Prototype -`enum ModelExtendedId obj_get_model_id_extended(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_set_model_extended](#obj_set_model_extended) - -### Description -Sets an object's model to `modelId` - -### Lua Example -`obj_set_model_extended(o, modelId)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | - -### Returns -- None - -### C Prototype -`void obj_set_model_extended(struct Object *o, enum ModelExtendedId modelId);` - -[:arrow_up_small:](#) - -
- -## [get_trajectory](#get_trajectory) - -### Description -Gets a trajectory by `name` - -### Lua Example -`local PointerValue = get_trajectory(name)` - -### Parameters -| Field | Type | -| ----- | ---- | -| name | `string` | - -### Returns -- `Pointer` <`Trajectory`> - -### C Prototype -`Trajectory* get_trajectory(const char* name);` - -[:arrow_up_small:](#) - -
- -## [geo_get_current_object](#geo_get_current_object) - -### Description -When used in a geo function, retrieve the current processed object - -### Lua Example -`local ObjectValue = geo_get_current_object()` - -### Parameters -- None - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *geo_get_current_object(void);` - -[:arrow_up_small:](#) - -
- -## [get_current_object](#get_current_object) - -### Description -Gets the object currently being processed - -### Lua Example -`local ObjectValue = get_current_object()` - -### Parameters -- None - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *get_current_object(void);` - -[:arrow_up_small:](#) - -
- -## [get_dialog_object](#get_dialog_object) - -### Description -Gets the NPC object Mario is talking to - -### Lua Example -`local ObjectValue = get_dialog_object()` - -### Parameters -- None - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *get_dialog_object(void);` - -[:arrow_up_small:](#) - -
- -## [get_cutscene_focus](#get_cutscene_focus) - -### Description -Gets the cutscene focus object - -### Lua Example -`local ObjectValue = get_cutscene_focus()` - -### Parameters -- None - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *get_cutscene_focus(void);` - -[:arrow_up_small:](#) - -
- -## [get_secondary_camera_focus](#get_secondary_camera_focus) - -### Description -Gets the secondary camera focus object - -### Lua Example -`local ObjectValue = get_secondary_camera_focus()` - -### Parameters -- None - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *get_secondary_camera_focus(void);` - -[:arrow_up_small:](#) - -
- -## [set_cutscene_focus](#set_cutscene_focus) - -### Description -Sets the cutscene focus object - -### Lua Example -`set_cutscene_focus(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void set_cutscene_focus(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [set_secondary_camera_focus](#set_secondary_camera_focus) - -### Description -Sets the secondary camera focus object - -### Lua Example -`set_secondary_camera_focus(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -- None - -### C Prototype -`void set_secondary_camera_focus(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_get_first](#obj_get_first) - -### Description -Gets the first object in an object list - -### Lua Example -`local ObjectValue = obj_get_first(objList)` - -### Parameters -| Field | Type | -| ----- | ---- | -| objList | [enum ObjectList](constants.md#enum-ObjectList) | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *obj_get_first(enum ObjectList objList);` - -[:arrow_up_small:](#) - -
- -## [obj_get_first_with_behavior_id](#obj_get_first_with_behavior_id) - -### Description -Gets the first object loaded with `behaviorId` - -### Lua Example -`local ObjectValue = obj_get_first_with_behavior_id(behaviorId)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId);` - -[:arrow_up_small:](#) - -
- -## [obj_get_first_with_behavior_id_and_field_s32](#obj_get_first_with_behavior_id_and_field_s32) - -### Description -Gets the first object loaded with `behaviorId` and object signed 32-bit integer field (look in `object_fields.h` to get the index of a field) - -### Lua Example -`local ObjectValue = obj_get_first_with_behavior_id_and_field_s32(behaviorId, fieldIndex, value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | -| fieldIndex | `integer` | -| value | `integer` | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value);` - -[:arrow_up_small:](#) - -
- -## [obj_get_first_with_behavior_id_and_field_f32](#obj_get_first_with_behavior_id_and_field_f32) - -### Description -Gets the first object loaded with `behaviorId` and object float field (look in `object_fields.h` to get the index of a field) - -### Lua Example -`local ObjectValue = obj_get_first_with_behavior_id_and_field_f32(behaviorId, fieldIndex, value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | -| fieldIndex | `integer` | -| value | `number` | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *obj_get_first_with_behavior_id_and_field_f32(enum BehaviorId behaviorId, s32 fieldIndex, f32 value);` - -[:arrow_up_small:](#) - -
- -## [obj_get_next](#obj_get_next) - -### Description -Gets the next object in an object list - -### Lua Example -`local ObjectValue = obj_get_next(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *obj_get_next(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_get_next_with_same_behavior_id](#obj_get_next_with_same_behavior_id) - -### Description -Gets the next object loaded with the same behavior ID - -### Lua Example -`local ObjectValue = obj_get_next_with_same_behavior_id(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *obj_get_next_with_same_behavior_id(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_get_next_with_same_behavior_id_and_field_s32](#obj_get_next_with_same_behavior_id_and_field_s32) - -### Description -Gets the next object loaded with the same behavior ID and object signed 32-bit integer field (look in `object_fields.h` to get the index of a field) - -### Lua Example -`local ObjectValue = obj_get_next_with_same_behavior_id_and_field_s32(o, fieldIndex, value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| fieldIndex | `integer` | -| value | `integer` | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *obj_get_next_with_same_behavior_id_and_field_s32(struct Object *o, s32 fieldIndex, s32 value);` - -[:arrow_up_small:](#) - -
- -## [obj_get_next_with_same_behavior_id_and_field_f32](#obj_get_next_with_same_behavior_id_and_field_f32) - -### Description -Gets the next object loaded with the same behavior ID and object float field (look in `object_fields.h` to get the index of a field) - -### Lua Example -`local ObjectValue = obj_get_next_with_same_behavior_id_and_field_f32(o, fieldIndex, value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| fieldIndex | `integer` | -| value | `number` | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *obj_get_next_with_same_behavior_id_and_field_f32(struct Object *o, s32 fieldIndex, f32 value);` - -[:arrow_up_small:](#) - -
- -## [obj_get_nearest_object_with_behavior_id](#obj_get_nearest_object_with_behavior_id) - -### Description -Gets the nearest object with `behaviorId` to `o` - -### Lua Example -`local ObjectValue = obj_get_nearest_object_with_behavior_id(o, behaviorId)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *obj_get_nearest_object_with_behavior_id(struct Object *o, enum BehaviorId behaviorId);` - -[:arrow_up_small:](#) - -
- -## [obj_count_objects_with_behavior_id](#obj_count_objects_with_behavior_id) - -### Description -Counts every object with `behaviorId` - -### Lua Example -`local integerValue = obj_count_objects_with_behavior_id(behaviorId)` - -### Parameters -| Field | Type | -| ----- | ---- | -| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | - -### Returns -- `integer` - -### C Prototype -`s32 obj_count_objects_with_behavior_id(enum BehaviorId behaviorId);` - -[:arrow_up_small:](#) - -
- -## [obj_get_collided_object](#obj_get_collided_object) - -### Description -Gets the corresponding collided object to an index from `o` - -### Lua Example -`local ObjectValue = obj_get_collided_object(o, index)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| index | `integer` | - -### Returns -[Object](structs.md#Object) - -### C Prototype -`struct Object *obj_get_collided_object(struct Object *o, s16 index);` - -[:arrow_up_small:](#) - -
- -## [obj_get_field_u32](#obj_get_field_u32) - -### Description -Gets the unsigned 32-bit integer value from the field corresponding to `fieldIndex` - -### Lua Example -`local integerValue = obj_get_field_u32(o, fieldIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| fieldIndex | `integer` | - -### Returns -- `integer` - -### C Prototype -`u32 obj_get_field_u32(struct Object *o, s32 fieldIndex);` - -[:arrow_up_small:](#) - -
- -## [obj_get_field_s32](#obj_get_field_s32) - -### Description -Gets the signed 32-bit integer value from the field corresponding to `fieldIndex` - -### Lua Example -`local integerValue = obj_get_field_s32(o, fieldIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| fieldIndex | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 obj_get_field_s32(struct Object *o, s32 fieldIndex);` - -[:arrow_up_small:](#) - -
- -## [obj_get_field_f32](#obj_get_field_f32) - -### Description -Sets the float value from the field corresponding to `fieldIndex` - -### Lua Example -`local numberValue = obj_get_field_f32(o, fieldIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| fieldIndex | `integer` | - -### Returns -- `number` - -### C Prototype -`f32 obj_get_field_f32(struct Object *o, s32 fieldIndex);` - -[:arrow_up_small:](#) - -
- -## [obj_get_field_s16](#obj_get_field_s16) - -### Description -Gets the signed 32-bit integer value from the sub field corresponding to `fieldSubIndex` from the field corresponding to `fieldIndex` - -### Lua Example -`local integerValue = obj_get_field_s16(o, fieldIndex, fieldSubIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| fieldIndex | `integer` | -| fieldSubIndex | `integer` | - -### Returns -- `integer` - -### C Prototype -`s16 obj_get_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex);` - -[:arrow_up_small:](#) - -
- -## [obj_set_field_u32](#obj_set_field_u32) - -### Description -Sets the unsigned 32-bit integer value from the field corresponding to `fieldIndex` - -### Lua Example -`obj_set_field_u32(o, fieldIndex, value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| fieldIndex | `integer` | -| value | `integer` | - -### Returns -- None - -### C Prototype -`void obj_set_field_u32(struct Object *o, s32 fieldIndex, u32 value);` - -[:arrow_up_small:](#) - -
- -## [obj_set_field_s32](#obj_set_field_s32) - -### Description -Sets the signed 32-bit integer value from the field corresponding to `fieldIndex` - -### Lua Example -`obj_set_field_s32(o, fieldIndex, value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| fieldIndex | `integer` | -| value | `integer` | - -### Returns -- None - -### C Prototype -`void obj_set_field_s32(struct Object *o, s32 fieldIndex, s32 value);` - -[:arrow_up_small:](#) - -
- -## [obj_set_field_f32](#obj_set_field_f32) - -### Description -Sets the float value from the field corresponding to `fieldIndex` - -### Lua Example -`obj_set_field_f32(o, fieldIndex, value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| fieldIndex | `integer` | -| value | `number` | - -### Returns -- None - -### C Prototype -`void obj_set_field_f32(struct Object *o, s32 fieldIndex, f32 value);` - -[:arrow_up_small:](#) - -
- -## [obj_set_field_s16](#obj_set_field_s16) - -### Description -Sets the signed 32-bit integer value from the sub field corresponding to `fieldSubIndex` from the field corresponding to `fieldIndex` - -### Lua Example -`obj_set_field_s16(o, fieldIndex, fieldSubIndex, value)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| fieldIndex | `integer` | -| fieldSubIndex | `integer` | -| value | `integer` | - -### Returns -- None - -### C Prototype -`void obj_set_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex, s16 value);` - -[:arrow_up_small:](#) - -
- -## [obj_get_temp_spawn_particles_info](#obj_get_temp_spawn_particles_info) - -### Description -Returns a temporary particle spawn info pointer with its model loaded in from `modelId` - -### Lua Example -`local SpawnParticlesInfoValue = obj_get_temp_spawn_particles_info(modelId)` - -### Parameters -| Field | Type | -| ----- | ---- | -| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | - -### Returns -[SpawnParticlesInfo](structs.md#SpawnParticlesInfo) - -### C Prototype -`struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedId modelId);` - -[:arrow_up_small:](#) - -
- -## [get_temp_object_hitbox](#get_temp_object_hitbox) - -### Description -Returns a temporary object hitbox pointer - -### Lua Example -`local ObjectHitboxValue = get_temp_object_hitbox()` - -### Parameters -- None - -### Returns -[ObjectHitbox](structs.md#ObjectHitbox) - -### C Prototype -`struct ObjectHitbox* get_temp_object_hitbox(void);` - -[:arrow_up_small:](#) - -
- -## [obj_is_attackable](#obj_is_attackable) - -### Description -Checks if `o` is attackable - -### Lua Example -`local booleanValue = obj_is_attackable(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -- `boolean` - -### C Prototype -`bool obj_is_attackable(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_is_breakable_object](#obj_is_breakable_object) - -### Description -Checks if `o` is breakable - -### Lua Example -`local booleanValue = obj_is_breakable_object(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -- `boolean` - -### C Prototype -`bool obj_is_breakable_object(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_is_bully](#obj_is_bully) - -### Description -Checks if `o` is a Bully - -### Lua Example -`local booleanValue = obj_is_bully(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -- `boolean` - -### C Prototype -`bool obj_is_bully(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_is_coin](#obj_is_coin) - -### Description -Checks if `o` is a coin - -### Lua Example -`local booleanValue = obj_is_coin(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -- `boolean` - -### C Prototype -`bool obj_is_coin(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_is_exclamation_box](#obj_is_exclamation_box) - -### Description -Checks if `o` is an exclamation box - -### Lua Example -`local booleanValue = obj_is_exclamation_box(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -- `boolean` - -### C Prototype -`bool obj_is_exclamation_box(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_is_grabbable](#obj_is_grabbable) - -### Description -Checks if `o` is grabbable - -### Lua Example -`local booleanValue = obj_is_grabbable(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -- `boolean` - -### C Prototype -`bool obj_is_grabbable(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_is_mushroom_1up](#obj_is_mushroom_1up) - -### Description -Checks if `o` is a 1-Up Mushroom - -### Lua Example -`local booleanValue = obj_is_mushroom_1up(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -- `boolean` - -### C Prototype -`bool obj_is_mushroom_1up(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_is_secret](#obj_is_secret) - -### Description -Checks if `o` is a secret - -### Lua Example -`local booleanValue = obj_is_secret(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -- `boolean` - -### C Prototype -`bool obj_is_secret(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_is_valid_for_interaction](#obj_is_valid_for_interaction) - -### Description -Checks if `o` is activated, tangible, and interactible - -### Lua Example -`local booleanValue = obj_is_valid_for_interaction(o)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | - -### Returns -- `boolean` - -### C Prototype -`bool obj_is_valid_for_interaction(struct Object *o);` - -[:arrow_up_small:](#) - -
- -## [obj_check_hitbox_overlap](#obj_check_hitbox_overlap) - -### Description -Checks if `o1`'s hitbox is colliding with `o2`'s hitbox - -### Lua Example -`local booleanValue = obj_check_hitbox_overlap(o1, o2)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o1 | [Object](structs.md#Object) | -| o2 | [Object](structs.md#Object) | - -### Returns -- `boolean` - -### C Prototype -`bool obj_check_hitbox_overlap(struct Object *o1, struct Object *o2);` - -[:arrow_up_small:](#) - -
- -## [obj_check_overlap_with_hitbox_params](#obj_check_overlap_with_hitbox_params) - -### Description -Checks if `o`'s hitbox is colliding with the parameters of a hitbox - -### Lua Example -`local booleanValue = obj_check_overlap_with_hitbox_params(o, x, y, z, h, r, d)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| x | `number` | -| y | `number` | -| z | `number` | -| h | `number` | -| r | `number` | -| d | `number` | - -### Returns -- `boolean` - -### C Prototype -`bool obj_check_overlap_with_hitbox_params(struct Object *o, f32 x, f32 y, f32 z, f32 h, f32 r, f32 d);` - -[:arrow_up_small:](#) - -
- -## [obj_set_vel](#obj_set_vel) - -### Description -Sets an object's velocity to `vx`, `vy`, and `vz` - -### Lua Example -`obj_set_vel(o, vx, vy, vz)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| vx | `number` | -| vy | `number` | -| vz | `number` | - -### Returns -- None - -### C Prototype -`void obj_set_vel(struct Object *o, f32 vx, f32 vy, f32 vz);` - -[:arrow_up_small:](#) - -
- -## [obj_move_xyz](#obj_move_xyz) - -### Description -Moves the object in the direction of `dx`, `dy`, and `dz` - -### Lua Example -`obj_move_xyz(o, dx, dy, dz)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| dx | `number` | -| dy | `number` | -| dz | `number` | - -### Returns -- None - -### C Prototype -`void obj_move_xyz(struct Object *o, f32 dx, f32 dy, f32 dz);` - -[:arrow_up_small:](#) - -
- -## [set_whirlpools](#set_whirlpools) - -### Description -Sets the parameters of one of the two whirlpools (0-indexed) in an area - -### Lua Example -`set_whirlpools(x, y, z, strength, area, index)` - -### Parameters -| Field | Type | -| ----- | ---- | -| x | `number` | -| y | `number` | -| z | `number` | -| strength | `integer` | -| area | `integer` | -| index | `integer` | - -### Returns -- None - -### C Prototype -`void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index);` - -[:arrow_up_small:](#) - -
- ---- -# functions from smlua_text_utils.h - -
- - -## [smlua_text_utils_reset_all](#smlua_text_utils_reset_all) - -### Description -Resets every modified dialog back to vanilla - -### Lua Example -`smlua_text_utils_reset_all()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void smlua_text_utils_reset_all(void);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_dialog_get](#smlua_text_utils_dialog_get) - -### Description -Gets the DialogEntry struct for the given `dialogId` - -### Lua Example -`local DialogEntryValue = smlua_text_utils_dialog_get(dialogId)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dialogId | [enum DialogId](constants.md#enum-DialogId) | - -### Returns -[DialogEntry](structs.md#DialogEntry) - -### C Prototype -`struct DialogEntry* smlua_text_utils_dialog_get(enum DialogId dialogId);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_dialog_replace](#smlua_text_utils_dialog_replace) - -### Description -Replaces `dialogId` with a custom one - -### Lua Example -`smlua_text_utils_dialog_replace(dialogId, unused, linesPerBox, leftOffset, width, str)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dialogId | [enum DialogId](constants.md#enum-DialogId) | -| unused | `integer` | -| linesPerBox | `integer` | -| leftOffset | `integer` | -| width | `integer` | -| str | `string` | - -### Returns -- None - -### C Prototype -`void smlua_text_utils_dialog_replace(enum DialogId dialogId, u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_dialog_restore](#smlua_text_utils_dialog_restore) - -### Description -Restores a replaced DialogEntry to its original state. - -### Lua Example -`smlua_text_utils_dialog_restore(dialogId)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dialogId | [enum DialogId](constants.md#enum-DialogId) | - -### Returns -- None - -### C Prototype -`void smlua_text_utils_dialog_restore(enum DialogId dialogId);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_dialog_is_replaced](#smlua_text_utils_dialog_is_replaced) - -### Description -Returns whether the dialog with the given ID has been replaced - -### Lua Example -`local booleanValue = smlua_text_utils_dialog_is_replaced(dialogId)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dialogId | [enum DialogId](constants.md#enum-DialogId) | - -### Returns -- `boolean` - -### C Prototype -`bool smlua_text_utils_dialog_is_replaced(enum DialogId dialogId);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_allocate_dialog](#smlua_text_utils_allocate_dialog) - -### Description -Allocates a new dialog entry - -### Lua Example -`local integerValue = smlua_text_utils_allocate_dialog()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 smlua_text_utils_allocate_dialog(void);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_course_acts_replace](#smlua_text_utils_course_acts_replace) - -### Description -Replaces the act names of `courseNum` - -### Lua Example -`smlua_text_utils_course_acts_replace(courseNum, courseName, act1, act2, act3, act4, act5, act6)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | -| courseName | `string` | -| act1 | `string` | -| act2 | `string` | -| act3 | `string` | -| act4 | `string` | -| act5 | `string` | -| act6 | `string` | - -### Returns -- None - -### C Prototype -`void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_secret_star_replace](#smlua_text_utils_secret_star_replace) - -### Description -Replaces the secret star course name of `courseNum` with `courseName` - -### Lua Example -`smlua_text_utils_secret_star_replace(courseNum, courseName)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | -| courseName | `string` | - -### Returns -- None - -### C Prototype -`void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_course_name_replace](#smlua_text_utils_course_name_replace) - -### Description -Replaces the name of `courseNum` with `name` - -### Lua Example -`smlua_text_utils_course_name_replace(courseNum, name)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | -| name | `string` | - -### Returns -- None - -### C Prototype -`void smlua_text_utils_course_name_replace(s16 courseNum, const char* name);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_course_name_get](#smlua_text_utils_course_name_get) - -### Description -Gets the name of `courseNum` - -### Lua Example -`local stringValue = smlua_text_utils_course_name_get(courseNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | - -### Returns -- `string` - -### C Prototype -`const char* smlua_text_utils_course_name_get(s16 courseNum);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_course_name_mod_index](#smlua_text_utils_course_name_mod_index) - -### Description -Gets the index of the mod that replaced the name of `courseNum` - -### Lua Example -`local integerValue = smlua_text_utils_course_name_mod_index(courseNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 smlua_text_utils_course_name_mod_index(s16 courseNum);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_course_name_reset](#smlua_text_utils_course_name_reset) - -### Description -Resets the name of `courseNum` - -### Lua Example -`smlua_text_utils_course_name_reset(courseNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | - -### Returns -- None - -### C Prototype -`void smlua_text_utils_course_name_reset(s16 courseNum);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_act_name_replace](#smlua_text_utils_act_name_replace) - -### Description -Replaces the act name of `actNum` in `courseNum` with `name` - -### Lua Example -`smlua_text_utils_act_name_replace(courseNum, actNum, name)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | -| actNum | `integer` | -| name | `string` | - -### Returns -- None - -### C Prototype -`void smlua_text_utils_act_name_replace(s16 courseNum, u8 actNum, const char* name);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_act_name_get](#smlua_text_utils_act_name_get) - -### Description -Gets the act name of `actNum` in `courseNum` - -### Lua Example -`local stringValue = smlua_text_utils_act_name_get(courseNum, actNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | -| actNum | `integer` | - -### Returns -- `string` - -### C Prototype -`const char* smlua_text_utils_act_name_get(s16 courseNum, u8 actNum);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_act_name_mod_index](#smlua_text_utils_act_name_mod_index) - -### Description -Gets the index of the mod that replaced the act name of `actNum` in `courseNum` - -### Lua Example -`local integerValue = smlua_text_utils_act_name_mod_index(courseNum, actNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | -| actNum | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 smlua_text_utils_act_name_mod_index(s16 courseNum, u8 actNum);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_act_name_reset](#smlua_text_utils_act_name_reset) - -### Description -Resets the act name of `actNum` in `courseNum` - -### Lua Example -`smlua_text_utils_act_name_reset(courseNum, actNum)` - -### Parameters -| Field | Type | -| ----- | ---- | -| courseNum | `integer` | -| actNum | `integer` | - -### Returns -- None - -### C Prototype -`void smlua_text_utils_act_name_reset(s16 courseNum, u8 actNum);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_castle_secret_stars_replace](#smlua_text_utils_castle_secret_stars_replace) - -### Description -Replaces the castle secret stars text with `name` - -### Lua Example -`smlua_text_utils_castle_secret_stars_replace(name)` - -### Parameters -| Field | Type | -| ----- | ---- | -| name | `string` | - -### Returns -- None - -### C Prototype -`void smlua_text_utils_castle_secret_stars_replace(const char* name);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_castle_secret_stars_get](#smlua_text_utils_castle_secret_stars_get) - -### Description -Gets the castle secret stars text - -### Lua Example -`local stringValue = smlua_text_utils_castle_secret_stars_get()` - -### Parameters -- None - -### Returns -- `string` - -### C Prototype -`const char* smlua_text_utils_castle_secret_stars_get();` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_castle_secret_stars_mod_index](#smlua_text_utils_castle_secret_stars_mod_index) - -### Description -Gets the index of the mod that replaced the castle secret stars text - -### Lua Example -`local integerValue = smlua_text_utils_castle_secret_stars_mod_index()` - -### Parameters -- None - -### Returns -- `integer` - -### C Prototype -`s32 smlua_text_utils_castle_secret_stars_mod_index();` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_castle_secret_stars_reset](#smlua_text_utils_castle_secret_stars_reset) - -### Description -Resets the castle secret stars text - -### Lua Example -`smlua_text_utils_castle_secret_stars_reset()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void smlua_text_utils_castle_secret_stars_reset();` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_extra_text_replace](#smlua_text_utils_extra_text_replace) - -### Description -Replace extra text (e.g. one of the castle's secret stars) with `text` - -### Lua Example -`smlua_text_utils_extra_text_replace(index, text)` - -### Parameters -| Field | Type | -| ----- | ---- | -| index | `integer` | -| text | `string` | - -### Returns -- None - -### C Prototype -`void smlua_text_utils_extra_text_replace(s16 index, const char* text);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_extra_text_get](#smlua_text_utils_extra_text_get) - -### Description -Gets the extra text at `index` - -### Lua Example -`local stringValue = smlua_text_utils_extra_text_get(index)` - -### Parameters -| Field | Type | -| ----- | ---- | -| index | `integer` | - -### Returns -- `string` - -### C Prototype -`const char* smlua_text_utils_extra_text_get(s16 index);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_extra_text_mod_index](#smlua_text_utils_extra_text_mod_index) - -### Description -Gets the index of the mod that replaced the extra text at `index` - -### Lua Example -`local integerValue = smlua_text_utils_extra_text_mod_index(index)` - -### Parameters -| Field | Type | -| ----- | ---- | -| index | `integer` | - -### Returns -- `integer` - -### C Prototype -`s32 smlua_text_utils_extra_text_mod_index(s16 index);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_extra_text_reset](#smlua_text_utils_extra_text_reset) - -### Description -Resets the extra text at `index` - -### Lua Example -`smlua_text_utils_extra_text_reset(index)` - -### Parameters -| Field | Type | -| ----- | ---- | -| index | `integer` | - -### Returns -- None - -### C Prototype -`void smlua_text_utils_extra_text_reset(s16 index);` - -[:arrow_up_small:](#) - -
- -## [smlua_text_utils_get_language](#smlua_text_utils_get_language) - -### Description -Gets the current language - -### Lua Example -`local stringValue = smlua_text_utils_get_language()` - -### Parameters -- None - -### Returns -- `string` - -### C Prototype -`const char* smlua_text_utils_get_language(void);` - -[:arrow_up_small:](#) - -
- ---- -# functions from sound_init.h - -
- - -## [reset_volume](#reset_volume) - -### Description -Resets if music volume has been lowered - -### Lua Example -`reset_volume()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void reset_volume(void);` - -[:arrow_up_small:](#) - -
- -## [raise_background_noise](#raise_background_noise) - -### Description -Raises music volume back up to normal levels - -### Lua Example -`raise_background_noise(a)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a | `integer` | - -### Returns -- None - -### C Prototype -`void raise_background_noise(s32 a);` - -[:arrow_up_small:](#) - -
- -## [lower_background_noise](#lower_background_noise) - -### Description -Lowers the volume of music by 40% - -### Lua Example -`lower_background_noise(a)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a | `integer` | - -### Returns -- None - -### C Prototype -`void lower_background_noise(s32 a);` - -[:arrow_up_small:](#) - -
- -## [disable_background_sound](#disable_background_sound) - -### Description -Disables background soundbanks - -### Lua Example -`disable_background_sound()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void disable_background_sound(void);` - -[:arrow_up_small:](#) - -
- -## [enable_background_sound](#enable_background_sound) - -### Description -Enables background soundbanks - -### Lua Example -`enable_background_sound()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void enable_background_sound(void);` - -[:arrow_up_small:](#) - -
- -## [play_menu_sounds](#play_menu_sounds) - -### Description -Play menu sounds from `SOUND_MENU_FLAG_*` constants and queues rumble if `SOUND_MENU_FLAG_LETGOMARIOFACE` is one of the flags - -### Lua Example -`play_menu_sounds(soundMenuFlags)` - -### Parameters -| Field | Type | -| ----- | ---- | -| soundMenuFlags | `integer` | - -### Returns -- None - -### C Prototype -`void play_menu_sounds(s16 soundMenuFlags);` - -[:arrow_up_small:](#) - -
- -## [play_painting_eject_sound](#play_painting_eject_sound) - -### Description -Plays the painting eject sound effect if it has not already been played - -### Lua Example -`play_painting_eject_sound()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void play_painting_eject_sound(void);` - -[:arrow_up_small:](#) - -
- -## [play_infinite_stairs_music](#play_infinite_stairs_music) - -### Description -Plays the infinite stairs music if you're in the endless stairs room and have less than `gLevelValues.infiniteStairsRequirement` stars - -### Lua Example -`play_infinite_stairs_music()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void play_infinite_stairs_music(void);` - -[:arrow_up_small:](#) - -
- -## [set_background_music](#set_background_music) - -### Description -Sets the background music to `seqArgs` on sequence player `a` with a fade in time of `fadeTimer` - -### Lua Example -`set_background_music(a, seqArgs, fadeTimer)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a | `integer` | -| seqArgs | `integer` | -| fadeTimer | `integer` | - -### Returns -- None - -### C Prototype -`void set_background_music(u16 a, u16 seqArgs, s16 fadeTimer);` - -[:arrow_up_small:](#) - -
- -## [fadeout_music](#fadeout_music) - -### Description -Fades out level, shell, and cap music - -### Lua Example -`fadeout_music(fadeOutTime)` - -### Parameters -| Field | Type | -| ----- | ---- | -| fadeOutTime | `integer` | - -### Returns -- None - -### C Prototype -`void fadeout_music(s16 fadeOutTime);` - -[:arrow_up_small:](#) - -
- -## [fadeout_level_music](#fadeout_level_music) - -### Description -Fades out the level sequence player - -### Lua Example -`fadeout_level_music(fadeTimer)` - -### Parameters -| Field | Type | -| ----- | ---- | -| fadeTimer | `integer` | - -### Returns -- None - -### C Prototype -`void fadeout_level_music(s16 fadeTimer);` - -[:arrow_up_small:](#) - -
- -## [play_cutscene_music](#play_cutscene_music) - -### Description -Plays and sets the current music to `seqArgs` - -### Lua Example -`play_cutscene_music(seqArgs)` - -### Parameters -| Field | Type | -| ----- | ---- | -| seqArgs | `integer` | - -### Returns -- None - -### C Prototype -`void play_cutscene_music(u16 seqArgs);` - -[:arrow_up_small:](#) - -
- -## [play_shell_music](#play_shell_music) - -### Description -Plays shell music - -### Lua Example -`play_shell_music()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void play_shell_music(void);` - -[:arrow_up_small:](#) - -
- -## [stop_shell_music](#stop_shell_music) - -### Description -Stops shell music completely - -### Lua Example -`stop_shell_music()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void stop_shell_music(void);` - -[:arrow_up_small:](#) - -
- -## [play_cap_music](#play_cap_music) - -### Description -Plays `seqArgs` as cap music - -### Lua Example -`play_cap_music(seqArgs)` - -### Parameters -| Field | Type | -| ----- | ---- | -| seqArgs | `integer` | - -### Returns -- None - -### C Prototype -`void play_cap_music(u16 seqArgs);` - -[:arrow_up_small:](#) - -
- -## [fadeout_cap_music](#fadeout_cap_music) - -### Description -Fades out cap music - -### Lua Example -`fadeout_cap_music()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void fadeout_cap_music(void);` - -[:arrow_up_small:](#) - -
- -## [stop_cap_music](#stop_cap_music) - -### Description -Stops cap music completely - -### Lua Example -`stop_cap_music()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void stop_cap_music(void);` - -[:arrow_up_small:](#) - -
- ---- -# functions from spawn_sound.h - -
- - -## [cur_obj_play_sound_1](#cur_obj_play_sound_1) - -### Description -Plays a sound if the current object is visible - -### Lua Example -`cur_obj_play_sound_1(soundMagic)` - -### Parameters -| Field | Type | -| ----- | ---- | -| soundMagic | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_play_sound_1(s32 soundMagic);` - -[:arrow_up_small:](#) - -
- -## [cur_obj_play_sound_2](#cur_obj_play_sound_2) - -### Description -Plays a sound if the current object is visible and queues rumble for specific sounds - -### Lua Example -`cur_obj_play_sound_2(soundMagic)` - -### Parameters -| Field | Type | -| ----- | ---- | -| soundMagic | `integer` | - -### Returns -- None - -### C Prototype -`void cur_obj_play_sound_2(s32 soundMagic);` - -[:arrow_up_small:](#) - -
- -## [create_sound_spawner](#create_sound_spawner) - -### Description -Create a sound spawner for objects that need a sound play once. (Breakable walls, King Bobomb exploding, etc) - -### Lua Example -`create_sound_spawner(soundMagic)` - -### Parameters -| Field | Type | -| ----- | ---- | -| soundMagic | `integer` | - -### Returns -- None - -### C Prototype -`void create_sound_spawner(s32 soundMagic);` - -[:arrow_up_small:](#) - -
- -## [calc_dist_to_volume_range_1](#calc_dist_to_volume_range_1) - -### Description -Unused vanilla function, calculates a volume based on `distance`. If `distance` is less than 500 then 127, if `distance` is greater than 1500 then 0, if `distance` is between 500 and 1500 then it ranges linearly from 60 to 124. What an even more strange and confusing function - -### Lua Example -`local integerValue = calc_dist_to_volume_range_1(distance)` - -### Parameters -| Field | Type | -| ----- | ---- | -| distance | `number` | - -### Returns -- `integer` - -### C Prototype -`s32 calc_dist_to_volume_range_1(f32 distance);` - -[:arrow_up_small:](#) - -
- -## [calc_dist_to_volume_range_2](#calc_dist_to_volume_range_2) - -### Description -Unused vanilla function, calculates a volume based on `distance`. If `distance` is less than 1300 then 127, if `distance` is greater than 2300 then 0, if `distance` is between 1300 and 2300 then it ranges linearly from 60 to 127. What a strange and confusing function - -### Lua Example -`local integerValue = calc_dist_to_volume_range_2(distance)` - -### Parameters -| Field | Type | -| ----- | ---- | -| distance | `number` | - -### Returns -- `integer` - -### C Prototype -`s32 calc_dist_to_volume_range_2(f32 distance);` - -[:arrow_up_small:](#) - -
- ---- -# functions from surface_collision.h - -
- - -## [find_wall_collisions](#find_wall_collisions) - -### Description -Detects wall collisions at a given position and adjusts the position based on the walls found. Returns the number of wall collisions detected - -### Lua Example -`local integerValue = find_wall_collisions(colData)` - -### Parameters -| Field | Type | -| ----- | ---- | -| colData | [WallCollisionData](structs.md#WallCollisionData) | - -### Returns -- `integer` - -### C Prototype -`s32 find_wall_collisions(struct WallCollisionData *colData);` - -[:arrow_up_small:](#) - -
- -## [find_ceil_height](#find_ceil_height) - -### Description -Finds the height of the highest ceiling above a given position (x, y, z). If no ceiling is found, returns the default height limit of `gLevelValues.cellHeightLimit`(20000 by default) - -### Lua Example -`local numberValue = find_ceil_height(x, y, z)` - -### Parameters -| Field | Type | -| ----- | ---- | -| x | `number` | -| y | `number` | -| z | `number` | - -### Returns -- `number` - -### C Prototype -`f32 find_ceil_height(f32 x, f32 y, f32 z);` - -[:arrow_up_small:](#) - -
- -## [find_floor_height](#find_floor_height) - -### Description -Finds the height of the highest floor below a given position (x, y, z). If no floor is found, returns the default floor height of `gLevelValues.floorLowerLimit`(-11000 by default) - -### Lua Example -`local numberValue = find_floor_height(x, y, z)` - -### Parameters -| Field | Type | -| ----- | ---- | -| x | `number` | -| y | `number` | -| z | `number` | - -### Returns -- `number` - -### C Prototype -`f32 find_floor_height(f32 x, f32 y, f32 z);` - -[:arrow_up_small:](#) - -
- -## [find_water_level](#find_water_level) - -### Description -Finds the height of water at a given position (x, z), if the position is within a water region. If no water is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default) - -### Lua Example -`local numberValue = find_water_level(x, z)` - -### Parameters -| Field | Type | -| ----- | ---- | -| x | `number` | -| z | `number` | - -### Returns -- `number` - -### C Prototype -`f32 find_water_level(f32 x, f32 z);` - -[:arrow_up_small:](#) - -
- -## [find_poison_gas_level](#find_poison_gas_level) - -### Description -Finds the height of the poison gas at a given position (x, z), if the position is within a gas region. If no gas is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default) - -### Lua Example -`local numberValue = find_poison_gas_level(x, z)` - -### Parameters -| Field | Type | -| ----- | ---- | -| x | `number` | -| z | `number` | - -### Returns -- `number` - -### C Prototype -`f32 find_poison_gas_level(f32 x, f32 z);` - -[:arrow_up_small:](#) - -
- -## [set_find_wall_direction](#set_find_wall_direction) - -### Description -Sets whether collision finding functions should check wall directions. - -### Lua Example -`set_find_wall_direction(dir, active, airborne)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dir | [Vec3f](structs.md#Vec3f) | -| active | `boolean` | -| airborne | `boolean` | - -### Returns -- None - -### C Prototype -`void set_find_wall_direction(Vec3f dir, bool active, bool airborne);` - -[:arrow_up_small:](#) - -
- -## [closest_point_to_triangle](#closest_point_to_triangle) - -### Description -Gets the closest point of the triangle to `src` and returns it in `out`. - -### Lua Example -`closest_point_to_triangle(surf, src, out)` - -### Parameters -| Field | Type | -| ----- | ---- | -| surf | [Surface](structs.md#Surface) | -| src | [Vec3f](structs.md#Vec3f) | -| out | [Vec3f](structs.md#Vec3f) | - -### Returns -- None - -### C Prototype -`void closest_point_to_triangle(struct Surface* surf, Vec3f src, OUT Vec3f out);` - -[:arrow_up_small:](#) - -
- ---- -# functions from surface_load.h - -
- - -## [load_object_collision_model](#load_object_collision_model) - -### Description -Loads the object's collision data into dynamic collision. You must run this every frame in your object's behavior loop for it to have collision - -### Lua Example -`load_object_collision_model()` - -### Parameters -- None - -### Returns -- None - -### C Prototype -`void load_object_collision_model(void);` - -[:arrow_up_small:](#) - -
- -## [obj_get_surface_from_index](#obj_get_surface_from_index) - -### Description -Gets a surface corresponding to `index` from the surface pool buffer - -### Lua Example -`local SurfaceValue = obj_get_surface_from_index(o, index)` - -### Parameters -| Field | Type | -| ----- | ---- | -| o | [Object](structs.md#Object) | -| index | `integer` | - -### Returns -[Surface](structs.md#Surface) - -### C Prototype -`struct Surface *obj_get_surface_from_index(struct Object *o, u32 index);` - -[:arrow_up_small:](#) - -
- -## [surface_has_force](#surface_has_force) - -### Description -Checks if a surface has force - -### Lua Example -`local booleanValue = surface_has_force(surfaceType)` - -### Parameters -| Field | Type | -| ----- | ---- | -| surfaceType | `integer` | - -### Returns -- `boolean` - -### C Prototype -`bool surface_has_force(s16 surfaceType);` - -[:arrow_up_small:](#) -
--- diff --git a/docs/lua/functions-7.md b/docs/lua/functions-7.md index bc3786df4..bfb92be17 100644 --- a/docs/lua/functions-7.md +++ b/docs/lua/functions-7.md @@ -5,6 +5,4787 @@ [< prev](functions-6.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | 7] +--- +# functions from smlua_level_utils.h + +
+ + +## [smlua_level_util_change_area](#smlua_level_util_change_area) + +### Description +Instantly changes the current area to `areaIndex` + +### Lua Example +`smlua_level_util_change_area(areaIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| areaIndex | `integer` | + +### Returns +- None + +### C Prototype +`void smlua_level_util_change_area(s32 areaIndex);` + +[:arrow_up_small:](#) + +
+ +## [smlua_level_util_get_info](#smlua_level_util_get_info) + +### Description +Gets information on a custom level from `levelNum` + +### Lua Example +`local CustomLevelInfoValue = smlua_level_util_get_info(levelNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| levelNum | `integer` | + +### Returns +[CustomLevelInfo](structs.md#CustomLevelInfo) + +### C Prototype +`struct CustomLevelInfo* smlua_level_util_get_info(s16 levelNum);` + +[:arrow_up_small:](#) + +
+ +## [smlua_level_util_get_info_from_short_name](#smlua_level_util_get_info_from_short_name) + +### Description +Gets information on a custom level from `shortName` + +### Lua Example +`local CustomLevelInfoValue = smlua_level_util_get_info_from_short_name(shortName)` + +### Parameters +| Field | Type | +| ----- | ---- | +| shortName | `string` | + +### Returns +[CustomLevelInfo](structs.md#CustomLevelInfo) + +### C Prototype +`struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(const char* shortName);` + +[:arrow_up_small:](#) + +
+ +## [smlua_level_util_get_info_from_course_num](#smlua_level_util_get_info_from_course_num) + +### Description +Gets information on a custom level from `courseNum` + +### Lua Example +`local CustomLevelInfoValue = smlua_level_util_get_info_from_course_num(courseNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | + +### Returns +[CustomLevelInfo](structs.md#CustomLevelInfo) + +### C Prototype +`struct CustomLevelInfo* smlua_level_util_get_info_from_course_num(u8 courseNum);` + +[:arrow_up_small:](#) + +
+ +## [level_register](#level_register) + +### Description +Registers a fully custom level. Level ID begins at 50 + +### Lua Example +`local integerValue = level_register(scriptEntryName, courseNum, fullName, shortName, acousticReach, echoLevel1, echoLevel2, echoLevel3)` + +### Parameters +| Field | Type | +| ----- | ---- | +| scriptEntryName | `string` | +| courseNum | `integer` | +| fullName | `string` | +| shortName | `string` | +| acousticReach | `integer` | +| echoLevel1 | `integer` | +| echoLevel2 | `integer` | +| echoLevel3 | `integer` | + +### Returns +- `integer` + +### C Prototype +`s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3);` + +[:arrow_up_small:](#) + +
+ +## [level_is_vanilla_level](#level_is_vanilla_level) + +### Description +Checks if `levelNum` is a vanilla level + +### Lua Example +`local booleanValue = level_is_vanilla_level(levelNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| levelNum | `integer` | + +### Returns +- `boolean` + +### C Prototype +`bool level_is_vanilla_level(s16 levelNum);` + +[:arrow_up_small:](#) + +
+ +## [warp_to_warpnode](#warp_to_warpnode) + +### Description +Warps to `aWarpId` of `aArea` in `aLevel` during `aAct` + +### Lua Example +`local booleanValue = warp_to_warpnode(aLevel, aArea, aAct, aWarpId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| aLevel | `integer` | +| aArea | `integer` | +| aAct | `integer` | +| aWarpId | `integer` | + +### Returns +- `boolean` + +### C Prototype +`bool warp_to_warpnode(s32 aLevel, s32 aArea, s32 aAct, s32 aWarpId);` + +[:arrow_up_small:](#) + +
+ +## [warp_to_level](#warp_to_level) + +### Description +Warps to `aArea` of `aLevel` in `aAct` + +### Lua Example +`local booleanValue = warp_to_level(aLevel, aArea, aAct)` + +### Parameters +| Field | Type | +| ----- | ---- | +| aLevel | `integer` | +| aArea | `integer` | +| aAct | `integer` | + +### Returns +- `boolean` + +### C Prototype +`bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct);` + +[:arrow_up_small:](#) + +
+ +## [warp_restart_level](#warp_restart_level) + +### Description +Restarts the current level + +### Lua Example +`local booleanValue = warp_restart_level()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool warp_restart_level(void);` + +[:arrow_up_small:](#) + +
+ +## [warp_to_start_level](#warp_to_start_level) + +### Description +Warps to the start level (Castle Grounds by default) + +### Lua Example +`local booleanValue = warp_to_start_level()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool warp_to_start_level(void);` + +[:arrow_up_small:](#) + +
+ +## [warp_exit_level](#warp_exit_level) + +### Description +Exits the current level after `aDelay` + +### Lua Example +`local booleanValue = warp_exit_level(aDelay)` + +### Parameters +| Field | Type | +| ----- | ---- | +| aDelay | `integer` | + +### Returns +- `boolean` + +### C Prototype +`bool warp_exit_level(s32 aDelay);` + +[:arrow_up_small:](#) + +
+ +## [warp_to_castle](#warp_to_castle) + +### Description +Warps back to the castle from `aLevel` + +### Lua Example +`local booleanValue = warp_to_castle(aLevel)` + +### Parameters +| Field | Type | +| ----- | ---- | +| aLevel | `integer` | + +### Returns +- `boolean` + +### C Prototype +`bool warp_to_castle(s32 aLevel);` + +[:arrow_up_small:](#) + +
+ +--- +# functions from smlua_misc_utils.h + +
+ + +## [get_network_area_timer](#get_network_area_timer) + +### Description +Gets the current area's networked timer + +### Lua Example +`local integerValue = get_network_area_timer()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u32 get_network_area_timer(void);` + +[:arrow_up_small:](#) + +
+ +## [get_area_update_counter](#get_area_update_counter) + +### Description +Gets the area update counter incremented when objects are updated + +### Lua Example +`local integerValue = get_area_update_counter()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u16 get_area_update_counter(void);` + +[:arrow_up_small:](#) + +
+ +## [get_temp_s32_pointer](#get_temp_s32_pointer) + +### Description +Returns a temporary signed 32-bit integer pointer with its value set to `initialValue` + +### Lua Example +`local PointerValue = get_temp_s32_pointer(initialValue)` + +### Parameters +| Field | Type | +| ----- | ---- | +| initialValue | `integer` | + +### Returns +- `Pointer` <`integer`> + +### C Prototype +`s32* get_temp_s32_pointer(s32 initialValue);` + +[:arrow_up_small:](#) + +
+ +## [deref_s32_pointer](#deref_s32_pointer) + +### Description +Gets the signed 32-bit integer value from `pointer` + +### Lua Example +`local integerValue = deref_s32_pointer(pointer)` + +### Parameters +| Field | Type | +| ----- | ---- | +| pointer | `Pointer` <`integer`> | + +### Returns +- `integer` + +### C Prototype +`s32 deref_s32_pointer(s32* pointer);` + +[:arrow_up_small:](#) + +
+ +## [djui_popup_create_global](#djui_popup_create_global) + +### Description +Creates a DJUI popup that is broadcasted to every client + +### Lua Example +`djui_popup_create_global(message, lines)` + +### Parameters +| Field | Type | +| ----- | ---- | +| message | `string` | +| lines | `integer` | + +### Returns +- None + +### C Prototype +`void djui_popup_create_global(const char* message, int lines);` + +[:arrow_up_small:](#) + +
+ +## [djui_is_popup_disabled](#djui_is_popup_disabled) + +### Description +Returns if popups are disabled + +### Lua Example +`local booleanValue = djui_is_popup_disabled()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool djui_is_popup_disabled(void);` + +[:arrow_up_small:](#) + +
+ +## [djui_set_popup_disabled_override](#djui_set_popup_disabled_override) + +### Description +Sets if popups are disabled + +### Lua Example +`djui_set_popup_disabled_override(value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| value | `boolean` | + +### Returns +- None + +### C Prototype +`void djui_set_popup_disabled_override(bool value);` + +[:arrow_up_small:](#) + +
+ +## [djui_reset_popup_disabled_override](#djui_reset_popup_disabled_override) + +### Description +Resets if popups are disabled + +### Lua Example +`djui_reset_popup_disabled_override()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void djui_reset_popup_disabled_override(void);` + +[:arrow_up_small:](#) + +
+ +## [djui_is_playerlist_open](#djui_is_playerlist_open) + +### Description +Checks if the DJUI playerlist is open + +### Lua Example +`local booleanValue = djui_is_playerlist_open()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool djui_is_playerlist_open(void);` + +[:arrow_up_small:](#) + +
+ +## [djui_attempting_to_open_playerlist](#djui_attempting_to_open_playerlist) + +### Description +Checks if the DJUI playerlist is attempting to be opened + +### Lua Example +`local booleanValue = djui_attempting_to_open_playerlist()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool djui_attempting_to_open_playerlist(void);` + +[:arrow_up_small:](#) + +
+ +## [djui_get_playerlist_page_index](#djui_get_playerlist_page_index) + +### Description +Gets the DJUI playerlist's page index + +### Lua Example +`local integerValue = djui_get_playerlist_page_index()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u8 djui_get_playerlist_page_index(void);` + +[:arrow_up_small:](#) + +
+ +## [djui_menu_get_font](#djui_menu_get_font) + +### Description +Gets the DJUI menu font + +### Lua Example +`local enumValue = djui_menu_get_font()` + +### Parameters +- None + +### Returns +[enum DjuiFontType](constants.md#enum-DjuiFontType) + +### C Prototype +`enum DjuiFontType djui_menu_get_font(void);` + +[:arrow_up_small:](#) + +
+ +## [djui_menu_get_theme](#djui_menu_get_theme) + +### Description +Gets the DJUI menu theme + +### Lua Example +`local DjuiThemeValue = djui_menu_get_theme()` + +### Parameters +- None + +### Returns +[DjuiTheme](structs.md#DjuiTheme) + +### C Prototype +`struct DjuiTheme* djui_menu_get_theme(void);` + +[:arrow_up_small:](#) + +
+ +## [djui_is_playerlist_ping_visible](#djui_is_playerlist_ping_visible) + +### Description +Checks if the DJUI playerlist ping icon is visible + +### Lua Example +`local booleanValue = djui_is_playerlist_ping_visible()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool djui_is_playerlist_ping_visible(void);` + +[:arrow_up_small:](#) + +
+ +## [get_dialog_box_state](#get_dialog_box_state) + +### Description +Gets the current state of the dialog box + +### Lua Example +`local integerValue = get_dialog_box_state()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s8 get_dialog_box_state(void);` + +[:arrow_up_small:](#) + +
+ +## [get_dialog_id](#get_dialog_id) + +### Description +Gets the current dialog box ID + +### Lua Example +`local integerValue = get_dialog_id()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 get_dialog_id(void);` + +[:arrow_up_small:](#) + +
+ +## [get_last_star_or_key](#get_last_star_or_key) + +### Description +Gets if the last objective collected was a star (0) or a key (1) + +### Lua Example +`local integerValue = get_last_star_or_key()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u8 get_last_star_or_key(void);` + +[:arrow_up_small:](#) + +
+ +## [set_last_star_or_key](#set_last_star_or_key) + +### Description +Sets if the last objective collected was a star (0) or a key (1) + +### Lua Example +`set_last_star_or_key(value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| value | `integer` | + +### Returns +- None + +### C Prototype +`void set_last_star_or_key(u8 value);` + +[:arrow_up_small:](#) + +
+ +## [get_last_completed_course_num](#get_last_completed_course_num) + +### Description +Gets the last course a star or key was collected in + +### Lua Example +`local integerValue = get_last_completed_course_num()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u8 get_last_completed_course_num(void);` + +[:arrow_up_small:](#) + +
+ +## [set_last_completed_course_num](#set_last_completed_course_num) + +### Description +Sets the last course a star or key was collected in + +### Lua Example +`set_last_completed_course_num(courseNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | + +### Returns +- None + +### C Prototype +`void set_last_completed_course_num(u8 courseNum);` + +[:arrow_up_small:](#) + +
+ +## [get_last_completed_star_num](#get_last_completed_star_num) + +### Description +Gets the last collected star's number (1-7) + +### Lua Example +`local integerValue = get_last_completed_star_num()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u8 get_last_completed_star_num(void);` + +[:arrow_up_small:](#) + +
+ +## [set_last_completed_star_num](#set_last_completed_star_num) + +### Description +Sets the last collected star's number (1-7) + +### Lua Example +`set_last_completed_star_num(starNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| starNum | `integer` | + +### Returns +- None + +### C Prototype +`void set_last_completed_star_num(u8 starNum);` + +[:arrow_up_small:](#) + +
+ +## [get_got_file_coin_hi_score](#get_got_file_coin_hi_score) + +### Description +Checks if the save file's coin "HI SCORE" was obtained with the last star or key collection + +### Lua Example +`local booleanValue = get_got_file_coin_hi_score()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool get_got_file_coin_hi_score(void);` + +[:arrow_up_small:](#) + +
+ +## [set_got_file_coin_hi_score](#set_got_file_coin_hi_score) + +### Description +Sets if the save file's coin "HI SCORE" was obtained with the last star or key collection + +### Lua Example +`set_got_file_coin_hi_score(value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| value | `boolean` | + +### Returns +- None + +### C Prototype +`void set_got_file_coin_hi_score(bool value);` + +[:arrow_up_small:](#) + +
+ +## [get_save_file_modified](#get_save_file_modified) + +### Description +Checks if the save file has been modified without saving + +### Lua Example +`local booleanValue = get_save_file_modified()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool get_save_file_modified(void);` + +[:arrow_up_small:](#) + +
+ +## [set_save_file_modified](#set_save_file_modified) + +### Description +Sets if the save file has been modified without saving + +### Lua Example +`set_save_file_modified(value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| value | `boolean` | + +### Returns +- None + +### C Prototype +`void set_save_file_modified(bool value);` + +[:arrow_up_small:](#) + +
+ +## [hud_hide](#hud_hide) + +### Description +Hides the HUD + +### Lua Example +`hud_hide()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void hud_hide(void);` + +[:arrow_up_small:](#) + +
+ +## [hud_show](#hud_show) + +### Description +Shows the HUD + +### Lua Example +`hud_show()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void hud_show(void);` + +[:arrow_up_small:](#) + +
+ +## [hud_is_hidden](#hud_is_hidden) + +### Description +Checks if the HUD is hidden + +### Lua Example +`local booleanValue = hud_is_hidden()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool hud_is_hidden(void);` + +[:arrow_up_small:](#) + +
+ +## [hud_get_value](#hud_get_value) + +### Description +Gets a HUD display value + +### Lua Example +`local integerValue = hud_get_value(type)` + +### Parameters +| Field | Type | +| ----- | ---- | +| type | [enum HudDisplayValue](constants.md#enum-HudDisplayValue) | + +### Returns +- `integer` + +### C Prototype +`s32 hud_get_value(enum HudDisplayValue type);` + +[:arrow_up_small:](#) + +
+ +## [hud_set_value](#hud_set_value) + +### Description +Sets a HUD display value + +### Lua Example +`hud_set_value(type, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| type | [enum HudDisplayValue](constants.md#enum-HudDisplayValue) | +| value | `integer` | + +### Returns +- None + +### C Prototype +`void hud_set_value(enum HudDisplayValue type, s32 value);` + +[:arrow_up_small:](#) + +
+ +## [hud_render_power_meter](#hud_render_power_meter) + +### Description +Renders a power meter on the HUD + +### Lua Example +`hud_render_power_meter(health, x, y, width, height)` + +### Parameters +| Field | Type | +| ----- | ---- | +| health | `integer` | +| x | `number` | +| y | `number` | +| width | `number` | +| height | `number` | + +### Returns +- None + +### C Prototype +`void hud_render_power_meter(s32 health, f32 x, f32 y, f32 width, f32 height);` + +[:arrow_up_small:](#) + +
+ +## [hud_render_power_meter_interpolated](#hud_render_power_meter_interpolated) + +### Description +Renders an interpolated power meter on the HUD + +### Lua Example +`hud_render_power_meter_interpolated(health, prevX, prevY, prevWidth, prevHeight, x, y, width, height)` + +### Parameters +| Field | Type | +| ----- | ---- | +| health | `integer` | +| prevX | `number` | +| prevY | `number` | +| prevWidth | `number` | +| prevHeight | `number` | +| x | `number` | +| y | `number` | +| width | `number` | +| height | `number` | + +### Returns +- None + +### C Prototype +`void hud_render_power_meter_interpolated(s32 health, f32 prevX, f32 prevY, f32 prevWidth, f32 prevHeight, f32 x, f32 y, f32 width, f32 height);` + +[:arrow_up_small:](#) + +
+ +## [hud_get_flash](#hud_get_flash) + +### Description +Gets if the star counter on the HUD should flash + +### Lua Example +`local integerValue = hud_get_flash()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s8 hud_get_flash(void);` + +[:arrow_up_small:](#) + +
+ +## [hud_set_flash](#hud_set_flash) + +### Description +Sets if the star counter on the HUD should flash + +### Lua Example +`hud_set_flash(value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| value | `integer` | + +### Returns +- None + +### C Prototype +`void hud_set_flash(s8 value);` + +[:arrow_up_small:](#) + +
+ +## [act_select_hud_hide](#act_select_hud_hide) + +### Description +Hides part of the Act Select HUD + +### Lua Example +`act_select_hud_hide(part)` + +### Parameters +| Field | Type | +| ----- | ---- | +| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) | + +### Returns +- None + +### C Prototype +`void act_select_hud_hide(enum ActSelectHudPart part);` + +[:arrow_up_small:](#) + +
+ +## [act_select_hud_show](#act_select_hud_show) + +### Description +Shows part of the Act Select HUD + +### Lua Example +`act_select_hud_show(part)` + +### Parameters +| Field | Type | +| ----- | ---- | +| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) | + +### Returns +- None + +### C Prototype +`void act_select_hud_show(enum ActSelectHudPart part);` + +[:arrow_up_small:](#) + +
+ +## [act_select_hud_is_hidden](#act_select_hud_is_hidden) + +### Description +Checks if part of the Act Select HUD is hidden + +### Lua Example +`local booleanValue = act_select_hud_is_hidden(part)` + +### Parameters +| Field | Type | +| ----- | ---- | +| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) | + +### Returns +- `boolean` + +### C Prototype +`bool act_select_hud_is_hidden(enum ActSelectHudPart part);` + +[:arrow_up_small:](#) + +
+ +## [is_game_paused](#is_game_paused) + +### Description +Checks if the game is paused + +### Lua Example +`local booleanValue = is_game_paused()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool is_game_paused(void);` + +[:arrow_up_small:](#) + +
+ +## [is_transition_playing](#is_transition_playing) + +### Description +Checks if a screen transition is playing + +### Lua Example +`local booleanValue = is_transition_playing()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool is_transition_playing(void);` + +[:arrow_up_small:](#) + +
+ +## [allocate_mario_action](#allocate_mario_action) + +### Description +Allocates an action ID with bitwise flags + +### Lua Example +`local integerValue = allocate_mario_action(actFlags)` + +### Parameters +| Field | Type | +| ----- | ---- | +| actFlags | `integer` | + +### Returns +- `integer` + +### C Prototype +`u32 allocate_mario_action(u32 actFlags);` + +[:arrow_up_small:](#) + +
+ +## [get_hand_foot_pos_x](#get_hand_foot_pos_x) + +### Description +Gets the X coordinate of Mario's hand (0-1) or foot (2-3) but it is important to note that the positions are not updated off-screen + +### Lua Example +`local numberValue = get_hand_foot_pos_x(m, index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| index | `integer` | + +### Returns +- `number` + +### C Prototype +`f32 get_hand_foot_pos_x(struct MarioState* m, u8 index);` + +[:arrow_up_small:](#) + +
+ +## [get_hand_foot_pos_y](#get_hand_foot_pos_y) + +### Description +Gets the Y coordinate of Mario's hand (0-1) or foot (2-3) but It is important to note that the positions are not updated off-screen + +### Lua Example +`local numberValue = get_hand_foot_pos_y(m, index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| index | `integer` | + +### Returns +- `number` + +### C Prototype +`f32 get_hand_foot_pos_y(struct MarioState* m, u8 index);` + +[:arrow_up_small:](#) + +
+ +## [get_hand_foot_pos_z](#get_hand_foot_pos_z) + +### Description +Gets the Z coordinate of Mario's hand (0-1) or foot (2-3) but it is important to note that the positions are not updated off-screen + +### Lua Example +`local numberValue = get_hand_foot_pos_z(m, index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| index | `integer` | + +### Returns +- `number` + +### C Prototype +`f32 get_hand_foot_pos_z(struct MarioState* m, u8 index);` + +[:arrow_up_small:](#) + +
+ +## [get_mario_anim_part_pos](#get_mario_anim_part_pos) + +### Description +Retrieves the animated part position associated to `animPart` from the MarioState `m` and stores it into `pos`. Returns `true` on success or `false` on failure + +### Lua Example +`local booleanValue = get_mario_anim_part_pos(m, animPart, pos)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| animPart | `integer` | +| pos | [Vec3f](structs.md#Vec3f) | + +### Returns +- `boolean` + +### C Prototype +`bool get_mario_anim_part_pos(struct MarioState *m, u32 animPart, OUT Vec3f pos);` + +[:arrow_up_small:](#) + +
+ +## [get_current_save_file_num](#get_current_save_file_num) + +### Description +Gets the current save file number (1-indexed) + +### Lua Example +`local integerValue = get_current_save_file_num()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s16 get_current_save_file_num(void);` + +[:arrow_up_small:](#) + +
+ +## [save_file_get_using_backup_slot](#save_file_get_using_backup_slot) + +### Description +Checks if the save file is using its backup slot + +### Lua Example +`local booleanValue = save_file_get_using_backup_slot()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool save_file_get_using_backup_slot(void);` + +[:arrow_up_small:](#) + +
+ +## [save_file_set_using_backup_slot](#save_file_set_using_backup_slot) + +### Description +Sets if the save file should use its backup slot + +### Lua Example +`save_file_set_using_backup_slot(usingBackupSlot)` + +### Parameters +| Field | Type | +| ----- | ---- | +| usingBackupSlot | `boolean` | + +### Returns +- None + +### C Prototype +`void save_file_set_using_backup_slot(bool usingBackupSlot);` + +[:arrow_up_small:](#) + +
+ +## [movtexqc_register](#movtexqc_register) + +### Description +Registers a custom moving texture entry (used for vanilla water boxes) + +### Lua Example +`movtexqc_register(name, level, area, type)` + +### Parameters +| Field | Type | +| ----- | ---- | +| name | `string` | +| level | `integer` | +| area | `integer` | +| type | `integer` | + +### Returns +- None + +### C Prototype +`void movtexqc_register(const char* name, s16 level, s16 area, s16 type);` + +[:arrow_up_small:](#) + +
+ +## [get_water_level](#get_water_level) + +### Description +Gets the water level in an area corresponding to `index` (0-indexed) + +### Lua Example +`local integerValue = get_water_level(index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| index | `integer` | + +### Returns +- `integer` + +### C Prototype +`s16 get_water_level(u8 index);` + +[:arrow_up_small:](#) + +
+ +## [set_water_level](#set_water_level) + +### Description +Sets the water level in an area corresponding to `index` (0-indexed) + +### Lua Example +`set_water_level(index, height, sync)` + +### Parameters +| Field | Type | +| ----- | ---- | +| index | `integer` | +| height | `integer` | +| sync | `boolean` | + +### Returns +- None + +### C Prototype +`void set_water_level(u8 index, s16 height, bool sync);` + +[:arrow_up_small:](#) + +
+ +## [course_is_main_course](#course_is_main_course) + +### Description +Checks if a course is a main course and not the castle or secret levels + +### Lua Example +`local booleanValue = course_is_main_course(courseNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | + +### Returns +- `boolean` + +### C Prototype +`bool course_is_main_course(u16 courseNum);` + +[:arrow_up_small:](#) + +
+ +## [get_ttc_speed_setting](#get_ttc_speed_setting) + +### Description +Gets TTC's speed setting + +### Lua Example +`local integerValue = get_ttc_speed_setting()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s16 get_ttc_speed_setting(void);` + +[:arrow_up_small:](#) + +
+ +## [set_ttc_speed_setting](#set_ttc_speed_setting) + +### Description +Sets TTC's speed setting (TTC_SPEED_*) + +### Lua Example +`set_ttc_speed_setting(speed)` + +### Parameters +| Field | Type | +| ----- | ---- | +| speed | `integer` | + +### Returns +- None + +### C Prototype +`void set_ttc_speed_setting(s16 speed);` + +[:arrow_up_small:](#) + +
+ +## [get_time](#get_time) + +### Description +Gets the Unix Timestamp + +### Lua Example +`local integerValue = get_time()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s64 get_time(void);` + +[:arrow_up_small:](#) + +
+ +## [get_date_and_time](#get_date_and_time) + +### Description +Gets the system clock's date and time + +### Lua Example +`local DateTimeValue = get_date_and_time()` + +### Parameters +- None + +### Returns +[DateTime](structs.md#DateTime) + +### C Prototype +`struct DateTime* get_date_and_time(void);` + +[:arrow_up_small:](#) + +
+ +## [get_envfx](#get_envfx) + +### Description +Gets the non overridden environment effect (e.g. snow) + +### Lua Example +`local integerValue = get_envfx()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u16 get_envfx(void);` + +[:arrow_up_small:](#) + +
+ +## [set_override_envfx](#set_override_envfx) + +### Description +Sets the override environment effect (e.g. snow) + +### Lua Example +`set_override_envfx(envfx)` + +### Parameters +| Field | Type | +| ----- | ---- | +| envfx | `integer` | + +### Returns +- None + +### C Prototype +`void set_override_envfx(s32 envfx);` + +[:arrow_up_small:](#) + +
+ +## [get_global_timer](#get_global_timer) + +### Description +Gets the global timer that has been ticking at 30 frames per second since game boot + +### Lua Example +`local integerValue = get_global_timer()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`u32 get_global_timer(void);` + +[:arrow_up_small:](#) + +
+ +## [get_dialog_response](#get_dialog_response) + +### Description +Gets the choice selected inside of a dialog box (0-1) + +### Lua Example +`local integerValue = get_dialog_response()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 get_dialog_response(void);` + +[:arrow_up_small:](#) + +
+ +## [get_local_discord_id](#get_local_discord_id) + +### Description +Gets the local discord ID if it isn't disabled, otherwise "0" is returned + +### Lua Example +`local stringValue = get_local_discord_id()` + +### Parameters +- None + +### Returns +- `string` + +### C Prototype +`const char* get_local_discord_id(void);` + +[:arrow_up_small:](#) + +
+ +## [get_coopnet_id](#get_coopnet_id) + +### Description +Gets the CoopNet ID of a player with `localIndex` if CoopNet is being used and the player is connected, otherwise "-1" is returned + +### Lua Example +`local stringValue = get_coopnet_id(localIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| localIndex | `integer` | + +### Returns +- `string` + +### C Prototype +`const char* get_coopnet_id(s8 localIndex);` + +[:arrow_up_small:](#) + +
+ +## [get_volume_master](#get_volume_master) + +### Description +Gets the master volume level + +### Lua Example +`local numberValue = get_volume_master()` + +### Parameters +- None + +### Returns +- `number` + +### C Prototype +`f32 get_volume_master(void);` + +[:arrow_up_small:](#) + +
+ +## [get_volume_level](#get_volume_level) + +### Description +Gets the volume level of music + +### Lua Example +`local numberValue = get_volume_level()` + +### Parameters +- None + +### Returns +- `number` + +### C Prototype +`f32 get_volume_level(void);` + +[:arrow_up_small:](#) + +
+ +## [get_volume_sfx](#get_volume_sfx) + +### Description +Gets the volume level of sound effects + +### Lua Example +`local numberValue = get_volume_sfx()` + +### Parameters +- None + +### Returns +- `number` + +### C Prototype +`f32 get_volume_sfx(void);` + +[:arrow_up_small:](#) + +
+ +## [get_volume_env](#get_volume_env) + +### Description +Gets the volume level of environment sounds effects + +### Lua Example +`local numberValue = get_volume_env()` + +### Parameters +- None + +### Returns +- `number` + +### C Prototype +`f32 get_volume_env(void);` + +[:arrow_up_small:](#) + +
+ +## [set_volume_master](#set_volume_master) + +### Description +Sets the master volume level + +### Lua Example +`set_volume_master(volume)` + +### Parameters +| Field | Type | +| ----- | ---- | +| volume | `number` | + +### Returns +- None + +### C Prototype +`void set_volume_master(f32 volume);` + +[:arrow_up_small:](#) + +
+ +## [set_volume_level](#set_volume_level) + +### Description +Sets the volume level of music + +### Lua Example +`set_volume_level(volume)` + +### Parameters +| Field | Type | +| ----- | ---- | +| volume | `number` | + +### Returns +- None + +### C Prototype +`void set_volume_level(f32 volume);` + +[:arrow_up_small:](#) + +
+ +## [set_volume_sfx](#set_volume_sfx) + +### Description +Sets the volume level of sound effects + +### Lua Example +`set_volume_sfx(volume)` + +### Parameters +| Field | Type | +| ----- | ---- | +| volume | `number` | + +### Returns +- None + +### C Prototype +`void set_volume_sfx(f32 volume);` + +[:arrow_up_small:](#) + +
+ +## [set_volume_env](#set_volume_env) + +### Description +Sets the volume level of environment sounds effects + +### Lua Example +`set_volume_env(volume)` + +### Parameters +| Field | Type | +| ----- | ---- | +| volume | `number` | + +### Returns +- None + +### C Prototype +`void set_volume_env(f32 volume);` + +[:arrow_up_small:](#) + +
+ +## [get_environment_region](#get_environment_region) + +### Description +Gets an environment region (gas/water boxes) height value + +### Lua Example +`local integerValue = get_environment_region(index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| index | `integer` | + +### Returns +- `integer` + +### C Prototype +`s16 get_environment_region(u8 index);` + +[:arrow_up_small:](#) + +
+ +## [set_environment_region](#set_environment_region) + +### Description +Sets an environment region (gas/water boxes) height value + +### Lua Example +`set_environment_region(index, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| index | `integer` | +| value | `integer` | + +### Returns +- None + +### C Prototype +`void set_environment_region(u8 index, s16 value);` + +[:arrow_up_small:](#) + +
+ +## [mod_file_exists](#mod_file_exists) + +### Description +Checks if a file exists inside of a mod + +### Lua Example +`local booleanValue = mod_file_exists(filename)` + +### Parameters +| Field | Type | +| ----- | ---- | +| filename | `string` | + +### Returns +- `boolean` + +### C Prototype +`bool mod_file_exists(const char* filename);` + +[:arrow_up_small:](#) + +
+ +## [get_active_mod](#get_active_mod) + +### Description +Gets the mod currently being processed + +### Lua Example +`local ModValue = get_active_mod()` + +### Parameters +- None + +### Returns +[Mod](structs.md#Mod) + +### C Prototype +`struct Mod* get_active_mod(void);` + +[:arrow_up_small:](#) + +
+ +## [set_window_title](#set_window_title) + +### Description +Sets the window title to a custom title + +### Lua Example +`set_window_title(title)` + +### Parameters +| Field | Type | +| ----- | ---- | +| title | `string` | + +### Returns +- None + +### C Prototype +`void set_window_title(const char* title);` + +[:arrow_up_small:](#) + +
+ +## [reset_window_title](#reset_window_title) + +### Description +Resets the window title + +### Lua Example +`reset_window_title()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void reset_window_title(void);` + +[:arrow_up_small:](#) + +
+ +## [get_os_name](#get_os_name) + +### Description +Gets the name of the operating system the game is running on + +### Lua Example +`local stringValue = get_os_name()` + +### Parameters +- None + +### Returns +- `string` + +### C Prototype +`const char* get_os_name(void);` + +[:arrow_up_small:](#) + +
+ +## [geo_get_current_root](#geo_get_current_root) + +### Description +Gets the current GraphNodeRoot + +### Lua Example +`local GraphNodeRootValue = geo_get_current_root()` + +### Parameters +- None + +### Returns +[GraphNodeRoot](structs.md#GraphNodeRoot) + +### C Prototype +`struct GraphNodeRoot* geo_get_current_root(void);` + +[:arrow_up_small:](#) + +
+ +## [geo_get_current_master_list](#geo_get_current_master_list) + +### Description +Gets the current GraphNodeMasterList + +### Lua Example +`local GraphNodeMasterListValue = geo_get_current_master_list()` + +### Parameters +- None + +### Returns +[GraphNodeMasterList](structs.md#GraphNodeMasterList) + +### C Prototype +`struct GraphNodeMasterList* geo_get_current_master_list(void);` + +[:arrow_up_small:](#) + +
+ +## [geo_get_current_perspective](#geo_get_current_perspective) + +### Description +Gets the current GraphNodePerspective + +### Lua Example +`local GraphNodePerspectiveValue = geo_get_current_perspective()` + +### Parameters +- None + +### Returns +[GraphNodePerspective](structs.md#GraphNodePerspective) + +### C Prototype +`struct GraphNodePerspective* geo_get_current_perspective(void);` + +[:arrow_up_small:](#) + +
+ +## [geo_get_current_camera](#geo_get_current_camera) + +### Description +Gets the current GraphNodeCamera + +### Lua Example +`local GraphNodeCameraValue = geo_get_current_camera()` + +### Parameters +- None + +### Returns +[GraphNodeCamera](structs.md#GraphNodeCamera) + +### C Prototype +`struct GraphNodeCamera* geo_get_current_camera(void);` + +[:arrow_up_small:](#) + +
+ +## [geo_get_current_held_object](#geo_get_current_held_object) + +### Description +Gets the current GraphNodeHeldObject + +### Lua Example +`local GraphNodeHeldObjectValue = geo_get_current_held_object()` + +### Parameters +- None + +### Returns +[GraphNodeHeldObject](structs.md#GraphNodeHeldObject) + +### C Prototype +`struct GraphNodeHeldObject* geo_get_current_held_object(void);` + +[:arrow_up_small:](#) + +
+ +## [texture_to_lua_table](#texture_to_lua_table) + +### Description +Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures + +### Lua Example +`texture_to_lua_table(tex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| tex | `Pointer` <`Texture`> | + +### Returns +- None + +### C Prototype +`void texture_to_lua_table(const Texture *tex);` + +[:arrow_up_small:](#) + +
+ +## [get_texture_name](#get_texture_name) + +### Description +Gets the name of the provided texture pointer `tex` + +### Lua Example +`local stringValue = get_texture_name(tex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| tex | `Pointer` <`Texture`> | + +### Returns +- `string` + +### C Prototype +`const char *get_texture_name(const Texture *tex);` + +[:arrow_up_small:](#) + +
+ +--- +# functions from smlua_model_utils.h + +
+ + +## [smlua_model_util_get_id](#smlua_model_util_get_id) + +### Description +Gets the extended model ID for the `name` of a `GeoLayout` + +### Lua Example +`local enumValue = smlua_model_util_get_id(name)` + +### Parameters +| Field | Type | +| ----- | ---- | +| name | `string` | + +### Returns +[enum ModelExtendedId](constants.md#enum-ModelExtendedId) + +### C Prototype +`enum ModelExtendedId smlua_model_util_get_id(const char* name);` + +[:arrow_up_small:](#) + +
+ +--- +# functions from smlua_obj_utils.h + +
+ + +## [spawn_sync_object](#spawn_sync_object) + +### Description +Spawns a synchronized object at `x`, `y`, and `z` as a child object of the local Mario with his rotation. You can change the fields of the object in `objSetupFunction` + +### Lua Example +`local ObjectValue = spawn_sync_object(behaviorId, modelId, x, y, z, objSetupFunction)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | +| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | +| x | `number` | +| y | `number` | +| z | `number` | +| objSetupFunction | `Lua Function` () | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object* spawn_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);` + +[:arrow_up_small:](#) + +
+ +## [spawn_non_sync_object](#spawn_non_sync_object) + +### Description +Spawns a non-synchronized object at `x`, `y`, and `z` as a child object of the local Mario with his rotation. You can change the fields of the object in `objSetupFunction` + +### Lua Example +`local ObjectValue = spawn_non_sync_object(behaviorId, modelId, x, y, z, objSetupFunction)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | +| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | +| x | `number` | +| y | `number` | +| z | `number` | +| objSetupFunction | `Lua Function` () | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object* spawn_non_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);` + +[:arrow_up_small:](#) + +
+ +## [obj_has_behavior_id](#obj_has_behavior_id) + +### Description +Checks if an object has `behaviorId` + +### Lua Example +`local integerValue = obj_has_behavior_id(o, behaviorId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | + +### Returns +- `integer` + +### C Prototype +`s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId);` + +[:arrow_up_small:](#) + +
+ +## [obj_has_model_extended](#obj_has_model_extended) + +### Description +Checks if an object's model is equal to `modelId` + +### Lua Example +`local integerValue = obj_has_model_extended(o, modelId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | + +### Returns +- `integer` + +### C Prototype +`s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_model_id_extended](#obj_get_model_id_extended) + +### Description +Returns an object's extended model id + +### Lua Example +`local enumValue = obj_get_model_id_extended(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +[enum ModelExtendedId](constants.md#enum-ModelExtendedId) + +### C Prototype +`enum ModelExtendedId obj_get_model_id_extended(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_model_extended](#obj_set_model_extended) + +### Description +Sets an object's model to `modelId` + +### Lua Example +`obj_set_model_extended(o, modelId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | + +### Returns +- None + +### C Prototype +`void obj_set_model_extended(struct Object *o, enum ModelExtendedId modelId);` + +[:arrow_up_small:](#) + +
+ +## [get_trajectory](#get_trajectory) + +### Description +Gets a trajectory by `name` + +### Lua Example +`local PointerValue = get_trajectory(name)` + +### Parameters +| Field | Type | +| ----- | ---- | +| name | `string` | + +### Returns +- `Pointer` <`Trajectory`> + +### C Prototype +`Trajectory* get_trajectory(const char* name);` + +[:arrow_up_small:](#) + +
+ +## [geo_get_current_object](#geo_get_current_object) + +### Description +When used in a geo function, retrieve the current processed object + +### Lua Example +`local ObjectValue = geo_get_current_object()` + +### Parameters +- None + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *geo_get_current_object(void);` + +[:arrow_up_small:](#) + +
+ +## [get_current_object](#get_current_object) + +### Description +Gets the object currently being processed + +### Lua Example +`local ObjectValue = get_current_object()` + +### Parameters +- None + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *get_current_object(void);` + +[:arrow_up_small:](#) + +
+ +## [get_dialog_object](#get_dialog_object) + +### Description +Gets the NPC object Mario is talking to + +### Lua Example +`local ObjectValue = get_dialog_object()` + +### Parameters +- None + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *get_dialog_object(void);` + +[:arrow_up_small:](#) + +
+ +## [get_cutscene_focus](#get_cutscene_focus) + +### Description +Gets the cutscene focus object + +### Lua Example +`local ObjectValue = get_cutscene_focus()` + +### Parameters +- None + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *get_cutscene_focus(void);` + +[:arrow_up_small:](#) + +
+ +## [get_secondary_camera_focus](#get_secondary_camera_focus) + +### Description +Gets the secondary camera focus object + +### Lua Example +`local ObjectValue = get_secondary_camera_focus()` + +### Parameters +- None + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *get_secondary_camera_focus(void);` + +[:arrow_up_small:](#) + +
+ +## [set_cutscene_focus](#set_cutscene_focus) + +### Description +Sets the cutscene focus object + +### Lua Example +`set_cutscene_focus(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void set_cutscene_focus(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [set_secondary_camera_focus](#set_secondary_camera_focus) + +### Description +Sets the secondary camera focus object + +### Lua Example +`set_secondary_camera_focus(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +- None + +### C Prototype +`void set_secondary_camera_focus(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_first](#obj_get_first) + +### Description +Gets the first object in an object list + +### Lua Example +`local ObjectValue = obj_get_first(objList)` + +### Parameters +| Field | Type | +| ----- | ---- | +| objList | [enum ObjectList](constants.md#enum-ObjectList) | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *obj_get_first(enum ObjectList objList);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_first_with_behavior_id](#obj_get_first_with_behavior_id) + +### Description +Gets the first object loaded with `behaviorId` + +### Lua Example +`local ObjectValue = obj_get_first_with_behavior_id(behaviorId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_first_with_behavior_id_and_field_s32](#obj_get_first_with_behavior_id_and_field_s32) + +### Description +Gets the first object loaded with `behaviorId` and object signed 32-bit integer field (look in `object_fields.h` to get the index of a field) + +### Lua Example +`local ObjectValue = obj_get_first_with_behavior_id_and_field_s32(behaviorId, fieldIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | +| fieldIndex | `integer` | +| value | `integer` | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_first_with_behavior_id_and_field_f32](#obj_get_first_with_behavior_id_and_field_f32) + +### Description +Gets the first object loaded with `behaviorId` and object float field (look in `object_fields.h` to get the index of a field) + +### Lua Example +`local ObjectValue = obj_get_first_with_behavior_id_and_field_f32(behaviorId, fieldIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | +| fieldIndex | `integer` | +| value | `number` | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *obj_get_first_with_behavior_id_and_field_f32(enum BehaviorId behaviorId, s32 fieldIndex, f32 value);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_next](#obj_get_next) + +### Description +Gets the next object in an object list + +### Lua Example +`local ObjectValue = obj_get_next(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *obj_get_next(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_next_with_same_behavior_id](#obj_get_next_with_same_behavior_id) + +### Description +Gets the next object loaded with the same behavior ID + +### Lua Example +`local ObjectValue = obj_get_next_with_same_behavior_id(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *obj_get_next_with_same_behavior_id(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_next_with_same_behavior_id_and_field_s32](#obj_get_next_with_same_behavior_id_and_field_s32) + +### Description +Gets the next object loaded with the same behavior ID and object signed 32-bit integer field (look in `object_fields.h` to get the index of a field) + +### Lua Example +`local ObjectValue = obj_get_next_with_same_behavior_id_and_field_s32(o, fieldIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| value | `integer` | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *obj_get_next_with_same_behavior_id_and_field_s32(struct Object *o, s32 fieldIndex, s32 value);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_next_with_same_behavior_id_and_field_f32](#obj_get_next_with_same_behavior_id_and_field_f32) + +### Description +Gets the next object loaded with the same behavior ID and object float field (look in `object_fields.h` to get the index of a field) + +### Lua Example +`local ObjectValue = obj_get_next_with_same_behavior_id_and_field_f32(o, fieldIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| value | `number` | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *obj_get_next_with_same_behavior_id_and_field_f32(struct Object *o, s32 fieldIndex, f32 value);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_nearest_object_with_behavior_id](#obj_get_nearest_object_with_behavior_id) + +### Description +Gets the nearest object with `behaviorId` to `o` + +### Lua Example +`local ObjectValue = obj_get_nearest_object_with_behavior_id(o, behaviorId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *obj_get_nearest_object_with_behavior_id(struct Object *o, enum BehaviorId behaviorId);` + +[:arrow_up_small:](#) + +
+ +## [obj_count_objects_with_behavior_id](#obj_count_objects_with_behavior_id) + +### Description +Counts every object with `behaviorId` + +### Lua Example +`local integerValue = obj_count_objects_with_behavior_id(behaviorId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | + +### Returns +- `integer` + +### C Prototype +`s32 obj_count_objects_with_behavior_id(enum BehaviorId behaviorId);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_collided_object](#obj_get_collided_object) + +### Description +Gets the corresponding collided object to an index from `o` + +### Lua Example +`local ObjectValue = obj_get_collided_object(o, index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| index | `integer` | + +### Returns +[Object](structs.md#Object) + +### C Prototype +`struct Object *obj_get_collided_object(struct Object *o, s16 index);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_field_u32](#obj_get_field_u32) + +### Description +Gets the unsigned 32-bit integer value from the field corresponding to `fieldIndex` + +### Lua Example +`local integerValue = obj_get_field_u32(o, fieldIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | + +### Returns +- `integer` + +### C Prototype +`u32 obj_get_field_u32(struct Object *o, s32 fieldIndex);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_field_s32](#obj_get_field_s32) + +### Description +Gets the signed 32-bit integer value from the field corresponding to `fieldIndex` + +### Lua Example +`local integerValue = obj_get_field_s32(o, fieldIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 obj_get_field_s32(struct Object *o, s32 fieldIndex);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_field_f32](#obj_get_field_f32) + +### Description +Sets the float value from the field corresponding to `fieldIndex` + +### Lua Example +`local numberValue = obj_get_field_f32(o, fieldIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | + +### Returns +- `number` + +### C Prototype +`f32 obj_get_field_f32(struct Object *o, s32 fieldIndex);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_field_s16](#obj_get_field_s16) + +### Description +Gets the signed 32-bit integer value from the sub field corresponding to `fieldSubIndex` from the field corresponding to `fieldIndex` + +### Lua Example +`local integerValue = obj_get_field_s16(o, fieldIndex, fieldSubIndex)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| fieldSubIndex | `integer` | + +### Returns +- `integer` + +### C Prototype +`s16 obj_get_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_field_u32](#obj_set_field_u32) + +### Description +Sets the unsigned 32-bit integer value from the field corresponding to `fieldIndex` + +### Lua Example +`obj_set_field_u32(o, fieldIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| value | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_field_u32(struct Object *o, s32 fieldIndex, u32 value);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_field_s32](#obj_set_field_s32) + +### Description +Sets the signed 32-bit integer value from the field corresponding to `fieldIndex` + +### Lua Example +`obj_set_field_s32(o, fieldIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| value | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_field_s32(struct Object *o, s32 fieldIndex, s32 value);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_field_f32](#obj_set_field_f32) + +### Description +Sets the float value from the field corresponding to `fieldIndex` + +### Lua Example +`obj_set_field_f32(o, fieldIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| value | `number` | + +### Returns +- None + +### C Prototype +`void obj_set_field_f32(struct Object *o, s32 fieldIndex, f32 value);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_field_s16](#obj_set_field_s16) + +### Description +Sets the signed 32-bit integer value from the sub field corresponding to `fieldSubIndex` from the field corresponding to `fieldIndex` + +### Lua Example +`obj_set_field_s16(o, fieldIndex, fieldSubIndex, value)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| fieldIndex | `integer` | +| fieldSubIndex | `integer` | +| value | `integer` | + +### Returns +- None + +### C Prototype +`void obj_set_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex, s16 value);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_temp_spawn_particles_info](#obj_get_temp_spawn_particles_info) + +### Description +Returns a temporary particle spawn info pointer with its model loaded in from `modelId` + +### Lua Example +`local SpawnParticlesInfoValue = obj_get_temp_spawn_particles_info(modelId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | + +### Returns +[SpawnParticlesInfo](structs.md#SpawnParticlesInfo) + +### C Prototype +`struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedId modelId);` + +[:arrow_up_small:](#) + +
+ +## [get_temp_object_hitbox](#get_temp_object_hitbox) + +### Description +Returns a temporary object hitbox pointer + +### Lua Example +`local ObjectHitboxValue = get_temp_object_hitbox()` + +### Parameters +- None + +### Returns +[ObjectHitbox](structs.md#ObjectHitbox) + +### C Prototype +`struct ObjectHitbox* get_temp_object_hitbox(void);` + +[:arrow_up_small:](#) + +
+ +## [obj_is_attackable](#obj_is_attackable) + +### Description +Checks if `o` is attackable + +### Lua Example +`local booleanValue = obj_is_attackable(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +- `boolean` + +### C Prototype +`bool obj_is_attackable(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_is_breakable_object](#obj_is_breakable_object) + +### Description +Checks if `o` is breakable + +### Lua Example +`local booleanValue = obj_is_breakable_object(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +- `boolean` + +### C Prototype +`bool obj_is_breakable_object(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_is_bully](#obj_is_bully) + +### Description +Checks if `o` is a Bully + +### Lua Example +`local booleanValue = obj_is_bully(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +- `boolean` + +### C Prototype +`bool obj_is_bully(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_is_coin](#obj_is_coin) + +### Description +Checks if `o` is a coin + +### Lua Example +`local booleanValue = obj_is_coin(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +- `boolean` + +### C Prototype +`bool obj_is_coin(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_is_exclamation_box](#obj_is_exclamation_box) + +### Description +Checks if `o` is an exclamation box + +### Lua Example +`local booleanValue = obj_is_exclamation_box(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +- `boolean` + +### C Prototype +`bool obj_is_exclamation_box(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_is_grabbable](#obj_is_grabbable) + +### Description +Checks if `o` is grabbable + +### Lua Example +`local booleanValue = obj_is_grabbable(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +- `boolean` + +### C Prototype +`bool obj_is_grabbable(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_is_mushroom_1up](#obj_is_mushroom_1up) + +### Description +Checks if `o` is a 1-Up Mushroom + +### Lua Example +`local booleanValue = obj_is_mushroom_1up(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +- `boolean` + +### C Prototype +`bool obj_is_mushroom_1up(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_is_secret](#obj_is_secret) + +### Description +Checks if `o` is a secret + +### Lua Example +`local booleanValue = obj_is_secret(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +- `boolean` + +### C Prototype +`bool obj_is_secret(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_is_valid_for_interaction](#obj_is_valid_for_interaction) + +### Description +Checks if `o` is activated, tangible, and interactible + +### Lua Example +`local booleanValue = obj_is_valid_for_interaction(o)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | + +### Returns +- `boolean` + +### C Prototype +`bool obj_is_valid_for_interaction(struct Object *o);` + +[:arrow_up_small:](#) + +
+ +## [obj_check_hitbox_overlap](#obj_check_hitbox_overlap) + +### Description +Checks if `o1`'s hitbox is colliding with `o2`'s hitbox + +### Lua Example +`local booleanValue = obj_check_hitbox_overlap(o1, o2)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o1 | [Object](structs.md#Object) | +| o2 | [Object](structs.md#Object) | + +### Returns +- `boolean` + +### C Prototype +`bool obj_check_hitbox_overlap(struct Object *o1, struct Object *o2);` + +[:arrow_up_small:](#) + +
+ +## [obj_check_overlap_with_hitbox_params](#obj_check_overlap_with_hitbox_params) + +### Description +Checks if `o`'s hitbox is colliding with the parameters of a hitbox + +### Lua Example +`local booleanValue = obj_check_overlap_with_hitbox_params(o, x, y, z, h, r, d)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| x | `number` | +| y | `number` | +| z | `number` | +| h | `number` | +| r | `number` | +| d | `number` | + +### Returns +- `boolean` + +### C Prototype +`bool obj_check_overlap_with_hitbox_params(struct Object *o, f32 x, f32 y, f32 z, f32 h, f32 r, f32 d);` + +[:arrow_up_small:](#) + +
+ +## [obj_set_vel](#obj_set_vel) + +### Description +Sets an object's velocity to `vx`, `vy`, and `vz` + +### Lua Example +`obj_set_vel(o, vx, vy, vz)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| vx | `number` | +| vy | `number` | +| vz | `number` | + +### Returns +- None + +### C Prototype +`void obj_set_vel(struct Object *o, f32 vx, f32 vy, f32 vz);` + +[:arrow_up_small:](#) + +
+ +## [obj_move_xyz](#obj_move_xyz) + +### Description +Moves the object in the direction of `dx`, `dy`, and `dz` + +### Lua Example +`obj_move_xyz(o, dx, dy, dz)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| dx | `number` | +| dy | `number` | +| dz | `number` | + +### Returns +- None + +### C Prototype +`void obj_move_xyz(struct Object *o, f32 dx, f32 dy, f32 dz);` + +[:arrow_up_small:](#) + +
+ +## [set_whirlpools](#set_whirlpools) + +### Description +Sets the parameters of one of the two whirlpools (0-indexed) in an area + +### Lua Example +`set_whirlpools(x, y, z, strength, area, index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| x | `number` | +| y | `number` | +| z | `number` | +| strength | `integer` | +| area | `integer` | +| index | `integer` | + +### Returns +- None + +### C Prototype +`void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index);` + +[:arrow_up_small:](#) + +
+ +--- +# functions from smlua_text_utils.h + +
+ + +## [smlua_text_utils_reset_all](#smlua_text_utils_reset_all) + +### Description +Resets every modified dialog back to vanilla + +### Lua Example +`smlua_text_utils_reset_all()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void smlua_text_utils_reset_all(void);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_dialog_get](#smlua_text_utils_dialog_get) + +### Description +Gets the DialogEntry struct for the given `dialogId` + +### Lua Example +`local DialogEntryValue = smlua_text_utils_dialog_get(dialogId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dialogId | [enum DialogId](constants.md#enum-DialogId) | + +### Returns +[DialogEntry](structs.md#DialogEntry) + +### C Prototype +`struct DialogEntry* smlua_text_utils_dialog_get(enum DialogId dialogId);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_dialog_replace](#smlua_text_utils_dialog_replace) + +### Description +Replaces `dialogId` with a custom one + +### Lua Example +`smlua_text_utils_dialog_replace(dialogId, unused, linesPerBox, leftOffset, width, str)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dialogId | [enum DialogId](constants.md#enum-DialogId) | +| unused | `integer` | +| linesPerBox | `integer` | +| leftOffset | `integer` | +| width | `integer` | +| str | `string` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_dialog_replace(enum DialogId dialogId, u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_dialog_restore](#smlua_text_utils_dialog_restore) + +### Description +Restores a replaced DialogEntry to its original state. + +### Lua Example +`smlua_text_utils_dialog_restore(dialogId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dialogId | [enum DialogId](constants.md#enum-DialogId) | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_dialog_restore(enum DialogId dialogId);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_dialog_is_replaced](#smlua_text_utils_dialog_is_replaced) + +### Description +Returns whether the dialog with the given ID has been replaced + +### Lua Example +`local booleanValue = smlua_text_utils_dialog_is_replaced(dialogId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dialogId | [enum DialogId](constants.md#enum-DialogId) | + +### Returns +- `boolean` + +### C Prototype +`bool smlua_text_utils_dialog_is_replaced(enum DialogId dialogId);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_allocate_dialog](#smlua_text_utils_allocate_dialog) + +### Description +Allocates a new dialog entry + +### Lua Example +`local integerValue = smlua_text_utils_allocate_dialog()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 smlua_text_utils_allocate_dialog(void);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_course_acts_replace](#smlua_text_utils_course_acts_replace) + +### Description +Replaces the act names of `courseNum` + +### Lua Example +`smlua_text_utils_course_acts_replace(courseNum, courseName, act1, act2, act3, act4, act5, act6)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| courseName | `string` | +| act1 | `string` | +| act2 | `string` | +| act3 | `string` | +| act4 | `string` | +| act5 | `string` | +| act6 | `string` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_secret_star_replace](#smlua_text_utils_secret_star_replace) + +### Description +Replaces the secret star course name of `courseNum` with `courseName` + +### Lua Example +`smlua_text_utils_secret_star_replace(courseNum, courseName)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| courseName | `string` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_course_name_replace](#smlua_text_utils_course_name_replace) + +### Description +Replaces the name of `courseNum` with `name` + +### Lua Example +`smlua_text_utils_course_name_replace(courseNum, name)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| name | `string` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_course_name_replace(s16 courseNum, const char* name);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_course_name_get](#smlua_text_utils_course_name_get) + +### Description +Gets the name of `courseNum` + +### Lua Example +`local stringValue = smlua_text_utils_course_name_get(courseNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | + +### Returns +- `string` + +### C Prototype +`const char* smlua_text_utils_course_name_get(s16 courseNum);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_course_name_mod_index](#smlua_text_utils_course_name_mod_index) + +### Description +Gets the index of the mod that replaced the name of `courseNum` + +### Lua Example +`local integerValue = smlua_text_utils_course_name_mod_index(courseNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 smlua_text_utils_course_name_mod_index(s16 courseNum);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_course_name_reset](#smlua_text_utils_course_name_reset) + +### Description +Resets the name of `courseNum` + +### Lua Example +`smlua_text_utils_course_name_reset(courseNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_course_name_reset(s16 courseNum);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_act_name_replace](#smlua_text_utils_act_name_replace) + +### Description +Replaces the act name of `actNum` in `courseNum` with `name` + +### Lua Example +`smlua_text_utils_act_name_replace(courseNum, actNum, name)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| actNum | `integer` | +| name | `string` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_act_name_replace(s16 courseNum, u8 actNum, const char* name);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_act_name_get](#smlua_text_utils_act_name_get) + +### Description +Gets the act name of `actNum` in `courseNum` + +### Lua Example +`local stringValue = smlua_text_utils_act_name_get(courseNum, actNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| actNum | `integer` | + +### Returns +- `string` + +### C Prototype +`const char* smlua_text_utils_act_name_get(s16 courseNum, u8 actNum);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_act_name_mod_index](#smlua_text_utils_act_name_mod_index) + +### Description +Gets the index of the mod that replaced the act name of `actNum` in `courseNum` + +### Lua Example +`local integerValue = smlua_text_utils_act_name_mod_index(courseNum, actNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| actNum | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 smlua_text_utils_act_name_mod_index(s16 courseNum, u8 actNum);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_act_name_reset](#smlua_text_utils_act_name_reset) + +### Description +Resets the act name of `actNum` in `courseNum` + +### Lua Example +`smlua_text_utils_act_name_reset(courseNum, actNum)` + +### Parameters +| Field | Type | +| ----- | ---- | +| courseNum | `integer` | +| actNum | `integer` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_act_name_reset(s16 courseNum, u8 actNum);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_castle_secret_stars_replace](#smlua_text_utils_castle_secret_stars_replace) + +### Description +Replaces the castle secret stars text with `name` + +### Lua Example +`smlua_text_utils_castle_secret_stars_replace(name)` + +### Parameters +| Field | Type | +| ----- | ---- | +| name | `string` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_castle_secret_stars_replace(const char* name);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_castle_secret_stars_get](#smlua_text_utils_castle_secret_stars_get) + +### Description +Gets the castle secret stars text + +### Lua Example +`local stringValue = smlua_text_utils_castle_secret_stars_get()` + +### Parameters +- None + +### Returns +- `string` + +### C Prototype +`const char* smlua_text_utils_castle_secret_stars_get();` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_castle_secret_stars_mod_index](#smlua_text_utils_castle_secret_stars_mod_index) + +### Description +Gets the index of the mod that replaced the castle secret stars text + +### Lua Example +`local integerValue = smlua_text_utils_castle_secret_stars_mod_index()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s32 smlua_text_utils_castle_secret_stars_mod_index();` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_castle_secret_stars_reset](#smlua_text_utils_castle_secret_stars_reset) + +### Description +Resets the castle secret stars text + +### Lua Example +`smlua_text_utils_castle_secret_stars_reset()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void smlua_text_utils_castle_secret_stars_reset();` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_extra_text_replace](#smlua_text_utils_extra_text_replace) + +### Description +Replace extra text (e.g. one of the castle's secret stars) with `text` + +### Lua Example +`smlua_text_utils_extra_text_replace(index, text)` + +### Parameters +| Field | Type | +| ----- | ---- | +| index | `integer` | +| text | `string` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_extra_text_replace(s16 index, const char* text);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_extra_text_get](#smlua_text_utils_extra_text_get) + +### Description +Gets the extra text at `index` + +### Lua Example +`local stringValue = smlua_text_utils_extra_text_get(index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| index | `integer` | + +### Returns +- `string` + +### C Prototype +`const char* smlua_text_utils_extra_text_get(s16 index);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_extra_text_mod_index](#smlua_text_utils_extra_text_mod_index) + +### Description +Gets the index of the mod that replaced the extra text at `index` + +### Lua Example +`local integerValue = smlua_text_utils_extra_text_mod_index(index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| index | `integer` | + +### Returns +- `integer` + +### C Prototype +`s32 smlua_text_utils_extra_text_mod_index(s16 index);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_extra_text_reset](#smlua_text_utils_extra_text_reset) + +### Description +Resets the extra text at `index` + +### Lua Example +`smlua_text_utils_extra_text_reset(index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| index | `integer` | + +### Returns +- None + +### C Prototype +`void smlua_text_utils_extra_text_reset(s16 index);` + +[:arrow_up_small:](#) + +
+ +## [smlua_text_utils_get_language](#smlua_text_utils_get_language) + +### Description +Gets the current language + +### Lua Example +`local stringValue = smlua_text_utils_get_language()` + +### Parameters +- None + +### Returns +- `string` + +### C Prototype +`const char* smlua_text_utils_get_language(void);` + +[:arrow_up_small:](#) + +
+ +--- +# functions from sound_init.h + +
+ + +## [reset_volume](#reset_volume) + +### Description +Resets if music volume has been lowered + +### Lua Example +`reset_volume()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void reset_volume(void);` + +[:arrow_up_small:](#) + +
+ +## [raise_background_noise](#raise_background_noise) + +### Description +Raises music volume back up to normal levels + +### Lua Example +`raise_background_noise(a)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a | `integer` | + +### Returns +- None + +### C Prototype +`void raise_background_noise(s32 a);` + +[:arrow_up_small:](#) + +
+ +## [lower_background_noise](#lower_background_noise) + +### Description +Lowers the volume of music by 40% + +### Lua Example +`lower_background_noise(a)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a | `integer` | + +### Returns +- None + +### C Prototype +`void lower_background_noise(s32 a);` + +[:arrow_up_small:](#) + +
+ +## [disable_background_sound](#disable_background_sound) + +### Description +Disables background soundbanks + +### Lua Example +`disable_background_sound()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void disable_background_sound(void);` + +[:arrow_up_small:](#) + +
+ +## [enable_background_sound](#enable_background_sound) + +### Description +Enables background soundbanks + +### Lua Example +`enable_background_sound()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void enable_background_sound(void);` + +[:arrow_up_small:](#) + +
+ +## [play_menu_sounds](#play_menu_sounds) + +### Description +Play menu sounds from `SOUND_MENU_FLAG_*` constants and queues rumble if `SOUND_MENU_FLAG_LETGOMARIOFACE` is one of the flags + +### Lua Example +`play_menu_sounds(soundMenuFlags)` + +### Parameters +| Field | Type | +| ----- | ---- | +| soundMenuFlags | `integer` | + +### Returns +- None + +### C Prototype +`void play_menu_sounds(s16 soundMenuFlags);` + +[:arrow_up_small:](#) + +
+ +## [play_painting_eject_sound](#play_painting_eject_sound) + +### Description +Plays the painting eject sound effect if it has not already been played + +### Lua Example +`play_painting_eject_sound()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void play_painting_eject_sound(void);` + +[:arrow_up_small:](#) + +
+ +## [play_infinite_stairs_music](#play_infinite_stairs_music) + +### Description +Plays the infinite stairs music if you're in the endless stairs room and have less than `gLevelValues.infiniteStairsRequirement` stars + +### Lua Example +`play_infinite_stairs_music()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void play_infinite_stairs_music(void);` + +[:arrow_up_small:](#) + +
+ +## [set_background_music](#set_background_music) + +### Description +Sets the background music to `seqArgs` on sequence player `a` with a fade in time of `fadeTimer` + +### Lua Example +`set_background_music(a, seqArgs, fadeTimer)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a | `integer` | +| seqArgs | `integer` | +| fadeTimer | `integer` | + +### Returns +- None + +### C Prototype +`void set_background_music(u16 a, u16 seqArgs, s16 fadeTimer);` + +[:arrow_up_small:](#) + +
+ +## [fadeout_music](#fadeout_music) + +### Description +Fades out level, shell, and cap music + +### Lua Example +`fadeout_music(fadeOutTime)` + +### Parameters +| Field | Type | +| ----- | ---- | +| fadeOutTime | `integer` | + +### Returns +- None + +### C Prototype +`void fadeout_music(s16 fadeOutTime);` + +[:arrow_up_small:](#) + +
+ +## [fadeout_level_music](#fadeout_level_music) + +### Description +Fades out the level sequence player + +### Lua Example +`fadeout_level_music(fadeTimer)` + +### Parameters +| Field | Type | +| ----- | ---- | +| fadeTimer | `integer` | + +### Returns +- None + +### C Prototype +`void fadeout_level_music(s16 fadeTimer);` + +[:arrow_up_small:](#) + +
+ +## [play_cutscene_music](#play_cutscene_music) + +### Description +Plays and sets the current music to `seqArgs` + +### Lua Example +`play_cutscene_music(seqArgs)` + +### Parameters +| Field | Type | +| ----- | ---- | +| seqArgs | `integer` | + +### Returns +- None + +### C Prototype +`void play_cutscene_music(u16 seqArgs);` + +[:arrow_up_small:](#) + +
+ +## [play_shell_music](#play_shell_music) + +### Description +Plays shell music + +### Lua Example +`play_shell_music()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void play_shell_music(void);` + +[:arrow_up_small:](#) + +
+ +## [stop_shell_music](#stop_shell_music) + +### Description +Stops shell music completely + +### Lua Example +`stop_shell_music()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void stop_shell_music(void);` + +[:arrow_up_small:](#) + +
+ +## [play_cap_music](#play_cap_music) + +### Description +Plays `seqArgs` as cap music + +### Lua Example +`play_cap_music(seqArgs)` + +### Parameters +| Field | Type | +| ----- | ---- | +| seqArgs | `integer` | + +### Returns +- None + +### C Prototype +`void play_cap_music(u16 seqArgs);` + +[:arrow_up_small:](#) + +
+ +## [fadeout_cap_music](#fadeout_cap_music) + +### Description +Fades out cap music + +### Lua Example +`fadeout_cap_music()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void fadeout_cap_music(void);` + +[:arrow_up_small:](#) + +
+ +## [stop_cap_music](#stop_cap_music) + +### Description +Stops cap music completely + +### Lua Example +`stop_cap_music()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void stop_cap_music(void);` + +[:arrow_up_small:](#) + +
+ +--- +# functions from spawn_sound.h + +
+ + +## [cur_obj_play_sound_1](#cur_obj_play_sound_1) + +### Description +Plays a sound if the current object is visible + +### Lua Example +`cur_obj_play_sound_1(soundMagic)` + +### Parameters +| Field | Type | +| ----- | ---- | +| soundMagic | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_play_sound_1(s32 soundMagic);` + +[:arrow_up_small:](#) + +
+ +## [cur_obj_play_sound_2](#cur_obj_play_sound_2) + +### Description +Plays a sound if the current object is visible and queues rumble for specific sounds + +### Lua Example +`cur_obj_play_sound_2(soundMagic)` + +### Parameters +| Field | Type | +| ----- | ---- | +| soundMagic | `integer` | + +### Returns +- None + +### C Prototype +`void cur_obj_play_sound_2(s32 soundMagic);` + +[:arrow_up_small:](#) + +
+ +## [create_sound_spawner](#create_sound_spawner) + +### Description +Create a sound spawner for objects that need a sound play once. (Breakable walls, King Bobomb exploding, etc) + +### Lua Example +`create_sound_spawner(soundMagic)` + +### Parameters +| Field | Type | +| ----- | ---- | +| soundMagic | `integer` | + +### Returns +- None + +### C Prototype +`void create_sound_spawner(s32 soundMagic);` + +[:arrow_up_small:](#) + +
+ +## [calc_dist_to_volume_range_1](#calc_dist_to_volume_range_1) + +### Description +Unused vanilla function, calculates a volume based on `distance`. If `distance` is less than 500 then 127, if `distance` is greater than 1500 then 0, if `distance` is between 500 and 1500 then it ranges linearly from 60 to 124. What an even more strange and confusing function + +### Lua Example +`local integerValue = calc_dist_to_volume_range_1(distance)` + +### Parameters +| Field | Type | +| ----- | ---- | +| distance | `number` | + +### Returns +- `integer` + +### C Prototype +`s32 calc_dist_to_volume_range_1(f32 distance);` + +[:arrow_up_small:](#) + +
+ +## [calc_dist_to_volume_range_2](#calc_dist_to_volume_range_2) + +### Description +Unused vanilla function, calculates a volume based on `distance`. If `distance` is less than 1300 then 127, if `distance` is greater than 2300 then 0, if `distance` is between 1300 and 2300 then it ranges linearly from 60 to 127. What a strange and confusing function + +### Lua Example +`local integerValue = calc_dist_to_volume_range_2(distance)` + +### Parameters +| Field | Type | +| ----- | ---- | +| distance | `number` | + +### Returns +- `integer` + +### C Prototype +`s32 calc_dist_to_volume_range_2(f32 distance);` + +[:arrow_up_small:](#) + +
+ +--- +# functions from surface_collision.h + +
+ + +## [find_wall_collisions](#find_wall_collisions) + +### Description +Detects wall collisions at a given position and adjusts the position based on the walls found. Returns the number of wall collisions detected + +### Lua Example +`local integerValue = find_wall_collisions(colData)` + +### Parameters +| Field | Type | +| ----- | ---- | +| colData | [WallCollisionData](structs.md#WallCollisionData) | + +### Returns +- `integer` + +### C Prototype +`s32 find_wall_collisions(struct WallCollisionData *colData);` + +[:arrow_up_small:](#) + +
+ +## [find_ceil_height](#find_ceil_height) + +### Description +Finds the height of the highest ceiling above a given position (x, y, z). If no ceiling is found, returns the default height limit of `gLevelValues.cellHeightLimit`(20000 by default) + +### Lua Example +`local numberValue = find_ceil_height(x, y, z)` + +### Parameters +| Field | Type | +| ----- | ---- | +| x | `number` | +| y | `number` | +| z | `number` | + +### Returns +- `number` + +### C Prototype +`f32 find_ceil_height(f32 x, f32 y, f32 z);` + +[:arrow_up_small:](#) + +
+ +## [find_floor_height](#find_floor_height) + +### Description +Finds the height of the highest floor below a given position (x, y, z). If no floor is found, returns the default floor height of `gLevelValues.floorLowerLimit`(-11000 by default) + +### Lua Example +`local numberValue = find_floor_height(x, y, z)` + +### Parameters +| Field | Type | +| ----- | ---- | +| x | `number` | +| y | `number` | +| z | `number` | + +### Returns +- `number` + +### C Prototype +`f32 find_floor_height(f32 x, f32 y, f32 z);` + +[:arrow_up_small:](#) + +
+ +## [find_water_level](#find_water_level) + +### Description +Finds the height of water at a given position (x, z), if the position is within a water region. If no water is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default) + +### Lua Example +`local numberValue = find_water_level(x, z)` + +### Parameters +| Field | Type | +| ----- | ---- | +| x | `number` | +| z | `number` | + +### Returns +- `number` + +### C Prototype +`f32 find_water_level(f32 x, f32 z);` + +[:arrow_up_small:](#) + +
+ +## [find_poison_gas_level](#find_poison_gas_level) + +### Description +Finds the height of the poison gas at a given position (x, z), if the position is within a gas region. If no gas is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default) + +### Lua Example +`local numberValue = find_poison_gas_level(x, z)` + +### Parameters +| Field | Type | +| ----- | ---- | +| x | `number` | +| z | `number` | + +### Returns +- `number` + +### C Prototype +`f32 find_poison_gas_level(f32 x, f32 z);` + +[:arrow_up_small:](#) + +
+ +## [set_find_wall_direction](#set_find_wall_direction) + +### Description +Sets whether collision finding functions should check wall directions. + +### Lua Example +`set_find_wall_direction(dir, active, airborne)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dir | [Vec3f](structs.md#Vec3f) | +| active | `boolean` | +| airborne | `boolean` | + +### Returns +- None + +### C Prototype +`void set_find_wall_direction(Vec3f dir, bool active, bool airborne);` + +[:arrow_up_small:](#) + +
+ +## [closest_point_to_triangle](#closest_point_to_triangle) + +### Description +Gets the closest point of the triangle to `src` and returns it in `out`. + +### Lua Example +`closest_point_to_triangle(surf, src, out)` + +### Parameters +| Field | Type | +| ----- | ---- | +| surf | [Surface](structs.md#Surface) | +| src | [Vec3f](structs.md#Vec3f) | +| out | [Vec3f](structs.md#Vec3f) | + +### Returns +- None + +### C Prototype +`void closest_point_to_triangle(struct Surface* surf, Vec3f src, OUT Vec3f out);` + +[:arrow_up_small:](#) + +
+ +--- +# functions from surface_load.h + +
+ + +## [load_object_collision_model](#load_object_collision_model) + +### Description +Loads the object's collision data into dynamic collision. You must run this every frame in your object's behavior loop for it to have collision + +### Lua Example +`load_object_collision_model()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void load_object_collision_model(void);` + +[:arrow_up_small:](#) + +
+ +## [load_static_object_collision](#load_static_object_collision) + +### Description +Loads the object's collision data into static collision. You may run this only once to capture the object's collision at that frame. + +### Lua Example +`local StaticObjectCollisionValue = load_static_object_collision()` + +### Parameters +- None + +### Returns +[StaticObjectCollision](structs.md#StaticObjectCollision) + +### C Prototype +`struct StaticObjectCollision *load_static_object_collision();` + +[:arrow_up_small:](#) + +
+ +## [toggle_static_object_collision](#toggle_static_object_collision) + +### Description +Toggles a collection of static object surfaces + +### Lua Example +`toggle_static_object_collision(col, tangible)` + +### Parameters +| Field | Type | +| ----- | ---- | +| col | [StaticObjectCollision](structs.md#StaticObjectCollision) | +| tangible | `boolean` | + +### Returns +- None + +### C Prototype +`void toggle_static_object_collision(struct StaticObjectCollision *col, bool tangible);` + +[:arrow_up_small:](#) + +
+ +## [get_static_object_surface](#get_static_object_surface) + +### Description +Gets a surface corresponding to `index` from the static object collision + +### Lua Example +`local SurfaceValue = get_static_object_surface(col, index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| col | [StaticObjectCollision](structs.md#StaticObjectCollision) | +| index | `integer` | + +### Returns +[Surface](structs.md#Surface) + +### C Prototype +`struct Surface *get_static_object_surface(struct StaticObjectCollision *col, u32 index);` + +[:arrow_up_small:](#) + +
+ +## [obj_get_surface_from_index](#obj_get_surface_from_index) + +### Description +Gets a surface corresponding to `index` from the surface pool buffer + +### Lua Example +`local SurfaceValue = obj_get_surface_from_index(o, index)` + +### Parameters +| Field | Type | +| ----- | ---- | +| o | [Object](structs.md#Object) | +| index | `integer` | + +### Returns +[Surface](structs.md#Surface) + +### C Prototype +`struct Surface *obj_get_surface_from_index(struct Object *o, u32 index);` + +[:arrow_up_small:](#) + +
+ +## [surface_has_force](#surface_has_force) + +### Description +Checks if a surface has force + +### Lua Example +`local booleanValue = surface_has_force(surfaceType)` + +### Parameters +| Field | Type | +| ----- | ---- | +| surfaceType | `integer` | + +### Returns +- `boolean` + +### C Prototype +`bool surface_has_force(s16 surfaceType);` + +[:arrow_up_small:](#) + +
+ --- # functions from sync_object.h diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 5683b3946..9fe4cc414 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -1354,9 +1354,6 @@ - [mod_fs_get](functions-5.md#mod_fs_get) - [mod_fs_reload](functions-5.md#mod_fs_reload) - [mod_fs_create](functions-5.md#mod_fs_create) - - [mod_fs_delete](functions-5.md#mod_fs_delete) - - [mod_fs_save](functions-5.md#mod_fs_save) - - [mod_fs_set_public](functions-5.md#mod_fs_set_public) - [mod_fs_get_filename](functions-5.md#mod_fs_get_filename) - [mod_fs_get_file](functions-5.md#mod_fs_get_file) - [mod_fs_create_file](functions-5.md#mod_fs_create_file) @@ -1364,6 +1361,9 @@ - [mod_fs_copy_file](functions-5.md#mod_fs_copy_file) - [mod_fs_delete_file](functions-5.md#mod_fs_delete_file) - [mod_fs_clear](functions-5.md#mod_fs_clear) + - [mod_fs_save](functions-5.md#mod_fs_save) + - [mod_fs_delete](functions-5.md#mod_fs_delete) + - [mod_fs_set_public](functions-5.md#mod_fs_set_public) - [mod_fs_file_read_bool](functions-5.md#mod_fs_file_read_bool) - [mod_fs_file_read_integer](functions-5.md#mod_fs_file_read_integer) - [mod_fs_file_read_number](functions-5.md#mod_fs_file_read_number) @@ -1377,9 +1377,11 @@ - [mod_fs_file_write_string](functions-5.md#mod_fs_file_write_string) - [mod_fs_file_write_line](functions-5.md#mod_fs_file_write_line) - [mod_fs_file_seek](functions-5.md#mod_fs_file_seek) + - [mod_fs_file_rewind](functions-5.md#mod_fs_file_rewind) - [mod_fs_file_is_eof](functions-5.md#mod_fs_file_is_eof) - [mod_fs_file_fill](functions-5.md#mod_fs_file_fill) - [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_hide_errors](functions-5.md#mod_fs_hide_errors) - [mod_fs_get_last_error](functions-5.md#mod_fs_get_last_error) @@ -1393,6 +1395,7 @@ - [mod_storage_load](functions-5.md#mod_storage_load) - [mod_storage_load_number](functions-5.md#mod_storage_load_number) - [mod_storage_load_bool](functions-5.md#mod_storage_load_bool) + - [mod_storage_load_all](functions-5.md#mod_storage_load_all) - [mod_storage_exists](functions-5.md#mod_storage_exists) - [mod_storage_remove](functions-5.md#mod_storage_remove) - [mod_storage_clear](functions-5.md#mod_storage_clear) @@ -1516,232 +1519,232 @@
- object_helpers.c - - [clear_move_flag](functions-5.md#clear_move_flag) - - [set_room_override](functions-5.md#set_room_override) - - [obj_update_pos_from_parent_transformation](functions-5.md#obj_update_pos_from_parent_transformation) - - [obj_apply_scale_to_matrix](functions-5.md#obj_apply_scale_to_matrix) - - [create_transformation_from_matrices](functions-5.md#create_transformation_from_matrices) - - [obj_set_held_state](functions-5.md#obj_set_held_state) - - [lateral_dist_between_objects](functions-5.md#lateral_dist_between_objects) - - [dist_between_objects](functions-5.md#dist_between_objects) - - [dist_between_object_and_point](functions-5.md#dist_between_object_and_point) - - [cur_obj_forward_vel_approach_upward](functions-5.md#cur_obj_forward_vel_approach_upward) - - [approach_f32_signed](functions-5.md#approach_f32_signed) - - [approach_f32_symmetric](functions-5.md#approach_f32_symmetric) - - [approach_s16_symmetric](functions-5.md#approach_s16_symmetric) - - [cur_obj_rotate_yaw_toward](functions-5.md#cur_obj_rotate_yaw_toward) - - [obj_angle_to_object](functions-5.md#obj_angle_to_object) - - [obj_pitch_to_object](functions-5.md#obj_pitch_to_object) - - [obj_angle_to_point](functions-5.md#obj_angle_to_point) - - [obj_turn_toward_object](functions-5.md#obj_turn_toward_object) - - [obj_set_parent_relative_pos](functions-5.md#obj_set_parent_relative_pos) - - [obj_set_pos](functions-5.md#obj_set_pos) - - [obj_set_angle](functions-5.md#obj_set_angle) - - [obj_set_move_angle](functions-5.md#obj_set_move_angle) - - [obj_set_face_angle](functions-5.md#obj_set_face_angle) - - [obj_set_gfx_angle](functions-5.md#obj_set_gfx_angle) - - [obj_set_gfx_pos](functions-5.md#obj_set_gfx_pos) - - [obj_set_gfx_scale](functions-5.md#obj_set_gfx_scale) - - [spawn_water_droplet](functions-5.md#spawn_water_droplet) - - [obj_build_relative_transform](functions-5.md#obj_build_relative_transform) - - [cur_obj_move_using_vel](functions-5.md#cur_obj_move_using_vel) - - [obj_copy_graph_y_offset](functions-5.md#obj_copy_graph_y_offset) - - [obj_copy_pos_and_angle](functions-5.md#obj_copy_pos_and_angle) - - [obj_copy_pos](functions-5.md#obj_copy_pos) - - [obj_copy_angle](functions-5.md#obj_copy_angle) - - [obj_set_gfx_pos_from_pos](functions-5.md#obj_set_gfx_pos_from_pos) - - [obj_init_animation](functions-5.md#obj_init_animation) - - [linear_mtxf_mul_vec3f](functions-5.md#linear_mtxf_mul_vec3f) - - [linear_mtxf_transpose_mul_vec3f](functions-5.md#linear_mtxf_transpose_mul_vec3f) - - [obj_apply_scale_to_transform](functions-5.md#obj_apply_scale_to_transform) - - [obj_copy_scale](functions-5.md#obj_copy_scale) - - [obj_scale_xyz](functions-5.md#obj_scale_xyz) - - [obj_scale](functions-5.md#obj_scale) - - [cur_obj_scale](functions-5.md#cur_obj_scale) - - [cur_obj_init_animation](functions-5.md#cur_obj_init_animation) - - [cur_obj_init_animation_with_sound](functions-5.md#cur_obj_init_animation_with_sound) - - [obj_init_animation_with_accel_and_sound](functions-5.md#obj_init_animation_with_accel_and_sound) - - [cur_obj_init_animation_with_accel_and_sound](functions-5.md#cur_obj_init_animation_with_accel_and_sound) - - [obj_init_animation_with_sound](functions-5.md#obj_init_animation_with_sound) - - [cur_obj_enable_rendering_and_become_tangible](functions-5.md#cur_obj_enable_rendering_and_become_tangible) - - [cur_obj_enable_rendering](functions-5.md#cur_obj_enable_rendering) - - [cur_obj_disable_rendering_and_become_intangible](functions-5.md#cur_obj_disable_rendering_and_become_intangible) - - [cur_obj_disable_rendering](functions-5.md#cur_obj_disable_rendering) - - [cur_obj_unhide](functions-5.md#cur_obj_unhide) - - [cur_obj_hide](functions-5.md#cur_obj_hide) - - [cur_obj_set_pos_relative](functions-5.md#cur_obj_set_pos_relative) - - [cur_obj_set_pos_relative_to_parent](functions-5.md#cur_obj_set_pos_relative_to_parent) - - [cur_obj_enable_rendering_2](functions-5.md#cur_obj_enable_rendering_2) - - [cur_obj_unused_init_on_floor](functions-5.md#cur_obj_unused_init_on_floor) - - [obj_set_face_angle_to_move_angle](functions-5.md#obj_set_face_angle_to_move_angle) - - [get_object_list_from_behavior](functions-5.md#get_object_list_from_behavior) - - [cur_obj_nearest_object_with_behavior](functions-5.md#cur_obj_nearest_object_with_behavior) - - [cur_obj_dist_to_nearest_object_with_behavior](functions-5.md#cur_obj_dist_to_nearest_object_with_behavior) - - [cur_obj_find_nearest_pole](functions-5.md#cur_obj_find_nearest_pole) - - [cur_obj_find_nearest_object_with_behavior](functions-5.md#cur_obj_find_nearest_object_with_behavior) - - [cur_obj_count_objects_with_behavior](functions-5.md#cur_obj_count_objects_with_behavior) - - [find_unimportant_object](functions-5.md#find_unimportant_object) - - [count_unimportant_objects](functions-5.md#count_unimportant_objects) - - [count_objects_with_behavior](functions-5.md#count_objects_with_behavior) - - [find_object_with_behavior](functions-5.md#find_object_with_behavior) - - [cur_obj_find_nearby_held_actor](functions-5.md#cur_obj_find_nearby_held_actor) - - [cur_obj_reset_timer_and_subaction](functions-5.md#cur_obj_reset_timer_and_subaction) - - [cur_obj_change_action](functions-5.md#cur_obj_change_action) - - [cur_obj_set_vel_from_mario_vel](functions-5.md#cur_obj_set_vel_from_mario_vel) - - [cur_obj_reverse_animation](functions-5.md#cur_obj_reverse_animation) - - [cur_obj_extend_animation_if_at_end](functions-5.md#cur_obj_extend_animation_if_at_end) - - [cur_obj_check_if_near_animation_end](functions-5.md#cur_obj_check_if_near_animation_end) - - [cur_obj_check_if_at_animation_end](functions-5.md#cur_obj_check_if_at_animation_end) - - [cur_obj_check_anim_frame](functions-5.md#cur_obj_check_anim_frame) - - [cur_obj_check_anim_frame_in_range](functions-5.md#cur_obj_check_anim_frame_in_range) - - [cur_obj_check_frame_prior_current_frame](functions-5.md#cur_obj_check_frame_prior_current_frame) - - [mario_is_in_air_action](functions-5.md#mario_is_in_air_action) - - [mario_is_dive_sliding](functions-5.md#mario_is_dive_sliding) - - [cur_obj_set_y_vel_and_animation](functions-5.md#cur_obj_set_y_vel_and_animation) - - [cur_obj_unrender_and_reset_state](functions-5.md#cur_obj_unrender_and_reset_state) - - [cur_obj_move_after_thrown_or_dropped](functions-5.md#cur_obj_move_after_thrown_or_dropped) - - [cur_obj_get_thrown_or_placed](functions-5.md#cur_obj_get_thrown_or_placed) - - [cur_obj_get_dropped](functions-5.md#cur_obj_get_dropped) - - [mario_set_flag](functions-5.md#mario_set_flag) - - [cur_obj_clear_interact_status_flag](functions-5.md#cur_obj_clear_interact_status_flag) - - [obj_mark_for_deletion](functions-5.md#obj_mark_for_deletion) - - [cur_obj_disable](functions-5.md#cur_obj_disable) - - [cur_obj_become_intangible](functions-5.md#cur_obj_become_intangible) - - [cur_obj_become_tangible](functions-5.md#cur_obj_become_tangible) - - [obj_become_tangible](functions-5.md#obj_become_tangible) - - [cur_obj_update_floor_height](functions-5.md#cur_obj_update_floor_height) - - [cur_obj_update_floor_height_and_get_floor](functions-5.md#cur_obj_update_floor_height_and_get_floor) - - [apply_drag_to_value](functions-5.md#apply_drag_to_value) - - [cur_obj_apply_drag_xz](functions-5.md#cur_obj_apply_drag_xz) - - [cur_obj_move_xz](functions-5.md#cur_obj_move_xz) - - [cur_obj_move_update_underwater_flags](functions-5.md#cur_obj_move_update_underwater_flags) - - [cur_obj_move_update_ground_air_flags](functions-5.md#cur_obj_move_update_ground_air_flags) - - [cur_obj_move_y_and_get_water_level](functions-5.md#cur_obj_move_y_and_get_water_level) - - [cur_obj_move_y](functions-5.md#cur_obj_move_y) - - [cur_obj_unused_resolve_wall_collisions](functions-5.md#cur_obj_unused_resolve_wall_collisions) - - [abs_angle_diff](functions-5.md#abs_angle_diff) - - [cur_obj_move_xz_using_fvel_and_yaw](functions-5.md#cur_obj_move_xz_using_fvel_and_yaw) - - [cur_obj_move_y_with_terminal_vel](functions-5.md#cur_obj_move_y_with_terminal_vel) - - [cur_obj_compute_vel_xz](functions-5.md#cur_obj_compute_vel_xz) - - [increment_velocity_toward_range](functions-5.md#increment_velocity_toward_range) - - [obj_check_if_collided_with_object](functions-5.md#obj_check_if_collided_with_object) - - [cur_obj_set_behavior](functions-5.md#cur_obj_set_behavior) - - [obj_set_behavior](functions-5.md#obj_set_behavior) - - [cur_obj_has_behavior](functions-5.md#cur_obj_has_behavior) - - [obj_has_behavior](functions-5.md#obj_has_behavior) - - [cur_obj_lateral_dist_from_obj_to_home](functions-5.md#cur_obj_lateral_dist_from_obj_to_home) - - [cur_obj_lateral_dist_from_mario_to_home](functions-5.md#cur_obj_lateral_dist_from_mario_to_home) - - [cur_obj_lateral_dist_to_home](functions-5.md#cur_obj_lateral_dist_to_home) - - [cur_obj_outside_home_square](functions-5.md#cur_obj_outside_home_square) - - [cur_obj_outside_home_rectangle](functions-5.md#cur_obj_outside_home_rectangle) - - [cur_obj_set_pos_to_home](functions-5.md#cur_obj_set_pos_to_home) - - [cur_obj_set_pos_to_home_and_stop](functions-5.md#cur_obj_set_pos_to_home_and_stop) - - [cur_obj_shake_y](functions-5.md#cur_obj_shake_y) - - [cur_obj_start_cam_event](functions-5.md#cur_obj_start_cam_event) - - [set_mario_interact_hoot_if_in_range](functions-5.md#set_mario_interact_hoot_if_in_range) - - [obj_set_billboard](functions-5.md#obj_set_billboard) - - [obj_set_cylboard](functions-5.md#obj_set_cylboard) - - [cur_obj_set_billboard_if_vanilla_cam](functions-5.md#cur_obj_set_billboard_if_vanilla_cam) - - [obj_set_hitbox_radius_and_height](functions-5.md#obj_set_hitbox_radius_and_height) - - [obj_set_hurtbox_radius_and_height](functions-5.md#obj_set_hurtbox_radius_and_height) - - [cur_obj_set_hitbox_radius_and_height](functions-5.md#cur_obj_set_hitbox_radius_and_height) - - [cur_obj_set_hurtbox_radius_and_height](functions-5.md#cur_obj_set_hurtbox_radius_and_height) - - [obj_spawn_loot_coins](functions-5.md#obj_spawn_loot_coins) - - [obj_spawn_loot_blue_coins](functions-5.md#obj_spawn_loot_blue_coins) - - [obj_spawn_loot_yellow_coins](functions-5.md#obj_spawn_loot_yellow_coins) - - [cur_obj_spawn_loot_coin_at_mario_pos](functions-5.md#cur_obj_spawn_loot_coin_at_mario_pos) - - [cur_obj_abs_y_dist_to_home](functions-5.md#cur_obj_abs_y_dist_to_home) - - [cur_obj_advance_looping_anim](functions-5.md#cur_obj_advance_looping_anim) - - [cur_obj_detect_steep_floor](functions-5.md#cur_obj_detect_steep_floor) - - [cur_obj_resolve_wall_collisions](functions-5.md#cur_obj_resolve_wall_collisions) - - [cur_obj_update_floor](functions-5.md#cur_obj_update_floor) - - [cur_obj_update_floor_and_resolve_wall_collisions](functions-5.md#cur_obj_update_floor_and_resolve_wall_collisions) - - [cur_obj_update_floor_and_walls](functions-5.md#cur_obj_update_floor_and_walls) - - [cur_obj_move_standard](functions-5.md#cur_obj_move_standard) - - [cur_obj_within_12k_bounds](functions-5.md#cur_obj_within_12k_bounds) - - [cur_obj_move_using_vel_and_gravity](functions-5.md#cur_obj_move_using_vel_and_gravity) - - [cur_obj_move_using_fvel_and_gravity](functions-5.md#cur_obj_move_using_fvel_and_gravity) - - [obj_set_pos_relative](functions-5.md#obj_set_pos_relative) - - [cur_obj_angle_to_home](functions-5.md#cur_obj_angle_to_home) - - [obj_set_gfx_pos_at_obj_pos](functions-5.md#obj_set_gfx_pos_at_obj_pos) - - [obj_translate_local](functions-5.md#obj_translate_local) - - [obj_build_transform_from_pos_and_angle](functions-5.md#obj_build_transform_from_pos_and_angle) - - [obj_set_throw_matrix_from_transform](functions-5.md#obj_set_throw_matrix_from_transform) - - [obj_build_transform_relative_to_parent](functions-5.md#obj_build_transform_relative_to_parent) - - [obj_create_transform_from_self](functions-5.md#obj_create_transform_from_self) - - [cur_obj_rotate_move_angle_using_vel](functions-5.md#cur_obj_rotate_move_angle_using_vel) - - [cur_obj_rotate_face_angle_using_vel](functions-5.md#cur_obj_rotate_face_angle_using_vel) - - [cur_obj_set_face_angle_to_move_angle](functions-5.md#cur_obj_set_face_angle_to_move_angle) - - [cur_obj_follow_path](functions-5.md#cur_obj_follow_path) - - [chain_segment_init](functions-5.md#chain_segment_init) - - [random_f32_around_zero](functions-5.md#random_f32_around_zero) - - [obj_scale_random](functions-5.md#obj_scale_random) - - [obj_translate_xyz_random](functions-5.md#obj_translate_xyz_random) - - [obj_translate_xz_random](functions-5.md#obj_translate_xz_random) - - [obj_build_vel_from_transform](functions-5.md#obj_build_vel_from_transform) - - [cur_obj_set_pos_via_transform](functions-5.md#cur_obj_set_pos_via_transform) - - [cur_obj_reflect_move_angle_off_wall](functions-5.md#cur_obj_reflect_move_angle_off_wall) - - [cur_obj_spawn_particles](functions-5.md#cur_obj_spawn_particles) - - [obj_set_hitbox](functions-5.md#obj_set_hitbox) - - [signum_positive](functions-5.md#signum_positive) - - [cur_obj_wait_then_blink](functions-5.md#cur_obj_wait_then_blink) - - [cur_obj_is_mario_ground_pounding_platform](functions-5.md#cur_obj_is_mario_ground_pounding_platform) - - [obj_is_mario_ground_pounding_platform](functions-5.md#obj_is_mario_ground_pounding_platform) - - [spawn_mist_particles](functions-5.md#spawn_mist_particles) - - [spawn_mist_particles_with_sound](functions-5.md#spawn_mist_particles_with_sound) - - [cur_obj_push_mario_away](functions-5.md#cur_obj_push_mario_away) - - [cur_obj_push_mario_away_from_cylinder](functions-5.md#cur_obj_push_mario_away_from_cylinder) - - [bhv_dust_smoke_loop](functions-5.md#bhv_dust_smoke_loop) - - [stub_obj_helpers_3](functions-5.md#stub_obj_helpers_3) - - [cur_obj_scale_over_time](functions-5.md#cur_obj_scale_over_time) - - [cur_obj_set_pos_to_home_with_debug](functions-5.md#cur_obj_set_pos_to_home_with_debug) - - [stub_obj_helpers_4](functions-5.md#stub_obj_helpers_4) - - [cur_obj_is_mario_on_platform](functions-5.md#cur_obj_is_mario_on_platform) - - [cur_obj_is_any_player_on_platform](functions-5.md#cur_obj_is_any_player_on_platform) - - [cur_obj_shake_y_until](functions-5.md#cur_obj_shake_y_until) - - [cur_obj_move_up_and_down](functions-5.md#cur_obj_move_up_and_down) - - [spawn_star_with_no_lvl_exit](functions-5.md#spawn_star_with_no_lvl_exit) - - [spawn_base_star_with_no_lvl_exit](functions-5.md#spawn_base_star_with_no_lvl_exit) - - [bit_shift_left](functions-5.md#bit_shift_left) - - [cur_obj_mario_far_away](functions-5.md#cur_obj_mario_far_away) - - [is_mario_moving_fast_or_in_air](functions-5.md#is_mario_moving_fast_or_in_air) - - [is_item_in_array](functions-5.md#is_item_in_array) - - [bhv_init_room](functions-5.md#bhv_init_room) - - [cur_obj_enable_rendering_if_mario_in_room](functions-5.md#cur_obj_enable_rendering_if_mario_in_room) - - [cur_obj_set_hitbox_and_die_if_attacked](functions-5.md#cur_obj_set_hitbox_and_die_if_attacked) - - [obj_explode_and_spawn_coins](functions-5.md#obj_explode_and_spawn_coins) - - [cur_obj_if_hit_wall_bounce_away](functions-5.md#cur_obj_if_hit_wall_bounce_away) - - [cur_obj_hide_if_mario_far_away_y](functions-5.md#cur_obj_hide_if_mario_far_away_y) - - [obj_is_hidden](functions-5.md#obj_is_hidden) - - [enable_time_stop](functions-5.md#enable_time_stop) - - [enable_time_stop_if_alone](functions-5.md#enable_time_stop_if_alone) - - [disable_time_stop](functions-5.md#disable_time_stop) - - [set_time_stop_flags](functions-5.md#set_time_stop_flags) - - [set_time_stop_flags_if_alone](functions-5.md#set_time_stop_flags_if_alone) - - [clear_time_stop_flags](functions-5.md#clear_time_stop_flags) - - [cur_obj_can_mario_activate_textbox](functions-5.md#cur_obj_can_mario_activate_textbox) - - [cur_obj_can_mario_activate_textbox_2](functions-5.md#cur_obj_can_mario_activate_textbox_2) - - [cur_obj_end_dialog](functions-5.md#cur_obj_end_dialog) - - [cur_obj_has_model](functions-5.md#cur_obj_has_model) - - [cur_obj_align_gfx_with_floor](functions-5.md#cur_obj_align_gfx_with_floor) - - [mario_is_within_rectangle](functions-5.md#mario_is_within_rectangle) - - [cur_obj_shake_screen](functions-5.md#cur_obj_shake_screen) - - [obj_attack_collided_from_other_object](functions-5.md#obj_attack_collided_from_other_object) - - [cur_obj_was_attacked_or_ground_pounded](functions-5.md#cur_obj_was_attacked_or_ground_pounded) - - [obj_copy_behavior_params](functions-5.md#obj_copy_behavior_params) - - [cur_obj_init_animation_and_anim_frame](functions-5.md#cur_obj_init_animation_and_anim_frame) - - [cur_obj_init_animation_and_check_if_near_end](functions-5.md#cur_obj_init_animation_and_check_if_near_end) - - [cur_obj_init_animation_and_extend_if_at_end](functions-5.md#cur_obj_init_animation_and_extend_if_at_end) - - [cur_obj_check_grabbed_mario](functions-5.md#cur_obj_check_grabbed_mario) - - [player_performed_grab_escape_action](functions-5.md#player_performed_grab_escape_action) - - [cur_obj_unused_play_footstep_sound](functions-5.md#cur_obj_unused_play_footstep_sound) - - [enable_time_stop_including_mario](functions-5.md#enable_time_stop_including_mario) - - [disable_time_stop_including_mario](functions-5.md#disable_time_stop_including_mario) - - [cur_obj_check_interacted](functions-5.md#cur_obj_check_interacted) - - [cur_obj_spawn_loot_blue_coin](functions-5.md#cur_obj_spawn_loot_blue_coin) - - [cur_obj_spawn_star_at_y_offset](functions-5.md#cur_obj_spawn_star_at_y_offset) - - [cur_obj_set_home_once](functions-5.md#cur_obj_set_home_once) - - [get_trajectory_length](functions-5.md#get_trajectory_length) + - [clear_move_flag](functions-6.md#clear_move_flag) + - [set_room_override](functions-6.md#set_room_override) + - [obj_update_pos_from_parent_transformation](functions-6.md#obj_update_pos_from_parent_transformation) + - [obj_apply_scale_to_matrix](functions-6.md#obj_apply_scale_to_matrix) + - [create_transformation_from_matrices](functions-6.md#create_transformation_from_matrices) + - [obj_set_held_state](functions-6.md#obj_set_held_state) + - [lateral_dist_between_objects](functions-6.md#lateral_dist_between_objects) + - [dist_between_objects](functions-6.md#dist_between_objects) + - [dist_between_object_and_point](functions-6.md#dist_between_object_and_point) + - [cur_obj_forward_vel_approach_upward](functions-6.md#cur_obj_forward_vel_approach_upward) + - [approach_f32_signed](functions-6.md#approach_f32_signed) + - [approach_f32_symmetric](functions-6.md#approach_f32_symmetric) + - [approach_s16_symmetric](functions-6.md#approach_s16_symmetric) + - [cur_obj_rotate_yaw_toward](functions-6.md#cur_obj_rotate_yaw_toward) + - [obj_angle_to_object](functions-6.md#obj_angle_to_object) + - [obj_pitch_to_object](functions-6.md#obj_pitch_to_object) + - [obj_angle_to_point](functions-6.md#obj_angle_to_point) + - [obj_turn_toward_object](functions-6.md#obj_turn_toward_object) + - [obj_set_parent_relative_pos](functions-6.md#obj_set_parent_relative_pos) + - [obj_set_pos](functions-6.md#obj_set_pos) + - [obj_set_angle](functions-6.md#obj_set_angle) + - [obj_set_move_angle](functions-6.md#obj_set_move_angle) + - [obj_set_face_angle](functions-6.md#obj_set_face_angle) + - [obj_set_gfx_angle](functions-6.md#obj_set_gfx_angle) + - [obj_set_gfx_pos](functions-6.md#obj_set_gfx_pos) + - [obj_set_gfx_scale](functions-6.md#obj_set_gfx_scale) + - [spawn_water_droplet](functions-6.md#spawn_water_droplet) + - [obj_build_relative_transform](functions-6.md#obj_build_relative_transform) + - [cur_obj_move_using_vel](functions-6.md#cur_obj_move_using_vel) + - [obj_copy_graph_y_offset](functions-6.md#obj_copy_graph_y_offset) + - [obj_copy_pos_and_angle](functions-6.md#obj_copy_pos_and_angle) + - [obj_copy_pos](functions-6.md#obj_copy_pos) + - [obj_copy_angle](functions-6.md#obj_copy_angle) + - [obj_set_gfx_pos_from_pos](functions-6.md#obj_set_gfx_pos_from_pos) + - [obj_init_animation](functions-6.md#obj_init_animation) + - [linear_mtxf_mul_vec3f](functions-6.md#linear_mtxf_mul_vec3f) + - [linear_mtxf_transpose_mul_vec3f](functions-6.md#linear_mtxf_transpose_mul_vec3f) + - [obj_apply_scale_to_transform](functions-6.md#obj_apply_scale_to_transform) + - [obj_copy_scale](functions-6.md#obj_copy_scale) + - [obj_scale_xyz](functions-6.md#obj_scale_xyz) + - [obj_scale](functions-6.md#obj_scale) + - [cur_obj_scale](functions-6.md#cur_obj_scale) + - [cur_obj_init_animation](functions-6.md#cur_obj_init_animation) + - [cur_obj_init_animation_with_sound](functions-6.md#cur_obj_init_animation_with_sound) + - [obj_init_animation_with_accel_and_sound](functions-6.md#obj_init_animation_with_accel_and_sound) + - [cur_obj_init_animation_with_accel_and_sound](functions-6.md#cur_obj_init_animation_with_accel_and_sound) + - [obj_init_animation_with_sound](functions-6.md#obj_init_animation_with_sound) + - [cur_obj_enable_rendering_and_become_tangible](functions-6.md#cur_obj_enable_rendering_and_become_tangible) + - [cur_obj_enable_rendering](functions-6.md#cur_obj_enable_rendering) + - [cur_obj_disable_rendering_and_become_intangible](functions-6.md#cur_obj_disable_rendering_and_become_intangible) + - [cur_obj_disable_rendering](functions-6.md#cur_obj_disable_rendering) + - [cur_obj_unhide](functions-6.md#cur_obj_unhide) + - [cur_obj_hide](functions-6.md#cur_obj_hide) + - [cur_obj_set_pos_relative](functions-6.md#cur_obj_set_pos_relative) + - [cur_obj_set_pos_relative_to_parent](functions-6.md#cur_obj_set_pos_relative_to_parent) + - [cur_obj_enable_rendering_2](functions-6.md#cur_obj_enable_rendering_2) + - [cur_obj_unused_init_on_floor](functions-6.md#cur_obj_unused_init_on_floor) + - [obj_set_face_angle_to_move_angle](functions-6.md#obj_set_face_angle_to_move_angle) + - [get_object_list_from_behavior](functions-6.md#get_object_list_from_behavior) + - [cur_obj_nearest_object_with_behavior](functions-6.md#cur_obj_nearest_object_with_behavior) + - [cur_obj_dist_to_nearest_object_with_behavior](functions-6.md#cur_obj_dist_to_nearest_object_with_behavior) + - [cur_obj_find_nearest_pole](functions-6.md#cur_obj_find_nearest_pole) + - [cur_obj_find_nearest_object_with_behavior](functions-6.md#cur_obj_find_nearest_object_with_behavior) + - [cur_obj_count_objects_with_behavior](functions-6.md#cur_obj_count_objects_with_behavior) + - [find_unimportant_object](functions-6.md#find_unimportant_object) + - [count_unimportant_objects](functions-6.md#count_unimportant_objects) + - [count_objects_with_behavior](functions-6.md#count_objects_with_behavior) + - [find_object_with_behavior](functions-6.md#find_object_with_behavior) + - [cur_obj_find_nearby_held_actor](functions-6.md#cur_obj_find_nearby_held_actor) + - [cur_obj_reset_timer_and_subaction](functions-6.md#cur_obj_reset_timer_and_subaction) + - [cur_obj_change_action](functions-6.md#cur_obj_change_action) + - [cur_obj_set_vel_from_mario_vel](functions-6.md#cur_obj_set_vel_from_mario_vel) + - [cur_obj_reverse_animation](functions-6.md#cur_obj_reverse_animation) + - [cur_obj_extend_animation_if_at_end](functions-6.md#cur_obj_extend_animation_if_at_end) + - [cur_obj_check_if_near_animation_end](functions-6.md#cur_obj_check_if_near_animation_end) + - [cur_obj_check_if_at_animation_end](functions-6.md#cur_obj_check_if_at_animation_end) + - [cur_obj_check_anim_frame](functions-6.md#cur_obj_check_anim_frame) + - [cur_obj_check_anim_frame_in_range](functions-6.md#cur_obj_check_anim_frame_in_range) + - [cur_obj_check_frame_prior_current_frame](functions-6.md#cur_obj_check_frame_prior_current_frame) + - [mario_is_in_air_action](functions-6.md#mario_is_in_air_action) + - [mario_is_dive_sliding](functions-6.md#mario_is_dive_sliding) + - [cur_obj_set_y_vel_and_animation](functions-6.md#cur_obj_set_y_vel_and_animation) + - [cur_obj_unrender_and_reset_state](functions-6.md#cur_obj_unrender_and_reset_state) + - [cur_obj_move_after_thrown_or_dropped](functions-6.md#cur_obj_move_after_thrown_or_dropped) + - [cur_obj_get_thrown_or_placed](functions-6.md#cur_obj_get_thrown_or_placed) + - [cur_obj_get_dropped](functions-6.md#cur_obj_get_dropped) + - [mario_set_flag](functions-6.md#mario_set_flag) + - [cur_obj_clear_interact_status_flag](functions-6.md#cur_obj_clear_interact_status_flag) + - [obj_mark_for_deletion](functions-6.md#obj_mark_for_deletion) + - [cur_obj_disable](functions-6.md#cur_obj_disable) + - [cur_obj_become_intangible](functions-6.md#cur_obj_become_intangible) + - [cur_obj_become_tangible](functions-6.md#cur_obj_become_tangible) + - [obj_become_tangible](functions-6.md#obj_become_tangible) + - [cur_obj_update_floor_height](functions-6.md#cur_obj_update_floor_height) + - [cur_obj_update_floor_height_and_get_floor](functions-6.md#cur_obj_update_floor_height_and_get_floor) + - [apply_drag_to_value](functions-6.md#apply_drag_to_value) + - [cur_obj_apply_drag_xz](functions-6.md#cur_obj_apply_drag_xz) + - [cur_obj_move_xz](functions-6.md#cur_obj_move_xz) + - [cur_obj_move_update_underwater_flags](functions-6.md#cur_obj_move_update_underwater_flags) + - [cur_obj_move_update_ground_air_flags](functions-6.md#cur_obj_move_update_ground_air_flags) + - [cur_obj_move_y_and_get_water_level](functions-6.md#cur_obj_move_y_and_get_water_level) + - [cur_obj_move_y](functions-6.md#cur_obj_move_y) + - [cur_obj_unused_resolve_wall_collisions](functions-6.md#cur_obj_unused_resolve_wall_collisions) + - [abs_angle_diff](functions-6.md#abs_angle_diff) + - [cur_obj_move_xz_using_fvel_and_yaw](functions-6.md#cur_obj_move_xz_using_fvel_and_yaw) + - [cur_obj_move_y_with_terminal_vel](functions-6.md#cur_obj_move_y_with_terminal_vel) + - [cur_obj_compute_vel_xz](functions-6.md#cur_obj_compute_vel_xz) + - [increment_velocity_toward_range](functions-6.md#increment_velocity_toward_range) + - [obj_check_if_collided_with_object](functions-6.md#obj_check_if_collided_with_object) + - [cur_obj_set_behavior](functions-6.md#cur_obj_set_behavior) + - [obj_set_behavior](functions-6.md#obj_set_behavior) + - [cur_obj_has_behavior](functions-6.md#cur_obj_has_behavior) + - [obj_has_behavior](functions-6.md#obj_has_behavior) + - [cur_obj_lateral_dist_from_obj_to_home](functions-6.md#cur_obj_lateral_dist_from_obj_to_home) + - [cur_obj_lateral_dist_from_mario_to_home](functions-6.md#cur_obj_lateral_dist_from_mario_to_home) + - [cur_obj_lateral_dist_to_home](functions-6.md#cur_obj_lateral_dist_to_home) + - [cur_obj_outside_home_square](functions-6.md#cur_obj_outside_home_square) + - [cur_obj_outside_home_rectangle](functions-6.md#cur_obj_outside_home_rectangle) + - [cur_obj_set_pos_to_home](functions-6.md#cur_obj_set_pos_to_home) + - [cur_obj_set_pos_to_home_and_stop](functions-6.md#cur_obj_set_pos_to_home_and_stop) + - [cur_obj_shake_y](functions-6.md#cur_obj_shake_y) + - [cur_obj_start_cam_event](functions-6.md#cur_obj_start_cam_event) + - [set_mario_interact_hoot_if_in_range](functions-6.md#set_mario_interact_hoot_if_in_range) + - [obj_set_billboard](functions-6.md#obj_set_billboard) + - [obj_set_cylboard](functions-6.md#obj_set_cylboard) + - [cur_obj_set_billboard_if_vanilla_cam](functions-6.md#cur_obj_set_billboard_if_vanilla_cam) + - [obj_set_hitbox_radius_and_height](functions-6.md#obj_set_hitbox_radius_and_height) + - [obj_set_hurtbox_radius_and_height](functions-6.md#obj_set_hurtbox_radius_and_height) + - [cur_obj_set_hitbox_radius_and_height](functions-6.md#cur_obj_set_hitbox_radius_and_height) + - [cur_obj_set_hurtbox_radius_and_height](functions-6.md#cur_obj_set_hurtbox_radius_and_height) + - [obj_spawn_loot_coins](functions-6.md#obj_spawn_loot_coins) + - [obj_spawn_loot_blue_coins](functions-6.md#obj_spawn_loot_blue_coins) + - [obj_spawn_loot_yellow_coins](functions-6.md#obj_spawn_loot_yellow_coins) + - [cur_obj_spawn_loot_coin_at_mario_pos](functions-6.md#cur_obj_spawn_loot_coin_at_mario_pos) + - [cur_obj_abs_y_dist_to_home](functions-6.md#cur_obj_abs_y_dist_to_home) + - [cur_obj_advance_looping_anim](functions-6.md#cur_obj_advance_looping_anim) + - [cur_obj_detect_steep_floor](functions-6.md#cur_obj_detect_steep_floor) + - [cur_obj_resolve_wall_collisions](functions-6.md#cur_obj_resolve_wall_collisions) + - [cur_obj_update_floor](functions-6.md#cur_obj_update_floor) + - [cur_obj_update_floor_and_resolve_wall_collisions](functions-6.md#cur_obj_update_floor_and_resolve_wall_collisions) + - [cur_obj_update_floor_and_walls](functions-6.md#cur_obj_update_floor_and_walls) + - [cur_obj_move_standard](functions-6.md#cur_obj_move_standard) + - [cur_obj_within_12k_bounds](functions-6.md#cur_obj_within_12k_bounds) + - [cur_obj_move_using_vel_and_gravity](functions-6.md#cur_obj_move_using_vel_and_gravity) + - [cur_obj_move_using_fvel_and_gravity](functions-6.md#cur_obj_move_using_fvel_and_gravity) + - [obj_set_pos_relative](functions-6.md#obj_set_pos_relative) + - [cur_obj_angle_to_home](functions-6.md#cur_obj_angle_to_home) + - [obj_set_gfx_pos_at_obj_pos](functions-6.md#obj_set_gfx_pos_at_obj_pos) + - [obj_translate_local](functions-6.md#obj_translate_local) + - [obj_build_transform_from_pos_and_angle](functions-6.md#obj_build_transform_from_pos_and_angle) + - [obj_set_throw_matrix_from_transform](functions-6.md#obj_set_throw_matrix_from_transform) + - [obj_build_transform_relative_to_parent](functions-6.md#obj_build_transform_relative_to_parent) + - [obj_create_transform_from_self](functions-6.md#obj_create_transform_from_self) + - [cur_obj_rotate_move_angle_using_vel](functions-6.md#cur_obj_rotate_move_angle_using_vel) + - [cur_obj_rotate_face_angle_using_vel](functions-6.md#cur_obj_rotate_face_angle_using_vel) + - [cur_obj_set_face_angle_to_move_angle](functions-6.md#cur_obj_set_face_angle_to_move_angle) + - [cur_obj_follow_path](functions-6.md#cur_obj_follow_path) + - [chain_segment_init](functions-6.md#chain_segment_init) + - [random_f32_around_zero](functions-6.md#random_f32_around_zero) + - [obj_scale_random](functions-6.md#obj_scale_random) + - [obj_translate_xyz_random](functions-6.md#obj_translate_xyz_random) + - [obj_translate_xz_random](functions-6.md#obj_translate_xz_random) + - [obj_build_vel_from_transform](functions-6.md#obj_build_vel_from_transform) + - [cur_obj_set_pos_via_transform](functions-6.md#cur_obj_set_pos_via_transform) + - [cur_obj_reflect_move_angle_off_wall](functions-6.md#cur_obj_reflect_move_angle_off_wall) + - [cur_obj_spawn_particles](functions-6.md#cur_obj_spawn_particles) + - [obj_set_hitbox](functions-6.md#obj_set_hitbox) + - [signum_positive](functions-6.md#signum_positive) + - [cur_obj_wait_then_blink](functions-6.md#cur_obj_wait_then_blink) + - [cur_obj_is_mario_ground_pounding_platform](functions-6.md#cur_obj_is_mario_ground_pounding_platform) + - [obj_is_mario_ground_pounding_platform](functions-6.md#obj_is_mario_ground_pounding_platform) + - [spawn_mist_particles](functions-6.md#spawn_mist_particles) + - [spawn_mist_particles_with_sound](functions-6.md#spawn_mist_particles_with_sound) + - [cur_obj_push_mario_away](functions-6.md#cur_obj_push_mario_away) + - [cur_obj_push_mario_away_from_cylinder](functions-6.md#cur_obj_push_mario_away_from_cylinder) + - [bhv_dust_smoke_loop](functions-6.md#bhv_dust_smoke_loop) + - [stub_obj_helpers_3](functions-6.md#stub_obj_helpers_3) + - [cur_obj_scale_over_time](functions-6.md#cur_obj_scale_over_time) + - [cur_obj_set_pos_to_home_with_debug](functions-6.md#cur_obj_set_pos_to_home_with_debug) + - [stub_obj_helpers_4](functions-6.md#stub_obj_helpers_4) + - [cur_obj_is_mario_on_platform](functions-6.md#cur_obj_is_mario_on_platform) + - [cur_obj_is_any_player_on_platform](functions-6.md#cur_obj_is_any_player_on_platform) + - [cur_obj_shake_y_until](functions-6.md#cur_obj_shake_y_until) + - [cur_obj_move_up_and_down](functions-6.md#cur_obj_move_up_and_down) + - [spawn_star_with_no_lvl_exit](functions-6.md#spawn_star_with_no_lvl_exit) + - [spawn_base_star_with_no_lvl_exit](functions-6.md#spawn_base_star_with_no_lvl_exit) + - [bit_shift_left](functions-6.md#bit_shift_left) + - [cur_obj_mario_far_away](functions-6.md#cur_obj_mario_far_away) + - [is_mario_moving_fast_or_in_air](functions-6.md#is_mario_moving_fast_or_in_air) + - [is_item_in_array](functions-6.md#is_item_in_array) + - [bhv_init_room](functions-6.md#bhv_init_room) + - [cur_obj_enable_rendering_if_mario_in_room](functions-6.md#cur_obj_enable_rendering_if_mario_in_room) + - [cur_obj_set_hitbox_and_die_if_attacked](functions-6.md#cur_obj_set_hitbox_and_die_if_attacked) + - [obj_explode_and_spawn_coins](functions-6.md#obj_explode_and_spawn_coins) + - [cur_obj_if_hit_wall_bounce_away](functions-6.md#cur_obj_if_hit_wall_bounce_away) + - [cur_obj_hide_if_mario_far_away_y](functions-6.md#cur_obj_hide_if_mario_far_away_y) + - [obj_is_hidden](functions-6.md#obj_is_hidden) + - [enable_time_stop](functions-6.md#enable_time_stop) + - [enable_time_stop_if_alone](functions-6.md#enable_time_stop_if_alone) + - [disable_time_stop](functions-6.md#disable_time_stop) + - [set_time_stop_flags](functions-6.md#set_time_stop_flags) + - [set_time_stop_flags_if_alone](functions-6.md#set_time_stop_flags_if_alone) + - [clear_time_stop_flags](functions-6.md#clear_time_stop_flags) + - [cur_obj_can_mario_activate_textbox](functions-6.md#cur_obj_can_mario_activate_textbox) + - [cur_obj_can_mario_activate_textbox_2](functions-6.md#cur_obj_can_mario_activate_textbox_2) + - [cur_obj_end_dialog](functions-6.md#cur_obj_end_dialog) + - [cur_obj_has_model](functions-6.md#cur_obj_has_model) + - [cur_obj_align_gfx_with_floor](functions-6.md#cur_obj_align_gfx_with_floor) + - [mario_is_within_rectangle](functions-6.md#mario_is_within_rectangle) + - [cur_obj_shake_screen](functions-6.md#cur_obj_shake_screen) + - [obj_attack_collided_from_other_object](functions-6.md#obj_attack_collided_from_other_object) + - [cur_obj_was_attacked_or_ground_pounded](functions-6.md#cur_obj_was_attacked_or_ground_pounded) + - [obj_copy_behavior_params](functions-6.md#obj_copy_behavior_params) + - [cur_obj_init_animation_and_anim_frame](functions-6.md#cur_obj_init_animation_and_anim_frame) + - [cur_obj_init_animation_and_check_if_near_end](functions-6.md#cur_obj_init_animation_and_check_if_near_end) + - [cur_obj_init_animation_and_extend_if_at_end](functions-6.md#cur_obj_init_animation_and_extend_if_at_end) + - [cur_obj_check_grabbed_mario](functions-6.md#cur_obj_check_grabbed_mario) + - [player_performed_grab_escape_action](functions-6.md#player_performed_grab_escape_action) + - [cur_obj_unused_play_footstep_sound](functions-6.md#cur_obj_unused_play_footstep_sound) + - [enable_time_stop_including_mario](functions-6.md#enable_time_stop_including_mario) + - [disable_time_stop_including_mario](functions-6.md#disable_time_stop_including_mario) + - [cur_obj_check_interacted](functions-6.md#cur_obj_check_interacted) + - [cur_obj_spawn_loot_blue_coin](functions-6.md#cur_obj_spawn_loot_blue_coin) + - [cur_obj_spawn_star_at_y_offset](functions-6.md#cur_obj_spawn_star_at_y_offset) + - [cur_obj_set_home_once](functions-6.md#cur_obj_set_home_once) + - [get_trajectory_length](functions-6.md#get_trajectory_length)
@@ -1934,6 +1937,7 @@ - [gfx_get_vertex_buffer](functions-6.md#gfx_get_vertex_buffer) - [gfx_get_vertex_count](functions-6.md#gfx_get_vertex_count) - [gfx_get_texture](functions-6.md#gfx_get_texture) + - [gfx_get_name](functions-6.md#gfx_get_name) - [gfx_get_length](functions-6.md#gfx_get_length) - [gfx_get_command](functions-6.md#gfx_get_command) - [gfx_get_next_command](functions-6.md#gfx_get_next_command) @@ -1942,6 +1946,7 @@ - [gfx_resize](functions-6.md#gfx_resize) - [gfx_delete](functions-6.md#gfx_delete) - [gfx_delete_all](functions-6.md#gfx_delete_all) + - [vtx_get_name](functions-6.md#vtx_get_name) - [vtx_get_count](functions-6.md#vtx_get_count) - [vtx_get_vertex](functions-6.md#vtx_get_vertex) - [vtx_get_next_vertex](functions-6.md#vtx_get_next_vertex) @@ -1954,240 +1959,244 @@
- smlua_level_utils.h - - [smlua_level_util_change_area](functions-6.md#smlua_level_util_change_area) - - [smlua_level_util_get_info](functions-6.md#smlua_level_util_get_info) - - [smlua_level_util_get_info_from_short_name](functions-6.md#smlua_level_util_get_info_from_short_name) - - [smlua_level_util_get_info_from_course_num](functions-6.md#smlua_level_util_get_info_from_course_num) - - [level_register](functions-6.md#level_register) - - [level_is_vanilla_level](functions-6.md#level_is_vanilla_level) - - [warp_to_warpnode](functions-6.md#warp_to_warpnode) - - [warp_to_level](functions-6.md#warp_to_level) - - [warp_restart_level](functions-6.md#warp_restart_level) - - [warp_to_start_level](functions-6.md#warp_to_start_level) - - [warp_exit_level](functions-6.md#warp_exit_level) - - [warp_to_castle](functions-6.md#warp_to_castle) + - [smlua_level_util_change_area](functions-7.md#smlua_level_util_change_area) + - [smlua_level_util_get_info](functions-7.md#smlua_level_util_get_info) + - [smlua_level_util_get_info_from_short_name](functions-7.md#smlua_level_util_get_info_from_short_name) + - [smlua_level_util_get_info_from_course_num](functions-7.md#smlua_level_util_get_info_from_course_num) + - [level_register](functions-7.md#level_register) + - [level_is_vanilla_level](functions-7.md#level_is_vanilla_level) + - [warp_to_warpnode](functions-7.md#warp_to_warpnode) + - [warp_to_level](functions-7.md#warp_to_level) + - [warp_restart_level](functions-7.md#warp_restart_level) + - [warp_to_start_level](functions-7.md#warp_to_start_level) + - [warp_exit_level](functions-7.md#warp_exit_level) + - [warp_to_castle](functions-7.md#warp_to_castle)
- smlua_misc_utils.h - - [get_network_area_timer](functions-6.md#get_network_area_timer) - - [get_area_update_counter](functions-6.md#get_area_update_counter) - - [get_temp_s32_pointer](functions-6.md#get_temp_s32_pointer) - - [deref_s32_pointer](functions-6.md#deref_s32_pointer) - - [djui_popup_create_global](functions-6.md#djui_popup_create_global) - - [djui_is_popup_disabled](functions-6.md#djui_is_popup_disabled) - - [djui_set_popup_disabled_override](functions-6.md#djui_set_popup_disabled_override) - - [djui_reset_popup_disabled_override](functions-6.md#djui_reset_popup_disabled_override) - - [djui_is_playerlist_open](functions-6.md#djui_is_playerlist_open) - - [djui_attempting_to_open_playerlist](functions-6.md#djui_attempting_to_open_playerlist) - - [djui_get_playerlist_page_index](functions-6.md#djui_get_playerlist_page_index) - - [djui_menu_get_font](functions-6.md#djui_menu_get_font) - - [djui_menu_get_theme](functions-6.md#djui_menu_get_theme) - - [djui_is_playerlist_ping_visible](functions-6.md#djui_is_playerlist_ping_visible) - - [get_dialog_box_state](functions-6.md#get_dialog_box_state) - - [get_dialog_id](functions-6.md#get_dialog_id) - - [get_last_star_or_key](functions-6.md#get_last_star_or_key) - - [set_last_star_or_key](functions-6.md#set_last_star_or_key) - - [get_last_completed_course_num](functions-6.md#get_last_completed_course_num) - - [set_last_completed_course_num](functions-6.md#set_last_completed_course_num) - - [get_last_completed_star_num](functions-6.md#get_last_completed_star_num) - - [set_last_completed_star_num](functions-6.md#set_last_completed_star_num) - - [get_got_file_coin_hi_score](functions-6.md#get_got_file_coin_hi_score) - - [set_got_file_coin_hi_score](functions-6.md#set_got_file_coin_hi_score) - - [get_save_file_modified](functions-6.md#get_save_file_modified) - - [set_save_file_modified](functions-6.md#set_save_file_modified) - - [hud_hide](functions-6.md#hud_hide) - - [hud_show](functions-6.md#hud_show) - - [hud_is_hidden](functions-6.md#hud_is_hidden) - - [hud_get_value](functions-6.md#hud_get_value) - - [hud_set_value](functions-6.md#hud_set_value) - - [hud_render_power_meter](functions-6.md#hud_render_power_meter) - - [hud_render_power_meter_interpolated](functions-6.md#hud_render_power_meter_interpolated) - - [hud_get_flash](functions-6.md#hud_get_flash) - - [hud_set_flash](functions-6.md#hud_set_flash) - - [act_select_hud_hide](functions-6.md#act_select_hud_hide) - - [act_select_hud_show](functions-6.md#act_select_hud_show) - - [act_select_hud_is_hidden](functions-6.md#act_select_hud_is_hidden) - - [is_game_paused](functions-6.md#is_game_paused) - - [is_transition_playing](functions-6.md#is_transition_playing) - - [allocate_mario_action](functions-6.md#allocate_mario_action) - - [get_hand_foot_pos_x](functions-6.md#get_hand_foot_pos_x) - - [get_hand_foot_pos_y](functions-6.md#get_hand_foot_pos_y) - - [get_hand_foot_pos_z](functions-6.md#get_hand_foot_pos_z) - - [get_mario_anim_part_pos](functions-6.md#get_mario_anim_part_pos) - - [get_current_save_file_num](functions-6.md#get_current_save_file_num) - - [save_file_get_using_backup_slot](functions-6.md#save_file_get_using_backup_slot) - - [save_file_set_using_backup_slot](functions-6.md#save_file_set_using_backup_slot) - - [movtexqc_register](functions-6.md#movtexqc_register) - - [get_water_level](functions-6.md#get_water_level) - - [set_water_level](functions-6.md#set_water_level) - - [course_is_main_course](functions-6.md#course_is_main_course) - - [get_ttc_speed_setting](functions-6.md#get_ttc_speed_setting) - - [set_ttc_speed_setting](functions-6.md#set_ttc_speed_setting) - - [get_time](functions-6.md#get_time) - - [get_date_and_time](functions-6.md#get_date_and_time) - - [get_envfx](functions-6.md#get_envfx) - - [set_override_envfx](functions-6.md#set_override_envfx) - - [get_global_timer](functions-6.md#get_global_timer) - - [get_dialog_response](functions-6.md#get_dialog_response) - - [get_local_discord_id](functions-6.md#get_local_discord_id) - - [get_coopnet_id](functions-6.md#get_coopnet_id) - - [get_volume_master](functions-6.md#get_volume_master) - - [get_volume_level](functions-6.md#get_volume_level) - - [get_volume_sfx](functions-6.md#get_volume_sfx) - - [get_volume_env](functions-6.md#get_volume_env) - - [set_volume_master](functions-6.md#set_volume_master) - - [set_volume_level](functions-6.md#set_volume_level) - - [set_volume_sfx](functions-6.md#set_volume_sfx) - - [set_volume_env](functions-6.md#set_volume_env) - - [get_environment_region](functions-6.md#get_environment_region) - - [set_environment_region](functions-6.md#set_environment_region) - - [mod_file_exists](functions-6.md#mod_file_exists) - - [get_active_mod](functions-6.md#get_active_mod) - - [set_window_title](functions-6.md#set_window_title) - - [reset_window_title](functions-6.md#reset_window_title) - - [get_os_name](functions-6.md#get_os_name) - - [geo_get_current_root](functions-6.md#geo_get_current_root) - - [geo_get_current_master_list](functions-6.md#geo_get_current_master_list) - - [geo_get_current_perspective](functions-6.md#geo_get_current_perspective) - - [geo_get_current_camera](functions-6.md#geo_get_current_camera) - - [geo_get_current_held_object](functions-6.md#geo_get_current_held_object) - - [texture_to_lua_table](functions-6.md#texture_to_lua_table) + - [get_network_area_timer](functions-7.md#get_network_area_timer) + - [get_area_update_counter](functions-7.md#get_area_update_counter) + - [get_temp_s32_pointer](functions-7.md#get_temp_s32_pointer) + - [deref_s32_pointer](functions-7.md#deref_s32_pointer) + - [djui_popup_create_global](functions-7.md#djui_popup_create_global) + - [djui_is_popup_disabled](functions-7.md#djui_is_popup_disabled) + - [djui_set_popup_disabled_override](functions-7.md#djui_set_popup_disabled_override) + - [djui_reset_popup_disabled_override](functions-7.md#djui_reset_popup_disabled_override) + - [djui_is_playerlist_open](functions-7.md#djui_is_playerlist_open) + - [djui_attempting_to_open_playerlist](functions-7.md#djui_attempting_to_open_playerlist) + - [djui_get_playerlist_page_index](functions-7.md#djui_get_playerlist_page_index) + - [djui_menu_get_font](functions-7.md#djui_menu_get_font) + - [djui_menu_get_theme](functions-7.md#djui_menu_get_theme) + - [djui_is_playerlist_ping_visible](functions-7.md#djui_is_playerlist_ping_visible) + - [get_dialog_box_state](functions-7.md#get_dialog_box_state) + - [get_dialog_id](functions-7.md#get_dialog_id) + - [get_last_star_or_key](functions-7.md#get_last_star_or_key) + - [set_last_star_or_key](functions-7.md#set_last_star_or_key) + - [get_last_completed_course_num](functions-7.md#get_last_completed_course_num) + - [set_last_completed_course_num](functions-7.md#set_last_completed_course_num) + - [get_last_completed_star_num](functions-7.md#get_last_completed_star_num) + - [set_last_completed_star_num](functions-7.md#set_last_completed_star_num) + - [get_got_file_coin_hi_score](functions-7.md#get_got_file_coin_hi_score) + - [set_got_file_coin_hi_score](functions-7.md#set_got_file_coin_hi_score) + - [get_save_file_modified](functions-7.md#get_save_file_modified) + - [set_save_file_modified](functions-7.md#set_save_file_modified) + - [hud_hide](functions-7.md#hud_hide) + - [hud_show](functions-7.md#hud_show) + - [hud_is_hidden](functions-7.md#hud_is_hidden) + - [hud_get_value](functions-7.md#hud_get_value) + - [hud_set_value](functions-7.md#hud_set_value) + - [hud_render_power_meter](functions-7.md#hud_render_power_meter) + - [hud_render_power_meter_interpolated](functions-7.md#hud_render_power_meter_interpolated) + - [hud_get_flash](functions-7.md#hud_get_flash) + - [hud_set_flash](functions-7.md#hud_set_flash) + - [act_select_hud_hide](functions-7.md#act_select_hud_hide) + - [act_select_hud_show](functions-7.md#act_select_hud_show) + - [act_select_hud_is_hidden](functions-7.md#act_select_hud_is_hidden) + - [is_game_paused](functions-7.md#is_game_paused) + - [is_transition_playing](functions-7.md#is_transition_playing) + - [allocate_mario_action](functions-7.md#allocate_mario_action) + - [get_hand_foot_pos_x](functions-7.md#get_hand_foot_pos_x) + - [get_hand_foot_pos_y](functions-7.md#get_hand_foot_pos_y) + - [get_hand_foot_pos_z](functions-7.md#get_hand_foot_pos_z) + - [get_mario_anim_part_pos](functions-7.md#get_mario_anim_part_pos) + - [get_current_save_file_num](functions-7.md#get_current_save_file_num) + - [save_file_get_using_backup_slot](functions-7.md#save_file_get_using_backup_slot) + - [save_file_set_using_backup_slot](functions-7.md#save_file_set_using_backup_slot) + - [movtexqc_register](functions-7.md#movtexqc_register) + - [get_water_level](functions-7.md#get_water_level) + - [set_water_level](functions-7.md#set_water_level) + - [course_is_main_course](functions-7.md#course_is_main_course) + - [get_ttc_speed_setting](functions-7.md#get_ttc_speed_setting) + - [set_ttc_speed_setting](functions-7.md#set_ttc_speed_setting) + - [get_time](functions-7.md#get_time) + - [get_date_and_time](functions-7.md#get_date_and_time) + - [get_envfx](functions-7.md#get_envfx) + - [set_override_envfx](functions-7.md#set_override_envfx) + - [get_global_timer](functions-7.md#get_global_timer) + - [get_dialog_response](functions-7.md#get_dialog_response) + - [get_local_discord_id](functions-7.md#get_local_discord_id) + - [get_coopnet_id](functions-7.md#get_coopnet_id) + - [get_volume_master](functions-7.md#get_volume_master) + - [get_volume_level](functions-7.md#get_volume_level) + - [get_volume_sfx](functions-7.md#get_volume_sfx) + - [get_volume_env](functions-7.md#get_volume_env) + - [set_volume_master](functions-7.md#set_volume_master) + - [set_volume_level](functions-7.md#set_volume_level) + - [set_volume_sfx](functions-7.md#set_volume_sfx) + - [set_volume_env](functions-7.md#set_volume_env) + - [get_environment_region](functions-7.md#get_environment_region) + - [set_environment_region](functions-7.md#set_environment_region) + - [mod_file_exists](functions-7.md#mod_file_exists) + - [get_active_mod](functions-7.md#get_active_mod) + - [set_window_title](functions-7.md#set_window_title) + - [reset_window_title](functions-7.md#reset_window_title) + - [get_os_name](functions-7.md#get_os_name) + - [geo_get_current_root](functions-7.md#geo_get_current_root) + - [geo_get_current_master_list](functions-7.md#geo_get_current_master_list) + - [geo_get_current_perspective](functions-7.md#geo_get_current_perspective) + - [geo_get_current_camera](functions-7.md#geo_get_current_camera) + - [geo_get_current_held_object](functions-7.md#geo_get_current_held_object) + - [texture_to_lua_table](functions-7.md#texture_to_lua_table) + - [get_texture_name](functions-7.md#get_texture_name)
- smlua_model_utils.h - - [smlua_model_util_get_id](functions-6.md#smlua_model_util_get_id) + - [smlua_model_util_get_id](functions-7.md#smlua_model_util_get_id)
- smlua_obj_utils.h - - [spawn_sync_object](functions-6.md#spawn_sync_object) - - [spawn_non_sync_object](functions-6.md#spawn_non_sync_object) - - [obj_has_behavior_id](functions-6.md#obj_has_behavior_id) - - [obj_has_model_extended](functions-6.md#obj_has_model_extended) - - [obj_get_model_id_extended](functions-6.md#obj_get_model_id_extended) - - [obj_set_model_extended](functions-6.md#obj_set_model_extended) - - [get_trajectory](functions-6.md#get_trajectory) - - [geo_get_current_object](functions-6.md#geo_get_current_object) - - [get_current_object](functions-6.md#get_current_object) - - [get_dialog_object](functions-6.md#get_dialog_object) - - [get_cutscene_focus](functions-6.md#get_cutscene_focus) - - [get_secondary_camera_focus](functions-6.md#get_secondary_camera_focus) - - [set_cutscene_focus](functions-6.md#set_cutscene_focus) - - [set_secondary_camera_focus](functions-6.md#set_secondary_camera_focus) - - [obj_get_first](functions-6.md#obj_get_first) - - [obj_get_first_with_behavior_id](functions-6.md#obj_get_first_with_behavior_id) - - [obj_get_first_with_behavior_id_and_field_s32](functions-6.md#obj_get_first_with_behavior_id_and_field_s32) - - [obj_get_first_with_behavior_id_and_field_f32](functions-6.md#obj_get_first_with_behavior_id_and_field_f32) - - [obj_get_next](functions-6.md#obj_get_next) - - [obj_get_next_with_same_behavior_id](functions-6.md#obj_get_next_with_same_behavior_id) - - [obj_get_next_with_same_behavior_id_and_field_s32](functions-6.md#obj_get_next_with_same_behavior_id_and_field_s32) - - [obj_get_next_with_same_behavior_id_and_field_f32](functions-6.md#obj_get_next_with_same_behavior_id_and_field_f32) - - [obj_get_nearest_object_with_behavior_id](functions-6.md#obj_get_nearest_object_with_behavior_id) - - [obj_count_objects_with_behavior_id](functions-6.md#obj_count_objects_with_behavior_id) - - [obj_get_collided_object](functions-6.md#obj_get_collided_object) - - [obj_get_field_u32](functions-6.md#obj_get_field_u32) - - [obj_get_field_s32](functions-6.md#obj_get_field_s32) - - [obj_get_field_f32](functions-6.md#obj_get_field_f32) - - [obj_get_field_s16](functions-6.md#obj_get_field_s16) - - [obj_set_field_u32](functions-6.md#obj_set_field_u32) - - [obj_set_field_s32](functions-6.md#obj_set_field_s32) - - [obj_set_field_f32](functions-6.md#obj_set_field_f32) - - [obj_set_field_s16](functions-6.md#obj_set_field_s16) - - [obj_get_temp_spawn_particles_info](functions-6.md#obj_get_temp_spawn_particles_info) - - [get_temp_object_hitbox](functions-6.md#get_temp_object_hitbox) - - [obj_is_attackable](functions-6.md#obj_is_attackable) - - [obj_is_breakable_object](functions-6.md#obj_is_breakable_object) - - [obj_is_bully](functions-6.md#obj_is_bully) - - [obj_is_coin](functions-6.md#obj_is_coin) - - [obj_is_exclamation_box](functions-6.md#obj_is_exclamation_box) - - [obj_is_grabbable](functions-6.md#obj_is_grabbable) - - [obj_is_mushroom_1up](functions-6.md#obj_is_mushroom_1up) - - [obj_is_secret](functions-6.md#obj_is_secret) - - [obj_is_valid_for_interaction](functions-6.md#obj_is_valid_for_interaction) - - [obj_check_hitbox_overlap](functions-6.md#obj_check_hitbox_overlap) - - [obj_check_overlap_with_hitbox_params](functions-6.md#obj_check_overlap_with_hitbox_params) - - [obj_set_vel](functions-6.md#obj_set_vel) - - [obj_move_xyz](functions-6.md#obj_move_xyz) - - [set_whirlpools](functions-6.md#set_whirlpools) + - [spawn_sync_object](functions-7.md#spawn_sync_object) + - [spawn_non_sync_object](functions-7.md#spawn_non_sync_object) + - [obj_has_behavior_id](functions-7.md#obj_has_behavior_id) + - [obj_has_model_extended](functions-7.md#obj_has_model_extended) + - [obj_get_model_id_extended](functions-7.md#obj_get_model_id_extended) + - [obj_set_model_extended](functions-7.md#obj_set_model_extended) + - [get_trajectory](functions-7.md#get_trajectory) + - [geo_get_current_object](functions-7.md#geo_get_current_object) + - [get_current_object](functions-7.md#get_current_object) + - [get_dialog_object](functions-7.md#get_dialog_object) + - [get_cutscene_focus](functions-7.md#get_cutscene_focus) + - [get_secondary_camera_focus](functions-7.md#get_secondary_camera_focus) + - [set_cutscene_focus](functions-7.md#set_cutscene_focus) + - [set_secondary_camera_focus](functions-7.md#set_secondary_camera_focus) + - [obj_get_first](functions-7.md#obj_get_first) + - [obj_get_first_with_behavior_id](functions-7.md#obj_get_first_with_behavior_id) + - [obj_get_first_with_behavior_id_and_field_s32](functions-7.md#obj_get_first_with_behavior_id_and_field_s32) + - [obj_get_first_with_behavior_id_and_field_f32](functions-7.md#obj_get_first_with_behavior_id_and_field_f32) + - [obj_get_next](functions-7.md#obj_get_next) + - [obj_get_next_with_same_behavior_id](functions-7.md#obj_get_next_with_same_behavior_id) + - [obj_get_next_with_same_behavior_id_and_field_s32](functions-7.md#obj_get_next_with_same_behavior_id_and_field_s32) + - [obj_get_next_with_same_behavior_id_and_field_f32](functions-7.md#obj_get_next_with_same_behavior_id_and_field_f32) + - [obj_get_nearest_object_with_behavior_id](functions-7.md#obj_get_nearest_object_with_behavior_id) + - [obj_count_objects_with_behavior_id](functions-7.md#obj_count_objects_with_behavior_id) + - [obj_get_collided_object](functions-7.md#obj_get_collided_object) + - [obj_get_field_u32](functions-7.md#obj_get_field_u32) + - [obj_get_field_s32](functions-7.md#obj_get_field_s32) + - [obj_get_field_f32](functions-7.md#obj_get_field_f32) + - [obj_get_field_s16](functions-7.md#obj_get_field_s16) + - [obj_set_field_u32](functions-7.md#obj_set_field_u32) + - [obj_set_field_s32](functions-7.md#obj_set_field_s32) + - [obj_set_field_f32](functions-7.md#obj_set_field_f32) + - [obj_set_field_s16](functions-7.md#obj_set_field_s16) + - [obj_get_temp_spawn_particles_info](functions-7.md#obj_get_temp_spawn_particles_info) + - [get_temp_object_hitbox](functions-7.md#get_temp_object_hitbox) + - [obj_is_attackable](functions-7.md#obj_is_attackable) + - [obj_is_breakable_object](functions-7.md#obj_is_breakable_object) + - [obj_is_bully](functions-7.md#obj_is_bully) + - [obj_is_coin](functions-7.md#obj_is_coin) + - [obj_is_exclamation_box](functions-7.md#obj_is_exclamation_box) + - [obj_is_grabbable](functions-7.md#obj_is_grabbable) + - [obj_is_mushroom_1up](functions-7.md#obj_is_mushroom_1up) + - [obj_is_secret](functions-7.md#obj_is_secret) + - [obj_is_valid_for_interaction](functions-7.md#obj_is_valid_for_interaction) + - [obj_check_hitbox_overlap](functions-7.md#obj_check_hitbox_overlap) + - [obj_check_overlap_with_hitbox_params](functions-7.md#obj_check_overlap_with_hitbox_params) + - [obj_set_vel](functions-7.md#obj_set_vel) + - [obj_move_xyz](functions-7.md#obj_move_xyz) + - [set_whirlpools](functions-7.md#set_whirlpools)
- smlua_text_utils.h - - [smlua_text_utils_reset_all](functions-6.md#smlua_text_utils_reset_all) - - [smlua_text_utils_dialog_get](functions-6.md#smlua_text_utils_dialog_get) - - [smlua_text_utils_dialog_replace](functions-6.md#smlua_text_utils_dialog_replace) - - [smlua_text_utils_dialog_restore](functions-6.md#smlua_text_utils_dialog_restore) - - [smlua_text_utils_dialog_is_replaced](functions-6.md#smlua_text_utils_dialog_is_replaced) - - [smlua_text_utils_allocate_dialog](functions-6.md#smlua_text_utils_allocate_dialog) - - [smlua_text_utils_course_acts_replace](functions-6.md#smlua_text_utils_course_acts_replace) - - [smlua_text_utils_secret_star_replace](functions-6.md#smlua_text_utils_secret_star_replace) - - [smlua_text_utils_course_name_replace](functions-6.md#smlua_text_utils_course_name_replace) - - [smlua_text_utils_course_name_get](functions-6.md#smlua_text_utils_course_name_get) - - [smlua_text_utils_course_name_mod_index](functions-6.md#smlua_text_utils_course_name_mod_index) - - [smlua_text_utils_course_name_reset](functions-6.md#smlua_text_utils_course_name_reset) - - [smlua_text_utils_act_name_replace](functions-6.md#smlua_text_utils_act_name_replace) - - [smlua_text_utils_act_name_get](functions-6.md#smlua_text_utils_act_name_get) - - [smlua_text_utils_act_name_mod_index](functions-6.md#smlua_text_utils_act_name_mod_index) - - [smlua_text_utils_act_name_reset](functions-6.md#smlua_text_utils_act_name_reset) - - [smlua_text_utils_castle_secret_stars_replace](functions-6.md#smlua_text_utils_castle_secret_stars_replace) - - [smlua_text_utils_castle_secret_stars_get](functions-6.md#smlua_text_utils_castle_secret_stars_get) - - [smlua_text_utils_castle_secret_stars_mod_index](functions-6.md#smlua_text_utils_castle_secret_stars_mod_index) - - [smlua_text_utils_castle_secret_stars_reset](functions-6.md#smlua_text_utils_castle_secret_stars_reset) - - [smlua_text_utils_extra_text_replace](functions-6.md#smlua_text_utils_extra_text_replace) - - [smlua_text_utils_extra_text_get](functions-6.md#smlua_text_utils_extra_text_get) - - [smlua_text_utils_extra_text_mod_index](functions-6.md#smlua_text_utils_extra_text_mod_index) - - [smlua_text_utils_extra_text_reset](functions-6.md#smlua_text_utils_extra_text_reset) - - [smlua_text_utils_get_language](functions-6.md#smlua_text_utils_get_language) + - [smlua_text_utils_reset_all](functions-7.md#smlua_text_utils_reset_all) + - [smlua_text_utils_dialog_get](functions-7.md#smlua_text_utils_dialog_get) + - [smlua_text_utils_dialog_replace](functions-7.md#smlua_text_utils_dialog_replace) + - [smlua_text_utils_dialog_restore](functions-7.md#smlua_text_utils_dialog_restore) + - [smlua_text_utils_dialog_is_replaced](functions-7.md#smlua_text_utils_dialog_is_replaced) + - [smlua_text_utils_allocate_dialog](functions-7.md#smlua_text_utils_allocate_dialog) + - [smlua_text_utils_course_acts_replace](functions-7.md#smlua_text_utils_course_acts_replace) + - [smlua_text_utils_secret_star_replace](functions-7.md#smlua_text_utils_secret_star_replace) + - [smlua_text_utils_course_name_replace](functions-7.md#smlua_text_utils_course_name_replace) + - [smlua_text_utils_course_name_get](functions-7.md#smlua_text_utils_course_name_get) + - [smlua_text_utils_course_name_mod_index](functions-7.md#smlua_text_utils_course_name_mod_index) + - [smlua_text_utils_course_name_reset](functions-7.md#smlua_text_utils_course_name_reset) + - [smlua_text_utils_act_name_replace](functions-7.md#smlua_text_utils_act_name_replace) + - [smlua_text_utils_act_name_get](functions-7.md#smlua_text_utils_act_name_get) + - [smlua_text_utils_act_name_mod_index](functions-7.md#smlua_text_utils_act_name_mod_index) + - [smlua_text_utils_act_name_reset](functions-7.md#smlua_text_utils_act_name_reset) + - [smlua_text_utils_castle_secret_stars_replace](functions-7.md#smlua_text_utils_castle_secret_stars_replace) + - [smlua_text_utils_castle_secret_stars_get](functions-7.md#smlua_text_utils_castle_secret_stars_get) + - [smlua_text_utils_castle_secret_stars_mod_index](functions-7.md#smlua_text_utils_castle_secret_stars_mod_index) + - [smlua_text_utils_castle_secret_stars_reset](functions-7.md#smlua_text_utils_castle_secret_stars_reset) + - [smlua_text_utils_extra_text_replace](functions-7.md#smlua_text_utils_extra_text_replace) + - [smlua_text_utils_extra_text_get](functions-7.md#smlua_text_utils_extra_text_get) + - [smlua_text_utils_extra_text_mod_index](functions-7.md#smlua_text_utils_extra_text_mod_index) + - [smlua_text_utils_extra_text_reset](functions-7.md#smlua_text_utils_extra_text_reset) + - [smlua_text_utils_get_language](functions-7.md#smlua_text_utils_get_language)
- sound_init.h - - [reset_volume](functions-6.md#reset_volume) - - [raise_background_noise](functions-6.md#raise_background_noise) - - [lower_background_noise](functions-6.md#lower_background_noise) - - [disable_background_sound](functions-6.md#disable_background_sound) - - [enable_background_sound](functions-6.md#enable_background_sound) - - [play_menu_sounds](functions-6.md#play_menu_sounds) - - [play_painting_eject_sound](functions-6.md#play_painting_eject_sound) - - [play_infinite_stairs_music](functions-6.md#play_infinite_stairs_music) - - [set_background_music](functions-6.md#set_background_music) - - [fadeout_music](functions-6.md#fadeout_music) - - [fadeout_level_music](functions-6.md#fadeout_level_music) - - [play_cutscene_music](functions-6.md#play_cutscene_music) - - [play_shell_music](functions-6.md#play_shell_music) - - [stop_shell_music](functions-6.md#stop_shell_music) - - [play_cap_music](functions-6.md#play_cap_music) - - [fadeout_cap_music](functions-6.md#fadeout_cap_music) - - [stop_cap_music](functions-6.md#stop_cap_music) + - [reset_volume](functions-7.md#reset_volume) + - [raise_background_noise](functions-7.md#raise_background_noise) + - [lower_background_noise](functions-7.md#lower_background_noise) + - [disable_background_sound](functions-7.md#disable_background_sound) + - [enable_background_sound](functions-7.md#enable_background_sound) + - [play_menu_sounds](functions-7.md#play_menu_sounds) + - [play_painting_eject_sound](functions-7.md#play_painting_eject_sound) + - [play_infinite_stairs_music](functions-7.md#play_infinite_stairs_music) + - [set_background_music](functions-7.md#set_background_music) + - [fadeout_music](functions-7.md#fadeout_music) + - [fadeout_level_music](functions-7.md#fadeout_level_music) + - [play_cutscene_music](functions-7.md#play_cutscene_music) + - [play_shell_music](functions-7.md#play_shell_music) + - [stop_shell_music](functions-7.md#stop_shell_music) + - [play_cap_music](functions-7.md#play_cap_music) + - [fadeout_cap_music](functions-7.md#fadeout_cap_music) + - [stop_cap_music](functions-7.md#stop_cap_music)
- spawn_sound.h - - [cur_obj_play_sound_1](functions-6.md#cur_obj_play_sound_1) - - [cur_obj_play_sound_2](functions-6.md#cur_obj_play_sound_2) - - [create_sound_spawner](functions-6.md#create_sound_spawner) - - [calc_dist_to_volume_range_1](functions-6.md#calc_dist_to_volume_range_1) - - [calc_dist_to_volume_range_2](functions-6.md#calc_dist_to_volume_range_2) + - [cur_obj_play_sound_1](functions-7.md#cur_obj_play_sound_1) + - [cur_obj_play_sound_2](functions-7.md#cur_obj_play_sound_2) + - [create_sound_spawner](functions-7.md#create_sound_spawner) + - [calc_dist_to_volume_range_1](functions-7.md#calc_dist_to_volume_range_1) + - [calc_dist_to_volume_range_2](functions-7.md#calc_dist_to_volume_range_2)
- surface_collision.h - - [find_wall_collisions](functions-6.md#find_wall_collisions) - - [find_ceil_height](functions-6.md#find_ceil_height) - - [find_floor_height](functions-6.md#find_floor_height) - - [find_water_level](functions-6.md#find_water_level) - - [find_poison_gas_level](functions-6.md#find_poison_gas_level) - - [set_find_wall_direction](functions-6.md#set_find_wall_direction) - - [closest_point_to_triangle](functions-6.md#closest_point_to_triangle) + - [find_wall_collisions](functions-7.md#find_wall_collisions) + - [find_ceil_height](functions-7.md#find_ceil_height) + - [find_floor_height](functions-7.md#find_floor_height) + - [find_water_level](functions-7.md#find_water_level) + - [find_poison_gas_level](functions-7.md#find_poison_gas_level) + - [set_find_wall_direction](functions-7.md#set_find_wall_direction) + - [closest_point_to_triangle](functions-7.md#closest_point_to_triangle)
- surface_load.h - - [load_object_collision_model](functions-6.md#load_object_collision_model) - - [obj_get_surface_from_index](functions-6.md#obj_get_surface_from_index) - - [surface_has_force](functions-6.md#surface_has_force) + - [load_object_collision_model](functions-7.md#load_object_collision_model) + - [load_static_object_collision](functions-7.md#load_static_object_collision) + - [toggle_static_object_collision](functions-7.md#toggle_static_object_collision) + - [get_static_object_surface](functions-7.md#get_static_object_surface) + - [obj_get_surface_from_index](functions-7.md#obj_get_surface_from_index) + - [surface_has_force](functions-7.md#surface_has_force)
diff --git a/docs/lua/guides/lighting-engine.md b/docs/lua/guides/lighting-engine.md index 54c5963cf..1805a4201 100644 --- a/docs/lua/guides/lighting-engine.md +++ b/docs/lua/guides/lighting-engine.md @@ -1,3 +1,5 @@ +## [:rewind: Lua Reference](../lua.md) + # How to use the Lighting Engine ## Section 1: Preparation diff --git a/docs/lua/guides/mario-state.md b/docs/lua/guides/mario-state.md index 7b215e650..f24cd0dd0 100644 --- a/docs/lua/guides/mario-state.md +++ b/docs/lua/guides/mario-state.md @@ -1,3 +1,5 @@ +## [:rewind: Lua Reference](../lua.md) + # How to use `gMarioStates` ## Section 1: What is `gMarioStates`? diff --git a/docs/lua/guides/modfs.md b/docs/lua/guides/modfs.md new file mode 100644 index 000000000..41be978bb --- /dev/null +++ b/docs/lua/guides/modfs.md @@ -0,0 +1,272 @@ +## [:rewind: Lua Reference](../lua.md) + +# ModFS + +`ModFS` enables a small, sandboxed file system for mods. It allows to store and retrieve binary and text files, no matter their content.
+Each mod has its own file system, and can allow other mods to read its files. + +
+ +## Specs + +### File system + +Each ModFS file system: +- Has a maximum size of **32 MB** (`MOD_FS_MAX_SIZE`). Files can be any size, as long as the cumulative sum of file sizes doesn't exceed this limit. +- Can store at most **512 files** (`MOD_FS_MAX_FILES`). +- Is stored on disk as a `.modfs` file, which is a ZIP file, containing all files written in it. + +The ModFS files are located in the `sav` directory at the usual save file location: +- Windows: `%appdata%/sm64coopdx` +- Linux: `~/.local/share/sm64coopdx` +- MacOS: `~/Library/Application Support/sm64coopdx` + +### Files + +- The maximum filepath length is **256 characters** (`MOD_FS_MAX_PATH`), including the NUL terminator. +- Filepaths have the following restrictions: + - Cannot start, end or have two or more consecutive `/` + - Can contain only valid ASCII characters, no `*` or `\` + - Cannot be called `properties.json` (this name is reserved for ModFS internal properties) + - Only the following extensions (and extension-less files) are allowed: + - text: `.txt`, `.json`, `.ini`, `.sav` + - actors: `.bin`, `.col` + - behaviors: `.bhv` + - textures: `.tex`, `.png` + - levels: `.lvl` + - audio: `.m64`, `.aiff`, `.mp3`, `.ogg` + +
+ +## [`ModFs`](../structs.md#ModFs) + +The object holding the file system of the mod. + +### Fields + +All fields are immutable. + +| Name | Type | +| ----- | ---- | +| mod | [Mod](../structs.md#Mod) | +| modPath | `string` | +| numFiles | `integer` | +| totalSize | `integer` | +| isPublic | `boolean` | + +Fields can be accessed in Lua with the dot `.` character: +```lua +print("The ModFS " .. modFs.modPath .. " contains " .. modFs.numFiles .. " files.") +``` + +### Methods + +| Name | Reference | +| ---- | --------- | +| get_filename | [`mod_fs_get_filename`](../functions-5.md#mod_fs_get_filename) | +| get_file | [`mod_fs_get_file`](../functions-5.md#mod_fs_get_file) | +| create_file | [`mod_fs_create_file`](../functions-5.md#mod_fs_create_file) | +| move_file | [`mod_fs_move_file`](../functions-5.md#mod_fs_move_file) | +| copy_file | [`mod_fs_copy_file`](../functions-5.md#mod_fs_copy_file) | +| delete_file | [`mod_fs_delete_file`](../functions-5.md#mod_fs_delete_file) | +| clear | [`mod_fs_clear`](../functions-5.md#mod_fs_clear) | +| save | [`mod_fs_save`](../functions-5.md#mod_fs_save) | +| delete | [`mod_fs_delete`](../functions-5.md#mod_fs_delete) | +| set_public | [`mod_fs_set_public`](../functions-5.md#mod_fs_set_public) | + +Methods can be called in Lua with the colon `:` character: +```lua +print("The first file of ModFS " .. modFs.modPath .. " is named " .. modFs:get_filename(0) .. ".") +``` + +
+ +## [`ModFsFile`](../structs.md#ModFsFile) + +A handle to a ModFS file. + +### Fields + +All fields are immutable. + +| Field | Type | +| ----- | ---- | +| modFs | [ModFs](../structs.md#ModFs) | +| filepath | `string` | +| size | `integer` | +| offset | `integer` | +| isText | `boolean` | +| isPublic | `boolean` | + +Fields can be accessed in Lua with the dot `.` character: +```lua +print("The ModFS file " .. file.filepath .. " is " .. file.size .. " bytes long.") +``` + +### Methods + +| Name | Reference | +| ---- | --------- | +| read_bool | [`mod_fs_file_read_bool`](../functions-5.md#mod_fs_file_read_bool) | +| read_integer | [`mod_fs_file_read_integer`](../functions-5.md#mod_fs_file_read_integer) | +| read_number | [`mod_fs_file_read_number`](../functions-5.md#mod_fs_file_read_number) | +| read_bytes | [`mod_fs_file_read_bytes`](../functions-5.md#mod_fs_file_read_bytes) | +| read_string | [`mod_fs_file_read_string`](../functions-5.md#mod_fs_file_read_string) | +| read_line | [`mod_fs_file_read_line`](../functions-5.md#mod_fs_file_read_line) | +| write_bool | [`mod_fs_file_write_bool`](../functions-5.md#mod_fs_file_write_bool) | +| write_integer | [`mod_fs_file_write_integer`](../functions-5.md#mod_fs_file_write_integer) | +| write_number | [`mod_fs_file_write_number`](../functions-5.md#mod_fs_file_write_number) | +| write_bytes | [`mod_fs_file_write_bytes`](../functions-5.md#mod_fs_file_write_bytes) | +| write_string | [`mod_fs_file_write_string`](../functions-5.md#mod_fs_file_write_string) | +| write_line | [`mod_fs_file_write_line`](../functions-5.md#mod_fs_file_write_line) | +| seek | [`mod_fs_file_seek`](../functions-5.md#mod_fs_file_seek) | +| rewind | [`mod_fs_file_rewind`](../functions-5.md#mod_fs_file_rewind) | +| is_eof | [`mod_fs_file_is_eof`](../functions-5.md#mod_fs_file_is_eof) | +| fill | [`mod_fs_file_fill`](../functions-5.md#mod_fs_file_fill) | +| 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) | + +Methods can be called in Lua with the colon `:` character: +```lua +file:erase(file.size) +print("The ModFS file " .. file.filepath .. " is now empty.") +``` + +
+ +## Error handling + +All errors coming from ModFS functions are not blocking. However, they appear in the console and raise the "Mod has script errors" message. + +- The function [`mod_fs_hide_errors`](../functions-5.md#mod_fs_hide_errors) can suppress the ModFS errors from the console. +- Use the function [`mod_fs_get_last_error`](../functions-5.md#mod_fs_get_last_error) to retrieve the last error raised by ModFS. This function always return an error message if an error occurred, even if errors are hidden. + +
+ +## Usage with other sm64coopdx features + +One of the strengths of this feature is its interactions with other existing features of sm64coopdx: +- Load models with `smlua_model_util_get_id` +- Load textures with `get_texture_info` +- Load collisions with `smlua_collision_util_get` +- Load sequences with `smlua_audio_utils_replace_sequence` +- Load audio streams with `audio_stream_load` +- Load audio samples with `audio_sample_load` + +These functions can take a **ModFS URI** as argument instead of a resource name.
+Generate a ModFS URI from a `ModFs` object with the following code: +```lua +local uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "") +``` + +Here are some examples: + +```lua +-- Models +local custom_geo_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "custom_geo.bin") +local E_MODEL_CUSTOM = smlua_model_util_get_id(custom_geo_uri) + +-- Textures (both PNG and TEX) +local texture_png_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "texture.png") +local TEXTURE_PNG = get_texture_info(texture_png_uri) +local texture_tex_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "texture.tex") +local TEXTURE_TEX = get_texture_info(texture_tex_uri) + +-- Collisions +local custom_col_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "custom_col.col") +local COL_CUSTOM = smlua_collision_util_get(custom_col_uri) + +-- Sequences +local custom_m64_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "custom.m64") +smlua_audio_utils_replace_sequence(SEQ_LEVEL_GRASS, 0x11, 0x80, custom_m64_uri) + +-- Streams +local custom_stream_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "custom_stream.mp3") +local custom_stream = audio_stream_load(custom_stream_uri) + +-- Samples +local custom_sample_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "custom_sample.mp3") +local custom_sample = audio_sample_load(custom_sample_uri) +``` + +
+ +## Good practices + +### Always valid `ModFs` object + +Use the following piece of code to always retrieve a valid `ModFs` object: +```lua +local modFs = mod_fs_get() or mod_fs_create() +``` +If the ModFS for the current mod doesn't exist, it will create one. + +
+ +### Always valid `ModFsFile` object + +Use the following piece of code to always retrieve a valid `ModFsFile` object: +```lua +local file = modFs:get_file("myfile.txt") or modFs:create_file("myfile.txt", true) +``` +Like previously, if the file doesn't exist, it will create one.
+ +To make sure the file is empty when requested, add the following line to clear the existing file content. +```lua +file:erase(file.size) +``` + +
+ +### Correctly initialize a file + +The `get_file` method of a `ModFs` object opens a file only if the file is not loaded yet. Subsequent calls with the same filename will return the file handle without resetting its offset or mode.
+For example, one function could write to a file while another could read from the same file, so it's better to set the appropriate file offset and mode when it's needed before starting reading/writing: +```lua +local file = modFs:get_file("myfile.txt") +file:set_text_mode(true) -- Set mode to text +file:rewind() -- Reset offset to the beginning of the file +``` + +
+ +### Methods over functions + +Always use `ModFs` and `ModFsFile` objects methods over regular functions.
+It's more clear that way and helps to reduce errors: +```lua +-- Don't +local file = mod_fs_create_file(modFs, "myfile.txt", true) + +-- Do +local file = modFs:create_file("myfile.txt", true) +``` +```lua +-- Don't +mod_fs_file_write_string(file, "some text") + +-- Do +file:write_string("some text") +``` + +
+ +### Handle possible failures + +In addition to error messages that can be retrieved with [`mod_fs_get_last_error`](../functions-5.md#mod_fs_get_last_error), almost all ModFS functions have a boolean return value indicating if the function succeeded or failed. +```lua +if not modFs:delete_file("somefile") then + print(mod_fs_get_last_error()) +end +``` + +
+ +### Don't forget to save + +ModFS are not saved automatically when writing to files.
+The mod has to explicitly call the method `save` to save its ModFS on the disk. +```lua +modFs:save() +``` diff --git a/docs/lua/guides/object-lists.md b/docs/lua/guides/object-lists.md index 3a9ab5fbe..1d8a77ed8 100644 --- a/docs/lua/guides/object-lists.md +++ b/docs/lua/guides/object-lists.md @@ -1,3 +1,5 @@ +## [:rewind: Lua Reference](../lua.md) + # Every Behavior's Object List | Behavior | Object List | diff --git a/docs/lua/lua.md b/docs/lua/lua.md index 05d165769..553659b33 100644 --- a/docs/lua/lua.md +++ b/docs/lua/lua.md @@ -34,6 +34,8 @@ Save file locations: - [Hooks](guides/hooks.md) - [gMarioStates](guides/mario-state.md) - [Behavior Object Lists](guides/object-lists.md) +- [Lighting Engine](guides/lighting-engine.md) +- [ModFS](guides/modfs.md) ## Important notes on player indices @@ -69,7 +71,11 @@ All of this is a holdover from when there were only two players. It was a reason - [Custom HUD Texture](examples/custom-hud-texture) - [Custom Audio Test](examples/audio-test) - [Custom Texture Overriding](examples/texture-override) +- [Custom Animations (DynOS)](examples/custom-animations-dynos) +- [Custom Animations (Lua)](examples/custom-animations-lua) - [Bytestring Packet Example](examples/bytestring-packet-example.lua) +- [Gfx/Vtx Demo](examples/gfx-vtx-demo) +- [Lighting Engine Demo](examples/lighting-engine-demo) ## Example Lua mods (large) - [Hide and Seek Gamemode](../../mods/hide-and-seek.lua) diff --git a/docs/lua/structs.md b/docs/lua/structs.md index e603068cb..e11caf9f4 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -105,6 +105,7 @@ - [SpawnParticlesInfo](#SpawnParticlesInfo) - [StarPositions](#StarPositions) - [StarsNeededForDialog](#StarsNeededForDialog) +- [StaticObjectCollision](#StaticObjectCollision) - [Surface](#Surface) - [TextureInfo](#TextureInfo) - [TransitionInfo](#TransitionInfo) @@ -1955,7 +1956,7 @@ | Field | Type | Access | | ----- | ---- | ------ | -| file | [ModFile](structs.md#ModFile) | | +| filepath | `string` | read-only | | isStream | `boolean` | read-only | | baseVolume | `number` | | | loaded | `boolean` | read-only | @@ -2001,6 +2002,21 @@ | totalSize | `integer` | read-only | | isPublic | `boolean` | read-only | +**Functions:** + +| Name | Reference | +| ---- | --------- | +| get_filename | [`mod_fs_get_filename`](functions-5.md#mod_fs_get_filename) | +| get_file | [`mod_fs_get_file`](functions-5.md#mod_fs_get_file) | +| create_file | [`mod_fs_create_file`](functions-5.md#mod_fs_create_file) | +| move_file | [`mod_fs_move_file`](functions-5.md#mod_fs_move_file) | +| copy_file | [`mod_fs_copy_file`](functions-5.md#mod_fs_copy_file) | +| delete_file | [`mod_fs_delete_file`](functions-5.md#mod_fs_delete_file) | +| clear | [`mod_fs_clear`](functions-5.md#mod_fs_clear) | +| save | [`mod_fs_save`](functions-5.md#mod_fs_save) | +| delete | [`mod_fs_delete`](functions-5.md#mod_fs_delete) | +| set_public | [`mod_fs_set_public`](functions-5.md#mod_fs_set_public) | + [:arrow_up_small:](#)
@@ -2016,6 +2032,30 @@ | isText | `boolean` | read-only | | isPublic | `boolean` | read-only | +**Functions:** + +| Name | Reference | +| ---- | --------- | +| read_bool | [`mod_fs_file_read_bool`](functions-5.md#mod_fs_file_read_bool) | +| read_integer | [`mod_fs_file_read_integer`](functions-5.md#mod_fs_file_read_integer) | +| read_number | [`mod_fs_file_read_number`](functions-5.md#mod_fs_file_read_number) | +| read_bytes | [`mod_fs_file_read_bytes`](functions-5.md#mod_fs_file_read_bytes) | +| read_string | [`mod_fs_file_read_string`](functions-5.md#mod_fs_file_read_string) | +| read_line | [`mod_fs_file_read_line`](functions-5.md#mod_fs_file_read_line) | +| write_bool | [`mod_fs_file_write_bool`](functions-5.md#mod_fs_file_write_bool) | +| write_integer | [`mod_fs_file_write_integer`](functions-5.md#mod_fs_file_write_integer) | +| write_number | [`mod_fs_file_write_number`](functions-5.md#mod_fs_file_write_number) | +| write_bytes | [`mod_fs_file_write_bytes`](functions-5.md#mod_fs_file_write_bytes) | +| write_string | [`mod_fs_file_write_string`](functions-5.md#mod_fs_file_write_string) | +| write_line | [`mod_fs_file_write_line`](functions-5.md#mod_fs_file_write_line) | +| seek | [`mod_fs_file_seek`](functions-5.md#mod_fs_file_seek) | +| rewind | [`mod_fs_file_rewind`](functions-5.md#mod_fs_file_rewind) | +| is_eof | [`mod_fs_file_is_eof`](functions-5.md#mod_fs_file_is_eof) | +| fill | [`mod_fs_file_fill`](functions-5.md#mod_fs_file_fill) | +| 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) | + [:arrow_up_small:](#)
@@ -2947,10 +2987,9 @@ | rippleTimer | `number` | | | rippleX | `number` | | | rippleY | `number` | | -| normalDisplayList | `Pointer` <`Gfx`> | read-only | +| textureArray | `Array` <`Pointer` <`Texture`>> | read-only | | textureWidth | `integer` | read-only | | textureHeight | `integer` | read-only | -| rippleDisplayList | `Pointer` <`Gfx`> | read-only | | rippleTrigger | `integer` | | | alpha | `integer` | | | marioWasUnder | `integer` | | @@ -3211,6 +3250,17 @@
+## [StaticObjectCollision](#StaticObjectCollision) + +| Field | Type | Access | +| ----- | ---- | ------ | +| index | `integer` | read-only | +| length | `integer` | read-only | + +[:arrow_up_small:](#) + +
+ ## [Surface](#Surface) | Field | Type | Access | @@ -3240,7 +3290,7 @@ | Field | Type | Access | | ----- | ---- | ------ | -| texture | `Pointer` <`integer`> | read-only | +| texture | `Pointer` <`Texture`> | read-only | | name | `string` | read-only | | width | `integer` | read-only | | height | `integer` | read-only | diff --git a/include/PR/gbi_extension.h b/include/PR/gbi_extension.h index 1ea2d51b7..1aba0aa61 100644 --- a/include/PR/gbi_extension.h +++ b/include/PR/gbi_extension.h @@ -7,6 +7,9 @@ #define G_LIGHT_MAP_EXT 0x00000800 #define G_LIGHTING_ENGINE_EXT 0x00004000 #define G_PACKED_NORMALS_EXT 0x00000080 +#define G_CULL_INVERT_EXT 0x00000100 +#define G_FRESNEL_COLOR_EXT 0x00000040 +#define G_FRESNEL_ALPHA_EXT 0x00400000 ////////// // DJUI // @@ -118,3 +121,50 @@ (_SHIFTL(G_PPARTTOCOLOR, 24, 8)) | (_SHIFTL(color, 16, 8)), \ ((2 * ((part) + 1)) + 1 + offset) \ }} + +//////////////////// +//// G_MOVEWORD //// +//////////////////// + +#define G_MW_FX 0x00 /* replaces G_MW_MATRIX which is no longer supported */ +#define G_MWO_FRESNEL 0x0C + +/** + * Fresnel - Feature suggested by thecozies + * Enabled with the G_FRESNEL bit in geometry mode. + * The dot product between a vertex normal and the vector from the vertex to the + * camera is computed. The offset and scale here convert this to a shade alpha + * value. This is useful for making surfaces fade between transparent when + * viewed straight-on and opaque when viewed at a large angle, or for applying a + * fake "outline" around the border of meshes. + * + * If using Fresnel, you need to set the camera world position whenever you set + * the VP matrix, viewport, etc. See SPCameraWorld. + * + * The RSP does: + * s16 dotProduct = dot(vertex normal, camera pos - vertex pos); + * dotProduct = abs(dotProduct); // 0 = points to side, 7FFF = points at or away + * s32 factor = ((scale * dotProduct) >> 15) + offset; + * s16 result = clamp(factor << 8, 0, 7FFF); + * color_or_alpha = result >> 7; + * + * At dotMax, color_or_alpha = FF, result = 7F80, factor = 7F + * At dotMin, color_or_alpha = 00, result = 0, factor = 0 + * 7F = ((scale * dotMax) >> 15) + offset + * 00 = ((scale * dotMin) >> 15) + offset + * Subtract: 7F = (scale * (dotMax - dotMin)) >> 15 + * 3F8000 = scale * (dotMax - dotMin) + * scale = 3F8000 / (dotMax - dotMin) <-- + * offset = -(((3F8000 / (dotMax - dotMin)) * dotMin) >> 15) + * offset = -((7F * dotMin) / (dotMax - dotMin)) <-- + * + * To convert in the opposite direction: + * ((7F - offset) << 15) / scale = dotMax + * ((00 - offset) << 15) / scale = dotMin + */ +#define gSPFresnel(pkt, scale, offset) \ + gMoveWd(pkt, G_MW_FX, G_MWO_FRESNEL, \ + (_SHIFTL((scale), 16, 16) | _SHIFTL((offset), 0, 16))) +#define gsSPFresnel(scale, offset) \ + gsMoveWd(G_MW_FX, G_MWO_FRESNEL, \ + (_SHIFTL((scale), 16, 16) | _SHIFTL((offset), 0, 16))) diff --git a/include/gfx_symbols.h b/include/gfx_symbols.h index 0c8801995..a12858e8d 100644 --- a/include/gfx_symbols.h +++ b/include/gfx_symbols.h @@ -56,6 +56,7 @@ define_gfx_symbol(gsMoveWd, 3, false, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GF define_gfx_symbol(gsSPLoadGeometryMode, 1, false, GFX_PARAM_TYPE_INT); define_gfx_symbol(gsSPVertexNonGlobal, 3, true, GFX_PARAM_TYPE_VTX, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT); define_gfx_symbol(gsSPCopyPlayerPartToColor, 3, false, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT); +define_gfx_symbol(gsSPFresnel, 2, false, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT); define_gfx_symbol_manual(gsSPTexture, 5, false, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT); define_gfx_symbol_manual(gsSPSetGeometryMode, 1, false, GFX_PARAM_TYPE_INT); diff --git a/include/level_commands.h b/include/level_commands.h index 659c94425..b0258661c 100644 --- a/include/level_commands.h +++ b/include/level_commands.h @@ -30,6 +30,34 @@ #define WHIRLPOOL_COND_BOWSER2_BEATEN 2 #define WHIRLPOOL_COND_AT_LEAST_SECOND_STAR 3 +#define OBJECT_EXT_LUA_MODEL (1 << 0) +#define OBJECT_EXT_LUA_POS_X (1 << 1) +#define OBJECT_EXT_LUA_POS_Y (1 << 2) +#define OBJECT_EXT_LUA_POS_Z (1 << 3) +#define OBJECT_EXT_LUA_ANGLE_X (1 << 4) +#define OBJECT_EXT_LUA_ANGLE_Y (1 << 5) +#define OBJECT_EXT_LUA_ANGLE_Z (1 << 6) +#define OBJECT_EXT_LUA_BEH_PARAMS (1 << 7) +#define OBJECT_EXT_LUA_BEHAVIOR (1 << 8) +#define OBJECT_EXT_LUA_ACTS (1 << 9) + +#define OBJECT_EXT_LUA_MODEL_OFFSET(type) (type == 0x3F ? 3 : (type == 0x40 ? 20 : 4)) +#define OBJECT_EXT_LUA_POS_X_OFFSET(type) (type == 0x3F ? 4 : (type == 0x40 ? 4 : 8)) +#define OBJECT_EXT_LUA_POS_Y_OFFSET(type) (type == 0x3F ? 6 : (type == 0x40 ? 6 : 12)) +#define OBJECT_EXT_LUA_POS_Z_OFFSET(type) (type == 0x3F ? 8 : (type == 0x40 ? 8 : 16)) +#define OBJECT_EXT_LUA_ANGLE_X_OFFSET(type) (type == 0x3F ? 10 : (type == 0x40 ? 10 : 20)) +#define OBJECT_EXT_LUA_ANGLE_Y_OFFSET(type) (type == 0x3F ? 12 : (type == 0x40 ? 12 : 24)) +#define OBJECT_EXT_LUA_ANGLE_Z_OFFSET(type) (type == 0x3F ? 14 : (type == 0x40 ? 14 : 28)) +#define OBJECT_EXT_LUA_BEH_PARAMS_OFFSET(type) (type == 0x3F ? 16 : (type == 0x40 ? 16 : 32)) +#define OBJECT_EXT_LUA_BEHAVIOR_OFFSET(type) (type == 0x3F ? 20 : (type == 0x40 ? 24 : 36)) +#define OBJECT_EXT_LUA_ACTS_OFFSET(type) (type == 0x3F ? 2 : (type == 0x40 ? 2 : 40)) + +#define SHOW_DIALOG_EXT_LUA_INDEX (1 << 0) +#define SHOW_DIALOG_EXT_LUA_DIALOG (1 << 1) + +#define SHOW_DIALOG_EXT_LUA_INDEX_OFFSET(type) (4) +#define SHOW_DIALOG_EXT_LUA_DIALOG_OFFSET(type) (8) + // Head defines #define REGULAR_FACE 0x0002 #define DIZZY_FACE 0x0003 @@ -324,6 +352,30 @@ CMD_W(arg), \ CMD_PTR(target) +// This command is used when parameters are Lua variables. +// The flags parameter describes which parameter is a Lua variable. +// See OBJECT_EXT_LUA flags at the top of this file. +#define OBJECT_EXT_LUA_PARAMS(flags, model, posX, posY, posZ, angleX, angleY, angleZ, behParam, beh, acts) \ + CMD_BBH(0x43, 0x2C, flags), \ + CMD_PTR(model), \ + CMD_PTR(posX), \ + CMD_PTR(posY), \ + CMD_PTR(posZ), \ + CMD_PTR(angleX), \ + CMD_PTR(angleY), \ + CMD_PTR(angleZ), \ + CMD_PTR(behParam), \ + CMD_PTR(beh), \ + CMD_PTR(acts) + +// This command is used when parameters are Lua variables. +// The flags parameter describes which parameter is a Lua variable. +// See SHOW_DIALOG_EXT flags at the top of this file. +#define SHOW_DIALOG_EXT(flags, index, dialogId) \ + CMD_BBBB(0x44, 0x0C, flags, 0x00), \ + CMD_PTR(index), \ + CMD_PTR(dialogId) + // README // // README // // README // diff --git a/include/surface_terrains.h b/include/surface_terrains.h index 091ed64d4..c43924a5f 100644 --- a/include/surface_terrains.h +++ b/include/surface_terrains.h @@ -163,6 +163,7 @@ #define SURFACE_FLAG_DYNAMIC (1 << 0) #define SURFACE_FLAG_NO_CAM_COLLISION (1 << 1) +#define SURFACE_FLAG_INTANGIBLE (1 << 2) #define SURFACE_FLAG_X_PROJECTION (1 << 3) #define HAZARD_TYPE_LAVA_FLOOR 1 diff --git a/include/types.h b/include/types.h index 70c697636..53f07d508 100644 --- a/include/types.h +++ b/include/types.h @@ -577,7 +577,7 @@ struct MarioState struct TextureInfo { - u8 *texture; + Texture *texture; const char *name; u32 width; u32 height; diff --git a/levels/castle_inside/painting.inc.c b/levels/castle_inside/painting.inc.c index fac982371..c12f799bc 100644 --- a/levels/castle_inside/painting.inc.c +++ b/levels/castle_inside/painting.inc.c @@ -1255,57 +1255,57 @@ static const Gfx inside_castle_seg7_painting_dl_070235B8[] = { gsSPBranchList(inside_castle_seg7_painting_dl_07023580), }; -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235C0[] = { - inside_castle_seg7_texture_0700B800, inside_castle_seg7_texture_0700A800, -}; +#define inside_castle_seg7_painting_textures_070235C0 { \ + inside_castle_seg7_texture_0700B800, inside_castle_seg7_texture_0700A800, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235C8[] = { - inside_castle_seg7_texture_0700D800, inside_castle_seg7_texture_0700C800, -}; +#define inside_castle_seg7_painting_textures_070235C8 { \ + inside_castle_seg7_texture_0700D800, inside_castle_seg7_texture_0700C800, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235D0[] = { - inside_castle_seg7_texture_0700F800, inside_castle_seg7_texture_0700E800, -}; +#define inside_castle_seg7_painting_textures_070235D0 { \ + inside_castle_seg7_texture_0700F800, inside_castle_seg7_texture_0700E800, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235D8[] = { - inside_castle_seg7_texture_07011800, inside_castle_seg7_texture_07010800, -}; +#define inside_castle_seg7_painting_textures_070235D8 { \ + inside_castle_seg7_texture_07011800, inside_castle_seg7_texture_07010800, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235E0[] = { - inside_castle_seg7_texture_07012800, inside_castle_seg7_texture_07013800, -}; +#define inside_castle_seg7_painting_textures_070235E0 { \ + inside_castle_seg7_texture_07012800, inside_castle_seg7_texture_07013800, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235E8[] = { - inside_castle_seg7_texture_07015800, inside_castle_seg7_texture_07014800, -}; +#define inside_castle_seg7_painting_textures_070235E8 { \ + inside_castle_seg7_texture_07015800, inside_castle_seg7_texture_07014800, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235F0[] = { - inside_castle_seg7_texture_07016800, -}; +#define inside_castle_seg7_painting_textures_070235F0 { \ + inside_castle_seg7_texture_07016800, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235F4[] = { - inside_castle_seg7_texture_07017000, -}; +#define inside_castle_seg7_painting_textures_070235F4 { \ + inside_castle_seg7_texture_07017000, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235F8[] = { - inside_castle_seg7_texture_07018800, inside_castle_seg7_texture_07017800, -}; +#define inside_castle_seg7_painting_textures_070235F8 { \ + inside_castle_seg7_texture_07018800, inside_castle_seg7_texture_07017800, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_07023600[] = { - inside_castle_seg7_texture_0701A800, inside_castle_seg7_texture_07019800, -}; +#define inside_castle_seg7_painting_textures_07023600 { \ + inside_castle_seg7_texture_0701A800, inside_castle_seg7_texture_07019800, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_07023608[] = { - inside_castle_seg7_texture_0701C800, inside_castle_seg7_texture_0701B800, -}; +#define inside_castle_seg7_painting_textures_07023608 { \ + inside_castle_seg7_texture_0701C800, inside_castle_seg7_texture_0701B800, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_07023610[] = { - inside_castle_seg7_texture_0701E800, inside_castle_seg7_texture_0701D800, -}; +#define inside_castle_seg7_painting_textures_07023610 { \ + inside_castle_seg7_texture_0701E800, inside_castle_seg7_texture_0701D800, \ +} -ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_07023618[] = { - inside_castle_seg7_texture_07020800, inside_castle_seg7_texture_0701F800, -}; +#define inside_castle_seg7_painting_textures_07023618 { \ + inside_castle_seg7_texture_07020800, inside_castle_seg7_texture_0701F800, \ +} // 0x07023620 - 0x07023698 struct Painting bob_painting = { diff --git a/levels/hmc/areas/1/painting.inc.c b/levels/hmc/areas/1/painting.inc.c index ebad311eb..871750397 100644 --- a/levels/hmc/areas/1/painting.inc.c +++ b/levels/hmc/areas/1/painting.inc.c @@ -505,9 +505,9 @@ static const Gfx hmc_seg7_painting_dl_070254E0[] = { }; // 0x07025518 - 0x07025594 -const Texture *const hmc_seg7_painting_textures_07025518[] = { - hmc_seg7_texture_07024CE0, -}; +#define hmc_seg7_painting_textures_07025518 { \ + hmc_seg7_texture_07024CE0, \ +} // 0x0702551C (PaintingData) struct Painting cotmc_painting = { diff --git a/levels/ttm/areas/1/painting.inc.c b/levels/ttm/areas/1/painting.inc.c index fea728990..2ae5d05db 100644 --- a/levels/ttm/areas/1/painting.inc.c +++ b/levels/ttm/areas/1/painting.inc.c @@ -537,9 +537,9 @@ static const Gfx ttm_seg7_painting_dl_07012E98[] = { }; // 0x07012EF8 - 0x07012F78 -ALIGNED8 const Texture *const ttm_seg7_painting_textures_07012EF8[] = { - ttm_seg7_texture_07004000, ttm_seg7_texture_07003000, -}; +#define ttm_seg7_painting_textures_07012EF8 { \ + ttm_seg7_texture_07004000, ttm_seg7_texture_07003000, \ +} // 0x07012F00 (PaintingData) struct Painting ttm_slide_painting = { diff --git a/mods/char-select-the-originals/main.lua b/mods/char-select-the-originals/main.lua index ff18a8bc5..916691565 100644 --- a/mods/char-select-the-originals/main.lua +++ b/mods/char-select-the-originals/main.lua @@ -99,51 +99,95 @@ local PALETTE_FL_WALUIGI = { -- Sounds -- -local DJ_TOAD_SOUNDS = { - SOUND_MARIO_YAH_WAH_HOO, - SOUND_MARIO_HOOHOO, - SOUND_MARIO_YAHOO, - SOUND_MARIO_UH, - SOUND_MARIO_HRMM, - SOUND_MARIO_WAH2, - SOUND_MARIO_WHOA, - SOUND_MARIO_EEUH, - SOUND_MARIO_ATTACKED, - SOUND_MARIO_OOOF, - SOUND_MARIO_OOOF2, - SOUND_MARIO_HERE_WE_GO, - SOUND_MARIO_YAWNING, - SOUND_MARIO_SNORING1, - SOUND_MARIO_SNORING2, - SOUND_MARIO_WAAAOOOW, - SOUND_MARIO_HAHA, - SOUND_MARIO_HAHA_2, - SOUND_MARIO_UH2, - SOUND_MARIO_UH2_2, - SOUND_MARIO_ON_FIRE, - SOUND_MARIO_DYING, - SOUND_MARIO_PANTING_COLD, - SOUND_MARIO_PANTING, - SOUND_MARIO_COUGHING1, - SOUND_MARIO_COUGHING2, - SOUND_MARIO_COUGHING3, - SOUND_MARIO_PUNCH_YAH, - SOUND_MARIO_PUNCH_HOO, - SOUND_MARIO_MAMA_MIA, - SOUND_MARIO_GROUND_POUND_WAH, - SOUND_MARIO_DROWNING, - SOUND_MARIO_PUNCH_WAH, - SOUND_MARIO_YAHOO_WAHA_YIPPEE, - SOUND_MARIO_DOH, - SOUND_MARIO_GAME_OVER, - SOUND_MARIO_HELLO, - SOUND_MARIO_PRESS_START_TO_PLAY, - SOUND_MARIO_TWIRL_BOUNCE, - SOUND_MARIO_SNORING3, - SOUND_MARIO_SO_LONGA_BOWSER, - SOUND_MARIO_IMA_TIRED, - SOUND_MARIO_LETS_A_GO, - SOUND_MARIO_OKEY_DOKEY +local MARIO_SOUNDS = { + [CHAR_SOUND_OKEY_DOKEY] = SOUND_MARIO_OKEY_DOKEY, + [CHAR_SOUND_LETS_A_GO] = SOUND_MARIO_LETS_A_GO, + [CHAR_SOUND_PUNCH_YAH] = SOUND_MARIO_PUNCH_YAH, + [CHAR_SOUND_PUNCH_WAH] = SOUND_MARIO_PUNCH_WAH, + [CHAR_SOUND_WAH2] = SOUND_MARIO_WAH2, + [CHAR_SOUND_PUNCH_HOO] = SOUND_MARIO_PUNCH_HOO, + [CHAR_SOUND_YAH_WAH_HOO] = SOUND_MARIO_YAH_WAH_HOO, + [CHAR_SOUND_HOOHOO] = SOUND_MARIO_HOOHOO, + [CHAR_SOUND_YAHOO_WAHA_YIPPEE] = SOUND_MARIO_YAHOO_WAHA_YIPPEE, + [CHAR_SOUND_UH] = SOUND_MARIO_UH, + [CHAR_SOUND_UH2] = SOUND_MARIO_UH2, + [CHAR_SOUND_UH2_2] = SOUND_MARIO_UH2_2, + [CHAR_SOUND_HAHA] = SOUND_MARIO_HAHA, + [CHAR_SOUND_HAHA_2] = SOUND_MARIO_HAHA_2, + [CHAR_SOUND_YAHOO] = SOUND_MARIO_YAHOO, + [CHAR_SOUND_DOH] = SOUND_MARIO_DOH, + [CHAR_SOUND_WHOA] = SOUND_MARIO_WHOA, + [CHAR_SOUND_EEUH] = SOUND_MARIO_EEUH, + [CHAR_SOUND_WAAAOOOW] = SOUND_MARIO_WAAAOOOW, + [CHAR_SOUND_TWIRL_BOUNCE] = SOUND_MARIO_TWIRL_BOUNCE, + [CHAR_SOUND_GROUND_POUND_WAH] = SOUND_MARIO_GROUND_POUND_WAH, + [CHAR_SOUND_HRMM] = SOUND_MARIO_HRMM, + [CHAR_SOUND_HERE_WE_GO] = SOUND_MARIO_HERE_WE_GO, + [CHAR_SOUND_SO_LONGA_BOWSER] = SOUND_MARIO_SO_LONGA_BOWSER, + [CHAR_SOUND_OOOF] = SOUND_MARIO_OOOF, + [CHAR_SOUND_OOOF2] = SOUND_MARIO_OOOF2, + [CHAR_SOUND_ATTACKED] = SOUND_MARIO_ATTACKED, + [CHAR_SOUND_PANTING] = SOUND_MARIO_PANTING, + [CHAR_SOUND_PANTING_COLD] = SOUND_MARIO_PANTING_COLD, + [CHAR_SOUND_ON_FIRE] = SOUND_MARIO_ON_FIRE, + [CHAR_SOUND_IMA_TIRED] = SOUND_MARIO_IMA_TIRED, + [CHAR_SOUND_YAWNING] = SOUND_MARIO_YAWNING, + [CHAR_SOUND_SNORING1] = SOUND_MARIO_SNORING1, + [CHAR_SOUND_SNORING2] = SOUND_MARIO_SNORING2, + [CHAR_SOUND_SNORING3] = SOUND_MARIO_SNORING3, + [CHAR_SOUND_COUGHING1] = SOUND_MARIO_COUGHING1, + [CHAR_SOUND_COUGHING2] = SOUND_MARIO_COUGHING2, + [CHAR_SOUND_COUGHING3] = SOUND_MARIO_COUGHING3, + [CHAR_SOUND_DYING] = SOUND_MARIO_DYING, + [CHAR_SOUND_DROWNING] = SOUND_MARIO_DROWNING, + [CHAR_SOUND_MAMA_MIA] = SOUND_MARIO_MAMA_MIA, + [CHAR_SOUND_GAME_OVER] = SOUND_MARIO_GAME_OVER, + [CHAR_SOUND_HELLO] = SOUND_MARIO_HELLO, + [CHAR_SOUND_PRESS_START_TO_PLAY] = SOUND_MARIO_PRESS_START_TO_PLAY +} + +local VOICETABLE_CJ_LUIGI = { + [CHAR_SOUND_OKEY_DOKEY] = '0B_cj_luigi_okey_dokey.aiff', + [CHAR_SOUND_LETS_A_GO] = '1A_cj_luigi_lets_a_go.aiff', + [CHAR_SOUND_PUNCH_YAH] = '08_cj_luigi_punch_yah.aiff', + [CHAR_SOUND_PUNCH_WAH] = '01_cj_luigi_jump_wah.aiff', + [CHAR_SOUND_WAH2] = '07_cj_luigi_wah2.aiff', + [CHAR_SOUND_PUNCH_HOO] = '09_cj_luigi_punch_hoo.aiff', + [CHAR_SOUND_YAH_WAH_HOO] = { '00_cj_luigi_jump_hoo.aiff', '01_cj_luigi_jump_wah.aiff', '02_cj_luigi_yah.aiff' }, + [CHAR_SOUND_HOOHOO] = '01_cj_luigi_hoohoo.aiff', + [CHAR_SOUND_YAHOO_WAHA_YIPPEE] = { '04_cj_luigi_yahoo.aiff', '18_cj_luigi_waha.aiff', '19_cj_luigi_yippee.aiff' }, + [CHAR_SOUND_UH] = '05_cj_luigi_uh.aiff', + [CHAR_SOUND_UH2] = '05_cj_luigi_uh2.aiff', + [CHAR_SOUND_UH2_2] = '05_cj_luigi_uh2.aiff', + [CHAR_SOUND_HAHA] = '03_cj_luigi_haha.aiff', + [CHAR_SOUND_HAHA_2] = '03_cj_luigi_haha.aiff', + [CHAR_SOUND_YAHOO] = '04_cj_luigi_yahoo.aiff', + [CHAR_SOUND_DOH] = '10_cj_luigi_doh.aiff', + [CHAR_SOUND_WHOA] = '08_cj_luigi_whoa.aiff', + [CHAR_SOUND_EEUH] = '09_cj_luigi_eeuh.aiff', + [CHAR_SOUND_WAAAOOOW] = '00_cj_luigi_waaaooow.aiff', + [CHAR_SOUND_TWIRL_BOUNCE] = '14_cj_luigi_twirl_bounce.aiff', + [CHAR_SOUND_GROUND_POUND_WAH] = '07_cj_luigi_wah2.aiff', + [CHAR_SOUND_HRMM] = '06_cj_luigi_hrmm.aiff', + [CHAR_SOUND_HERE_WE_GO] = '0C_cj_luigi_here_we_go.aiff', + [CHAR_SOUND_SO_LONGA_BOWSER] = '16_cj_luigi_so_longa_bowser.aiff', + [CHAR_SOUND_OOOF] = '0B_cj_luigi_ooof.aiff', + [CHAR_SOUND_OOOF2] = '0B_cj_luigi_ooof.aiff', + [CHAR_SOUND_ATTACKED] = '0A_cj_luigi_attacked.aiff', + [CHAR_SOUND_PANTING] = '02_cj_luigi_panting.aiff', + [CHAR_SOUND_PANTING_COLD] = '02_cj_luigi_panting.aiff', + [CHAR_SOUND_ON_FIRE] = '04_cj_luigi_on_fire.aiff', + [CHAR_SOUND_IMA_TIRED] = '17_cj_luigi_ima_tired.aiff', + [CHAR_SOUND_YAWNING] = '0D_cj_luigi_yawning.aiff', + [CHAR_SOUND_SNORING1] = '0E_cj_luigi_snoring1.aiff', + [CHAR_SOUND_SNORING2] = '0F_cj_luigi_snoring2.aiff', + [CHAR_SOUND_SNORING3] = '15_cj_luigi_snoring3.aiff', + [CHAR_SOUND_COUGHING1] = '06_cj_luigi_coughing.aiff', + [CHAR_SOUND_COUGHING2] = '06_cj_luigi_coughing.aiff', + [CHAR_SOUND_COUGHING3] = '06_cj_luigi_coughing.aiff', + [CHAR_SOUND_DYING] = '03_cj_luigi_dying.aiff', + [CHAR_SOUND_DROWNING] = '0C_cj_luigi_drowning.aiff', + [CHAR_SOUND_MAMA_MIA] = '0A_cj_luigi_mama_mia.aiff' } -- Loading Characters -- @@ -161,14 +205,24 @@ local function on_character_select_load() charSelect.character_add_palette_preset(E_MODEL_FLUFFA_WARIO, PALETTE_FL_WARIO) charSelect.character_add_palette_preset(E_MODEL_KEEB_WALUIGI, PALETTE_KB_WALUIGI) charSelect.character_add_palette_preset(E_MODEL_FLUFFA_WALUIGI, PALETTE_FL_WALUIGI) + charSelect.character_add_voice(E_MODEL_CJ_LUIGI, VOICETABLE_CJ_LUIGI) + charSelect.config_character_sounds() end --- Djoslin Toad Sound + --- @param m MarioState --- @param sound CharacterSound +--- Pitched up Mario voice +local MODEL_FREQ_TABLE = { + [E_MODEL_DJOSLIN_TOAD] = 1.25, + [E_MODEL_VL_TONE_LUIGI] = 1.1 +} + local function character_sound(m, sound) - if obj_get_model_id_extended(m.marioObj) == E_MODEL_DJOSLIN_TOAD then - play_sound_with_freq_scale(DJ_TOAD_SOUNDS[sound + 1], m.marioObj.header.gfx.cameraToObject, 1.25) + local extendedModelId = obj_get_model_id_extended(m.marioObj) + local freqScale = MODEL_FREQ_TABLE[extendedModelId] + if freqScale then + play_sound_with_freq_scale(MARIO_SOUNDS[sound], m.marioObj.header.gfx.cameraToObject, freqScale) return NO_SOUND end end diff --git a/mods/char-select-the-originals/sound/00_cj_luigi_jump_hoo.aiff b/mods/char-select-the-originals/sound/00_cj_luigi_jump_hoo.aiff new file mode 100644 index 000000000..b3eeeee0f Binary files /dev/null and b/mods/char-select-the-originals/sound/00_cj_luigi_jump_hoo.aiff differ diff --git a/mods/char-select-the-originals/sound/00_cj_luigi_waaaooow.aiff b/mods/char-select-the-originals/sound/00_cj_luigi_waaaooow.aiff new file mode 100644 index 000000000..35850afde Binary files /dev/null and b/mods/char-select-the-originals/sound/00_cj_luigi_waaaooow.aiff differ diff --git a/mods/char-select-the-originals/sound/01_cj_luigi_hoohoo.aiff b/mods/char-select-the-originals/sound/01_cj_luigi_hoohoo.aiff new file mode 100644 index 000000000..588ab78cd Binary files /dev/null and b/mods/char-select-the-originals/sound/01_cj_luigi_hoohoo.aiff differ diff --git a/mods/char-select-the-originals/sound/01_cj_luigi_jump_wah.aiff b/mods/char-select-the-originals/sound/01_cj_luigi_jump_wah.aiff new file mode 100644 index 000000000..f2ffc0377 Binary files /dev/null and b/mods/char-select-the-originals/sound/01_cj_luigi_jump_wah.aiff differ diff --git a/mods/char-select-the-originals/sound/02_cj_luigi_panting.aiff b/mods/char-select-the-originals/sound/02_cj_luigi_panting.aiff new file mode 100644 index 000000000..c1f3ac196 Binary files /dev/null and b/mods/char-select-the-originals/sound/02_cj_luigi_panting.aiff differ diff --git a/mods/char-select-the-originals/sound/02_cj_luigi_yah.aiff b/mods/char-select-the-originals/sound/02_cj_luigi_yah.aiff new file mode 100644 index 000000000..ab47bd20c Binary files /dev/null and b/mods/char-select-the-originals/sound/02_cj_luigi_yah.aiff differ diff --git a/mods/char-select-the-originals/sound/03_cj_luigi_dying.aiff b/mods/char-select-the-originals/sound/03_cj_luigi_dying.aiff new file mode 100644 index 000000000..025fe4a09 Binary files /dev/null and b/mods/char-select-the-originals/sound/03_cj_luigi_dying.aiff differ diff --git a/mods/char-select-the-originals/sound/03_cj_luigi_haha.aiff b/mods/char-select-the-originals/sound/03_cj_luigi_haha.aiff new file mode 100644 index 000000000..1990f5f5d Binary files /dev/null and b/mods/char-select-the-originals/sound/03_cj_luigi_haha.aiff differ diff --git a/mods/char-select-the-originals/sound/04_cj_luigi_on_fire.aiff b/mods/char-select-the-originals/sound/04_cj_luigi_on_fire.aiff new file mode 100644 index 000000000..6863fa2b4 Binary files /dev/null and b/mods/char-select-the-originals/sound/04_cj_luigi_on_fire.aiff differ diff --git a/mods/char-select-the-originals/sound/04_cj_luigi_yahoo.aiff b/mods/char-select-the-originals/sound/04_cj_luigi_yahoo.aiff new file mode 100644 index 000000000..40f6b29a4 Binary files /dev/null and b/mods/char-select-the-originals/sound/04_cj_luigi_yahoo.aiff differ diff --git a/mods/char-select-the-originals/sound/05_cj_luigi_uh.aiff b/mods/char-select-the-originals/sound/05_cj_luigi_uh.aiff new file mode 100644 index 000000000..21b91ba85 Binary files /dev/null and b/mods/char-select-the-originals/sound/05_cj_luigi_uh.aiff differ diff --git a/mods/char-select-the-originals/sound/05_cj_luigi_uh2.aiff b/mods/char-select-the-originals/sound/05_cj_luigi_uh2.aiff new file mode 100644 index 000000000..1bc018711 Binary files /dev/null and b/mods/char-select-the-originals/sound/05_cj_luigi_uh2.aiff differ diff --git a/mods/char-select-the-originals/sound/06_cj_luigi_coughing.aiff b/mods/char-select-the-originals/sound/06_cj_luigi_coughing.aiff new file mode 100644 index 000000000..f7d0715ed Binary files /dev/null and b/mods/char-select-the-originals/sound/06_cj_luigi_coughing.aiff differ diff --git a/mods/char-select-the-originals/sound/06_cj_luigi_hrmm.aiff b/mods/char-select-the-originals/sound/06_cj_luigi_hrmm.aiff new file mode 100644 index 000000000..78342ae2b Binary files /dev/null and b/mods/char-select-the-originals/sound/06_cj_luigi_hrmm.aiff differ diff --git a/mods/char-select-the-originals/sound/07_cj_luigi_wah2.aiff b/mods/char-select-the-originals/sound/07_cj_luigi_wah2.aiff new file mode 100644 index 000000000..a20c73b8c Binary files /dev/null and b/mods/char-select-the-originals/sound/07_cj_luigi_wah2.aiff differ diff --git a/mods/char-select-the-originals/sound/08_cj_luigi_punch_yah.aiff b/mods/char-select-the-originals/sound/08_cj_luigi_punch_yah.aiff new file mode 100644 index 000000000..ba4e1d8b3 Binary files /dev/null and b/mods/char-select-the-originals/sound/08_cj_luigi_punch_yah.aiff differ diff --git a/mods/char-select-the-originals/sound/08_cj_luigi_whoa.aiff b/mods/char-select-the-originals/sound/08_cj_luigi_whoa.aiff new file mode 100644 index 000000000..52d9c5093 Binary files /dev/null and b/mods/char-select-the-originals/sound/08_cj_luigi_whoa.aiff differ diff --git a/mods/char-select-the-originals/sound/09_cj_luigi_eeuh.aiff b/mods/char-select-the-originals/sound/09_cj_luigi_eeuh.aiff new file mode 100644 index 000000000..865b487f3 Binary files /dev/null and b/mods/char-select-the-originals/sound/09_cj_luigi_eeuh.aiff differ diff --git a/mods/char-select-the-originals/sound/09_cj_luigi_punch_hoo.aiff b/mods/char-select-the-originals/sound/09_cj_luigi_punch_hoo.aiff new file mode 100644 index 000000000..8503de5d3 Binary files /dev/null and b/mods/char-select-the-originals/sound/09_cj_luigi_punch_hoo.aiff differ diff --git a/mods/char-select-the-originals/sound/0A_cj_luigi_attacked.aiff b/mods/char-select-the-originals/sound/0A_cj_luigi_attacked.aiff new file mode 100644 index 000000000..3af9e773b Binary files /dev/null and b/mods/char-select-the-originals/sound/0A_cj_luigi_attacked.aiff differ diff --git a/mods/char-select-the-originals/sound/0A_cj_luigi_mama_mia.aiff b/mods/char-select-the-originals/sound/0A_cj_luigi_mama_mia.aiff new file mode 100644 index 000000000..e78894012 Binary files /dev/null and b/mods/char-select-the-originals/sound/0A_cj_luigi_mama_mia.aiff differ diff --git a/mods/char-select-the-originals/sound/0B_cj_luigi_okey_dokey.aiff b/mods/char-select-the-originals/sound/0B_cj_luigi_okey_dokey.aiff new file mode 100644 index 000000000..3bd01f030 Binary files /dev/null and b/mods/char-select-the-originals/sound/0B_cj_luigi_okey_dokey.aiff differ diff --git a/mods/char-select-the-originals/sound/0B_cj_luigi_ooof.aiff b/mods/char-select-the-originals/sound/0B_cj_luigi_ooof.aiff new file mode 100644 index 000000000..0ad4c08e9 Binary files /dev/null and b/mods/char-select-the-originals/sound/0B_cj_luigi_ooof.aiff differ diff --git a/mods/char-select-the-originals/sound/0C_cj_luigi_drowning.aiff b/mods/char-select-the-originals/sound/0C_cj_luigi_drowning.aiff new file mode 100644 index 000000000..cc2de392c Binary files /dev/null and b/mods/char-select-the-originals/sound/0C_cj_luigi_drowning.aiff differ diff --git a/mods/char-select-the-originals/sound/0C_cj_luigi_here_we_go.aiff b/mods/char-select-the-originals/sound/0C_cj_luigi_here_we_go.aiff new file mode 100644 index 000000000..0f6610c16 Binary files /dev/null and b/mods/char-select-the-originals/sound/0C_cj_luigi_here_we_go.aiff differ diff --git a/mods/char-select-the-originals/sound/0D_cj_luigi_yawning.aiff b/mods/char-select-the-originals/sound/0D_cj_luigi_yawning.aiff new file mode 100644 index 000000000..b4cd11ab7 Binary files /dev/null and b/mods/char-select-the-originals/sound/0D_cj_luigi_yawning.aiff differ diff --git a/mods/char-select-the-originals/sound/0E_cj_luigi_snoring1.aiff b/mods/char-select-the-originals/sound/0E_cj_luigi_snoring1.aiff new file mode 100644 index 000000000..aed9d630d Binary files /dev/null and b/mods/char-select-the-originals/sound/0E_cj_luigi_snoring1.aiff differ diff --git a/mods/char-select-the-originals/sound/0F_cj_luigi_snoring2.aiff b/mods/char-select-the-originals/sound/0F_cj_luigi_snoring2.aiff new file mode 100644 index 000000000..81afa3b4b Binary files /dev/null and b/mods/char-select-the-originals/sound/0F_cj_luigi_snoring2.aiff differ diff --git a/mods/char-select-the-originals/sound/10_cj_luigi_doh.aiff b/mods/char-select-the-originals/sound/10_cj_luigi_doh.aiff new file mode 100644 index 000000000..4f76c269f Binary files /dev/null and b/mods/char-select-the-originals/sound/10_cj_luigi_doh.aiff differ diff --git a/mods/char-select-the-originals/sound/11_cj_luigi_game_over.aiff b/mods/char-select-the-originals/sound/11_cj_luigi_game_over.aiff new file mode 100644 index 000000000..7e65bbbca Binary files /dev/null and b/mods/char-select-the-originals/sound/11_cj_luigi_game_over.aiff differ diff --git a/mods/char-select-the-originals/sound/12_cj_luigi_hello.aiff b/mods/char-select-the-originals/sound/12_cj_luigi_hello.aiff new file mode 100644 index 000000000..6654130a7 Binary files /dev/null and b/mods/char-select-the-originals/sound/12_cj_luigi_hello.aiff differ diff --git a/mods/char-select-the-originals/sound/13_cj_luigi_press_start_to_play.aiff b/mods/char-select-the-originals/sound/13_cj_luigi_press_start_to_play.aiff new file mode 100644 index 000000000..4384d9569 Binary files /dev/null and b/mods/char-select-the-originals/sound/13_cj_luigi_press_start_to_play.aiff differ diff --git a/mods/char-select-the-originals/sound/14_cj_luigi_twirl_bounce.aiff b/mods/char-select-the-originals/sound/14_cj_luigi_twirl_bounce.aiff new file mode 100644 index 000000000..8169c964d Binary files /dev/null and b/mods/char-select-the-originals/sound/14_cj_luigi_twirl_bounce.aiff differ diff --git a/mods/char-select-the-originals/sound/15_cj_luigi_snoring3.aiff b/mods/char-select-the-originals/sound/15_cj_luigi_snoring3.aiff new file mode 100644 index 000000000..c78fd31be Binary files /dev/null and b/mods/char-select-the-originals/sound/15_cj_luigi_snoring3.aiff differ diff --git a/mods/char-select-the-originals/sound/16_cj_luigi_so_longa_bowser.aiff b/mods/char-select-the-originals/sound/16_cj_luigi_so_longa_bowser.aiff new file mode 100644 index 000000000..ac78fab09 Binary files /dev/null and b/mods/char-select-the-originals/sound/16_cj_luigi_so_longa_bowser.aiff differ diff --git a/mods/char-select-the-originals/sound/17_cj_luigi_ima_tired.aiff b/mods/char-select-the-originals/sound/17_cj_luigi_ima_tired.aiff new file mode 100644 index 000000000..806dcb55f Binary files /dev/null and b/mods/char-select-the-originals/sound/17_cj_luigi_ima_tired.aiff differ diff --git a/mods/char-select-the-originals/sound/18_cj_luigi_waha.aiff b/mods/char-select-the-originals/sound/18_cj_luigi_waha.aiff new file mode 100644 index 000000000..db50b250c Binary files /dev/null and b/mods/char-select-the-originals/sound/18_cj_luigi_waha.aiff differ diff --git a/mods/char-select-the-originals/sound/19_cj_luigi_yippee.aiff b/mods/char-select-the-originals/sound/19_cj_luigi_yippee.aiff new file mode 100644 index 000000000..8b1e6b3a6 Binary files /dev/null and b/mods/char-select-the-originals/sound/19_cj_luigi_yippee.aiff differ diff --git a/mods/char-select-the-originals/sound/1A_cj_luigi_lets_a_go.aiff b/mods/char-select-the-originals/sound/1A_cj_luigi_lets_a_go.aiff new file mode 100644 index 000000000..27465f9d8 Binary files /dev/null and b/mods/char-select-the-originals/sound/1A_cj_luigi_lets_a_go.aiff differ diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h index c044fa548..7e61e9f4c 100644 --- a/src/engine/graph_node.h +++ b/src/engine/graph_node.h @@ -20,6 +20,7 @@ // Extra, custom, flags #define GRAPH_EXTRA_FORCE_3D (1 << 0) +#define GRAPH_EXTRA_ROTATE_HELD (1 << 1) // Whether the node type has a function pointer of type GraphNodeFunc #define GRAPH_NODE_TYPE_FUNCTIONAL 0x100 diff --git a/src/engine/level_script.c b/src/engine/level_script.c index 7d7129cbc..bb955dce6 100644 --- a/src/engine/level_script.c +++ b/src/engine/level_script.c @@ -18,6 +18,7 @@ #include "goddard/renderer.h" #include "geo_layout.h" #include "graph_node.h" +#include "level_commands.h" #include "level_script.h" #include "level_misc_macros.h" #include "macro_presets.h" @@ -501,8 +502,7 @@ static void level_cmd_23(void) { } static void level_cmd_init_mario(void) { - u32 behaviorArg = CMD_GET(u32, 4); - behaviorArg = behaviorArg; + UNUSED u32 behaviorArg = CMD_GET(u32, 4); void* behaviorScript = CMD_GET(void*, 8); u16 slot = CMD_GET(u8, 3); struct GraphNode* unk18 = dynos_model_get_geo(slot); @@ -918,124 +918,94 @@ static void level_cmd_cleardemoptr(void) sCurrentCmd = CMD_NEXT; } +// // coop -static void level_cmd_place_object_ext(void) { - u8 val7 = 1 << (gCurrActNum - 1); - struct SpawnInfo *spawnInfo; +// - u16 modIndex = gLevelScriptModIndex; - const char* behStr = dynos_level_get_token(CMD_GET(u32, 20)); +static bool find_lua_param(uintptr_t *param, u32 offset, u32 luaParams, u32 luaParamFlag) { + *param = CMD_GET(uintptr_t, offset); + if (luaParams & luaParamFlag) { + if (gLevelScriptModIndex == -1) { + LOG_ERROR("Could not find level script mod index"); + return false; + } - if (gLevelScriptModIndex == -1) { - LOG_ERROR("Could not find level script mod index"); - sCurrentCmd = CMD_NEXT; - return; - } - - gSmLuaConvertSuccess = true; - enum BehaviorId behId = smlua_get_integer_mod_variable(modIndex, behStr); - - if (!gSmLuaConvertSuccess) { + const char *paramStr = dynos_level_get_token(*param); gSmLuaConvertSuccess = true; - behId = smlua_get_any_integer_mod_variable(behStr); + *param = smlua_get_integer_mod_variable(gLevelScriptModIndex, paramStr); + + if (!gSmLuaConvertSuccess) { + gSmLuaConvertSuccess = true; + *param = smlua_get_any_integer_mod_variable(paramStr); + } + + if (!gSmLuaConvertSuccess) { + LOG_LUA("Failed to execute level command, could not find parameter '%s'", paramStr); + return false; + } } - - if (!gSmLuaConvertSuccess) { - LOG_LUA("Failed to place custom object, could not find behavior '%s'", behStr); - sCurrentCmd = CMD_NEXT; - return; - } - - if (sCurrAreaIndex != -1 && (gLevelValues.disableActs || (CMD_GET(u8, 2) & val7) || CMD_GET(u8, 2) == 0x1F)) { - u16 model = CMD_GET(u8, 3); - spawnInfo = dynamic_pool_alloc(gLevelPool, sizeof(struct SpawnInfo)); - - spawnInfo->startPos[0] = CMD_GET(s16, 4); - spawnInfo->startPos[1] = CMD_GET(s16, 6); - spawnInfo->startPos[2] = CMD_GET(s16, 8); - - spawnInfo->startAngle[0] = CMD_GET(s16, 10) * 0x8000 / 180; - spawnInfo->startAngle[1] = CMD_GET(s16, 12) * 0x8000 / 180; - spawnInfo->startAngle[2] = CMD_GET(s16, 14) * 0x8000 / 180; - - spawnInfo->areaIndex = sCurrAreaIndex; - spawnInfo->activeAreaIndex = sCurrAreaIndex; - - spawnInfo->behaviorArg = CMD_GET(u32, 16); - - spawnInfo->behaviorScript = (BehaviorScript*)get_behavior_from_id(behId); - spawnInfo->unk18 = dynos_model_get_geo(model); - spawnInfo->next = gAreas[sCurrAreaIndex].objectSpawnInfos; - - spawnInfo->syncID = spawnInfo->next - ? spawnInfo->next->syncID + 10 - : 10; - - gAreas[sCurrAreaIndex].objectSpawnInfos = spawnInfo; - area_check_red_coin_or_secret(spawnInfo->behaviorScript, false); - } - - sCurrentCmd = CMD_NEXT; + return true; } -static void level_cmd_place_object_ext2(void) { +#define get_lua_param(name, type, flag) \ + uintptr_t name##Param; \ + if (!find_lua_param(&name##Param, flag##_OFFSET(cmdType), luaParams, flag)) { \ + sCurrentCmd = CMD_NEXT; \ + return; \ + } \ + type name = (type) name##Param; + +static void level_cmd_place_object_ext_lua_params(void) { u8 val7 = 1 << (gCurrActNum - 1); struct SpawnInfo *spawnInfo; - u16 modIndex = gLevelScriptModIndex; - const char* modelStr = dynos_level_get_token(CMD_GET(u32, 20)); - const char* behStr = dynos_level_get_token(CMD_GET(u32, 24)); + u8 cmdType = sCurrentCmd->type; + u16 luaParams = ( + cmdType == 0x3F ? OBJECT_EXT_LUA_BEHAVIOR : ( + cmdType == 0x40 ? OBJECT_EXT_LUA_BEHAVIOR | OBJECT_EXT_LUA_MODEL : ( + CMD_GET(u16, 2) + ))); - if (gLevelScriptModIndex == -1) { - LOG_ERROR("Could not find level script mod index"); - sCurrentCmd = CMD_NEXT; - return; - } + get_lua_param(acts, u8, OBJECT_EXT_LUA_ACTS); - gSmLuaConvertSuccess = true; - enum ModelExtendedId modelId = smlua_get_integer_mod_variable(modIndex, modelStr); - if (!gSmLuaConvertSuccess) { - gSmLuaConvertSuccess = true; - modelId = smlua_get_any_integer_mod_variable(modelStr); - } - if (!gSmLuaConvertSuccess) { - LOG_LUA("Failed to place custom object, could not find model '%s'", modelStr); - sCurrentCmd = CMD_NEXT; - return; - } - - gSmLuaConvertSuccess = true; - enum BehaviorId behId = smlua_get_integer_mod_variable(modIndex, behStr); - if (!gSmLuaConvertSuccess) { - gSmLuaConvertSuccess = true; - behId = smlua_get_any_integer_mod_variable(behStr); - } - - if (!gSmLuaConvertSuccess) { - LOG_LUA("Failed to place custom object, could not find behavior '%s'", behStr); - sCurrentCmd = CMD_NEXT; - return; - } - - if (sCurrAreaIndex != -1 && (gLevelValues.disableActs || (CMD_GET(u8, 2) & val7) || CMD_GET(u8, 2) == 0x1F)) { + if (sCurrAreaIndex != -1 && (gLevelValues.disableActs || (acts & val7) || acts == 0x1F)) { spawnInfo = dynamic_pool_alloc(gLevelPool, sizeof(struct SpawnInfo)); - spawnInfo->startPos[0] = CMD_GET(s16, 4); - spawnInfo->startPos[1] = CMD_GET(s16, 6); - spawnInfo->startPos[2] = CMD_GET(s16, 8); + get_lua_param(modelId, u32, OBJECT_EXT_LUA_MODEL); + get_lua_param(posX, s16, OBJECT_EXT_LUA_POS_X); + get_lua_param(posY, s16, OBJECT_EXT_LUA_POS_Y); + get_lua_param(posZ, s16, OBJECT_EXT_LUA_POS_Z); + get_lua_param(angleX, s16, OBJECT_EXT_LUA_ANGLE_X); + get_lua_param(angleY, s16, OBJECT_EXT_LUA_ANGLE_Y); + get_lua_param(angleZ, s16, OBJECT_EXT_LUA_ANGLE_Z); + get_lua_param(behParam, u32, OBJECT_EXT_LUA_BEH_PARAMS); + get_lua_param(behavior, uintptr_t, OBJECT_EXT_LUA_BEHAVIOR); - spawnInfo->startAngle[0] = CMD_GET(s16, 10) * 0x8000 / 180; - spawnInfo->startAngle[1] = CMD_GET(s16, 12) * 0x8000 / 180; - spawnInfo->startAngle[2] = CMD_GET(s16, 14) * 0x8000 / 180; + spawnInfo->startPos[0] = posX; + spawnInfo->startPos[1] = posY; + spawnInfo->startPos[2] = posZ; + spawnInfo->startAngle[0] = (angleX * 0x8000) / 180; + spawnInfo->startAngle[1] = (angleY * 0x8000) / 180; + spawnInfo->startAngle[2] = (angleZ * 0x8000) / 180; spawnInfo->areaIndex = sCurrAreaIndex; spawnInfo->activeAreaIndex = sCurrAreaIndex; - spawnInfo->behaviorArg = CMD_GET(u32, 16); + spawnInfo->behaviorArg = behParam; + + if (luaParams & OBJECT_EXT_LUA_MODEL) { + u16 slot = smlua_model_util_load((enum ModelExtendedId) modelId); + spawnInfo->unk18 = dynos_model_get_geo(slot); + } else { + spawnInfo->unk18 = dynos_model_get_geo(modelId); + } + + if (luaParams & OBJECT_EXT_LUA_BEHAVIOR) { + spawnInfo->behaviorScript = (BehaviorScript *) get_behavior_from_id((enum BehaviorId) behavior); + } else { + spawnInfo->behaviorScript = (BehaviorScript *) behavior; + } - spawnInfo->behaviorScript = (BehaviorScript*)get_behavior_from_id(behId); - u16 slot = smlua_model_util_load(modelId); - spawnInfo->unk18 = dynos_model_get_geo(slot); spawnInfo->next = gAreas[sCurrAreaIndex].objectSpawnInfos; spawnInfo->syncID = spawnInfo->next @@ -1064,6 +1034,21 @@ static void level_cmd_jump_area_ext(void) { } } +static void level_cmd_show_dialog_ext(void) { + if (sCurrAreaIndex != -1 && !gDjuiInMainMenu) { + u8 luaParams = CMD_GET(u8, 2); + + get_lua_param(index, u8, SHOW_DIALOG_EXT_LUA_INDEX); + get_lua_param(dialogId, s32, SHOW_DIALOG_EXT_LUA_DIALOG); + + if (index < 2) { + gAreas[sCurrAreaIndex].dialog[index] = dialogId; + } + } + + sCurrentCmd = CMD_NEXT; +} + static void (*LevelScriptJumpTable[])(void) = { /*00*/ level_cmd_load_and_execute, /*01*/ level_cmd_exit_and_execute, @@ -1130,10 +1115,12 @@ static void (*LevelScriptJumpTable[])(void) = { /*3E*/ level_cmd_cleardemoptr, // coop - /*3F*/ level_cmd_place_object_ext, - /*40*/ level_cmd_place_object_ext2, + /*3F*/ level_cmd_place_object_ext_lua_params, + /*40*/ level_cmd_place_object_ext_lua_params, /*41*/ level_cmd_load_model_from_geo_ext, /*42*/ level_cmd_jump_area_ext, + /*43*/ level_cmd_place_object_ext_lua_params, + /*44*/ level_cmd_show_dialog_ext }; struct LevelCommand *level_script_execute(struct LevelCommand *cmd) { diff --git a/src/engine/math_util.c b/src/engine/math_util.c index fc3562799..a5a82e602 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -233,6 +233,30 @@ OPTIMIZE_O3 s32 anim_spline_poll(struct MarioState* m, OUT Vec3f result) { return hasEnded; } + /////////// + // Vec2f // +/////////// + +Vec2f gVec2fZero = { 0.0f, 0.0f }; + +Vec2f gVec2fOne = { 1.0f, 1.0f }; + + /////////// + // Vec2i // +/////////// + +Vec2i gVec2iZero = { 0, 0 }; + +Vec2i gVec2iOne = { 1, 1 }; + + /////////// + // Vec2s // +/////////// + +Vec2s gVec2sZero = { 0, 0 }; + +Vec2s gVec2sOne = { 1, 1 }; + /////////// // Vec3f // /////////// diff --git a/src/engine/math_util.h b/src/engine/math_util.h index 72ead474d..16e30eba2 100644 --- a/src/engine/math_util.h +++ b/src/engine/math_util.h @@ -87,6 +87,12 @@ extern f32 gCosineTable[]; #endif +extern Vec2f gVec2fZero; +extern Vec2i gVec2iZero; +extern Vec2s gVec2sZero; +extern Vec2f gVec2fOne; +extern Vec2i gVec2iOne; +extern Vec2s gVec2sOne; extern Vec3f gVec3fZero; extern Vec3i gVec3iZero; extern Vec3s gVec3sZero; @@ -143,6 +149,24 @@ Advances the spline-based animation associated with `m` and stores the current i |descriptionEnd| */ OPTIMIZE_O3 s32 anim_spline_poll(struct MarioState* m, OUT Vec3f result); + /////////// + // Vec2f // +/////////// + +#include "math_util_vec2f.inl" + + /////////// + // Vec2i // +/////////// + +#include "math_util_vec2i.inl" + + /////////// + // Vec2s // +/////////// + +#include "math_util_vec2s.inl" + /////////// // Vec3f // /////////// diff --git a/src/engine/math_util_vec2.tmpl b/src/engine/math_util_vec2.tmpl new file mode 100644 index 000000000..bfb24f14a --- /dev/null +++ b/src/engine/math_util_vec2.tmpl @@ -0,0 +1,157 @@ +#pragma once + +/* |description| +Sets the components of the 2D {{desc}} vector `v` to 0 +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_zero(OUT Vec2{{suffix}} v) { + memset(v, 0, sizeof(Vec2{{suffix}})); + return v; +} + +/* |description| +Copies the contents of a 2D {{desc}} vector (`src`) into another 2D {{desc}} vector (`dest`) +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_copy(OUT Vec2{{suffix}} dest, Vec2{{suffix}} src) { + dest[0] = src[0]; + dest[1] = src[1]; + return dest; +} + +/* |description| +Sets the values of the 2D {{desc}} vector `dest` to the given x and y values +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_set(OUT Vec2{{suffix}} dest, {{type}} x, {{type}} y) { + dest[0] = x; + dest[1] = y; + return dest; +} + +/* |description| +Adds the components of the 2D {{desc}} vector `a` to `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_add(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a) { + dest[0] += a[0]; + dest[1] += a[1]; + return dest; +} + +/* |description| +Adds the components of two 2D {{desc}} vectors `a` and `b` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_sum(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a, Vec2{{suffix}} b) { + dest[0] = a[0] + b[0]; + dest[1] = a[1] + b[1]; + return dest; +} + +/* |description| +Subtracts the components of the 2D {{desc}} vector `a` from `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_sub(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a) { + dest[0] -= a[0]; + dest[1] -= a[1]; + return dest; +} + +/* |description| +Subtracts the components of the 2D {{desc}} vector `b` from the components of `a` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_dif(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a, Vec2{{suffix}} b) { + dest[0] = a[0] - b[0]; + dest[1] = a[1] - b[1]; + return dest; +} + +/* |description| +Multiplies each component of the 2D {{desc}} vector `dest` by the scalar value `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_mul(OUT Vec2{{suffix}} dest, f32 a) { + dest[0] *= a; + dest[1] *= a; + return dest; +} + +/* |description| +Multiplies the components of the 2D {{desc}} vector `dest` with the components of `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_mult(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a) { + dest[0] *= a[0]; + dest[1] *= a[1]; + return dest; +} + +/* |description| +Multiplies the components of two 2D {{desc}} vectors `a` and `b` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_prod(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a, Vec2{{suffix}} b) { + dest[0] = a[0] * b[0]; + dest[1] = a[1] * b[1]; + return dest; +} + +/* |description| +Divides each component of the 2D {{desc}} vector `dest` by the scalar value `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_div(OUT Vec2{{suffix}} dest, f32 a) { + if (a == 0) { return dest; } + dest[0] /= a; + dest[1] /= a; + return dest; +} + +/* |description| +Calculates the length (magnitude) of the 2D {{desc}} vector `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2{{suffix}}_length(Vec2{{suffix}} a) { + return sqrtf(a[0] * a[0] + a[1] * a[1]); +} + +/* |description| +Normalizes the 2D {{desc}} vector `v` so that its length (magnitude) becomes 1, while retaining its direction +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_normalize(OUT Vec2{{suffix}} v) { + f32 mag = vec2{{suffix}}_length(v); + vec2{{suffix}}_div(v, mag); + return v; +} + +/* |description| +Sets the length (magnitude) of 2D {{desc}} vector `v`, while retaining its direction +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_set_magnitude(OUT Vec2{{suffix}} v, f32 mag) { + vec2{{suffix}}_normalize(v); + vec2{{suffix}}_mul(v, mag); + return v; +} + +/* |description| +Computes the dot product of the two 2D {{desc}} vectors `a` and `b` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2{{suffix}}_dot(Vec2{{suffix}} a, Vec2{{suffix}} b) { + return (f32) (a[0] * b[0] + a[1] * b[1]); +} + +/* |description| +Takes two 2D {{desc}} vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_combine(OUT Vec2{{suffix}} dest, Vec2{{suffix}} vecA, Vec2{{suffix}} vecB, f32 sclA, f32 sclB) { + dest[0] = vecA[0] * sclA + vecB[0] * sclB; + dest[1] = vecA[1] * sclA + vecB[1] * sclB; + return dest; +} + +/* |description| +Calculates the distance between two 2D {{desc}} vectors `v1` and `v2` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2{{suffix}}_dist(Vec2{{suffix}} v1, Vec2{{suffix}} v2) { + Vec2{{suffix}} diff; + vec2{{suffix}}_dif(diff, v1, v2); + return vec2{{suffix}}_length(diff); +} + +/* |description| +Returns `true` if all components of the 2D {{desc}} vector `v` are zero +|descriptionEnd| */ +INLINE OPTIMIZE_O3 bool vec2{{suffix}}_is_zero(Vec2{{suffix}} v) { + return memcmp(v, gVec2{{suffix}}Zero, sizeof(Vec2{{suffix}})) == 0; +} diff --git a/src/engine/math_util_vec2f.inl b/src/engine/math_util_vec2f.inl new file mode 100644 index 000000000..edea0385b --- /dev/null +++ b/src/engine/math_util_vec2f.inl @@ -0,0 +1,178 @@ +/* THIS FILE IS AUTO-GENERATED */ +/* DO NOT EDIT IT MANUALLY */ + +#pragma once + +/* |description| +Sets the components of the 2D floating-point vector `v` to 0 +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_zero(OUT Vec2f v) { + memset(v, 0, sizeof(Vec2f)); + return v; +} + +/* |description| +Copies the contents of a 2D floating-point vector (`src`) into another 2D floating-point vector (`dest`) +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_copy(OUT Vec2f dest, Vec2f src) { + dest[0] = src[0]; + dest[1] = src[1]; + return dest; +} + +/* |description| +Sets the values of the 2D floating-point vector `dest` to the given x and y values +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_set(OUT Vec2f dest, f32 x, f32 y) { + dest[0] = x; + dest[1] = y; + return dest; +} + +/* |description| +Adds the components of the 2D floating-point vector `a` to `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_add(OUT Vec2f dest, Vec2f a) { + dest[0] += a[0]; + dest[1] += a[1]; + return dest; +} + +/* |description| +Adds the components of two 2D floating-point vectors `a` and `b` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_sum(OUT Vec2f dest, Vec2f a, Vec2f b) { + dest[0] = a[0] + b[0]; + dest[1] = a[1] + b[1]; + return dest; +} + +/* |description| +Subtracts the components of the 2D floating-point vector `a` from `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_sub(OUT Vec2f dest, Vec2f a) { + dest[0] -= a[0]; + dest[1] -= a[1]; + return dest; +} + +/* |description| +Subtracts the components of the 2D floating-point vector `b` from the components of `a` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_dif(OUT Vec2f dest, Vec2f a, Vec2f b) { + dest[0] = a[0] - b[0]; + dest[1] = a[1] - b[1]; + return dest; +} + +/* |description| +Multiplies each component of the 2D floating-point vector `dest` by the scalar value `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_mul(OUT Vec2f dest, f32 a) { + dest[0] *= a; + dest[1] *= a; + return dest; +} + +/* |description| +Multiplies the components of the 2D floating-point vector `dest` with the components of `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_mult(OUT Vec2f dest, Vec2f a) { + dest[0] *= a[0]; + dest[1] *= a[1]; + return dest; +} + +/* |description| +Multiplies the components of two 2D floating-point vectors `a` and `b` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_prod(OUT Vec2f dest, Vec2f a, Vec2f b) { + dest[0] = a[0] * b[0]; + dest[1] = a[1] * b[1]; + return dest; +} + +/* |description| +Divides each component of the 2D floating-point vector `dest` by the scalar value `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_div(OUT Vec2f dest, f32 a) { + if (a == 0) { return dest; } + dest[0] /= a; + dest[1] /= a; + return dest; +} + +/* |description| +Calculates the length (magnitude) of the 2D floating-point vector `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2f_length(Vec2f a) { + return sqrtf(a[0] * a[0] + a[1] * a[1]); +} + +/* |description| +Normalizes the 2D floating-point vector `v` so that its length (magnitude) becomes 1, while retaining its direction +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_normalize(OUT Vec2f v) { + f32 mag = vec2f_length(v); + vec2f_div(v, mag); + return v; +} + +/* |description| +Sets the length (magnitude) of 2D floating-point vector `v`, while retaining its direction +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_set_magnitude(OUT Vec2f v, f32 mag) { + vec2f_normalize(v); + vec2f_mul(v, mag); + return v; +} + +/* |description| +Computes the dot product of the two 2D floating-point vectors `a` and `b` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2f_dot(Vec2f a, Vec2f b) { + return (f32) (a[0] * b[0] + a[1] * b[1]); +} + +/* |description| +Takes two 2D floating-point vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2f_combine(OUT Vec2f dest, Vec2f vecA, Vec2f vecB, f32 sclA, f32 sclB) { + dest[0] = vecA[0] * sclA + vecB[0] * sclB; + dest[1] = vecA[1] * sclA + vecB[1] * sclB; + return dest; +} + +/* |description| +Calculates the distance between two 2D floating-point vectors `v1` and `v2` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2f_dist(Vec2f v1, Vec2f v2) { + Vec2f diff; + vec2f_dif(diff, v1, v2); + return vec2f_length(diff); +} + +/* |description| +Returns `true` if all components of the 2D floating-point vector `v` are zero +|descriptionEnd| */ +INLINE OPTIMIZE_O3 bool vec2f_is_zero(Vec2f v) { + return memcmp(v, gVec2fZero, sizeof(Vec2f)) == 0; +} + +/* |description| +Converts a 2D floating-point vector `a` into a 2D integer vector and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2f_to_vec2i(OUT Vec2i dest, Vec2f a) { + dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f); + dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f); + return dest; +} + +/* |description| +Converts a 2D floating-point vector `a` into a 2D short integer vector and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2f_to_vec2s(OUT Vec2s dest, Vec2f a) { + dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f); + dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f); + return dest; +} diff --git a/src/engine/math_util_vec2i.inl b/src/engine/math_util_vec2i.inl new file mode 100644 index 000000000..774bedb38 --- /dev/null +++ b/src/engine/math_util_vec2i.inl @@ -0,0 +1,178 @@ +/* THIS FILE IS AUTO-GENERATED */ +/* DO NOT EDIT IT MANUALLY */ + +#pragma once + +/* |description| +Sets the components of the 2D integer vector `v` to 0 +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_zero(OUT Vec2i v) { + memset(v, 0, sizeof(Vec2i)); + return v; +} + +/* |description| +Copies the contents of a 2D integer vector (`src`) into another 2D integer vector (`dest`) +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_copy(OUT Vec2i dest, Vec2i src) { + dest[0] = src[0]; + dest[1] = src[1]; + return dest; +} + +/* |description| +Sets the values of the 2D integer vector `dest` to the given x and y values +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_set(OUT Vec2i dest, s32 x, s32 y) { + dest[0] = x; + dest[1] = y; + return dest; +} + +/* |description| +Adds the components of the 2D integer vector `a` to `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_add(OUT Vec2i dest, Vec2i a) { + dest[0] += a[0]; + dest[1] += a[1]; + return dest; +} + +/* |description| +Adds the components of two 2D integer vectors `a` and `b` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_sum(OUT Vec2i dest, Vec2i a, Vec2i b) { + dest[0] = a[0] + b[0]; + dest[1] = a[1] + b[1]; + return dest; +} + +/* |description| +Subtracts the components of the 2D integer vector `a` from `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_sub(OUT Vec2i dest, Vec2i a) { + dest[0] -= a[0]; + dest[1] -= a[1]; + return dest; +} + +/* |description| +Subtracts the components of the 2D integer vector `b` from the components of `a` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_dif(OUT Vec2i dest, Vec2i a, Vec2i b) { + dest[0] = a[0] - b[0]; + dest[1] = a[1] - b[1]; + return dest; +} + +/* |description| +Multiplies each component of the 2D integer vector `dest` by the scalar value `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_mul(OUT Vec2i dest, f32 a) { + dest[0] *= a; + dest[1] *= a; + return dest; +} + +/* |description| +Multiplies the components of the 2D integer vector `dest` with the components of `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_mult(OUT Vec2i dest, Vec2i a) { + dest[0] *= a[0]; + dest[1] *= a[1]; + return dest; +} + +/* |description| +Multiplies the components of two 2D integer vectors `a` and `b` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_prod(OUT Vec2i dest, Vec2i a, Vec2i b) { + dest[0] = a[0] * b[0]; + dest[1] = a[1] * b[1]; + return dest; +} + +/* |description| +Divides each component of the 2D integer vector `dest` by the scalar value `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_div(OUT Vec2i dest, f32 a) { + if (a == 0) { return dest; } + dest[0] /= a; + dest[1] /= a; + return dest; +} + +/* |description| +Calculates the length (magnitude) of the 2D integer vector `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2i_length(Vec2i a) { + return sqrtf(a[0] * a[0] + a[1] * a[1]); +} + +/* |description| +Normalizes the 2D integer vector `v` so that its length (magnitude) becomes 1, while retaining its direction +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_normalize(OUT Vec2i v) { + f32 mag = vec2i_length(v); + vec2i_div(v, mag); + return v; +} + +/* |description| +Sets the length (magnitude) of 2D integer vector `v`, while retaining its direction +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_set_magnitude(OUT Vec2i v, f32 mag) { + vec2i_normalize(v); + vec2i_mul(v, mag); + return v; +} + +/* |description| +Computes the dot product of the two 2D integer vectors `a` and `b` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2i_dot(Vec2i a, Vec2i b) { + return (f32) (a[0] * b[0] + a[1] * b[1]); +} + +/* |description| +Takes two 2D integer vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2i_combine(OUT Vec2i dest, Vec2i vecA, Vec2i vecB, f32 sclA, f32 sclB) { + dest[0] = vecA[0] * sclA + vecB[0] * sclB; + dest[1] = vecA[1] * sclA + vecB[1] * sclB; + return dest; +} + +/* |description| +Calculates the distance between two 2D integer vectors `v1` and `v2` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2i_dist(Vec2i v1, Vec2i v2) { + Vec2i diff; + vec2i_dif(diff, v1, v2); + return vec2i_length(diff); +} + +/* |description| +Returns `true` if all components of the 2D integer vector `v` are zero +|descriptionEnd| */ +INLINE OPTIMIZE_O3 bool vec2i_is_zero(Vec2i v) { + return memcmp(v, gVec2iZero, sizeof(Vec2i)) == 0; +} + +/* |description| +Converts a 2D integer vector `a` into a 2D floating-point vector and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2i_to_vec2f(OUT Vec2f dest, Vec2i a) { + dest[0] = a[0]; + dest[1] = a[1]; + return dest; +} + +/* |description| +Converts a 2D integer vector `a` into a 2D short integer vector and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2i_to_vec2s(OUT Vec2s dest, Vec2i a) { + dest[0] = a[0]; + dest[1] = a[1]; + return dest; +} diff --git a/src/engine/math_util_vec2s.inl b/src/engine/math_util_vec2s.inl new file mode 100644 index 000000000..2dde2fdbd --- /dev/null +++ b/src/engine/math_util_vec2s.inl @@ -0,0 +1,178 @@ +/* THIS FILE IS AUTO-GENERATED */ +/* DO NOT EDIT IT MANUALLY */ + +#pragma once + +/* |description| +Sets the components of the 2D short integer vector `v` to 0 +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_zero(OUT Vec2s v) { + memset(v, 0, sizeof(Vec2s)); + return v; +} + +/* |description| +Copies the contents of a 2D short integer vector (`src`) into another 2D short integer vector (`dest`) +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_copy(OUT Vec2s dest, Vec2s src) { + dest[0] = src[0]; + dest[1] = src[1]; + return dest; +} + +/* |description| +Sets the values of the 2D short integer vector `dest` to the given x and y values +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_set(OUT Vec2s dest, s16 x, s16 y) { + dest[0] = x; + dest[1] = y; + return dest; +} + +/* |description| +Adds the components of the 2D short integer vector `a` to `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_add(OUT Vec2s dest, Vec2s a) { + dest[0] += a[0]; + dest[1] += a[1]; + return dest; +} + +/* |description| +Adds the components of two 2D short integer vectors `a` and `b` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_sum(OUT Vec2s dest, Vec2s a, Vec2s b) { + dest[0] = a[0] + b[0]; + dest[1] = a[1] + b[1]; + return dest; +} + +/* |description| +Subtracts the components of the 2D short integer vector `a` from `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_sub(OUT Vec2s dest, Vec2s a) { + dest[0] -= a[0]; + dest[1] -= a[1]; + return dest; +} + +/* |description| +Subtracts the components of the 2D short integer vector `b` from the components of `a` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_dif(OUT Vec2s dest, Vec2s a, Vec2s b) { + dest[0] = a[0] - b[0]; + dest[1] = a[1] - b[1]; + return dest; +} + +/* |description| +Multiplies each component of the 2D short integer vector `dest` by the scalar value `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_mul(OUT Vec2s dest, f32 a) { + dest[0] *= a; + dest[1] *= a; + return dest; +} + +/* |description| +Multiplies the components of the 2D short integer vector `dest` with the components of `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_mult(OUT Vec2s dest, Vec2s a) { + dest[0] *= a[0]; + dest[1] *= a[1]; + return dest; +} + +/* |description| +Multiplies the components of two 2D short integer vectors `a` and `b` and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_prod(OUT Vec2s dest, Vec2s a, Vec2s b) { + dest[0] = a[0] * b[0]; + dest[1] = a[1] * b[1]; + return dest; +} + +/* |description| +Divides each component of the 2D short integer vector `dest` by the scalar value `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_div(OUT Vec2s dest, f32 a) { + if (a == 0) { return dest; } + dest[0] /= a; + dest[1] /= a; + return dest; +} + +/* |description| +Calculates the length (magnitude) of the 2D short integer vector `a` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2s_length(Vec2s a) { + return sqrtf(a[0] * a[0] + a[1] * a[1]); +} + +/* |description| +Normalizes the 2D short integer vector `v` so that its length (magnitude) becomes 1, while retaining its direction +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_normalize(OUT Vec2s v) { + f32 mag = vec2s_length(v); + vec2s_div(v, mag); + return v; +} + +/* |description| +Sets the length (magnitude) of 2D short integer vector `v`, while retaining its direction +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_set_magnitude(OUT Vec2s v, f32 mag) { + vec2s_normalize(v); + vec2s_mul(v, mag); + return v; +} + +/* |description| +Computes the dot product of the two 2D short integer vectors `a` and `b` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2s_dot(Vec2s a, Vec2s b) { + return (f32) (a[0] * b[0] + a[1] * b[1]); +} + +/* |description| +Takes two 2D short integer vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2sp vec2s_combine(OUT Vec2s dest, Vec2s vecA, Vec2s vecB, f32 sclA, f32 sclB) { + dest[0] = vecA[0] * sclA + vecB[0] * sclB; + dest[1] = vecA[1] * sclA + vecB[1] * sclB; + return dest; +} + +/* |description| +Calculates the distance between two 2D short integer vectors `v1` and `v2` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 f32 vec2s_dist(Vec2s v1, Vec2s v2) { + Vec2s diff; + vec2s_dif(diff, v1, v2); + return vec2s_length(diff); +} + +/* |description| +Returns `true` if all components of the 2D short integer vector `v` are zero +|descriptionEnd| */ +INLINE OPTIMIZE_O3 bool vec2s_is_zero(Vec2s v) { + return memcmp(v, gVec2sZero, sizeof(Vec2s)) == 0; +} + +/* |description| +Converts a 2D short integer vector `a` into a 2D floating-point vector and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2fp vec2s_to_vec2f(OUT Vec2f dest, Vec2s a) { + dest[0] = a[0]; + dest[1] = a[1]; + return dest; +} + +/* |description| +Converts a 2D short integer vector `a` into a 2D integer vector and stores the result in `dest` +|descriptionEnd| */ +INLINE OPTIMIZE_O3 Vec2ip vec2s_to_vec2i(OUT Vec2i dest, Vec2s a) { + dest[0] = a[0]; + dest[1] = a[1]; + return dest; +} diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c index 96ef6cfcb..1e34afd7f 100644 --- a/src/engine/surface_collision.c +++ b/src/engine/surface_collision.c @@ -137,9 +137,8 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode, surfaceNode = surfaceNode->next; // Exclude a large number of walls immediately to optimize. - if (y < surf->lowerY || y > surf->upperY) { - continue; - } + if (y < surf->lowerY || y > surf->upperY) { continue; } + if (surf->flags & SURFACE_FLAG_INTANGIBLE) { continue; } if (gLevelValues.fixCollisionBugs && gLevelValues.fixCollisionBugsRoundedCorners && !gFindWallDirectionAirborne) { // Check AABB to exclude walls before doing expensive triangle check @@ -399,6 +398,8 @@ static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32 surf = surfaceNode->surface; surfaceNode = surfaceNode->next; + if (surf->flags & SURFACE_FLAG_INTANGIBLE) { continue; } + x1 = surf->vertex1[0]; z1 = surf->vertex1[2]; z2 = surf->vertex2[2]; @@ -622,7 +623,8 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32 if (surf == NULL) { break; } surfaceNode = surfaceNode->next; interpolate = gInterpolatingSurfaces; - + + if (surf->flags & SURFACE_FLAG_INTANGIBLE) { continue; } if (gCheckingSurfaceCollisionsForObject != NULL) { if (surf->object != gCheckingSurfaceCollisionsForObject) { continue; diff --git a/src/engine/surface_collision.h b/src/engine/surface_collision.h index d954b847b..ff5257a57 100644 --- a/src/engine/surface_collision.h +++ b/src/engine/surface_collision.h @@ -38,6 +38,12 @@ struct FloorGeometry f32 originOffset; }; +struct StaticObjectCollision +{ + u32 index; + u16 length; +}; + extern Vec3f gFindWallDirection; extern u8 gFindWallDirectionActive; extern u8 gFindWallDirectionAirborne; diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index f74eb8110..e5296490e 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -28,12 +28,48 @@ SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS]; SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS]; +/** + * The total number of surface nodes allocated (a node is allocated for each + * spatial partition cell that a surface intersects). + */ +s32 gSurfaceNodesAllocated; + +/** + * The total number of surfaces allocated. + */ +s32 gSurfacesAllocated; + +/** + * The number of nodes that have been created for static surfaces. + */ +s32 gNumStaticSurfaceNodes; + +/** + * The number of static surfaces in the pool. + */ +s32 gNumStaticSurfaces; + +/** + * The number of nodes that have been created for static object collision surfaces. + */ +s32 gNumSOCSurfaceNodes; + +/** + * The number of static object collision surfaces in the pool. + */ +s32 gNumSOCSurfaces; + /** * Pools of data to contain either surface nodes or surfaces. */ static struct GrowingArray *sSurfaceNodePool = NULL; static struct GrowingArray *sSurfacePool = NULL; +/** + * Pool of data for static object collisions. + */ +static struct GrowingArray *sSOCPool = NULL; + /** * Allocate the part of the surface node pool to contain a surface node. */ @@ -51,6 +87,10 @@ static struct Surface *alloc_surface(void) { return growing_array_alloc(sSurfacePool, sizeof(struct Surface)); } +static struct StaticObjectCollision *alloc_static_object_collision(void) { + return growing_array_alloc(sSOCPool, sizeof(struct StaticObjectCollision)); +} + /** * Iterates through the entire partition, clearing the surfaces. */ @@ -71,6 +111,7 @@ static void clear_spatial_partition(SpatialPartitionCell *cells) { */ static void clear_static_surfaces(void) { clear_spatial_partition(&gStaticSurfacePartition[0][0]); + sSOCPool = growing_array_init(sSOCPool, 0x100, malloc, smlua_free_soc); } /** @@ -479,6 +520,8 @@ void alloc_surface_pools(void) { gSurfacesAllocated = 0; gNumStaticSurfaceNodes = 0; gNumStaticSurfaces = 0; + gNumSOCSurfaceNodes = 0; + gNumSOCSurfaces = 0; gCCMEnteredSlide = 0; reset_red_coins_collected(); @@ -586,6 +629,8 @@ void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects gNumStaticSurfaceNodes = gSurfaceNodesAllocated; gNumStaticSurfaces = gSurfacesAllocated; + gNumSOCSurfaceNodes = 0; + gNumSOCSurfaces = 0; } /** @@ -593,8 +638,8 @@ void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects */ void clear_dynamic_surfaces(void) { if (!(gTimeStopState & TIME_STOP_ACTIVE)) { - gSurfacesAllocated = gNumStaticSurfaces; - gSurfaceNodesAllocated = gNumStaticSurfaceNodes; + gSurfacesAllocated = gNumStaticSurfaces + gNumSOCSurfaces; + gSurfaceNodesAllocated = gNumStaticSurfaceNodes + gNumSOCSurfaceNodes; clear_spatial_partition(&gDynamicSurfacePartition[0][0]); @@ -650,7 +695,7 @@ void transform_object_vertices(s16 **data, s16 *vertexData) { /** * Load in the surfaces for the gCurrentObject. This includes setting the flags, exertion, and room. */ -void load_object_surfaces(s16** data, s16* vertexData) { +void load_object_surfaces(s16** data, s16* vertexData, bool isSOC) { if (!gCurrentObject) { return; } s32 surfaceType; s32 i; @@ -682,15 +727,16 @@ void load_object_surfaces(s16** data, s16* vertexData) { struct Surface* surface = read_surface_data(vertexData, data); if (surface != NULL) { - - // Set index of first surface - if (gCurrentObject->firstSurface == 0) { - gCurrentObject->firstSurface = gSurfacesAllocated - 1; + if (!isSOC) { + // Set index of first surface + if (gCurrentObject->firstSurface == 0) { + gCurrentObject->firstSurface = gSurfacesAllocated - 1; + } + + // Increase surface count + gCurrentObject->numSurfaces++; } - // Increase surface count - gCurrentObject->numSurfaces++; - surface->object = gCurrentObject; surface->type = surfaceType; @@ -702,7 +748,7 @@ void load_object_surfaces(s16** data, s16* vertexData) { surface->flags |= flags; surface->room = (s8)room; - add_surface(surface, TRUE); + add_surface(surface, !isSOC); } if (hasForce) { @@ -716,9 +762,12 @@ void load_object_surfaces(s16** data, s16* vertexData) { /** * Transform an object's vertices, reload them, and render the object. */ -void load_object_collision_model(void) { +static void load_object_collision_model_internal(bool isSOC) { + static bool sIsLoadingCollision = false; + if (!gCurrentObject) { return; } if (gCurrentObject->collisionData == NULL) { return; } + if (sIsLoadingCollision) { return; } s32 numVertices = 64; if (gCurrentObject->collisionData[0] == COL_INIT()) { @@ -736,6 +785,9 @@ void load_object_collision_model(void) { static s32 sVertexDataCount = 0; static s16* sVertexData = NULL; + // start loading collision + sIsLoadingCollision = true; + // allocate vertex data if (numVertices > sVertexDataCount || sVertexData == NULL) { if (sVertexData) { free(sVertexData); } @@ -746,39 +798,99 @@ void load_object_collision_model(void) { } s16* collisionData = gCurrentObject->collisionData; - f32 tangibleDist = gCurrentObject->oCollisionDistance; u8 anyPlayerInTangibleRange = FALSE; - for (s32 i = 0; i < MAX_PLAYERS; i++) { - f32 dist = dist_between_objects(gCurrentObject, gMarioStates[i].marioObj); - if (dist < tangibleDist) { anyPlayerInTangibleRange = TRUE; } + if (!isSOC) { + f32 tangibleDist = gCurrentObject->oCollisionDistance; + + for (s32 i = 0; i < MAX_PLAYERS; i++) { + f32 dist = dist_between_objects(gCurrentObject, gMarioStates[i].marioObj); + if (dist < tangibleDist) { anyPlayerInTangibleRange = TRUE; } + } + + // If the object collision is supposed to be loaded more than the + // drawing distance of 4000, extend the drawing range. + if (gCurrentObject->oCollisionDistance > 4000.0f) { + gCurrentObject->oDrawingDistance = gCurrentObject->oCollisionDistance; + } } - // If the object collision is supposed to be loaded more than the - // drawing distance of 4000, extend the drawing range. - if (gCurrentObject->oCollisionDistance > 4000.0f) { - gCurrentObject->oDrawingDistance = gCurrentObject->oCollisionDistance; - } - - // Update if no Time Stop, in range, and in the current room. - if (!(gTimeStopState & TIME_STOP_ACTIVE) + // Update if no Time Stop, in range, and in the current room. (or if static) + if (isSOC || + (!(gTimeStopState & TIME_STOP_ACTIVE) && (anyPlayerInTangibleRange) - && !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { + && !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) + ) { collisionData++; transform_object_vertices(&collisionData, sVertexData); // TERRAIN_LOAD_CONTINUE acts as an "end" to the terrain data. while (*collisionData != TERRAIN_LOAD_CONTINUE) { - load_object_surfaces(&collisionData, sVertexData); + load_object_surfaces(&collisionData, sVertexData, isSOC); } } - f32 marioDist = dist_between_objects(gCurrentObject, gMarioStates[0].marioObj); - if (marioDist < gCurrentObject->oDrawingDistance * draw_distance_scalar()) { - gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; - } else { - gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; + if (!isSOC) { + f32 marioDist = dist_between_objects(gCurrentObject, gMarioStates[0].marioObj); + if (marioDist < gCurrentObject->oDrawingDistance * draw_distance_scalar()) { + gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE; + } else { + gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; + } } + + // stop loading collision + sIsLoadingCollision = false; +} + +void load_object_collision_model(void) { + load_object_collision_model_internal(false); +} + +struct StaticObjectCollision *load_static_object_collision() { + struct StaticObjectCollision *col; + u32 lastSurfaceIndex = gSurfacesAllocated; + u32 lastSurfaceNodeIndex = gSurfaceNodesAllocated; + u32 lastSOCSurfaceIndex = gNumStaticSurfaces + gNumSOCSurfaces; + u32 lastSOCSurfaceNodeIndex = gNumStaticSurfaceNodes + gNumSOCSurfaceNodes; + + load_object_collision_model_internal(true); + + // Reorder surfaces and nodes and update SOC variables + u32 addedSurfaces = gSurfacesAllocated - lastSurfaceIndex; + u32 addedSurfaceNodes = gSurfaceNodesAllocated - lastSurfaceNodeIndex; + if (addedSurfaces > 0) { + growing_array_move(sSurfacePool, lastSurfaceIndex, lastSOCSurfaceIndex, addedSurfaces); + gNumSOCSurfaces += addedSurfaces; + } + if (addedSurfaceNodes > 0) { + growing_array_move(sSurfaceNodePool, lastSurfaceNodeIndex, lastSOCSurfaceNodeIndex, addedSurfaceNodes); + gNumSOCSurfaceNodes += addedSurfaceNodes; + } + + col = alloc_static_object_collision(); + col->index = lastSOCSurfaceIndex; + col->length = addedSurfaces; + + return col; +} + +void toggle_static_object_collision(struct StaticObjectCollision *col, bool tangible) { + for (s32 i = 0; i < col->length; i++) { + struct Surface *surf = sSurfacePool->buffer[col->index + i]; + if (tangible) { + surf->flags &= ~SURFACE_FLAG_INTANGIBLE; + } else { + surf->flags |= SURFACE_FLAG_INTANGIBLE; + } + } +} + +struct Surface *get_static_object_surface(struct StaticObjectCollision *col, u32 index) { + if (!col) { return NULL; } + if (index >= col->length) { return NULL; } + struct Surface *surf = sSurfacePool->buffer[col->index + index]; + return surf; } struct Surface *obj_get_surface_from_index(struct Object *o, u32 index) { diff --git a/src/engine/surface_load.h b/src/engine/surface_load.h index 262958423..d0f2db1ad 100644 --- a/src/engine/surface_load.h +++ b/src/engine/surface_load.h @@ -27,6 +27,13 @@ typedef struct SurfaceNode SpatialPartitionCell[3]; extern SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS]; extern SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS]; +extern s32 gSurfaceNodesAllocated; +extern s32 gSurfacesAllocated; +extern s32 gNumStaticSurfaceNodes; +extern s32 gNumStaticSurfaces; +extern s32 gNumSOCSurfaceNodes; +extern s32 gNumSOCSurfaces; + void alloc_surface_pools(void); u32 get_area_terrain_size(s16 *data); @@ -38,6 +45,15 @@ Loads the object's collision data into dynamic collision. You must run this every frame in your object's behavior loop for it to have collision |descriptionEnd| */ void load_object_collision_model(void); +/* |description| +Loads the object's collision data into static collision. +You may run this only once to capture the object's collision at that frame. +|descriptionEnd| */ +struct StaticObjectCollision *load_static_object_collision(); +/* |description|Toggles a collection of static object surfaces|descriptionEnd| */ +void toggle_static_object_collision(struct StaticObjectCollision *col, bool tangible); +/* |description|Gets a surface corresponding to `index` from the static object collision|descriptionEnd| */ +struct Surface *get_static_object_surface(struct StaticObjectCollision *col, u32 index); /* |description|Gets a surface corresponding to `index` from the surface pool buffer|descriptionEnd| */ struct Surface *obj_get_surface_from_index(struct Object *o, u32 index); /* |description|Checks if a surface has force|descriptionEnd| */ diff --git a/src/game/area.h b/src/game/area.h index 0fe0b45c6..d5340fdee 100644 --- a/src/game/area.h +++ b/src/game/area.h @@ -79,9 +79,9 @@ struct Area /*0x24*/ struct Camera *camera; /*0x28*/ struct UnusedArea28 *unused28; // Filled by level script 0x3A, but is unused. /*0x2C*/ struct Whirlpool *whirlpools[2]; - /*0x34*/ u8 dialog[2]; // Level start dialog number (set by level script cmd 0x30) - /*0x36*/ u16 musicParam; - /*0x38*/ u16 musicParam2; + /*0x34*/ s32 dialog[2]; // Level start dialog number (set by level script cmd 0x30 and 0x44) + /*0x3C*/ u16 musicParam; + /*0x40*/ u16 musicParam2; /*????*/ u32 localAreaTimer; /*????*/ u8 *macroObjectsAltered; /*????*/ u8 numRedCoins; diff --git a/src/game/bettercamera.inc.h b/src/game/bettercamera.inc.h index 995b81686..5a81b42b8 100644 --- a/src/game/bettercamera.inc.h +++ b/src/game/bettercamera.inc.h @@ -101,7 +101,7 @@ inline static s16 newcam_adjust_value(f32 var, f32 val, f32 limit) { inline static s32 newcam_ivrt(u8 axis) { return ( axis == 0 ? - (gNewCamera.invertX ? 1 : -1) : + (gNewCamera.invertX ? -1 : 1) : (gNewCamera.invertY ? -1 : 1) ); } @@ -313,7 +313,7 @@ static void newcam_zoom_button(void) { // When you press L, set the flag for centering the camera. Afterwards, start setting the yaw to the Player's yaw at the time. if (gNewCamera.LCentering && (gPlayer1Controller->buttonDown & L_TRIG)) { - gNewCamera.yawTarget = -gMarioState->faceAngle[1] - 0x4000; + gNewCamera.yawTarget = -gMarioState->statusForCamera->faceAngle[1] - 0x4000; gNewCamera.centering = true; } @@ -346,24 +346,24 @@ static void newcam_update_values(void) { if (gNewCamera.turnWait > 0 && gMarioState->vel[1] == 0) { gNewCamera.turnWait--; } else if (gMarioState->intendedMag > 0 && gMarioState->vel[1] == 0) { - gNewCamera.yaw = approach_s16_symmetric(gNewCamera.yaw, -gMarioState->faceAngle[1] - 0x4000, ((gNewCamera.aggression * (ABS(gPlayer1Controller->rawStickX / 10.f))) * (gMarioState->forwardVel / 32.f))); + gNewCamera.yaw = approach_s16_symmetric(gNewCamera.yaw, -gMarioState->statusForCamera->faceAngle[1] - 0x4000, ((gNewCamera.aggression * (ABS(gPlayer1Controller->rawStickX / 10.f))) * (gMarioState->forwardVel / 32.f))); } else { gNewCamera.turnWait = 10; } // During slide actions in slide levels, force centering if (gNewCamera.isSlide && ( - gMarioState->action == ACT_BUTT_SLIDE || - gMarioState->action == ACT_STOMACH_SLIDE || - gMarioState->action == ACT_HOLD_BUTT_SLIDE || - gMarioState->action == ACT_HOLD_STOMACH_SLIDE) + gMarioState->statusForCamera->action == ACT_BUTT_SLIDE || + gMarioState->statusForCamera->action == ACT_STOMACH_SLIDE || + gMarioState->statusForCamera->action == ACT_HOLD_BUTT_SLIDE || + gMarioState->statusForCamera->action == ACT_HOLD_STOMACH_SLIDE) ) { centering = (gMarioState->forwardVel > 8); ycentering = false; } // Force centering when flying - if ((gMarioState->action & ACT_FLAG_FLYING) == ACT_FLAG_FLYING) { + if ((gMarioState->statusForCamera->action & ACT_FLAG_FLYING) == ACT_FLAG_FLYING) { centering = true; } @@ -371,12 +371,12 @@ static void newcam_update_values(void) { // Place the camera behind Mario during the ACT_SHOT_FROM_CANNON action static u32 sLastAction = 0; static bool sForceCentering = false; - if (sLastAction != gMarioState->action) { - sLastAction = gMarioState->action; + if (sLastAction != gMarioState->statusForCamera->action) { + sLastAction = gMarioState->statusForCamera->action; sForceCentering = true; - switch (gMarioState->action) { + switch (gMarioState->statusForCamera->action) { case ACT_SHOT_FROM_CANNON: - gNewCamera.yaw = -gMarioState->faceAngle[1] - 0x4000; + gNewCamera.yaw = -gMarioState->statusForCamera->faceAngle[1] - 0x4000; break; } } @@ -392,14 +392,14 @@ static void newcam_update_values(void) { } // Force centering during non-still swimming actions - if (gMarioState->action & ACT_FLAG_SWIMMING && gMarioState->forwardVel > 2) { + if (gMarioState->statusForCamera->action & ACT_FLAG_SWIMMING && gMarioState->forwardVel > 2) { centering = true; } if (centering) { - gNewCamera.yaw = approach_s16_symmetric(gNewCamera.yaw, -gMarioState->faceAngle[1] - 0x4000, gMarioState->forwardVel * 128); + gNewCamera.yaw = approach_s16_symmetric(gNewCamera.yaw, -gMarioState->statusForCamera->faceAngle[1] - 0x4000, gMarioState->forwardVel * 128); if (gMarioState->forwardVel > 1 && ycentering) { - gNewCamera.tilt = approach_s16_symmetric(gNewCamera.tilt, (-gMarioState->faceAngle[0] * 0.8f) + NEWCAM_TILT_CENTERING, gMarioState->forwardVel * 32); + gNewCamera.tilt = approach_s16_symmetric(gNewCamera.tilt, (-gMarioState->statusForCamera->faceAngle[0] * 0.8f) + NEWCAM_TILT_CENTERING, gMarioState->forwardVel * 32); } else { gNewCamera.tilt = approach_s16_symmetric(gNewCamera.tilt, NEWCAM_TILT_CENTERING, 32); } @@ -508,12 +508,12 @@ static void newcam_set_pan(void) { } // Apply panning values based on Mario's direction. - if (gMarioState->action != ACT_HOLDING_BOWSER && - gMarioState->action != ACT_SLEEPING && - gMarioState->action != ACT_START_SLEEPING + if (gMarioState->statusForCamera->action != ACT_HOLDING_BOWSER && + gMarioState->statusForCamera->action != ACT_SLEEPING && + gMarioState->statusForCamera->action != ACT_START_SLEEPING ) { - approach_f32_asymptotic_bool(&gNewCamera.panX, newcam_lengthdir_x((160.f * gNewCamera.panLevel) / 100.f, -gMarioState->faceAngle[1] - 0x4000), 0.05f); - approach_f32_asymptotic_bool(&gNewCamera.panZ, newcam_lengthdir_y((160.f * gNewCamera.panLevel) / 100.f, -gMarioState->faceAngle[1] - 0x4000), 0.05f); + approach_f32_asymptotic_bool(&gNewCamera.panX, newcam_lengthdir_x((160.f * gNewCamera.panLevel) / 100.f, -gMarioState->statusForCamera->faceAngle[1] - 0x4000), 0.05f); + approach_f32_asymptotic_bool(&gNewCamera.panZ, newcam_lengthdir_y((160.f * gNewCamera.panLevel) / 100.f, -gMarioState->statusForCamera->faceAngle[1] - 0x4000), 0.05f); } else { approach_f32_asymptotic_bool(&gNewCamera.panX, 0, 0.05f); approach_f32_asymptotic_bool(&gNewCamera.panZ, 0, 0.05f); @@ -538,7 +538,7 @@ static void newcam_level_bounds(void) { static void newcam_position_cam(void) { f32 floorY = 0; f32 floorY2 = 0; - if (!(gMarioState->action & ACT_FLAG_SWIMMING)) { + if (!(gMarioState->statusForCamera->action & ACT_FLAG_SWIMMING)) { calc_y_to_curr_floor(&floorY, 1.f, 200.f, &floorY2, 0.9f, 200.f); } @@ -549,9 +549,9 @@ static void newcam_position_cam(void) { // Fetch Mario's current position. // Not hardcoded just for the sake of flexibility, though this specific bit is temp, // because it won't always want to be focusing on Mario. - gNewCamera.posTarget[0] = gMarioState->pos[0]; - gNewCamera.posTarget[1] = gMarioState->pos[1] + NEWCAM_MARIO_HEIGHT; - gNewCamera.posTarget[2] = gMarioState->pos[2]; + gNewCamera.posTarget[0] = gMarioState->statusForCamera->pos[0]; + gNewCamera.posTarget[1] = gMarioState->statusForCamera->pos[1] + NEWCAM_MARIO_HEIGHT; + gNewCamera.posTarget[2] = gMarioState->statusForCamera->pos[2]; // These will set the position of the camera to where Mario is supposed to be, // minus adjustments for where the camera should be, on top of. @@ -607,7 +607,7 @@ static void newcam_apply_values(struct Camera *c) { // The ingame cutscene system is such a spaghetti mess I actually have to resort to something as stupid as this to cover every base. static void newcam_update_camera_yaw(struct Camera *c, bool useMarioYaw) { if (useMarioYaw) { - gNewCamera.yaw = -gMarioState->faceAngle[1] - 0x4000; + gNewCamera.yaw = -gMarioState->statusForCamera->faceAngle[1] - 0x4000; } else { gNewCamera.yaw = -c->yaw + 0x4000; } diff --git a/src/game/camera.c b/src/game/camera.c index d455ef7fe..15de4b863 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -10947,10 +10947,12 @@ void cutscene_palette_editor(struct Camera *c) { return; } + bool capMissing = !(m->flags & (MARIO_CAP_ON_HEAD | MARIO_CAP_IN_HAND)); + // Press the Z bind to toggle cap static bool pressed = false; if (gInteractablePad.button & PAD_BUTTON_Z) { - if (!pressed && m->action == ACT_IDLE) { + if (!capMissing && !pressed && m->action == ACT_IDLE) { set_mario_action(m, ACT_PALETTE_EDITOR_CAP, (m->flags & MARIO_CAP_ON_HEAD) != 0); } pressed = true; @@ -10962,8 +10964,10 @@ void cutscene_palette_editor(struct Camera *c) { if (gDjuiPaletteToggle) { djui_base_set_visible( &gDjuiPaletteToggle->base, - m->action == ACT_IDLE || - m->action == ACT_PALETTE_EDITOR_CAP + ( + m->action == ACT_IDLE || + m->action == ACT_PALETTE_EDITOR_CAP + ) && !capMissing ); } @@ -12249,7 +12253,7 @@ static u8 rom_hack_cam_can_see_mario(Vec3f desiredPos) { f32 mDist; s16 mPitch; s16 mYaw; - vec3f_get_dist_and_angle(desiredPos, gMarioStates[0].pos, &mDist, &mPitch, &mYaw); + vec3f_get_dist_and_angle(desiredPos, sMarioCamState->pos, &mDist, &mPitch, &mYaw); s16 degreeMult = sRomHackZoom ? 7 : 5; @@ -12379,7 +12383,7 @@ void mode_rom_hack_camera(struct Camera *c) { // Thank you hackersm64 if (gRomhackCameraSettings.dpad) { if (gMarioStates[0].controller->buttonPressed & U_JPAD) { - sRomHackYaw = DEGREES(180 + 90) - gMarioStates[0].faceAngle[1]; + sRomHackYaw = DEGREES(180 + 90) - sMarioCamState->faceAngle[1]; } else if (gMarioStates[0].controller->buttonDown & L_JPAD) { sRomHackYaw -= DEGREES(0.5) * (camera_config_is_x_inverted() ? 1 : -1); } else if (gMarioStates[0].controller->buttonDown & R_JPAD) { @@ -12408,7 +12412,7 @@ void mode_rom_hack_camera(struct Camera *c) { // figure out desired position f32 desiredDist = sRomHackZoom ? gRomhackCameraSettings.zoomedInDist : gRomhackCameraSettings.zoomedOutDist; f32 desiredHeight = sRomHackZoom ? gRomhackCameraSettings.zoomedInHeight : gRomhackCameraSettings.zoomedOutHeight; - f32* mPos = &gMarioStates[0].pos[0]; + f32* mPos = &sMarioCamState->pos[0]; pos[0] = mPos[0] + coss(sRomHackYaw) * desiredDist; pos[1] = mPos[1] + desiredHeight; pos[2] = mPos[2] + sins(sRomHackYaw) * desiredDist; @@ -12443,9 +12447,9 @@ void mode_rom_hack_camera(struct Camera *c) { vec3f_normalize(dir); // start at mario - c->pos[0] = gMarioStates[0].pos[0]; - c->pos[1] = gMarioStates[0].pos[1] + 150; - c->pos[2] = gMarioStates[0].pos[2]; + c->pos[0] = sMarioCamState->pos[0]; + c->pos[1] = sMarioCamState->pos[1] + 150; + c->pos[2] = sMarioCamState->pos[2]; rom_hack_cam_walk(c->pos, dir, desiredDist); } @@ -12489,8 +12493,8 @@ s32 update_rom_hack_camera(struct Camera *c, Vec3f focus, Vec3f pos) { // if rom hack camera was just set, figure out the yaw to use if (!sRomHackIsUpdate) { sRomHackYaw = DEGREES(90) - atan2s( - c->pos[2] - gMarioStates[0].pos[2], - c->pos[0] - gMarioStates[0].pos[0]); + c->pos[2] - sMarioCamState->pos[2], + c->pos[0] - sMarioCamState->pos[0]); sRomHackYaw = (sRomHackYaw / DEGREES(45)) * DEGREES(45); } diff --git a/src/game/characters.c b/src/game/characters.c index 4c0fce483..d751fba7d 100644 --- a/src/game/characters.c +++ b/src/game/characters.c @@ -35,7 +35,7 @@ struct Character gCharacters[CT_MAX] = { .type = CT_MARIO, .name = "Mario", .hudHead = '(', - .hudHeadTexture = { .texture = (u8*)texture_hud_char_mario_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_mario_head" }, + .hudHeadTexture = { .texture = (Texture*)texture_hud_char_mario_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_mario_head" }, .cameraHudHead = GLYPH_CAM_MARIO_HEAD, .modelId = MODEL_MARIO, .capModelId = MODEL_MARIOS_CAP, @@ -101,7 +101,7 @@ struct Character gCharacters[CT_MAX] = { .type = CT_LUIGI, .name = "Luigi", .hudHead = ')', - .hudHeadTexture = { .texture = (u8*)texture_hud_char_luigi_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_luigi_head" }, + .hudHeadTexture = { .texture = (Texture*)texture_hud_char_luigi_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_luigi_head" }, .cameraHudHead = GLYPH_CAM_LUIGI_HEAD, .modelId = MODEL_LUIGI, .capModelId = MODEL_LUIGIS_CAP, @@ -167,7 +167,7 @@ struct Character gCharacters[CT_MAX] = { .type = CT_TOAD, .name = "Toad", .hudHead = '|', - .hudHeadTexture = { .texture = (u8*)texture_hud_char_toad_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_toad_head" }, + .hudHeadTexture = { .texture = (Texture*)texture_hud_char_toad_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_toad_head" }, .cameraHudHead = GLYPH_CAM_TOAD_HEAD, .modelId = MODEL_TOAD_PLAYER, .capModelId = MODEL_TOADS_CAP, @@ -233,7 +233,7 @@ struct Character gCharacters[CT_MAX] = { .type = CT_WALUIGI, .name = "Waluigi", .hudHead = ']', - .hudHeadTexture = { .texture = (u8*)texture_hud_char_waluigi_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_waluigi_head" }, + .hudHeadTexture = { .texture = (Texture*)texture_hud_char_waluigi_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_waluigi_head" }, .cameraHudHead = GLYPH_CAM_WALUIGI_HEAD, .modelId = MODEL_WALUIGI, .capModelId = MODEL_WALUIGIS_CAP, @@ -299,7 +299,7 @@ struct Character gCharacters[CT_MAX] = { .type = CT_WARIO, .name = "Wario", .hudHead = '[', - .hudHeadTexture = { .texture = (u8*)texture_hud_char_wario_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_wario_head" }, + .hudHeadTexture = { .texture = (Texture*)texture_hud_char_wario_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_wario_head" }, .cameraHudHead = GLYPH_CAM_WARIO_HEAD, .modelId = MODEL_WARIO, .capModelId = MODEL_WARIOS_CAP, diff --git a/src/game/hud.c b/src/game/hud.c index 3397dc2bd..245edd56b 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -305,7 +305,7 @@ void render_hud_power_meter(void) { #define HUD_TOP_Y 209 #endif -void render_hud_icon(Vtx *vtx, const u8 *texture, u32 fmt, u32 siz, s32 texW, s32 texH, s32 x, s32 y, s32 w, s32 h, s32 tileX, s32 tileY, s32 tileW, s32 tileH) { +void render_hud_icon(Vtx *vtx, const Texture *texture, u32 fmt, u32 siz, s32 texW, s32 texH, s32 x, s32 y, s32 w, s32 h, s32 tileX, s32 tileY, s32 tileW, s32 tileH) { create_dl_ortho_matrix(); if (!vtx) { vtx = alloc_display_list(sizeof(Vtx) * 4); diff --git a/src/game/hud.h b/src/game/hud.h index 766c81312..e57031349 100644 --- a/src/game/hud.h +++ b/src/game/hud.h @@ -27,7 +27,7 @@ enum CameraHUDLut { extern u8 gOverrideHideHud; -void render_hud_icon(Vtx *vtx, const u8 *texture, u32 fmt, u32 siz, s32 texW, s32 texH, s32 x, s32 y, s32 w, s32 h, s32 tileX, s32 tileY, s32 tileW, s32 tileH); +void render_hud_icon(Vtx *vtx, const Texture *texture, u32 fmt, u32 siz, s32 texW, s32 texH, s32 x, s32 y, s32 w, s32 h, s32 tileX, s32 tileY, s32 tileW, s32 tileH); s16 get_hud_camera_status(void); void set_hud_camera_status(s16 status); diff --git a/src/game/mario_actions_stationary.c b/src/game/mario_actions_stationary.c index 05334b243..8fe099c85 100644 --- a/src/game/mario_actions_stationary.c +++ b/src/game/mario_actions_stationary.c @@ -1162,13 +1162,20 @@ s32 act_first_person(struct MarioState *m) { } s32 mario_exit_palette_editor(struct MarioState *m, struct Camera *c) { + if (!(m->flags & (MARIO_CAP_ON_HEAD | MARIO_CAP_IN_HAND))) { + return FALSE; + } + switch (c->paletteEditorCapState) { case 0: return FALSE; case 1: cutscene_put_cap_on(m); break; case 2: cutscene_take_cap_off(m); break; } c->paletteEditorCapState = 0; - return set_mario_action(m, ACT_IDLE, 0); + if (m->action == ACT_PALETTE_EDITOR_CAP) { + set_mario_action(m, ACT_IDLE, 0); + } + return TRUE; } s32 act_palette_editor_cap(struct MarioState *m) { diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c index 2163116da..f2e742d69 100644 --- a/src/game/mario_misc.c +++ b/src/game/mario_misc.c @@ -788,8 +788,11 @@ static Gfx *geo_mario_create_player_colors_dl(s32 index, Gfx *capEnemyGfx, Gfx * if (gfx) { Gfx *gfxp = gfx; for (s32 part = 0; part != PLAYER_PART_MAX; ++part) { - gSPLight(gfxp++, &gNetworkPlayerColors[index].parts[part].l, (2 * (part + 1)) + 1); - gSPLight(gfxp++, &gNetworkPlayerColors[index].parts[part].a, (2 * (part + 1)) + 2); + Lights1 *light = alloc_display_list(sizeof(Lights1)); + if (!light) { return NULL; } + *light = gNetworkPlayerColors[index].parts[part]; + gSPLight(gfxp++, &light->l, (2 * (part + 1)) + 1); + gSPLight(gfxp++, &light->a, (2 * (part + 1)) + 2); } if (capEnemyGfx) { gSPDisplayList(gfxp++, capEnemyGfx); } if (capEnemyDecalGfx) { gSPDisplayList(gfxp++, capEnemyDecalGfx); } diff --git a/src/game/memory.c b/src/game/memory.c index 6018a6e33..feca24fd1 100644 --- a/src/game/memory.c +++ b/src/game/memory.c @@ -220,6 +220,32 @@ void *growing_array_alloc(struct GrowingArray *array, u32 size) { return NULL; } +void growing_array_move(struct GrowingArray *array, u32 from, u32 to, u32 count) { + if (array && array->buffer && count > 0 && + (to < from || to > from + count) && + (from + count) <= array->count && to <= array->count) { + + void **temp = malloc(sizeof(void *) * count); + if (!temp) { return; } + + // Copy elements to move to temporary buffer + memcpy(temp, array->buffer + from, sizeof(void *) * count); + + // Remove copied elements from the array + memmove(array->buffer + from, array->buffer + (from + count), sizeof(void *) * (array->count - (from + count))); + + // Make place for the copied elements + // If moving left to right, account for the removed elements + if (to > from) { to -= count; } + memmove(array->buffer + (to + count), array->buffer + to, sizeof(void *) * (array->count - (to + count))); + + // Insert copied elements + memcpy(array->buffer + to, temp, sizeof(void *) * count); + + free(temp); + } +} + void growing_array_free(struct GrowingArray **array) { if (*array) { for (u32 i = 0; i != (*array)->capacity; ++i) { diff --git a/src/game/memory.h b/src/game/memory.h index dba8f7535..d8f469814 100644 --- a/src/game/memory.h +++ b/src/game/memory.h @@ -77,6 +77,7 @@ void growing_pool_free_pool(struct GrowingPool *pool); struct GrowingArray *growing_array_init(struct GrowingArray *array, u32 capacity, GrowingArrayAllocFunc alloc, GrowingArrayFreeFunc free); void *growing_array_alloc(struct GrowingArray *array, u32 size); +void growing_array_move(struct GrowingArray *array, u32 from, u32 to, u32 count); void growing_array_free(struct GrowingArray **array); void growing_array_debug_print(struct GrowingArray *array, const char *name, s32 x, s32 y); diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index 3e901bdc7..1752ae7b4 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -122,27 +122,6 @@ const BehaviorScript *gCurBhvCommand; */ s16 gPrevFrameObjectCount; -/** - * The total number of surface nodes allocated (a node is allocated for each - * spatial partition cell that a surface intersects). - */ -s32 gSurfaceNodesAllocated; - -/** - * The total number of surfaces allocated. - */ -s32 gSurfacesAllocated; - -/** - * The number of nodes that have been created for surfaces. - */ -s32 gNumStaticSurfaceNodes; - -/** - * The number of surfaces in the pool. - */ -s32 gNumStaticSurfaces; - struct Object* gCheckingSurfaceCollisionsForObject = NULL; s16 gCheckingSurfaceCollisionsForCamera; s16 gFindFloorIncludeSurfaceIntangible; diff --git a/src/game/object_list_processor.h b/src/game/object_list_processor.h index 24a1acf27..98cb25a95 100644 --- a/src/game/object_list_processor.h +++ b/src/game/object_list_processor.h @@ -91,11 +91,6 @@ extern struct Object *gCurrentObject; extern const BehaviorScript *gCurBhvCommand; extern s16 gPrevFrameObjectCount; -extern s32 gSurfaceNodesAllocated; -extern s32 gSurfacesAllocated; -extern s32 gNumStaticSurfaceNodes; -extern s32 gNumStaticSurfaces; - extern struct Object* gCheckingSurfaceCollisionsForObject; extern s16 gCheckingSurfaceCollisionsForCamera; extern s16 gFindFloorIncludeSurfaceIntangible; diff --git a/src/game/paintings.c b/src/game/paintings.c index 574e6bc45..071337531 100644 --- a/src/game/paintings.c +++ b/src/game/paintings.c @@ -20,6 +20,7 @@ #include "obj_behaviors.h" #include "level_update.h" #include "pc/network/network_player.h" +#include "pc/lua/utils/smlua_gfx_utils.h" #include "print.h" #include "hardcoded.h" @@ -1537,6 +1538,31 @@ Gfx *display_painting_rippling(struct Painting *painting) { return dlist; } +static Gfx *get_painting_normal_display_list(struct Painting *painting) { + const Gfx *normalDisplayList = painting->normalDisplayList; + if (!normalDisplayList) { + return NULL; + } + + u32 dlistLength = gfx_get_length_no_sentinel(normalDisplayList); + Gfx *dlist = alloc_display_list(dlistLength * sizeof(Gfx)); + if (!dlist) { + return NULL; + } + + Gfx *gfx = dlist; + s8 textureIndex = 0; + for (u32 i = 0; i < dlistLength; ++i, gfx++, normalDisplayList++) { + *gfx = *normalDisplayList; + + // Replace the texture pointer by the painting's corresponding texture + if (GFX_OP(normalDisplayList) == G_SETTIMG && textureIndex < painting->imageCount) { + gfx->words.w1 = (uintptr_t) painting->textureArray[textureIndex++]; + } + } + return dlist; +} + /** * Render a normal painting. */ @@ -1547,8 +1573,14 @@ Gfx *display_painting_not_rippling(struct Painting *painting) { if (dlist == NULL) { return dlist; } + + Gfx *normalDisplayList = get_painting_normal_display_list(painting); + if (!normalDisplayList) { + return NULL; + } + gSPDisplayList(gfx++, painting_model_view_transform(painting)); - gSPDisplayList(gfx++, painting->normalDisplayList); + gSPDisplayList(gfx++, normalDisplayList); gSPPopMatrix(gfx++, G_MTX_MODELVIEW); gSPEndDisplayList(gfx); return dlist; diff --git a/src/game/paintings.h b/src/game/paintings.h index 086c9fafd..98fe85fd8 100644 --- a/src/game/paintings.h +++ b/src/game/paintings.h @@ -109,7 +109,7 @@ struct Painting const s16 *const *textureMaps; // Texture data - const Texture *const *textureArray; + const Texture *textureArray[2]; s16 textureWidth; s16 textureHeight; diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 0edbfbf2f..c2a44de59 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -718,14 +718,12 @@ static void geo_process_camera(struct GraphNodeCamera *node) { mtxf_copy(gCamera->mtx, gMatStack[gMatStackIndex]); } - // compute inverse matrix for lighting engine - if (le_is_enabled()) { - Mat4 invCameraMatrix; - if (mtxf_inverse_non_affine(invCameraMatrix, gCamera->mtx)) { - Mtx *invMtx = alloc_display_list(sizeof(Mtx)); - mtxf_to_mtx(invMtx, invCameraMatrix); - gSPMatrix(gDisplayListHead++, invMtx, G_MTX_INVERSE_CAMERA_EXT); - } + // compute inverse matrix for lighting engine and fresnel + Mat4 invCameraMatrix; + if (mtxf_inverse_non_affine(invCameraMatrix, gCamera->mtx)) { + Mtx *invMtx = alloc_display_list(sizeof(Mtx)); + mtxf_to_mtx(invMtx, invCameraMatrix); + gSPMatrix(gDisplayListHead++, invMtx, G_MTX_INVERSE_CAMERA_EXT); } if (node->fnNode.node.children != 0) { @@ -1630,6 +1628,7 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) { Mat4 mat; Vec3f translation; Vec3f scalePrev; + Vec3s anglePrev; // Sanity check our stack index, If we above or equal to our stack size. Return to prevent OOB\. if ((gMatStackIndex + 1) >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; } @@ -1650,19 +1649,29 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) { if (gGlobalTimer == node->objNode->header.gfx.prevScaleTimestamp + 1) { vec3f_copy(scalePrev, node->objNode->header.gfx.prevScale); + vec3s_copy(anglePrev, node->objNode->header.gfx.prevAngle); } else { vec3f_copy(scalePrev, node->objNode->header.gfx.scale); + vec3s_copy(anglePrev, node->objNode->header.gfx.angle); } vec3f_copy(node->objNode->header.gfx.prevScale, node->objNode->header.gfx.scale); node->objNode->header.gfx.prevScaleTimestamp = gGlobalTimer; - mtxf_translate(mat, translation); + if (node->objNode->header.gfx.sharedChild->extraFlags & GRAPH_EXTRA_ROTATE_HELD) { + vec3s_copy(node->objNode->header.gfx.prevAngle, node->objNode->header.gfx.angle); + mtxf_rotate_zxy_and_translate(mat, translation, node->objNode->header.gfx.angle); + } else { + mtxf_translate(mat, translation); + } mtxf_copy(gMatStack[gMatStackIndex + 1], *gCurGraphNodeObject->throwMatrix); gMatStack[gMatStackIndex + 1][3][0] = gMatStack[gMatStackIndex][3][0]; gMatStack[gMatStackIndex + 1][3][1] = gMatStack[gMatStackIndex][3][1]; gMatStack[gMatStackIndex + 1][3][2] = gMatStack[gMatStackIndex][3][2]; mtxf_mul(gMatStack[gMatStackIndex + 1], mat, gMatStack[gMatStackIndex + 1]); mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1], node->objNode->header.gfx.scale); + if (node->objNode->header.gfx.sharedChild->extraFlags & GRAPH_EXTRA_ROTATE_HELD) { + mtxf_rotate_zxy_and_translate(mat, translation, anglePrev); + } mtxf_copy(gMatStackPrev[gMatStackIndex + 1], (void *) gCurGraphNodeObject->throwMatrixPrev); gMatStackPrev[gMatStackIndex + 1][3][0] = gMatStackPrev[gMatStackIndex][3][0]; gMatStackPrev[gMatStackIndex + 1][3][1] = gMatStackPrev[gMatStackIndex][3][1]; @@ -2005,4 +2014,4 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor) gCurGraphNodeRoot = NULL; } -} \ No newline at end of file +} diff --git a/src/pc/chat_commands.c b/src/pc/chat_commands.c index 40d132b7d..adb2bec1e 100644 --- a/src/pc/chat_commands.c +++ b/src/pc/chat_commands.c @@ -8,6 +8,7 @@ #include "pc/network/moderator_list.h" #include "pc/debuglog.h" #include "pc/lua/utils/smlua_level_utils.h" +#include "pc/mods/mods_utils.h" #include "level_table.h" #ifdef DEVELOPMENT #include "pc/dev/chat.h" @@ -39,10 +40,6 @@ static struct NetworkPlayer* chat_get_network_player(const char* name) { return NULL; } -static bool str_starts_with(const char* pre, const char* str) { - return strncmp(pre, str, strlen(pre)) == 0; -} - static void chat_construct_player_message(struct NetworkPlayer* np, char* msg) { char built[256] = { 0 }; snprintf(built, 256, "\\#fff982\\"); @@ -124,7 +121,7 @@ bool exec_chat_command(char* command) { return true; } - if (str_starts_with("/kick ", command)) { + if (str_starts_with(command, "/kick ")) { if (gNetworkType != NT_SERVER && !npl->moderator) { djui_chat_message_create(DLANG(CHAT, NO_PERMS)); return true; @@ -152,7 +149,7 @@ bool exec_chat_command(char* command) { return true; } - if (str_starts_with("/ban ", command)) { + if (str_starts_with(command, "/ban ")) { if (gNetworkType != NT_SERVER && !npl->moderator) { djui_chat_message_create(DLANG(CHAT, NO_PERMS)); return true; @@ -180,7 +177,7 @@ bool exec_chat_command(char* command) { return true; } - if (str_starts_with("/permban ", command)) { + if (str_starts_with(command, "/permban ")) { if (gNetworkType != NT_SERVER && !npl->moderator) { djui_chat_message_create(DLANG(CHAT, NO_PERMS)); return true; @@ -208,7 +205,7 @@ bool exec_chat_command(char* command) { return true; } - if (str_starts_with("/moderator ", command)) { + if (str_starts_with(command, "/moderator ")) { if (gNetworkType != NT_SERVER) { djui_chat_message_create(DLANG(CHAT, SERVER_ONLY)); return true; @@ -237,7 +234,7 @@ bool exec_chat_command(char* command) { return true; } - if (str_starts_with("/nametags ", command)) { + if (str_starts_with(command, "/nametags ")) { char *option = &command[10]; if (strcmp("show-tag", option) == 0) { gNametagsSettings.showSelfTag = !gNametagsSettings.showSelfTag; diff --git a/src/pc/dev/chat.c b/src/pc/dev/chat.c index dc5a08fc1..7118c4665 100644 --- a/src/pc/dev/chat.c +++ b/src/pc/dev/chat.c @@ -8,15 +8,12 @@ #include "pc/network/moderator_list.h" #include "pc/debuglog.h" #include "pc/lua/utils/smlua_level_utils.h" +#include "pc/mods/mods_utils.h" #include "level_table.h" #include "game/save_file.h" #ifdef DEVELOPMENT -static bool str_starts_with(const char* pre, char* str) { - return strncmp(pre, str, strlen(pre)) == 0; -} - // For case insensitivity static const char *upper(char *str) { static char buffer[50]; @@ -74,7 +71,7 @@ bool exec_dev_chat_command(char* command) { return true; } - if (str_starts_with("/warp ", command)) { + if (str_starts_with(command, "/warp ")) { static const struct { const char *name; s32 num; } sLevelNumByName[] = { #undef STUB_LEVEL #undef DEFINE_LEVEL @@ -169,7 +166,7 @@ bool exec_dev_chat_command(char* command) { return true; } - if (str_starts_with("/lua ", command)) { + if (str_starts_with(command, "/lua ")) { smlua_exec_str(&command[5]); return true; } @@ -179,7 +176,7 @@ bool exec_dev_chat_command(char* command) { return true; } - if (str_starts_with("/luaf ", command)) { + if (str_starts_with(command, "/luaf ")) { smlua_exec_file(&command[6]); return true; } diff --git a/src/pc/djui/djui_gfx.c b/src/pc/djui/djui_gfx.c index 5a9d2bbcf..6e347b8e3 100644 --- a/src/pc/djui/djui_gfx.c +++ b/src/pc/djui/djui_gfx.c @@ -123,13 +123,13 @@ static u8 djui_gfx_power_of_two(u32 value) { } } -void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize, bool filter) { +void djui_gfx_render_texture(const Texture* texture, u32 w, u32 h, u32 bitSize, bool filter) { gDPSetTextureFilter(gDisplayListHead++, filter ? G_TF_BILERP : G_TF_POINT); gDPSetTextureOverrideDjui(gDisplayListHead++, texture, djui_gfx_power_of_two(w), djui_gfx_power_of_two(h), bitSize); gSPDisplayList(gDisplayListHead++, dl_djui_image); } -void djui_gfx_render_texture_tile(const u8* texture, u32 w, u32 h, u32 bitSize, u32 tileX, u32 tileY, u32 tileW, u32 tileH, bool filter, bool font) { +void djui_gfx_render_texture_tile(const Texture* texture, u32 w, u32 h, u32 bitSize, u32 tileX, u32 tileY, u32 tileW, u32 tileH, bool filter, bool font) { if (!gDisplayListHead) { LOG_ERROR("Retrieved a null displaylist head"); return; diff --git a/src/pc/djui/djui_gfx.h b/src/pc/djui/djui_gfx.h index a49227983..93622d0ad 100644 --- a/src/pc/djui/djui_gfx.h +++ b/src/pc/djui/djui_gfx.h @@ -15,8 +15,8 @@ void djui_gfx_displaylist_end(void); f32 djui_gfx_get_scale(void); -void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize, bool filter); -void djui_gfx_render_texture_tile(const u8* texture, u32 w, u32 h, u32 bitSize, u32 tileX, u32 tileY, u32 tileW, u32 tileH, bool filter, bool font); +void djui_gfx_render_texture(const Texture* texture, u32 w, u32 h, u32 bitSize, bool filter); +void djui_gfx_render_texture_tile(const Texture* texture, u32 w, u32 h, u32 bitSize, u32 tileX, u32 tileY, u32 tileW, u32 tileH, bool filter, bool font); void gfx_get_dimensions(u32* width, u32* height); diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c index 7fe351d93..ae2485891 100644 --- a/src/pc/djui/djui_hud_utils.c +++ b/src/pc/djui/djui_hud_utils.c @@ -51,20 +51,20 @@ extern ALIGNED8 const u8 texture_hud_char_apostrophe[]; extern ALIGNED8 const u8 texture_hud_char_double_quote[]; struct GlobalTextures gGlobalTextures = { - .camera = { .texture = (u8*)texture_hud_char_camera, "texture_hud_char_camera", .width = 16, .height = 16, .bitSize = 8 }, - .lakitu = { .texture = (u8*)texture_hud_char_lakitu, "texture_hud_char_lakitu", .width = 16, .height = 16, .bitSize = 8 }, - .no_camera = { .texture = (u8*)texture_hud_char_no_camera, "texture_hud_char_no_camera", .width = 16, .height = 16, .bitSize = 8 }, - .arrow_up = { .texture = (u8*)texture_hud_char_arrow_up, "texture_hud_char_arrow_up", .width = 8, .height = 8, .bitSize = 8 }, - .arrow_down = { .texture = (u8*)texture_hud_char_arrow_down, "texture_hud_char_arrow_down", .width = 8, .height = 8, .bitSize = 8 }, - .coin = { .texture = (u8*)texture_hud_char_coin, "texture_hud_char_coin", .width = 16, .height = 16, .bitSize = 8 }, - .star = { .texture = (u8*)texture_hud_char_star, "texture_hud_char_star", .width = 16, .height = 16, .bitSize = 8 }, - .apostrophe = { .texture = (u8*)texture_hud_char_apostrophe, "texture_hud_char_apostrophe", .width = 16, .height = 16, .bitSize = 8 }, - .double_quote = { .texture = (u8*)texture_hud_char_double_quote, "texture_hud_char_double_quote", .width = 16, .height = 16, .bitSize = 8 }, - .mario_head = { .texture = (u8*)texture_hud_char_mario_head, "texture_hud_char_mario_head", .width = 16, .height = 16, .bitSize = 8 }, - .luigi_head = { .texture = (u8*)texture_hud_char_luigi_head, "texture_hud_char_luigi_head", .width = 16, .height = 16, .bitSize = 8 }, - .toad_head = { .texture = (u8*)texture_hud_char_toad_head, "texture_hud_char_toad_head", .width = 16, .height = 16, .bitSize = 8 }, - .waluigi_head = { .texture = (u8*)texture_hud_char_waluigi_head, "texture_hud_char_waluigi_head", .width = 16, .height = 16, .bitSize = 8 }, - .wario_head = { .texture = (u8*)texture_hud_char_wario_head, "texture_hud_char_wario_head", .width = 16, .height = 16, .bitSize = 8 } + .camera = { .texture = (Texture*)texture_hud_char_camera, "texture_hud_char_camera", .width = 16, .height = 16, .bitSize = 8 }, + .lakitu = { .texture = (Texture*)texture_hud_char_lakitu, "texture_hud_char_lakitu", .width = 16, .height = 16, .bitSize = 8 }, + .no_camera = { .texture = (Texture*)texture_hud_char_no_camera, "texture_hud_char_no_camera", .width = 16, .height = 16, .bitSize = 8 }, + .arrow_up = { .texture = (Texture*)texture_hud_char_arrow_up, "texture_hud_char_arrow_up", .width = 8, .height = 8, .bitSize = 8 }, + .arrow_down = { .texture = (Texture*)texture_hud_char_arrow_down, "texture_hud_char_arrow_down", .width = 8, .height = 8, .bitSize = 8 }, + .coin = { .texture = (Texture*)texture_hud_char_coin, "texture_hud_char_coin", .width = 16, .height = 16, .bitSize = 8 }, + .star = { .texture = (Texture*)texture_hud_char_star, "texture_hud_char_star", .width = 16, .height = 16, .bitSize = 8 }, + .apostrophe = { .texture = (Texture*)texture_hud_char_apostrophe, "texture_hud_char_apostrophe", .width = 16, .height = 16, .bitSize = 8 }, + .double_quote = { .texture = (Texture*)texture_hud_char_double_quote, "texture_hud_char_double_quote", .width = 16, .height = 16, .bitSize = 8 }, + .mario_head = { .texture = (Texture*)texture_hud_char_mario_head, "texture_hud_char_mario_head", .width = 16, .height = 16, .bitSize = 8 }, + .luigi_head = { .texture = (Texture*)texture_hud_char_luigi_head, "texture_hud_char_luigi_head", .width = 16, .height = 16, .bitSize = 8 }, + .toad_head = { .texture = (Texture*)texture_hud_char_toad_head, "texture_hud_char_toad_head", .width = 16, .height = 16, .bitSize = 8 }, + .waluigi_head = { .texture = (Texture*)texture_hud_char_waluigi_head, "texture_hud_char_waluigi_head", .width = 16, .height = 16, .bitSize = 8 }, + .wario_head = { .texture = (Texture*)texture_hud_char_wario_head, "texture_hud_char_wario_head", .width = 16, .height = 16, .bitSize = 8 } }; static void djui_hud_position_translate(f32* x, f32* y) { @@ -495,7 +495,7 @@ static inline bool is_power_of_two(u32 n) { return (n > 0) && ((n & (n - 1)) == 0); } -void djui_hud_render_texture_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH) { +void djui_hud_render_texture_raw(const Texture* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH) { if (!is_power_of_two(width) || !is_power_of_two(height)) { LOG_LUA_LINE("Tried to render DJUI HUD texture with NPOT width or height"); return; @@ -534,7 +534,7 @@ void djui_hud_render_texture_raw(const u8* texture, u32 bitSize, u32 width, u32 gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); } -void djui_hud_render_texture_tile_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH) { +void djui_hud_render_texture_tile_raw(const Texture* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH) { if (!texture) { return; } gDjuiHudUtilsZ += 0.01f; diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h index 2e2748be4..13efed6c8 100644 --- a/src/pc/djui/djui_hud_utils.h +++ b/src/pc/djui/djui_hud_utils.h @@ -121,10 +121,10 @@ void djui_hud_print_text(const char* message, f32 x, f32 y, f32 scale); void djui_hud_print_text_interpolated(const char* message, f32 prevX, f32 prevY, f32 prevScale, f32 x, f32 y, f32 scale); /* |description|Renders a DJUI HUD texture onto the screen|descriptionEnd| */ void djui_hud_render_texture(struct TextureInfo* texInfo, f32 x, f32 y, f32 scaleW, f32 scaleH); -void djui_hud_render_texture_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH); +void djui_hud_render_texture_raw(const Texture* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH); /* |description|Renders a DJUI HUD texture tile onto the screen|descriptionEnd| */ void djui_hud_render_texture_tile(struct TextureInfo* texInfo, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH); -void djui_hud_render_texture_tile_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH); +void djui_hud_render_texture_tile_raw(const Texture* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH); /* |description|Renders an interpolated DJUI HUD texture onto the screen|descriptionEnd| */ void djui_hud_render_texture_interpolated(struct TextureInfo* texInfo, f32 prevX, f32 prevY, f32 prevScaleW, f32 prevScaleH, f32 x, f32 y, f32 scaleW, f32 scaleH); /* |description|Renders an interpolated DJUI HUD texture tile onto the screen|descriptionEnd| */ diff --git a/src/pc/djui/djui_image.c b/src/pc/djui/djui_image.c index f227421c7..fa1101bc7 100644 --- a/src/pc/djui/djui_image.c +++ b/src/pc/djui/djui_image.c @@ -6,7 +6,7 @@ // properties // //////////////// -void djui_image_set_image(struct DjuiImage* image, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize) { +void djui_image_set_image(struct DjuiImage* image, const Texture* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize) { image->texture = texture; image->textureWidth = textureWidth; image->textureHeight = textureHeight; @@ -48,7 +48,7 @@ static void djui_image_destroy(struct DjuiBase* base) { free(image); } -struct DjuiImage* djui_image_create(struct DjuiBase* parent, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize) { +struct DjuiImage* djui_image_create(struct DjuiBase* parent, const Texture* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize) { struct DjuiImage* image = calloc(1, sizeof(struct DjuiImage)); struct DjuiBase* base = &image->base; diff --git a/src/pc/djui/djui_image.h b/src/pc/djui/djui_image.h index 84ffb35da..88b2d0b7d 100644 --- a/src/pc/djui/djui_image.h +++ b/src/pc/djui/djui_image.h @@ -3,12 +3,12 @@ struct DjuiImage { struct DjuiBase base; - const u8* texture; + const Texture* texture; u16 textureWidth; u16 textureHeight; u16 textureBitSize; }; -void djui_image_set_image(struct DjuiImage* image, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize); +void djui_image_set_image(struct DjuiImage* image, const Texture* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize); -struct DjuiImage* djui_image_create(struct DjuiBase* parent, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize); +struct DjuiImage* djui_image_create(struct DjuiBase* parent, const Texture* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize); diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 21329aca6..9c1a6b62e 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -61,6 +61,7 @@ static struct RSP { uint32_t geometry_mode; int16_t fog_mul, fog_offset; + int16_t fresnel_scale, fresnel_offset; struct { // U0.16 @@ -850,6 +851,33 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons d->color.b *= vtxB; } + if (rsp.geometry_mode & (G_FRESNEL_COLOR_EXT | G_FRESNEL_ALPHA_EXT)) { + Vec3f vpos = { v->ob[0], v->ob[1], v->ob[2] }; + Vec3f vnormal = { nx / 255.0f, ny / 255.0f, nz / 255.0f }; + // transform vpos and vnormal to world space + gfx_local_to_world_space(vpos, vnormal); + + Vec3f viewDir = { + sInverseCameraMatrix[3][0] - vpos[0], + sInverseCameraMatrix[3][1] - vpos[1], + sInverseCameraMatrix[3][2] - vpos[2] + }; + vec3f_normalize(viewDir); + vec3f_normalize(vnormal); + + int32_t dot = (int32_t) (fabsf(vec3f_dot(vnormal, viewDir)) * 32767.0f); + int32_t factor = ((rsp.fresnel_scale * dot) >> 15) + rsp.fresnel_offset; + int32_t fresnel = clamp(factor << 8, 0, 0x7FFF); + uint8_t result = (uint8_t) (fresnel >> 7); + + if (rsp.geometry_mode & G_FRESNEL_COLOR_EXT) { + d->color.r = d->color.g = d->color.b = result; + } + if (rsp.geometry_mode & G_FRESNEL_ALPHA_EXT) { + d->color.a = result; + } + } + if (rsp.geometry_mode & G_TEXTURE_GEN) { float dotx = 0, doty = 0; dotx += nx * rsp.current_lookat_coeffs[0][0]; @@ -970,8 +998,9 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons if (fog_z > 255) fog_z = 255; d->fog_z = fog_z; } - - d->color.a = v->cn[3]; + if (!(rsp.geometry_mode & G_FRESNEL_ALPHA_EXT)) { + d->color.a = v->cn[3]; + } } } @@ -999,6 +1028,11 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t cross = -cross; } + // Invert culling: back becomes front and front becomes back + if (rsp.geometry_mode & G_CULL_INVERT_EXT) { + cross = -cross; + } + switch (rsp.geometry_mode & G_CULL_BOTH) { case G_CULL_FRONT: if (cross <= 0) return; @@ -1297,7 +1331,7 @@ static void gfx_sp_copymem(uint8_t idx, uint16_t dstofs, uint16_t srcofs, UNUSED } #endif -static void gfx_sp_moveword(uint8_t index, UNUSED uint16_t offset, uint32_t data) { +static void gfx_sp_moveword(uint8_t index, uint16_t offset, uint32_t data) { switch (index) { case G_MW_NUMLIGHT: #ifdef F3DEX_GBI_2 @@ -1319,6 +1353,22 @@ static void gfx_sp_moveword(uint8_t index, UNUSED uint16_t offset, uint32_t data sDepthZSub = gProjectionVanillaNearValue; break; + case G_MW_FX: + if (offset == G_MWO_FRESNEL) { + rsp.fresnel_scale = (int16_t)(data >> 16); + rsp.fresnel_offset = (int16_t)data; + } + break; + case G_MW_LIGHTCOL: { + int lightNum = offset / 24; + // data = packed color + if (lightNum >= 0 && lightNum <= MAX_LIGHTS) { + rsp.current_lights[lightNum].col[0] = (uint8_t)(data >> 24); + rsp.current_lights[lightNum].col[1] = (uint8_t)(data >> 16); + rsp.current_lights[lightNum].col[2] = (uint8_t)(data >> 8); + } + break; + } } } diff --git a/src/pc/lua/smlua.c b/src/pc/lua/smlua.c index b93b5679a..cd2502050 100644 --- a/src/pc/lua/smlua.c +++ b/src/pc/lua/smlua.c @@ -4,6 +4,8 @@ #include "game/hardcoded.h" #include "pc/mods/mods.h" #include "pc/mods/mods_utils.h" +#include "pc/mods/mod_storage.h" +#include "pc/mods/mod_fs.h" #include "pc/crash_handler.h" #include "pc/lua/utils/smlua_text_utils.h" #include "pc/lua/utils/smlua_audio_utils.h" @@ -352,7 +354,7 @@ void smlua_init(void) { for (int j = 0; j < mod->fileCount; j++) { struct ModFile* file = &mod->files[j]; // skip loading non-lua files - if (!(str_ends_with(file->relativePath, ".lua") || str_ends_with(file->relativePath, ".luac"))) { + if (!(path_ends_with(file->relativePath, ".lua") || path_ends_with(file->relativePath, ".luac"))) { continue; } @@ -362,7 +364,19 @@ void smlua_init(void) { } gLuaActiveModFile = file; - smlua_load_script(mod, file, i, true); + + // file has been required by some module before this + if (!smlua_get_cached_module_result(L, mod, file)) { + smlua_mark_module_as_loading(L, mod, file); + + s32 prevTop = lua_gettop(L); + int rc = smlua_load_script(mod, file, i, true); + + if (rc == LUA_OK) { + smlua_cache_module_result(L, mod, file, prevTop); + } + } + lua_settop(L, 0); } gLuaActiveMod = NULL; @@ -406,6 +420,8 @@ void smlua_shutdown(void) { smlua_model_util_clear(); smlua_level_util_reset(); smlua_anim_util_reset(); + mod_storage_shutdown(); + mod_fs_shutdown(); lua_State* L = gLuaState; if (L != NULL) { lua_close(L); diff --git a/src/pc/lua/smlua_autogen.h b/src/pc/lua/smlua_autogen.h index 53b49e5ed..5267c76e6 100644 --- a/src/pc/lua/smlua_autogen.h +++ b/src/pc/lua/smlua_autogen.h @@ -13,4 +13,7 @@ // Optional parameters must be contiguous until the last parameter (a mandatory parameter following an optional parameter is not allowed) #define OPTIONAL +// A macro to tell autogen the field `name` is a function member of the struct that calls `c_function` +#define FUNCTION(name, c_function) + #endif // SMLUA_AUTOGEN_H diff --git a/src/pc/lua/smlua_cobject.c b/src/pc/lua/smlua_cobject.c index 67b47ecf4..4f7da423a 100644 --- a/src/pc/lua/smlua_cobject.c +++ b/src/pc/lua/smlua_cobject.c @@ -68,7 +68,7 @@ bool smlua_valid_lvt(u16 lvt) { return (lvt < LVT_MAX); } -const char *sLuaLvtNames[] = { +static const char *sLuaLvtNames[] = { [LVT_BOOL] = "bool", [LVT_BOOL_P] = "bool Pointer", [LVT_U8] = "u8", @@ -91,18 +91,16 @@ const char *sLuaLvtNames[] = { [LVT_COBJECT_P] = "CObject Pointer", [LVT_STRING] = "string", [LVT_STRING_P] = "string Pointer", - [LVT_BEHAVIORSCRIPT] = "BehaviorScript", [LVT_BEHAVIORSCRIPT_P] = "BehaviorScript Pointer", - [LVT_OBJECTANIMPOINTER] = "ObjectAnimPointer", [LVT_OBJECTANIMPOINTER_P] = "ObjectAnimPointer Pointer", - [LVT_COLLISION] = "Collision", [LVT_COLLISION_P] = "Collision Pointer", - [LVT_LEVELSCRIPT] = "LevelScript", [LVT_LEVELSCRIPT_P] = "LevelScript Pointer", - [LVT_TRAJECTORY] = "Trajectory", [LVT_TRAJECTORY_P] = "Trajectory Pointer", + [LVT_TEXTURE_P] = "Texture Pointer", [LVT_LUAFUNCTION] = "LuaFunction", + [LVT_LUATABLE] = "LuaTable", [LVT_POINTER] = "Pointer", + [LVT_FUNCTION] = "Function", [LVT_MAX] = "Max", }; @@ -373,24 +371,19 @@ struct LuaObjectField* smlua_get_custom_field(lua_State* L, u32 lot, int keyInde static bool smlua_push_field(lua_State* L, u8* p, struct LuaObjectField *data) { switch (data->valueType) { - case LVT_BOOL: lua_pushboolean(L, *(u8* )p); break; - case LVT_U8: lua_pushinteger(L, *(u8* )p); break; - case LVT_U16: lua_pushinteger(L, *(u16*)p); break; - case LVT_U32: lua_pushinteger(L, *(u32*)p); break; - case LVT_S8: lua_pushinteger(L, *(s8* )p); break; - case LVT_S16: lua_pushinteger(L, *(s16*)p); break; - case LVT_S32: lua_pushinteger(L, *(s32*)p); break; - case LVT_F32: lua_pushnumber( L, *(f32*)p); break; - case LVT_U64: lua_pushinteger(L, *(u64*)p); break; - case LVT_COBJECT: smlua_push_object(L, data->lot, p, NULL); break; - case LVT_COBJECT_P: smlua_push_object(L, data->lot, *(u8**)p, NULL); break; - case LVT_STRING: lua_pushstring(L, (char*)p); break; - case LVT_STRING_P: lua_pushstring(L, *(char**)p); break; - case LVT_BEHAVIORSCRIPT: lua_pushinteger(L, *(s32*)p); break; - case LVT_OBJECTANIMPOINTER: lua_pushinteger(L, *(s32*)p); break; - case LVT_COLLISION: lua_pushinteger(L, *(s32*)p); break; - case LVT_LEVELSCRIPT: lua_pushinteger(L, *(s32*)p); break; - case LVT_TRAJECTORY: lua_pushinteger(L, *(s16*)p); break; + case LVT_BOOL: lua_pushboolean(L, *(u8* )p); break; + case LVT_U8: lua_pushinteger(L, *(u8* )p); break; + case LVT_U16: lua_pushinteger(L, *(u16*)p); break; + case LVT_U32: lua_pushinteger(L, *(u32*)p); break; + case LVT_S8: lua_pushinteger(L, *(s8* )p); break; + case LVT_S16: lua_pushinteger(L, *(s16*)p); break; + case LVT_S32: lua_pushinteger(L, *(s32*)p); break; + case LVT_F32: lua_pushnumber( L, *(f32*)p); break; + case LVT_U64: lua_pushinteger(L, *(u64*)p); break; + case LVT_COBJECT: smlua_push_object(L, data->lot, p, NULL); break; + case LVT_COBJECT_P: smlua_push_object(L, data->lot, *(u8**)p, NULL); break; + case LVT_STRING: lua_pushstring(L, (char*)p); break; + case LVT_STRING_P: lua_pushstring(L, *(char**)p); break; // pointers case LVT_BOOL_P: @@ -407,6 +400,7 @@ static bool smlua_push_field(lua_State* L, u8* p, struct LuaObjectField *data) { case LVT_COLLISION_P: case LVT_LEVELSCRIPT_P: case LVT_TRAJECTORY_P: + case LVT_TEXTURE_P: smlua_push_pointer(L, data->valueType, *(u8**)p, NULL); break; @@ -453,7 +447,9 @@ static bool smlua_set_field(lua_State* L, u8* p, struct LuaObjectField *data) { case LVT_BEHAVIORSCRIPT_P: case LVT_OBJECTANIMPOINTER_P: case LVT_COLLISION_P: + case LVT_LEVELSCRIPT_P: case LVT_TRAJECTORY_P: + case LVT_TEXTURE_P: if (lua_isnil(L, 3)) { *(u8**)p = NULL; break; @@ -555,6 +551,14 @@ static int smlua__get_field(lua_State* L) { return 0; } + // CObject function members + if (data->valueType == LVT_FUNCTION) { + const char *function = (const char *) data->valueOffset; + lua_getglobal(L, function); + LUA_STACK_CHECK_END(L); + return 1; + } + u8* p = ((u8*)(intptr_t)pointer) + data->valueOffset; if (data->count == 1) { if (smlua_push_field(L, p, data)) { @@ -656,6 +660,12 @@ int smlua__eq(lua_State *L) { return 1; } +int smlua__bnot(lua_State *L) { + const CObject *a = lua_touserdata(L, 1); + lua_pushboolean(L, !a || a->freed); + return 1; +} + static int smlua_cpointer_get(lua_State* L) { const CPointer *cptr = lua_touserdata(L, 1); const char *key = lua_tostring(L, 2); @@ -696,6 +706,7 @@ void smlua_cobject_init_globals(void) { { "__index", smlua__get_field }, { "__newindex", smlua__set_field }, { "__eq", smlua__eq }, + { "__bnot", smlua__bnot }, { "__metatable", NULL }, { NULL, NULL } }; @@ -706,6 +717,7 @@ void smlua_cobject_init_globals(void) { { "__index", smlua_cpointer_get }, { "__newindex", smlua_cpointer_set }, { "__eq", smlua__eq }, + { "__bnot", smlua__bnot }, { "__metatable", NULL }, { NULL, NULL } }; diff --git a/src/pc/lua/smlua_cobject.h b/src/pc/lua/smlua_cobject.h index 403f4e828..83cac836d 100644 --- a/src/pc/lua/smlua_cobject.h +++ b/src/pc/lua/smlua_cobject.h @@ -1,6 +1,8 @@ #ifndef SMLUA_COBJECT_H #define SMLUA_COBJECT_H +#include "lua.h" + enum LuaValueType { LVT_BOOL, LVT_BOOL_P, @@ -24,18 +26,16 @@ enum LuaValueType { LVT_COBJECT_P, LVT_STRING, LVT_STRING_P, - LVT_BEHAVIORSCRIPT, LVT_BEHAVIORSCRIPT_P, - LVT_OBJECTANIMPOINTER, LVT_OBJECTANIMPOINTER_P, - LVT_COLLISION, LVT_COLLISION_P, - LVT_LEVELSCRIPT, LVT_LEVELSCRIPT_P, - LVT_TRAJECTORY, LVT_TRAJECTORY_P, + LVT_TEXTURE_P, LVT_LUAFUNCTION, + LVT_LUATABLE, LVT_POINTER, + LVT_FUNCTION, LVT_MAX, }; diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index 0fb70f2a1..aeec902f6 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -201,7 +201,7 @@ static struct LuaObjectField sAnimationTableFields[LUA_ANIMATION_TABLE_FIELD_COU #define LUA_AREA_FIELD_COUNT 21 static struct LuaObjectField sAreaFields[LUA_AREA_FIELD_COUNT] = { { "camera", LVT_COBJECT_P, offsetof(struct Area, camera), false, LOT_CAMERA, 1, sizeof(struct Camera*) }, - { "dialog", LVT_U8, offsetof(struct Area, dialog), false, LOT_NONE, 2, sizeof(u8) }, + { "dialog", LVT_S32, offsetof(struct Area, dialog), false, LOT_NONE, 2, sizeof(s32) }, { "flags", LVT_S8, offsetof(struct Area, flags), false, LOT_NONE, 1, sizeof(s8) }, { "index", LVT_S8, offsetof(struct Area, index), false, LOT_NONE, 1, sizeof(s8) }, { "instantWarps", LVT_COBJECT_P, offsetof(struct Area, instantWarps), false, LOT_INSTANTWARP, 1, sizeof(struct InstantWarp*) }, @@ -1607,10 +1607,10 @@ static struct LuaObjectField sModFields[LUA_MOD_FIELD_COUNT] = { #define LUA_MOD_AUDIO_FIELD_COUNT 4 static struct LuaObjectField sModAudioFields[LUA_MOD_AUDIO_FIELD_COUNT] = { - { "baseVolume", LVT_F32, offsetof(struct ModAudio, baseVolume), false, LOT_NONE, 1, sizeof(f32) }, - { "file", LVT_COBJECT_P, offsetof(struct ModAudio, file), false, LOT_MODFILE, 1, sizeof(struct ModFile*) }, - { "isStream", LVT_BOOL, offsetof(struct ModAudio, isStream), true, LOT_NONE, 1, sizeof(bool) }, - { "loaded", LVT_BOOL, offsetof(struct ModAudio, loaded), true, LOT_NONE, 1, sizeof(bool) }, + { "baseVolume", LVT_F32, offsetof(struct ModAudio, baseVolume), false, LOT_NONE, 1, sizeof(f32) }, + { "filepath", LVT_STRING_P, offsetof(struct ModAudio, filepath), true, LOT_NONE, 1, sizeof(const char*) }, + { "isStream", LVT_BOOL, offsetof(struct ModAudio, isStream), true, LOT_NONE, 1, sizeof(bool) }, + { "loaded", LVT_BOOL, offsetof(struct ModAudio, loaded), true, LOT_NONE, 1, sizeof(bool) }, }; #define LUA_MOD_AUDIO_SAMPLE_COPIES_FIELD_COUNT 3 @@ -1634,23 +1634,83 @@ static struct LuaObjectField sModFileFields[LUA_MOD_FILE_FIELD_COUNT] = { { "wroteBytes", LVT_U64, offsetof(struct ModFile, wroteBytes), true, LOT_NONE, 1, sizeof(u64) }, }; -#define LUA_MOD_FS_FIELD_COUNT 5 +static const char FUNCTION__mod_fs_clear[] = "mod_fs_clear"; +static const char FUNCTION__mod_fs_copy_file[] = "mod_fs_copy_file"; +static const char FUNCTION__mod_fs_create_file[] = "mod_fs_create_file"; +static const char FUNCTION__mod_fs_delete[] = "mod_fs_delete"; +static const char FUNCTION__mod_fs_delete_file[] = "mod_fs_delete_file"; +static const char FUNCTION__mod_fs_get_file[] = "mod_fs_get_file"; +static const char FUNCTION__mod_fs_get_filename[] = "mod_fs_get_filename"; +static const char FUNCTION__mod_fs_move_file[] = "mod_fs_move_file"; +static const char FUNCTION__mod_fs_save[] = "mod_fs_save"; +static const char FUNCTION__mod_fs_set_public[] = "mod_fs_set_public"; + +#define LUA_MOD_FS_FIELD_COUNT 15 static struct LuaObjectField sModFsFields[LUA_MOD_FS_FIELD_COUNT] = { - { "isPublic", LVT_BOOL, offsetof(struct ModFs, isPublic), true, LOT_NONE, 1, sizeof(bool) }, - { "mod", LVT_COBJECT_P, offsetof(struct ModFs, mod), true, LOT_MOD, 1, sizeof(struct Mod*) }, - { "modPath", LVT_STRING, offsetof(struct ModFs, modPath), true, LOT_NONE, 1, sizeof(char) }, - { "numFiles", LVT_U16, offsetof(struct ModFs, numFiles), true, LOT_NONE, 1, sizeof(u16) }, - { "totalSize", LVT_U32, offsetof(struct ModFs, totalSize), true, LOT_NONE, 1, sizeof(u32) }, + { "clear", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_clear, true, LOT_NONE, 1, sizeof(const char *) }, + { "copy_file", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_copy_file, true, LOT_NONE, 1, sizeof(const char *) }, + { "create_file", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_create_file, true, LOT_NONE, 1, sizeof(const char *) }, + { "delete", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_delete, true, LOT_NONE, 1, sizeof(const char *) }, + { "delete_file", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_delete_file, true, LOT_NONE, 1, sizeof(const char *) }, + { "get_file", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_get_file, true, LOT_NONE, 1, sizeof(const char *) }, + { "get_filename", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_get_filename, true, LOT_NONE, 1, sizeof(const char *) }, + { "isPublic", LVT_BOOL, offsetof(struct ModFs, isPublic), true, LOT_NONE, 1, sizeof(bool) }, + { "mod", LVT_COBJECT_P, offsetof(struct ModFs, mod), true, LOT_MOD, 1, sizeof(struct Mod*) }, + { "modPath", LVT_STRING, offsetof(struct ModFs, modPath), true, LOT_NONE, 1, sizeof(char) }, + { "move_file", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_move_file, true, LOT_NONE, 1, sizeof(const char *) }, + { "numFiles", LVT_U16, offsetof(struct ModFs, numFiles), true, LOT_NONE, 1, sizeof(u16) }, + { "save", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_save, true, LOT_NONE, 1, sizeof(const char *) }, + { "set_public", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_set_public, true, LOT_NONE, 1, sizeof(const char *) }, + { "totalSize", LVT_U32, offsetof(struct ModFs, totalSize), true, LOT_NONE, 1, sizeof(u32) }, }; -#define LUA_MOD_FS_FILE_FIELD_COUNT 6 +static const char FUNCTION__mod_fs_file_erase[] = "mod_fs_file_erase"; +static const char FUNCTION__mod_fs_file_fill[] = "mod_fs_file_fill"; +static const char FUNCTION__mod_fs_file_is_eof[] = "mod_fs_file_is_eof"; +static const char FUNCTION__mod_fs_file_read_bool[] = "mod_fs_file_read_bool"; +static const char FUNCTION__mod_fs_file_read_bytes[] = "mod_fs_file_read_bytes"; +static const char FUNCTION__mod_fs_file_read_integer[] = "mod_fs_file_read_integer"; +static const char FUNCTION__mod_fs_file_read_line[] = "mod_fs_file_read_line"; +static const char FUNCTION__mod_fs_file_read_number[] = "mod_fs_file_read_number"; +static const char FUNCTION__mod_fs_file_read_string[] = "mod_fs_file_read_string"; +static const char FUNCTION__mod_fs_file_rewind[] = "mod_fs_file_rewind"; +static const char FUNCTION__mod_fs_file_seek[] = "mod_fs_file_seek"; +static const char FUNCTION__mod_fs_file_set_public[] = "mod_fs_file_set_public"; +static const char FUNCTION__mod_fs_file_set_text_mode[] = "mod_fs_file_set_text_mode"; +static const char FUNCTION__mod_fs_file_write_bool[] = "mod_fs_file_write_bool"; +static const char FUNCTION__mod_fs_file_write_bytes[] = "mod_fs_file_write_bytes"; +static const char FUNCTION__mod_fs_file_write_integer[] = "mod_fs_file_write_integer"; +static const char FUNCTION__mod_fs_file_write_line[] = "mod_fs_file_write_line"; +static const char FUNCTION__mod_fs_file_write_number[] = "mod_fs_file_write_number"; +static const char FUNCTION__mod_fs_file_write_string[] = "mod_fs_file_write_string"; + +#define LUA_MOD_FS_FILE_FIELD_COUNT 25 static struct LuaObjectField sModFsFileFields[LUA_MOD_FS_FILE_FIELD_COUNT] = { - { "filepath", LVT_STRING, offsetof(struct ModFsFile, filepath), true, LOT_NONE, 1, sizeof(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) }, - { "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) }, - { "size", LVT_U32, offsetof(struct ModFsFile, size), true, LOT_NONE, 1, sizeof(u32) }, + { "erase", LVT_FUNCTION, (size_t) FUNCTION__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) FUNCTION__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) FUNCTION__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) FUNCTION__mod_fs_file_read_bool, true, LOT_NONE, 1, sizeof(const char *) }, + { "read_bytes", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_read_bytes, true, LOT_NONE, 1, sizeof(const char *) }, + { "read_integer", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_read_integer, true, LOT_NONE, 1, sizeof(const char *) }, + { "read_line", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_read_line, true, LOT_NONE, 1, sizeof(const char *) }, + { "read_number", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_read_number, true, LOT_NONE, 1, sizeof(const char *) }, + { "read_string", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_read_string, true, LOT_NONE, 1, sizeof(const char *) }, + { "rewind", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_rewind, true, LOT_NONE, 1, sizeof(const char *) }, + { "seek", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_seek, true, LOT_NONE, 1, sizeof(const char *) }, + { "set_public", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_set_public, true, LOT_NONE, 1, sizeof(const char *) }, + { "set_text_mode", LVT_FUNCTION, (size_t) FUNCTION__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) FUNCTION__mod_fs_file_write_bool, true, LOT_NONE, 1, sizeof(const char *) }, + { "write_bytes", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_write_bytes, true, LOT_NONE, 1, sizeof(const char *) }, + { "write_integer", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_write_integer, true, LOT_NONE, 1, sizeof(const char *) }, + { "write_line", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_write_line, true, LOT_NONE, 1, sizeof(const char *) }, + { "write_number", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_write_number, true, LOT_NONE, 1, sizeof(const char *) }, + { "write_string", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_write_string, true, LOT_NONE, 1, sizeof(const char *) }, }; #define LUA_MODE_TRANSITION_INFO_FIELD_COUNT 6 @@ -2521,48 +2581,44 @@ static struct LuaObjectField sOffsetSizePairFields[LUA_OFFSET_SIZE_PAIR_FIELD_CO { "size", LVT_U32, offsetof(struct OffsetSizePair, size), false, LOT_NONE, 1, sizeof(u32) }, }; -#define LUA_PAINTING_FIELD_COUNT 37 +#define LUA_PAINTING_FIELD_COUNT 36 static struct LuaObjectField sPaintingFields[LUA_PAINTING_FIELD_COUNT] = { - { "alpha", LVT_U8, offsetof(struct Painting, alpha), false, LOT_NONE, 1, sizeof(u8) }, - { "currFloor", LVT_S8, offsetof(struct Painting, currFloor), false, LOT_NONE, 1, sizeof(s8) }, - { "currRippleMag", LVT_F32, offsetof(struct Painting, currRippleMag), false, LOT_NONE, 1, sizeof(f32) }, - { "currRippleRate", LVT_F32, offsetof(struct Painting, currRippleRate), false, LOT_NONE, 1, sizeof(f32) }, - { "dispersionFactor", LVT_F32, offsetof(struct Painting, dispersionFactor), false, LOT_NONE, 1, sizeof(f32) }, - { "entryDispersionFactor", LVT_F32, offsetof(struct Painting, entryDispersionFactor), false, LOT_NONE, 1, sizeof(f32) }, - { "entryRippleDecay", LVT_F32, offsetof(struct Painting, entryRippleDecay), false, LOT_NONE, 1, sizeof(f32) }, - { "entryRippleMag", LVT_F32, offsetof(struct Painting, entryRippleMag), false, LOT_NONE, 1, sizeof(f32) }, - { "entryRippleRate", LVT_F32, offsetof(struct Painting, entryRippleRate), false, LOT_NONE, 1, sizeof(f32) }, - { "floorEntered", LVT_S8, offsetof(struct Painting, floorEntered), false, LOT_NONE, 1, sizeof(s8) }, - { "id", LVT_S16, offsetof(struct Painting, id), true, LOT_NONE, 1, sizeof(s16) }, - { "imageCount", LVT_S8, offsetof(struct Painting, imageCount), true, LOT_NONE, 1, sizeof(s8) }, - { "lastFloor", LVT_S8, offsetof(struct Painting, lastFloor), false, LOT_NONE, 1, sizeof(s8) }, - { "marioIsUnder", LVT_S8, offsetof(struct Painting, marioIsUnder), false, LOT_NONE, 1, sizeof(s8) }, - { "marioWasUnder", LVT_S8, offsetof(struct Painting, marioWasUnder), false, LOT_NONE, 1, sizeof(s8) }, - { "marioWentUnder", LVT_S8, offsetof(struct Painting, marioWentUnder), false, LOT_NONE, 1, sizeof(s8) }, - { "normalDisplayList", LVT_COBJECT_P, offsetof(struct Painting, normalDisplayList), true, LOT_GFX, 1, sizeof(const Gfx*) }, - { "passiveDispersionFactor", LVT_F32, offsetof(struct Painting, passiveDispersionFactor), false, LOT_NONE, 1, sizeof(f32) }, - { "passiveRippleDecay", LVT_F32, offsetof(struct Painting, passiveRippleDecay), false, LOT_NONE, 1, sizeof(f32) }, - { "passiveRippleMag", LVT_F32, offsetof(struct Painting, passiveRippleMag), false, LOT_NONE, 1, sizeof(f32) }, - { "passiveRippleRate", LVT_F32, offsetof(struct Painting, passiveRippleRate), false, LOT_NONE, 1, sizeof(f32) }, - { "pitch", LVT_F32, offsetof(struct Painting, pitch), false, LOT_NONE, 1, sizeof(f32) }, - { "posX", LVT_F32, offsetof(struct Painting, posX), false, LOT_NONE, 1, sizeof(f32) }, - { "posY", LVT_F32, offsetof(struct Painting, posY), false, LOT_NONE, 1, sizeof(f32) }, - { "posZ", LVT_F32, offsetof(struct Painting, posZ), false, LOT_NONE, 1, sizeof(f32) }, - { "rippleDecay", LVT_F32, offsetof(struct Painting, rippleDecay), false, LOT_NONE, 1, sizeof(f32) }, - { "rippleDisplayList", LVT_COBJECT_P, offsetof(struct Painting, rippleDisplayList), true, LOT_GFX, 1, sizeof(const Gfx*) }, - { "rippleTimer", LVT_F32, offsetof(struct Painting, rippleTimer), false, LOT_NONE, 1, sizeof(f32) }, - { "rippleTrigger", LVT_S8, offsetof(struct Painting, rippleTrigger), false, LOT_NONE, 1, sizeof(s8) }, - { "rippleX", LVT_F32, offsetof(struct Painting, rippleX), false, LOT_NONE, 1, sizeof(f32) }, - { "rippleY", LVT_F32, offsetof(struct Painting, rippleY), false, LOT_NONE, 1, sizeof(f32) }, -// { "ripples", LVT_???, offsetof(struct Painting, ripples), false, LOT_???, 1, sizeof(struct { ... }) }, <--- UNIMPLEMENTED - { "size", LVT_F32, offsetof(struct Painting, size), false, LOT_NONE, 1, sizeof(f32) }, - { "state", LVT_S8, offsetof(struct Painting, state), false, LOT_NONE, 1, sizeof(s8) }, -// { "textureArray", LVT_???, offsetof(struct Painting, textureArray), true, LOT_???, 1, sizeof(const Texture *const*) }, <--- UNIMPLEMENTED - { "textureHeight", LVT_S16, offsetof(struct Painting, textureHeight), true, LOT_NONE, 1, sizeof(s16) }, -// { "textureMaps", LVT_???, offsetof(struct Painting, textureMaps), true, LOT_???, 1, sizeof(const s16 *const*) }, <--- UNIMPLEMENTED - { "textureType", LVT_S8, offsetof(struct Painting, textureType), true, LOT_NONE, 1, sizeof(s8) }, - { "textureWidth", LVT_S16, offsetof(struct Painting, textureWidth), true, LOT_NONE, 1, sizeof(s16) }, - { "yaw", LVT_F32, offsetof(struct Painting, yaw), false, LOT_NONE, 1, sizeof(f32) }, + { "alpha", LVT_U8, offsetof(struct Painting, alpha), false, LOT_NONE, 1, sizeof(u8) }, + { "currFloor", LVT_S8, offsetof(struct Painting, currFloor), false, LOT_NONE, 1, sizeof(s8) }, + { "currRippleMag", LVT_F32, offsetof(struct Painting, currRippleMag), false, LOT_NONE, 1, sizeof(f32) }, + { "currRippleRate", LVT_F32, offsetof(struct Painting, currRippleRate), false, LOT_NONE, 1, sizeof(f32) }, + { "dispersionFactor", LVT_F32, offsetof(struct Painting, dispersionFactor), false, LOT_NONE, 1, sizeof(f32) }, + { "entryDispersionFactor", LVT_F32, offsetof(struct Painting, entryDispersionFactor), false, LOT_NONE, 1, sizeof(f32) }, + { "entryRippleDecay", LVT_F32, offsetof(struct Painting, entryRippleDecay), false, LOT_NONE, 1, sizeof(f32) }, + { "entryRippleMag", LVT_F32, offsetof(struct Painting, entryRippleMag), false, LOT_NONE, 1, sizeof(f32) }, + { "entryRippleRate", LVT_F32, offsetof(struct Painting, entryRippleRate), false, LOT_NONE, 1, sizeof(f32) }, + { "floorEntered", LVT_S8, offsetof(struct Painting, floorEntered), false, LOT_NONE, 1, sizeof(s8) }, + { "id", LVT_S16, offsetof(struct Painting, id), true, LOT_NONE, 1, sizeof(s16) }, + { "imageCount", LVT_S8, offsetof(struct Painting, imageCount), true, LOT_NONE, 1, sizeof(s8) }, + { "lastFloor", LVT_S8, offsetof(struct Painting, lastFloor), false, LOT_NONE, 1, sizeof(s8) }, + { "marioIsUnder", LVT_S8, offsetof(struct Painting, marioIsUnder), false, LOT_NONE, 1, sizeof(s8) }, + { "marioWasUnder", LVT_S8, offsetof(struct Painting, marioWasUnder), false, LOT_NONE, 1, sizeof(s8) }, + { "marioWentUnder", LVT_S8, offsetof(struct Painting, marioWentUnder), false, LOT_NONE, 1, sizeof(s8) }, + { "passiveDispersionFactor", LVT_F32, offsetof(struct Painting, passiveDispersionFactor), false, LOT_NONE, 1, sizeof(f32) }, + { "passiveRippleDecay", LVT_F32, offsetof(struct Painting, passiveRippleDecay), false, LOT_NONE, 1, sizeof(f32) }, + { "passiveRippleMag", LVT_F32, offsetof(struct Painting, passiveRippleMag), false, LOT_NONE, 1, sizeof(f32) }, + { "passiveRippleRate", LVT_F32, offsetof(struct Painting, passiveRippleRate), false, LOT_NONE, 1, sizeof(f32) }, + { "pitch", LVT_F32, offsetof(struct Painting, pitch), false, LOT_NONE, 1, sizeof(f32) }, + { "posX", LVT_F32, offsetof(struct Painting, posX), false, LOT_NONE, 1, sizeof(f32) }, + { "posY", LVT_F32, offsetof(struct Painting, posY), false, LOT_NONE, 1, sizeof(f32) }, + { "posZ", LVT_F32, offsetof(struct Painting, posZ), false, LOT_NONE, 1, sizeof(f32) }, + { "rippleDecay", LVT_F32, offsetof(struct Painting, rippleDecay), false, LOT_NONE, 1, sizeof(f32) }, + { "rippleTimer", LVT_F32, offsetof(struct Painting, rippleTimer), false, LOT_NONE, 1, sizeof(f32) }, + { "rippleTrigger", LVT_S8, offsetof(struct Painting, rippleTrigger), false, LOT_NONE, 1, sizeof(s8) }, + { "rippleX", LVT_F32, offsetof(struct Painting, rippleX), false, LOT_NONE, 1, sizeof(f32) }, + { "rippleY", LVT_F32, offsetof(struct Painting, rippleY), false, LOT_NONE, 1, sizeof(f32) }, + { "size", LVT_F32, offsetof(struct Painting, size), false, LOT_NONE, 1, sizeof(f32) }, + { "state", LVT_S8, offsetof(struct Painting, state), false, LOT_NONE, 1, sizeof(s8) }, + { "textureArray", LVT_TEXTURE_P, offsetof(struct Painting, textureArray), true, LOT_POINTER, 2, sizeof(const Texture*) }, + { "textureHeight", LVT_S16, offsetof(struct Painting, textureHeight), true, LOT_NONE, 1, sizeof(s16) }, + { "textureType", LVT_S8, offsetof(struct Painting, textureType), true, LOT_NONE, 1, sizeof(s8) }, + { "textureWidth", LVT_S16, offsetof(struct Painting, textureWidth), true, LOT_NONE, 1, sizeof(s16) }, + { "yaw", LVT_F32, offsetof(struct Painting, yaw), false, LOT_NONE, 1, sizeof(f32) }, }; #define LUA_PAINTING_MESH_VERTEX_FIELD_COUNT 2 @@ -2746,6 +2802,12 @@ static struct LuaObjectField sStarsNeededForDialogFields[LUA_STARS_NEEDED_FOR_DI { "dialog6", LVT_U16, offsetof(struct StarsNeededForDialog, dialog6), false, LOT_NONE, 1, sizeof(u16) }, }; +#define LUA_STATIC_OBJECT_COLLISION_FIELD_COUNT 2 +static struct LuaObjectField sStaticObjectCollisionFields[LUA_STATIC_OBJECT_COLLISION_FIELD_COUNT] = { + { "index", LVT_U32, offsetof(struct StaticObjectCollision, index), true, LOT_NONE, 1, sizeof(u32) }, + { "length", LVT_U16, offsetof(struct StaticObjectCollision, length), true, LOT_NONE, 1, sizeof(u16) }, +}; + #define LUA_SURFACE_FIELD_COUNT 16 static struct LuaObjectField sSurfaceFields[LUA_SURFACE_FIELD_COUNT] = { { "flags", LVT_S8, offsetof(struct Surface, flags), false, LOT_NONE, 1, sizeof(s8) }, @@ -2768,11 +2830,11 @@ static struct LuaObjectField sSurfaceFields[LUA_SURFACE_FIELD_COUNT] = { #define LUA_TEXTURE_INFO_FIELD_COUNT 5 static struct LuaObjectField sTextureInfoFields[LUA_TEXTURE_INFO_FIELD_COUNT] = { - { "bitSize", LVT_U8, offsetof(struct TextureInfo, bitSize), true, LOT_NONE, 1, sizeof(u8) }, - { "height", LVT_U32, offsetof(struct TextureInfo, height), true, LOT_NONE, 1, sizeof(u32) }, - { "name", LVT_STRING_P, offsetof(struct TextureInfo, name), true, LOT_NONE, 1, sizeof(const char*) }, - { "texture", LVT_U8_P, offsetof(struct TextureInfo, texture), true, LOT_POINTER, 1, sizeof(u8*) }, - { "width", LVT_U32, offsetof(struct TextureInfo, width), true, LOT_NONE, 1, sizeof(u32) }, + { "bitSize", LVT_U8, offsetof(struct TextureInfo, bitSize), true, LOT_NONE, 1, sizeof(u8) }, + { "height", LVT_U32, offsetof(struct TextureInfo, height), true, LOT_NONE, 1, sizeof(u32) }, + { "name", LVT_STRING_P, offsetof(struct TextureInfo, name), true, LOT_NONE, 1, sizeof(const char*) }, + { "texture", LVT_TEXTURE_P, offsetof(struct TextureInfo, texture), true, LOT_POINTER, 1, sizeof(Texture*) }, + { "width", LVT_U32, offsetof(struct TextureInfo, width), true, LOT_NONE, 1, sizeof(u32) }, }; #define LUA_TRANSITION_INFO_FIELD_COUNT 9 @@ -2984,6 +3046,7 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN] { LOT_SPAWNPARTICLESINFO, sSpawnParticlesInfoFields, LUA_SPAWN_PARTICLES_INFO_FIELD_COUNT }, { LOT_STARPOSITIONS, sStarPositionsFields, LUA_STAR_POSITIONS_FIELD_COUNT }, { LOT_STARSNEEDEDFORDIALOG, sStarsNeededForDialogFields, LUA_STARS_NEEDED_FOR_DIALOG_FIELD_COUNT }, + { LOT_STATICOBJECTCOLLISION, sStaticObjectCollisionFields, LUA_STATIC_OBJECT_COLLISION_FIELD_COUNT }, { LOT_SURFACE, sSurfaceFields, LUA_SURFACE_FIELD_COUNT }, { LOT_TEXTUREINFO, sTextureInfoFields, LUA_TEXTURE_INFO_FIELD_COUNT }, { LOT_TRANSITIONINFO, sTransitionInfoFields, LUA_TRANSITION_INFO_FIELD_COUNT }, @@ -3114,6 +3177,7 @@ const char *sLuaLotNames[] = { [LOT_SPAWNPARTICLESINFO] = "SpawnParticlesInfo", [LOT_STARPOSITIONS] = "StarPositions", [LOT_STARSNEEDEDFORDIALOG] = "StarsNeededForDialog", + [LOT_STATICOBJECTCOLLISION] = "StaticObjectCollision", [LOT_SURFACE] = "Surface", [LOT_TEXTUREINFO] = "TextureInfo", [LOT_TRANSITIONINFO] = "TransitionInfo", diff --git a/src/pc/lua/smlua_cobject_autogen.h b/src/pc/lua/smlua_cobject_autogen.h index b5ec35d19..a79378a98 100644 --- a/src/pc/lua/smlua_cobject_autogen.h +++ b/src/pc/lua/smlua_cobject_autogen.h @@ -123,6 +123,7 @@ enum LuaObjectAutogenType { LOT_SPAWNPARTICLESINFO, LOT_STARPOSITIONS, LOT_STARSNEEDEDFORDIALOG, + LOT_STATICOBJECTCOLLISION, LOT_SURFACE, LOT_TEXTUREINFO, LOT_TRANSITIONINFO, diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index f4ebbea66..3f2c1b199 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -1544,6 +1544,7 @@ char gSmluaConstants[] = "" "GRAPH_RENDER_CYLBOARD=(1 << 6)\n" "GRAPH_RENDER_PLAYER=(1 << 7)\n" "GRAPH_EXTRA_FORCE_3D=(1 << 0)\n" +"GRAPH_EXTRA_ROTATE_HELD=(1 << 1)\n" "GRAPH_NODE_TYPE_FUNCTIONAL=0x100\n" "GRAPH_NODE_TYPE_400=0x400\n" "GRAPH_NODE_TYPE_ROOT=0x001\n" @@ -2238,9 +2239,11 @@ char gSmluaConstants[] = "" "GRAB_POS_LIGHT_OBJ=1\n" "GRAB_POS_HEAVY_OBJ=2\n" "GRAB_POS_BOWSER=3\n" -"MOD_FS_MAX_SIZE=0x1000000\n" -"MOD_FS_MAX_FILES=0x100\n" +"MOD_FS_MAX_SIZE=0x2000000\n" +"MOD_FS_MAX_FILES=0x200\n" "MOD_FS_MAX_PATH=0x100\n" +"MOD_FS_URI_PREFIX='modfs:/'\n" +"MOD_FS_URI_FORMAT='modfs:/%s/%s'\n" "INT_TYPE_U8=0\n" "INT_TYPE_U16=1\n" "INT_TYPE_U32=2\n" @@ -2977,6 +2980,7 @@ char gSmluaConstants[] = "" "L_CBUTTONS=CONT_C\n" "R_CBUTTONS=CONT_F\n" "D_CBUTTONS=CONT_D\n" +"PALETTES_DIRECTORY='palettes'\n" "MAX_PRESET_PALETTES=128\n" "PANTS=0\n" "SHIRT=1\n" @@ -4542,6 +4546,7 @@ char gSmluaConstants[] = "" "SURFACE_CLASS_NOT_SLIPPERY=0x0015\n" "SURFACE_FLAG_DYNAMIC=(1 << 0)\n" "SURFACE_FLAG_NO_CAM_COLLISION=(1 << 1)\n" +"SURFACE_FLAG_INTANGIBLE=(1 << 2)\n" "SURFACE_FLAG_X_PROJECTION=(1 << 3)\n" "HAZARD_TYPE_LAVA_FLOOR=1\n" "HAZARD_TYPE_LAVA_WALL=2\n" @@ -4619,5 +4624,7 @@ char gSmluaConstants[] = "" "VERSION_TEXT='v'\n" "VERSION_NUMBER=41\n" "MINOR_VERSION_NUMBER=0\n" +"GAME_NAME='sm64coopdx'\n" +"WINDOW_NAME='Super Mario 64 Coop Deluxe'\n" "MAX_VERSION_LENGTH=128\n" ; \ No newline at end of file diff --git a/src/pc/lua/smlua_functions.c b/src/pc/lua/smlua_functions.c index 1aba4cb47..aae860717 100644 --- a/src/pc/lua/smlua_functions.c +++ b/src/pc/lua/smlua_functions.c @@ -10,6 +10,7 @@ #include "game/mario_actions_stationary.h" #include "audio/external.h" #include "object_fields.h" +#include "level_commands.h" #include "engine/math_util.h" #include "engine/level_script.h" #include "pc/djui/djui_hud_utils.h" @@ -433,7 +434,7 @@ int smlua_func_get_texture_info(lua_State* L) { lua_newtable(L); lua_pushstring(L, "texture"); - smlua_push_pointer(L, LVT_U8_P, texInfo.texture, NULL); + smlua_push_pointer(L, LVT_TEXTURE_P, texInfo.texture, NULL); lua_settable(L, -3); lua_pushstring(L, "bitSize"); @@ -492,6 +493,30 @@ struct LuaLevelScriptParse { struct LuaLevelScriptParse sLevelScriptParse = { 0 }; +static bool smlua_func_level_find_lua_param(u64 *param, void *cmd, u32 offset, u32 luaParams, u32 luaParamFlag) { + *param = dynos_level_cmd_get(cmd, offset); + if (luaParams & luaParamFlag) { + const char *paramStr = dynos_level_get_token(*param); + gSmLuaConvertSuccess = true; + *param = smlua_get_integer_mod_variable(gLevelScriptModIndex, paramStr); + if (!gSmLuaConvertSuccess) { + gSmLuaConvertSuccess = true; + *param = smlua_get_any_integer_mod_variable(paramStr); + } + if (!gSmLuaConvertSuccess) { + return false; + } + } + return true; +} + +#define smlua_func_level_get_lua_param(name, ptype, flag) \ + u64 name##Param; \ + if (!smlua_func_level_find_lua_param(&name##Param, cmd, flag##_OFFSET(type), luaParams, flag)) { \ + break; \ + } \ + ptype name = (ptype) name##Param; + s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) { u32 areaIndex, bhvId, bhvArgs, bhvModelId; s16 bhvPosX, bhvPosY, bhvPosZ; @@ -513,7 +538,7 @@ s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) { const BehaviorScript *bhvPtr = (const BehaviorScript *) dynos_level_cmd_get(cmd, 20); if (bhvPtr) { bhvId = get_id_from_behavior(bhvPtr); - if (bhvId == id_bhv1Up) { + if (bhvId == id_bhv_max_count) { bhvId = get_id_from_vanilla_behavior(bhvPtr); // for behaviors with no id in the script (e.g. bhvInstantActiveWarp) } bhvArgs = dynos_level_cmd_get(cmd, 16); @@ -529,54 +554,46 @@ s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) { } break; // OBJECT_EXT, OBJECT_WITH_ACTS_EXT - case 0x3F: { - if (gLevelScriptModIndex != -1) { - const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 20)); - if (bhvStr) { - gSmLuaConvertSuccess = true; - bhvId = smlua_get_integer_mod_variable(gLevelScriptModIndex, bhvStr); - if (!gSmLuaConvertSuccess) { - gSmLuaConvertSuccess = true; - bhvId = smlua_get_any_integer_mod_variable(bhvStr); - } - if (gSmLuaConvertSuccess) { - bhvArgs = dynos_level_cmd_get(cmd, 16); - bhvModelId = dynos_level_cmd_get(cmd, 3); - bhvPosX = dynos_level_cmd_get(cmd, 4); - bhvPosY = dynos_level_cmd_get(cmd, 6); - bhvPosZ = dynos_level_cmd_get(cmd, 8); - bhvPitch = (dynos_level_cmd_get(cmd, 10) * 0x8000) / 180; - bhvYaw = (dynos_level_cmd_get(cmd, 12) * 0x8000) / 180; - bhvRoll = (dynos_level_cmd_get(cmd, 14) * 0x8000) / 180; - bhv = true; - } - } - } - } break; - // OBJECT_EXT2, OBJECT_WITH_ACTS_EXT2 - case 0x40: { + // OBJECT_EXT_LUA_PARAMS + case 0x3F: + case 0x40: + case 0x43: { if (gLevelScriptModIndex != -1) { - const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 24)); - if (bhvStr) { - gSmLuaConvertSuccess = true; - bhvId = smlua_get_integer_mod_variable(gLevelScriptModIndex, bhvStr); - if (!gSmLuaConvertSuccess) { - gSmLuaConvertSuccess = true; - bhvId = smlua_get_any_integer_mod_variable(bhvStr); - } - if (gSmLuaConvertSuccess) { - bhvArgs = dynos_level_cmd_get(cmd, 16); - bhvModelId = dynos_level_cmd_get(cmd, 3); - bhvPosX = dynos_level_cmd_get(cmd, 4); - bhvPosY = dynos_level_cmd_get(cmd, 6); - bhvPosZ = dynos_level_cmd_get(cmd, 8); - bhvPitch = (dynos_level_cmd_get(cmd, 10) * 0x8000) / 180; - bhvYaw = (dynos_level_cmd_get(cmd, 12) * 0x8000) / 180; - bhvRoll = (dynos_level_cmd_get(cmd, 14) * 0x8000) / 180; - bhv = true; + u16 luaParams = ( + type == 0x3F ? OBJECT_EXT_LUA_BEHAVIOR : ( + type == 0x40 ? OBJECT_EXT_LUA_BEHAVIOR | OBJECT_EXT_LUA_MODEL : ( + dynos_level_cmd_get(cmd, 2) + ))); + + smlua_func_level_get_lua_param(modelId, u32, OBJECT_EXT_LUA_MODEL); + smlua_func_level_get_lua_param(posX, s16, OBJECT_EXT_LUA_POS_X); + smlua_func_level_get_lua_param(posY, s16, OBJECT_EXT_LUA_POS_Y); + smlua_func_level_get_lua_param(posZ, s16, OBJECT_EXT_LUA_POS_Z); + smlua_func_level_get_lua_param(angleX, s16, OBJECT_EXT_LUA_ANGLE_X); + smlua_func_level_get_lua_param(angleY, s16, OBJECT_EXT_LUA_ANGLE_Y); + smlua_func_level_get_lua_param(angleZ, s16, OBJECT_EXT_LUA_ANGLE_Z); + smlua_func_level_get_lua_param(behParam, u32, OBJECT_EXT_LUA_BEH_PARAMS); + smlua_func_level_get_lua_param(behavior, uintptr_t, OBJECT_EXT_LUA_BEHAVIOR); + + bhvArgs = behParam; + bhvModelId = modelId; + bhvPosX = posX; + bhvPosY = posY; + bhvPosZ = posZ; + bhvPitch = angleX; + bhvYaw = angleY; + bhvRoll = angleZ; + if (luaParams & OBJECT_EXT_LUA_BEHAVIOR) { + bhvId = (u32) behavior; + } else { + bhvId = get_id_from_behavior((const BehaviorScript *) behavior); + if (bhvId == id_bhv_max_count) { + bhvId = get_id_from_vanilla_behavior((const BehaviorScript *) behavior); } } + + bhv = true; } } break; diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 521a08a18..a76b089fb 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -22481,53 +22481,6 @@ int smlua_func_mod_fs_create(UNUSED lua_State* L) { return 1; } -int smlua_func_mod_fs_delete(UNUSED lua_State* L) { - if (L == NULL) { return 0; } - - int top = lua_gettop(L); - if (top != 0) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_delete", 0, top); - return 0; - } - - - lua_pushboolean(L, mod_fs_delete()); - - return 1; -} - -int smlua_func_mod_fs_save(UNUSED lua_State* L) { - if (L == NULL) { return 0; } - - int top = lua_gettop(L); - if (top != 0) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_save", 0, top); - return 0; - } - - - lua_pushboolean(L, mod_fs_save()); - - return 1; -} - -int smlua_func_mod_fs_set_public(lua_State* L) { - if (L == NULL) { return 0; } - - int top = lua_gettop(L); - if (top != 1) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_set_public", 1, top); - return 0; - } - - bool pub = smlua_to_boolean(L, 1); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mod_fs_set_public"); return 0; } - - lua_pushboolean(L, mod_fs_set_public(pub)); - - return 1; -} - int smlua_func_mod_fs_get_filename(lua_State* L) { if (L == NULL) { return 0; } @@ -22669,6 +22622,59 @@ int smlua_func_mod_fs_clear(lua_State* L) { return 1; } +int smlua_func_mod_fs_save(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_save", 1, top); + return 0; + } + + struct ModFs* modFs = (struct ModFs*)smlua_to_cobject(L, 1, LOT_MODFS); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mod_fs_save"); return 0; } + + lua_pushboolean(L, mod_fs_save(modFs)); + + return 1; +} + +int smlua_func_mod_fs_delete(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_delete", 1, top); + return 0; + } + + struct ModFs* modFs = (struct ModFs*)smlua_to_cobject(L, 1, LOT_MODFS); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mod_fs_delete"); return 0; } + + lua_pushboolean(L, mod_fs_delete(modFs)); + + return 1; +} + +int smlua_func_mod_fs_set_public(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_set_public", 2, top); + return 0; + } + + struct ModFs* modFs = (struct ModFs*)smlua_to_cobject(L, 1, LOT_MODFS); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mod_fs_set_public"); return 0; } + bool pub = smlua_to_boolean(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "mod_fs_set_public"); return 0; } + + lua_pushboolean(L, mod_fs_set_public(modFs, pub)); + + return 1; +} + int smlua_func_mod_fs_file_read_bool(lua_State* L) { if (L == NULL) { return 0; } @@ -22916,6 +22922,23 @@ int smlua_func_mod_fs_file_seek(lua_State* L) { return 1; } +int smlua_func_mod_fs_file_rewind(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_file_rewind", 1, 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_rewind"); return 0; } + + lua_pushboolean(L, mod_fs_file_rewind(file)); + + return 1; +} + int smlua_func_mod_fs_file_is_eof(lua_State* L) { if (L == NULL) { return 0; } @@ -22973,6 +22996,25 @@ int smlua_func_mod_fs_file_erase(lua_State* L) { return 1; } +int smlua_func_mod_fs_file_set_text_mode(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_text_mode", 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_text_mode"); return 0; } + bool text = smlua_to_boolean(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "mod_fs_file_set_text_mode"); return 0; } + + lua_pushboolean(L, mod_fs_file_set_text_mode(file, text)); + + return 1; +} + int smlua_func_mod_fs_file_set_public(lua_State* L) { if (L == NULL) { return 0; } @@ -23136,6 +23178,21 @@ int smlua_func_mod_storage_load_bool(lua_State* L) { return 1; } +int smlua_func_mod_storage_load_all(UNUSED lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 0) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_storage_load_all", 0, top); + return 0; + } + + + smlua_push_lua_table(L, mod_storage_load_all()); + + return 1; +} + int smlua_func_mod_storage_exists(lua_State* L) { if (L == NULL) { return 0; } @@ -32473,7 +32530,24 @@ int smlua_func_gfx_get_texture(lua_State* L) { Gfx * cmd = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_texture"); return 0; } - smlua_push_pointer(L, LVT_U8_P, (void*)gfx_get_texture(cmd), NULL); + smlua_push_pointer(L, LVT_TEXTURE_P, (void*)gfx_get_texture(cmd), NULL); + + return 1; +} + +int smlua_func_gfx_get_name(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_name", 1, top); + return 0; + } + + Gfx * gfx = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_name"); return 0; } + + lua_pushstring(L, gfx_get_name(gfx)); return 1; } @@ -32622,6 +32696,23 @@ int smlua_func_gfx_delete_all(UNUSED lua_State* L) { return 1; } +int smlua_func_vtx_get_name(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vtx_get_name", 1, top); + return 0; + } + + Vtx * vtx = (Vtx *)smlua_to_cobject(L, 1, LOT_VTX); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vtx_get_name"); return 0; } + + lua_pushstring(L, vtx_get_name(vtx)); + + return 1; +} + int smlua_func_vtx_get_count(lua_State* L) { if (L == NULL) { return 0; } @@ -34367,7 +34458,7 @@ int smlua_func_texture_to_lua_table(lua_State* L) { return 0; } - u8 * tex = (u8 *)smlua_to_cpointer(L, 1, LVT_U8_P); + Texture * tex = (Texture *)smlua_to_cpointer(L, 1, LVT_TEXTURE_P); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "texture_to_lua_table"); return 0; } texture_to_lua_table(tex); @@ -34375,6 +34466,23 @@ int smlua_func_texture_to_lua_table(lua_State* L) { return 1; } +int smlua_func_get_texture_name(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_texture_name", 1, top); + return 0; + } + + Texture * tex = (Texture *)smlua_to_cpointer(L, 1, LVT_TEXTURE_P); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_texture_name"); return 0; } + + lua_pushstring(L, get_texture_name(tex)); + + return 1; +} + ///////////////////////// // smlua_model_utils.h // ///////////////////////// @@ -36434,6 +36542,59 @@ int smlua_func_load_object_collision_model(UNUSED lua_State* L) { return 1; } +int smlua_func_load_static_object_collision(UNUSED lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 0) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "load_static_object_collision", 0, top); + return 0; + } + + + smlua_push_object(L, LOT_STATICOBJECTCOLLISION, load_static_object_collision(), NULL); + + return 1; +} + +int smlua_func_toggle_static_object_collision(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", "toggle_static_object_collision", 2, top); + return 0; + } + + struct StaticObjectCollision* col = (struct StaticObjectCollision*)smlua_to_cobject(L, 1, LOT_STATICOBJECTCOLLISION); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "toggle_static_object_collision"); return 0; } + bool tangible = smlua_to_boolean(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "toggle_static_object_collision"); return 0; } + + toggle_static_object_collision(col, tangible); + + return 1; +} + +int smlua_func_get_static_object_surface(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", "get_static_object_surface", 2, top); + return 0; + } + + struct StaticObjectCollision* col = (struct StaticObjectCollision*)smlua_to_cobject(L, 1, LOT_STATICOBJECTCOLLISION); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_static_object_surface"); return 0; } + u32 index = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "get_static_object_surface"); return 0; } + + smlua_push_object(L, LOT_SURFACE, get_static_object_surface(col, index), NULL); + + return 1; +} + int smlua_func_obj_get_surface_from_index(lua_State* L) { if (L == NULL) { return 0; } @@ -37800,9 +37961,6 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "mod_fs_get", smlua_func_mod_fs_get); smlua_bind_function(L, "mod_fs_reload", smlua_func_mod_fs_reload); smlua_bind_function(L, "mod_fs_create", smlua_func_mod_fs_create); - smlua_bind_function(L, "mod_fs_delete", smlua_func_mod_fs_delete); - smlua_bind_function(L, "mod_fs_save", smlua_func_mod_fs_save); - smlua_bind_function(L, "mod_fs_set_public", smlua_func_mod_fs_set_public); smlua_bind_function(L, "mod_fs_get_filename", smlua_func_mod_fs_get_filename); smlua_bind_function(L, "mod_fs_get_file", smlua_func_mod_fs_get_file); smlua_bind_function(L, "mod_fs_create_file", smlua_func_mod_fs_create_file); @@ -37810,6 +37968,9 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "mod_fs_copy_file", smlua_func_mod_fs_copy_file); smlua_bind_function(L, "mod_fs_delete_file", smlua_func_mod_fs_delete_file); smlua_bind_function(L, "mod_fs_clear", smlua_func_mod_fs_clear); + smlua_bind_function(L, "mod_fs_save", smlua_func_mod_fs_save); + smlua_bind_function(L, "mod_fs_delete", smlua_func_mod_fs_delete); + smlua_bind_function(L, "mod_fs_set_public", smlua_func_mod_fs_set_public); smlua_bind_function(L, "mod_fs_file_read_bool", smlua_func_mod_fs_file_read_bool); smlua_bind_function(L, "mod_fs_file_read_integer", smlua_func_mod_fs_file_read_integer); smlua_bind_function(L, "mod_fs_file_read_number", smlua_func_mod_fs_file_read_number); @@ -37823,9 +37984,11 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "mod_fs_file_write_string", smlua_func_mod_fs_file_write_string); smlua_bind_function(L, "mod_fs_file_write_line", smlua_func_mod_fs_file_write_line); smlua_bind_function(L, "mod_fs_file_seek", smlua_func_mod_fs_file_seek); + smlua_bind_function(L, "mod_fs_file_rewind", smlua_func_mod_fs_file_rewind); smlua_bind_function(L, "mod_fs_file_is_eof", smlua_func_mod_fs_file_is_eof); smlua_bind_function(L, "mod_fs_file_fill", smlua_func_mod_fs_file_fill); 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_hide_errors", smlua_func_mod_fs_hide_errors); smlua_bind_function(L, "mod_fs_get_last_error", smlua_func_mod_fs_get_last_error); @@ -37837,6 +38000,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "mod_storage_load", smlua_func_mod_storage_load); smlua_bind_function(L, "mod_storage_load_number", smlua_func_mod_storage_load_number); smlua_bind_function(L, "mod_storage_load_bool", smlua_func_mod_storage_load_bool); + smlua_bind_function(L, "mod_storage_load_all", smlua_func_mod_storage_load_all); smlua_bind_function(L, "mod_storage_exists", smlua_func_mod_storage_exists); smlua_bind_function(L, "mod_storage_remove", smlua_func_mod_storage_remove); smlua_bind_function(L, "mod_storage_clear", smlua_func_mod_storage_clear); @@ -38365,6 +38529,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "gfx_get_vertex_buffer", smlua_func_gfx_get_vertex_buffer); smlua_bind_function(L, "gfx_get_vertex_count", smlua_func_gfx_get_vertex_count); smlua_bind_function(L, "gfx_get_texture", smlua_func_gfx_get_texture); + smlua_bind_function(L, "gfx_get_name", smlua_func_gfx_get_name); smlua_bind_function(L, "gfx_get_length", smlua_func_gfx_get_length); smlua_bind_function(L, "gfx_get_command", smlua_func_gfx_get_command); smlua_bind_function(L, "gfx_get_next_command", smlua_func_gfx_get_next_command); @@ -38373,6 +38538,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "gfx_resize", smlua_func_gfx_resize); smlua_bind_function(L, "gfx_delete", smlua_func_gfx_delete); smlua_bind_function(L, "gfx_delete_all", smlua_func_gfx_delete_all); + smlua_bind_function(L, "vtx_get_name", smlua_func_vtx_get_name); smlua_bind_function(L, "vtx_get_count", smlua_func_vtx_get_count); smlua_bind_function(L, "vtx_get_vertex", smlua_func_vtx_get_vertex); smlua_bind_function(L, "vtx_get_next_vertex", smlua_func_vtx_get_next_vertex); @@ -38480,6 +38646,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "geo_get_current_camera", smlua_func_geo_get_current_camera); smlua_bind_function(L, "geo_get_current_held_object", smlua_func_geo_get_current_held_object); smlua_bind_function(L, "texture_to_lua_table", smlua_func_texture_to_lua_table); + smlua_bind_function(L, "get_texture_name", smlua_func_get_texture_name); // smlua_model_utils.h smlua_bind_function(L, "smlua_model_util_get_id", smlua_func_smlua_model_util_get_id); @@ -38603,6 +38770,9 @@ void smlua_bind_functions_autogen(void) { // surface_load.h smlua_bind_function(L, "load_object_collision_model", smlua_func_load_object_collision_model); + smlua_bind_function(L, "load_static_object_collision", smlua_func_load_static_object_collision); + smlua_bind_function(L, "toggle_static_object_collision", smlua_func_toggle_static_object_collision); + smlua_bind_function(L, "get_static_object_surface", smlua_func_get_static_object_surface); smlua_bind_function(L, "obj_get_surface_from_index", smlua_func_obj_get_surface_from_index); smlua_bind_function(L, "surface_has_force", smlua_func_surface_has_force); diff --git a/src/pc/lua/smlua_hook_events_autogen.inl b/src/pc/lua/smlua_hook_events_autogen.inl index 84fe42ee5..eb2b7647f 100644 --- a/src/pc/lua/smlua_hook_events_autogen.inl +++ b/src/pc/lua/smlua_hook_events_autogen.inl @@ -1082,13 +1082,13 @@ bool smlua_call_event_hooks_HOOK_ON_DIALOG(s32 dialogID, bool *openDialogBox, co hookResult = true; // return openDialogBox - if (lua_type(L, -1) == LUA_TBOOLEAN) { - *openDialogBox = smlua_to_boolean(L, -1); + if (lua_type(L, -2) == LUA_TBOOLEAN) { + *openDialogBox = smlua_to_boolean(L, -2); } // return dialogTextOverride - if (lua_type(L, -2) == LUA_TSTRING) { - *dialogTextOverride = smlua_to_string(L, -2); + if (lua_type(L, -1) == LUA_TSTRING) { + *dialogTextOverride = smlua_to_string(L, -1); } lua_settop(L, prevTop); diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index f08e156d3..6ec341c05 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -41,10 +41,10 @@ struct LuaHookedEvent { static struct LuaHookedEvent sHookedEvents[HOOK_MAX] = { 0 }; static const char* sLuaHookedEventTypeName[] = { -#define SMLUA_EVENT_HOOK(hookEventType, ...) #hookEventType, +#define SMLUA_EVENT_HOOK(hookEventType, ...) [hookEventType] = #hookEventType, #include "smlua_hook_events.inl" #undef SMLUA_EVENT_HOOK - "HOOK_MAX" + [HOOK_MAX] = "HOOK_MAX" }; int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod, struct ModFile* activeModFile) { @@ -100,6 +100,7 @@ int smlua_hook_event(lua_State* L) { hook->reference[hook->count] = ref; hook->mod[hook->count] = gLuaActiveMod; + hook->modFile[hook->count] = gLuaActiveModFile; hook->count++; return 1; diff --git a/src/pc/lua/smlua_live_reload.c b/src/pc/lua/smlua_live_reload.c index 809572f4d..2b967bfdd 100644 --- a/src/pc/lua/smlua_live_reload.c +++ b/src/pc/lua/smlua_live_reload.c @@ -1,5 +1,6 @@ #include #include "smlua.h" +#include "smlua_require.h" #include "pc/mods/mods.h" #include "pc/mods/mods_utils.h" @@ -343,16 +344,8 @@ static void smlua_reload_module(lua_State *L, struct Mod* mod, struct ModFile *f // only handle loaded Lua modules if (!file->isLoadedLuaModule) { return; } - // build registry key for this mod's loaded table - char registryKey[SYS_MAX_PATH + 16]; - snprintf(registryKey, sizeof(registryKey), "mod_loaded_%s", mod->relativePath); - // get per-mod "loaded" table - lua_getfield(L, LUA_REGISTRYINDEX, registryKey); // ..., loadedTable - if (!lua_istable(L, -1)) { - lua_pop(L, 1); - return; - } + smlua_get_or_create_mod_loaded_table(L, mod); // get the old module table: loadedTable[file->relativePath] lua_getfield(L, -1, file->relativePath); // ..., loadedTable, oldMod diff --git a/src/pc/lua/smlua_require.c b/src/pc/lua/smlua_require.c index 196f8cb76..5852ac54a 100644 --- a/src/pc/lua/smlua_require.c +++ b/src/pc/lua/smlua_require.c @@ -4,47 +4,89 @@ #include "pc/mods/mods_utils.h" #include "pc/fs/fmem.h" +#define LOADING_SENTINEL ((void*)-1) + // table to track loaded modules per mod -static void smlua_init_mod_loaded_table(lua_State* L, const char* modPath) { - // Create a unique registry key for this mod's loaded table - char registryKey[SYS_MAX_PATH + 16]; - snprintf(registryKey, sizeof(registryKey), "mod_loaded_%s", modPath); +void smlua_get_or_create_mod_loaded_table(lua_State* L, struct Mod* mod) { + char registryKey[SYS_MAX_PATH + 16] = ""; + snprintf(registryKey, sizeof(registryKey), "mod_loaded_%s", mod->relativePath); lua_getfield(L, LUA_REGISTRYINDEX, registryKey); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_newtable(L); + lua_pushvalue(L, -1); lua_setfield(L, LUA_REGISTRYINDEX, registryKey); - } else { - lua_pop(L, 1); } } +bool smlua_get_cached_module_result(lua_State* L, struct Mod* mod, struct ModFile* file) { + smlua_get_or_create_mod_loaded_table(L, mod); + lua_getfield(L, -1, file->relativePath); + + if (lua_touserdata(L, -1) == LOADING_SENTINEL) { + LOG_LUA_LINE("loop or previous error loading module '%s'", file->relativePath); + lua_pop(L, 1); // pop sentinel + lua_pushnil(L); + + return true; + } + + if (lua_isnil(L, -1)) { + // not cached + lua_pop(L, 2); // pop nil and loaded table + return false; + } + + // cached, remove loaded table and leave value on top + lua_remove(L, -2); + return true; +} + +void smlua_mark_module_as_loading(lua_State* L, struct Mod* mod, struct ModFile* file) { + smlua_get_or_create_mod_loaded_table(L, mod); + lua_pushlightuserdata(L, LOADING_SENTINEL); + lua_setfield(L, -2, file->relativePath); + lua_pop(L, 1); // pop loaded table +} + +void smlua_cache_module_result(lua_State* L, struct Mod* mod, struct ModFile* file, s32 prevTop) { + if (lua_gettop(L) == prevTop) { + lua_pushboolean(L, 1); + } else if (lua_isnil(L, -1)) { + lua_pop(L, 1); + lua_pushboolean(L, 1); + } + + smlua_get_or_create_mod_loaded_table(L, mod); + + lua_pushvalue(L, -2); // duplicate result + lua_setfield(L, -2, file->relativePath); // loaded[file->relativePath] = result + lua_pop(L, 1); // pop loaded table +} + static struct ModFile* smlua_find_mod_file(const char* moduleName) { - char relativeDir[SYS_MAX_PATH] = ""; + char basePath[SYS_MAX_PATH] = ""; + char absolutePath[SYS_MAX_PATH] = ""; if (!gLuaActiveMod) { return NULL; } + // get the directory of the current file if (gLuaActiveModFile) { - path_get_folder(gLuaActiveModFile->relativePath, relativeDir); + path_get_folder(gLuaActiveModFile->relativePath, basePath); } - bool hasRelativeDir = strlen(relativeDir) > 0; + // resolve moduleName to a path relative to mod root + resolve_relative_path(basePath, moduleName, absolutePath); - struct ModFile* bestPick = NULL; - int bestRelativeDepth = INT_MAX; - int bestTotalDepth = INT_MAX; - bool foundRelativeFile = false; - - char rawName[SYS_MAX_PATH] = ""; char luaName[SYS_MAX_PATH] = ""; char luacName[SYS_MAX_PATH] = ""; - snprintf(rawName, SYS_MAX_PATH, "/%s", moduleName); - snprintf(luaName, SYS_MAX_PATH, "/%s.lua", moduleName); - snprintf(luacName, SYS_MAX_PATH, "/%s.luac", moduleName); + snprintf(luaName, SYS_MAX_PATH, "%s.lua", absolutePath); + snprintf(luacName, SYS_MAX_PATH, "%s.luac", absolutePath); + // since mods' relativePaths are relative to the mod's root, we can do a direct comparison for (int i = 0; i < gLuaActiveMod->fileCount; i++) { struct ModFile* file = &gLuaActiveMod->files[i]; @@ -54,41 +96,17 @@ static struct ModFile* smlua_find_mod_file(const char* moduleName) { } // only consider lua files - if (!str_ends_with(file->relativePath, ".lua") && !str_ends_with(file->relativePath, ".luac")) { + if (!path_ends_with(file->relativePath, ".lua") && !path_ends_with(file->relativePath, ".luac")) { continue; } // check for match - if (!str_ends_with(file->relativePath, rawName) && !str_ends_with(file->relativePath, luaName) && !str_ends_with(file->relativePath, luacName)) { - continue; - } - - // get total path depth - int totalDepth = path_depth(file->relativePath); - - // make sure we never load the old-style lua files with require() - if (totalDepth < 1) { - continue; - } - - // get relative path depth - int relativeDepth = INT_MAX; - if (hasRelativeDir && path_is_relative_to(file->relativePath, relativeDir)) { - relativeDepth = path_depth(file->relativePath + strlen(relativeDir)); - foundRelativeFile = true; - } - - // pick new best - // relative files will always win against absolute files - // other than that, shallower files will win - if (relativeDepth < bestRelativeDepth || (!foundRelativeFile && totalDepth < bestTotalDepth)) { - bestPick = file; - bestRelativeDepth = relativeDepth; - bestTotalDepth = totalDepth; + if (!strcmp(file->relativePath, luaName) || !strcmp(file->relativePath, luacName)) { + return file; } } - return bestPick; + return NULL; } static int smlua_custom_require(lua_State* L) { @@ -96,69 +114,47 @@ static int smlua_custom_require(lua_State* L) { struct Mod* activeMod = gLuaActiveMod; if (!activeMod) { - LOG_LUA("require() called outside of mod context"); + LOG_LUA_LINE("require() called outside of mod context"); return 0; } - // create registry key for this mod's loaded table - char registryKey[SYS_MAX_PATH + 16] = ""; - snprintf(registryKey, sizeof(registryKey), "mod_loaded_%s", activeMod->relativePath); - - // get or create the mod's loaded table - lua_getfield(L, LUA_REGISTRYINDEX, registryKey); - if (lua_isnil(L, -1)) { - lua_pop(L, 1); - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, registryKey); + if (path_ends_with(moduleName, "/") || path_ends_with(moduleName, "\\")) { + LOG_LUA_LINE("cannot require a directory"); + return 0; } // find the file in mod files struct ModFile* file = smlua_find_mod_file(moduleName); if (!file) { - LOG_LUA("module '%s' not found in mod files", moduleName); - lua_pop(L, 1); // pop table + LOG_LUA_LINE("module '%s' not found in mod files", moduleName); return 0; } - // check if module is already loaded - lua_getfield(L, -1, file->relativePath); - if (!lua_isnil(L, -1)) { - // module already loaded, return it - return 1; - } - lua_pop(L, 1); // pop nil value - - // mark module as "loading" to prevent recursion - lua_pushboolean(L, 1); - lua_setfield(L, -2, file->relativePath); - - // cache the previous mod file - struct ModFile* prevModFile = gLuaActiveModFile; - s32 prevTop = lua_gettop(L); - // tag it as a loaded lua module file->isLoadedLuaModule = true; - // load and execute - gLuaActiveModFile = file; - smlua_load_script(activeMod, file, activeMod->index, false); - gLuaActiveModFile = prevModFile; - - // if the module didn't return anything, use true - if (prevTop == lua_gettop(L)) { - lua_pushboolean(L, 1); - } else if (lua_isnil(L, -1)) { - lua_pop(L, 1); - lua_pushboolean(L, 1); + // check cache first + if (smlua_get_cached_module_result(L, activeMod, file)) { + return 1; } - // store in loaded table - lua_pushvalue(L, -1); // duplicate return value - lua_setfield(L, -3, file->relativePath); // loaded[file->relativePath] = return_value + // mark module as "loading" to prevent recursion + smlua_mark_module_as_loading(L, activeMod, file); - // clean up stack - lua_remove(L, -2); + // cache the previous mod file + struct ModFile* prevModFile = gLuaActiveModFile; + + // load and execute + gLuaActiveModFile = file; + s32 prevTop = lua_gettop(L); + + int rc = smlua_load_script(activeMod, file, activeMod->index, false); + + if (rc == LUA_OK) { + smlua_cache_module_result(L, activeMod, file, prevTop); + } + + gLuaActiveModFile = prevModFile; return 1; // return the module value } @@ -179,6 +175,7 @@ void smlua_init_require_system(void) { // initialize loaded tables for each mod for (int i = 0; i < gActiveMods.entryCount; i++) { struct Mod* mod = gActiveMods.entries[i]; - smlua_init_mod_loaded_table(L, mod->relativePath); + smlua_get_or_create_mod_loaded_table(L, mod); + lua_pop(L, 1); // pop loaded table } -} \ No newline at end of file +} diff --git a/src/pc/lua/smlua_require.h b/src/pc/lua/smlua_require.h index dcb8891cb..bb1b38df1 100644 --- a/src/pc/lua/smlua_require.h +++ b/src/pc/lua/smlua_require.h @@ -3,9 +3,11 @@ #include "smlua.h" -void smlua_require_update(lua_State* L); void smlua_bind_custom_require(lua_State* L); -void smlua_reload_module(lua_State *L, struct Mod* mod, struct ModFile *file); +void smlua_get_or_create_mod_loaded_table(lua_State* L, struct Mod* mod); +bool smlua_get_cached_module_result(lua_State* L, struct Mod* mod, struct ModFile* file); +void smlua_mark_module_as_loading(lua_State* L, struct Mod* mod, struct ModFile* file); +void smlua_cache_module_result(lua_State* L, struct Mod* mod, struct ModFile* file, s32 prevTop); void smlua_init_require_system(void); #endif \ No newline at end of file diff --git a/src/pc/lua/smlua_sync_table.c b/src/pc/lua/smlua_sync_table.c index 9fb2ec293..bd3c64f28 100644 --- a/src/pc/lua/smlua_sync_table.c +++ b/src/pc/lua/smlua_sync_table.c @@ -144,7 +144,6 @@ static void smlua_sync_table_call_hook(int syncTableIndex, int keyIndex, int pre // call hook struct Mod* prevActiveMod = gLuaActiveMod; - struct ModFile* prevActiveModFile = gLuaActiveModFile; gLuaActiveMod = mod; gLuaActiveModFile = NULL; @@ -156,7 +155,6 @@ static void smlua_sync_table_call_hook(int syncTableIndex, int keyIndex, int pre } gLuaActiveMod = prevActiveMod; - prevActiveModFile = prevActiveModFile; } lua_pop(L, 1); // pop _hook_on_changed's value @@ -181,12 +179,11 @@ static bool smlua_sync_table_send_field(u8 toLocalIndex, int stackIndex, bool al } // get key - struct LSTNetworkType lntKey = smlua_to_lnt(L, keyIndex); + smlua_to_lnt(L, keyIndex); if (!gSmLuaConvertSuccess) { LOG_LUA_LINE("Error: tried to alter sync table with an invalid key"); return false; } - lntKey = lntKey; //////////////// diff --git a/src/pc/lua/smlua_utils.c b/src/pc/lua/smlua_utils.c index 4018b6f16..496afb87b 100644 --- a/src/pc/lua/smlua_utils.c +++ b/src/pc/lua/smlua_utils.c @@ -156,6 +156,22 @@ LuaFunction smlua_to_lua_function(lua_State* L, int index) { return luaL_ref(L, LUA_REGISTRYINDEX); } +LuaTable smlua_to_lua_table(lua_State* L, int index) { + if (lua_type(L, index) == LUA_TNIL) { + return 0; + } + + if (lua_type(L, index) != LUA_TTABLE) { + LOG_LUA_LINE("smlua_to_lua_table received improper type '%s'", luaL_typename(L, index)); + gSmLuaConvertSuccess = false; + return 0; + } + + gSmLuaConvertSuccess = true; + lua_pushvalue(L, index); + return luaL_ref(L, LUA_REGISTRYINDEX); +} + bool smlua_is_cobject(lua_State* L, int index, UNUSED u16 lot) { return lua_isuserdata(L, index); } @@ -288,7 +304,7 @@ struct TextureInfo *smlua_to_texture_info(lua_State *L, int index) { lua_pushstring(L, "texture"); lua_gettable(L, top + 1); - const u8 *texPtr = smlua_to_cpointer(L, lua_gettop(L), LVT_U8_P); + const Texture *texPtr = smlua_to_cpointer(L, lua_gettop(L), LVT_TEXTURE_P); lua_pop(L, 1); if (!gSmLuaConvertSuccess) { return NULL; } @@ -497,6 +513,14 @@ void smlua_push_table_field(int index, const char* name) { /////////////////////////////////////////////////////////////////////////////////////////// +void smlua_push_lua_table(lua_State* L, LuaTable table) { + if (table != 0) { + lua_rawgeti(L, LUA_REGISTRYINDEX, table); + } else { + lua_pushnil(L); + } +} + void smlua_push_bytestring(lua_State* L, ByteString bytestring) { if (bytestring.bytes) { lua_pushlstring(L, bytestring.bytes, bytestring.length); diff --git a/src/pc/lua/smlua_utils.h b/src/pc/lua/smlua_utils.h index f64286392..6324fc57f 100644 --- a/src/pc/lua/smlua_utils.h +++ b/src/pc/lua/smlua_utils.h @@ -1,10 +1,12 @@ #ifndef SMLUA_UTILS_H #define SMLUA_UTILS_H +#include "smlua.h" #include "src/pc/network/packets/packet.h" extern u8 gSmLuaConvertSuccess; typedef int LuaFunction; +typedef int LuaTable; typedef struct ByteString { const char *bytes; @@ -26,6 +28,7 @@ lua_Number smlua_to_number(lua_State* L, int index); const char* smlua_to_string(lua_State* L, int index); ByteString smlua_to_bytestring(lua_State* L, int index); LuaFunction smlua_to_lua_function(lua_State* L, int index); +LuaTable smlua_to_lua_table(lua_State* L, int index); bool smlua_is_cobject(lua_State* L, int index, u16 lot); void* smlua_to_cobject(lua_State* L, int index, u16 lot); void* smlua_to_cpointer(lua_State* L, int index, u16 lvt); @@ -43,6 +46,7 @@ void smlua_push_string_field(int index, const char* name, const char* val); void smlua_push_nil_field(int index, const char* name); void smlua_push_table_field(int index, const char* name); +void smlua_push_lua_table(lua_State* L, LuaTable table); void smlua_push_bytestring(lua_State* L, ByteString bytestring); void smlua_push_lnt(struct LSTNetworkType* lnt); @@ -68,5 +72,6 @@ void smlua_free(void *ptr, u16 lot); static inline void smlua_free_##name(void *ptr) { smlua_free(ptr, lot); } smlua_free_lot(surface, LOT_SURFACE); +smlua_free_lot(soc, LOT_STATICOBJECTCOLLISION); #endif \ No newline at end of file diff --git a/src/pc/lua/utils/smlua_audio_utils.c b/src/pc/lua/utils/smlua_audio_utils.c index 2345b0878..03d0fa60c 100644 --- a/src/pc/lua/utils/smlua_audio_utils.c +++ b/src/pc/lua/utils/smlua_audio_utils.c @@ -10,6 +10,7 @@ #include "game/camera.h" #include "engine/math_util.h" #include "pc/mods/mods.h" +#include "pc/mods/mod_fs.h" #include "pc/lua/smlua.h" #include "pc/lua/utils/smlua_audio_utils.h" #include "pc/mods/mods_utils.h" @@ -78,27 +79,37 @@ bool smlua_audio_utils_override(u8 sequenceId, s32* bankId, void** seqData) { return true; } - static u8* buffer = NULL; - static long int length = 0; + u8* buffer = NULL; + u32 length = 0; - FILE* fp = f_open_r(override->filename); - if (!fp) { return false; } - f_seek(fp, 0L, SEEK_END); - length = f_tell(fp); + if (is_mod_fs_file(override->filename)) { + if (!mod_fs_read_file_from_uri(override->filename, (void **) &buffer, &length)) { + return false; + } + } else { + FILE* fp = f_open_r(override->filename); + if (!fp) { return false; } + 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"); + f_close(fp); + f_delete(fp); + return false; + } + + f_seek(fp, 0L, SEEK_SET); + f_read(buffer, length, 1, fp); - buffer = malloc(length+1); - if (buffer == NULL) { - LOG_ERROR("Failed to malloc m64 sound file"); f_close(fp); f_delete(fp); - return false; } - f_seek(fp, 0L, SEEK_SET); - f_read(buffer, length, 1, fp); - - f_close(fp); - f_delete(fp); + if (!buffer || !length) { + return false; + } // cache override->loaded = true; @@ -110,6 +121,17 @@ bool smlua_audio_utils_override(u8 sequenceId, s32* bankId, void** seqData) { return true; } +static void smlua_audio_utils_create_audio_override(u8 sequenceId, u8 bankId, u8 defaultVolume, const char *filepath) { + struct AudioOverride* override = &sAudioOverrides[sequenceId]; + if (override->enabled) { audio_init(); } + smlua_audio_utils_reset(override); + LOG_INFO("Loading audio: %s", filepath); + override->filename = strdup(filepath); + override->enabled = true; + override->bank = bankId; + sound_set_background_music_default_volume(sequenceId, defaultVolume); +} + void smlua_audio_utils_replace_sequence(u8 sequenceId, u8 bankId, u8 defaultVolume, const char* m64Name) { if (gLuaActiveMod == NULL) { return; } if (sequenceId >= MAX_AUDIO_OVERRIDE) { @@ -122,6 +144,11 @@ void smlua_audio_utils_replace_sequence(u8 sequenceId, u8 bankId, u8 defaultVolu return; } + if (is_mod_fs_file(m64Name)) { + smlua_audio_utils_create_audio_override(sequenceId, bankId, defaultVolume, m64Name); + return; + } + char m64path[SYS_MAX_PATH] = { 0 }; if (snprintf(m64path, SYS_MAX_PATH-1, "sound/%s.m64", m64Name) < 0) { LOG_LUA_LINE("Could not concat m64path: %s", m64path); @@ -134,19 +161,8 @@ void smlua_audio_utils_replace_sequence(u8 sequenceId, u8 bankId, u8 defaultVolu char relPath[SYS_MAX_PATH] = { 0 }; snprintf(relPath, SYS_MAX_PATH-1, "%s", file->relativePath); normalize_path(relPath); - if (str_ends_with(relPath, m64path)) { - struct AudioOverride* override = &sAudioOverrides[sequenceId]; - if (override->enabled) { audio_init(); } - smlua_audio_utils_reset(override); - LOG_INFO("Loading audio: %s", file->cachedPath); - override->filename = strdup(file->cachedPath); - override->enabled = true; - override->bank = bankId; -#ifdef VERSION_EU - //sBackgroundMusicDefaultVolume[sequenceId] = defaultVolume; -#else - sound_set_background_music_default_volume(sequenceId, defaultVolume); -#endif + if (path_ends_with(relPath, m64path)) { + smlua_audio_utils_create_audio_override(sequenceId, bankId, defaultVolume, file->cachedPath); return; } } @@ -174,12 +190,12 @@ static void smlua_audio_custom_init(void) { } } -static struct ModAudio* find_mod_audio(struct ModFile* file) { +static struct ModAudio* find_mod_audio(const char *filepath) { struct DynamicPoolNode* node = sModAudioPool->tail; while (node) { struct DynamicPoolNode* prev = node->prev; struct ModAudio* audio = node->ptr; - if (audio->file == file) { return audio; } + if (strcmp(filepath, audio->filepath) == 0) { return audio; } node = prev; } return NULL; @@ -209,7 +225,7 @@ struct ModAudio* audio_load_internal(const char* filename, bool isStream) { const char* fileTypes[] = { ".mp3", ".aiff", ".ogg", NULL }; const char** ft = fileTypes; while (*ft != NULL) { - if (str_ends_with((char*)filename, (char*)*ft)) { + if (path_ends_with(filename, *ft)) { validFileType = true; break; } @@ -220,25 +236,30 @@ struct ModAudio* audio_load_internal(const char* filename, bool isStream) { return NULL; } - // find mod file in mod list - bool foundModFile = false; - struct ModFile* modFile = NULL; - u16 fileCount = gLuaActiveMod->fileCount; - for (u16 i = 0; i < fileCount; i++) { - struct ModFile* file = &gLuaActiveMod->files[i]; - if(str_ends_with(file->relativePath, (char*)filename)) { - foundModFile = true; - modFile = file; - break; + const char *filepath = filename; + if (!is_mod_fs_file(filename)) { + + // find mod file in mod list + bool foundModFile = false; + struct ModFile* modFile = NULL; + u16 fileCount = gLuaActiveMod->fileCount; + for (u16 i = 0; i < fileCount; i++) { + struct ModFile* file = &gLuaActiveMod->files[i]; + if(path_ends_with(file->relativePath, filename)) { + foundModFile = true; + modFile = file; + break; + } } - } - if (!foundModFile) { - LOG_LUA_LINE("Could not find audio file: '%s'", filename); - return NULL; + if (!foundModFile) { + LOG_LUA_LINE("Could not find audio file: '%s'", filename); + return NULL; + } + filepath = modFile->cachedPath; } // find stream in ModAudio list - struct ModAudio* audio = find_mod_audio(modFile); + struct ModAudio* audio = find_mod_audio(filepath); if (audio) { if (isStream == audio->isStream) { return audio; @@ -261,36 +282,52 @@ struct ModAudio* audio_load_internal(const char* filename, bool isStream) { } // remember file - audio->file = modFile; + audio->filepath = strdup(filepath); - // load audio - FILE *f = f_open_r(modFile->cachedPath); - if (!f) { - LOG_ERROR("failed to load audio file '%s': file not found", filename); - return NULL; - } + void *buffer = NULL; + u32 size = 0; - f_seek(f, 0, SEEK_END); - u32 size = f_tell(f); - f_rewind(f); - void *buffer = calloc(size, 1); - if (!buffer) { + if (is_mod_fs_file(filepath)) { + if (!mod_fs_read_file_from_uri(filepath, &buffer, &size)) { + LOG_ERROR("failed to load audio file '%s': an error occurred with modfs", filename); + return NULL; + } + } else { + + // load audio + FILE *f = f_open_r(filepath); + if (!f) { + LOG_ERROR("failed to load audio file '%s': file not found", filename); + return NULL; + } + + f_seek(f, 0, SEEK_END); + size = f_tell(f); + f_rewind(f); + 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); - 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); + if (!buffer || !size) { + LOG_ERROR("failed to load audio file '%s': failed to read audio data", filename); return NULL; } - f_close(f); - f_delete(f); // decode the audio buffer ma_result result = ma_decoder_init_memory(buffer, size, NULL, &audio->decoder); @@ -604,6 +641,7 @@ void audio_custom_shutdown(void) { audio_sample_destroy_copies(audio); } ma_sound_uninit(&audio->sound); + free((void *) audio->filepath); } dynamic_pool_free(sModAudioPool, audio); node = prev; diff --git a/src/pc/lua/utils/smlua_audio_utils.h b/src/pc/lua/utils/smlua_audio_utils.h index 4fc276548..deca8b0d0 100644 --- a/src/pc/lua/utils/smlua_audio_utils.h +++ b/src/pc/lua/utils/smlua_audio_utils.h @@ -22,7 +22,7 @@ struct ModAudioSampleCopies { }; struct ModAudio { - struct ModFile* file; + const char *filepath; ma_sound sound; ma_decoder decoder; void *buffer; diff --git a/src/pc/lua/utils/smlua_gfx_utils.c b/src/pc/lua/utils/smlua_gfx_utils.c index b9d663481..821b42696 100644 --- a/src/pc/lua/utils/smlua_gfx_utils.c +++ b/src/pc/lua/utils/smlua_gfx_utils.c @@ -238,13 +238,19 @@ u16 gfx_get_vertex_count(Gfx *cmd) { return C0(cmd, 12, 8); } -u8 *gfx_get_texture(Gfx *cmd) { +Texture *gfx_get_texture(Gfx *cmd) { if (!cmd) { return 0; } u32 op = GFX_OP(cmd); if (op != G_SETCIMG && op != G_SETZIMG && op != G_SETTIMG) { return 0; } if (cmd->words.w1 == 0) { return 0; } - return (u8 *) cmd->words.w1; + return (Texture *) cmd->words.w1; +} + +const char *gfx_get_name(Gfx *gfx) { + if (!gfx) { return NULL; } + + return dynos_gfx_get_name(gfx); } u32 gfx_get_length(Gfx *gfx) { @@ -349,6 +355,12 @@ void gfx_delete_all() { dynos_gfx_delete_all(); } +const char *vtx_get_name(Vtx *vtx) { + if (!vtx) { return NULL; } + + return dynos_vtx_get_name(vtx); +} + u32 vtx_get_count(Vtx *vtx) { if (!vtx) { return 0; } diff --git a/src/pc/lua/utils/smlua_gfx_utils.h b/src/pc/lua/utils/smlua_gfx_utils.h index 331dcc456..4175188b3 100644 --- a/src/pc/lua/utils/smlua_gfx_utils.h +++ b/src/pc/lua/utils/smlua_gfx_utils.h @@ -67,8 +67,10 @@ Vtx *gfx_get_vertex_buffer(Gfx *cmd); /* |description|Gets the number of vertices from a display list command if it has the op `G_VTX`|descriptionEnd| */ u16 gfx_get_vertex_count(Gfx *cmd); /* |description|Gets the texture from a display list command if it has an image related op|descriptionEnd| */ -u8 *gfx_get_texture(Gfx *cmd); +Texture *gfx_get_texture(Gfx *cmd); +/* |description|Gets the name of a display list|descriptionEnd| */ +const char *gfx_get_name(Gfx *gfx); /* |description|Gets the max length of a display list|descriptionEnd| */ u32 gfx_get_length(Gfx *gfx); /* |description|Gets a command of a display list at position `offset`|descriptionEnd| */ @@ -86,6 +88,8 @@ void gfx_delete(Gfx *gfx); /* |description|Deletes all display lists created by `gfx_create`|descriptionEnd| */ void gfx_delete_all(); +/* |description|Gets the name of a vertex buffer|descriptionEnd| */ +const char *vtx_get_name(Vtx *vtx); /* |description|Gets the max count of vertices of a vertex buffer|descriptionEnd| */ u32 vtx_get_count(Vtx *vtx); /* |description|Gets a vertex of a vertex buffer at position `offset`|descriptionEnd| */ diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c index c57c06d3f..7a469db0a 100644 --- a/src/pc/lua/utils/smlua_misc_utils.c +++ b/src/pc/lua/utils/smlua_misc_utils.c @@ -241,16 +241,16 @@ extern const u8 texture_power_meter_two_segments[]; extern const u8 texture_power_meter_one_segments[]; static struct TextureInfo sPowerMeterTexturesInfo[] = { - { (u8*)texture_power_meter_left_side, "texture_power_meter_left_side", 32, 64, 8 }, - { (u8*)texture_power_meter_right_side, "texture_power_meter_right_side", 32, 64, 8 }, - { (u8*)texture_power_meter_one_segments, "texture_power_meter_one_segments", 32, 32, 8 }, - { (u8*)texture_power_meter_two_segments, "texture_power_meter_two_segments", 32, 32, 8 }, - { (u8*)texture_power_meter_three_segments, "texture_power_meter_three_segments", 32, 32, 8 }, - { (u8*)texture_power_meter_four_segments, "texture_power_meter_four_segments", 32, 32, 8 }, - { (u8*)texture_power_meter_five_segments, "texture_power_meter_five_segments", 32, 32, 8 }, - { (u8*)texture_power_meter_six_segments, "texture_power_meter_six_segments", 32, 32, 8 }, - { (u8*)texture_power_meter_seven_segments, "texture_power_meter_seven_segments", 32, 32, 8 }, - { (u8*)texture_power_meter_full, "texture_power_meter_full", 32, 32, 8 }, + { (Texture*)texture_power_meter_left_side, "texture_power_meter_left_side", 32, 64, 8 }, + { (Texture*)texture_power_meter_right_side, "texture_power_meter_right_side", 32, 64, 8 }, + { (Texture*)texture_power_meter_one_segments, "texture_power_meter_one_segments", 32, 32, 8 }, + { (Texture*)texture_power_meter_two_segments, "texture_power_meter_two_segments", 32, 32, 8 }, + { (Texture*)texture_power_meter_three_segments, "texture_power_meter_three_segments", 32, 32, 8 }, + { (Texture*)texture_power_meter_four_segments, "texture_power_meter_four_segments", 32, 32, 8 }, + { (Texture*)texture_power_meter_five_segments, "texture_power_meter_five_segments", 32, 32, 8 }, + { (Texture*)texture_power_meter_six_segments, "texture_power_meter_six_segments", 32, 32, 8 }, + { (Texture*)texture_power_meter_seven_segments, "texture_power_meter_seven_segments", 32, 32, 8 }, + { (Texture*)texture_power_meter_full, "texture_power_meter_full", 32, 32, 8 }, }; void hud_render_power_meter(s32 health, f32 x, f32 y, f32 width, f32 height) { @@ -539,9 +539,17 @@ void set_environment_region(u8 index, s16 value) { bool mod_file_exists(const char* filename) { if (gLuaActiveMod == NULL) { return false; } + char normPath[SYS_MAX_PATH] = { 0 }; + + if (snprintf(normPath, sizeof(normPath), "%s", filename) < 0) { + LOG_ERROR("Failed to copy filename for normalization: %s", filename); + } + + normalize_path(normPath); + for (s32 i = 0; i < gLuaActiveMod->fileCount; i++) { struct ModFile* file = &gLuaActiveMod->files[i]; - if (!strcmp(file->relativePath, filename)) { + if (!strcmp(file->relativePath, normPath)) { return true; } } @@ -603,7 +611,7 @@ struct GraphNodeHeldObject* geo_get_current_held_object(void) { return gCurGraphNodeHeldObject; } -void texture_to_lua_table(const u8 *tex) { +void texture_to_lua_table(const Texture *tex) { lua_State *L = gLuaState; if (!L || !tex) { return; } @@ -614,7 +622,7 @@ void texture_to_lua_table(const u8 *tex) { if (bpp != 16 && bpp != 32) { return; } u32 bytesPerPixel = bpp / 8; - const u8 *data = texInfo.texture; + const Texture *data = texInfo.texture; u32 texSize = texInfo.width * texInfo.height * bytesPerPixel; lua_newtable(L); @@ -642,3 +650,11 @@ void texture_to_lua_table(const u8 *tex) { lua_rawseti(L, -2, i / bytesPerPixel + 1); } } + +const char *get_texture_name(const Texture *tex) { + struct TextureInfo texInfo; + if (dynos_texture_get_from_data(tex, &texInfo)) { + return texInfo.name; + } + return NULL; +} diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h index b8b5b198b..8332a2d48 100644 --- a/src/pc/lua/utils/smlua_misc_utils.h +++ b/src/pc/lua/utils/smlua_misc_utils.h @@ -252,7 +252,10 @@ struct GraphNodeCamera* geo_get_current_camera(void); /* |description|Gets the current GraphNodeHeldObject|descriptionEnd|*/ struct GraphNodeHeldObject* geo_get_current_held_object(void); -/* |description|Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures.|descriptionEnd|*/ -void texture_to_lua_table(const u8 *tex); +/* |description|Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures|descriptionEnd|*/ +void texture_to_lua_table(const Texture *tex); + +/* |description|Gets the name of the provided texture pointer `tex`|descriptionEnd|*/ +const char *get_texture_name(const Texture *tex); #endif diff --git a/src/pc/mods/mod.c b/src/pc/mods/mod.c index a0e5c817b..aca944c85 100644 --- a/src/pc/mods/mod.c +++ b/src/pc/mods/mod.c @@ -23,7 +23,7 @@ size_t mod_get_lua_size(struct Mod* mod) { for (int i = 0; i < mod->fileCount; i++) { struct ModFile* file = &mod->files[i]; - if (!(str_ends_with(file->relativePath, ".lua") || str_ends_with(file->relativePath, ".luac"))) { continue; } + if (!(path_ends_with(file->relativePath, ".lua") || path_ends_with(file->relativePath, ".luac"))) { continue; } size += file->size; } @@ -161,19 +161,19 @@ void mod_activate(struct Mod* mod) { mod_cache_update(mod, file); } - if (str_ends_with(file->relativePath, ".bin")) { + if (path_ends_with(file->relativePath, ".bin")) { mod_activate_bin(mod, file); } - if (str_ends_with(file->relativePath, ".col")) { + if (path_ends_with(file->relativePath, ".col")) { mod_activate_col(file); } - if (str_ends_with(file->relativePath, ".lvl")) { + if (path_ends_with(file->relativePath, ".lvl")) { mod_activate_lvl(mod, file); } - if (str_ends_with(file->relativePath, ".bhv")) { + if (path_ends_with(file->relativePath, ".bhv")) { mod_activate_bhv(mod, file); } - if (str_ends_with(file->relativePath, ".tex")) { + if (path_ends_with(file->relativePath, ".tex")) { mod_activate_tex(file); } } @@ -245,15 +245,22 @@ static struct ModFile* mod_allocate_file(struct Mod* mod, char* relativePath) { memset(file, 0, sizeof(struct ModFile)); // set relative path - if (snprintf(file->relativePath, SYS_MAX_PATH - 1, "%s", relativePath) < 0) { - LOG_ERROR("Failed to remember relative path '%s'", relativePath); + char normPath[SYS_MAX_PATH] = { 0 }; + if (snprintf(normPath, sizeof(normPath), "%s", relativePath) < 0) { + LOG_ERROR("Failed to copy relative path for normalization: %s", relativePath); + } + + normalize_path(normPath); + + if (snprintf(file->relativePath, SYS_MAX_PATH - 1, "%s", normPath) < 0) { + LOG_ERROR("Failed to remember relative path '%s'", normPath); return NULL; } // figure out full path char fullPath[SYS_MAX_PATH] = { 0 }; if (!mod_file_full_path(fullPath, mod, file)) { - LOG_ERROR("Failed to concat path: '%s' + '%s'", mod->basePath, relativePath); + LOG_ERROR("Failed to concat path: '%s' + '%s'", mod->basePath, normPath); return NULL; } @@ -330,7 +337,7 @@ static bool mod_load_files_dir(struct Mod* mod, char* fullPath, const char* subD bool fileTypeMatch = false; const char** ft = fileTypes; while (*ft != NULL) { - if (str_ends_with(path, (char*)*ft)) { + if (path_ends_with(path, (char*)*ft)) { fileTypeMatch = true; } ft++; @@ -555,7 +562,7 @@ bool mod_load(struct Mods* mods, char* basePath, char* modName) { bool isDirectory = fs_sys_dir_exists(fullPath); // make sure mod is valid - if (str_ends_with(modName, ".lua")) { + if (path_ends_with(modName, ".lua")) { valid = true; } else if (fs_sys_dir_exists(fullPath)) { char tmpPath[SYS_MAX_PATH] = { 0 }; diff --git a/src/pc/mods/mod_fs.cpp b/src/pc/mods/mod_fs.cpp index c141e64e0..1dcfb4305 100644 --- a/src/pc/mods/mod_fs.cpp +++ b/src/pc/mods/mod_fs.cpp @@ -2,20 +2,38 @@ extern "C" { #include "mod_fs.h" #include "src/pc/fs/fs.h" #include "src/pc/mods/mods_utils.h" +#include "pc/utils/miniz/miniz.h" } #include #include #include #include #include +#include "pc/utils/json.hpp" #define C_DEFINE extern "C" -static std::vector sModFsList = {}; -static char sModFsFileReadStringBuf[MOD_FS_MAX_SIZE + 1]; +using json = nlohmann::json; +static const json sEmptyJson = {}; -#define MOD_FS_MAGIC "MODFSSM64COOPDX" -#define MOD_FS_HEADER_SIZE 32 +static std::vector sModFsList = {}; + +#define MOD_FS_DIRECTORY "sav" +#define MOD_FS_EXTENSION ".modfs" +#define MOD_FS_PROPERTIES "properties.json" + +#define MOD_FS_IS_PUBLIC_DEFAULT false +#define MOD_FS_FILE_IS_PUBLIC_DEFAULT false + +static const char *MOD_FS_FILE_ALLOWED_EXTENSIONS[] = { + ".txt", ".json", ".ini", ".sav", // text + ".bin", ".col", // actors + ".bhv", // behaviors + ".tex", ".png", // textures + ".lvl", // levels + ".m64", ".aiff", ".mp3", ".ogg", // audio + NULL +}; // // Error handling @@ -37,7 +55,7 @@ static char sModFsErrorFunction[256]; } #define mod_fs_raise_error(fmt, ...) { \ - snprintf(sModFsLastError, sizeof(sModFsLastError), "%s: " fmt, sModFsErrorFunction, __VA_ARGS__); \ + snprintf(sModFsLastError, sizeof(sModFsLastError), "%s: " fmt, sModFsErrorFunction, ##__VA_ARGS__); \ if (!sModFsHideErrors) { \ LOG_LUA_LINE("%s", sModFsLastError); \ } \ @@ -123,6 +141,119 @@ static FILE *mod_fs_get_file_handle(const char *modPath, const char *mode) { return NULL; } +static int mod_fs_compare_filepaths(const void *l, const void *r) { + const struct ModFsFile *lfile = *((const struct ModFsFile **) l); + const struct ModFsFile *rfile = *((const struct ModFsFile **) r); + return strcmp(lfile->filepath, rfile->filepath); +} + +static bool mod_fs_check_filepath(struct ModFs *modFs, const char *filepath) { + + // check length + u32 filepathLength = strlen(filepath); + if (filepathLength == 0) { + mod_fs_raise_error( + "modPath: %s, filepath: %s - filepath length cannot be 0", modFs->modPath, filepath + ); + return false; + } + if (filepathLength > MOD_FS_MAX_PATH - 1) { + mod_fs_raise_error( + "modPath: %s, filepath: %s - exceeded filepath length: %u (max is: %u)", modFs->modPath, filepath, filepathLength, MOD_FS_MAX_PATH - 1 + ); + return false; + } + + // cannot be called properties.json + if (strcmp(filepath, MOD_FS_PROPERTIES) == 0) { + mod_fs_raise_error( + "modPath: %s, filepath: %s - forbidden filepath: \"" MOD_FS_PROPERTIES "\" is reserved", modFs->modPath, filepath + ); + return false; + } + + // check character validity + // only ascii chars, no control chars, no star, no backslash + for (u32 i = 0; i != filepathLength; ++i) { + char c = filepath[i]; + if (!isascii(c) || iscntrl(c) || c == '*' || c == '\\') { + mod_fs_raise_error( + "modPath: %s, filepath: %s - invalid character at position %d: '%c' (%02X)", modFs->modPath, filepath, i, c, (u8) c + ); + return false; + } + } + + // cannot start with a slash + if (filepath[0] == '/') { + mod_fs_raise_error( + "modPath: %s, filepath: %s - filepath cannot start with a slash '/'", modFs->modPath, filepath + ); + return false; + } + + // cannot end with a slash + if (filepath[filepathLength - 1] == '/') { + mod_fs_raise_error( + "modPath: %s, filepath: %s - filepath cannot end with a slash '/'", modFs->modPath, filepath + ); + return false; + } + + // no two consecutive slashes + if (strstr(filepath, "//")) { + mod_fs_raise_error( + "modPath: %s, filepath: %s - two or more consecutive slashes '/' are not allowed", modFs->modPath, filepath + ); + return false; + } + + // check extension + const char *lastSlash = strrchr(filepath, '/'); + const char *lastDot = strrchr(filepath, '.'); + if (lastDot > lastSlash) { + bool allowedExtension = false; + for (const char **ext = MOD_FS_FILE_ALLOWED_EXTENSIONS; *ext; ext++) { + if (strcasecmp(lastDot, *ext) == 0) { + allowedExtension = true; + break; + } + } + if (!allowedExtension) { + mod_fs_raise_error( + "modPath: %s, filepath: %s - file extension not allowed: %s", modFs->modPath, filepath, lastDot + ); + return false; + } + } + + return true; +} + +static bool mod_fs_check_file_content(struct ModFs *modFs, struct ModFsFile *file) { + if (!file->data.bin || file->size < 4) { + return true; + } + + // Reject Windows executable files + if (memcmp(file->data.bin, "MZ", 2) == 0) { + mod_fs_raise_error( + "modPath: %s, filepath: %s - Binary file cannot start with \"MZ\" bytes", modFs->modPath, file->filepath + ); + return false; + } + + // Reject ELF files + if (memcmp(file->data.bin, "\177ELF", 4) == 0) { + mod_fs_raise_error( + "modPath: %s, filepath: %s - Binary file cannot start with \"\\x7fELF\" bytes", modFs->modPath, file->filepath + ); + return false; + } + + return true; +} + // // ctor, dtor // @@ -132,7 +263,7 @@ static struct ModFs *mod_fs_new() { struct ModFs *modFs = mod_fs_alloc(); if (!modFs) { mod_fs_raise_error( - "failed to allocate modfs object", NULL + "failed to allocate modfs object" ); return NULL; } @@ -141,7 +272,7 @@ static struct ModFs *mod_fs_new() { modFs->files = NULL; modFs->numFiles = 0; modFs->totalSize = 0; - modFs->isPublic = false; + modFs->isPublic = MOD_FS_IS_PUBLIC_DEFAULT; return modFs; } return NULL; @@ -163,30 +294,169 @@ static void mod_fs_destroy(struct ModFs *modFs) { memset(modFs, 0, sizeof(struct ModFs)); } +// +// Properties +// + +template +T mod_fs_get_property_value(const json &property, const T &defaultValue); + +template <> +bool mod_fs_get_property_value(const json &property, const bool &defaultValue) { + if (property.is_boolean()) { + return (bool) 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) { + if (!current->is_object() || !current->contains(key)) { + return sEmptyJson; + } + current = &(*current)[key]; + } + return *current; +} + +template +static T mod_fs_read_property(const json &properties, const std::vector &propertyPath, const T &defaultValue) { + return mod_fs_get_property_value( + mod_fs_get_properties_at(properties, propertyPath), + defaultValue + ); +} + +static bool mod_fs_get_wildcard_tokens(const char *path, char *prefix, char *suffix) { + const char *wildcard = strchr(path, '*'); + if (!wildcard) { + return false; + } + + // Multiple wildcards are not supported + if (strchr(wildcard + 1, '*') != NULL) { + return false; + } + + snprintf(prefix, SYS_MAX_PATH, "%.*s", (s32) (wildcard - path), path); + snprintf(suffix, SYS_MAX_PATH, "%s", wildcard + 1); + return true; +} + +static const json &mod_fs_read_properties_for_filepath(const json &properties, const char *filepath) { + + // Get all files properties + const json &filesProperties = mod_fs_get_properties_at(properties, { "files" }); + if (filesProperties.empty()) { + return sEmptyJson; + } + + // First, check for the exact path + const json &fileProperties = mod_fs_get_properties_at(filesProperties, { filepath }); + if (!fileProperties.empty()) { + return fileProperties; + } + + // If not found, look for wildcards + for (auto it = filesProperties.begin(); it != filesProperties.end(); it++) { + char prefix[SYS_MAX_PATH]; + char suffix[SYS_MAX_PATH]; + if (!mod_fs_get_wildcard_tokens(it.key().c_str(), prefix, suffix)) { + continue; + } + if (str_starts_with(filepath, prefix) && str_ends_with(filepath, suffix)) { + return it.value(); + } + } + + return sEmptyJson; +} + +static json mod_fs_get_properties_json(struct ModFs *modFs) { + json properties; + properties["isPublic"] = modFs->isPublic; + for (u16 i = 0; i != modFs->numFiles; ++i) { + struct ModFsFile *file = modFs->files[i]; + properties["files"][file->filepath] = { + { "isText", file->isText }, + { "isPublic", file->isPublic } + }; + } + return properties; +} + +static bool mod_fs_file_detect_text_mode(struct ModFsFile *file) { + for (u32 i = 0; i != file->size; ++i) { + u8 c = file->data.bin[i]; + if (iscntrl(c) && !isspace(c)) { + return false; + } + } + return true; +} + // // Read // -#define mod_fs_read_raise_error(modFs, f, ...) { \ - mod_fs_destroy(modFs); \ - fclose(f); \ +#define mod_fs_read_return(ret) { \ + if (zipBuf) { free(zipBuf); } \ + if (f) { fclose(f); } \ + mz_zip_reader_end(zip); \ + if (!ret) { mod_fs_destroy(modFs); } \ + return ret; \ +} + +#define mod_fs_read_raise_error(...) { \ mod_fs_raise_error(__VA_ARGS__); \ - return false; \ + mod_fs_read_return(false); \ } -#define mod_fs_read_fread_or_fail(modFs, f, buf, size, count, ...) { \ - if (fread(buf, size, count, f) < count) { \ - mod_fs_read_raise_error(modFs, f, __VA_ARGS__); \ - } \ +#define mod_fs_read_raise_error_zip() { \ + mod_fs_read_raise_error("modPath: %s - cannot read zip file: %s", modFs->modPath, mz_zip_get_error_string(mz_zip_get_last_error(zip))); \ } -static bool mod_fs_read(const char *modPath, struct ModFs *modFs, bool readHeaderOnly) { +static bool mod_fs_read_properties(mz_zip_archive *zip, json &properties, std::string &error) { + properties.clear(); + + // locate file in zip + s32 fileIndex = mz_zip_reader_locate_file(zip, MOD_FS_PROPERTIES, NULL, 0); + if (fileIndex < 0) { + return true; + } + + // read file + size_t fileSize; + void *fileBuf = mz_zip_reader_extract_to_heap(zip, fileIndex, &fileSize, 0); + if (!fileBuf) { + error = "cannot read file \"" MOD_FS_PROPERTIES "\": " + std::string(mz_zip_get_error_string(mz_zip_get_last_error(zip))); + return false; + } + std::string textBuf((const char *) fileBuf, fileSize); + mz_free(fileBuf); + + // parse json + try { + properties = json::parse(textBuf); + } catch (const json::parse_error& e) { + error = e.what(); + return false; + } + + // properties found + return true; +} + +static bool mod_fs_read(const char *modPath, struct ModFs *modFs, bool checkExistenceOnly) { FILE *f = mod_fs_get_file_handle(modPath, "rb"); if (f) { + mz_zip_archive zip[1] = {0}; + void *zipBuf = NULL; // get true modPath and mod if (!mod_fs_get_modpath(modPath, modFs->modPath)) { - mod_fs_read_raise_error(modFs, f, + mod_fs_read_raise_error( "unable to retrieve modPath from %s", modPath ); } @@ -197,147 +467,171 @@ static bool mod_fs_read(const char *modPath, struct ModFs *modFs, bool readHeade modFs->mod = NULL; } - // read magic (last byte is version) - char magic[sizeof(MOD_FS_MAGIC)] = {0}; - mod_fs_read_fread_or_fail(modFs, f, magic, 1, sizeof(magic), - "modPath: %s - cannot read file magic", modFs->modPath - ); - if (memcmp(magic, MOD_FS_MAGIC, sizeof(MOD_FS_MAGIC) - 1) != 0) { - mod_fs_read_raise_error(modFs, f, - "modPath: %s - not a modfs file", modFs->modPath + // read zip file + fseek(f, 0, SEEK_END); + size_t zipSize = ftell(f); + rewind(f); + zipBuf = malloc(zipSize); + if (!zipBuf || fread(zipBuf, 1, zipSize, f) < zipSize) { + mod_fs_read_raise_error( + "modPath: %s - cannot read zip file", modFs->modPath ); } - u8 version = (u8) magic[sizeof(MOD_FS_MAGIC) - 1]; - if (version == 0 || version > MOD_FS_VERSION) { - mod_fs_read_raise_error(modFs, f, - "modPath: %s - invalid version: %u (must be between 1 and %u)", modFs->modPath, version, MOD_FS_VERSION + fclose(f); + f = NULL; + + // initialize zip + if (!mz_zip_reader_init_mem(zip, zipBuf, zipSize, 0)) { + mod_fs_read_raise_error_zip(); + } + + // find and read properties file + json properties; + std::string error; + if (!mod_fs_read_properties(zip, properties, error)) { + mod_fs_read_raise_error( + "modPath: %s - %s", modFs->modPath, error.c_str() ); } - // read header - mod_fs_read_fread_or_fail(modFs, f, &modFs->numFiles, sizeof(modFs->numFiles), 1, - "modPath: %s - cannot read number of files", modFs->modPath - ); - mod_fs_read_fread_or_fail(modFs, f, &modFs->isPublic, sizeof(modFs->isPublic), 1, - "modPath: %s - cannot read public flag", modFs->modPath - ); - - // check validity - if (modFs->numFiles > MOD_FS_MAX_FILES) { - mod_fs_read_raise_error(modFs, f, - "modPath: %s - exceeded number of files: %u (max is: %u)", modFs->modPath, modFs->numFiles, MOD_FS_MAX_FILES - ); - } - - // check access + // check if modfs is public + modFs->isPublic = mod_fs_read_property(properties, { "isPublic" }, MOD_FS_IS_PUBLIC_DEFAULT); if (!mod_fs_is_active_mod(modFs) && !modFs->isPublic) { // don't raise an error, user should not know if a private modfs file exists - mod_fs_destroy(modFs); - fclose(f); - return false; + mod_fs_read_return (false); } - if (readHeaderOnly) { - fclose(f); - return true; + if (checkExistenceOnly) { + mod_fs_read_return (true); } - // padding (empty space for future versions) - if (fseek(f, MOD_FS_HEADER_SIZE, SEEK_SET) != 0) { - mod_fs_read_raise_error(modFs, f, - "modPath: %s - cannot read header", modFs->modPath - ); + modFs->numFiles = 0; + modFs->totalSize = 0; + u32 numFiles = mz_zip_reader_get_num_files(zip); + std::vector files; + + // retrieve files and start building them + // check filename, file size, total size and number of files here + for (u32 i = 0; i != numFiles; ++i) { + mz_zip_archive_file_stat fileStat; + if (!mz_zip_reader_is_file_a_directory(zip, i) && // not a directory + mz_zip_reader_file_stat(zip, i, &fileStat) && // valid file + strcmp(fileStat.m_filename, MOD_FS_PROPERTIES) != 0 // not properties.json + ) { + struct ModFsFile file = {0}; + file.offset = i; + + // check filepath + const char *filepath = fileStat.m_filename; + if (!mod_fs_check_filepath(modFs, filepath)) { + mod_fs_read_raise_error( + "modPath: %s - invalid filepath: %s", modFs->modPath, filepath + ); + } + memcpy(file.filepath, filepath, strlen(filepath)); + + // check file size + if (fileStat.m_uncomp_size > MOD_FS_MAX_SIZE) { + mod_fs_read_raise_error( + "modPath: %s, filepath: %s - exceeded file size: %llu (max is: %u)", modFs->modPath, file.filepath, (u64) fileStat.m_uncomp_size, MOD_FS_MAX_SIZE + ); + } + file.size = file.capacity = fileStat.m_uncomp_size; + + // check total size + modFs->totalSize += file.size; + if (modFs->totalSize > MOD_FS_MAX_SIZE) { + mod_fs_read_raise_error( + "modPath: %s - exceeded total size: %u (max is: %u)", modFs->modPath, modFs->totalSize, MOD_FS_MAX_SIZE + ); + } + + // read isPublic property + const json &fileProperties = mod_fs_read_properties_for_filepath(properties, file.filepath); + file.isPublic = mod_fs_read_property(fileProperties, { "isPublic" }, MOD_FS_FILE_IS_PUBLIC_DEFAULT); + + // skip file if it's private + if (!mod_fs_is_active_mod(modFs) && !file.isPublic) { + continue; + } + + files.push_back(file); + modFs->numFiles++; + + // check number of files + if (modFs->numFiles > MOD_FS_MAX_FILES) { + mod_fs_read_raise_error( + "modPath: %s - exceeded number of files: %u (max is: %u)", modFs->modPath, numFiles, MOD_FS_MAX_FILES + ); + } + } } - // read files and compute total size + // read files data if (modFs->numFiles) { modFs->files = (struct ModFsFile **) calloc(modFs->numFiles, sizeof(struct ModFsFile *)); if (!modFs->files) { - mod_fs_read_raise_error(modFs, f, + mod_fs_read_raise_error( "modPath: %s - failed to allocate buffer for modfs files", modFs->modPath ); } } else { modFs->files = NULL; } - modFs->totalSize = 0; - for (u16 i = 0; i != modFs->numFiles; ++i) { + for (u16 i = 0, j = 0; i != modFs->numFiles; ++i) { + const struct ModFsFile &fileRef = files[i]; - // check filepath length - u16 filepathLength; - mod_fs_read_fread_or_fail(modFs, f, &filepathLength, sizeof(filepathLength), 1, - "modPath: %s - cannot read filepath length", modFs->modPath - ); - if (filepathLength == 0) { - mod_fs_read_raise_error(modFs, f, - "modPath: %s - filepath length cannot be 0", modFs->modPath - ); + // read file + size_t fileSize; + void *fileBuf = mz_zip_reader_extract_to_heap(zip, fileRef.offset, &fileSize, 0); + if (!fileBuf) { + mod_fs_read_raise_error_zip(); } - if (filepathLength > MOD_FS_MAX_PATH - 1) { - mod_fs_read_raise_error(modFs, f, - "modPath: %s - exceeded filepath length: %u (max is: %u)", modFs->modPath, filepathLength, MOD_FS_MAX_PATH - 1 + + // check file size + if (fileSize != fileRef.size) { + mod_fs_read_raise_error( + "modPath: %s, filepath: %s - truncated data: read size is %llu (expected: %u)", modFs->modPath, fileRef.filepath, (u64) fileSize, fileRef.size ); } - // get filename - char filepath[MOD_FS_MAX_PATH] = {0}; - mod_fs_read_fread_or_fail(modFs, f, filepath, sizeof(char), filepathLength, - "modPath: %s - cannot read filepath", modFs->modPath - ); - - // read file header - struct ModFsFile fileHeader = {0}; - mod_fs_read_fread_or_fail(modFs, f, &fileHeader.size, sizeof(fileHeader.size), 1, - "modPath: %s, filepath: %s - cannot read file size", modFs->modPath, filepath - ); - mod_fs_read_fread_or_fail(modFs, f, &fileHeader.isPublic, sizeof(fileHeader.isPublic), 1, - "modPath: %s, filepath: %s - cannot read file public flag", modFs->modPath, filepath - ); - mod_fs_read_fread_or_fail(modFs, f, &fileHeader.isText, sizeof(fileHeader.isText), 1, - "modPath: %s, filepath: %s - cannot read file text flag", modFs->modPath, filepath - ); - - // don't create file if it's private - if (!mod_fs_is_active_mod(modFs) && !fileHeader.isPublic) { - modFs->numFiles--; - i--; - fseek(f, fileHeader.size, SEEK_CUR); - continue; - } - - // create file + // create modfs file struct ModFsFile *file = modFs->files[i] = mod_fs_alloc(); if (!file) { - mod_fs_read_raise_error(modFs, f, + mod_fs_read_raise_error( "modPath: %s, filepath: %s - failed to allocate modfs file object", modFs->modPath, file->filepath ); } - memcpy(file, &fileHeader, sizeof(struct ModFsFile)); - snprintf(file->filepath, MOD_FS_MAX_PATH, "%s", filepath); - modFs->totalSize += file->size; - if (modFs->totalSize > MOD_FS_MAX_SIZE) { - mod_fs_read_raise_error(modFs, f, - "modPath: %s - exceeded total size: %u (max is: %u)", modFs->modPath, modFs->totalSize, MOD_FS_MAX_SIZE - ); - } + memcpy(file, &fileRef, sizeof(struct ModFsFile)); file->offset = 0; - - // read file data - file->capacity = file->size; if (file->size > 0) { file->data.bin = (u8 *) malloc(file->capacity); if (!file->data.bin) { - mod_fs_read_raise_error(modFs, f, + mod_fs_read_raise_error( "modPath: %s, filepath: %s - failed to allocate buffer for modfs file data", modFs->modPath, file->filepath ); } - mod_fs_read_fread_or_fail(modFs, f, file->data.bin, 1, file->size, - "modPath: %s, filepath: %s - cannot read file data", modFs->modPath, file->filepath + memcpy(file->data.bin, fileBuf, file->size); + } + mz_free(fileBuf); + + // read isText property + const bool isText = mod_fs_file_detect_text_mode(file); + const json &fileProperties = mod_fs_read_properties_for_filepath(properties, file->filepath); + file->isText = mod_fs_read_property(fileProperties, { "isText" }, isText); + + // check file content if binary + if (!isText && !mod_fs_check_file_content(modFs, file)) { + mod_fs_read_raise_error( + "modPath: %s, filepath: %s - Invalid file data", modFs->modPath, file->filepath ); } } - fclose(f); - return true; + if (modFs->files) { + qsort(modFs->files, modFs->numFiles, sizeof(struct ModFsFile *), mod_fs_compare_filepaths); + } + + mod_fs_read_return (true); } return false; } @@ -346,50 +640,63 @@ static bool mod_fs_read(const char *modPath, struct ModFs *modFs, bool readHeade // Write // -#define mod_fs_write_fwrite_or_fail(f, buf, size, count) { \ - if (fwrite(buf, size, count, f) < count) { \ - fclose(f); \ - return false; \ - } \ +#define mod_fs_write_raise_error(...) { \ + mod_fs_raise_error("cannot save modfs for the active mod: " __VA_ARGS__); \ + mz_zip_writer_end(zip); \ + fclose(f); \ + return false; \ +} + +#define mod_fs_write_raise_error_zip() { \ + mod_fs_write_raise_error("%s", mz_zip_get_error_string(mz_zip_get_last_error(zip))); \ } static bool mod_fs_write(struct ModFs *modFs) { FILE *f = mod_fs_get_file_handle(modFs->modPath, "wb"); if (f) { + mz_zip_archive zip[1] = {0}; - // magic + version - const u8 version = MOD_FS_VERSION; - mod_fs_write_fwrite_or_fail(f, MOD_FS_MAGIC, 1, sizeof(MOD_FS_MAGIC) - 1); - mod_fs_write_fwrite_or_fail(f, &version, sizeof(u8), 1); + // initialize zip + if (!mz_zip_writer_init_heap(zip, 0, 0)) { + mod_fs_write_raise_error_zip(); + } - // header - mod_fs_write_fwrite_or_fail(f, &modFs->numFiles, sizeof(modFs->numFiles), 1); - mod_fs_write_fwrite_or_fail(f, &modFs->isPublic, sizeof(modFs->isPublic), 1); - - // padding (empty space for future versions) - const u8 padding[MOD_FS_HEADER_SIZE] = {0}; - u32 paddingLength = MOD_FS_HEADER_SIZE - ftell(f); - mod_fs_write_fwrite_or_fail(f, padding, 1, paddingLength); - - // files + // add each modfs file to the zip archive for (u16 i = 0; i != modFs->numFiles; ++i) { struct ModFsFile *file = modFs->files[i]; - // filepath - u16 filepathLength = strlen(file->filepath); - mod_fs_write_fwrite_or_fail(f, &filepathLength, sizeof(filepathLength), 1); - mod_fs_write_fwrite_or_fail(f, file->filepath, sizeof(char), filepathLength); + // check file content before writing if binary + const bool isText = mod_fs_file_detect_text_mode(file); + if (!isText && !mod_fs_check_file_content(modFs, file)) { + mod_fs_write_raise_error( + "filepath: %s - Invalid file data", file->filepath + ); + } - // data - mod_fs_write_fwrite_or_fail(f, &file->size, sizeof(file->size), 1); - mod_fs_write_fwrite_or_fail(f, &file->isPublic, sizeof(file->isPublic), 1); - mod_fs_write_fwrite_or_fail(f, &file->isText, sizeof(file->isText), 1); - if (file->data.bin) { - mod_fs_write_fwrite_or_fail(f, file->data.bin, 1, file->size); + if (!mz_zip_writer_add_mem(zip, file->filepath, file->data.bin, file->size, MZ_BEST_COMPRESSION)) { + 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)) { + mod_fs_write_raise_error_zip(); + } + + // finalize and gets zip archive + void *zipBuf = NULL; + size_t zipSize = 0; + if (!mz_zip_writer_finalize_heap_archive(zip, &zipBuf, &zipSize)) { + mod_fs_write_raise_error_zip(); + } + + // write file and cleanup + fwrite(zipBuf, 1, zipSize, f); + mz_zip_writer_end(zip); + mz_free(zipBuf); fclose(f); + return true; } return false; @@ -413,7 +720,7 @@ static bool mod_fs_check_pointer(T *ptr, const char *typeName) { static bool mod_fs_check_write(struct ModFs *modFs, const char *action) { if (!mod_fs_is_active_mod(modFs)) { mod_fs_raise_error( - "modPath: %s - %s files in other mods modfs is not allowed", modFs->modPath, action + "modPath: %s - %s other mods modfs is not allowed", modFs->modPath, action ); return false; } @@ -430,22 +737,6 @@ static bool mod_fs_file_check_write(struct ModFsFile *file) { return true; } -static bool mod_fs_check_filepath_length(struct ModFs *modFs, u32 filepathLength) { - if (filepathLength == 0) { - mod_fs_raise_error( - "modPath: %s - filepath length cannot be 0", modFs->modPath - ); - return false; - } - if (filepathLength > MOD_FS_MAX_PATH - 1) { - mod_fs_raise_error( - "modPath: %s - exceeded filepath length: %u (max is: %u)", modFs->modPath, filepathLength, MOD_FS_MAX_PATH - 1 - ); - return false; - } - return true; -} - static bool mod_fs_file_check_file_type(struct ModFsFile *file, bool isText, bool write, const char *dataName) { if (file->isText != isText) { mod_fs_raise_error( @@ -472,11 +763,6 @@ static bool mod_fs_file_check_parameter(struct ModFsFile *file, u8 parameter, u8 return true; } - - - - - // // FS management // @@ -501,7 +787,7 @@ static struct ModFs *mod_fs_get_or_load(const char *modPath, bool loadIfNotFound struct ModFs *modFs = mod_fs_alloc(); if (!modFs) { mod_fs_raise_error( - "failed to allocate modfs object", NULL + "failed to allocate modfs object" ); return NULL; } @@ -551,18 +837,17 @@ C_DEFINE struct ModFs *mod_fs_reload(OPTIONAL const char *modPath) { } // reload - return mod_fs_get_or_load(modPath, true); + return mod_fs_get(modPath); } C_DEFINE struct ModFs *mod_fs_create() { mod_fs_reset_last_error(); - struct ModFs *modFs = mod_fs_get_or_load(NULL, false); - if (!modFs) { - modFs = mod_fs_new(); + if (!mod_fs_exists(NULL)) { + struct ModFs *modFs = mod_fs_new(); if (!modFs) { mod_fs_raise_error( - "cannot create modfs for the active mod", NULL + "cannot create modfs for the active mod" ); return NULL; } @@ -572,78 +857,15 @@ C_DEFINE struct ModFs *mod_fs_create() { } mod_fs_raise_error( - "a modfs already exists for the active mod; use `mod_fs_get()` instead", NULL + "a modfs already exists for the active mod; use `mod_fs_get()` instead" ); return NULL; } -C_DEFINE bool mod_fs_delete() { - mod_fs_reset_last_error(); - - struct ModFs *modFs = mod_fs_get_or_load(NULL, true); - if (modFs) { - char filename[SYS_MAX_PATH]; - if (mod_fs_get_physical_filename(modFs->modPath, filename) && fs_sys_file_exists(filename)) { - remove(filename); - } - - sModFsList.erase(std::find(sModFsList.begin(), sModFsList.end(), modFs)); - mod_fs_destroy(modFs); - mod_fs_free(modFs); - return true; - } - - mod_fs_raise_error( - "there is no modfs for the active mod", NULL - ); - return false; -} - -C_DEFINE bool mod_fs_save() { - mod_fs_reset_last_error(); - - struct ModFs *modFs = mod_fs_get_or_load(NULL, true); - if (modFs) { - if (!mod_fs_write(modFs)) { - mod_fs_raise_error( - "cannot save modfs for the active mod", NULL - ); - return false; - } - return true; - } - - mod_fs_raise_error( - "there is no modfs for the active mod; use `mod_fs_create()` to create one", NULL - ); - return false; -} - -C_DEFINE bool mod_fs_set_public(bool pub) { - mod_fs_reset_last_error(); - - struct ModFs *modFs = mod_fs_get_or_load(NULL, true); - if (modFs) { - modFs->isPublic = pub; - return true; - } - - mod_fs_raise_error( - "there is no modfs for the active mod; use `mod_fs_create()` to create one", NULL - ); - return false; -} - // // File management // -static int mod_fs_compare_filepaths(const void *l, const void *r) { - const struct ModFsFile *lfile = (const struct ModFsFile *) l; - const struct ModFsFile *rfile = (const struct ModFsFile *) r; - return strcmp(lfile->filepath, rfile->filepath); -} - C_DEFINE const char *mod_fs_get_filename(struct ModFs *modFs, u16 index) { mod_fs_reset_last_error(); @@ -685,7 +907,7 @@ C_DEFINE struct ModFsFile *mod_fs_create_file(struct ModFs *modFs, const char *f } // cannot create new files in other mods modfs - if (!mod_fs_check_write(modFs, "creating")) { + if (!mod_fs_check_write(modFs, "creating files in")) { return NULL; } @@ -698,8 +920,15 @@ C_DEFINE struct ModFsFile *mod_fs_create_file(struct ModFs *modFs, const char *f } // check filepath - u32 filepathLength = strlen(filepath); - if (!mod_fs_check_filepath_length(modFs, filepathLength)) { + if (!mod_fs_check_filepath(modFs, filepath)) { + return NULL; + } + + // check existing file + if (mod_fs_get_file(modFs, filepath)) { + mod_fs_raise_error( + "modPath: %s - file %s already exists; use `mod_fs_get_file` instead", modFs->modPath, filepath + ); return NULL; } @@ -717,7 +946,7 @@ C_DEFINE struct ModFsFile *mod_fs_create_file(struct ModFs *modFs, const char *f file->capacity = 0; file->offset = 0; file->isText = text; - file->isPublic = false; + file->isPublic = MOD_FS_FILE_IS_PUBLIC_DEFAULT; file->modFs = modFs; // add file and sort by filename @@ -745,13 +974,12 @@ C_DEFINE bool mod_fs_move_file(struct ModFs *modFs, const char *oldpath, const c } // cannot move files in other mods modfs - if (!mod_fs_check_write(modFs, "moving")) { + if (!mod_fs_check_write(modFs, "moving files in")) { return false; } // check new filepath - u32 newpathLength = strlen(newpath); - if (!mod_fs_check_filepath_length(modFs, newpathLength)) { + if (!mod_fs_check_filepath(modFs, newpath)) { return false; } @@ -789,13 +1017,12 @@ C_DEFINE bool mod_fs_copy_file(struct ModFs *modFs, const char *srcpath, const c } // cannot copy files in other mods modfs - if (!mod_fs_check_write(modFs, "copying")) { + if (!mod_fs_check_write(modFs, "copying files in")) { return false; } // check dest filepath - u32 dstpathLength = strlen(dstpath); - if (!mod_fs_check_filepath_length(modFs, dstpathLength)) { + if (!mod_fs_check_filepath(modFs, dstpath)) { return false; } @@ -831,7 +1058,7 @@ C_DEFINE bool mod_fs_copy_file(struct ModFs *modFs, const char *srcpath, const c modFs->totalSize = newTotalSize; // copy file - u8 *buffer = (u8 *) malloc(srcfile->capacity); + u8 *buffer = (u8 *) malloc(srcfile->size); if (!buffer) { mod_fs_raise_error( "modPath: %s, filepath: %s - failed to allocate buffer for modfs file data", modFs->modPath, dstfile->filepath @@ -850,6 +1077,7 @@ C_DEFINE bool mod_fs_copy_file(struct ModFs *modFs, const char *srcpath, const c memcpy(dstfile, srcfile, sizeof(struct ModFsFile)); snprintf(dstfile->filepath, MOD_FS_MAX_PATH, "%s", dstpath); memcpy(buffer, srcfile->data.bin, srcfile->size); + dstfile->size = dstfile->capacity = srcfile->size; dstfile->data.bin = buffer; dstfile->offset = 0; return true; @@ -863,7 +1091,7 @@ C_DEFINE bool mod_fs_delete_file(struct ModFs *modFs, const char *filepath) { } // cannot delete files in other mods modfs - if (!mod_fs_check_write(modFs, "deleting")) { + if (!mod_fs_check_write(modFs, "deleting files in")) { return false; } @@ -898,7 +1126,7 @@ C_DEFINE bool mod_fs_clear(struct ModFs *modFs) { } // cannot delete files in other mods modfs - if (!mod_fs_check_write(modFs, "deleting")) { + if (!mod_fs_check_write(modFs, "deleting files in")) { return false; } @@ -915,6 +1143,60 @@ C_DEFINE bool mod_fs_clear(struct ModFs *modFs) { return true; } +C_DEFINE bool mod_fs_save(struct ModFs *modFs) { + mod_fs_reset_last_error(); + + if (!mod_fs_check_pointer(modFs, "modfs")) { + return false; + } + + // cannot save other mods modfs + if (!mod_fs_check_write(modFs, "saving over")) { + return false; + } + + return mod_fs_write(modFs); +} + +C_DEFINE bool mod_fs_delete(struct ModFs *modFs) { + mod_fs_reset_last_error(); + + if (!mod_fs_check_pointer(modFs, "modfs")) { + return false; + } + + // cannot delete other mods modfs + if (!mod_fs_check_write(modFs, "deleting")) { + return false; + } + + char filename[SYS_MAX_PATH]; + if (mod_fs_get_physical_filename(modFs->modPath, filename) && fs_sys_file_exists(filename)) { + remove(filename); + } + + sModFsList.erase(std::find(sModFsList.begin(), sModFsList.end(), modFs)); + mod_fs_destroy(modFs); + mod_fs_free(modFs); + return true; +} + +C_DEFINE bool mod_fs_set_public(struct ModFs *modFs, bool pub) { + mod_fs_reset_last_error(); + + if (!mod_fs_check_pointer(modFs, "modfs")) { + return false; + } + + // cannot change public flag of other mods modfs + if (!mod_fs_check_write(modFs, "changing public flag of")) { + return false; + } + + modFs->isPublic = pub; + return true; +} + // // Read data // @@ -941,6 +1223,31 @@ static T mod_fs_file_read_data(struct ModFsFile *file, T defaultValue) { return value; } +static const char *mod_fs_file_read_string_buffer(struct ModFsFile *file, u32 length, bool skipNextChar) { + static char *sModFsFileReadStringBuf = NULL; + static u32 sModFsFileReadStringBufLength = 0; + + // grow buffer if needed + if (length > sModFsFileReadStringBufLength) { + free(sModFsFileReadStringBuf); + sModFsFileReadStringBuf = (char *) malloc(length + 1); + if (!sModFsFileReadStringBuf) { + sModFsFileReadStringBufLength = 0; + mod_fs_raise_error( + "modPath: %s, filepath: %s - unable to allocate temporary buffer of length: %u", + file->modFs->modPath, file->filepath, length + ); + return NULL; + } + sModFsFileReadStringBufLength = length; + } + + memcpy(sModFsFileReadStringBuf, file->data.bin + file->offset, length); + sModFsFileReadStringBuf[length] = 0; + file->offset = MIN(file->offset + length + skipNextChar, file->size); + return sModFsFileReadStringBuf; +} + C_DEFINE bool mod_fs_file_read_bool(struct ModFsFile *file) { mod_fs_reset_last_error(); @@ -1041,26 +1348,23 @@ C_DEFINE const char *mod_fs_file_read_string(struct ModFsFile *file) { return NULL; } - memset(sModFsFileReadStringBuf, 0, sizeof(sModFsFileReadStringBuf)); if (mod_fs_file_read_check_eof(file, 1)) { return NULL; } // for text files, returns the whole content from offset if (file->isText) { - memcpy(sModFsFileReadStringBuf, file->data.text + file->offset, file->size - file->offset); - file->offset = file->size; - return sModFsFileReadStringBuf; + return mod_fs_file_read_string_buffer(file, file->size - file->offset, false); } - // for binary, stops at the first NULL char or at the end of the file - char *buf = sModFsFileReadStringBuf; - for (char *c = (char *) (file->data.bin + file->offset); *c && file->offset < file->size; c++, file->offset++, buf++) { - *buf = *c; + // for binary, stops at the first NUL char or at the end of the file + u32 length = 0; + const char *start = (const char *) (file->data.bin + file->offset); + const char *end = (const char *) (file->data.bin + file->size); + for (const char *c = start; *c && c < end; c++) { + length++; } - *buf = 0; - file->offset = MIN(file->offset + 1, file->size); - return sModFsFileReadStringBuf; + return mod_fs_file_read_string_buffer(file, length, true); } C_DEFINE const char *mod_fs_file_read_line(struct ModFsFile *file) { @@ -1075,18 +1379,18 @@ C_DEFINE const char *mod_fs_file_read_line(struct ModFsFile *file) { return 0; } - memset(sModFsFileReadStringBuf, 0, sizeof(sModFsFileReadStringBuf)); if (mod_fs_file_read_check_eof(file, 1)) { return NULL; } - char *buf = sModFsFileReadStringBuf; - for (char *c = file->data.text + file->offset; *c != '\n' && file->offset < file->size; c++, file->offset++, buf++) { - *buf = *c; + // stops at the first newline or at the end of the file + u32 length = 0; + const char *start = (const char *) (file->data.text + file->offset); + const char *end = (const char *) (file->data.text + file->size); + for (const char *c = start; *c != '\n' && c < end; c++) { + length++; } - *buf = 0; - file->offset = MIN(file->offset + 1, file->size); - return sModFsFileReadStringBuf; + return mod_fs_file_read_string_buffer(file, length, true); } // @@ -1108,7 +1412,7 @@ static bool mod_fs_file_write_resize_buffer(struct ModFsFile *file, u32 size) { // resize data buffer if (file->offset + size > file->capacity) { - u32 newCapacity = MAX(file->capacity * 2, 32); + u32 newCapacity = MAX(file->capacity * 2, file->offset + size); u8 *buffer = (u8 *) realloc(file->data.bin, newCapacity); if (!buffer) { mod_fs_raise_error( @@ -1319,6 +1623,17 @@ C_DEFINE bool mod_fs_file_seek(struct ModFsFile *file, s32 offset, enum ModFsFil return true; } +C_DEFINE bool mod_fs_file_rewind(struct ModFsFile *file) { + mod_fs_reset_last_error(); + + if (!mod_fs_check_pointer(file, "modfs file")) { + return false; + } + + file->offset = 0; + return true; +} + C_DEFINE bool mod_fs_file_is_eof(struct ModFsFile *file) { mod_fs_reset_last_error(); @@ -1368,6 +1683,17 @@ C_DEFINE bool mod_fs_file_erase(struct ModFsFile *file, u32 length) { return true; } +C_DEFINE bool mod_fs_file_set_text_mode(struct ModFsFile *file, bool text) { + mod_fs_reset_last_error(); + + if (!mod_fs_check_pointer(file, "modfs file")) { + return false; + } + + file->isText = text; + return true; +} + C_DEFINE bool mod_fs_file_set_public(struct ModFsFile *file, bool pub) { mod_fs_reset_last_error(); @@ -1388,10 +1714,75 @@ C_DEFINE bool mod_fs_file_set_public(struct ModFsFile *file, bool pub) { // Errors // -void mod_fs_hide_errors(bool hide) { +C_DEFINE void mod_fs_hide_errors(bool hide) { sModFsHideErrors = hide; } -const char *mod_fs_get_last_error() { +C_DEFINE const char *mod_fs_get_last_error() { return *sModFsLastError ? sModFsLastError : NULL; } + +// +// Functions used by other C modules, not API +// + +static bool mod_fs_extract_modpath_and_filepath(const char *uri, char *modPath, char *filepath) { + + // check prefix + if (!is_mod_fs_file(uri)) { + return false; + } + + // get modPath + const char *modPathBegin = uri + sizeof(MOD_FS_URI_PREFIX) - 1; + const char *modPathEnd = strchr(modPathBegin, '/'); + if (!modPathEnd) { + return false; + } + snprintf(modPath, SYS_MAX_PATH, "%.*s", (s32) (modPathEnd - modPathBegin), modPathBegin); + + // get filepath + snprintf(filepath, MOD_FS_MAX_PATH, "%s", modPathEnd + 1); + + return true; +} + +C_DEFINE bool mod_fs_read_file_from_uri(const char *uri, void **buffer, u32 *length) { + char modPath[SYS_MAX_PATH]; + char filepath[MOD_FS_MAX_PATH]; + if (!mod_fs_extract_modpath_and_filepath(uri, modPath, filepath)) { + return false; + } + + struct ModFs *modFs = mod_fs_get(modPath); + if (!modFs) { + return false; + } + + struct ModFsFile *file = mod_fs_get_file(modFs, filepath); + if (!file || !file->data.bin || !file->size) { + return false; + } + + *buffer = malloc(file->size); + if (!*buffer) { + return false; + } + memcpy(*buffer, file->data.bin, file->size); + *length = file->size; + return true; +} + +C_DEFINE void mod_fs_shutdown() { + + // Close all modfs + for (auto &modFs : sModFsList) { + mod_fs_destroy(modFs); + mod_fs_free(modFs); + } + sModFsList.clear(); + + // Reset error state + mod_fs_reset_last_error(); + sModFsHideErrors = false; +} diff --git a/src/pc/mods/mod_fs.h b/src/pc/mods/mod_fs.h index 90daa1838..8cd45794f 100644 --- a/src/pc/mods/mod_fs.h +++ b/src/pc/mods/mod_fs.h @@ -4,12 +4,13 @@ #include "types.h" #include "src/pc/lua/smlua.h" -#define MOD_FS_MAX_SIZE 0x1000000 // 16 MB -#define MOD_FS_MAX_FILES 0x100 +#define MOD_FS_MAX_SIZE 0x2000000 // 32 MB +#define MOD_FS_MAX_FILES 0x200 #define MOD_FS_MAX_PATH 0x100 -#define MOD_FS_DIRECTORY "sav" -#define MOD_FS_EXTENSION ".modfs" -#define MOD_FS_VERSION 1 +#define MOD_FS_URI_PREFIX "modfs:/" +#define MOD_FS_URI_FORMAT "modfs:/%s/%s" // modPath, filepath + +#define is_mod_fs_file(filepath) (memcmp(filepath, MOD_FS_URI_PREFIX, sizeof(MOD_FS_URI_PREFIX) - 1) == 0) enum ModFsFileIntType { INT_TYPE_U8, @@ -53,6 +54,26 @@ struct ModFsFile { u32 offset; bool isText; bool isPublic; + + FUNCTION(read_bool, mod_fs_file_read_bool); + FUNCTION(read_integer, mod_fs_file_read_integer); + FUNCTION(read_number, mod_fs_file_read_number); + FUNCTION(read_bytes, mod_fs_file_read_bytes); + FUNCTION(read_string, mod_fs_file_read_string); + FUNCTION(read_line, mod_fs_file_read_line); + FUNCTION(write_bool, mod_fs_file_write_bool); + FUNCTION(write_integer, mod_fs_file_write_integer); + FUNCTION(write_number, mod_fs_file_write_number); + FUNCTION(write_bytes, mod_fs_file_write_bytes); + FUNCTION(write_string, mod_fs_file_write_string); + FUNCTION(write_line, mod_fs_file_write_line); + FUNCTION(seek, mod_fs_file_seek); + FUNCTION(rewind, mod_fs_file_rewind); + FUNCTION(is_eof, mod_fs_file_is_eof); + FUNCTION(fill, mod_fs_file_fill); + FUNCTION(erase, mod_fs_file_erase); + FUNCTION(set_text_mode, mod_fs_file_set_text_mode); + FUNCTION(set_public, mod_fs_file_set_public); }; struct ModFs { @@ -62,6 +83,17 @@ struct ModFs { u16 numFiles; u32 totalSize; bool isPublic; + + FUNCTION(get_filename, mod_fs_get_filename); + FUNCTION(get_file, mod_fs_get_file); + FUNCTION(create_file, mod_fs_create_file); + FUNCTION(move_file, mod_fs_move_file); + FUNCTION(copy_file, mod_fs_copy_file); + FUNCTION(delete_file, mod_fs_delete_file); + FUNCTION(clear, mod_fs_clear); + FUNCTION(save, mod_fs_save); + FUNCTION(delete, mod_fs_delete); + FUNCTION(set_public, mod_fs_set_public); }; /* |description| @@ -84,21 +116,6 @@ Creates a modfs object for the active mod if it doesn't exist. Returns the modfs |descriptionEnd| */ struct ModFs *mod_fs_create(); -/* |description| -Deletes the modfs object of the active mod if it exists. Returns true on success -|descriptionEnd| */ -bool mod_fs_delete(); - -/* |description| -Saves the modfs object of the active mod if it exists. Returns true on success -|descriptionEnd| */ -bool mod_fs_save(); - -/* |description| -Marks the modfs object of the active mod as public (i.e. readable by other mods) if it exists. Returns true on success -|descriptionEnd| */ -bool mod_fs_set_public(bool pub); - /* |description| Gets the filename at position `index` of the provided `modFs` |descriptionEnd| */ @@ -134,6 +151,21 @@ Deletes all files of the provided `modFs`. Returns true on success |descriptionEnd| */ bool mod_fs_clear(struct ModFs *modFs); +/* |description| +Saves the provided `modFs` to persistent storage. Returns true on success +|descriptionEnd| */ +bool mod_fs_save(struct ModFs *modFs); + +/* |description| +Removes the provided `modFs` from persistent storage and deletes its object. Returns true on success +|descriptionEnd| */ +bool mod_fs_delete(struct ModFs *modFs); + +/* |description| +Marks the provided `modFs` as public (i.e. readable by other mods). Returns true on success +|descriptionEnd| */ +bool mod_fs_set_public(struct ModFs *modFs, bool pub); + /* |description| Reads a boolean from a binary modfs `file` |descriptionEnd| */ @@ -203,6 +235,12 @@ Returns true on success |descriptionEnd| */ bool mod_fs_file_seek(struct ModFsFile *file, s32 offset, enum ModFsFileSeek origin); +/* |description| +Sets the current position of a modfs `file` to its beginning. +Returns true on success +|descriptionEnd| */ +bool mod_fs_file_rewind(struct ModFsFile *file); + /* |description| Returns true if the provided modfs `file` has reached its end of file |descriptionEnd| */ @@ -218,6 +256,11 @@ Erases `length` bytes or characters from a modfs `file`. Returns true on success |descriptionEnd| */ bool mod_fs_file_erase(struct ModFsFile *file, u32 length); +/* |description| +Marks the provided modfs `file` as text. Returns true on success +|descriptionEnd| */ +bool mod_fs_file_set_text_mode(struct ModFsFile *file, bool text); + /* |description| Marks the provided modfs `file` as public (i.e. readable by other mods). Returns true on success |descriptionEnd| */ @@ -233,4 +276,9 @@ Returns the last error message generated by `mod_fs` functions or nil if no erro |descriptionEnd| */ const char *mod_fs_get_last_error(); +// Functions used by other C modules, not API + +bool mod_fs_read_file_from_uri(const char *uri, void **buffer, u32 *length); +void mod_fs_shutdown(); + #endif // MOD_FS_H diff --git a/src/pc/mods/mod_import.c b/src/pc/mods/mod_import.c index 116893dad..ad9de35c7 100644 --- a/src/pc/mods/mod_import.c +++ b/src/pc/mods/mod_import.c @@ -124,15 +124,15 @@ static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) { return false; } - if (str_ends_with(file_stat.m_filename, ".lua") || str_ends_with(file_stat.m_filename, ".luac")) { + if (path_ends_with(file_stat.m_filename, ".lua") || path_ends_with(file_stat.m_filename, ".luac")) { path_get_folder(file_stat.m_filename, luaPath); *isLua = true; break; - } else if (str_ends_with(file_stat.m_filename, ".tex")) { + } else if (path_ends_with(file_stat.m_filename, ".tex")) { *isDynos = true; - } else if (str_ends_with(file_stat.m_filename, ".png")) { + } else if (path_ends_with(file_stat.m_filename, ".png")) { *isDynos = true; - } else if (str_ends_with(file_stat.m_filename, ".bin")) { + } else if (path_ends_with(file_stat.m_filename, ".bin")) { *isDynos = true; } } @@ -258,18 +258,18 @@ bool mod_import_file(char* path) { bool isPalette = false; bool ret = false; - if (gNetworkType != NT_NONE && !str_ends_with(path, ".ini")) { + if (gNetworkType != NT_NONE && !path_ends_with(path, ".ini")) { djui_popup_create(DLANG(NOTIF, IMPORT_FAIL_INGAME), 2); return false; } - if (str_ends_with(path, ".lua") || str_ends_with(path, ".luac")) { + if (path_ends_with(path, ".lua") || path_ends_with(path, ".luac")) { isLua = true; ret = mod_import_lua(path); - } else if (str_ends_with(path, ".ini")) { + } else if (path_ends_with(path, ".ini")) { isPalette = true; ret = mod_import_palette(path); - } else if (str_ends_with(path, ".zip")) { + } else if (path_ends_with(path, ".zip")) { ret = mod_import_zip(path, &isLua, &isDynos); } diff --git a/src/pc/mods/mod_storage.cpp b/src/pc/mods/mod_storage.cpp index f75686df3..e64a9ff2a 100644 --- a/src/pc/mods/mod_storage.cpp +++ b/src/pc/mods/mod_storage.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "pc/mini.h" extern "C" { @@ -16,6 +17,8 @@ extern "C" { #define C_FIELD extern "C" +static std::map sModStorageFiles; + static void strdelete(char* string, const char* substr) { // i is used to loop through the string u16 i = 0; @@ -43,7 +46,7 @@ static void strdelete(char* string, const char* substr) { string[i] = '\0'; } -bool char_valid(const char* buffer, bool isKey) { +static bool char_valid(const char* buffer, bool isKey) { if (buffer[0] == '\0') { return false; } while (*buffer != '\0') { @@ -57,7 +60,7 @@ bool char_valid(const char* buffer, bool isKey) { return true; } -void mod_storage_get_filename(char* dest) { +static void mod_storage_get_filename(char* dest) { const char* path = fs_get_write_path(SAVE_DIRECTORY); // get user path snprintf(dest, SYS_MAX_PATH - 1, "%s/%s", path, gLuaActiveMod->relativePath); // append sav folder strdelete(dest, ".lua"); // delete ".lua" from sav name @@ -65,63 +68,63 @@ void mod_storage_get_filename(char* dest) { normalize_path(dest); // fix any out of place slashes } -C_FIELD bool mod_storage_save(const char* key, const char* value) { - if (gLuaActiveMod == NULL) { return false; } - if (strlen(key) > MAX_KEY_VALUE_LENGTH || strlen(value) > MAX_KEY_VALUE_LENGTH) { return false; } - if (!char_valid(key, true) || !char_valid(value, false)) { return false; } +static bool mod_storage_check_inputs(const char *key, const char *value, char *filename) { - char filename[SYS_MAX_PATH] = { 0 }; + // check active mod + if (gLuaActiveMod == NULL) { return false; } + + // retrieve filename mod_storage_get_filename(filename); - // ensure savPath exists - const char* savPath = fs_get_write_path(SAVE_DIRECTORY); - if (!fs_sys_dir_exists(savPath)) { fs_sys_mkdir(savPath); } + // check key validity + if (key != NULL) { + if (strlen(key) > MAX_KEY_VALUE_LENGTH) { return false; } + if (!char_valid(key, true)) { return false; } + } - mINI::INIFile file(filename); - mINI::INIStructure ini; - file.read(ini); + // check value validity + if (value != NULL) { + if (strlen(value) > MAX_KEY_VALUE_LENGTH) { return false; } + if (!char_valid(value, false)) { return false; } - if (ini["storage"].size() > MAX_KEYS) { return false; } + // write: ensure savPath exists + const char* savPath = fs_get_write_path(SAVE_DIRECTORY); + if (!fs_sys_dir_exists(savPath)) { fs_sys_mkdir(savPath); } + } - ini["storage"][key] = value; - - file.write(ini); - file.generate(ini); + // No value == read or delete, check if filename exists + else { + if (!fs_sys_path_exists(filename)) { return false; } + } return true; } -C_FIELD bool mod_storage_save_number(const char* key, f32 value) { - // Store string results in a temporary buffer - // this assumes mod_storage_load will only ever be called by Lua - static char str[MAX_KEY_VALUE_LENGTH]; - if (floor(value) == value) { - snprintf(str, MAX_KEY_VALUE_LENGTH, "%lld", (s64)value); - } else { - snprintf(str, MAX_KEY_VALUE_LENGTH, "%f", value); + ////////// + // read // +////////// + +static mINI::INIStructure &mod_storage_read_file(const char *filename) { + const auto &it = sModStorageFiles.find(filename); + if (it != sModStorageFiles.end()) { + return it->second; } - return mod_storage_save(key, str); -} - -C_FIELD bool mod_storage_save_bool(const char* key, bool value) { - return mod_storage_save(key, value ? "true" : "false"); -} - -C_FIELD const char* mod_storage_load(const char* key) { - if (gLuaActiveMod == NULL) { return NULL; } - if (strlen(key) > MAX_KEY_VALUE_LENGTH) { return NULL; } - if (!char_valid(key, true)) { return NULL; } - - char filename[SYS_MAX_PATH] = { 0 }; - mod_storage_get_filename(filename); - if (!fs_sys_path_exists(filename)) { return NULL; } - mINI::INIFile file(filename); mINI::INIStructure ini; file.read(ini); + sModStorageFiles[filename] = ini; + return sModStorageFiles[filename]; +} - std::string str = ini["storage"][key]; +C_FIELD const char* mod_storage_load(const char* key) { + char filename[SYS_MAX_PATH] = { 0 }; + if (!mod_storage_check_inputs(key, NULL, filename)) { + return NULL; + } + + const mINI::INIStructure &ini = mod_storage_read_file(filename); + std::string str = ini.get("storage").get(key); if (str.empty()) { return NULL; } // Store string results in a temporary buffer @@ -146,35 +149,83 @@ C_FIELD bool mod_storage_load_bool(const char* key) { } C_FIELD bool mod_storage_exists(const char* key) { - if (gLuaActiveMod == NULL) { return false; } - if (strlen(key) > MAX_KEY_VALUE_LENGTH) { return false; } - if (!char_valid(key, true)) { return false; } + return mod_storage_load(key) != NULL; +} + +C_FIELD LuaTable mod_storage_load_all(void) { + struct lua_State *L = gLuaState; + if (!L) { return 0; } char filename[SYS_MAX_PATH] = { 0 }; - mod_storage_get_filename(filename); - if (!fs_sys_path_exists(filename)) { return false; } + if (!mod_storage_check_inputs(NULL, NULL, filename)) { + lua_pushnil(L); + return 0; + } + + const mINI::INIStructure &ini = mod_storage_read_file(filename); + + LUA_STACK_CHECK_BEGIN_NUM(L, 1); + + lua_newtable(L); + for (const auto &kv : ini.get("storage")) { + lua_pushstring(L, kv.first.c_str()); + lua_pushstring(L, kv.second.c_str()); + lua_settable(L, -3); + } + + LUA_STACK_CHECK_END(L); + return smlua_to_lua_table(L, -1); +} + + /////////// + // write // +/////////// + +C_FIELD bool mod_storage_save(const char* key, const char* value) { + char filename[SYS_MAX_PATH] = { 0 }; + if (!mod_storage_check_inputs(key, value, filename)) { + return false; + } + + mINI::INIStructure &ini = mod_storage_read_file(filename); + if (!ini["storage"].has(key) && ini["storage"].size() >= MAX_KEYS) { return false; } + + ini["storage"][key] = value; mINI::INIFile file(filename); - mINI::INIStructure ini; - file.read(ini); + file.write(ini); + file.generate(ini); - return ini["storage"].has(key); + return true; +} + +C_FIELD bool mod_storage_save_number(const char* key, f32 value) { + // Store string results in a temporary buffer + // this assumes mod_storage_load will only ever be called by Lua + static char str[MAX_KEY_VALUE_LENGTH]; + if (floor(value) == value) { + snprintf(str, MAX_KEY_VALUE_LENGTH, "%lld", (s64)value); + } else { + snprintf(str, MAX_KEY_VALUE_LENGTH, "%f", value); + } + + return mod_storage_save(key, str); +} + +C_FIELD bool mod_storage_save_bool(const char* key, bool value) { + return mod_storage_save(key, value ? "true" : "false"); } C_FIELD bool mod_storage_remove(const char* key) { - if (gLuaActiveMod == NULL) { return false; } - if (strlen(key) > MAX_KEY_VALUE_LENGTH) { return false; } - if (!char_valid(key, true)) { return false; } - char filename[SYS_MAX_PATH] = { 0 }; - mod_storage_get_filename(filename); - if (!fs_sys_path_exists(filename)) { return false; } + if (!mod_storage_check_inputs(key, NULL, filename)) { + return false; + } - mINI::INIFile file(filename); - mINI::INIStructure ini; - file.read(ini); + mINI::INIStructure &ini = mod_storage_read_file(filename); if (ini["storage"].remove(key)) { + mINI::INIFile file(filename); file.write(ini); file.generate(ini); return true; @@ -184,22 +235,26 @@ C_FIELD bool mod_storage_remove(const char* key) { } C_FIELD bool mod_storage_clear(void) { - if (gLuaActiveMod == NULL) { return false; } - char filename[SYS_MAX_PATH] = { 0 }; - mod_storage_get_filename(filename); - if (!fs_sys_path_exists(filename)) { return false; } - - mINI::INIFile file(filename); - mINI::INIStructure ini; - file.read(ini); + if (!mod_storage_check_inputs(NULL, NULL, filename)) { + return false; + } + mINI::INIStructure &ini = mod_storage_read_file(filename); if (ini["storage"].size() == 0) { return false; } ini["storage"].clear(); + mINI::INIFile file(filename); file.write(ini); file.generate(ini); return true; } + +C_FIELD void mod_storage_shutdown(void) { + for (auto &file : sModStorageFiles) { + file.second.clear(); + } + sModStorageFiles.clear(); +} diff --git a/src/pc/mods/mod_storage.h b/src/pc/mods/mod_storage.h index 5c337c15e..a3762e3f7 100644 --- a/src/pc/mods/mod_storage.h +++ b/src/pc/mods/mod_storage.h @@ -6,6 +6,7 @@ #ifdef __cplusplus extern "C" { #endif +#include "pc/lua/smlua_utils.h" #define MAX_KEYS 4096 #define MAX_KEY_VALUE_LENGTH 1024 @@ -25,6 +26,8 @@ const char *mod_storage_load(const char* key); f32 mod_storage_load_number(const char* key); /* |description|Loads a bool `value` from a `key` in mod storage|descriptionEnd| */ bool mod_storage_load_bool(const char* key); +/* |description|Loads all keys and values in mod storage as strings and returns them as a table|descriptionEnd| */ +LuaTable mod_storage_load_all(void); /* |description|Checks if a `key` is in mod storage|descriptionEnd| */ bool mod_storage_exists(const char* key); @@ -33,6 +36,8 @@ bool mod_storage_remove(const char* key); /* |description|Clears the mod's data from mod storage|descriptionEnd| */ bool mod_storage_clear(void); +void mod_storage_shutdown(void); + #ifdef __cplusplus } #endif diff --git a/src/pc/mods/mods_utils.c b/src/pc/mods/mods_utils.c index 429a22628..6e8c2bcd9 100644 --- a/src/pc/mods/mods_utils.c +++ b/src/pc/mods/mods_utils.c @@ -160,21 +160,35 @@ bool mod_file_create_directories(struct Mod* mod, struct ModFile* modFile) { ////////////////////////////////////////////////////////////////////////////////////////// -bool str_ends_with(const char* string, const char* suffix) { +bool str_starts_with(const char *string, const char *prefix) { + if (string == NULL || prefix == NULL) { return false; } + + return strncmp(string, prefix, strlen(prefix)) == 0; +} + +bool str_ends_with(const char *string, const char *suffix) { if (string == NULL || suffix == NULL) { return false; } size_t stringLength = strlen(string); size_t suffixLength = strlen(suffix); + return stringLength >= suffixLength && strncmp(string + stringLength - suffixLength, suffix, suffixLength) == 0; +} - if (suffixLength > stringLength) { return false; } +bool path_ends_with(const char* path, const char* suffix) { + if (path == NULL || suffix == NULL) { return false; } + + size_t pathLength = strlen(path); + size_t suffixLength = strlen(suffix); + + if (suffixLength > pathLength) { return false; } #ifdef _WIN32 // Paths on Windows are case-insensitive and might have // upper-case or mixed-case endings. - return (0 == _stricmp(&(string[stringLength - suffixLength]), suffix)); + return (0 == _stricmp(&(path[pathLength - suffixLength]), suffix)); #else // Always expecting lower-case file paths and extensions - return (0 == strcmp(&(string[stringLength - suffixLength]), suffix)); + return (0 == strcmp(&(path[pathLength - suffixLength]), suffix)); #endif } @@ -244,6 +258,47 @@ int path_depth(const char* path) { return depth; } +void resolve_relative_path(const char* base, const char* path, char* output) { + char combined[SYS_MAX_PATH] = ""; + + // If path is absolute, copy as is. Otherwise, combine base and relative path + if (path[0] == '/' || path[0] == '\\') { + snprintf(combined, sizeof(combined), "%s", path); + } else { + snprintf(combined, sizeof(combined), "%s/%s", base, path); + } + + char* tokens[64]; + int tokenCount = 0; + + // Tokenize path by separators + char* token = strtok(combined, "/\\"); + while (token && tokenCount < 64) { + if (strcmp(token, "..") == 0) { + // Pop last token to go up a directory + if (tokenCount > 0) { tokenCount--; } + + // Ignore "." (current directory) or empty tokens + } else if (strcmp(token, ".") != 0 && token[0] != '\0') { + tokens[tokenCount++] = token; + } + + token = strtok(NULL, "/\\"); + } + + output[0] = '\0'; + + // Build output path from tokens + for (int i = 0; i < tokenCount; i++) { + if (i > 0) { + strncat(output, "/", SYS_MAX_PATH - strlen(output) - 1); + } + strncat(output, tokens[i], SYS_MAX_PATH - strlen(output) - 1); + } + + normalize_path(output); +} + bool path_is_relative_to(const char* fullPath, const char* baseDir) { return strncmp(fullPath, baseDir, strlen(baseDir)) == 0; } diff --git a/src/pc/mods/mods_utils.h b/src/pc/mods/mods_utils.h index ad07e8216..493965134 100644 --- a/src/pc/mods/mods_utils.h +++ b/src/pc/mods/mods_utils.h @@ -12,7 +12,10 @@ void mods_delete_tmp(void); bool mod_file_full_path(char* destination, struct Mod* mod, struct ModFile* modFile); bool mod_file_create_directories(struct Mod* mod, struct ModFile* modFile); -bool str_ends_with(const char* string, const char* suffix); +bool str_starts_with(const char *string, const char *prefix); +bool str_ends_with(const char *string, const char *suffix); + +bool path_ends_with(const char* path, const char* suffix); char* extract_lua_field(char* fieldName, char* buffer); @@ -21,6 +24,7 @@ bool concat_path(char* destination, char* path, char* fname); char* path_basename(char* path); void path_get_folder(char* path, char* outpath); int path_depth(const char* path); +void resolve_relative_path(const char* base, const char* path, char* output); bool path_is_relative_to(const char* fullPath, const char* baseDir); bool directory_sanity_check(struct dirent* dir, char* dirPath, char* outPath); diff --git a/src/pc/network/packets/packet_debug_sync.c b/src/pc/network/packets/packet_debug_sync.c index b5d33e6d6..a0ff7d026 100644 --- a/src/pc/network/packets/packet_debug_sync.c +++ b/src/pc/network/packets/packet_debug_sync.c @@ -15,7 +15,6 @@ void print_sync_object_table(void) { if (so->o->oSyncID != so->id) { LOG_INFO("^^^^^^^^^^^^^^^^^^^^^ %u != %u", so->o->oSyncID, so->id); } - behaviorId = behaviorId; // suppress warning } LOG_INFO(" "); } diff --git a/src/pc/network/version.h b/src/pc/network/version.h index cb982a566..6f23a13f7 100644 --- a/src/pc/network/version.h +++ b/src/pc/network/version.h @@ -19,7 +19,7 @@ #endif #ifdef DEVELOPMENT -#define GAME_NAME "sm64coopdx-dev" +#define GAME_NAME "sm64coopdx-dev" #define WINDOW_NAME "Super Mario 64 Coop Deluxe (DEV)" #elif !defined(VERSION_US) #define GAME_NAME "sm64coopdx-intl" diff --git a/src/pc/rom_checker.cpp b/src/pc/rom_checker.cpp index 2024dd0de..ee6e4ce65 100644 --- a/src/pc/rom_checker.cpp +++ b/src/pc/rom_checker.cpp @@ -10,7 +10,7 @@ extern "C" { #include "platform.h" -#include "mods/mods_utils.h" // for str_ends_with +#include "mods/mods_utils.h" // for path_ends_with #include "mods/mod_cache.h" // for md5 hashing #include "mods/mods.h" #include "loading.h" @@ -81,7 +81,7 @@ static bool is_rom_valid(const std::string romPath) { inline static bool scan_path_for_rom(const char *dir) { for (const auto &entry: std::filesystem::directory_iterator(dir)) { std::string path = entry.path().generic_string(); - if (str_ends_with(path.c_str(), ".z64")) { + if (path_ends_with(path.c_str(), ".z64")) { if (is_rom_valid(path)) { return true; } } } diff --git a/src/pc/update_checker.c b/src/pc/update_checker.c index 1613c80f1..7709724c0 100644 --- a/src/pc/update_checker.c +++ b/src/pc/update_checker.c @@ -46,11 +46,13 @@ size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) { void parse_version(const char *data) { const char *version = strstr(data, VERSION_IDENTIFIER); if (version == NULL) { return; } - u8 len = strlen(VERSION_IDENTIFIER); + size_t len = strlen(VERSION_IDENTIFIER); version += len; const char *end = strchr(version, '"'); - memcpy(sRemoteVersion, version, end - version); - sRemoteVersion[end - version] = '\0'; + size_t versionLength = (size_t)(end - version); + if (versionLength > sizeof(sRemoteVersion) - 1) { return; } + memcpy(sRemoteVersion, version, versionLength); + sRemoteVersion[versionLength] = '\0'; } // function to download a text file from the internet @@ -80,9 +82,9 @@ void get_version_remote(void) { DWORD dwSize = sizeof(contentLength); HttpQueryInfo(hUrl, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &contentLength, &dwSize, NULL); - // read data from the URL + // read data from the URL, making room in the buffer for the null-terminator DWORD bytesRead; - if (!InternetReadFile(hUrl, buffer, sizeof(buffer), &bytesRead)) { + if (!InternetReadFile(hUrl, buffer, sizeof(buffer) - 1, &bytesRead)) { printf("Failed to check for updates!\n"); InternetCloseHandle(hInternet); InternetCloseHandle(hUrl); diff --git a/src/pc/utils/json.hpp b/src/pc/utils/json.hpp new file mode 100644 index 000000000..e66265542 --- /dev/null +++ b/src/pc/utils/json.hpp @@ -0,0 +1,25677 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + +/****************************************************************************\ + * Note on documentation: The source files contain links to the online * + * documentation of the public API at https://json.nlohmann.me. This URL * + * contains the most recent documentation and should also be applicable to * + * previous versions; documentation for deprecated functions is not * + * removed, but marked deprecated. See "Generate documentation" section in * + * file docs/README.md. * +\****************************************************************************/ + +#ifndef INCLUDE_NLOHMANN_JSON_HPP_ +#define INCLUDE_NLOHMANN_JSON_HPP_ + +#include // all_of, find, for_each +#include // nullptr_t, ptrdiff_t, size_t +#include // hash, less +#include // initializer_list +#ifndef JSON_NO_IO + #include // istream, ostream +#endif // JSON_NO_IO +#include // random_access_iterator_tag +#include // unique_ptr +#include // string, stoi, to_string +#include // declval, forward, move, pair, swap +#include // vector + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// This file contains all macro definitions affecting or depending on the ABI + +#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK + #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) + #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0 + #warning "Already included a different version of the library!" + #endif + #endif +#endif + +#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_MINOR 12 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum) + +#ifndef JSON_DIAGNOSTICS + #define JSON_DIAGNOSTICS 0 +#endif + +#ifndef JSON_DIAGNOSTIC_POSITIONS + #define JSON_DIAGNOSTIC_POSITIONS 0 +#endif + +#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 +#endif + +#if JSON_DIAGNOSTICS + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag +#else + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS +#endif + +#if JSON_DIAGNOSTIC_POSITIONS + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp +#else + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS +#endif + +#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp +#else + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION + #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 +#endif + +// Construct the namespace ABI tags component +#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) json_abi ## a ## b ## c +#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c) \ + NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) + +#define NLOHMANN_JSON_ABI_TAGS \ + NLOHMANN_JSON_ABI_TAGS_CONCAT( \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ + NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS) + +// Construct the namespace version component +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ + _v ## major ## _ ## minor ## _ ## patch +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) + +#if NLOHMANN_JSON_NAMESPACE_NO_VERSION +#define NLOHMANN_JSON_NAMESPACE_VERSION +#else +#define NLOHMANN_JSON_NAMESPACE_VERSION \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ + NLOHMANN_JSON_VERSION_MINOR, \ + NLOHMANN_JSON_VERSION_PATCH) +#endif + +// Combine namespace components +#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b +#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ + NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) + +#ifndef NLOHMANN_JSON_NAMESPACE +#define NLOHMANN_JSON_NAMESPACE \ + nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN +#define NLOHMANN_JSON_NAMESPACE_BEGIN \ + namespace nlohmann \ + { \ + inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) \ + { +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_END +#define NLOHMANN_JSON_NAMESPACE_END \ + } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ + } // namespace nlohmann +#endif + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // transform +#include // array +#include // forward_list +#include // inserter, front_inserter, end +#include // map +#include // string +#include // tuple, make_tuple +#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible +#include // unordered_map +#include // pair, declval +#include // valarray + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // nullptr_t +#include // exception +#if JSON_DIAGNOSTICS + #include // accumulate +#endif +#include // runtime_error +#include // to_string +#include // vector + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // array +#include // size_t +#include // uint8_t +#include // string + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // declval, pair +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// https://en.cppreference.com/w/cpp/experimental/is_detected +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + nonesuch(nonesuch const&&) = delete; + void operator=(nonesuch const&) = delete; + void operator=(nonesuch&&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template class Op, class... Args> +using is_detected = typename detector::value_t; + +template class Op, class... Args> +struct is_detected_lazy : is_detected { }; + +template class Op, class... Args> +using detected_t = typename detector::type; + +template class Op, class... Args> +using detected_or = detector; + +template class Op, class... Args> +using detected_or_t = typename detected_or::type; + +template class Op, class... Args> +using is_detected_exact = std::is_same>; + +template class Op, class... Args> +using is_detected_convertible = + std::is_convertible, To>; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + + +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-FileCopyrightText: 2016 - 2021 Evan Nemerson +// SPDX-License-Identifier: MIT + +/* Hedley - https://nemequ.github.io/hedley + * Created by Evan Nemerson + */ + +#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) +#if defined(JSON_HEDLEY_VERSION) + #undef JSON_HEDLEY_VERSION +#endif +#define JSON_HEDLEY_VERSION 15 + +#if defined(JSON_HEDLEY_STRINGIFY_EX) + #undef JSON_HEDLEY_STRINGIFY_EX +#endif +#define JSON_HEDLEY_STRINGIFY_EX(x) #x + +#if defined(JSON_HEDLEY_STRINGIFY) + #undef JSON_HEDLEY_STRINGIFY +#endif +#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) + +#if defined(JSON_HEDLEY_CONCAT_EX) + #undef JSON_HEDLEY_CONCAT_EX +#endif +#define JSON_HEDLEY_CONCAT_EX(a,b) a##b + +#if defined(JSON_HEDLEY_CONCAT) + #undef JSON_HEDLEY_CONCAT +#endif +#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) + +#if defined(JSON_HEDLEY_CONCAT3_EX) + #undef JSON_HEDLEY_CONCAT3_EX +#endif +#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c + +#if defined(JSON_HEDLEY_CONCAT3) + #undef JSON_HEDLEY_CONCAT3 +#endif +#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) + +#if defined(JSON_HEDLEY_VERSION_ENCODE) + #undef JSON_HEDLEY_VERSION_ENCODE +#endif +#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) + +#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) + #undef JSON_HEDLEY_VERSION_DECODE_MAJOR +#endif +#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) + +#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) + #undef JSON_HEDLEY_VERSION_DECODE_MINOR +#endif +#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) + +#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) + #undef JSON_HEDLEY_VERSION_DECODE_REVISION +#endif +#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) + +#if defined(JSON_HEDLEY_GNUC_VERSION) + #undef JSON_HEDLEY_GNUC_VERSION +#endif +#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) + #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#elif defined(__GNUC__) + #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) +#endif + +#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) + #undef JSON_HEDLEY_GNUC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_GNUC_VERSION) + #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_MSVC_VERSION) + #undef JSON_HEDLEY_MSVC_VERSION +#endif +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) +#elif defined(_MSC_FULL_VER) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) +#elif defined(_MSC_VER) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) +#endif + +#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) + #undef JSON_HEDLEY_MSVC_VERSION_CHECK +#endif +#if !defined(JSON_HEDLEY_MSVC_VERSION) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) +#elif defined(_MSC_VER) && (_MSC_VER >= 1200) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) +#else + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) +#endif + +#if defined(JSON_HEDLEY_INTEL_VERSION) + #undef JSON_HEDLEY_INTEL_VERSION +#endif +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) + #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) +#elif defined(__INTEL_COMPILER) && !defined(__ICL) + #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) +#endif + +#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) + #undef JSON_HEDLEY_INTEL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_INTEL_VERSION) + #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #undef JSON_HEDLEY_INTEL_CL_VERSION +#endif +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) + #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) +#endif + +#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) + #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_PGI_VERSION) + #undef JSON_HEDLEY_PGI_VERSION +#endif +#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) + #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) +#endif + +#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) + #undef JSON_HEDLEY_PGI_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_PGI_VERSION) + #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_SUNPRO_VERSION) + #undef JSON_HEDLEY_SUNPRO_VERSION +#endif +#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) +#elif defined(__SUNPRO_C) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) +#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) +#elif defined(__SUNPRO_CC) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) +#endif + +#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) + #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_SUNPRO_VERSION) + #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) + #undef JSON_HEDLEY_EMSCRIPTEN_VERSION +#endif +#if defined(__EMSCRIPTEN__) + #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) +#endif + +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) + #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) + #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_ARM_VERSION) + #undef JSON_HEDLEY_ARM_VERSION +#endif +#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) + #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) +#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) + #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) +#endif + +#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) + #undef JSON_HEDLEY_ARM_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_ARM_VERSION) + #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_IBM_VERSION) + #undef JSON_HEDLEY_IBM_VERSION +#endif +#if defined(__ibmxl__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) +#elif defined(__xlC__) && defined(__xlC_ver__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) +#elif defined(__xlC__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) +#endif + +#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) + #undef JSON_HEDLEY_IBM_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_IBM_VERSION) + #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_VERSION) + #undef JSON_HEDLEY_TI_VERSION +#endif +#if \ + defined(__TI_COMPILER_VERSION__) && \ + ( \ + defined(__TMS470__) || defined(__TI_ARM__) || \ + defined(__MSP430__) || \ + defined(__TMS320C2000__) \ + ) +#if (__TI_COMPILER_VERSION__ >= 16000000) + #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif +#endif + +#if defined(JSON_HEDLEY_TI_VERSION_CHECK) + #undef JSON_HEDLEY_TI_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_VERSION) + #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #undef JSON_HEDLEY_TI_CL2000_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) + #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #undef JSON_HEDLEY_TI_CL430_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) + #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #undef JSON_HEDLEY_TI_ARMCL_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) + #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) + #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #undef JSON_HEDLEY_TI_CL6X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) + #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #undef JSON_HEDLEY_TI_CL7X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) + #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #undef JSON_HEDLEY_TI_CLPRU_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) + #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_CRAY_VERSION) + #undef JSON_HEDLEY_CRAY_VERSION +#endif +#if defined(_CRAYC) + #if defined(_RELEASE_PATCHLEVEL) + #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) + #else + #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) + #endif +#endif + +#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) + #undef JSON_HEDLEY_CRAY_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_CRAY_VERSION) + #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_IAR_VERSION) + #undef JSON_HEDLEY_IAR_VERSION +#endif +#if defined(__IAR_SYSTEMS_ICC__) + #if __VER__ > 1000 + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) + #else + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) + #endif +#endif + +#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) + #undef JSON_HEDLEY_IAR_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_IAR_VERSION) + #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TINYC_VERSION) + #undef JSON_HEDLEY_TINYC_VERSION +#endif +#if defined(__TINYC__) + #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) +#endif + +#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) + #undef JSON_HEDLEY_TINYC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TINYC_VERSION) + #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_DMC_VERSION) + #undef JSON_HEDLEY_DMC_VERSION +#endif +#if defined(__DMC__) + #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) +#endif + +#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) + #undef JSON_HEDLEY_DMC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_DMC_VERSION) + #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_COMPCERT_VERSION) + #undef JSON_HEDLEY_COMPCERT_VERSION +#endif +#if defined(__COMPCERT_VERSION__) + #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) +#endif + +#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) + #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_COMPCERT_VERSION) + #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_PELLES_VERSION) + #undef JSON_HEDLEY_PELLES_VERSION +#endif +#if defined(__POCC__) + #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) +#endif + +#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) + #undef JSON_HEDLEY_PELLES_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_PELLES_VERSION) + #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #undef JSON_HEDLEY_MCST_LCC_VERSION +#endif +#if defined(__LCC__) && defined(__LCC_MINOR__) + #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) +#endif + +#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) + #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_GCC_VERSION) + #undef JSON_HEDLEY_GCC_VERSION +#endif +#if \ + defined(JSON_HEDLEY_GNUC_VERSION) && \ + !defined(__clang__) && \ + !defined(JSON_HEDLEY_INTEL_VERSION) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_ARM_VERSION) && \ + !defined(JSON_HEDLEY_CRAY_VERSION) && \ + !defined(JSON_HEDLEY_TI_VERSION) && \ + !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ + !defined(__COMPCERT__) && \ + !defined(JSON_HEDLEY_MCST_LCC_VERSION) + #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION +#endif + +#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) + #undef JSON_HEDLEY_GCC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_GCC_VERSION) + #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_ATTRIBUTE +#endif +#if \ + defined(__has_attribute) && \ + ( \ + (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ + ) +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) +#else +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE +#endif +#if defined(__has_attribute) + #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE +#endif +#if defined(__has_attribute) + #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE +#endif +#if \ + defined(__has_cpp_attribute) && \ + defined(__cplusplus) && \ + (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) + #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS +#endif +#if !defined(__cplusplus) || !defined(__has_cpp_attribute) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) +#elif \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION) && \ + (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ + (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) +#else + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE +#endif +#if defined(__has_cpp_attribute) && defined(__cplusplus) + #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE +#endif +#if defined(__has_cpp_attribute) && defined(__cplusplus) + #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_BUILTIN) + #undef JSON_HEDLEY_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) +#else + #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) + #undef JSON_HEDLEY_GNUC_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) +#else + #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) + #undef JSON_HEDLEY_GCC_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) +#else + #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_FEATURE) + #undef JSON_HEDLEY_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) +#else + #define JSON_HEDLEY_HAS_FEATURE(feature) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) + #undef JSON_HEDLEY_GNUC_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) +#else + #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) + #undef JSON_HEDLEY_GCC_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) +#else + #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_EXTENSION) + #undef JSON_HEDLEY_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) +#else + #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) + #undef JSON_HEDLEY_GNUC_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) +#else + #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) + #undef JSON_HEDLEY_GCC_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) +#else + #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_WARNING) + #undef JSON_HEDLEY_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) +#else + #define JSON_HEDLEY_HAS_WARNING(warning) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) + #undef JSON_HEDLEY_GNUC_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) +#else + #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_WARNING) + #undef JSON_HEDLEY_GCC_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) +#else + #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + defined(__clang__) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ + (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) + #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_PRAGMA(value) __pragma(value) +#else + #define JSON_HEDLEY_PRAGMA(value) +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) + #undef JSON_HEDLEY_DIAGNOSTIC_PUSH +#endif +#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) + #undef JSON_HEDLEY_DIAGNOSTIC_POP +#endif +#if defined(__clang__) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) + #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) +#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") +#else + #define JSON_HEDLEY_DIAGNOSTIC_PUSH + #define JSON_HEDLEY_DIAGNOSTIC_POP +#endif + +/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for + HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") +# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") +# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# endif +#endif +#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x +#endif + +#if defined(JSON_HEDLEY_CONST_CAST) + #undef JSON_HEDLEY_CONST_CAST +#endif +#if defined(__cplusplus) +# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) +#elif \ + JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ + ((T) (expr)); \ + JSON_HEDLEY_DIAGNOSTIC_POP \ + })) +#else +# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_REINTERPRET_CAST) + #undef JSON_HEDLEY_REINTERPRET_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) +#else + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_STATIC_CAST) + #undef JSON_HEDLEY_STATIC_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) +#else + #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_CPP_CAST) + #undef JSON_HEDLEY_CPP_CAST +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ + ((T) (expr)) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("diag_suppress=Pe137") \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) +# endif +#else +# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif + +#if defined(JSON_HEDLEY_DEPRECATED) + #undef JSON_HEDLEY_DEPRECATED +#endif +#if defined(JSON_HEDLEY_DEPRECATED_FOR) + #undef JSON_HEDLEY_DEPRECATED_FOR +#endif +#if \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) +#elif \ + (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) +#elif defined(__cplusplus) && (__cplusplus >= 201402L) + #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") +#else + #define JSON_HEDLEY_DEPRECATED(since) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) +#endif + +#if defined(JSON_HEDLEY_UNAVAILABLE) + #undef JSON_HEDLEY_UNAVAILABLE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) +#else + #define JSON_HEDLEY_UNAVAILABLE(available_since) +#endif + +#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) + #undef JSON_HEDLEY_WARN_UNUSED_RESULT +#endif +#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) + #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) +#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) +#elif defined(_Check_return_) /* SAL */ + #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ +#else + #define JSON_HEDLEY_WARN_UNUSED_RESULT + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) +#endif + +#if defined(JSON_HEDLEY_SENTINEL) + #undef JSON_HEDLEY_SENTINEL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) +#else + #define JSON_HEDLEY_SENTINEL(position) +#endif + +#if defined(JSON_HEDLEY_NO_RETURN) + #undef JSON_HEDLEY_NO_RETURN +#endif +#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_NO_RETURN __noreturn +#elif \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + #define JSON_HEDLEY_NO_RETURN _Noreturn +#elif defined(__cplusplus) && (__cplusplus >= 201103L) + #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) + #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") +#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) + #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) + #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) +#else + #define JSON_HEDLEY_NO_RETURN +#endif + +#if defined(JSON_HEDLEY_NO_ESCAPE) + #undef JSON_HEDLEY_NO_ESCAPE +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) + #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) +#else + #define JSON_HEDLEY_NO_ESCAPE +#endif + +#if defined(JSON_HEDLEY_UNREACHABLE) + #undef JSON_HEDLEY_UNREACHABLE +#endif +#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) + #undef JSON_HEDLEY_UNREACHABLE_RETURN +#endif +#if defined(JSON_HEDLEY_ASSUME) + #undef JSON_HEDLEY_ASSUME +#endif +#if \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_ASSUME(expr) __assume(expr) +#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) + #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) +#elif \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) + #if defined(__cplusplus) + #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) + #else + #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) + #endif +#endif +#if \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() +#elif defined(JSON_HEDLEY_ASSUME) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) +#endif +#if !defined(JSON_HEDLEY_ASSUME) + #if defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) + #else + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) + #endif +#endif +#if defined(JSON_HEDLEY_UNREACHABLE) + #if \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) + #else + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() + #endif +#else + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) +#endif +#if !defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) +#endif + +JSON_HEDLEY_DIAGNOSTIC_PUSH +#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") + #pragma clang diagnostic ignored "-Wpedantic" +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) + #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +#endif +#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) + #if defined(__clang__) + #pragma clang diagnostic ignored "-Wvariadic-macros" + #elif defined(JSON_HEDLEY_GCC_VERSION) + #pragma GCC diagnostic ignored "-Wvariadic-macros" + #endif +#endif +#if defined(JSON_HEDLEY_NON_NULL) + #undef JSON_HEDLEY_NON_NULL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) + #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) +#else + #define JSON_HEDLEY_NON_NULL(...) +#endif +JSON_HEDLEY_DIAGNOSTIC_POP + +#if defined(JSON_HEDLEY_PRINTF_FORMAT) + #undef JSON_HEDLEY_PRINTF_FORMAT +#endif +#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) +#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) +#else + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) +#endif + +#if defined(JSON_HEDLEY_CONSTEXPR) + #undef JSON_HEDLEY_CONSTEXPR +#endif +#if defined(__cplusplus) + #if __cplusplus >= 201103L + #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) + #endif +#endif +#if !defined(JSON_HEDLEY_CONSTEXPR) + #define JSON_HEDLEY_CONSTEXPR +#endif + +#if defined(JSON_HEDLEY_PREDICT) + #undef JSON_HEDLEY_PREDICT +#endif +#if defined(JSON_HEDLEY_LIKELY) + #undef JSON_HEDLEY_LIKELY +#endif +#if defined(JSON_HEDLEY_UNLIKELY) + #undef JSON_HEDLEY_UNLIKELY +#endif +#if defined(JSON_HEDLEY_UNPREDICTABLE) + #undef JSON_HEDLEY_UNPREDICTABLE +#endif +#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) + #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) +#endif +#if \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) +# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) +# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) +#elif \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ + (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ + (__extension__ ({ \ + double hedley_probability_ = (probability); \ + ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ + })) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ + (__extension__ ({ \ + double hedley_probability_ = (probability); \ + ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ + })) +# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) +# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) +#else +# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) +# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) +# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) +#endif +#if !defined(JSON_HEDLEY_UNPREDICTABLE) + #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) +#endif + +#if defined(JSON_HEDLEY_MALLOC) + #undef JSON_HEDLEY_MALLOC +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_MALLOC __declspec(restrict) +#else + #define JSON_HEDLEY_MALLOC +#endif + +#if defined(JSON_HEDLEY_PURE) + #undef JSON_HEDLEY_PURE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PURE __attribute__((__pure__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) +# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ + ) +# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") +#else +# define JSON_HEDLEY_PURE +#endif + +#if defined(JSON_HEDLEY_CONST) + #undef JSON_HEDLEY_CONST +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_CONST __attribute__((__const__)) +#elif \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_CONST _Pragma("no_side_effect") +#else + #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE +#endif + +#if defined(JSON_HEDLEY_RESTRICT) + #undef JSON_HEDLEY_RESTRICT +#endif +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) + #define JSON_HEDLEY_RESTRICT restrict +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ + defined(__clang__) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_RESTRICT __restrict +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) + #define JSON_HEDLEY_RESTRICT _Restrict +#else + #define JSON_HEDLEY_RESTRICT +#endif + +#if defined(JSON_HEDLEY_INLINE) + #undef JSON_HEDLEY_INLINE +#endif +#if \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + (defined(__cplusplus) && (__cplusplus >= 199711L)) + #define JSON_HEDLEY_INLINE inline +#elif \ + defined(JSON_HEDLEY_GCC_VERSION) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) + #define JSON_HEDLEY_INLINE __inline__ +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_INLINE __inline +#else + #define JSON_HEDLEY_INLINE +#endif + +#if defined(JSON_HEDLEY_ALWAYS_INLINE) + #undef JSON_HEDLEY_ALWAYS_INLINE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) +# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_ALWAYS_INLINE __forceinline +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ + ) +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") +#else +# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE +#endif + +#if defined(JSON_HEDLEY_NEVER_INLINE) + #undef JSON_HEDLEY_NEVER_INLINE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") +#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) + #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) + #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) +#else + #define JSON_HEDLEY_NEVER_INLINE +#endif + +#if defined(JSON_HEDLEY_PRIVATE) + #undef JSON_HEDLEY_PRIVATE +#endif +#if defined(JSON_HEDLEY_PUBLIC) + #undef JSON_HEDLEY_PUBLIC +#endif +#if defined(JSON_HEDLEY_IMPORT) + #undef JSON_HEDLEY_IMPORT +#endif +#if defined(_WIN32) || defined(__CYGWIN__) +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC __declspec(dllexport) +# define JSON_HEDLEY_IMPORT __declspec(dllimport) +#else +# if \ + JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + ( \ + defined(__TI_EABI__) && \ + ( \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ + ) \ + ) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) +# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) +# else +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC +# endif +# define JSON_HEDLEY_IMPORT extern +#endif + +#if defined(JSON_HEDLEY_NO_THROW) + #undef JSON_HEDLEY_NO_THROW +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) + #define JSON_HEDLEY_NO_THROW __declspec(nothrow) +#else + #define JSON_HEDLEY_NO_THROW +#endif + +#if defined(JSON_HEDLEY_FALL_THROUGH) + #undef JSON_HEDLEY_FALL_THROUGH +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) + #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) + #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) +#elif defined(__fallthrough) /* SAL */ + #define JSON_HEDLEY_FALL_THROUGH __fallthrough +#else + #define JSON_HEDLEY_FALL_THROUGH +#endif + +#if defined(JSON_HEDLEY_RETURNS_NON_NULL) + #undef JSON_HEDLEY_RETURNS_NON_NULL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) +#elif defined(_Ret_notnull_) /* SAL */ + #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ +#else + #define JSON_HEDLEY_RETURNS_NON_NULL +#endif + +#if defined(JSON_HEDLEY_ARRAY_PARAM) + #undef JSON_HEDLEY_ARRAY_PARAM +#endif +#if \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ + !defined(__STDC_NO_VLA__) && \ + !defined(__cplusplus) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_TINYC_VERSION) + #define JSON_HEDLEY_ARRAY_PARAM(name) (name) +#else + #define JSON_HEDLEY_ARRAY_PARAM(name) +#endif + +#if defined(JSON_HEDLEY_IS_CONSTANT) + #undef JSON_HEDLEY_IS_CONSTANT +#endif +#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) + #undef JSON_HEDLEY_REQUIRE_CONSTEXPR +#endif +/* JSON_HEDLEY_IS_CONSTEXPR_ is for + HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ +#if defined(JSON_HEDLEY_IS_CONSTEXPR_) + #undef JSON_HEDLEY_IS_CONSTEXPR_ +#endif +#if \ + JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) +#endif +#if !defined(__cplusplus) +# if \ + JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) +#if defined(__INTPTR_TYPE__) + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) +#else + #include + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) +#endif +# elif \ + ( \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION)) || \ + (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) +#if defined(__INTPTR_TYPE__) + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) +#else + #include + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) +#endif +# elif \ + defined(JSON_HEDLEY_GCC_VERSION) || \ + defined(JSON_HEDLEY_INTEL_VERSION) || \ + defined(JSON_HEDLEY_TINYC_VERSION) || \ + defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ + defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ + defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ + defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ + defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ + defined(__clang__) +# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ + sizeof(void) != \ + sizeof(*( \ + 1 ? \ + ((void*) ((expr) * 0L) ) : \ +((struct { char v[sizeof(void) * 2]; } *) 1) \ + ) \ + ) \ + ) +# endif +#endif +#if defined(JSON_HEDLEY_IS_CONSTEXPR_) + #if !defined(JSON_HEDLEY_IS_CONSTANT) + #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) + #endif + #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) +#else + #if !defined(JSON_HEDLEY_IS_CONSTANT) + #define JSON_HEDLEY_IS_CONSTANT(expr) (0) + #endif + #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) +#endif + +#if defined(JSON_HEDLEY_BEGIN_C_DECLS) + #undef JSON_HEDLEY_BEGIN_C_DECLS +#endif +#if defined(JSON_HEDLEY_END_C_DECLS) + #undef JSON_HEDLEY_END_C_DECLS +#endif +#if defined(JSON_HEDLEY_C_DECL) + #undef JSON_HEDLEY_C_DECL +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { + #define JSON_HEDLEY_END_C_DECLS } + #define JSON_HEDLEY_C_DECL extern "C" +#else + #define JSON_HEDLEY_BEGIN_C_DECLS + #define JSON_HEDLEY_END_C_DECLS + #define JSON_HEDLEY_C_DECL +#endif + +#if defined(JSON_HEDLEY_STATIC_ASSERT) + #undef JSON_HEDLEY_STATIC_ASSERT +#endif +#if \ + !defined(__cplusplus) && ( \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ + (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + defined(_Static_assert) \ + ) +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) +#elif \ + (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ + JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) +#else +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) +#endif + +#if defined(JSON_HEDLEY_NULL) + #undef JSON_HEDLEY_NULL +#endif +#if defined(__cplusplus) + #if __cplusplus >= 201103L + #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) + #elif defined(NULL) + #define JSON_HEDLEY_NULL NULL + #else + #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) + #endif +#elif defined(NULL) + #define JSON_HEDLEY_NULL NULL +#else + #define JSON_HEDLEY_NULL ((void*) 0) +#endif + +#if defined(JSON_HEDLEY_MESSAGE) + #undef JSON_HEDLEY_MESSAGE +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") +# define JSON_HEDLEY_MESSAGE(msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ + JSON_HEDLEY_PRAGMA(message msg) \ + JSON_HEDLEY_DIAGNOSTIC_POP +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) +#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#else +# define JSON_HEDLEY_MESSAGE(msg) +#endif + +#if defined(JSON_HEDLEY_WARNING) + #undef JSON_HEDLEY_WARNING +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") +# define JSON_HEDLEY_WARNING(msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ + JSON_HEDLEY_PRAGMA(clang warning msg) \ + JSON_HEDLEY_DIAGNOSTIC_POP +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#else +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) +#endif + +#if defined(JSON_HEDLEY_REQUIRE) + #undef JSON_HEDLEY_REQUIRE +#endif +#if defined(JSON_HEDLEY_REQUIRE_MSG) + #undef JSON_HEDLEY_REQUIRE_MSG +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) +# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") +# define JSON_HEDLEY_REQUIRE(expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ + __attribute__((diagnose_if(!(expr), #expr, "error"))) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ + __attribute__((diagnose_if(!(expr), msg, "error"))) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) +# endif +#else +# define JSON_HEDLEY_REQUIRE(expr) +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) +#endif + +#if defined(JSON_HEDLEY_FLAGS) + #undef JSON_HEDLEY_FLAGS +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) + #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) +#else + #define JSON_HEDLEY_FLAGS +#endif + +#if defined(JSON_HEDLEY_FLAGS_CAST) + #undef JSON_HEDLEY_FLAGS_CAST +#endif +#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) +# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("warning(disable:188)") \ + ((T) (expr)); \ + JSON_HEDLEY_DIAGNOSTIC_POP \ + })) +#else +# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) +#endif + +#if defined(JSON_HEDLEY_EMPTY_BASES) + #undef JSON_HEDLEY_EMPTY_BASES +#endif +#if \ + (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) +#else + #define JSON_HEDLEY_EMPTY_BASES +#endif + +/* Remaining macros are deprecated. */ + +#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) + #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK +#endif +#if defined(__clang__) + #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) +#else + #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) + #undef JSON_HEDLEY_CLANG_HAS_BUILTIN +#endif +#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) + +#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) + #undef JSON_HEDLEY_CLANG_HAS_FEATURE +#endif +#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) + +#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) + #undef JSON_HEDLEY_CLANG_HAS_EXTENSION +#endif +#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) + +#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) + #undef JSON_HEDLEY_CLANG_HAS_WARNING +#endif +#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) + +#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ + + +// This file contains all internal macro definitions (except those affecting ABI) +// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them + +// #include + + +// exclude unsupported compilers +#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) + #if defined(__clang__) + #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 + #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 + #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #endif +#endif + +// C++ language standard detection +// if the user manually specified the used C++ version, this is skipped +#if !defined(JSON_HAS_CPP_26) && !defined(JSON_HAS_CPP_23) && !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) + #if (defined(__cplusplus) && __cplusplus > 202302L) || (defined(_MSVC_LANG) && _MSVC_LANG > 202302L) + #define JSON_HAS_CPP_26 + #define JSON_HAS_CPP_23 + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus > 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG > 202002L) + #define JSON_HAS_CPP_23 + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus > 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG > 201703L) + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus > 201402L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus > 201103L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 + #endif + // the cpp 11 flag is always specified because it is the minimal required version + #define JSON_HAS_CPP_11 +#endif + +#ifdef __has_include + #if __has_include() + #include + #endif +#endif + +#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) + #ifdef JSON_HAS_CPP_17 + #if defined(__cpp_lib_filesystem) + #define JSON_HAS_FILESYSTEM 1 + #elif defined(__cpp_lib_experimental_filesystem) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif !defined(__has_include) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #endif + + // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ + #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__clang_major__) && __clang_major__ < 7 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support + #if defined(_MSC_VER) && _MSC_VER < 1914 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before iOS 13 + #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before macOS Catalina + #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + #endif +#endif + +#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_FILESYSTEM + #define JSON_HAS_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_THREE_WAY_COMPARISON + #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ + && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L + #define JSON_HAS_THREE_WAY_COMPARISON 1 + #else + #define JSON_HAS_THREE_WAY_COMPARISON 0 + #endif +#endif + +#ifndef JSON_HAS_RANGES + // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has a syntax error + #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 + #define JSON_HAS_RANGES 0 + #elif defined(__cpp_lib_ranges) + #define JSON_HAS_RANGES 1 + #else + #define JSON_HAS_RANGES 0 + #endif +#endif + +#ifndef JSON_HAS_STATIC_RTTI + #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0 + #define JSON_HAS_STATIC_RTTI 1 + #else + #define JSON_HAS_STATIC_RTTI 0 + #endif +#endif + +#ifdef JSON_HAS_CPP_17 + #define JSON_INLINE_VARIABLE inline +#else + #define JSON_INLINE_VARIABLE +#endif + +#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) + #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] +#else + #define JSON_NO_UNIQUE_ADDRESS +#endif + +// disable documentation warnings on clang +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdocumentation" + #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +#endif + +// allow disabling exceptions +#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) + #define JSON_THROW(exception) throw exception + #define JSON_TRY try + #define JSON_CATCH(exception) catch(exception) + #define JSON_INTERNAL_CATCH(exception) catch(exception) +#else + #include + #define JSON_THROW(exception) std::abort() + #define JSON_TRY if(true) + #define JSON_CATCH(exception) if(false) + #define JSON_INTERNAL_CATCH(exception) if(false) +#endif + +// override exception macros +#if defined(JSON_THROW_USER) + #undef JSON_THROW + #define JSON_THROW JSON_THROW_USER +#endif +#if defined(JSON_TRY_USER) + #undef JSON_TRY + #define JSON_TRY JSON_TRY_USER +#endif +#if defined(JSON_CATCH_USER) + #undef JSON_CATCH + #define JSON_CATCH JSON_CATCH_USER + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_CATCH_USER +#endif +#if defined(JSON_INTERNAL_CATCH_USER) + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER +#endif + +// allow overriding assert +#if !defined(JSON_ASSERT) + #include // assert + #define JSON_ASSERT(x) assert(x) +#endif + +// allow accessing some private functions (needed by the test suite) +#if defined(JSON_TESTS_PRIVATE) + #define JSON_PRIVATE_UNLESS_TESTED public +#else + #define JSON_PRIVATE_UNLESS_TESTED private +#endif + +/*! +@brief macro to briefly define a mapping between an enum and JSON +@def NLOHMANN_JSON_SERIALIZE_ENUM +@since version 3.4.0 +*/ +#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ + template \ + inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ + { \ + /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.first == e; \ + }); \ + j = ((it != std::end(m)) ? it : std::begin(m))->second; \ + } \ + template \ + inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ + { \ + /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [&j](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.second == j; \ + }); \ + e = ((it != std::end(m)) ? it : std::begin(m))->first; \ + } + +// Ugly macros to avoid uglier copy-paste when specializing basic_json. They +// may be removed in the future once the class is split. + +#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ + template class ObjectType, \ + template class ArrayType, \ + class StringType, class BooleanType, class NumberIntegerType, \ + class NumberUnsignedType, class NumberFloatType, \ + template class AllocatorType, \ + template class JSONSerializer, \ + class BinaryType, \ + class CustomBaseClass> + +#define NLOHMANN_BASIC_JSON_TPL \ + basic_json + +// Macros to simplify conversion from/to types + +#define NLOHMANN_JSON_EXPAND( x ) x +#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME +#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ + NLOHMANN_JSON_PASTE64, \ + NLOHMANN_JSON_PASTE63, \ + NLOHMANN_JSON_PASTE62, \ + NLOHMANN_JSON_PASTE61, \ + NLOHMANN_JSON_PASTE60, \ + NLOHMANN_JSON_PASTE59, \ + NLOHMANN_JSON_PASTE58, \ + NLOHMANN_JSON_PASTE57, \ + NLOHMANN_JSON_PASTE56, \ + NLOHMANN_JSON_PASTE55, \ + NLOHMANN_JSON_PASTE54, \ + NLOHMANN_JSON_PASTE53, \ + NLOHMANN_JSON_PASTE52, \ + NLOHMANN_JSON_PASTE51, \ + NLOHMANN_JSON_PASTE50, \ + NLOHMANN_JSON_PASTE49, \ + NLOHMANN_JSON_PASTE48, \ + NLOHMANN_JSON_PASTE47, \ + NLOHMANN_JSON_PASTE46, \ + NLOHMANN_JSON_PASTE45, \ + NLOHMANN_JSON_PASTE44, \ + NLOHMANN_JSON_PASTE43, \ + NLOHMANN_JSON_PASTE42, \ + NLOHMANN_JSON_PASTE41, \ + NLOHMANN_JSON_PASTE40, \ + NLOHMANN_JSON_PASTE39, \ + NLOHMANN_JSON_PASTE38, \ + NLOHMANN_JSON_PASTE37, \ + NLOHMANN_JSON_PASTE36, \ + NLOHMANN_JSON_PASTE35, \ + NLOHMANN_JSON_PASTE34, \ + NLOHMANN_JSON_PASTE33, \ + NLOHMANN_JSON_PASTE32, \ + NLOHMANN_JSON_PASTE31, \ + NLOHMANN_JSON_PASTE30, \ + NLOHMANN_JSON_PASTE29, \ + NLOHMANN_JSON_PASTE28, \ + NLOHMANN_JSON_PASTE27, \ + NLOHMANN_JSON_PASTE26, \ + NLOHMANN_JSON_PASTE25, \ + NLOHMANN_JSON_PASTE24, \ + NLOHMANN_JSON_PASTE23, \ + NLOHMANN_JSON_PASTE22, \ + NLOHMANN_JSON_PASTE21, \ + NLOHMANN_JSON_PASTE20, \ + NLOHMANN_JSON_PASTE19, \ + NLOHMANN_JSON_PASTE18, \ + NLOHMANN_JSON_PASTE17, \ + NLOHMANN_JSON_PASTE16, \ + NLOHMANN_JSON_PASTE15, \ + NLOHMANN_JSON_PASTE14, \ + NLOHMANN_JSON_PASTE13, \ + NLOHMANN_JSON_PASTE12, \ + NLOHMANN_JSON_PASTE11, \ + NLOHMANN_JSON_PASTE10, \ + NLOHMANN_JSON_PASTE9, \ + NLOHMANN_JSON_PASTE8, \ + NLOHMANN_JSON_PASTE7, \ + NLOHMANN_JSON_PASTE6, \ + NLOHMANN_JSON_PASTE5, \ + NLOHMANN_JSON_PASTE4, \ + NLOHMANN_JSON_PASTE3, \ + NLOHMANN_JSON_PASTE2, \ + NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) +#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) +#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) +#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) +#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) +#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) +#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) +#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) +#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) +#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) +#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) +#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) +#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) +#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) +#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) +#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) +#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) +#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) +#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) +#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) +#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) +#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) +#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) +#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) +#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) +#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) +#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) +#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) +#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) +#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) +#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) +#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) +#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) +#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) +#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) +#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) +#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) +#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) +#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) +#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) +#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) +#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) +#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) +#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) +#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) +#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) +#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) +#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) +#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) +#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) +#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) +#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) +#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) +#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) +#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) +#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) +#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) +#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) +#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) +#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) +#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) +#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) +#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) +#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) + +#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; +#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); +#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1) : nlohmann_json_default_obj.v1; + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE +@since version 3.9.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT +@since version 3.11.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE +@since version 3.11.3 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE +@since version 3.9.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT +@since version 3.11.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE +@since version 3.11.3 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +// inspired from https://stackoverflow.com/a/26745591 +// allows calling any std function as if (e.g., with begin): +// using std::begin; begin(x); +// +// it allows using the detected idiom to retrieve the return type +// of such an expression +#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ + namespace detail { \ + using std::std_name; \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + } \ + \ + namespace detail2 { \ + struct std_name##_tag \ + { \ + }; \ + \ + template \ + std_name##_tag std_name(T&&...); \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + \ + template \ + struct would_call_std_##std_name \ + { \ + static constexpr auto const value = ::nlohmann::detail:: \ + is_detected_exact::value; \ + }; \ + } /* namespace detail2 */ \ + \ + template \ + struct would_call_std_##std_name : detail2::would_call_std_##std_name \ + { \ + } + +#ifndef JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_USE_IMPLICIT_CONVERSIONS 1 +#endif + +#if JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_EXPLICIT +#else + #define JSON_EXPLICIT explicit +#endif + +#ifndef JSON_DISABLE_ENUM_SERIALIZATION + #define JSON_DISABLE_ENUM_SERIALIZATION 0 +#endif + +#ifndef JSON_USE_GLOBAL_UDLS + #define JSON_USE_GLOBAL_UDLS 1 +#endif + +#if JSON_HAS_THREE_WAY_COMPARISON + #include // partial_ordering +#endif + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/////////////////////////// +// JSON type enumeration // +/////////////////////////// + +/*! +@brief the JSON type enumeration + +This enumeration collects the different JSON types. It is internally used to +distinguish the stored values, and the functions @ref basic_json::is_null(), +@ref basic_json::is_object(), @ref basic_json::is_array(), +@ref basic_json::is_string(), @ref basic_json::is_boolean(), +@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), +@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), +@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and +@ref basic_json::is_structured() rely on it. + +@note There are three enumeration entries (number_integer, number_unsigned, and +number_float), because the library distinguishes these three types for numbers: +@ref basic_json::number_unsigned_t is used for unsigned integers, +@ref basic_json::number_integer_t is used for signed integers, and +@ref basic_json::number_float_t is used for floating-point numbers or to +approximate integers which do not fit in the limits of their respective type. + +@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON +value with the default value for a given type + +@since version 1.0.0 +*/ +enum class value_t : std::uint8_t +{ + null, ///< null value + object, ///< object (unordered set of name/value pairs) + array, ///< array (ordered collection of values) + string, ///< string value + boolean, ///< boolean value + number_integer, ///< number value (signed integer) + number_unsigned, ///< number value (unsigned integer) + number_float, ///< number value (floating-point) + binary, ///< binary array (ordered collection of bytes) + discarded ///< discarded by the parser callback function +}; + +/*! +@brief comparison operator for JSON types + +Returns an ordering that is similar to Python: +- order: null < boolean < number < object < array < string < binary +- furthermore, each type is not smaller than itself +- discarded values are not comparable +- binary is represented as a b"" string in python and directly comparable to a + string; however, making a binary array directly comparable with a string would + be surprising behavior in a JSON file. + +@since version 1.0.0 +*/ +#if JSON_HAS_THREE_WAY_COMPARISON + inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* +#else + inline bool operator<(const value_t lhs, const value_t rhs) noexcept +#endif +{ + static constexpr std::array order = {{ + 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, + 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, + 6 /* binary */ + } + }; + + const auto l_index = static_cast(lhs); + const auto r_index = static_cast(rhs); +#if JSON_HAS_THREE_WAY_COMPARISON + if (l_index < order.size() && r_index < order.size()) + { + return order[l_index] <=> order[r_index]; // *NOPAD* + } + return std::partial_ordering::unordered; +#else + return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; +#endif +} + +// GCC selects the built-in operator< over an operator rewritten from +// a user-defined spaceship operator +// Clang, MSVC, and ICC select the rewritten candidate +// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) +#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) +inline bool operator<(const value_t lhs, const value_t rhs) noexcept +{ + return std::is_lt(lhs <=> rhs); // *NOPAD* +} +#endif + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/*! +@brief replace all occurrences of a substring by another string + +@param[in,out] s the string to manipulate; changed so that all + occurrences of @a f are replaced with @a t +@param[in] f the substring to replace with @a t +@param[in] t the string to replace @a f + +@pre The search string @a f must not be empty. **This precondition is +enforced with an assertion.** + +@since version 2.0.0 +*/ +template +inline void replace_substring(StringType& s, const StringType& f, + const StringType& t) +{ + JSON_ASSERT(!f.empty()); + for (auto pos = s.find(f); // find the first occurrence of f + pos != StringType::npos; // make sure f was found + s.replace(pos, f.size(), t), // replace with t, and + pos = s.find(f, pos + t.size())) // find the next occurrence of f + {} +} + +/*! + * @brief string escaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to escape + * @return escaped string + * + * Note the order of escaping "~" to "~0" and "/" to "~1" is important. + */ +template +inline StringType escape(StringType s) +{ + replace_substring(s, StringType{"~"}, StringType{"~0"}); + replace_substring(s, StringType{"/"}, StringType{"~1"}); + return s; +} + +/*! + * @brief string unescaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to unescape + * @return unescaped string + * + * Note the order of escaping "~1" to "/" and "~0" to "~" is important. + */ +template +inline void unescape(StringType& s) +{ + replace_substring(s, StringType{"~1"}, StringType{"/"}); + replace_substring(s, StringType{"~0"}, StringType{"~"}); +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // size_t + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/// struct to capture the start position of the current token +struct position_t +{ + /// the total number of characters read + std::size_t chars_read_total = 0; + /// the number of characters read in the current line + std::size_t chars_read_current_line = 0; + /// the number of lines read + std::size_t lines_read = 0; + + /// conversion to size_t to preserve SAX interface + constexpr operator size_t() const + { + return chars_read_total; + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-FileCopyrightText: 2018 The Abseil Authors +// SPDX-License-Identifier: MIT + + + +#include // array +#include // size_t +#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type +#include // index_sequence, make_index_sequence, index_sequence_for + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +using uncvref_t = typename std::remove_cv::type>::type; + +#ifdef JSON_HAS_CPP_14 + +// the following utilities are natively available in C++14 +using std::enable_if_t; +using std::index_sequence; +using std::make_index_sequence; +using std::index_sequence_for; + +#else + +// alias templates to reduce boilerplate +template +using enable_if_t = typename std::enable_if::type; + +// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h +// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. + +//// START OF CODE FROM GOOGLE ABSEIL + +// integer_sequence +// +// Class template representing a compile-time integer sequence. An instantiation +// of `integer_sequence` has a sequence of integers encoded in its +// type through its template arguments (which is a common need when +// working with C++11 variadic templates). `absl::integer_sequence` is designed +// to be a drop-in replacement for C++14's `std::integer_sequence`. +// +// Example: +// +// template< class T, T... Ints > +// void user_function(integer_sequence); +// +// int main() +// { +// // user_function's `T` will be deduced to `int` and `Ints...` +// // will be deduced to `0, 1, 2, 3, 4`. +// user_function(make_integer_sequence()); +// } +template +struct integer_sequence +{ + using value_type = T; + static constexpr std::size_t size() noexcept + { + return sizeof...(Ints); + } +}; + +// index_sequence +// +// A helper template for an `integer_sequence` of `size_t`, +// `absl::index_sequence` is designed to be a drop-in replacement for C++14's +// `std::index_sequence`. +template +using index_sequence = integer_sequence; + +namespace utility_internal +{ + +template +struct Extend; + +// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. +template +struct Extend, SeqSize, 0> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; +}; + +template +struct Extend, SeqSize, 1> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; +}; + +// Recursion helper for 'make_integer_sequence'. +// 'Gen::type' is an alias for 'integer_sequence'. +template +struct Gen +{ + using type = + typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; +}; + +template +struct Gen +{ + using type = integer_sequence; +}; + +} // namespace utility_internal + +// Compile-time sequences of integers + +// make_integer_sequence +// +// This template alias is equivalent to +// `integer_sequence`, and is designed to be a drop-in +// replacement for C++14's `std::make_integer_sequence`. +template +using make_integer_sequence = typename utility_internal::Gen::type; + +// make_index_sequence +// +// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, +// and is designed to be a drop-in replacement for C++14's +// `std::make_index_sequence`. +template +using make_index_sequence = make_integer_sequence; + +// index_sequence_for +// +// Converts a typename pack into an index sequence of the same length, and +// is designed to be a drop-in replacement for C++14's +// `std::index_sequence_for()` +template +using index_sequence_for = make_index_sequence; + +//// END OF CODE FROM GOOGLE ABSEIL + +#endif + +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag < N - 1 > {}; +template<> struct priority_tag<0> {}; + +// taken from ranges-v3 +template +struct static_const +{ + static JSON_INLINE_VARIABLE constexpr T value{}; +}; + +#ifndef JSON_HAS_CPP_17 + template + constexpr T static_const::value; +#endif + +template +constexpr std::array make_array(Args&& ... args) +{ + return std::array {{static_cast(std::forward(args))...}}; +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // numeric_limits +#include // char_traits +#include // tuple +#include // false_type, is_constructible, is_integral, is_same, true_type +#include // declval +#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L + #include // byte +#endif +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // random_access_iterator_tag + +// #include + +// #include + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +struct iterator_types {}; + +template +struct iterator_types < + It, + void_t> +{ + using difference_type = typename It::difference_type; + using value_type = typename It::value_type; + using pointer = typename It::pointer; + using reference = typename It::reference; + using iterator_category = typename It::iterator_category; +}; + +// This is required as some compilers implement std::iterator_traits in a way that +// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. +template +struct iterator_traits +{ +}; + +template +struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> + : iterator_types +{ +}; + +template +struct iterator_traits::value>> +{ + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); + +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); + +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann +// SPDX-License-Identifier: MIT + +#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ + #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ + + #include // int64_t, uint64_t + #include // map + #include // allocator + #include // string + #include // vector + + // #include + + + /*! + @brief namespace for Niels Lohmann + @see https://github.com/nlohmann + @since version 1.0.0 + */ + NLOHMANN_JSON_NAMESPACE_BEGIN + + /*! + @brief default JSONSerializer template argument + + This serializer ignores the template arguments and uses ADL + ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) + for serialization. + */ + template + struct adl_serializer; + + /// a class to store JSON values + /// @sa https://json.nlohmann.me/api/basic_json/ + template class ObjectType = + std::map, + template class ArrayType = std::vector, + class StringType = std::string, class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = + adl_serializer, + class BinaryType = std::vector, // cppcheck-suppress syntaxError + class CustomBaseClass = void> + class basic_json; + + /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document + /// @sa https://json.nlohmann.me/api/json_pointer/ + template + class json_pointer; + + /*! + @brief default specialization + @sa https://json.nlohmann.me/api/json/ + */ + using json = basic_json<>; + + /// @brief a minimal map-like container that preserves insertion order + /// @sa https://json.nlohmann.me/api/ordered_map/ + template + struct ordered_map; + + /// @brief specialization that maintains the insertion order of object keys + /// @sa https://json.nlohmann.me/api/ordered_json/ + using ordered_json = basic_json; + + NLOHMANN_JSON_NAMESPACE_END + +#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ + + +NLOHMANN_JSON_NAMESPACE_BEGIN +/*! +@brief detail namespace with internal helper functions + +This namespace collects functions that should not be exposed, +implementations of some @ref basic_json methods, and meta-programming helpers. + +@since version 2.1.0 +*/ +namespace detail +{ + +///////////// +// helpers // +///////////// + +// Note to maintainers: +// +// Every trait in this file expects a non-CV-qualified type. +// The only exceptions are in the 'aliases for detected' section +// (i.e., those of the form: decltype(T::member_function(std::declval()))) +// +// In this case, T has to be properly CV-qualified to constraint the function arguments +// (e.g., to_json(BasicJsonType&, const T&)) + +template struct is_basic_json : std::false_type {}; + +NLOHMANN_BASIC_JSON_TPL_DECLARATION +struct is_basic_json : std::true_type {}; + +// used by exceptions create() member functions +// true_type for the pointer to possibly cv-qualified basic_json or std::nullptr_t +// false_type otherwise +template +struct is_basic_json_context : + std::integral_constant < bool, + is_basic_json::type>::type>::value + || std::is_same::value > +{}; + +////////////////////// +// json_ref helpers // +////////////////////// + +template +class json_ref; + +template +struct is_json_ref : std::false_type {}; + +template +struct is_json_ref> : std::true_type {}; + +////////////////////////// +// aliases for detected // +////////////////////////// + +template +using mapped_type_t = typename T::mapped_type; + +template +using key_type_t = typename T::key_type; + +template +using value_type_t = typename T::value_type; + +template +using difference_type_t = typename T::difference_type; + +template +using pointer_t = typename T::pointer; + +template +using reference_t = typename T::reference; + +template +using iterator_category_t = typename T::iterator_category; + +template +using to_json_function = decltype(T::to_json(std::declval()...)); + +template +using from_json_function = decltype(T::from_json(std::declval()...)); + +template +using get_template_function = decltype(std::declval().template get()); + +// trait checking if JSONSerializer::from_json(json const&, udt&) exists +template +struct has_from_json : std::false_type {}; + +// trait checking if j.get is valid +// use this trait instead of std::is_constructible or std::is_convertible, +// both rely on, or make use of implicit conversions, and thus fail when T +// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) +template +struct is_getable +{ + static constexpr bool value = is_detected::value; +}; + +template +struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if JSONSerializer::from_json(json const&) exists +// this overload is used for non-default-constructible user-defined-types +template +struct has_non_default_from_json : std::false_type {}; + +template +struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if BasicJsonType::json_serializer::to_json exists +// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. +template +struct has_to_json : std::false_type {}; + +template +struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +template +using detect_key_compare = typename T::key_compare; + +template +struct has_key_compare : std::integral_constant::value> {}; + +// obtains the actual object key comparator +template +struct actual_object_comparator +{ + using object_t = typename BasicJsonType::object_t; + using object_comparator_t = typename BasicJsonType::default_object_comparator_t; + using type = typename std::conditional < has_key_compare::value, + typename object_t::key_compare, object_comparator_t>::type; +}; + +template +using actual_object_comparator_t = typename actual_object_comparator::type; + +///////////////// +// char_traits // +///////////////// + +// Primary template of char_traits calls std char_traits +template +struct char_traits : std::char_traits +{}; + +// Explicitly define char traits for unsigned char since it is not standard +template<> +struct char_traits : std::char_traits +{ + using char_type = unsigned char; + using int_type = uint64_t; + + // Redefine to_int_type function + static int_type to_int_type(char_type c) noexcept + { + return static_cast(c); + } + + static char_type to_char_type(int_type i) noexcept + { + return static_cast(i); + } + + static constexpr int_type eof() noexcept + { + return static_cast(std::char_traits::eof()); + } +}; + +// Explicitly define char traits for signed char since it is not standard +template<> +struct char_traits : std::char_traits +{ + using char_type = signed char; + using int_type = uint64_t; + + // Redefine to_int_type function + static int_type to_int_type(char_type c) noexcept + { + return static_cast(c); + } + + static char_type to_char_type(int_type i) noexcept + { + return static_cast(i); + } + + static constexpr int_type eof() noexcept + { + return static_cast(std::char_traits::eof()); + } +}; + +#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L +template<> +struct char_traits : std::char_traits +{ + using char_type = std::byte; + using int_type = uint64_t; + + static int_type to_int_type(char_type c) noexcept + { + return static_cast(std::to_integer(c)); + } + + static char_type to_char_type(int_type i) noexcept + { + return std::byte(static_cast(i)); + } + + static constexpr int_type eof() noexcept + { + return static_cast(std::char_traits::eof()); + } +}; +#endif + +/////////////////// +// is_ functions // +/////////////////// + +// https://en.cppreference.com/w/cpp/types/conjunction +template struct conjunction : std::true_type { }; +template struct conjunction : B { }; +template +struct conjunction +: std::conditional(B::value), conjunction, B>::type {}; + +// https://en.cppreference.com/w/cpp/types/negation +template struct negation : std::integral_constant < bool, !B::value > { }; + +// Reimplementation of is_constructible and is_default_constructible, due to them being broken for +// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). +// This causes compile errors in e.g., Clang 3.5 or GCC 4.9. +template +struct is_default_constructible : std::is_default_constructible {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + +template +struct is_constructible : std::is_constructible {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_iterator_traits : std::false_type {}; + +template +struct is_iterator_traits> +{ + private: + using traits = iterator_traits; + + public: + static constexpr auto value = + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value; +}; + +template +struct is_range +{ + private: + using t_ref = typename std::add_lvalue_reference::type; + + using iterator = detected_t; + using sentinel = detected_t; + + // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator + // and https://en.cppreference.com/w/cpp/iterator/sentinel_for + // but reimplementing these would be too much work, as a lot of other concepts are used underneath + static constexpr auto is_iterator_begin = + is_iterator_traits>::value; + + public: + static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; +}; + +template +using iterator_t = enable_if_t::value, result_of_begin())>>; + +template +using range_value_t = value_type_t>>; + +// The following implementation of is_complete_type is taken from +// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ +// and is written by Xiang Fan who agreed to use it in this library. + +template +struct is_complete_type : std::false_type {}; + +template +struct is_complete_type : std::true_type {}; + +template +struct is_compatible_object_type_impl : std::false_type {}; + +template +struct is_compatible_object_type_impl < + BasicJsonType, CompatibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + // macOS's is_constructible does not play well with nonesuch... + static constexpr bool value = + is_constructible::value && + is_constructible::value; +}; + +template +struct is_compatible_object_type + : is_compatible_object_type_impl {}; + +template +struct is_constructible_object_type_impl : std::false_type {}; + +template +struct is_constructible_object_type_impl < + BasicJsonType, ConstructibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + static constexpr bool value = + (is_default_constructible::value && + (std::is_move_assignable::value || + std::is_copy_assignable::value) && + (is_constructible::value && + std::is_same < + typename object_t::mapped_type, + typename ConstructibleObjectType::mapped_type >::value)) || + (has_from_json::value || + has_non_default_from_json < + BasicJsonType, + typename ConstructibleObjectType::mapped_type >::value); +}; + +template +struct is_constructible_object_type + : is_constructible_object_type_impl {}; + +template +struct is_compatible_string_type +{ + static constexpr auto value = + is_constructible::value; +}; + +template +struct is_constructible_string_type +{ + // launder type through decltype() to fix compilation failure on ICPC +#ifdef __INTEL_COMPILER + using laundered_type = decltype(std::declval()); +#else + using laundered_type = ConstructibleStringType; +#endif + + static constexpr auto value = + conjunction < + is_constructible, + is_detected_exact>::value; +}; + +template +struct is_compatible_array_type_impl : std::false_type {}; + +template +struct is_compatible_array_type_impl < + BasicJsonType, CompatibleArrayType, + enable_if_t < + is_detected::value&& + is_iterator_traits>>::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 + !std::is_same>::value >> +{ + static constexpr bool value = + is_constructible>::value; +}; + +template +struct is_compatible_array_type + : is_compatible_array_type_impl {}; + +template +struct is_constructible_array_type_impl : std::false_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t::value >> + : std::true_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t < !std::is_same::value&& + !is_compatible_string_type::value&& + is_default_constructible::value&& +(std::is_move_assignable::value || + std::is_copy_assignable::value)&& +is_detected::value&& +is_iterator_traits>>::value&& +is_detected::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 +!std::is_same>::value&& +is_complete_type < +detected_t>::value >> +{ + using value_type = range_value_t; + + static constexpr bool value = + std::is_same::value || + has_from_json::value || + has_non_default_from_json < + BasicJsonType, + value_type >::value; +}; + +template +struct is_constructible_array_type + : is_constructible_array_type_impl {}; + +template +struct is_compatible_integer_type_impl : std::false_type {}; + +template +struct is_compatible_integer_type_impl < + RealIntegerType, CompatibleNumberIntegerType, + enable_if_t < std::is_integral::value&& + std::is_integral::value&& + !std::is_same::value >> +{ + // is there an assert somewhere on overflows? + using RealLimits = std::numeric_limits; + using CompatibleLimits = std::numeric_limits; + + static constexpr auto value = + is_constructible::value && + CompatibleLimits::is_integer && + RealLimits::is_signed == CompatibleLimits::is_signed; +}; + +template +struct is_compatible_integer_type + : is_compatible_integer_type_impl {}; + +template +struct is_compatible_type_impl: std::false_type {}; + +template +struct is_compatible_type_impl < + BasicJsonType, CompatibleType, + enable_if_t::value >> +{ + static constexpr bool value = + has_to_json::value; +}; + +template +struct is_compatible_type + : is_compatible_type_impl {}; + +template +struct is_constructible_tuple : std::false_type {}; + +template +struct is_constructible_tuple> : conjunction...> {}; + +template +struct is_json_iterator_of : std::false_type {}; + +template +struct is_json_iterator_of : std::true_type {}; + +template +struct is_json_iterator_of : std::true_type +{}; + +// checks if a given type T is a template specialization of Primary +template