diff --git a/Makefile b/Makefile index 94eb9478f..66b02100f 100644 --- a/Makefile +++ b/Makefile @@ -1603,7 +1603,7 @@ all: cp build/us_pc/discord_game_sdk.dylib $(APP_MACOS_DIR); \ cp build/us_pc/libdiscord_game_sdk.dylib $(APP_MACOS_DIR); \ cp build/us_pc/libcoopnet.dylib $(APP_MACOS_DIR); \ - cp build/us_pc/libjuice.1.2.2.dylib $(APP_MACOS_DIR); \ + cp build/us_pc/libjuice.1.6.2.dylib $(APP_MACOS_DIR); \ cp $(SDL2_LIB) $(APP_MACOS_DIR)/libSDL2.dylib; \ install_name_tool -change $(BREW_PREFIX)/opt/sdl2/lib/libSDL2-2.0.0.dylib @executable_path/libSDL2.dylib $(APP_MACOS_DIR)/sm64coopdx; > /dev/null 2>&1 \ install_name_tool -id @executable_path/libSDL2.dylib $(APP_MACOS_DIR)/libSDL2.dylib; > /dev/null 2>&1 \ diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index ba1b753fa..5a12779b7 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -93,7 +93,7 @@ override_allowed_functions = { "src/game/object_list_processor.h": [ "set_object_respawn_info_bits" ], "src/game/platform_displacement.h": [ "apply_platform_displacement" ], "src/game/mario_misc.h": [ "bhv_toad.*", "bhv_unlock_door.*", "geo_get_.*_state" ], - "src/game/level_update.h": [ "level_trigger_warp", "get_painting_warp_node", "initiate_painting_warp", "warp_special", "lvl_set_current_level", "level_control_timer_running", "pressed_pause", "fade_into_special_warp", "get_instant_warp" ], + "src/game/level_update.h": [ "level_trigger_warp", "get_painting_warp_node", "initiate_warp", "initiate_painting_warp", "warp_special", "lvl_set_current_level", "level_control_timer_running", "pressed_pause", "fade_into_special_warp", "get_instant_warp" ], "src/game/area.h": [ "get_mario_spawn_type", "area_get_warp_node", "area_get_any_warp_node", "play_transition" ], "src/engine/level_script.h": [ "area_create_warp_node" ], "src/game/ingame_menu.h": [ "set_min_dialog_width", "set_dialog_override_pos", "reset_dialog_override_pos", "set_dialog_override_color", "reset_dialog_override_color", "set_menu_mode", "create_dialog_box", "create_dialog_box_with_var", "create_dialog_inverted_box", "create_dialog_box_with_response", "reset_dialog_render_state", "set_dialog_box_state", "handle_special_dialog_text" ], @@ -159,7 +159,9 @@ lua_function_params = { } parameter_keywords = [ - "OUT", + "VEC_OUT", + "RET", + "INOUT", "OPTIONAL" ] @@ -833,18 +835,45 @@ def build_param(fid, param, i): def build_param_after(param, i): ptype = param['type'] pid = param['identifier'] - is_output = 'OUT' in param + is_output = 'VEC_OUT' in param if ptype in VEC_TYPES and is_output: return (vec_type_after % (ptype.lower())).replace('$[IDENTIFIER]', str(pid)).replace('$[INDEX]', str(i)) else: return '' +def build_return_value(id, rtype): + rtype = alter_type(rtype) + lot = translate_type_to_lot(rtype) + + lfunc = 'UNIMPLEMENTED -->' + if rtype in integer_types: + lfunc = 'lua_pushinteger' + elif rtype in number_types: + lfunc = 'lua_pushnumber' + elif rtype == 'bool': + lfunc = 'lua_pushboolean' + elif rtype == 'char*': + lfunc = 'lua_pushstring' + elif rtype == 'const char*': + lfunc = 'lua_pushstring' + elif rtype == 'ByteString': + lfunc = 'smlua_push_bytestring' + elif rtype == 'LuaTable': + lfunc = 'smlua_push_lua_table' + elif lot == 'LOT_POINTER': + lvt = translate_type_to_lvt(rtype) + return ' smlua_push_pointer(L, %s, (void*)%s, NULL);\n' % (lvt, id) + elif '???' not in lot and lot != 'LOT_NONE': + return ' smlua_push_object(L, %s, %s, NULL);\n' % (lot, id) + + return ' %s(L, %s);\n' % (lfunc, id) + def build_call(function): ftype = alter_type(function['type']) fid = function['identifier'] - ccall = '%s(%s)' % (fid, ', '.join([x['identifier'] for x in function['params']])) + ccall = '%s(%s)' % (fid, ', '.join([('&' if ('RET' in x or 'INOUT' in x) else '') + x['identifier'] for x in function['params']])) if ftype == 'void': return ' %s;\n' % ccall @@ -856,30 +885,21 @@ def build_call(function): if ftype in VECP_TYPES: return ' %s;\n' % ccall - flot = translate_type_to_lot(ftype) + return build_return_value(ccall, ftype) - lfunc = 'UNIMPLEMENTED -->' - if ftype in integer_types: - lfunc = 'lua_pushinteger' - elif ftype in number_types: - lfunc = 'lua_pushnumber' - elif ftype == 'bool': - lfunc = 'lua_pushboolean' - elif ftype == 'char*': - lfunc = 'lua_pushstring' - elif ftype == 'const char*': - 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) - elif '???' not in flot and flot != 'LOT_NONE': - return ' smlua_push_object(L, %s, %s, NULL);\n' % (flot, ccall) - - return ' %s(L, %s);\n' % (lfunc, ccall) +def split_function_parameters_and_returns(function): + fparams = [] + freturns = [] + for param in function['params']: + deref_type = param['type'][:param['type'].rfind('*')].strip() # Remove pointer + if 'INOUT' in param: + fparams.append({ **{ k: v for k, v in param.items() if k != "type" }, "type": deref_type}) + freturns.append({ **param, "rtype": deref_type }) + elif 'RET' in param: + freturns.append({ **param, "rtype": deref_type }) + else: + fparams.append(param) + return fparams, freturns def build_function(function, do_extern): s = '' @@ -888,6 +908,8 @@ def build_function(function, do_extern): if fid in override_function_version_excludes: s += '#ifndef ' + override_function_version_excludes[fid] + '\n' + fparams, freturns = split_function_parameters_and_returns(function) + if len(function['params']) <= 0: s += 'int smlua_func_%s(UNUSED lua_State* L) {\n' % function['identifier'] else: @@ -899,8 +921,8 @@ def build_function(function, do_extern): if 'bhv_' in fid: s += ' if (!gCurrentObject) { return 0; }\n' - params_max = len(function['params']) - params_min = len([param for param in function['params'] if 'OPTIONAL' not in param]) + params_max = len(fparams) + params_min = len([param for param in fparams if 'OPTIONAL' not in param]) if params_min == params_max: s += """ if (L == NULL) { return 0; }\n int top = lua_gettop(L); @@ -919,7 +941,7 @@ def build_function(function, do_extern): is_interact_func = fid.startswith('interact_') and fname == 'interaction.h' i = 1 - for param in function['params']: + for param in fparams: pid = param['identifier'] if is_interact_func and pid == 'interactType': s += " // interactType skipped so mods can't lie about what interaction it is\n" @@ -938,14 +960,25 @@ def build_function(function, do_extern): i += 1 s += '\n' + if freturns: + for param in freturns: + if 'INOUT' not in param: + pid = param['identifier'] + ptype = alter_type(param['rtype']) + s += ' %s %s;\n' % (ptype, pid) + s += '\n' + if do_extern: s += ' extern %s\n' % function['line'] + push_value = True if is_interact_func: # special case for interaction functions to call the hooks associated with interactions s += " lua_pushinteger(L, process_interaction(m, " + fid.upper() + ", o, " + fid + "));\n" else: - s += build_call(function) + call_str = build_call(function) + push_value = "lua_push" in call_str + s += call_str i = 1 for param in function['params']: @@ -953,14 +986,23 @@ def build_function(function, do_extern): i += 1 s += '\n' - # To allow chaining vector functions calls, return the table corresponding to the `OUT` parameter + # To allow chaining vector functions calls, return the table corresponding to the `VEC_OUT` parameter if function['type'] in VECP_TYPES: for i, param in enumerate(function['params']): - if 'OUT' in param: + if 'VEC_OUT' in param: s += ' lua_settop(L, %d);\n' % (i + 1) break - s += ' return 1;\n}\n' + # Push extra return values + if freturns: + for param in freturns: + pid = param['identifier'] + ptype = alter_type(param['rtype']) + s += build_return_value(pid, ptype) + s += '\n' + + num_returns = max(1, push_value + len(freturns)) + s += ' return %d;\n}\n' % num_returns if fid in override_function_version_excludes: s += '#endif\n' @@ -1252,23 +1294,34 @@ def doc_function(fname, function): description = function.get('description', "") rtype, rlink = translate_type_to_lua(function['type']) - param_str = ', '.join([x['identifier'] for x in function['params']]) + param_str = ', '.join([x['identifier'] for x in function['params'] if 'RET' not in x]) if description != "": s += '\n### Description\n' s += f'{description}\n' s += "\n### Lua Example\n" - if rtype != None: - s += "`local %sValue = %s(%s)`\n" % (rtype.replace('`', '').split(' ')[0], fid, param_str) + rvalues = [] + if rtype is not None: + rid = rtype.replace('`', '').split(' ')[0] + rid = rid[0].lower() + rid[1:] + rvalues.append((rid + 'Value', rtype, rlink)) + + fparams, freturns = split_function_parameters_and_returns(function) + for param in freturns: + ptype, plink = translate_type_to_lua(param['rtype']) + rvalues.append((param['identifier'], ptype, plink)) + + if rvalues: + s += "`local %s = %s(%s)`\n" % (", ".join([id for id, _, _ in rvalues]), fid, param_str) else: s += "`%s(%s)`\n" % (fid, param_str) s += '\n### Parameters\n' - if len(function['params']) > 0: + if len(fparams) > 0: s += '| Field | Type |\n' s += '| ----- | ---- |\n' - for param in function['params']: + for param in fparams: pid = param['identifier'] ptype = param['type'] ptype, plink = translate_type_to_lua(ptype) @@ -1288,10 +1341,11 @@ def doc_function(fname, function): s += '\n### Returns\n' if rtype != None: - if rlink: - s += '[%s](%s)\n' % (rtype, rlink) - else: - s += '- %s\n' % rtype + for _, ptype, plink in rvalues: + if plink: + s += '- [%s](%s)\n' % (ptype, plink) + else: + s += '- %s\n' % ptype else: s += '- None\n' @@ -1380,19 +1434,26 @@ def def_function(fname, function): if not doc_should_document(fname, fid): return '' - rtype, rlink = translate_type_to_lua(function['type']) - param_str = ', '.join([x['identifier'] for x in function['params']]) + rtype, _ = translate_type_to_lua(function['type']) + param_str = ', '.join([x['identifier'] for x in function['params'] if 'RET' not in x]) - if rtype == None: - rtype = 'nil' + rtypes = [] + if rtype is not None: + rtypes.append((rtype, None)) + + fparams, freturns = split_function_parameters_and_returns(function) + for param in freturns: + rtype, _ = translate_type_to_lua(param['rtype']) + rid = param['identifier'] + rtypes.append((rtype, rid)) if function['description'].startswith("[DEPRECATED"): s += "--- @deprecated\n" - for param in function['params']: + for param in fparams: pid = param['identifier'] ptype = param['type'] - ptype, plink = translate_type_to_lua(ptype) + ptype, _ = translate_type_to_lua(ptype) ptype = translate_to_def(ptype) if ptype.startswith('Pointer_') and ptype not in def_pointers: @@ -1400,12 +1461,14 @@ def def_function(fname, function): s += '--- @param %s%s %s\n' % (pid, ('?' if 'OPTIONAL' in param else ''), ptype) - rtype = translate_to_def(rtype) - if rtype.startswith('Pointer_') and rtype not in def_pointers: - def_pointers.append(rtype) + for rtype, rid in rtypes: + rtype = translate_to_def(rtype) + if rtype.startswith('Pointer_') and rtype not in def_pointers: + def_pointers.append(rtype) + + if rtype != "nil": + s += ('--- @return %s' % rtype) + (' %s' % rid if rid else '') + '\n' - if rtype != "nil": - s += '--- @return %s\n' % rtype if function['description'] != "": s += "--- %s\n" % (function['description']) s += "function %s(%s)\n -- ...\nend\n\n" % (fid, param_str) diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py index 5cff396b2..3a88390ec 100644 --- a/autogen/convert_structs.py +++ b/autogen/convert_structs.py @@ -118,7 +118,7 @@ override_field_immutable = { "GlobalObjectAnimations": [ "*"], "SpawnParticlesInfo": [ "model" ], "WaterDropletParams": [ "model" ], - "MarioBodyState": [ "updateTorsoTime", "updateHeadPosTime", "animPartsPos", "currAnimPart" ], + "MarioBodyState": [ "updateTorsoTime", "updateHeadPosTime", "animPartsPos", "animPartsRot", "currAnimPart" ], "Area": [ "localAreaTimer", "nextSyncID", "objectSpawnInfos", "paintingWarpNodes", "warpNodes" ], "Mod": [ "*" ], "ModFile": [ "*" ], @@ -550,26 +550,26 @@ def build_struct(struct): endStr += '\n#endif' startStr += ' { ' 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 ) + row.append(startStr ) + row.append('"%s", ' % fid ) + row.append('%s, ' % lvt ) + row.append('(size_t) "%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(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 ) + 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) @@ -577,10 +577,6 @@ def build_struct(struct): struct_lot = 'LOT_%s' % sid.upper() 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) diff --git a/autogen/gen_math.py b/autogen/gen_math.py index e5ef37b6f..8903d4843 100644 --- a/autogen/gen_math.py +++ b/autogen/gen_math.py @@ -4,7 +4,7 @@ VECX_TO_VECY = """ /* |description| Converts a {{size}}D {{desc}} vector `a` into a {{size}}D {{desc_2}} vector and stores the result in `dest` |descriptionEnd| */ -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) { +INLINE OPTIMIZE_O3 Vec{{size}}{{suffix_2}}p vec{{size}}{{suffix}}_to_vec{{size}}{{suffix_2}}(VEC_OUT Vec{{size}}{{suffix_2}} dest, Vec{{size}}{{suffix}} a) { {{body}} return dest; } diff --git a/autogen/lua_constants/deprecated.lua b/autogen/lua_constants/deprecated.lua index 1ea4e98b2..5d11959af 100644 --- a/autogen/lua_constants/deprecated.lua +++ b/autogen/lua_constants/deprecated.lua @@ -5,6 +5,13 @@ FONT_TINY = -1 ANIM_FLAG_FORWARD = (1 << 1) +----------------------- +-- Renamed functions -- +----------------------- + +rom_hack_cam_set_collisions = camera_romhack_set_collisions + + -------------------- -- Math functions -- -------------------- diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index e2fd6a244..f2d30851a 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -3635,7 +3635,7 @@ HUD_DISPLAY_DEFAULT = HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_CO --- | `HUD_DISPLAY_DEFAULT` --- @type integer -LE_MAX_LIGHTS = 256 +LE_MAX_LIGHTS = 512 LE_MODE_AFFECT_ALL_SHADED_AND_COLORED = 0 --- @type LEMode LE_MODE_AFFECT_ALL_SHADED = 1 --- @type LEMode @@ -9523,7 +9523,7 @@ SOUND_PEACH_FOR_MARIO = SOUND_ARG_LOAD(SOUND_BANK_MARIO_VOICE, 0x3E, 0xFF, SOUND SOUND_PEACH_MARIO2 = SOUND_ARG_LOAD(SOUND_BANK_MARIO_VOICE, 0x3F, 0xFF, SOUND_NO_PRIORITY_LOSS | SOUND_DISCRETE) --- @type integer -SOUND_MARIO_LETS_A_GO = SOUND_MENU_STAR_SOUND_LETS_A_GO +SOUND_MARIO_LETS_A_GO = SOUND_ARG_LOAD(SOUND_BANK_MENU, 0x24, 0xFF, SOUND_DISCRETE) --- @type integer SOUND_GENERAL_ACTIVATE_CAP_SWITCH = SOUND_ARG_LOAD(SOUND_BANK_GENERAL, 0x00, 0x80, SOUND_DISCRETE) @@ -11170,7 +11170,7 @@ COOP_OBJ_FLAG_NON_SYNC = (1 << 2) COOP_OBJ_FLAG_INITIALIZED = (1 << 3) --- @type string -SM64COOPDX_VERSION = "v1.4" +SM64COOPDX_VERSION = "v1.4.1" --- @type string VERSION_TEXT = "v" @@ -11179,7 +11179,7 @@ VERSION_TEXT = "v" VERSION_NUMBER = 41 --- @type integer -MINOR_VERSION_NUMBER = 0 +MINOR_VERSION_NUMBER = 1 --- @type string GAME_NAME = "sm64coopdx" diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index adb750035..816cc8018 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -124,9 +124,10 @@ function play_penguin_walking_sound(walk) -- ... end ---- @param angle Pointer_integer +--- @param angle integer --- @return integer ---- Updates the current object's angle from its move flags +--- @return integer angle +--- Computes and returns an angle depending on the current object's angle and move flags function update_angle_from_move_flags(angle) -- ... end @@ -3204,20 +3205,22 @@ function is_within_100_units_of_mario(posX, posY, posZ) -- ... end ---- @param dst Pointer_number +--- @param dst number --- @param goal number --- @param scale number --- @return integer ---- Smoothly transitions or directly sets a floating-point value (`dst`) to approach a target (`goal`). Uses asymptotic scaling for gradual adjustments or direct assignment +--- @return number dst +--- Smoothly transitions or directly sets a floating-point value (`dst`) to approach a target (`goal`). Uses asymptotic scaling for gradual adjustments or direct assignment. Returns FALSE if `dst` reaches `goal` function set_or_approach_f32_asymptotic(dst, goal, scale) -- ... end ---- @param current Pointer_number +--- @param current number --- @param target number --- @param multiplier number --- @return integer ---- Gradually adjusts a floating-point value (`current`) towards a target (`target`) using asymptotic smoothing. Returns true if `current` reaches the `target` and false otherwise +--- @return number current +--- Gradually adjusts a floating-point value (`current`) towards a target (`target`) using asymptotic smoothing. Returns FALSE if `current` reaches the `target` function approach_f32_asymptotic_bool(current, target, multiplier) -- ... end @@ -3231,11 +3234,12 @@ function approach_f32_asymptotic(current, target, multiplier) -- ... end ---- @param current Pointer_integer +--- @param current integer --- @param target integer --- @param divisor integer --- @return integer ---- Gradually adjusts a signed 16-bit integer (`current`) towards a target (`target`) using asymptotic smoothing. Returns true if `current` reaches `target` and false otherwise +--- @return integer current +--- Gradually adjusts a signed 16-bit integer (`current`) towards a target (`target`) using asymptotic smoothing. Returns FALSE if `current` reaches `target` function approach_s16_asymptotic_bool(current, target, divisor) -- ... end @@ -3269,29 +3273,32 @@ function set_or_approach_vec3f_asymptotic(dst, goal, xMul, yMul, zMul) -- ... end ---- @param current Pointer_integer +--- @param current integer --- @param target integer --- @param increment integer --- @return integer ---- Adjusts a signed 16-bit integer (`current`) towards a target (`target`) symmetrically with a fixed increment (`increment`). Returns true if the value reaches the target and false otherwise +--- @return integer current +--- Adjusts a signed 16-bit integer (`current`) towards a target (`target`) symmetrically with a fixed increment (`increment`). Returns FALSE if `current` reaches the `target` function camera_approach_s16_symmetric_bool(current, target, increment) -- ... end ---- @param current Pointer_integer +--- @param current integer --- @param target integer --- @param increment integer --- @return integer ---- Smoothly transitions or directly sets a signed 16-bit value (`current`) to approach a target (`target`). Uses symmetric scaling for gradual or immediate adjustments +--- @return integer current +--- Smoothly transitions or directly sets a signed 16-bit value (`current`) to approach a target (`target`). Uses symmetric scaling for gradual or immediate adjustments. Returns FALSE if `current` reaches the `target` function set_or_approach_s16_symmetric(current, target, increment) -- ... end ---- @param current Pointer_number +--- @param current number --- @param target number --- @param increment number --- @return integer ---- Adjusts a floating-point value (`current`) towards a target (`target`) symmetrically with a fixed increment (`increment`). Returns true if the value reaches the target and false otherwise +--- @return number current +--- Adjusts a floating-point value (`current`) towards a target (`target`) symmetrically with a fixed increment (`increment`). Returns FALSE if `current` reaches the `target` function camera_approach_f32_symmetric_bool(current, target, increment) -- ... end @@ -3364,10 +3371,10 @@ end --- @param from Vec3f --- @param to Vec3f ---- @param pitch Pointer_integer ---- @param yaw Pointer_integer ---- Calculates the pitch and yaw angles from one 3D position (`from`) to another (`to`). Updates the provided pointers with the computed pitch and yaw values -function calculate_angles(from, to, pitch, yaw) +--- @return integer pitch +--- @return integer yaw +--- Calculates and returns the pitch and yaw angles from one 3D position (`from`) to another (`to`) +function calculate_angles(from, to) -- ... end @@ -3453,7 +3460,8 @@ function shake_camera_yaw(pos, focus) -- ... end ---- @param roll Pointer_integer +--- @param roll integer +--- @return integer roll --- Applies a roll-based shake effect to the camera. Simulates rotational disturbances caused by impacts or other events function shake_camera_roll(roll) -- ... @@ -3607,9 +3615,10 @@ end --- @param c Camera --- @param cPos Vec3f ---- @param avoidYaw Pointer_integer +--- @param avoidYaw integer --- @param yawRange integer --- @return integer +--- @return integer avoidYaw --- Rotates the camera to avoid walls or other obstructions. Ensures clear visibility of the player or target objects function rotate_camera_around_walls(c, cPos, avoidYaw, yawRange) -- ... @@ -5039,6 +5048,15 @@ function warp_special(arg) -- ... end +--- @param destLevel integer +--- @param destArea integer +--- @param destWarpNode integer +--- @param arg integer +--- Initiates a warp to `destLevel` in `destArea` at `destWarpNode` with `arg`. This function is unstable and it's generally recommended to use `warp_to_level` instead +function initiate_warp(destLevel, destArea, destWarpNode, arg) + -- ... +end + --- @param param integer --- @param levelNum integer --- @return integer @@ -5439,6 +5457,24 @@ function resolve_and_return_wall_collisions_data(pos, offset, radius, collisionD -- ... end +--- @param pos Vec3f +--- @param height number +--- @return number +--- @return Surface ceil +--- Finds the ceiling from a vec3f horizontally and a height (with 80 vertical buffer). Returns the ceiling height and surface +function vec3f_find_ceil(pos, height) + -- ... +end + +--- @param pos Vec3f +--- @param height number +--- @return number +--- @return Surface ceil +--- Finds the ceiling from a vec3f horizontally and a height (with 80 vertical buffer). Prevents exposed ceiling bug. Returns the ceiling height and surface +function vec3f_mario_ceil(pos, height) + -- ... +end + --- @param m MarioState --- @param turnYaw integer --- @return integer @@ -6584,11 +6620,11 @@ end --- @param from Vec3f --- @param to Vec3f ---- @param dist Pointer_number ---- @param pitch Pointer_integer ---- @param yaw Pointer_integer ---- Calculates the distance between two points in 3D space (`from` and `to`), as well as the pitch and yaw angles that describe the direction from `from` to `to`. The results are stored in `dist`, `pitch`, and `yaw` -function vec3f_get_dist_and_angle(from, to, dist, pitch, yaw) +--- @return number dist +--- @return integer pitch +--- @return integer yaw +--- Calculates the distance between two points in 3D space (`from` and `to`), as well as the pitch and yaw angles that describe the direction from `from` to `to`. Returns the calculated distance, pitch and yaw +function vec3f_get_dist_and_angle(from, to) -- ... end @@ -7917,10 +7953,10 @@ function obj_orient_graph(obj, normalX, normalY, normalZ) -- ... end ---- @param objFriction Pointer_number --- @param floor_nY number ---- Orients an object with the given normals, typically the surface under the object. -function calc_obj_friction(objFriction, floor_nY) +--- @return number objFriction +--- Determines an object's forward speed multiplier. +function calc_obj_friction(floor_nY) -- ... end @@ -8276,11 +8312,12 @@ function obj_turn_pitch_toward_mario(m, targetOffsetY, turnAmount) -- ... end ---- @param px Pointer_number +--- @param px number --- @param target number --- @param delta number --- @return integer ---- Approaches a `target` for `px` using `delta` +--- @return number px +--- Approaches a `target` for `px` using `delta`. Returns TRUE if `px` reaches `target` function approach_f32_ptr(px, target, delta) -- ... end @@ -8333,14 +8370,16 @@ function obj_face_roll_approach(targetRoll, deltaRoll) -- ... end ---- @param angleVel Pointer_integer ---- @param angle Pointer_integer +--- @param angleVel integer +--- @param angle integer --- @param targetAngle integer --- @param targetSpeedProportion number --- @param accel integer --- @param minSpeed integer --- @param maxSpeed integer --- @return integer +--- @return integer angleVel +--- @return integer angle function obj_smooth_turn(angleVel, angle, targetAngle, targetSpeedProportion, accel, minSpeed, maxSpeed) -- ... end @@ -8377,45 +8416,49 @@ function obj_random_fixed_turn(delta) -- ... end ---- @param scaleVel Pointer_number +--- @param scaleVel number --- @param shootFireScale number --- @param endScale number --- @return integer ---- Begin by increasing the current object's scale by `*scaleVel`, and slowly decreasing `scaleVel`. Once the object starts to shrink, wait a bit, and then begin to scale the object toward `endScale`. The first time it reaches below `shootFireScale` during this time, return 1. Return -1 once it's reached endScale +--- @return number scaleVel +--- Begin by increasing the current object's scale by `scaleVel`, and slowly decreasing `scaleVel`. Once the object starts to shrink, wait a bit, and then begin to scale the object toward `endScale`. The first time it reaches below `shootFireScale` during this time, return 1. Return -1 once it's reached endScale function obj_grow_then_shrink(scaleVel, shootFireScale, endScale) -- ... end ---- @param value Pointer_integer ---- @param vel Pointer_number +--- @param value integer +--- @param vel number --- @param target integer --- @param velCloseToZero number --- @param accel number --- @param slowdown number --- @return integer +--- @return integer value +--- @return number vel function oscillate_toward(value, vel, target, velCloseToZero, accel, slowdown) -- ... end ---- @param blinkTimer Pointer_integer +--- @param blinkTimer integer --- @param baseCycleLength integer --- @param cycleLengthRange integer --- @param blinkLength integer +--- @return integer blinkTimer function obj_update_blinking(blinkTimer, baseCycleLength, cycleLengthRange, blinkLength) -- ... end ---- @param targetYaw Pointer_integer --- @return integer ---- Resolves "collisions" with the current object and other objects by offsetting the current object's position -function obj_resolve_object_collisions(targetYaw) +--- @return integer targetYaw +--- Resolves "collisions" with the current object and other objects by offsetting the current object's position. Returns TRUE and the target yaw if there is collision +function obj_resolve_object_collisions() -- ... end ---- @param targetYaw Pointer_integer --- @return integer ---- Bounces the current object off of walls, edges, and objects using `*targetYaw` -function obj_bounce_off_walls_edges_objects(targetYaw) +--- @return integer targetYaw +--- Bounces the current object off of walls, edges, and objects. Returns TRUE and the target yaw if there is collision +function obj_bounce_off_walls_edges_objects() -- ... end @@ -8493,10 +8536,10 @@ function obj_move_for_one_second(endAction) end --- @param threshold number ---- @param distanceToPlayer Pointer_integer ---- @param angleToPlayer Pointer_integer ---- Moves the current object for specifically one second (`oTimer` < 30) -function treat_far_home_as_mario(threshold, distanceToPlayer, angleToPlayer) +--- @return integer distanceToPlayer +--- @return integer angleToPlayer +--- Treats far home as Mario. Returns the distance and angle to the nearest player +function treat_far_home_as_mario(threshold) -- ... end @@ -8513,9 +8556,11 @@ function obj_spit_fire(relativePosX, relativePosY, relativePosZ, scale, model, s -- ... end ---- @param bitSet Pointer_integer +--- @param bitSet integer --- @param flag integer --- @return integer +--- @return integer bitSet +--- Clears the `flag` from the `bitSet` function clear_move_flag(bitSet, flag) -- ... end @@ -8581,10 +8626,11 @@ function cur_obj_forward_vel_approach_upward(target, increment) -- ... end ---- @param value Pointer_number +--- @param value number --- @param target number --- @param increment number --- @return integer +--- @return number value function approach_f32_signed(value, target, increment) -- ... end @@ -8905,9 +8951,9 @@ function cur_obj_find_nearest_pole() end --- @param behavior Pointer_BehaviorScript ---- @param dist Pointer_number --- @return Object -function cur_obj_find_nearest_object_with_behavior(behavior, dist) +--- @return number dist +function cur_obj_find_nearest_object_with_behavior(behavior) -- ... end @@ -9084,8 +9130,9 @@ function cur_obj_update_floor_height_and_get_floor() -- ... end ---- @param value Pointer_number +--- @param value number --- @param dragStrength number +--- @return number value function apply_drag_to_value(value, dragStrength) -- ... end @@ -10301,7 +10348,7 @@ end --- @param enable integer --- Toggles collision settings for the ROM hack camera. This enables or disables specific collision behaviors in modded levels -function rom_hack_cam_set_collisions(enable) +function camera_romhack_set_collisions(enable) -- ... end @@ -10805,6 +10852,14 @@ function gfx_get_texture(cmd) -- ... end +--- @param name string +--- @return Pointer_Gfx +--- @return integer length +--- Gets a display list of the current mod from its name. Returns a pointer to the display list and its length +function gfx_get_from_name(name) + -- ... +end + --- @param gfx Pointer_Gfx --- @return string --- Gets the name of a display list @@ -10868,6 +10923,14 @@ function gfx_delete_all() -- ... end +--- @param name string +--- @return Pointer_Vtx +--- @return integer count +--- Gets a vertex buffer of the current mod from its name. Returns a pointer to the vertex buffering and its vertex count +function vtx_get_from_name(name) + -- ... +end + --- @param vtx Pointer_Vtx --- @return string --- Gets the name of a vertex buffer @@ -11347,6 +11410,15 @@ function get_mario_anim_part_pos(m, animPart, pos) -- ... end +--- @param m MarioState +--- @param animPart integer +--- @param rot Vec3s +--- @return boolean +--- Retrieves the animated part rotation associated to `animPart` from the MarioState `m` and stores it into `rot`. Returns `true` on success or `false` on failure +function get_mario_anim_part_rot(m, animPart, rot) + -- ... +end + --- @return integer --- Gets the current save file number (1-indexed) function get_current_save_file_num() @@ -12300,6 +12372,16 @@ function find_wall_collisions(colData) -- ... end +--- @param posX number +--- @param posY number +--- @param posZ number +--- @return number +--- @return Surface pceil +--- Finds the height of the highest ceiling above a given position (x, y, z) and return the corresponding ceil surface. If no ceiling is found, returns the default height limit of `gLevelValues.cellHeightLimit`(20000 by default) +function find_ceil(posX, posY, posZ) + -- ... +end + --- @param x number --- @param y number --- @param z number @@ -12318,6 +12400,16 @@ function find_floor_height(x, y, z) -- ... end +--- @param xPos number +--- @param yPos number +--- @param zPos number +--- @return number +--- @return Surface pfloor +--- Finds the height of the highest floor below a given position (x, y, z) and return the corresponding floor surface. If no floor is found, returns the default floor height of `gLevelValues.floorLowerLimit`(-11000 by default) +function find_floor(xPos, yPos, zPos) + -- ... +end + --- @param x number --- @param z number --- @return number @@ -12412,9 +12504,8 @@ function sync_object_is_owned_locally(syncId) -- ... end ---- @alias Pointer_integer integer --- @alias Pointer_BehaviorScript BehaviorScript ---- @alias Pointer_number number +--- @alias Pointer_integer integer --- @alias Pointer_Vec4s Vec4s --- @alias Pointer_Trajectory Trajectory --- @alias Pointer_Collision Collision diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index cae4894d4..c971ce2ff 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -195,6 +195,7 @@ --- @field public RespawnShellBoxes integer --- @field public MultipleCapCollection integer --- @field public InfiniteRenderDistance integer +--- @field public ProcessLODs integer --- @field public CourtyardBoosRequirement integer --- @field public starsNeededForDialog StarsNeededForDialog --- @field public dialogs BehaviorDialogs @@ -1085,6 +1086,7 @@ --- @field public torsoPos Vec3f --- @field public heldObjLastPosition Vec3f --- @field public animPartsPos Vec3f[] +--- @field public animPartsRot Vec3s[] --- @field public currAnimPart integer --- @field public updateTorsoTime integer --- @field public updateHeadPosTime integer diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index 29331f45d..e0b699d9d 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -3,6 +3,7 @@ #ifdef __cplusplus #include "dynos.h" +#include extern "C" { #include "engine/behavior_script.h" @@ -158,6 +159,9 @@ public: template T *Read(T *aBuffer, s32 aCount) const { + if (aCount <= 0 || aBuffer == NULL) { + return aBuffer; + } if (mOffset + aCount * sizeof(T) <= mSize) { memcpy(aBuffer, mData + mOffset, aCount * sizeof(T)); mOffset += aCount * sizeof(T); @@ -176,6 +180,9 @@ public: template void Write(const T *aBuffer, s32 aCount) { + if (aCount <= 0 || aBuffer == NULL) { + return; + } if (!mReadOnly) { Grow(mOffset + aCount * sizeof(T)); memcpy(mData + mOffset, aBuffer, aCount * sizeof(T)); @@ -304,6 +311,10 @@ public: public: void Read(BinFile *aFile) { s32 _Length = aFile->Read(); + if (_Length <= 0) { + Resize(0); + return; + } Resize(_Length); aFile->Read(mBuffer, _Length); } @@ -597,8 +608,8 @@ struct PackData { bool mEnabled; SysPath mPath; String mDisplayName; - Array> mGfxData; - Array*> mTextures; + std::vector> mGfxData; + std::vector*> mTextures; bool mLoaded; }; @@ -878,7 +889,7 @@ void DynOS_Pack_SetEnabled(PackData* aPack, bool aEnabled); PackData* DynOS_Pack_GetFromIndex(s32 aIndex); PackData* DynOS_Pack_GetFromPath(const SysPath& aPath); PackData* DynOS_Pack_Add(const SysPath& aPath); -Pair* DynOS_Pack_GetActor(PackData* aPackData, const char* aActorName); +std::pair* DynOS_Pack_GetActor(PackData* aPackData, const char* aActorName); void DynOS_Pack_AddActor(PackData* aPackData, const char* aActorName, GfxData* aGfxData); DataNode* DynOS_Pack_GetTex(PackData* aPackData, const char* aTexName); void DynOS_Pack_AddTex(PackData* aPackData, DataNode* aTexData); @@ -927,7 +938,7 @@ void DynOS_Tex_ModShutdown(); // Lvl Manager // -Array> &DynOS_Lvl_GetArray(); +std::vector> &DynOS_Lvl_GetArray(); LevelScript* DynOS_Lvl_GetScript(const char* aScriptEntryName); void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilePath, const char *aLevelName); GfxData* DynOS_Lvl_GetActiveGfx(void); @@ -942,7 +953,7 @@ void DynOS_Lvl_ModShutdown(); // Bhv Manager // -Array> &DynOS_Bhv_GetArray(); +std::vector> &DynOS_Bhv_GetArray(); void DynOS_Bhv_Activate(s32 modIndex, const SysPath &aFilename, const char *aBehaviorName); GfxData *DynOS_Bhv_GetActiveGfx(BehaviorScript *bhvScript); bool DynOS_Bhv_GetActiveModIndex(BehaviorScript *bhvScript, s32 *modIndex, s32 *modFileIndex); diff --git a/data/dynos_bin_col.cpp b/data/dynos_bin_col.cpp index a9e88c921..cd5a58e50 100644 --- a/data/dynos_bin_col.cpp +++ b/data/dynos_bin_col.cpp @@ -64,9 +64,6 @@ static void ValidateColSectionChange(GfxData* aGfxData, struct CollisionValidati } static void ValidateColInit(GfxData* aGfxData, struct CollisionValidationData& aColValData) { - if (aColValData.tokenIndex != 0) { - PrintDataError("COL_INIT found after the first token"); - } ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_VTX); } diff --git a/data/dynos_bin_pointer.cpp b/data/dynos_bin_pointer.cpp index f660bbe47..e619d7631 100644 --- a/data/dynos_bin_pointer.cpp +++ b/data/dynos_bin_pointer.cpp @@ -13,6 +13,7 @@ typedef Pair PointerData; static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) { // Lights for (auto& _Node : aGfxData->mLights) { + if (!_Node->mData) { continue; } if (&_Node->mData->l[0] == aPtr) { // Light *, not Lights1 * return { _Node->mName, 1 }; } @@ -23,6 +24,7 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) { // Light0s for (auto& _Node : aGfxData->mLight0s) { + if (!_Node->mData) { continue; } if (&_Node->mData->l[0] == aPtr) { // Light *, not Lights1 * return { _Node->mName, 1 }; } @@ -33,6 +35,7 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) { // Light_ts for (auto& _Node : aGfxData->mLightTs) { + if (!_Node->mData) { continue; } if (&_Node->mData->col[0] == aPtr) { return { _Node->mName, 1 }; } @@ -46,6 +49,7 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) { // Ambient_ts for (auto& _Node : aGfxData->mAmbientTs) { + if (!_Node->mData) { continue; } if (&_Node->mData->col[0] == aPtr) { return { _Node->mName, 1 }; } @@ -81,7 +85,7 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) { return { _Node->mName, 0 }; } } - + // Collisions for (auto& _Node : aGfxData->mCollisions) { if (_Node->mData == aPtr) { @@ -153,7 +157,7 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) { if (builtinCol != NULL) { return { builtinCol, 0 }; } - + // Built-in Animations auto builtinAnim = DynOS_Builtin_Anim_GetFromData((const Animation *)aPtr); if (builtinAnim != NULL) { @@ -360,7 +364,7 @@ static void *GetPointerFromData(GfxData *aGfxData, const String &aPtrName, u32 a return (void *) (_Node->mData + aPtrData); } } - + // Behavior scripts for (auto &_Node : aGfxData->mBehaviorScripts) { if (_Node->mName == aPtrName) { @@ -432,7 +436,7 @@ static void *GetPointerFromData(GfxData *aGfxData, const String &aPtrName, u32 a if (builtinCol != NULL) { return (void*)builtinCol; } - + // Built-in Animations auto builtinAnim = DynOS_Builtin_Anim_GetFromName(aPtrName.begin()); if (builtinAnim != NULL) { diff --git a/data/dynos_level.cpp b/data/dynos_level.cpp index bd03604da..a630fd1d7 100644 --- a/data/dynos_level.cpp +++ b/data/dynos_level.cpp @@ -54,7 +54,9 @@ static s32 sDynosCustomLevelSlot[LEVEL_UNKNOWN_2 + 1] = { 0 }; u64 DynOS_Level_CmdGet(void *aCmd, u64 aOffset) { u64 _Offset = (((aOffset) & 3llu) | (((aOffset) & ~3llu) << (sizeof(void *) >> 3llu))); - return *((u64 *) (u64(aCmd) + _Offset)); + u64 value = 0; + memcpy(&value, (void *) ((uintptr_t) aCmd + _Offset), sizeof(value)); + return value; } LvlCmd *DynOS_Level_CmdNext(LvlCmd *aCmd) { diff --git a/data/dynos_mgr_actor.cpp b/data/dynos_mgr_actor.cpp index fda357d0c..802a4ee37 100644 --- a/data/dynos_mgr_actor.cpp +++ b/data/dynos_mgr_actor.cpp @@ -18,8 +18,8 @@ static std::map& DynosValidActors() { return sDynosValidActors; } -static Array>& DynosCustomActors() { - static Array> sDynosCustomActors; +static std::vector> &DynosCustomActors() { + static std::vector> sDynosCustomActors; return sDynosCustomActors; } @@ -35,14 +35,11 @@ std::map &DynOS_Actor_GetValidActors() { 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); - char* actorName = (char*)calloc(1, sizeof(char) * (actorLen + 1)); - strcpy(actorName, aActorName); + std::string actorName = aActorName; - GfxData *_GfxData = DynOS_Actor_LoadFromBinary(aFilename, actorName, aFilename, false); + GfxData *_GfxData = DynOS_Actor_LoadFromBinary(aFilename, actorName.c_str(), aFilename, false); if (!_GfxData) { - PrintError(" ERROR: Couldn't load Actor Binary \"%s\" from \"%s\"", actorName, aFilename.c_str()); - free(actorName); + PrintError(" ERROR: Couldn't load Actor Binary \"%s\" from \"%s\"", actorName.c_str(), aFilename.c_str()); return false; } _GfxData->mModIndex = aModIndex; @@ -50,8 +47,7 @@ bool DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFil void* geoLayout = (*(_GfxData->mGeoLayouts.end() - 1))->mData; if (!geoLayout) { - PrintError(" ERROR: Couldn't load geo layout for \"%s\"", actorName); - free(actorName); + PrintError(" ERROR: Couldn't load geo layout for \"%s\"", actorName.c_str()); return false; } @@ -62,21 +58,19 @@ bool DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFil actorGfx.mPackIndex = MOD_PACK_INDEX; actorGfx.mGraphNode = (GraphNode *) DynOS_Model_LoadGeo(&id, MODEL_POOL_SESSION, geoLayout, true); if (!actorGfx.mGraphNode) { - PrintError(" ERROR: Couldn't load graph node for \"%s\"", actorName); - free(actorName); + PrintError(" ERROR: Couldn't load graph node for \"%s\"", actorName.c_str()); return false; } actorGfx.mGraphNode->georef = georef; // Add to custom actors if (georef == NULL) { - DynosCustomActors().Add({ strdup(actorName), geoLayout }); + DynosCustomActors().emplace_back(actorName, geoLayout); georef = geoLayout; } // Add to list DynOS_Actor_Valid(georef, actorGfx); - free(actorName); return true; } @@ -95,7 +89,7 @@ const void *DynOS_Actor_GetLayoutFromName(const char *aActorName) { // check custom actors for (auto& pair : DynosCustomActors()) { - if (!strcmp(aActorName, pair.first)) { + if (pair.first == aActorName) { return pair.second; } } @@ -297,12 +291,10 @@ void DynOS_Actor_RegisterModifiedGraphNode(GraphNode *aNode) { void DynOS_Actor_ModShutdown() { auto& _DynosCustomActors = DynosCustomActors(); - while (_DynosCustomActors.Count() > 0) { - auto& pair = _DynosCustomActors[0]; + for (auto &pair : _DynosCustomActors) { DynOS_Actor_Invalid(pair.second, MOD_PACK_INDEX); - free((void*)pair.first); - _DynosCustomActors.Remove(0); } + _DynosCustomActors.clear(); auto& _ValidActors = DynosValidActors(); for (auto it = _ValidActors.cbegin(); it != _ValidActors.cend();) { diff --git a/data/dynos_mgr_bhv.cpp b/data/dynos_mgr_bhv.cpp index 9f501d577..bb6aa7b86 100644 --- a/data/dynos_mgr_bhv.cpp +++ b/data/dynos_mgr_bhv.cpp @@ -6,8 +6,8 @@ extern "C" { #include "pc/lua/smlua_hooks.h" } -Array> &DynOS_Bhv_GetArray() { - static Array> sDynosCustomBehaviorScripts; +std::vector> &DynOS_Bhv_GetArray() { + static std::vector> sDynosCustomBehaviorScripts; return sDynosCustomBehaviorScripts; } @@ -15,44 +15,37 @@ void DynOS_Bhv_Activate(s32 modIndex, const SysPath &aFilename, const char *aBeh auto &_CustomBehaviorScripts = DynOS_Bhv_GetArray(); // check for duplicates - for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) { - if (!strcmp(_CustomBehaviorScripts[i].first, aBehaviorName)) { + for (auto &behavior : _CustomBehaviorScripts) { + if (behavior.first == aBehaviorName) { return; } } - u16 behaviorLen = strlen(aBehaviorName); - char *behaviorName = (char *)calloc(1, sizeof(char) * (behaviorLen + 1)); - strcpy(behaviorName, aBehaviorName); + std::string behaviorName = aBehaviorName; - GfxData *_Node = DynOS_Bhv_LoadFromBinary(aFilename, behaviorName); - if (!_Node) { - free(behaviorName); - return; - } + GfxData *_Node = DynOS_Bhv_LoadFromBinary(aFilename, behaviorName.c_str()); + if (!_Node) { return; } // Remember index _Node->mModIndex = modIndex; // Add to behaviors - _CustomBehaviorScripts.Add({ behaviorName, _Node }); + _CustomBehaviorScripts.emplace_back(behaviorName, _Node); } void DynOS_Bhv_ModShutdown() { auto &_CustomBehaviorScripts = DynOS_Bhv_GetArray(); - while (_CustomBehaviorScripts.Count() > 0) { - auto &pair = _CustomBehaviorScripts[0]; + for (auto &pair : _CustomBehaviorScripts) { Delete(pair.second); - free((void *)pair.first); - _CustomBehaviorScripts.Remove(0); } + _CustomBehaviorScripts.clear(); } GfxData *DynOS_Bhv_GetActiveGfx(BehaviorScript *bhvScript) { auto &_CustomBehaviorScripts = DynOS_Bhv_GetArray(); - for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) { - auto &gfxData = _CustomBehaviorScripts[i].second; + for (auto &behavior : _CustomBehaviorScripts) { + auto &gfxData = behavior.second; auto &scripts = gfxData->mBehaviorScripts; if (scripts.Count() == 0) { continue; } if (bhvScript == scripts[scripts.Count() - 1]->mData) { @@ -65,8 +58,8 @@ GfxData *DynOS_Bhv_GetActiveGfx(BehaviorScript *bhvScript) { bool DynOS_Bhv_GetActiveModIndex(BehaviorScript *bhvScript, s32 *modIndex, s32 *modFileIndex) { auto &_CustomBehaviorScripts = DynOS_Bhv_GetArray(); - for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) { - auto &gfxData = _CustomBehaviorScripts[i].second; + for (auto &behavior : _CustomBehaviorScripts) { + auto &gfxData = behavior.second; auto &scripts = gfxData->mBehaviorScripts; if (scripts.Count() == 0) { continue; } if (bhvScript == scripts[scripts.Count() - 1]->mData) { @@ -97,17 +90,17 @@ const char *DynOS_Bhv_GetToken(BehaviorScript *bhvScript, u32 index) { void DynOS_Bhv_HookAllCustomBehaviors() { auto &_CustomBehaviorScripts = DynOS_Bhv_GetArray(); - for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) { - auto &scriptName = _CustomBehaviorScripts[i].first; - auto &aGfxData = _CustomBehaviorScripts[i].second; + for (auto &behavior : _CustomBehaviorScripts) { + auto &scriptName = behavior.first; + auto &aGfxData = behavior.second; if (aGfxData->mBehaviorScripts.Count() == 0) { continue; } auto *node = aGfxData->mBehaviorScripts[aGfxData->mBehaviorScripts.Count() - 1]; if (node == nullptr) { continue; } auto &script = node->mData; // Theres currently no better place but to do this here. - if (smlua_hook_custom_bhv(script, scriptName) == 0) { - PrintDataError(" ERROR: Failed to add custom behavior '%s'!", scriptName); + if (smlua_hook_custom_bhv(script, scriptName.c_str()) == 0) { + PrintDataError(" ERROR: Failed to add custom behavior '%s'!", scriptName.c_str()); } } -} \ No newline at end of file +} diff --git a/data/dynos_mgr_col.cpp b/data/dynos_mgr_col.cpp index 66bf497ae..7678eee24 100644 --- a/data/dynos_mgr_col.cpp +++ b/data/dynos_mgr_col.cpp @@ -4,8 +4,8 @@ extern "C" { #include "pc/mods/mod_fs.h" } -static Array*>>& DynosCollisions() { - static Array*>> sDynosCollisions; +static std::vector*>> &DynosCollisions() { + static std::vector*>> sDynosCollisions; return sDynosCollisions; } @@ -13,26 +13,18 @@ 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)) { + for (auto &collision : _DynosCollisions) { + if (collision.first == aCollisionName) { return true; } } - // Allocate name - u16 collisionLen = strlen(aCollisionName); - char* collisionName = (char*)calloc(1, sizeof(char) * (collisionLen + 1)); - strcpy(collisionName, aCollisionName); - // Load - DataNode* _Node = DynOS_Col_LoadFromBinary(aFilename, collisionName); - if (!_Node) { - free(collisionName); - return false; - } + DataNode* _Node = DynOS_Col_LoadFromBinary(aFilename, aCollisionName); + if (!_Node) { return false; } // Add to collisions - _DynosCollisions.Add({ collisionName, _Node }); + _DynosCollisions.emplace_back(aCollisionName, _Node); return true; } @@ -50,9 +42,9 @@ Collision* DynOS_Col_Get(const char* collisionName) { } // check mod actor collisions - for (s32 i = 0; i < _DynosCollisions.Count(); ++i) { - if (!strcmp(_DynosCollisions[i].first, collisionName)) { - return _DynosCollisions[i].second->mData; + for (auto &collision : _DynosCollisions) { + if (collision.first == collisionName) { + return collision.second->mData; } } @@ -69,10 +61,8 @@ Collision* DynOS_Col_Get(const char* collisionName) { void DynOS_Col_ModShutdown() { auto& _DynosCollisions = DynosCollisions(); - while (_DynosCollisions.Count() > 0) { - auto& pair = _DynosCollisions[0]; - free((void*)pair.first); + for (auto &pair : _DynosCollisions) { Delete(pair.second); - _DynosCollisions.Remove(0); } + _DynosCollisions.clear(); } diff --git a/data/dynos_mgr_lvl.cpp b/data/dynos_mgr_lvl.cpp index 56f1b7e96..6d1aa7de0 100644 --- a/data/dynos_mgr_lvl.cpp +++ b/data/dynos_mgr_lvl.cpp @@ -6,26 +6,26 @@ extern "C" { } struct OverrideLevelScript { - const void* originalScript; - const void* newScript; - GfxData* gfxData; + const void *originalScript; + const void *newScript; + GfxData *gfxData; }; -static Array& DynosOverrideLevelScripts() { - static Array sDynosOverrideLevelScripts; +static std::vector &DynosOverrideLevelScripts() { + static std::vector sDynosOverrideLevelScripts; return sDynosOverrideLevelScripts; } -Array> &DynOS_Lvl_GetArray() { - static Array> sDynosCustomLevelScripts; +std::vector> &DynOS_Lvl_GetArray() { + static std::vector> sDynosCustomLevelScripts; return sDynosCustomLevelScripts; } LevelScript* DynOS_Lvl_GetScript(const char* aScriptEntryName) { auto& _CustomLevelScripts = DynOS_Lvl_GetArray(); - for (s32 i = 0; i < _CustomLevelScripts.Count(); ++i) { + for (size_t i = 0; i < _CustomLevelScripts.size(); ++i) { auto& pair = _CustomLevelScripts[i]; - if (!strcmp(pair.first, aScriptEntryName)) { + if (pair.first == aScriptEntryName) { auto& newScripts = pair.second->mLevelScripts; auto& newScriptNode = newScripts[newScripts.Count() - 1]; return newScriptNode->mData; @@ -38,17 +38,16 @@ void DynOS_Lvl_ModShutdown() { DynOS_Level_Unoverride(); auto& _CustomLevelScripts = DynOS_Lvl_GetArray(); - while (_CustomLevelScripts.Count() > 0) { + if (!_CustomLevelScripts.empty()) { for (auto& pair : _CustomLevelScripts) { DynOS_Tex_Invalid(pair.second); Delete(pair.second); - free((void*)pair.first); } - _CustomLevelScripts.Clear(); + _CustomLevelScripts.clear(); } auto& _OverrideLevelScripts = DynosOverrideLevelScripts(); - _OverrideLevelScripts.Clear(); + _OverrideLevelScripts.clear(); } void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLevelName) { @@ -59,19 +58,16 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev DynOS_Level_Init(); // check for duplicates - for (s32 i = 0; i < _CustomLevelScripts.Count(); ++i) { - if (!strcmp(_CustomLevelScripts[i].first, aLevelName)) { + for (auto &customLevel : _CustomLevelScripts) { + if (customLevel.first == aLevelName) { return; } } - u16 levelLen = strlen(aLevelName); - char* levelName = (char*)calloc(1, sizeof(char) * (levelLen + 1)); - strcpy(levelName, aLevelName); + std::string levelName = aLevelName; - GfxData* _Node = DynOS_Lvl_LoadFromBinary(aFilename, levelName); + GfxData* _Node = DynOS_Lvl_LoadFromBinary(aFilename, levelName.c_str()); if (!_Node) { - free(levelName); return; } @@ -79,7 +75,7 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev _Node->mModIndex = modIndex; // Add to levels - _CustomLevelScripts.Add({ levelName, _Node }); + _CustomLevelScripts.emplace_back(levelName, _Node); DynOS_Tex_Valid(_Node); // Override vanilla script @@ -96,13 +92,13 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev } DynOS_Level_Override((void*)originalScript, newScriptNode->mData, modIndex); - _OverrideLevelScripts.Add({ originalScript, newScriptNode->mData, _Node}); + _OverrideLevelScripts.push_back({ originalScript, newScriptNode->mData, _Node}); } GfxData* DynOS_Lvl_GetActiveGfx(void) { auto& _CustomLevelScripts = DynOS_Lvl_GetArray(); - for (s32 i = 0; i < _CustomLevelScripts.Count(); ++i) { - auto& gfxData = _CustomLevelScripts[i].second; + for (auto &lvlEntry : _CustomLevelScripts) { + auto& gfxData = lvlEntry.second; auto& scripts = gfxData->mLevelScripts; for (auto& s : scripts) { if (gLevelScriptActive == s->mData) { @@ -200,4 +196,3 @@ void *DynOS_Lvl_Override(void *aCmd) { return aCmd; } - diff --git a/data/dynos_mgr_movtexqc.cpp b/data/dynos_mgr_movtexqc.cpp index b4422b39c..d07767d57 100644 --- a/data/dynos_mgr_movtexqc.cpp +++ b/data/dynos_mgr_movtexqc.cpp @@ -10,8 +10,8 @@ struct RegisteredMovtexQC { s16 type; }; -static Array& DynosRegisteredMovtexQCs() { - static Array sDynosRegisteredMovtexQCs; +static std::vector &DynosRegisteredMovtexQCs() { + static std::vector sDynosRegisteredMovtexQCs; return sDynosRegisteredMovtexQCs; } @@ -28,7 +28,7 @@ void DynOS_MovtexQC_Register(const char* name, s16 level, s16 area, s16 type) { for (auto& node : lvlPair.second->mMovtexQCs) { if (node->mName == name) { // add it - _DynosRegisteredMovtexQCs.Add({ + _DynosRegisteredMovtexQCs.push_back({ .dataNode = node, .level = level, .area = area, @@ -70,9 +70,8 @@ DataNode* DynOS_MovtexQC_GetFromIndex(s32 index) { void DynOS_MovtexQC_ModShutdown() { auto& _DynosRegisteredMovtexQCs = DynosRegisteredMovtexQCs(); - while (_DynosRegisteredMovtexQCs.Count() > 0) { - auto& registered = _DynosRegisteredMovtexQCs[0]; + for (auto ®istered : _DynosRegisteredMovtexQCs) { Delete(registered.dataNode); - _DynosRegisteredMovtexQCs.Remove(0); } + _DynosRegisteredMovtexQCs.clear(); } diff --git a/data/dynos_mgr_pack.cpp b/data/dynos_mgr_pack.cpp index 82c804fbc..9bd54ad92 100644 --- a/data/dynos_mgr_pack.cpp +++ b/data/dynos_mgr_pack.cpp @@ -1,10 +1,11 @@ +#include #include "dynos.cpp.h" extern "C" { #include "engine/graph_node.h" } -static Array& DynosPacks() { - static Array sDynosPacks; +static std::deque& DynosPacks() { + static std::deque sDynosPacks; return sDynosPacks; } @@ -37,8 +38,8 @@ static void ScanPackBins(struct PackData* aPack) { } } -static void DynOS_Pack_ActivateActor(s32 aPackIndex, Pair& pair) { - const char* aActorName = pair.first; +static void DynOS_Pack_ActivateActor(s32 aPackIndex, std::pair &pair) { + const char* aActorName = pair.first.c_str(); GfxData* aGfxData = pair.second; auto& geoNode = *(aGfxData->mGeoLayouts.end() - 1); @@ -64,13 +65,13 @@ static void DynOS_Pack_ActivateActor(s32 aPackIndex, Pair& pair) { - const char* aActorName = pair.first; +static void DynOS_Pack_DeactivateActor(s32 aPackIndex, std::pair &pair) { + const char* aActorName = pair.first.c_str(); const void* georef = DynOS_Builtin_Actor_GetFromName(aActorName); DynOS_Actor_Invalid(georef, aPackIndex); // figure out which actor to replace it with - Pair* _Replacement = NULL; + std::pair *_Replacement = NULL; s32 _ReplacementPackIndex = 0; for (auto& _Pack : DynosPacks()) { if (!_Pack.mEnabled) { continue; } @@ -86,7 +87,7 @@ static void DynOS_Pack_DeactivateActor(s32 aPackIndex, Pair= _DynosPacks.Count()) { + if (aIndex < 0 || aIndex >= _DynosPacks.size()) { return NULL; } return &_DynosPacks[aIndex]; @@ -163,7 +164,7 @@ PackData* DynOS_Pack_Add(const SysPath& aPath) { auto& _DynosPacks = DynosPacks(); - s32 index = _DynosPacks.Count(); + s32 index = _DynosPacks.size(); const PackData packData = { .mIndex = index, .mEnabled = false, @@ -173,21 +174,21 @@ PackData* DynOS_Pack_Add(const SysPath& aPath) { .mTextures = {}, .mLoaded = false, }; - _DynosPacks.Add(packData); + _DynosPacks.push_back(packData); - PackData* _Pack = &_DynosPacks[index]; + PackData* _Pack = &_DynosPacks.back(); _Pack->mDisplayName = displayName; return _Pack; } -Pair* DynOS_Pack_GetActor(PackData* aPackData, const char* aActorName) { +std::pair* DynOS_Pack_GetActor(PackData* aPackData, const char* aActorName) { if (aPackData == NULL || aActorName == NULL) { return NULL; } for (auto& pair : aPackData->mGfxData) { - if (!strcmp(pair.first, aActorName)) { + if (pair.first == aActorName) { return &pair; } } @@ -199,8 +200,8 @@ void DynOS_Pack_AddActor(PackData* aPackData, const char* aActorName, GfxData* a return; } - s32 index = aPackData->mGfxData.Count(); - aPackData->mGfxData.Add({ strdup(aActorName), aGfxData }); + s32 index = aPackData->mGfxData.size(); + aPackData->mGfxData.emplace_back(aActorName, aGfxData); if (aPackData->mEnabled) { DynOS_Pack_ActivateActor(aPackData->mIndex, aPackData->mGfxData[index]); @@ -225,7 +226,7 @@ void DynOS_Pack_AddTex(PackData* aPackData, DataNode* aTexData) { return; } - aPackData->mTextures.Add(aTexData); + aPackData->mTextures.push_back(aTexData); if (aPackData->mEnabled) { DynOS_Tex_Activate(aTexData, false); diff --git a/data/dynos_mgr_tex.cpp b/data/dynos_mgr_tex.cpp index 287195f87..50e00bf3b 100644 --- a/data/dynos_mgr_tex.cpp +++ b/data/dynos_mgr_tex.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include "dynos.cpp.h" extern "C" { #include "pc/gfx/gfx.h" @@ -32,13 +34,13 @@ static std::set *>& DynosValidTextures() { return sDynosValidTextures; } -static Array *>& DynosScheduledInvalidTextures() { - static Array *> sDynosScheduledInvalidTextures; +static std::vector *> &DynosScheduledInvalidTextures() { + static std::vector *> sDynosScheduledInvalidTextures; return sDynosScheduledInvalidTextures; } -static Array*>>& DynosCustomTexs() { - static Array*>> sDynosCustomTexs; +static std::vector *>> &DynosCustomTexs() { + static std::vector *>> sDynosCustomTexs; return sDynosCustomTexs; } @@ -284,17 +286,17 @@ void DynOS_Tex_Valid(GfxData* aGfxData) { void DynOS_Tex_Invalid(GfxData* aGfxData) { auto& schedule = DynosScheduledInvalidTextures(); for (auto &_Texture : aGfxData->mTextures) { - schedule.Add(_Texture); + schedule.push_back(_Texture); } } void DynOS_Tex_Update() { auto& schedule = DynosScheduledInvalidTextures(); - if (schedule.Count() == 0) { return; } + if (schedule.empty()) { return; } for (auto &_Texture : schedule) { DynosValidTextures().erase(_Texture); } - schedule.Clear(); + schedule.clear(); } // @@ -368,8 +370,8 @@ void DynOS_Tex_Activate(DataNode* aNode, bool aCustomTexture) { // check for duplicates auto& _DynosCustomTexs = DynosCustomTexs(); bool _HasCustomTex = false; - for (s32 i = 0; i < _DynosCustomTexs.Count(); ++i) { - if (!strcmp(_DynosCustomTexs[i].first, aNode->mName.begin())) { + for (auto &customTex : _DynosCustomTexs) { + if (customTex.first == aNode->mName.begin()) { _HasCustomTex = true; break; } @@ -389,7 +391,7 @@ void DynOS_Tex_Activate(DataNode* aNode, bool aCustomTexture) { // Add to custom textures if (!_HasCustomTex && aCustomTexture) { - _DynosCustomTexs.Add({ aNode->mName.begin(), aNode }); + _DynosCustomTexs.emplace_back(aNode->mName.begin(), aNode); } // Add to valid @@ -402,10 +404,11 @@ void DynOS_Tex_Deactivate(DataNode* aNode) { // remove from custom textures auto& _DynosCustomTexs = DynosCustomTexs(); - for (s32 i = 0; i < _DynosCustomTexs.Count(); ++i) { + for (size_t i = 0; i < _DynosCustomTexs.size();) { if (_DynosCustomTexs[i].second == aNode) { - _DynosCustomTexs.Remove(i); - i--; + _DynosCustomTexs.erase(_DynosCustomTexs.begin() + i); + } else { + ++i; } } @@ -421,28 +424,22 @@ void DynOS_Tex_Deactivate(DataNode* aNode) { // Remove from valid auto& _Schedule = DynosScheduledInvalidTextures(); - _Schedule.Add(aNode); + _Schedule.push_back(aNode); } 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)) { + for (auto &customTex : _DynosCustomTexs) { + if (customTex.first == aTexName) { return true; } } - // Allocate name - u16 texLen = strlen(aTexName); - char* _TexName = (char*)calloc(1, sizeof(char) * (texLen + 1)); - strcpy(_TexName, aTexName); - // Load SysPath _PackFolder = ""; - DataNode* _Node = DynOS_Tex_LoadFromBinary(_PackFolder, aFilename, _TexName, false); - free(_TexName); + DataNode* _Node = DynOS_Tex_LoadFromBinary(_PackFolder, aFilename, aTexName, false); if (_Node) { DynOS_Tex_Activate(_Node, true); return true; @@ -463,9 +460,9 @@ bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) { // check custom textures auto& _DynosCustomTexs = DynosCustomTexs(); - for (s32 i = 0; i < _DynosCustomTexs.Count(); ++i) { - if (!strcmp(_DynosCustomTexs[i].first, aTexName)) { - auto& _Data = _DynosCustomTexs[i].second->mData; + for (auto &customTex : _DynosCustomTexs) { + if (customTex.first == aTexName) { + auto& _Data = customTex.second->mData; // load the texture if it hasn't been yet if (_Data->mRawData.begin() == NULL) { @@ -529,9 +526,9 @@ bool DynOS_Tex_GetFromData(const Texture *aTex, struct TextureInfo* aOutTexInfo) static DataNode *DynOS_Lua_Tex_RetrieveNode(const char* aName) { auto& _DynosCustomTexs = DynosCustomTexs(); - for (s32 i = 0; i < _DynosCustomTexs.Count(); ++i) { - if (!strcmp(_DynosCustomTexs[i].first, aName)) { - return _DynosCustomTexs[i].second; + for (auto &customTex : _DynosCustomTexs) { + if (customTex.first == aName) { + return customTex.second; } } @@ -567,13 +564,25 @@ void DynOS_Tex_Override_Set(const char* aTexName, struct TextureInfo* aOverrideT void DynOS_Tex_Override_Reset(const char* aTexName) { // Override texture - const Texture* _BuiltinTex = DynOS_Builtin_Tex_GetFromName(aTexName); - if (!_BuiltinTex) { return; } + const Texture* _BuiltinTexture = DynOS_Builtin_Tex_GetFromName(aTexName); + DataNode* _BuiltinTexData; + if (!_BuiltinTexture) { + _BuiltinTexData = DynOS_Lua_Tex_RetrieveNode(aTexName); + if (!_BuiltinTexData) { return; } + } - auto& _DynosOverrideLuaTextures = DynosOverrideLuaTextures(); - auto _Override = _DynosOverrideLuaTextures[_BuiltinTex]; - if (_Override) { - _DynosOverrideLuaTextures.erase(_BuiltinTex); + if (_BuiltinTexture) { + auto& _DynosOverrideLuaTextures = DynosOverrideLuaTextures(); + auto _Override = _DynosOverrideLuaTextures[_BuiltinTexture]; + if (_Override) { + _DynosOverrideLuaTextures.erase(_BuiltinTexture); + } + } else { + auto& _DynosOverrideLuaTexData = DynosOverrideLuaTexData(); + auto _Override = _DynosOverrideLuaTexData[_BuiltinTexData]; + if (_Override) { + _DynosOverrideLuaTexData.erase(_BuiltinTexData); + } } } @@ -582,7 +591,7 @@ void DynOS_Tex_ModShutdown() { _DynosOverrideLuaTextures.clear(); auto& _DynosCustomTexs = DynosCustomTexs(); - while (_DynosCustomTexs.Count() > 0) { + while (!_DynosCustomTexs.empty()) { auto& pair = _DynosCustomTexs[0]; DynOS_Tex_Deactivate(pair.second); } diff --git a/data/dynos_warps.cpp b/data/dynos_warps.cpp index 4e7fd725f..edeb08b1a 100644 --- a/data/dynos_warps.cpp +++ b/data/dynos_warps.cpp @@ -13,12 +13,9 @@ extern "C" { #include "game/object_list_processor.h" #include "pc/network/packets/packet.h" #include "pc/lua/smlua_hooks.h" -extern s8 gDialogBoxState; -extern s16 gMenuMode; extern s32 gWdwWaterLevelSet; extern u8 sSpawnTypeFromWarpBhv[]; extern void set_mario_initial_action(struct MarioState *, u32, u32); -extern void set_play_mode(s16); } // diff --git a/docs/lua/functions-2.md b/docs/lua/functions-2.md index 6bd635827..0fe24495c 100644 --- a/docs/lua/functions-2.md +++ b/docs/lua/functions-2.md @@ -257,21 +257,22 @@ Plays the penguin walking sound ## [update_angle_from_move_flags](#update_angle_from_move_flags) ### Description -Updates the current object's angle from its move flags +Computes and returns an angle depending on the current object's angle and move flags ### Lua Example -`local integerValue = update_angle_from_move_flags(angle)` +`local integerValue, angle = update_angle_from_move_flags(angle)` ### Parameters | Field | Type | | ----- | ---- | -| angle | `Pointer` <`integer`> | +| angle | `integer` | ### Returns - `integer` +- `integer` ### C Prototype -`s32 update_angle_from_move_flags(s32 *angle);` +`s32 update_angle_from_move_flags(INOUT s32 *angle);` [:arrow_up_small:](#) @@ -12011,7 +12012,7 @@ Behavior loop function for the lighting engine point light Spawns a Star with an ID corresponding to the current object's first behavior parameter byte ### Lua Example -`local ObjectValue = spawn_default_star(x, y, z)` +`local objectValue = spawn_default_star(x, y, z)` ### Parameters | Field | Type | @@ -12021,7 +12022,7 @@ Spawns a Star with an ID corresponding to the current object's first behavior pa | z | `number` | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object* spawn_default_star(f32 x, f32 y, f32 z);` @@ -12036,7 +12037,7 @@ Spawns a Star with an ID corresponding to the current object's first behavior pa Spawns a Red Coin cutscene star with an ID corresponding to the current object's first behavior parameter byte ### Lua Example -`local ObjectValue = spawn_red_coin_cutscene_star(x, y, z)` +`local objectValue = spawn_red_coin_cutscene_star(x, y, z)` ### Parameters | Field | Type | @@ -12046,7 +12047,7 @@ Spawns a Red Coin cutscene star with an ID corresponding to the current object's | z | `number` | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object* spawn_red_coin_cutscene_star(f32 x, f32 y, f32 z);` @@ -12061,7 +12062,7 @@ Spawns a Red Coin cutscene star with an ID corresponding to the current object's Spawns a Star that won't make Mario exit the level with an ID corresponding to the current object's first behavior parameter byte ### Lua Example -`local ObjectValue = spawn_no_exit_star(x, y, z)` +`local objectValue = spawn_no_exit_star(x, y, z)` ### Parameters | Field | Type | @@ -12071,7 +12072,7 @@ Spawns a Star that won't make Mario exit the level with an ID corresponding to t | z | `number` | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object* spawn_no_exit_star(f32 x, f32 y, f32 z);` diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md index 3a2751af1..4c256ee21 100644 --- a/docs/lua/functions-3.md +++ b/docs/lua/functions-3.md @@ -180,7 +180,7 @@ Gets a behavior ID from a behavior script | behavior | `Pointer` <`BehaviorScript`> | ### Returns -[enum BehaviorId](constants.md#enum-BehaviorId) +- [enum BehaviorId](constants.md#enum-BehaviorId) ### C Prototype `enum BehaviorId get_id_from_behavior(const BehaviorScript* behavior);` @@ -203,7 +203,7 @@ Gets a behavior ID from only vanilla behavior scripts | behavior | `Pointer` <`BehaviorScript`> | ### Returns -[enum BehaviorId](constants.md#enum-BehaviorId) +- [enum BehaviorId](constants.md#enum-BehaviorId) ### C Prototype `enum BehaviorId get_id_from_vanilla_behavior(const BehaviorScript* behavior);` @@ -218,7 +218,7 @@ Gets a behavior ID from only vanilla behavior scripts Gets a behavior script from a behavior ID ### Lua Example -`local PointerValue = get_behavior_from_id(id)` +`local pointerValue = get_behavior_from_id(id)` ### Parameters | Field | Type | @@ -272,7 +272,7 @@ gets a behavior ID from a behavior name | name | `string` | ### Returns -[enum BehaviorId](constants.md#enum-BehaviorId) +- [enum BehaviorId](constants.md#enum-BehaviorId) ### C Prototype `enum BehaviorId get_id_from_behavior_name(const char* name);` @@ -537,7 +537,7 @@ Converts an object's position to a `Vec3f` format. Useful for aligning object be - None ### C Prototype -`void object_pos_to_vec3f(OUT Vec3f dst, struct Object *o);` +`void object_pos_to_vec3f(VEC_OUT Vec3f dst, struct Object *o);` [:arrow_up_small:](#) @@ -585,7 +585,7 @@ Converts an object's face angle to a `Vec3s` format - None ### C Prototype -`void object_face_angle_to_vec3s(OUT Vec3s dst, struct Object *o);` +`void object_face_angle_to_vec3s(VEC_OUT Vec3s dst, struct Object *o);` [:arrow_up_small:](#) @@ -633,7 +633,7 @@ Converts an object's move angle to a `Vec3s` format - None ### C Prototype -`void object_move_angle_to_vec3s(OUT Vec3s dst, struct Object *o);` +`void object_move_angle_to_vec3s(VEC_OUT Vec3s dst, struct Object *o);` [:arrow_up_small:](#) @@ -750,7 +750,7 @@ Activates a handheld camera shake effect. Calculates positional and focus adjust - None ### C Prototype -`void shake_camera_handheld(Vec3f pos, OUT Vec3f focus);` +`void shake_camera_handheld(Vec3f pos, VEC_OUT Vec3f focus);` [:arrow_up_small:](#) @@ -800,7 +800,7 @@ Checks for collisions between the camera and level geometry. Adjusts the camera' - `integer` ### C Prototype -`s32 collide_with_walls(OUT Vec3f pos, f32 offsetY, f32 radius);` +`s32 collide_with_walls(VEC_OUT Vec3f pos, f32 offsetY, f32 radius);` [:arrow_up_small:](#) @@ -826,7 +826,7 @@ Clamps the camera's pitch angle between a maximum and minimum value. Prevents ov - `integer` ### C Prototype -`s32 clamp_pitch(Vec3f from, OUT Vec3f to, s16 maxPitch, s16 minPitch);` +`s32 clamp_pitch(Vec3f from, VEC_OUT Vec3f to, s16 maxPitch, s16 minPitch);` [:arrow_up_small:](#) @@ -860,23 +860,24 @@ Checks if a position is within 100 units of Mario's current position. Returns tr ## [set_or_approach_f32_asymptotic](#set_or_approach_f32_asymptotic) ### Description -Smoothly transitions or directly sets a floating-point value (`dst`) to approach a target (`goal`). Uses asymptotic scaling for gradual adjustments or direct assignment +Smoothly transitions or directly sets a floating-point value (`dst`) to approach a target (`goal`). Uses asymptotic scaling for gradual adjustments or direct assignment. Returns FALSE if `dst` reaches `goal` ### Lua Example -`local integerValue = set_or_approach_f32_asymptotic(dst, goal, scale)` +`local integerValue, dst = set_or_approach_f32_asymptotic(dst, goal, scale)` ### Parameters | Field | Type | | ----- | ---- | -| dst | `Pointer` <`number`> | +| dst | `number` | | goal | `number` | | scale | `number` | ### Returns - `integer` +- `number` ### C Prototype -`s32 set_or_approach_f32_asymptotic(f32 *dst, f32 goal, f32 scale);` +`s32 set_or_approach_f32_asymptotic(INOUT f32 *dst, f32 goal, f32 scale);` [:arrow_up_small:](#) @@ -885,23 +886,24 @@ Smoothly transitions or directly sets a floating-point value (`dst`) to approach ## [approach_f32_asymptotic_bool](#approach_f32_asymptotic_bool) ### Description -Gradually adjusts a floating-point value (`current`) towards a target (`target`) using asymptotic smoothing. Returns true if `current` reaches the `target` and false otherwise +Gradually adjusts a floating-point value (`current`) towards a target (`target`) using asymptotic smoothing. Returns FALSE if `current` reaches the `target` ### Lua Example -`local integerValue = approach_f32_asymptotic_bool(current, target, multiplier)` +`local integerValue, current = approach_f32_asymptotic_bool(current, target, multiplier)` ### Parameters | Field | Type | | ----- | ---- | -| current | `Pointer` <`number`> | +| current | `number` | | target | `number` | | multiplier | `number` | ### Returns - `integer` +- `number` ### C Prototype -`s32 approach_f32_asymptotic_bool(f32 *current, f32 target, f32 multiplier);` +`s32 approach_f32_asymptotic_bool(INOUT f32 *current, f32 target, f32 multiplier);` [:arrow_up_small:](#) @@ -935,23 +937,24 @@ Gradually approaches a floating-point value (`target`) using asymptotic smoothin ## [approach_s16_asymptotic_bool](#approach_s16_asymptotic_bool) ### Description -Gradually adjusts a signed 16-bit integer (`current`) towards a target (`target`) using asymptotic smoothing. Returns true if `current` reaches `target` and false otherwise +Gradually adjusts a signed 16-bit integer (`current`) towards a target (`target`) using asymptotic smoothing. Returns FALSE if `current` reaches `target` ### Lua Example -`local integerValue = approach_s16_asymptotic_bool(current, target, divisor)` +`local integerValue, current = approach_s16_asymptotic_bool(current, target, divisor)` ### Parameters | Field | Type | | ----- | ---- | -| current | `Pointer` <`integer`> | +| current | `integer` | | target | `integer` | | divisor | `integer` | ### Returns - `integer` +- `integer` ### C Prototype -`s32 approach_s16_asymptotic_bool(s16 *current, s16 target, s16 divisor);` +`s32 approach_s16_asymptotic_bool(INOUT s16 *current, s16 target, s16 divisor);` [:arrow_up_small:](#) @@ -1003,7 +1006,7 @@ Smoothly transitions a 3D vector (`current`) towards a target vector (`target`) - None ### C Prototype -`void approach_vec3f_asymptotic(OUT Vec3f current, Vec3f target, f32 xMul, f32 yMul, f32 zMul);` +`void approach_vec3f_asymptotic(VEC_OUT Vec3f current, Vec3f target, f32 xMul, f32 yMul, f32 zMul);` [:arrow_up_small:](#) @@ -1030,7 +1033,7 @@ Smoothly transitions a 3D vector (`current`) toward a target vector (`goal`) usi - None ### C Prototype -`void set_or_approach_vec3f_asymptotic(OUT Vec3f dst, Vec3f goal, f32 xMul, f32 yMul, f32 zMul);` +`void set_or_approach_vec3f_asymptotic(VEC_OUT Vec3f dst, Vec3f goal, f32 xMul, f32 yMul, f32 zMul);` [:arrow_up_small:](#) @@ -1039,23 +1042,24 @@ Smoothly transitions a 3D vector (`current`) toward a target vector (`goal`) usi ## [camera_approach_s16_symmetric_bool](#camera_approach_s16_symmetric_bool) ### Description -Adjusts a signed 16-bit integer (`current`) towards a target (`target`) symmetrically with a fixed increment (`increment`). Returns true if the value reaches the target and false otherwise +Adjusts a signed 16-bit integer (`current`) towards a target (`target`) symmetrically with a fixed increment (`increment`). Returns FALSE if `current` reaches the `target` ### Lua Example -`local integerValue = camera_approach_s16_symmetric_bool(current, target, increment)` +`local integerValue, current = camera_approach_s16_symmetric_bool(current, target, increment)` ### Parameters | Field | Type | | ----- | ---- | -| current | `Pointer` <`integer`> | +| current | `integer` | | target | `integer` | | increment | `integer` | ### Returns - `integer` +- `integer` ### C Prototype -`s32 camera_approach_s16_symmetric_bool(s16 *current, s16 target, s16 increment);` +`s32 camera_approach_s16_symmetric_bool(INOUT s16 *current, s16 target, s16 increment);` [:arrow_up_small:](#) @@ -1064,23 +1068,24 @@ Adjusts a signed 16-bit integer (`current`) towards a target (`target`) symmetri ## [set_or_approach_s16_symmetric](#set_or_approach_s16_symmetric) ### Description -Smoothly transitions or directly sets a signed 16-bit value (`current`) to approach a target (`target`). Uses symmetric scaling for gradual or immediate adjustments +Smoothly transitions or directly sets a signed 16-bit value (`current`) to approach a target (`target`). Uses symmetric scaling for gradual or immediate adjustments. Returns FALSE if `current` reaches the `target` ### Lua Example -`local integerValue = set_or_approach_s16_symmetric(current, target, increment)` +`local integerValue, current = set_or_approach_s16_symmetric(current, target, increment)` ### Parameters | Field | Type | | ----- | ---- | -| current | `Pointer` <`integer`> | +| current | `integer` | | target | `integer` | | increment | `integer` | ### Returns - `integer` +- `integer` ### C Prototype -`s32 set_or_approach_s16_symmetric(s16 *current, s16 target, s16 increment);` +`s32 set_or_approach_s16_symmetric(INOUT s16 *current, s16 target, s16 increment);` [:arrow_up_small:](#) @@ -1089,23 +1094,24 @@ Smoothly transitions or directly sets a signed 16-bit value (`current`) to appro ## [camera_approach_f32_symmetric_bool](#camera_approach_f32_symmetric_bool) ### Description -Adjusts a floating-point value (`current`) towards a target (`target`) symmetrically with a fixed increment (`increment`). Returns true if the value reaches the target and false otherwise +Adjusts a floating-point value (`current`) towards a target (`target`) symmetrically with a fixed increment (`increment`). Returns FALSE if `current` reaches the `target` ### Lua Example -`local integerValue = camera_approach_f32_symmetric_bool(current, target, increment)` +`local integerValue, current = camera_approach_f32_symmetric_bool(current, target, increment)` ### Parameters | Field | Type | | ----- | ---- | -| current | `Pointer` <`number`> | +| current | `number` | | target | `number` | | increment | `number` | ### Returns - `integer` +- `number` ### C Prototype -`s32 camera_approach_f32_symmetric_bool(f32 *current, f32 target, f32 increment);` +`s32 camera_approach_f32_symmetric_bool(INOUT f32 *current, f32 target, f32 increment);` [:arrow_up_small:](#) @@ -1156,7 +1162,7 @@ Generates a random 3D vector with short integer components. Useful for randomize - None ### C Prototype -`void random_vec3s(OUT Vec3s dst, s16 xRange, s16 yRange, s16 zRange);` +`void random_vec3s(VEC_OUT Vec3s dst, s16 xRange, s16 yRange, s16 zRange);` [:arrow_up_small:](#) @@ -1184,7 +1190,7 @@ Clamps a position within specified X and Z bounds and calculates the yaw angle f - `integer` ### C Prototype -`s32 clamp_positions_and_find_yaw(OUT Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f32 zMax, f32 zMin);` +`s32 clamp_positions_and_find_yaw(VEC_OUT Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f32 zMax, f32 zMin);` [:arrow_up_small:](#) @@ -1237,7 +1243,7 @@ Scales a point along a line between two 3D points (`from` and `to`). The scaling - None ### C Prototype -`void scale_along_line(OUT Vec3f dest, Vec3f from, Vec3f to, f32 scale);` +`void scale_along_line(VEC_OUT Vec3f dest, Vec3f from, Vec3f to, f32 scale);` [:arrow_up_small:](#) @@ -1294,24 +1300,22 @@ Determines the yaw angle (rotation around the Y-axis) from one 3D position (`fro ## [calculate_angles](#calculate_angles) ### Description -Calculates the pitch and yaw angles from one 3D position (`from`) to another (`to`). Updates the provided pointers with the computed pitch and yaw values +Calculates and returns the pitch and yaw angles from one 3D position (`from`) to another (`to`) ### Lua Example -`calculate_angles(from, to, pitch, yaw)` +`local pitch, yaw = calculate_angles(from, to)` ### Parameters | Field | Type | | ----- | ---- | | from | [Vec3f](structs.md#Vec3f) | | to | [Vec3f](structs.md#Vec3f) | -| pitch | `Pointer` <`integer`> | -| yaw | `Pointer` <`integer`> | ### Returns - None ### C Prototype -`void calculate_angles(Vec3f from, Vec3f to, s16 *pitch, s16 *yaw);` +`void calculate_angles(Vec3f from, Vec3f to, RET s16 *pitch, RET s16 *yaw);` [:arrow_up_small:](#) @@ -1384,7 +1388,7 @@ Rotates a vector around the XZ-plane by a specified yaw angle. The result is sto - None ### C Prototype -`void rotate_in_xz(OUT Vec3f dst, Vec3f src, s16 yaw);` +`void rotate_in_xz(VEC_OUT Vec3f dst, Vec3f src, s16 yaw);` [:arrow_up_small:](#) @@ -1409,7 +1413,7 @@ Rotates a vector around the YZ-plane by a specified pitch angle. The result is s - None ### C Prototype -`void rotate_in_yz(OUT Vec3f dst, Vec3f src, s16 pitch);` +`void rotate_in_yz(VEC_OUT Vec3f dst, Vec3f src, s16 pitch);` [:arrow_up_small:](#) @@ -1537,7 +1541,7 @@ Activates a pitch-based shake effect. Adds vertical vibrational movement to the - None ### C Prototype -`void shake_camera_pitch(Vec3f pos, OUT Vec3f focus);` +`void shake_camera_pitch(Vec3f pos, VEC_OUT Vec3f focus);` [:arrow_up_small:](#) @@ -1561,7 +1565,7 @@ Activates a yaw-based shake effect. Adds horizontal vibrational movement to the - None ### C Prototype -`void shake_camera_yaw(Vec3f pos, OUT Vec3f focus);` +`void shake_camera_yaw(Vec3f pos, VEC_OUT Vec3f focus);` [:arrow_up_small:](#) @@ -1573,18 +1577,18 @@ Activates a yaw-based shake effect. Adds horizontal vibrational movement to the Applies a roll-based shake effect to the camera. Simulates rotational disturbances caused by impacts or other events ### Lua Example -`shake_camera_roll(roll)` +`local roll = shake_camera_roll(roll)` ### Parameters | Field | Type | | ----- | ---- | -| roll | `Pointer` <`integer`> | +| roll | `integer` | ### Returns - None ### C Prototype -`void shake_camera_roll(s16 *roll);` +`void shake_camera_roll(INOUT s16 *roll);` [:arrow_up_small:](#) @@ -1990,7 +1994,7 @@ Offsets a vector by rotating it in 3D space relative to a reference position. Th - None ### C Prototype -`void offset_rotated(OUT Vec3f dst, Vec3f from, Vec3f to, Vec3s rotation);` +`void offset_rotated(VEC_OUT Vec3f dst, Vec3f from, Vec3f to, Vec3s rotation);` [:arrow_up_small:](#) @@ -2019,7 +2023,7 @@ Transitions the camera to the next Lakitu state, updating position and focus. Th - `integer` ### C Prototype -`s16 next_lakitu_state(OUT Vec3f newPos, OUT Vec3f newFoc, Vec3f curPos, Vec3f curFoc, Vec3f oldPos, Vec3f oldFoc, s16 yaw);` +`s16 next_lakitu_state(VEC_OUT Vec3f newPos, VEC_OUT Vec3f newFoc, Vec3f curPos, Vec3f curFoc, Vec3f oldPos, Vec3f oldFoc, s16 yaw);` [:arrow_up_small:](#) @@ -2089,7 +2093,7 @@ Resolves collisions between the camera and level geometry. Adjusts the camera's - None ### C Prototype -`void resolve_geometry_collisions(OUT Vec3f pos, UNUSED Vec3f lastGood);` +`void resolve_geometry_collisions(VEC_OUT Vec3f pos, UNUSED Vec3f lastGood);` [:arrow_up_small:](#) @@ -2101,21 +2105,22 @@ Resolves collisions between the camera and level geometry. Adjusts the camera's Rotates the camera to avoid walls or other obstructions. Ensures clear visibility of the player or target objects ### Lua Example -`local integerValue = rotate_camera_around_walls(c, cPos, avoidYaw, yawRange)` +`local integerValue, avoidYaw = rotate_camera_around_walls(c, cPos, avoidYaw, yawRange)` ### Parameters | Field | Type | | ----- | ---- | | c | [Camera](structs.md#Camera) | | cPos | [Vec3f](structs.md#Vec3f) | -| avoidYaw | `Pointer` <`integer`> | +| avoidYaw | `integer` | | yawRange | `integer` | ### Returns - `integer` +- `integer` ### C Prototype -`s32 rotate_camera_around_walls(struct Camera *c, Vec3f cPos, s16 *avoidYaw, s16 yawRange);` +`s32 rotate_camera_around_walls(struct Camera *c, Vec3f cPos, INOUT s16 *avoidYaw, s16 yawRange);` [:arrow_up_small:](#) @@ -2494,7 +2499,7 @@ Centers the ROM hack camera. This function is designed for non-standard level la Gets a Character struct from `m` ### Lua Example -`local CharacterValue = get_character(m)` +`local characterValue = get_character(m)` ### Parameters | Field | Type | @@ -2502,7 +2507,7 @@ Gets a Character struct from `m` | m | [MarioState](structs.md#MarioState) | ### Returns -[Character](structs.md#Character) +- [Character](structs.md#Character) ### C Prototype `struct Character* get_character(struct MarioState* m);` @@ -2855,13 +2860,13 @@ Sets the current DJUI HUD font Gets the current DJUI HUD color ### Lua Example -`local DjuiColorValue = djui_hud_get_color()` +`local djuiColorValue = djui_hud_get_color()` ### Parameters - None ### Returns -[DjuiColor](structs.md#DjuiColor) +- [DjuiColor](structs.md#DjuiColor) ### C Prototype `struct DjuiColor* djui_hud_get_color(void);` @@ -2923,13 +2928,13 @@ Resets the current DJUI HUD color Gets the current DJUI HUD rotation ### Lua Example -`local HudUtilsRotationValue = djui_hud_get_rotation()` +`local hudUtilsRotationValue = djui_hud_get_rotation()` ### Parameters - None ### Returns -[HudUtilsRotation](structs.md#HudUtilsRotation) +- [HudUtilsRotation](structs.md#HudUtilsRotation) ### C Prototype `struct HudUtilsRotation* djui_hud_get_rotation(void);` @@ -3705,7 +3710,7 @@ Converts a world position to screen position - `boolean` ### C Prototype -`bool djui_hud_world_pos_to_screen_pos(Vec3f pos, OUT Vec3f out);` +`bool djui_hud_world_pos_to_screen_pos(Vec3f pos, VEC_OUT Vec3f out);` [:arrow_up_small:](#) @@ -6114,7 +6119,7 @@ Retrieves Mario's normal cap if it was previously lost. Removes the cap from Mar Returns a collided object that matches a given interaction type from Mario's current collision data. Useful for determining which object Mario has come into contact with ### Lua Example -`local ObjectValue = mario_get_collided_object(m, interactType)` +`local objectValue = mario_get_collided_object(m, interactType)` ### Parameters | Field | Type | @@ -6123,7 +6128,7 @@ Returns a collided object that matches a given interaction type from Mario's cur | interactType | `integer` | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *mario_get_collided_object(struct MarioState *m, u32 interactType);` @@ -6330,7 +6335,7 @@ Stores the local Mario's current state in lag compensation history Gets the local Mario's state stored in lag compensation history ### Lua Example -`local MarioStateValue = lag_compensation_get_local_state(otherNp)` +`local marioStateValue = lag_compensation_get_local_state(otherNp)` ### Parameters | Field | Type | @@ -6338,7 +6343,7 @@ Gets the local Mario's state stored in lag compensation history | otherNp | [NetworkPlayer](structs.md#NetworkPlayer) | ### Returns -[MarioState](structs.md#MarioState) +- [MarioState](structs.md#MarioState) ### C Prototype `struct MarioState* lag_compensation_get_local_state(struct NetworkPlayer* otherNp);` @@ -6427,7 +6432,7 @@ Returns the name of the level corresponding to `courseNum`, `levelNum` and `area Returns the name of the level corresponding to `courseNum`, `levelNum` and `areaIndex` as an SM64 encoded string. This function should not be used in Lua mods. Set `charCase` to 1 to capitalize or -1 to decapitalize the returned string ### Lua Example -`local PointerValue = get_level_name_sm64(courseNum, levelNum, areaIndex, charCase)` +`local pointerValue = get_level_name_sm64(courseNum, levelNum, areaIndex, charCase)` ### Parameters | Field | Type | @@ -6503,7 +6508,7 @@ Returns the name of the star corresponding to `courseNum` and `starNum` as an AS Returns the name of the star corresponding to `courseNum` and `starNum` as an SM64 encoded string. This function should not be used in Lua mods. Set `charCase` to 1 to capitalize or -1 to decapitalize the returned string ### Lua Example -`local PointerValue = get_star_name_sm64(courseNum, starNum, charCase)` +`local pointerValue = get_star_name_sm64(courseNum, starNum, charCase)` ### Parameters | Field | Type | @@ -6558,7 +6563,7 @@ Returns the name of the star corresponding to `courseNum` and `starNum` as a dec Creates a warp node in the current level and area with id `id` that goes to the warp node `destNode` in level `destLevel` and area `destArea`, and attach it to the object `o`. To work properly, object `o` must be able to trigger a warp (for example, with interact type set to `INTERACT_WARP`.) `checkpoint` should be set only to WARP_NO_CHECKPOINT (0x00) or WARP_CHECKPOINT (0x80.) If `checkpoint` is set to `0x80`, Mario will warp directly to this node if he enters the level again (after a death for example) ### Lua Example -`local ObjectWarpNodeValue = area_create_warp_node(id, destLevel, destArea, destNode, checkpoint, o)` +`local objectWarpNodeValue = area_create_warp_node(id, destLevel, destArea, destNode, checkpoint, o)` ### Parameters | Field | Type | @@ -6571,7 +6576,7 @@ Creates a warp node in the current level and area with id `id` that goes to the | o | [Object](structs.md#Object) | ### Returns -[ObjectWarpNode](structs.md#ObjectWarpNode) +- [ObjectWarpNode](structs.md#ObjectWarpNode) ### C Prototype `struct ObjectWarpNode *area_create_warp_node(u8 id, u8 destLevel, u8 destArea, u8 destNode, u8 checkpoint, struct Object *o);` @@ -6658,7 +6663,7 @@ Fades into a special warp with `arg` and using `color` Gets an instant warp from the current area's instant warp array (0-3) ### Lua Example -`local InstantWarpValue = get_instant_warp(index)` +`local instantWarpValue = get_instant_warp(index)` ### Parameters | Field | Type | @@ -6666,7 +6671,7 @@ Gets an instant warp from the current area's instant warp array (0-3) | index | `integer` | ### Returns -[InstantWarp](structs.md#InstantWarp) +- [InstantWarp](structs.md#InstantWarp) ### C Prototype `struct InstantWarp *get_instant_warp(u8 index);` @@ -6681,13 +6686,13 @@ Gets an instant warp from the current area's instant warp array (0-3) Gets a painting warp node from the local mario's floor type ### Lua Example -`local WarpNodeValue = get_painting_warp_node()` +`local warpNodeValue = get_painting_warp_node()` ### Parameters - None ### Returns -[WarpNode](structs.md#WarpNode) +- [WarpNode](structs.md#WarpNode) ### C Prototype `struct WarpNode *get_painting_warp_node(void);` @@ -6766,6 +6771,32 @@ Special warps to arg (`SPECIAL_WARP_*`)
+## [initiate_warp](#initiate_warp) + +### Description +Initiates a warp to `destLevel` in `destArea` at `destWarpNode` with `arg`. This function is unstable and it's generally recommended to use `warp_to_level` instead + +### Lua Example +`initiate_warp(destLevel, destArea, destWarpNode, arg)` + +### Parameters +| Field | Type | +| ----- | ---- | +| destLevel | `integer` | +| destArea | `integer` | +| destWarpNode | `integer` | +| arg | `integer` | + +### Returns +- None + +### C Prototype +`void initiate_warp(s16 destLevel, s16 destArea, s16 destWarpNode, s32 arg);` + +[:arrow_up_small:](#) + +
+ ## [lvl_set_current_level](#lvl_set_current_level) ### Description diff --git a/docs/lua/functions-4.md b/docs/lua/functions-4.md index d439877c6..545c0d19f 100644 --- a/docs/lua/functions-4.md +++ b/docs/lua/functions-4.md @@ -67,7 +67,7 @@ Gets the lighting engine mode - None ### Returns -[enum LEMode](constants.md#enum-LEMode) +- [enum LEMode](constants.md#enum-LEMode) ### C Prototype `enum LEMode le_get_mode(void);` @@ -116,7 +116,7 @@ Outputs the lighting engine's ambient color to `out` - None ### C Prototype -`void le_get_ambient_color(OUT Color out);` +`void le_get_ambient_color(VEC_OUT Color out);` [:arrow_up_small:](#) @@ -166,7 +166,7 @@ Calculates the lighting with `lightIntensityScalar` at a position and outputs th - None ### C Prototype -`void le_calculate_lighting_color(Vec3f pos, OUT Color out, f32 lightIntensityScalar);` +`void le_calculate_lighting_color(Vec3f pos, VEC_OUT Color out, f32 lightIntensityScalar);` [:arrow_up_small:](#) @@ -192,7 +192,7 @@ Calculates the lighting with `lightIntensityScalar` at a position and with a nor - None ### C Prototype -`void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, OUT Color out, f32 lightIntensityScalar);` +`void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, VEC_OUT Color out, f32 lightIntensityScalar);` [:arrow_up_small:](#) @@ -216,7 +216,7 @@ Calculates the lighting direction from a position and outputs the result in `out - None ### C Prototype -`void le_calculate_lighting_dir(Vec3f pos, OUT Vec3f out);` +`void le_calculate_lighting_dir(Vec3f pos, VEC_OUT Vec3f out);` [:arrow_up_small:](#) @@ -337,7 +337,7 @@ Outputs a lighting engine point light's position to `out` - None ### C Prototype -`void le_get_light_pos(s16 id, OUT Vec3f out);` +`void le_get_light_pos(s16 id, VEC_OUT Vec3f out);` [:arrow_up_small:](#) @@ -387,7 +387,7 @@ Outputs a lighting engine point light's color to `out` - None ### C Prototype -`void le_get_light_color(s16 id, OUT Color out);` +`void le_get_light_color(s16 id, VEC_OUT Color out);` [:arrow_up_small:](#) @@ -777,7 +777,7 @@ Retrieves the current animation flags and calculates the translation for Mario's - `integer` ### C Prototype -`s16 find_mario_anim_flags_and_translation(struct Object *o, s32 yaw, OUT Vec3s translation);` +`s16 find_mario_anim_flags_and_translation(struct Object *o, s32 yaw, VEC_OUT Vec3s translation);` [:arrow_up_small:](#) @@ -1239,7 +1239,7 @@ Computes a value added to terrain sounds, depending on the floor's type (sand, s Checks for and resolves wall collisions at a given position `pos`, returning the last wall encountered. Primarily used to prevent Mario from going through walls. Useful for collision detection when updating Mario's movement or adjusting his position ### Lua Example -`local SurfaceValue = resolve_and_return_wall_collisions(pos, offset, radius)` +`local surfaceValue = resolve_and_return_wall_collisions(pos, offset, radius)` ### Parameters | Field | Type | @@ -1249,10 +1249,10 @@ Checks for and resolves wall collisions at a given position `pos`, returning the | radius | `number` | ### Returns -[Surface](structs.md#Surface) +- [Surface](structs.md#Surface) ### C Prototype -`struct Surface *resolve_and_return_wall_collisions(OUT Vec3f pos, f32 offset, f32 radius);` +`struct Surface *resolve_and_return_wall_collisions(VEC_OUT Vec3f pos, f32 offset, f32 radius);` [:arrow_up_small:](#) @@ -1278,7 +1278,57 @@ Similar to `resolve_and_return_wall_collisions` but also returns detailed collis - None ### C Prototype -`void resolve_and_return_wall_collisions_data(OUT Vec3f pos, f32 offset, f32 radius, struct WallCollisionData* collisionData);` +`void resolve_and_return_wall_collisions_data(VEC_OUT Vec3f pos, f32 offset, f32 radius, struct WallCollisionData* collisionData);` + +[:arrow_up_small:](#) + +
+ +## [vec3f_find_ceil](#vec3f_find_ceil) + +### Description +Finds the ceiling from a vec3f horizontally and a height (with 80 vertical buffer). Returns the ceiling height and surface + +### Lua Example +`local numberValue, ceil = vec3f_find_ceil(pos, height)` + +### Parameters +| Field | Type | +| ----- | ---- | +| pos | [Vec3f](structs.md#Vec3f) | +| height | `number` | + +### Returns +- `number` +- [Surface](structs.md#Surface) + +### C Prototype +`f32 vec3f_find_ceil(Vec3f pos, f32 height, RET struct Surface **ceil);` + +[:arrow_up_small:](#) + +
+ +## [vec3f_mario_ceil](#vec3f_mario_ceil) + +### Description +Finds the ceiling from a vec3f horizontally and a height (with 80 vertical buffer). Prevents exposed ceiling bug. Returns the ceiling height and surface + +### Lua Example +`local numberValue, ceil = vec3f_mario_ceil(pos, height)` + +### Parameters +| Field | Type | +| ----- | ---- | +| pos | [Vec3f](structs.md#Vec3f) | +| height | `number` | + +### Returns +- `number` +- [Surface](structs.md#Surface) + +### C Prototype +`f32 vec3f_mario_ceil(Vec3f pos, f32 height, RET struct Surface **ceil);` [:arrow_up_small:](#) @@ -1837,7 +1887,7 @@ Updates Mario's wall information based on wall collisions (`WallCollisionData`). Gets the MarioState corresponding to the provided object if the object is a Mario object ### Lua Example -`local MarioStateValue = get_mario_state_from_object(o)` +`local marioStateValue = get_mario_state_from_object(o)` ### Parameters | Field | Type | @@ -1845,7 +1895,7 @@ Gets the MarioState corresponding to the provided object if the object is a Mari | o | [Object](structs.md#Object) | ### Returns -[MarioState](structs.md#MarioState) +- [MarioState](structs.md#MarioState) ### C Prototype `struct MarioState *get_mario_state_from_object(struct Object *o);` @@ -2427,7 +2477,7 @@ Performs a single step of movement while Mario is hanging from a ceiling. It han - `integer` ### C Prototype -`s32 perform_hanging_step(struct MarioState *m, OUT Vec3f nextPos);` +`s32 perform_hanging_step(struct MarioState *m, VEC_OUT Vec3f nextPos);` [:arrow_up_small:](#) @@ -4196,7 +4246,7 @@ Performs a full water movement step where ceilings, floors, and walls are handle - `integer` ### C Prototype -`u32 perform_water_full_step(struct MarioState *m, OUT Vec3f nextPos);` +`u32 perform_water_full_step(struct MarioState *m, VEC_OUT Vec3f nextPos);` [:arrow_up_small:](#) @@ -4220,7 +4270,7 @@ Calculates a water current and outputs it in `step` - None ### C Prototype -`void apply_water_current(struct MarioState *m, OUT Vec3f step);` +`void apply_water_current(struct MarioState *m, VEC_OUT Vec3f step);` [:arrow_up_small:](#) @@ -4391,13 +4441,13 @@ Behavior loop function for Star Door unlock object When used in a geo function, retrieve the MarioState associated to the current processed object ### Lua Example -`local MarioStateValue = geo_get_mario_state()` +`local marioStateValue = geo_get_mario_state()` ### Parameters - None ### Returns -[MarioState](structs.md#MarioState) +- [MarioState](structs.md#MarioState) ### C Prototype `struct MarioState *geo_get_mario_state(void);` @@ -4412,13 +4462,13 @@ When used in a geo function, retrieve the MarioState associated to the current p When used in a geo function, retrieve the MarioBodyState associated to the current processed object ### Lua Example -`local MarioBodyStateValue = geo_get_body_state()` +`local marioBodyStateValue = geo_get_body_state()` ### Parameters - None ### Returns -[MarioBodyState](structs.md#MarioBodyState) +- [MarioBodyState](structs.md#MarioBodyState) ### C Prototype `struct MarioBodyState *geo_get_body_state(void);` @@ -4861,7 +4911,7 @@ Computes spline interpolation weights for a given parameter `t` and stores these - None ### C Prototype -`void spline_get_weights(struct MarioState* m, OUT Vec4f result, f32 t, UNUSED s32 c);` +`void spline_get_weights(struct MarioState* m, VEC_OUT Vec4f result, f32 t, UNUSED s32 c);` [:arrow_up_small:](#) @@ -4909,7 +4959,7 @@ Advances the spline-based animation associated with `m` and stores the current i - `integer` ### C Prototype -`s32 anim_spline_poll(struct MarioState* m, OUT Vec3f result);` +`s32 anim_spline_poll(struct MarioState* m, VEC_OUT Vec3f result);` [:arrow_up_small:](#) @@ -4921,7 +4971,7 @@ Advances the spline-based animation associated with `m` and stores the current i Rotates the 3D floating-point vector `v` by the angles specified in the 3D signed-integer vector `rotate`, applying the rotations in the order Z, then X, then Y. The rotated vector replaces `v` ### Lua Example -`local Vec3fValue = vec3f_rotate_zxy(v, rotate)` +`local vec3fValue = vec3f_rotate_zxy(v, rotate)` ### Parameters | Field | Type | @@ -4930,10 +4980,10 @@ Rotates the 3D floating-point vector `v` by the angles specified in the 3D signe | rotate | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_rotate_zxy(OUT Vec3f v, Vec3s rotate);` +`Vec3fp vec3f_rotate_zxy(VEC_OUT Vec3f v, Vec3s rotate);` [:arrow_up_small:](#) @@ -4945,7 +4995,7 @@ Rotates the 3D floating-point vector `v` by the angles specified in the 3D signe Rotates the 3D floating-point vector `v` around the vector `n`, given a rotation `r` (in sm64 angle units), and stores the result in `dest` ### Lua Example -`local Vec3fValue = vec3f_rotate_around_n(dest, v, n, r)` +`local vec3fValue = vec3f_rotate_around_n(dest, v, n, r)` ### Parameters | Field | Type | @@ -4956,10 +5006,10 @@ Rotates the 3D floating-point vector `v` around the vector `n`, given a rotation | r | `integer` | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_rotate_around_n(OUT Vec3f dest, Vec3f v, Vec3f n, s16 r);` +`Vec3fp vec3f_rotate_around_n(VEC_OUT Vec3f dest, Vec3f v, Vec3f n, s16 r);` [:arrow_up_small:](#) @@ -4971,7 +5021,7 @@ Rotates the 3D floating-point vector `v` around the vector `n`, given a rotation Projects the 3D floating-point vector `v` onto another 3D floating-point vector `onto`. The resulting projection, stored in `dest`, represents how much of `v` lies along the direction of `onto` ### Lua Example -`local Vec3fValue = vec3f_project(dest, v, onto)` +`local vec3fValue = vec3f_project(dest, v, onto)` ### Parameters | Field | Type | @@ -4981,10 +5031,10 @@ Projects the 3D floating-point vector `v` onto another 3D floating-point vector | onto | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_project(OUT Vec3f dest, Vec3f v, Vec3f onto);` +`Vec3fp vec3f_project(VEC_OUT Vec3f dest, Vec3f v, Vec3f onto);` [:arrow_up_small:](#) @@ -4996,7 +5046,7 @@ Projects the 3D floating-point vector `v` onto another 3D floating-point vector Scales the 3D floating-point vector `v` by the vector `scale`, then rotates it by the rotation vector `rotation`, and finally translates it by the vector `translation`. The resulting vector is stored in `dest` ### Lua Example -`local Vec3fValue = vec3f_transform(dest, v, translation, rotation, scale)` +`local vec3fValue = vec3f_transform(dest, v, translation, rotation, scale)` ### Parameters | Field | Type | @@ -5008,10 +5058,10 @@ Scales the 3D floating-point vector `v` by the vector `scale`, then rotates it b | scale | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_transform(OUT Vec3f dest, Vec3f v, Vec3f translation, Vec3s rotation, Vec3f scale);` +`Vec3fp vec3f_transform(VEC_OUT Vec3f dest, Vec3f v, Vec3f translation, Vec3s rotation, Vec3f scale);` [:arrow_up_small:](#) @@ -5020,25 +5070,22 @@ Scales the 3D floating-point vector `v` by the vector `scale`, then rotates it b ## [vec3f_get_dist_and_angle](#vec3f_get_dist_and_angle) ### Description -Calculates the distance between two points in 3D space (`from` and `to`), as well as the pitch and yaw angles that describe the direction from `from` to `to`. The results are stored in `dist`, `pitch`, and `yaw` +Calculates the distance between two points in 3D space (`from` and `to`), as well as the pitch and yaw angles that describe the direction from `from` to `to`. Returns the calculated distance, pitch and yaw ### Lua Example -`vec3f_get_dist_and_angle(from, to, dist, pitch, yaw)` +`local dist, pitch, yaw = vec3f_get_dist_and_angle(from, to)` ### Parameters | Field | Type | | ----- | ---- | | from | [Vec3f](structs.md#Vec3f) | | to | [Vec3f](structs.md#Vec3f) | -| dist | `Pointer` <`number`> | -| pitch | `Pointer` <`integer`> | -| yaw | `Pointer` <`integer`> | ### Returns - None ### C Prototype -`void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw);` +`void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, RET f32 *dist, RET s16 *pitch, RET s16 *yaw);` [:arrow_up_small:](#) @@ -5065,7 +5112,7 @@ Positions the point `to` at a given `dist`, `pitch`, and `yaw` relative to the p - None ### C Prototype -`void vec3f_set_dist_and_angle(Vec3f from, OUT Vec3f to, f32 dist, s16 pitch, s16 yaw);` +`void vec3f_set_dist_and_angle(Vec3f from, VEC_OUT Vec3f to, f32 dist, s16 pitch, s16 yaw);` [:arrow_up_small:](#) @@ -5077,7 +5124,7 @@ Positions the point `to` at a given `dist`, `pitch`, and `yaw` relative to the p Determines a vector that is perpendicular (normal) to the plane defined by three given 3D floating-point points `a`, `b`, and `c`. The resulting perpendicular vector is stored in `dest` ### Lua Example -`local Vec3fValue = find_vector_perpendicular_to_plane(dest, a, b, c)` +`local vec3fValue = find_vector_perpendicular_to_plane(dest, a, b, c)` ### Parameters | Field | Type | @@ -5088,10 +5135,10 @@ Determines a vector that is perpendicular (normal) to the plane defined by three | c | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp find_vector_perpendicular_to_plane(OUT Vec3f dest, Vec3f a, Vec3f b, Vec3f c);` +`Vec3fp find_vector_perpendicular_to_plane(VEC_OUT Vec3f dest, Vec3f a, Vec3f b, Vec3f c);` [:arrow_up_small:](#) @@ -5117,7 +5164,7 @@ Adjusts the 4x4 floating-point matrix `mtx` so that it represents a viewing tran - None ### C Prototype -`void mtxf_lookat(OUT Mat4 mtx, Vec3f from, Vec3f to, s16 roll);` +`void mtxf_lookat(VEC_OUT Mat4 mtx, Vec3f from, Vec3f to, s16 roll);` [:arrow_up_small:](#) @@ -5142,7 +5189,7 @@ Rotates `dest` according to the angles in `rotate` using ZXY order, and then tra - None ### C Prototype -`void mtxf_rotate_zxy_and_translate(OUT Mat4 dest, Vec3f translate, Vec3s rotate);` +`void mtxf_rotate_zxy_and_translate(VEC_OUT Mat4 dest, Vec3f translate, Vec3s rotate);` [:arrow_up_small:](#) @@ -5167,7 +5214,7 @@ Rotates `dest` using angles in XYZ order, and then translates it by the 3D float - None ### C Prototype -`void mtxf_rotate_xyz_and_translate(OUT Mat4 dest, Vec3f b, Vec3s c);` +`void mtxf_rotate_xyz_and_translate(VEC_OUT Mat4 dest, Vec3f b, Vec3s c);` [:arrow_up_small:](#) @@ -5193,7 +5240,7 @@ Transforms a 4x4 floating-point matrix `mtx` into a "billboard" oriented toward - None ### C Prototype -`void mtxf_billboard(OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle);` +`void mtxf_billboard(VEC_OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle);` [:arrow_up_small:](#) @@ -5219,7 +5266,7 @@ Creates a "cylindrical billboard" transformation from the 4x4 matrix `mtx` place - None ### C Prototype -`void mtxf_cylboard(OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle);` +`void mtxf_cylboard(VEC_OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle);` [:arrow_up_small:](#) @@ -5245,7 +5292,7 @@ Aligns `dest` so that it fits the orientation of a terrain surface defined by it - None ### C Prototype -`void mtxf_align_terrain_normal(OUT Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw);` +`void mtxf_align_terrain_normal(VEC_OUT Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw);` [:arrow_up_small:](#) @@ -5271,7 +5318,7 @@ Aligns `mtx` to fit onto a terrain triangle at `pos`, applying a given `yaw` and - None ### C Prototype -`void mtxf_align_terrain_triangle(OUT Mat4 mtx, Vec3f pos, s16 yaw, f32 radius);` +`void mtxf_align_terrain_triangle(VEC_OUT Mat4 mtx, Vec3f pos, s16 yaw, f32 radius);` [:arrow_up_small:](#) @@ -5296,7 +5343,7 @@ Multiplies two 4x4 floating-point matrices `a` and `b` (in that order), storing - None ### C Prototype -`void mtxf_mul(OUT Mat4 dest, Mat4 a, Mat4 b);` +`void mtxf_mul(VEC_OUT Mat4 dest, Mat4 a, Mat4 b);` [:arrow_up_small:](#) @@ -5308,7 +5355,7 @@ Multiplies two 4x4 floating-point matrices `a` and `b` (in that order), storing Multiplies the 3D signed-integer vector `b` with the 4x4 floating-point matrix `mtx`, which applies the transformation to the point ### Lua Example -`local Vec3sValue = mtxf_mul_vec3s(mtx, b)` +`local vec3sValue = mtxf_mul_vec3s(mtx, b)` ### Parameters | Field | Type | @@ -5317,10 +5364,10 @@ Multiplies the 3D signed-integer vector `b` with the 4x4 floating-point matrix ` | b | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp mtxf_mul_vec3s(Mat4 mtx, OUT Vec3s b);` +`Vec3sp mtxf_mul_vec3s(Mat4 mtx, VEC_OUT Vec3s b);` [:arrow_up_small:](#) @@ -5344,7 +5391,7 @@ Rotates the matrix `mtx` in the XY plane by the given `angle`. Rotating in the X - None ### C Prototype -`void mtxf_rotate_xy(OUT Mat4 mtx, s16 angle);` +`void mtxf_rotate_xy(VEC_OUT Mat4 mtx, s16 angle);` [:arrow_up_small:](#) @@ -5368,7 +5415,7 @@ Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Ap - None ### C Prototype -`void mtxf_inverse(OUT Mat4 dest, Mat4 src);` +`void mtxf_inverse(VEC_OUT Mat4 dest, Mat4 src);` [:arrow_up_small:](#) @@ -5392,7 +5439,7 @@ Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Ap - `boolean` ### C Prototype -`bool mtxf_inverse_non_affine(OUT Mat4 dest, Mat4 src);` +`bool mtxf_inverse_non_affine(VEC_OUT Mat4 dest, Mat4 src);` [:arrow_up_small:](#) @@ -5404,7 +5451,7 @@ Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Ap Extracts the position (translation component) from the transformation matrix `objMtx` relative to the coordinate system defined by `camMtx` and stores that 3D position in `dest`. This can be used to get the object's coordinates in camera space ### Lua Example -`local Vec3fValue = get_pos_from_transform_mtx(dest, objMtx, camMtx)` +`local vec3fValue = get_pos_from_transform_mtx(dest, objMtx, camMtx)` ### Parameters | Field | Type | @@ -5414,10 +5461,10 @@ Extracts the position (translation component) from the transformation matrix `ob | camMtx | [Mat4](structs.md#Mat4) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp get_pos_from_transform_mtx(OUT Vec3f dest, Mat4 objMtx, Mat4 camMtx);` +`Vec3fp get_pos_from_transform_mtx(VEC_OUT Vec3f dest, Mat4 objMtx, Mat4 camMtx);` [:arrow_up_small:](#) @@ -5568,7 +5615,7 @@ Sets the 4x4 floating-point matrix `mtx` to all zeros. Unless you really need th - None ### C Prototype -`void mtxf_zero(OUT Mat4 mtx);` +`void mtxf_zero(VEC_OUT Mat4 mtx);` [:arrow_up_small:](#) @@ -5592,7 +5639,7 @@ Copies the 4x4 floating-point matrix `src` into `dest`. After this operation, `d - None ### C Prototype -`void mtxf_copy(OUT Mat4 dest, Mat4 src);` +`void mtxf_copy(VEC_OUT Mat4 dest, Mat4 src);` [:arrow_up_small:](#) @@ -5615,7 +5662,7 @@ Sets the 4x4 floating-point matrix `mtx` to the identity matrix. The identity ma - None ### C Prototype -`void mtxf_identity(OUT Mat4 mtx);` +`void mtxf_identity(VEC_OUT Mat4 mtx);` [:arrow_up_small:](#) @@ -5639,7 +5686,7 @@ Sets the 4x4 floating-point matrix `dest` to the translation matrix decribed by - None ### C Prototype -`void mtxf_translate(OUT Mat4 dest, Vec3f b);` +`void mtxf_translate(VEC_OUT Mat4 dest, Vec3f b);` [:arrow_up_small:](#) @@ -5664,7 +5711,7 @@ Scales the 4x4 floating-point matrix `mtx` by the scaling factors found in the 3 - None ### C Prototype -`void mtxf_scale_vec3f(OUT Mat4 dest, Mat4 mtx, Vec3f s);` +`void mtxf_scale_vec3f(VEC_OUT Mat4 dest, Mat4 mtx, Vec3f s);` [:arrow_up_small:](#) @@ -5682,7 +5729,7 @@ Scales the 4x4 floating-point matrix `mtx` by the scaling factors found in the 3 Sets the components of the 3D floating-point vector `v` to 0 ### Lua Example -`local Vec3fValue = vec3f_zero(v)` +`local vec3fValue = vec3f_zero(v)` ### Parameters | Field | Type | @@ -5690,10 +5737,10 @@ Sets the components of the 3D floating-point vector `v` to 0 | v | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_zero(OUT Vec3f v);` +`Vec3fp vec3f_zero(VEC_OUT Vec3f v);` [:arrow_up_small:](#) @@ -5705,7 +5752,7 @@ Sets the components of the 3D floating-point vector `v` to 0 Copies the contents of a 3D floating-point vector (`src`) into another 3D floating-point vector (`dest`) ### Lua Example -`local Vec3fValue = vec3f_copy(dest, src)` +`local vec3fValue = vec3f_copy(dest, src)` ### Parameters | Field | Type | @@ -5714,10 +5761,10 @@ Copies the contents of a 3D floating-point vector (`src`) into another 3D floati | src | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_copy(OUT Vec3f dest, Vec3f src);` +`Vec3fp vec3f_copy(VEC_OUT Vec3f dest, Vec3f src);` [:arrow_up_small:](#) @@ -5729,7 +5776,7 @@ Copies the contents of a 3D floating-point vector (`src`) into another 3D floati Sets the values of the 3D floating-point vector `dest` to the given x, y, and z values ### Lua Example -`local Vec3fValue = vec3f_set(dest, x, y, z)` +`local vec3fValue = vec3f_set(dest, x, y, z)` ### Parameters | Field | Type | @@ -5740,10 +5787,10 @@ Sets the values of the 3D floating-point vector `dest` to the given x, y, and z | z | `number` | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_set(OUT Vec3f dest, f32 x, f32 y, f32 z);` +`Vec3fp vec3f_set(VEC_OUT Vec3f dest, f32 x, f32 y, f32 z);` [:arrow_up_small:](#) @@ -5755,7 +5802,7 @@ Sets the values of the 3D floating-point vector `dest` to the given x, y, and z Adds the components of the 3D floating-point vector `a` to `dest` ### Lua Example -`local Vec3fValue = vec3f_add(dest, a)` +`local vec3fValue = vec3f_add(dest, a)` ### Parameters | Field | Type | @@ -5764,10 +5811,10 @@ Adds the components of the 3D floating-point vector `a` to `dest` | a | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_add(OUT Vec3f dest, Vec3f a);` +`Vec3fp vec3f_add(VEC_OUT Vec3f dest, Vec3f a);` [:arrow_up_small:](#) @@ -5779,7 +5826,7 @@ Adds the components of the 3D floating-point vector `a` to `dest` Adds the components of two 3D floating-point vectors `a` and `b` and stores the result in `dest` ### Lua Example -`local Vec3fValue = vec3f_sum(dest, a, b)` +`local vec3fValue = vec3f_sum(dest, a, b)` ### Parameters | Field | Type | @@ -5789,10 +5836,10 @@ Adds the components of two 3D floating-point vectors `a` and `b` and stores the | b | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_sum(OUT Vec3f dest, Vec3f a, Vec3f b);` +`Vec3fp vec3f_sum(VEC_OUT Vec3f dest, Vec3f a, Vec3f b);` [:arrow_up_small:](#) @@ -5804,7 +5851,7 @@ Adds the components of two 3D floating-point vectors `a` and `b` and stores the Subtracts the components of the 3D floating-point vector `a` from `dest` ### Lua Example -`local Vec3fValue = vec3f_sub(dest, a)` +`local vec3fValue = vec3f_sub(dest, a)` ### Parameters | Field | Type | @@ -5813,10 +5860,10 @@ Subtracts the components of the 3D floating-point vector `a` from `dest` | a | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_sub(OUT Vec3f dest, Vec3f a);` +`Vec3fp vec3f_sub(VEC_OUT Vec3f dest, Vec3f a);` [:arrow_up_small:](#) @@ -5828,7 +5875,7 @@ Subtracts the components of the 3D floating-point vector `a` from `dest` Subtracts the components of the 3D floating-point vector `b` from the components of `a` and stores the result in `dest` ### Lua Example -`local Vec3fValue = vec3f_dif(dest, a, b)` +`local vec3fValue = vec3f_dif(dest, a, b)` ### Parameters | Field | Type | @@ -5838,10 +5885,10 @@ Subtracts the components of the 3D floating-point vector `b` from the components | b | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_dif(OUT Vec3f dest, Vec3f a, Vec3f b);` +`Vec3fp vec3f_dif(VEC_OUT Vec3f dest, Vec3f a, Vec3f b);` [:arrow_up_small:](#) @@ -5853,7 +5900,7 @@ Subtracts the components of the 3D floating-point vector `b` from the components Multiplies each component of the 3D floating-point vector `dest` by the scalar value `a` ### Lua Example -`local Vec3fValue = vec3f_mul(dest, a)` +`local vec3fValue = vec3f_mul(dest, a)` ### Parameters | Field | Type | @@ -5862,10 +5909,10 @@ Multiplies each component of the 3D floating-point vector `dest` by the scalar v | a | `number` | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_mul(OUT Vec3f dest, f32 a);` +`Vec3fp vec3f_mul(VEC_OUT Vec3f dest, f32 a);` [:arrow_up_small:](#) @@ -5877,7 +5924,7 @@ Multiplies each component of the 3D floating-point vector `dest` by the scalar v Multiplies the components of the 3D floating-point vector `dest` with the components of `a` ### Lua Example -`local Vec3fValue = vec3f_mult(dest, a)` +`local vec3fValue = vec3f_mult(dest, a)` ### Parameters | Field | Type | @@ -5886,10 +5933,10 @@ Multiplies the components of the 3D floating-point vector `dest` with the compon | a | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_mult(OUT Vec3f dest, Vec3f a);` +`Vec3fp vec3f_mult(VEC_OUT Vec3f dest, Vec3f a);` [:arrow_up_small:](#) @@ -5901,7 +5948,7 @@ Multiplies the components of the 3D floating-point vector `dest` with the compon Multiplies the components of two 3D floating-point vectors `a` and `b` and stores the result in `dest` ### Lua Example -`local Vec3fValue = vec3f_prod(dest, a, b)` +`local vec3fValue = vec3f_prod(dest, a, b)` ### Parameters | Field | Type | @@ -5911,10 +5958,10 @@ Multiplies the components of two 3D floating-point vectors `a` and `b` and store | b | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_prod(OUT Vec3f dest, Vec3f a, Vec3f b);` +`Vec3fp vec3f_prod(VEC_OUT Vec3f dest, Vec3f a, Vec3f b);` [:arrow_up_small:](#) @@ -5926,7 +5973,7 @@ Multiplies the components of two 3D floating-point vectors `a` and `b` and store Divides each component of the 3D floating-point vector `dest` by the scalar value `a` ### Lua Example -`local Vec3fValue = vec3f_div(dest, a)` +`local vec3fValue = vec3f_div(dest, a)` ### Parameters | Field | Type | @@ -5935,10 +5982,10 @@ Divides each component of the 3D floating-point vector `dest` by the scalar valu | a | `number` | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_div(OUT Vec3f dest, f32 a);` +`Vec3fp vec3f_div(VEC_OUT Vec3f dest, f32 a);` [:arrow_up_small:](#) @@ -5973,7 +6020,7 @@ Calculates the length (magnitude) of the 3D floating-point vector `a` Normalizes the 3D floating-point vector `v` so that its length (magnitude) becomes 1, while retaining its direction ### Lua Example -`local Vec3fValue = vec3f_normalize(v)` +`local vec3fValue = vec3f_normalize(v)` ### Parameters | Field | Type | @@ -5981,10 +6028,10 @@ Normalizes the 3D floating-point vector `v` so that its length (magnitude) becom | v | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_normalize(OUT Vec3f v);` +`Vec3fp vec3f_normalize(VEC_OUT Vec3f v);` [:arrow_up_small:](#) @@ -5996,7 +6043,7 @@ Normalizes the 3D floating-point vector `v` so that its length (magnitude) becom Sets the length (magnitude) of 3D floating-point vector `v`, while retaining its direction ### Lua Example -`local Vec3fValue = vec3f_set_magnitude(v, mag)` +`local vec3fValue = vec3f_set_magnitude(v, mag)` ### Parameters | Field | Type | @@ -6005,10 +6052,10 @@ Sets the length (magnitude) of 3D floating-point vector `v`, while retaining its | mag | `number` | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_set_magnitude(OUT Vec3f v, f32 mag);` +`Vec3fp vec3f_set_magnitude(VEC_OUT Vec3f v, f32 mag);` [:arrow_up_small:](#) @@ -6044,7 +6091,7 @@ Computes the dot product of the two 3D floating-point vectors `a` and `b` Computes the cross product of two 3D floating-point vectors `a` and `b` and stores the result in `dest` ### Lua Example -`local Vec3fValue = vec3f_cross(dest, a, b)` +`local vec3fValue = vec3f_cross(dest, a, b)` ### Parameters | Field | Type | @@ -6054,10 +6101,10 @@ Computes the cross product of two 3D floating-point vectors `a` and `b` and stor | b | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_cross(OUT Vec3f dest, Vec3f a, Vec3f b);` +`Vec3fp vec3f_cross(VEC_OUT Vec3f dest, Vec3f a, Vec3f b);` [:arrow_up_small:](#) @@ -6069,7 +6116,7 @@ Computes the cross product of two 3D floating-point vectors `a` and `b` and stor Takes two 3D floating-point vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest` ### Lua Example -`local Vec3fValue = vec3f_combine(dest, vecA, vecB, sclA, sclB)` +`local vec3fValue = vec3f_combine(dest, vecA, vecB, sclA, sclB)` ### Parameters | Field | Type | @@ -6081,10 +6128,10 @@ Takes two 3D floating-point vectors `vecA` and `vecB`, multiplies them by `sclA` | sclB | `number` | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3f_combine(OUT Vec3f dest, Vec3f vecA, Vec3f vecB, f32 sclA, f32 sclB);` +`Vec3fp vec3f_combine(VEC_OUT Vec3f dest, Vec3f vecA, Vec3f vecB, f32 sclA, f32 sclB);` [:arrow_up_small:](#) @@ -6167,7 +6214,7 @@ Returns `true` if all components of the 3D floating-point vector `v` are zero Converts a 3D floating-point vector `a` into a 3D integer vector and stores the result in `dest` ### Lua Example -`local Vec3iValue = vec3f_to_vec3i(dest, a)` +`local vec3iValue = vec3f_to_vec3i(dest, a)` ### Parameters | Field | Type | @@ -6176,10 +6223,10 @@ Converts a 3D floating-point vector `a` into a 3D integer vector and stores the | a | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3i](structs.md#Vec3i) +- [Vec3i](structs.md#Vec3i) ### C Prototype -`Vec3ip vec3f_to_vec3i(OUT Vec3i dest, Vec3f a);` +`Vec3ip vec3f_to_vec3i(VEC_OUT Vec3i dest, Vec3f a);` [:arrow_up_small:](#) @@ -6191,7 +6238,7 @@ Converts a 3D floating-point vector `a` into a 3D integer vector and stores the Converts a 3D floating-point vector `a` into a 3D short integer vector and stores the result in `dest` ### Lua Example -`local Vec3sValue = vec3f_to_vec3s(dest, a)` +`local vec3sValue = vec3f_to_vec3s(dest, a)` ### Parameters | Field | Type | @@ -6200,549 +6247,10 @@ Converts a 3D floating-point vector `a` into a 3D short integer vector and store | a | [Vec3f](structs.md#Vec3f) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3f_to_vec3s(OUT Vec3s dest, Vec3f a);` - -[:arrow_up_small:](#) - -
- ---- -# functions from math_util_vec3i.inl - -
- - -## [vec3i_zero](#vec3i_zero) - -### Description -Sets the components of the 3D integer vector `v` to 0 - -### Lua Example -`local Vec3iValue = vec3i_zero(v)` - -### Parameters -| Field | Type | -| ----- | ---- | -| v | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_zero(OUT Vec3i v);` - -[:arrow_up_small:](#) - -
- -## [vec3i_copy](#vec3i_copy) - -### Description -Copies the contents of a 3D integer vector (`src`) into another 3D integer vector (`dest`) - -### Lua Example -`local Vec3iValue = vec3i_copy(dest, src)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| src | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_copy(OUT Vec3i dest, Vec3i src);` - -[:arrow_up_small:](#) - -
- -## [vec3i_set](#vec3i_set) - -### Description -Sets the values of the 3D integer vector `dest` to the given x, y, and z values - -### Lua Example -`local Vec3iValue = vec3i_set(dest, x, y, z)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| x | `integer` | -| y | `integer` | -| z | `integer` | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_set(OUT Vec3i dest, s32 x, s32 y, s32 z);` - -[:arrow_up_small:](#) - -
- -## [vec3i_add](#vec3i_add) - -### Description -Adds the components of the 3D integer vector `a` to `dest` - -### Lua Example -`local Vec3iValue = vec3i_add(dest, a)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| a | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_add(OUT Vec3i dest, Vec3i a);` - -[:arrow_up_small:](#) - -
- -## [vec3i_sum](#vec3i_sum) - -### Description -Adds the components of two 3D integer vectors `a` and `b` and stores the result in `dest` - -### Lua Example -`local Vec3iValue = vec3i_sum(dest, a, b)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| a | [Vec3i](structs.md#Vec3i) | -| b | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_sum(OUT Vec3i dest, Vec3i a, Vec3i b);` - -[:arrow_up_small:](#) - -
- -## [vec3i_sub](#vec3i_sub) - -### Description -Subtracts the components of the 3D integer vector `a` from `dest` - -### Lua Example -`local Vec3iValue = vec3i_sub(dest, a)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| a | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_sub(OUT Vec3i dest, Vec3i a);` - -[:arrow_up_small:](#) - -
- -## [vec3i_dif](#vec3i_dif) - -### Description -Subtracts the components of the 3D integer vector `b` from the components of `a` and stores the result in `dest` - -### Lua Example -`local Vec3iValue = vec3i_dif(dest, a, b)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| a | [Vec3i](structs.md#Vec3i) | -| b | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_dif(OUT Vec3i dest, Vec3i a, Vec3i b);` - -[:arrow_up_small:](#) - -
- -## [vec3i_mul](#vec3i_mul) - -### Description -Multiplies each component of the 3D integer vector `dest` by the scalar value `a` - -### Lua Example -`local Vec3iValue = vec3i_mul(dest, a)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| a | `number` | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_mul(OUT Vec3i dest, f32 a);` - -[:arrow_up_small:](#) - -
- -## [vec3i_mult](#vec3i_mult) - -### Description -Multiplies the components of the 3D integer vector `dest` with the components of `a` - -### Lua Example -`local Vec3iValue = vec3i_mult(dest, a)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| a | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_mult(OUT Vec3i dest, Vec3i a);` - -[:arrow_up_small:](#) - -
- -## [vec3i_prod](#vec3i_prod) - -### Description -Multiplies the components of two 3D integer vectors `a` and `b` and stores the result in `dest` - -### Lua Example -`local Vec3iValue = vec3i_prod(dest, a, b)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| a | [Vec3i](structs.md#Vec3i) | -| b | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_prod(OUT Vec3i dest, Vec3i a, Vec3i b);` - -[:arrow_up_small:](#) - -
- -## [vec3i_div](#vec3i_div) - -### Description -Divides each component of the 3D integer vector `dest` by the scalar value `a` - -### Lua Example -`local Vec3iValue = vec3i_div(dest, a)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| a | `number` | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_div(OUT Vec3i dest, f32 a);` - -[:arrow_up_small:](#) - -
- -## [vec3i_length](#vec3i_length) - -### Description -Calculates the length (magnitude) of the 3D integer vector `a` - -### Lua Example -`local numberValue = vec3i_length(a)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a | [Vec3i](structs.md#Vec3i) | - -### Returns -- `number` - -### C Prototype -`f32 vec3i_length(Vec3i a);` - -[:arrow_up_small:](#) - -
- -## [vec3i_normalize](#vec3i_normalize) - -### Description -Normalizes the 3D integer vector `v` so that its length (magnitude) becomes 1, while retaining its direction - -### Lua Example -`local Vec3iValue = vec3i_normalize(v)` - -### Parameters -| Field | Type | -| ----- | ---- | -| v | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_normalize(OUT Vec3i v);` - -[:arrow_up_small:](#) - -
- -## [vec3i_set_magnitude](#vec3i_set_magnitude) - -### Description -Sets the length (magnitude) of 3D integer vector `v`, while retaining its direction - -### Lua Example -`local Vec3iValue = vec3i_set_magnitude(v, mag)` - -### Parameters -| Field | Type | -| ----- | ---- | -| v | [Vec3i](structs.md#Vec3i) | -| mag | `number` | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_set_magnitude(OUT Vec3i v, f32 mag);` - -[:arrow_up_small:](#) - -
- -## [vec3i_dot](#vec3i_dot) - -### Description -Computes the dot product of the two 3D integer vectors `a` and `b` - -### Lua Example -`local numberValue = vec3i_dot(a, b)` - -### Parameters -| Field | Type | -| ----- | ---- | -| a | [Vec3i](structs.md#Vec3i) | -| b | [Vec3i](structs.md#Vec3i) | - -### Returns -- `number` - -### C Prototype -`f32 vec3i_dot(Vec3i a, Vec3i b);` - -[:arrow_up_small:](#) - -
- -## [vec3i_cross](#vec3i_cross) - -### Description -Computes the cross product of two 3D integer vectors `a` and `b` and stores the result in `dest` - -### Lua Example -`local Vec3iValue = vec3i_cross(dest, a, b)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| a | [Vec3i](structs.md#Vec3i) | -| b | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_cross(OUT Vec3i dest, Vec3i a, Vec3i b);` - -[:arrow_up_small:](#) - -
- -## [vec3i_combine](#vec3i_combine) - -### Description -Takes two 3D integer vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest` - -### Lua Example -`local Vec3iValue = vec3i_combine(dest, vecA, vecB, sclA, sclB)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3i](structs.md#Vec3i) | -| vecA | [Vec3i](structs.md#Vec3i) | -| vecB | [Vec3i](structs.md#Vec3i) | -| sclA | `number` | -| sclB | `number` | - -### Returns -[Vec3i](structs.md#Vec3i) - -### C Prototype -`Vec3ip vec3i_combine(OUT Vec3i dest, Vec3i vecA, Vec3i vecB, f32 sclA, f32 sclB);` - -[:arrow_up_small:](#) - -
- -## [vec3i_dist](#vec3i_dist) - -### Description -Calculates the distance between two 3D integer vectors `v1` and `v2` - -### Lua Example -`local numberValue = vec3i_dist(v1, v2)` - -### Parameters -| Field | Type | -| ----- | ---- | -| v1 | [Vec3i](structs.md#Vec3i) | -| v2 | [Vec3i](structs.md#Vec3i) | - -### Returns -- `number` - -### C Prototype -`f32 vec3i_dist(Vec3i v1, Vec3i v2);` - -[:arrow_up_small:](#) - -
- -## [vec3i_hdist](#vec3i_hdist) - -### Description -Calculates the horizontal distance between two 3D integer vectors `v1` and `v2`, as if their y component was 0 - -### Lua Example -`local numberValue = vec3i_hdist(v1, v2)` - -### Parameters -| Field | Type | -| ----- | ---- | -| v1 | [Vec3i](structs.md#Vec3i) | -| v2 | [Vec3i](structs.md#Vec3i) | - -### Returns -- `number` - -### C Prototype -`f32 vec3i_hdist(Vec3i v1, Vec3i v2);` - -[:arrow_up_small:](#) - -
- -## [vec3i_is_zero](#vec3i_is_zero) - -### Description -Returns `true` if all components of the 3D integer vector `v` are zero - -### Lua Example -`local booleanValue = vec3i_is_zero(v)` - -### Parameters -| Field | Type | -| ----- | ---- | -| v | [Vec3i](structs.md#Vec3i) | - -### Returns -- `boolean` - -### C Prototype -`bool vec3i_is_zero(Vec3i v);` - -[:arrow_up_small:](#) - -
- -## [vec3i_to_vec3f](#vec3i_to_vec3f) - -### Description -Converts a 3D integer vector `a` into a 3D floating-point vector and stores the result in `dest` - -### Lua Example -`local Vec3fValue = vec3i_to_vec3f(dest, a)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3f](structs.md#Vec3f) | -| a | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3f](structs.md#Vec3f) - -### C Prototype -`Vec3fp vec3i_to_vec3f(OUT Vec3f dest, Vec3i a);` - -[:arrow_up_small:](#) - -
- -## [vec3i_to_vec3s](#vec3i_to_vec3s) - -### Description -Converts a 3D integer vector `a` into a 3D short integer vector and stores the result in `dest` - -### Lua Example -`local Vec3sValue = vec3i_to_vec3s(dest, a)` - -### Parameters -| Field | Type | -| ----- | ---- | -| dest | [Vec3s](structs.md#Vec3s) | -| a | [Vec3i](structs.md#Vec3i) | - -### Returns -[Vec3s](structs.md#Vec3s) - -### C Prototype -`Vec3sp vec3i_to_vec3s(OUT Vec3s dest, Vec3i a);` +`Vec3sp vec3f_to_vec3s(VEC_OUT Vec3s dest, Vec3f a);` [:arrow_up_small:](#) diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md index 21ef90e6f..507dd7401 100644 --- a/docs/lua/functions-5.md +++ b/docs/lua/functions-5.md @@ -5,6 +5,545 @@ [< prev](functions-4.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | 5 | [6](functions-6.md) | [7](functions-7.md) | [next >](functions-6.md)] +--- +# functions from math_util_vec3i.inl + +
+ + +## [vec3i_zero](#vec3i_zero) + +### Description +Sets the components of the 3D integer vector `v` to 0 + +### Lua Example +`local vec3iValue = vec3i_zero(v)` + +### Parameters +| Field | Type | +| ----- | ---- | +| v | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_zero(VEC_OUT Vec3i v);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_copy](#vec3i_copy) + +### Description +Copies the contents of a 3D integer vector (`src`) into another 3D integer vector (`dest`) + +### Lua Example +`local vec3iValue = vec3i_copy(dest, src)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| src | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_copy(VEC_OUT Vec3i dest, Vec3i src);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_set](#vec3i_set) + +### Description +Sets the values of the 3D integer vector `dest` to the given x, y, and z values + +### Lua Example +`local vec3iValue = vec3i_set(dest, x, y, z)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| x | `integer` | +| y | `integer` | +| z | `integer` | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_set(VEC_OUT Vec3i dest, s32 x, s32 y, s32 z);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_add](#vec3i_add) + +### Description +Adds the components of the 3D integer vector `a` to `dest` + +### Lua Example +`local vec3iValue = vec3i_add(dest, a)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| a | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_add(VEC_OUT Vec3i dest, Vec3i a);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_sum](#vec3i_sum) + +### Description +Adds the components of two 3D integer vectors `a` and `b` and stores the result in `dest` + +### Lua Example +`local vec3iValue = vec3i_sum(dest, a, b)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| a | [Vec3i](structs.md#Vec3i) | +| b | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_sum(VEC_OUT Vec3i dest, Vec3i a, Vec3i b);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_sub](#vec3i_sub) + +### Description +Subtracts the components of the 3D integer vector `a` from `dest` + +### Lua Example +`local vec3iValue = vec3i_sub(dest, a)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| a | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_sub(VEC_OUT Vec3i dest, Vec3i a);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_dif](#vec3i_dif) + +### Description +Subtracts the components of the 3D integer vector `b` from the components of `a` and stores the result in `dest` + +### Lua Example +`local vec3iValue = vec3i_dif(dest, a, b)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| a | [Vec3i](structs.md#Vec3i) | +| b | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_dif(VEC_OUT Vec3i dest, Vec3i a, Vec3i b);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_mul](#vec3i_mul) + +### Description +Multiplies each component of the 3D integer vector `dest` by the scalar value `a` + +### Lua Example +`local vec3iValue = vec3i_mul(dest, a)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| a | `number` | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_mul(VEC_OUT Vec3i dest, f32 a);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_mult](#vec3i_mult) + +### Description +Multiplies the components of the 3D integer vector `dest` with the components of `a` + +### Lua Example +`local vec3iValue = vec3i_mult(dest, a)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| a | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_mult(VEC_OUT Vec3i dest, Vec3i a);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_prod](#vec3i_prod) + +### Description +Multiplies the components of two 3D integer vectors `a` and `b` and stores the result in `dest` + +### Lua Example +`local vec3iValue = vec3i_prod(dest, a, b)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| a | [Vec3i](structs.md#Vec3i) | +| b | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_prod(VEC_OUT Vec3i dest, Vec3i a, Vec3i b);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_div](#vec3i_div) + +### Description +Divides each component of the 3D integer vector `dest` by the scalar value `a` + +### Lua Example +`local vec3iValue = vec3i_div(dest, a)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| a | `number` | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_div(VEC_OUT Vec3i dest, f32 a);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_length](#vec3i_length) + +### Description +Calculates the length (magnitude) of the 3D integer vector `a` + +### Lua Example +`local numberValue = vec3i_length(a)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a | [Vec3i](structs.md#Vec3i) | + +### Returns +- `number` + +### C Prototype +`f32 vec3i_length(Vec3i a);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_normalize](#vec3i_normalize) + +### Description +Normalizes the 3D integer vector `v` so that its length (magnitude) becomes 1, while retaining its direction + +### Lua Example +`local vec3iValue = vec3i_normalize(v)` + +### Parameters +| Field | Type | +| ----- | ---- | +| v | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_normalize(VEC_OUT Vec3i v);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_set_magnitude](#vec3i_set_magnitude) + +### Description +Sets the length (magnitude) of 3D integer vector `v`, while retaining its direction + +### Lua Example +`local vec3iValue = vec3i_set_magnitude(v, mag)` + +### Parameters +| Field | Type | +| ----- | ---- | +| v | [Vec3i](structs.md#Vec3i) | +| mag | `number` | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_set_magnitude(VEC_OUT Vec3i v, f32 mag);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_dot](#vec3i_dot) + +### Description +Computes the dot product of the two 3D integer vectors `a` and `b` + +### Lua Example +`local numberValue = vec3i_dot(a, b)` + +### Parameters +| Field | Type | +| ----- | ---- | +| a | [Vec3i](structs.md#Vec3i) | +| b | [Vec3i](structs.md#Vec3i) | + +### Returns +- `number` + +### C Prototype +`f32 vec3i_dot(Vec3i a, Vec3i b);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_cross](#vec3i_cross) + +### Description +Computes the cross product of two 3D integer vectors `a` and `b` and stores the result in `dest` + +### Lua Example +`local vec3iValue = vec3i_cross(dest, a, b)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| a | [Vec3i](structs.md#Vec3i) | +| b | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_cross(VEC_OUT Vec3i dest, Vec3i a, Vec3i b);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_combine](#vec3i_combine) + +### Description +Takes two 3D integer vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest` + +### Lua Example +`local vec3iValue = vec3i_combine(dest, vecA, vecB, sclA, sclB)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3i](structs.md#Vec3i) | +| vecA | [Vec3i](structs.md#Vec3i) | +| vecB | [Vec3i](structs.md#Vec3i) | +| sclA | `number` | +| sclB | `number` | + +### Returns +- [Vec3i](structs.md#Vec3i) + +### C Prototype +`Vec3ip vec3i_combine(VEC_OUT Vec3i dest, Vec3i vecA, Vec3i vecB, f32 sclA, f32 sclB);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_dist](#vec3i_dist) + +### Description +Calculates the distance between two 3D integer vectors `v1` and `v2` + +### Lua Example +`local numberValue = vec3i_dist(v1, v2)` + +### Parameters +| Field | Type | +| ----- | ---- | +| v1 | [Vec3i](structs.md#Vec3i) | +| v2 | [Vec3i](structs.md#Vec3i) | + +### Returns +- `number` + +### C Prototype +`f32 vec3i_dist(Vec3i v1, Vec3i v2);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_hdist](#vec3i_hdist) + +### Description +Calculates the horizontal distance between two 3D integer vectors `v1` and `v2`, as if their y component was 0 + +### Lua Example +`local numberValue = vec3i_hdist(v1, v2)` + +### Parameters +| Field | Type | +| ----- | ---- | +| v1 | [Vec3i](structs.md#Vec3i) | +| v2 | [Vec3i](structs.md#Vec3i) | + +### Returns +- `number` + +### C Prototype +`f32 vec3i_hdist(Vec3i v1, Vec3i v2);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_is_zero](#vec3i_is_zero) + +### Description +Returns `true` if all components of the 3D integer vector `v` are zero + +### Lua Example +`local booleanValue = vec3i_is_zero(v)` + +### Parameters +| Field | Type | +| ----- | ---- | +| v | [Vec3i](structs.md#Vec3i) | + +### Returns +- `boolean` + +### C Prototype +`bool vec3i_is_zero(Vec3i v);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_to_vec3f](#vec3i_to_vec3f) + +### Description +Converts a 3D integer vector `a` into a 3D floating-point vector and stores the result in `dest` + +### Lua Example +`local vec3fValue = vec3i_to_vec3f(dest, a)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3f](structs.md#Vec3f) | +| a | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3f](structs.md#Vec3f) + +### C Prototype +`Vec3fp vec3i_to_vec3f(VEC_OUT Vec3f dest, Vec3i a);` + +[:arrow_up_small:](#) + +
+ +## [vec3i_to_vec3s](#vec3i_to_vec3s) + +### Description +Converts a 3D integer vector `a` into a 3D short integer vector and stores the result in `dest` + +### Lua Example +`local vec3sValue = vec3i_to_vec3s(dest, a)` + +### Parameters +| Field | Type | +| ----- | ---- | +| dest | [Vec3s](structs.md#Vec3s) | +| a | [Vec3i](structs.md#Vec3i) | + +### Returns +- [Vec3s](structs.md#Vec3s) + +### C Prototype +`Vec3sp vec3i_to_vec3s(VEC_OUT Vec3s dest, Vec3i a);` + +[:arrow_up_small:](#) + +
+ --- # functions from math_util_vec3s.inl @@ -17,7 +556,7 @@ Sets the components of the 3D short integer vector `v` to 0 ### Lua Example -`local Vec3sValue = vec3s_zero(v)` +`local vec3sValue = vec3s_zero(v)` ### Parameters | Field | Type | @@ -25,10 +564,10 @@ Sets the components of the 3D short integer vector `v` to 0 | v | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_zero(OUT Vec3s v);` +`Vec3sp vec3s_zero(VEC_OUT Vec3s v);` [:arrow_up_small:](#) @@ -40,7 +579,7 @@ Sets the components of the 3D short integer vector `v` to 0 Copies the contents of a 3D short integer vector (`src`) into another 3D short integer vector (`dest`) ### Lua Example -`local Vec3sValue = vec3s_copy(dest, src)` +`local vec3sValue = vec3s_copy(dest, src)` ### Parameters | Field | Type | @@ -49,10 +588,10 @@ Copies the contents of a 3D short integer vector (`src`) into another 3D short i | src | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_copy(OUT Vec3s dest, Vec3s src);` +`Vec3sp vec3s_copy(VEC_OUT Vec3s dest, Vec3s src);` [:arrow_up_small:](#) @@ -64,7 +603,7 @@ Copies the contents of a 3D short integer vector (`src`) into another 3D short i Sets the values of the 3D short integer vector `dest` to the given x, y, and z values ### Lua Example -`local Vec3sValue = vec3s_set(dest, x, y, z)` +`local vec3sValue = vec3s_set(dest, x, y, z)` ### Parameters | Field | Type | @@ -75,10 +614,10 @@ Sets the values of the 3D short integer vector `dest` to the given x, y, and z v | z | `integer` | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_set(OUT Vec3s dest, s16 x, s16 y, s16 z);` +`Vec3sp vec3s_set(VEC_OUT Vec3s dest, s16 x, s16 y, s16 z);` [:arrow_up_small:](#) @@ -90,7 +629,7 @@ Sets the values of the 3D short integer vector `dest` to the given x, y, and z v Adds the components of the 3D short integer vector `a` to `dest` ### Lua Example -`local Vec3sValue = vec3s_add(dest, a)` +`local vec3sValue = vec3s_add(dest, a)` ### Parameters | Field | Type | @@ -99,10 +638,10 @@ Adds the components of the 3D short integer vector `a` to `dest` | a | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_add(OUT Vec3s dest, Vec3s a);` +`Vec3sp vec3s_add(VEC_OUT Vec3s dest, Vec3s a);` [:arrow_up_small:](#) @@ -114,7 +653,7 @@ Adds the components of the 3D short integer vector `a` to `dest` Adds the components of two 3D short integer vectors `a` and `b` and stores the result in `dest` ### Lua Example -`local Vec3sValue = vec3s_sum(dest, a, b)` +`local vec3sValue = vec3s_sum(dest, a, b)` ### Parameters | Field | Type | @@ -124,10 +663,10 @@ Adds the components of two 3D short integer vectors `a` and `b` and stores the r | b | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_sum(OUT Vec3s dest, Vec3s a, Vec3s b);` +`Vec3sp vec3s_sum(VEC_OUT Vec3s dest, Vec3s a, Vec3s b);` [:arrow_up_small:](#) @@ -139,7 +678,7 @@ Adds the components of two 3D short integer vectors `a` and `b` and stores the r Subtracts the components of the 3D short integer vector `a` from `dest` ### Lua Example -`local Vec3sValue = vec3s_sub(dest, a)` +`local vec3sValue = vec3s_sub(dest, a)` ### Parameters | Field | Type | @@ -148,10 +687,10 @@ Subtracts the components of the 3D short integer vector `a` from `dest` | a | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_sub(OUT Vec3s dest, Vec3s a);` +`Vec3sp vec3s_sub(VEC_OUT Vec3s dest, Vec3s a);` [:arrow_up_small:](#) @@ -163,7 +702,7 @@ Subtracts the components of the 3D short integer vector `a` from `dest` Subtracts the components of the 3D short integer vector `b` from the components of `a` and stores the result in `dest` ### Lua Example -`local Vec3sValue = vec3s_dif(dest, a, b)` +`local vec3sValue = vec3s_dif(dest, a, b)` ### Parameters | Field | Type | @@ -173,10 +712,10 @@ Subtracts the components of the 3D short integer vector `b` from the components | b | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_dif(OUT Vec3s dest, Vec3s a, Vec3s b);` +`Vec3sp vec3s_dif(VEC_OUT Vec3s dest, Vec3s a, Vec3s b);` [:arrow_up_small:](#) @@ -188,7 +727,7 @@ Subtracts the components of the 3D short integer vector `b` from the components Multiplies each component of the 3D short integer vector `dest` by the scalar value `a` ### Lua Example -`local Vec3sValue = vec3s_mul(dest, a)` +`local vec3sValue = vec3s_mul(dest, a)` ### Parameters | Field | Type | @@ -197,10 +736,10 @@ Multiplies each component of the 3D short integer vector `dest` by the scalar va | a | `number` | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_mul(OUT Vec3s dest, f32 a);` +`Vec3sp vec3s_mul(VEC_OUT Vec3s dest, f32 a);` [:arrow_up_small:](#) @@ -212,7 +751,7 @@ Multiplies each component of the 3D short integer vector `dest` by the scalar va Multiplies the components of the 3D short integer vector `dest` with the components of `a` ### Lua Example -`local Vec3sValue = vec3s_mult(dest, a)` +`local vec3sValue = vec3s_mult(dest, a)` ### Parameters | Field | Type | @@ -221,10 +760,10 @@ Multiplies the components of the 3D short integer vector `dest` with the compone | a | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_mult(OUT Vec3s dest, Vec3s a);` +`Vec3sp vec3s_mult(VEC_OUT Vec3s dest, Vec3s a);` [:arrow_up_small:](#) @@ -236,7 +775,7 @@ Multiplies the components of the 3D short integer vector `dest` with the compone Multiplies the components of two 3D short integer vectors `a` and `b` and stores the result in `dest` ### Lua Example -`local Vec3sValue = vec3s_prod(dest, a, b)` +`local vec3sValue = vec3s_prod(dest, a, b)` ### Parameters | Field | Type | @@ -246,10 +785,10 @@ Multiplies the components of two 3D short integer vectors `a` and `b` and stores | b | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_prod(OUT Vec3s dest, Vec3s a, Vec3s b);` +`Vec3sp vec3s_prod(VEC_OUT Vec3s dest, Vec3s a, Vec3s b);` [:arrow_up_small:](#) @@ -261,7 +800,7 @@ Multiplies the components of two 3D short integer vectors `a` and `b` and stores Divides each component of the 3D short integer vector `dest` by the scalar value `a` ### Lua Example -`local Vec3sValue = vec3s_div(dest, a)` +`local vec3sValue = vec3s_div(dest, a)` ### Parameters | Field | Type | @@ -270,10 +809,10 @@ Divides each component of the 3D short integer vector `dest` by the scalar value | a | `number` | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_div(OUT Vec3s dest, f32 a);` +`Vec3sp vec3s_div(VEC_OUT Vec3s dest, f32 a);` [:arrow_up_small:](#) @@ -308,7 +847,7 @@ Calculates the length (magnitude) of the 3D short integer vector `a` Normalizes the 3D short integer vector `v` so that its length (magnitude) becomes 1, while retaining its direction ### Lua Example -`local Vec3sValue = vec3s_normalize(v)` +`local vec3sValue = vec3s_normalize(v)` ### Parameters | Field | Type | @@ -316,10 +855,10 @@ Normalizes the 3D short integer vector `v` so that its length (magnitude) become | v | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_normalize(OUT Vec3s v);` +`Vec3sp vec3s_normalize(VEC_OUT Vec3s v);` [:arrow_up_small:](#) @@ -331,7 +870,7 @@ Normalizes the 3D short integer vector `v` so that its length (magnitude) become Sets the length (magnitude) of 3D short integer vector `v`, while retaining its direction ### Lua Example -`local Vec3sValue = vec3s_set_magnitude(v, mag)` +`local vec3sValue = vec3s_set_magnitude(v, mag)` ### Parameters | Field | Type | @@ -340,10 +879,10 @@ Sets the length (magnitude) of 3D short integer vector `v`, while retaining its | mag | `number` | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_set_magnitude(OUT Vec3s v, f32 mag);` +`Vec3sp vec3s_set_magnitude(VEC_OUT Vec3s v, f32 mag);` [:arrow_up_small:](#) @@ -379,7 +918,7 @@ Computes the dot product of the two 3D short integer vectors `a` and `b` Computes the cross product of two 3D short integer vectors `a` and `b` and stores the result in `dest` ### Lua Example -`local Vec3sValue = vec3s_cross(dest, a, b)` +`local vec3sValue = vec3s_cross(dest, a, b)` ### Parameters | Field | Type | @@ -389,10 +928,10 @@ Computes the cross product of two 3D short integer vectors `a` and `b` and store | b | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_cross(OUT Vec3s dest, Vec3s a, Vec3s b);` +`Vec3sp vec3s_cross(VEC_OUT Vec3s dest, Vec3s a, Vec3s b);` [:arrow_up_small:](#) @@ -404,7 +943,7 @@ Computes the cross product of two 3D short integer vectors `a` and `b` and store Takes two 3D short integer vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest` ### Lua Example -`local Vec3sValue = vec3s_combine(dest, vecA, vecB, sclA, sclB)` +`local vec3sValue = vec3s_combine(dest, vecA, vecB, sclA, sclB)` ### Parameters | Field | Type | @@ -416,10 +955,10 @@ Takes two 3D short integer vectors `vecA` and `vecB`, multiplies them by `sclA` | sclB | `number` | ### Returns -[Vec3s](structs.md#Vec3s) +- [Vec3s](structs.md#Vec3s) ### C Prototype -`Vec3sp vec3s_combine(OUT Vec3s dest, Vec3s vecA, Vec3s vecB, f32 sclA, f32 sclB);` +`Vec3sp vec3s_combine(VEC_OUT Vec3s dest, Vec3s vecA, Vec3s vecB, f32 sclA, f32 sclB);` [:arrow_up_small:](#) @@ -502,7 +1041,7 @@ Returns `true` if all components of the 3D short integer vector `v` are zero Converts a 3D short integer vector `a` into a 3D floating-point vector and stores the result in `dest` ### Lua Example -`local Vec3fValue = vec3s_to_vec3f(dest, a)` +`local vec3fValue = vec3s_to_vec3f(dest, a)` ### Parameters | Field | Type | @@ -511,10 +1050,10 @@ Converts a 3D short integer vector `a` into a 3D floating-point vector and store | a | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3f](structs.md#Vec3f) +- [Vec3f](structs.md#Vec3f) ### C Prototype -`Vec3fp vec3s_to_vec3f(OUT Vec3f dest, Vec3s a);` +`Vec3fp vec3s_to_vec3f(VEC_OUT Vec3f dest, Vec3s a);` [:arrow_up_small:](#) @@ -526,7 +1065,7 @@ Converts a 3D short integer vector `a` into a 3D floating-point vector and store Converts a 3D short integer vector `a` into a 3D integer vector and stores the result in `dest` ### Lua Example -`local Vec3iValue = vec3s_to_vec3i(dest, a)` +`local vec3iValue = vec3s_to_vec3i(dest, a)` ### Parameters | Field | Type | @@ -535,10 +1074,10 @@ Converts a 3D short integer vector `a` into a 3D integer vector and stores the r | a | [Vec3s](structs.md#Vec3s) | ### Returns -[Vec3i](structs.md#Vec3i) +- [Vec3i](structs.md#Vec3i) ### C Prototype -`Vec3ip vec3s_to_vec3i(OUT Vec3i dest, Vec3s a);` +`Vec3ip vec3s_to_vec3i(VEC_OUT Vec3i dest, Vec3s a);` [:arrow_up_small:](#) @@ -753,7 +1292,7 @@ Linearly interpolates `res` between `a` and `b` with `delta` - None ### C Prototype -`void delta_interpolate_vec3f(OUT Vec3f res, Vec3f a, Vec3f b, f32 delta);` +`void delta_interpolate_vec3f(VEC_OUT Vec3f res, Vec3f a, Vec3f b, f32 delta);` [:arrow_up_small:](#) @@ -779,7 +1318,7 @@ Linearly interpolates `res` between `a` and `b` with `delta` - None ### C Prototype -`void delta_interpolate_vec3s(OUT Vec3s res, Vec3s a, Vec3s b, f32 delta);` +`void delta_interpolate_vec3s(VEC_OUT Vec3s res, Vec3s a, Vec3s b, f32 delta);` [:arrow_up_small:](#) @@ -820,7 +1359,7 @@ Checks the existence of a modfs at path `modPath` or for the active mod if not p Gets the modfs object at path `modPath` or the active mod one if not provided. This function will return nil for a private modfs, even if it exists ### Lua Example -`local ModFsValue = mod_fs_get(modPath)` +`local modFsValue = mod_fs_get(modPath)` ### Parameters | Field | Type | @@ -828,7 +1367,7 @@ Gets the modfs object at path `modPath` or the active mod one if not provided. T | modPath | `string` | ### Returns -[ModFs](structs.md#ModFs) +- [ModFs](structs.md#ModFs) ### C Prototype `struct ModFs *mod_fs_get(OPTIONAL const char *modPath);` @@ -843,7 +1382,7 @@ Gets the modfs object at path `modPath` or the active mod one if not provided. T Reloads the modfs object at path `modPath`. This function will return nil for a private modfs, even if it exists ### Lua Example -`local ModFsValue = mod_fs_reload(modPath)` +`local modFsValue = mod_fs_reload(modPath)` ### Parameters | Field | Type | @@ -851,7 +1390,7 @@ Reloads the modfs object at path `modPath`. This function will return nil for a | modPath | `string` | ### Returns -[ModFs](structs.md#ModFs) +- [ModFs](structs.md#ModFs) ### C Prototype `struct ModFs *mod_fs_reload(OPTIONAL const char *modPath);` @@ -866,13 +1405,13 @@ Reloads the modfs object at path `modPath`. This function will return nil for a Creates a modfs object for the active mod if it doesn't exist. Returns the modfs object on success ### Lua Example -`local ModFsValue = mod_fs_create()` +`local modFsValue = mod_fs_create()` ### Parameters - None ### Returns -[ModFs](structs.md#ModFs) +- [ModFs](structs.md#ModFs) ### C Prototype `struct ModFs *mod_fs_create();` @@ -911,7 +1450,7 @@ Gets the filename at position `index` of the provided `modFs` Gets the file object at path `filepath` of the provided `modFs`. This function will return nil for a private modfs file, even if it exists ### Lua Example -`local ModFsFileValue = mod_fs_get_file(modFs, filepath)` +`local modFsFileValue = mod_fs_get_file(modFs, filepath)` ### Parameters | Field | Type | @@ -920,7 +1459,7 @@ Gets the file object at path `filepath` of the provided `modFs`. This function w | filepath | `string` | ### Returns -[ModFsFile](structs.md#ModFsFile) +- [ModFsFile](structs.md#ModFsFile) ### C Prototype `struct ModFsFile *mod_fs_get_file(struct ModFs *modFs, const char *filepath);` @@ -935,7 +1474,7 @@ Gets the file object at path `filepath` of the provided `modFs`. This function w Creates a new file at path `filepath` for the provided `modFs`. Set `text` to true to treat the file as a pure text file, not a binary file. Returns the created file on success ### Lua Example -`local ModFsFileValue = mod_fs_create_file(modFs, filepath, text)` +`local modFsFileValue = mod_fs_create_file(modFs, filepath, text)` ### Parameters | Field | Type | @@ -945,7 +1484,7 @@ Creates a new file at path `filepath` for the provided `modFs`. Set `text` to tr | text | `boolean` | ### Returns -[ModFsFile](structs.md#ModFsFile) +- [ModFsFile](structs.md#ModFsFile) ### C Prototype `struct ModFsFile *mod_fs_create_file(struct ModFs *modFs, const char *filepath, bool text);` @@ -1942,7 +2481,7 @@ Overrides the location of `np` Gets a network player from `globalIndex` ### Lua Example -`local NetworkPlayerValue = network_player_from_global_index(globalIndex)` +`local networkPlayerValue = network_player_from_global_index(globalIndex)` ### Parameters | Field | Type | @@ -1950,7 +2489,7 @@ Gets a network player from `globalIndex` | globalIndex | `integer` | ### Returns -[NetworkPlayer](structs.md#NetworkPlayer) +- [NetworkPlayer](structs.md#NetworkPlayer) ### C Prototype `struct NetworkPlayer* network_player_from_global_index(u8 globalIndex);` @@ -1965,7 +2504,7 @@ Gets a network player from `globalIndex` Gets the first network player whose information matches `courseNum`, `actNum`, and `levelNum` ### Lua Example -`local NetworkPlayerValue = get_network_player_from_level(courseNum, actNum, levelNum)` +`local networkPlayerValue = get_network_player_from_level(courseNum, actNum, levelNum)` ### Parameters | Field | Type | @@ -1975,7 +2514,7 @@ Gets the first network player whose information matches `courseNum`, `actNum`, a | levelNum | `integer` | ### Returns -[NetworkPlayer](structs.md#NetworkPlayer) +- [NetworkPlayer](structs.md#NetworkPlayer) ### C Prototype `struct NetworkPlayer* get_network_player_from_level(s16 courseNum, s16 actNum, s16 levelNum);` @@ -1990,7 +2529,7 @@ Gets the first network player whose information matches `courseNum`, `actNum`, a Gets the first network player whose information matches `courseNum`, `actNum`, `levelNum`, and `areaIndex` ### Lua Example -`local NetworkPlayerValue = get_network_player_from_area(courseNum, actNum, levelNum, areaIndex)` +`local networkPlayerValue = get_network_player_from_area(courseNum, actNum, levelNum, areaIndex)` ### Parameters | Field | Type | @@ -2001,7 +2540,7 @@ Gets the first network player whose information matches `courseNum`, `actNum`, ` | areaIndex | `integer` | ### Returns -[NetworkPlayer](structs.md#NetworkPlayer) +- [NetworkPlayer](structs.md#NetworkPlayer) ### C Prototype `struct NetworkPlayer* get_network_player_from_area(s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex);` @@ -2016,13 +2555,13 @@ Gets the first network player whose information matches `courseNum`, `actNum`, ` Gets the active network player with the smallest global index. Useful for assigning one player to "own" some kind of functionality or object ### Lua Example -`local NetworkPlayerValue = get_network_player_smallest_global()` +`local networkPlayerValue = get_network_player_smallest_global()` ### Parameters - None ### Returns -[NetworkPlayer](structs.md#NetworkPlayer) +- [NetworkPlayer](structs.md#NetworkPlayer) ### C Prototype `struct NetworkPlayer* get_network_player_smallest_global(void);` @@ -2395,22 +2934,21 @@ Orients an object with the given normals, typically the surface under the object ## [calc_obj_friction](#calc_obj_friction) ### Description -Orients an object with the given normals, typically the surface under the object. +Determines an object's forward speed multiplier. ### Lua Example -`calc_obj_friction(objFriction, floor_nY)` +`local objFriction = calc_obj_friction(floor_nY)` ### Parameters | Field | Type | | ----- | ---- | -| objFriction | `Pointer` <`number`> | | floor_nY | `number` | ### Returns - None ### C Prototype -`void calc_obj_friction(f32 *objFriction, f32 floor_nY);` +`void calc_obj_friction(RET f32 *objFriction, f32 floor_nY);` [:arrow_up_small:](#) @@ -2704,7 +3242,7 @@ Checks if `m` is in the current course/act/level/area Gets the nearest active Mario who isn't bubbled to `obj` ### Lua Example -`local MarioStateValue = nearest_mario_state_to_object(obj)` +`local marioStateValue = nearest_mario_state_to_object(obj)` ### Parameters | Field | Type | @@ -2712,7 +3250,7 @@ Gets the nearest active Mario who isn't bubbled to `obj` | obj | [Object](structs.md#Object) | ### Returns -[MarioState](structs.md#MarioState) +- [MarioState](structs.md#MarioState) ### C Prototype `struct MarioState* nearest_mario_state_to_object(struct Object *obj);` @@ -2727,7 +3265,7 @@ Gets the nearest active Mario who isn't bubbled to `obj` Gets the nearest possible Mario to `obj` despite anything like bubbled state or enemy visibility ### Lua Example -`local MarioStateValue = nearest_possible_mario_state_to_object(obj)` +`local marioStateValue = nearest_possible_mario_state_to_object(obj)` ### Parameters | Field | Type | @@ -2735,7 +3273,7 @@ Gets the nearest possible Mario to `obj` despite anything like bubbled state or | obj | [Object](structs.md#Object) | ### Returns -[MarioState](structs.md#MarioState) +- [MarioState](structs.md#MarioState) ### C Prototype `struct MarioState* nearest_possible_mario_state_to_object(struct Object *obj);` @@ -2750,7 +3288,7 @@ Gets the nearest possible Mario to `obj` despite anything like bubbled state or Gets the nearest player (Mario Object) to `obj` ### Lua Example -`local ObjectValue = nearest_player_to_object(obj)` +`local objectValue = nearest_player_to_object(obj)` ### Parameters | Field | Type | @@ -2758,7 +3296,7 @@ Gets the nearest player (Mario Object) to `obj` | obj | [Object](structs.md#Object) | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object* nearest_player_to_object(struct Object *obj);` @@ -2773,7 +3311,7 @@ Gets the nearest player (Mario Object) to `obj` Gets the nearest interacting Mario to `obj` ### Lua Example -`local MarioStateValue = nearest_interacting_mario_state_to_object(obj)` +`local marioStateValue = nearest_interacting_mario_state_to_object(obj)` ### Parameters | Field | Type | @@ -2781,7 +3319,7 @@ Gets the nearest interacting Mario to `obj` | obj | [Object](structs.md#Object) | ### Returns -[MarioState](structs.md#MarioState) +- [MarioState](structs.md#MarioState) ### C Prototype `struct MarioState *nearest_interacting_mario_state_to_object(struct Object *obj);` @@ -2796,7 +3334,7 @@ Gets the nearest interacting Mario to `obj` Gets the nearest interacting player (Mario Object) to `obj` ### Lua Example -`local ObjectValue = nearest_interacting_player_to_object(obj)` +`local objectValue = nearest_interacting_player_to_object(obj)` ### Parameters | Field | Type | @@ -2804,7 +3342,7 @@ Gets the nearest interacting player (Mario Object) to `obj` | obj | [Object](structs.md#Object) | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *nearest_interacting_player_to_object(struct Object *obj);` @@ -3012,7 +3550,7 @@ Finds any wall collisions and returns what the displacement vector would be. - `integer` ### C Prototype -`s8 obj_find_wall_displacement(OUT Vec3f dist, f32 x, f32 y, f32 z, f32 radius);` +`s8 obj_find_wall_displacement(VEC_OUT Vec3f dist, f32 x, f32 y, f32 z, f32 radius);` [:arrow_up_small:](#) @@ -3522,23 +4060,24 @@ Turns the current object towards `m` by `turnAmount` and subtracts and adds `tar ## [approach_f32_ptr](#approach_f32_ptr) ### Description -Approaches a `target` for `px` using `delta` +Approaches a `target` for `px` using `delta`. Returns TRUE if `px` reaches `target` ### Lua Example -`local integerValue = approach_f32_ptr(px, target, delta)` +`local integerValue, px = approach_f32_ptr(px, target, delta)` ### Parameters | Field | Type | | ----- | ---- | -| px | `Pointer` <`number`> | +| px | `number` | | target | `number` | | delta | `number` | ### Returns - `integer` +- `number` ### C Prototype -`s32 approach_f32_ptr(f32 *px, f32 target, f32 delta);` +`s32 approach_f32_ptr(INOUT f32 *px, f32 target, f32 delta);` [:arrow_up_small:](#) @@ -3691,13 +4230,13 @@ Approaches a `target` value with the current object's facing roll using `delta` ## [obj_smooth_turn](#obj_smooth_turn) ### Lua Example -`local integerValue = obj_smooth_turn(angleVel, angle, targetAngle, targetSpeedProportion, accel, minSpeed, maxSpeed)` +`local integerValue, angleVel, angle = obj_smooth_turn(angleVel, angle, targetAngle, targetSpeedProportion, accel, minSpeed, maxSpeed)` ### Parameters | Field | Type | | ----- | ---- | -| angleVel | `Pointer` <`integer`> | -| angle | `Pointer` <`integer`> | +| angleVel | `integer` | +| angle | `integer` | | targetAngle | `integer` | | targetSpeedProportion | `number` | | accel | `integer` | @@ -3706,9 +4245,11 @@ Approaches a `target` value with the current object's facing roll using `delta` ### Returns - `integer` +- `integer` +- `integer` ### C Prototype -`s32 obj_smooth_turn(s16 *angleVel, s32 *angle, s16 targetAngle, f32 targetSpeedProportion, s16 accel, s16 minSpeed, s16 maxSpeed);` +`s32 obj_smooth_turn(INOUT s16 *angleVel, INOUT s32 *angle, s16 targetAngle, f32 targetSpeedProportion, s16 accel, s16 minSpeed, s16 maxSpeed);` [:arrow_up_small:](#) @@ -3814,23 +4355,24 @@ Rotates the current object's move angle yaw using `delta` in either a randomly d ## [obj_grow_then_shrink](#obj_grow_then_shrink) ### Description -Begin by increasing the current object's scale by `*scaleVel`, and slowly decreasing `scaleVel`. Once the object starts to shrink, wait a bit, and then begin to scale the object toward `endScale`. The first time it reaches below `shootFireScale` during this time, return 1. Return -1 once it's reached endScale +Begin by increasing the current object's scale by `scaleVel`, and slowly decreasing `scaleVel`. Once the object starts to shrink, wait a bit, and then begin to scale the object toward `endScale`. The first time it reaches below `shootFireScale` during this time, return 1. Return -1 once it's reached endScale ### Lua Example -`local integerValue = obj_grow_then_shrink(scaleVel, shootFireScale, endScale)` +`local integerValue, scaleVel = obj_grow_then_shrink(scaleVel, shootFireScale, endScale)` ### Parameters | Field | Type | | ----- | ---- | -| scaleVel | `Pointer` <`number`> | +| scaleVel | `number` | | shootFireScale | `number` | | endScale | `number` | ### Returns - `integer` +- `number` ### C Prototype -`s32 obj_grow_then_shrink(f32 *scaleVel, f32 shootFireScale, f32 endScale);` +`s32 obj_grow_then_shrink(INOUT f32 *scaleVel, f32 shootFireScale, f32 endScale);` [:arrow_up_small:](#) @@ -3839,13 +4381,13 @@ Begin by increasing the current object's scale by `*scaleVel`, and slowly decrea ## [oscillate_toward](#oscillate_toward) ### Lua Example -`local integerValue = oscillate_toward(value, vel, target, velCloseToZero, accel, slowdown)` +`local integerValue, value, vel = oscillate_toward(value, vel, target, velCloseToZero, accel, slowdown)` ### Parameters | Field | Type | | ----- | ---- | -| value | `Pointer` <`integer`> | -| vel | `Pointer` <`number`> | +| value | `integer` | +| vel | `number` | | target | `integer` | | velCloseToZero | `number` | | accel | `number` | @@ -3853,9 +4395,11 @@ Begin by increasing the current object's scale by `*scaleVel`, and slowly decrea ### Returns - `integer` +- `integer` +- `number` ### C Prototype -`s32 oscillate_toward(s32 *value, f32 *vel, s32 target, f32 velCloseToZero, f32 accel, f32 slowdown);` +`s32 oscillate_toward(INOUT s32 *value, INOUT f32 *vel, s32 target, f32 velCloseToZero, f32 accel, f32 slowdown);` [:arrow_up_small:](#) @@ -3864,12 +4408,12 @@ Begin by increasing the current object's scale by `*scaleVel`, and slowly decrea ## [obj_update_blinking](#obj_update_blinking) ### Lua Example -`obj_update_blinking(blinkTimer, baseCycleLength, cycleLengthRange, blinkLength)` +`local blinkTimer = obj_update_blinking(blinkTimer, baseCycleLength, cycleLengthRange, blinkLength)` ### Parameters | Field | Type | | ----- | ---- | -| blinkTimer | `Pointer` <`integer`> | +| blinkTimer | `integer` | | baseCycleLength | `integer` | | cycleLengthRange | `integer` | | blinkLength | `integer` | @@ -3878,7 +4422,7 @@ Begin by increasing the current object's scale by `*scaleVel`, and slowly decrea - None ### C Prototype -`void obj_update_blinking(s32 *blinkTimer, s16 baseCycleLength, s16 cycleLengthRange, s16 blinkLength);` +`void obj_update_blinking(INOUT s32 *blinkTimer, s16 baseCycleLength, s16 cycleLengthRange, s16 blinkLength);` [:arrow_up_small:](#) @@ -3887,21 +4431,20 @@ Begin by increasing the current object's scale by `*scaleVel`, and slowly decrea ## [obj_resolve_object_collisions](#obj_resolve_object_collisions) ### Description -Resolves "collisions" with the current object and other objects by offsetting the current object's position +Resolves "collisions" with the current object and other objects by offsetting the current object's position. Returns TRUE and the target yaw if there is collision ### Lua Example -`local integerValue = obj_resolve_object_collisions(targetYaw)` +`local integerValue, targetYaw = obj_resolve_object_collisions()` ### Parameters -| Field | Type | -| ----- | ---- | -| targetYaw | `Pointer` <`integer`> | +- None ### Returns - `integer` +- `integer` ### C Prototype -`s32 obj_resolve_object_collisions(s32 *targetYaw);` +`s32 obj_resolve_object_collisions(RET s32 *targetYaw);` [:arrow_up_small:](#) @@ -3910,21 +4453,20 @@ Resolves "collisions" with the current object and other objects by offsetting th ## [obj_bounce_off_walls_edges_objects](#obj_bounce_off_walls_edges_objects) ### Description -Bounces the current object off of walls, edges, and objects using `*targetYaw` +Bounces the current object off of walls, edges, and objects. Returns TRUE and the target yaw if there is collision ### Lua Example -`local integerValue = obj_bounce_off_walls_edges_objects(targetYaw)` +`local integerValue, targetYaw = obj_bounce_off_walls_edges_objects()` ### Parameters -| Field | Type | -| ----- | ---- | -| targetYaw | `Pointer` <`integer`> | +- None ### Returns - `integer` +- `integer` ### C Prototype -`s32 obj_bounce_off_walls_edges_objects(s32 *targetYaw);` +`s32 obj_bounce_off_walls_edges_objects(RET s32 *targetYaw);` [:arrow_up_small:](#) @@ -4190,23 +4732,21 @@ Moves the current object for specifically one second (`oTimer` < 30) ## [treat_far_home_as_mario](#treat_far_home_as_mario) ### Description -Moves the current object for specifically one second (`oTimer` < 30) +Treats far home as Mario. Returns the distance and angle to the nearest player ### Lua Example -`treat_far_home_as_mario(threshold, distanceToPlayer, angleToPlayer)` +`local distanceToPlayer, angleToPlayer = treat_far_home_as_mario(threshold)` ### Parameters | Field | Type | | ----- | ---- | | threshold | `number` | -| distanceToPlayer | `Pointer` <`integer`> | -| angleToPlayer | `Pointer` <`integer`> | ### Returns - None ### C Prototype -`void treat_far_home_as_mario(f32 threshold, s32* distanceToPlayer, s32* angleToPlayer);` +`void treat_far_home_as_mario(f32 threshold, RET s32* distanceToPlayer, RET s32* angleToPlayer);` [:arrow_up_small:](#) @@ -4215,7 +4755,7 @@ Moves the current object for specifically one second (`oTimer` < 30) ## [obj_spit_fire](#obj_spit_fire) ### Lua Example -`local ObjectValue = obj_spit_fire(relativePosX, relativePosY, relativePosZ, scale, model, startSpeed, endSpeed, movePitch)` +`local objectValue = obj_spit_fire(relativePosX, relativePosY, relativePosZ, scale, model, startSpeed, endSpeed, movePitch)` ### Parameters | Field | Type | @@ -4230,7 +4770,7 @@ Moves the current object for specifically one second (`oTimer` < 30) | movePitch | `integer` | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object* obj_spit_fire(s16 relativePosX, s16 relativePosY, s16 relativePosZ, f32 scale, s32 model, f32 startSpeed, f32 endSpeed, s16 movePitch);` diff --git a/docs/lua/functions-6.md b/docs/lua/functions-6.md index 925d9c5d3..afd96447e 100644 --- a/docs/lua/functions-6.md +++ b/docs/lua/functions-6.md @@ -13,20 +13,24 @@ ## [clear_move_flag](#clear_move_flag) +### Description +Clears the `flag` from the `bitSet` + ### Lua Example -`local integerValue = clear_move_flag(bitSet, flag)` +`local integerValue, bitSet = clear_move_flag(bitSet, flag)` ### Parameters | Field | Type | | ----- | ---- | -| bitSet | `Pointer` <`integer`> | +| bitSet | `integer` | | flag | `integer` | ### Returns - `integer` +- `integer` ### C Prototype -`s32 clear_move_flag(u32 *bitSet, s32 flag);` +`s32 clear_move_flag(INOUT u32 *bitSet, s32 flag);` [:arrow_up_small:](#) @@ -92,7 +96,7 @@ Overrides the current room Mario is in. Set to -1 to reset override - None ### C Prototype -`void obj_apply_scale_to_matrix(struct Object *obj, OUT Mat4 dst, Mat4 src);` +`void obj_apply_scale_to_matrix(struct Object *obj, VEC_OUT Mat4 dst, Mat4 src);` [:arrow_up_small:](#) @@ -114,7 +118,7 @@ Overrides the current room Mario is in. Set to -1 to reset override - None ### C Prototype -`void create_transformation_from_matrices(OUT Mat4 a0, Mat4 a1, Mat4 a2);` +`void create_transformation_from_matrices(VEC_OUT Mat4 a0, Mat4 a1, Mat4 a2);` [:arrow_up_small:](#) @@ -230,20 +234,21 @@ Overrides the current room Mario is in. Set to -1 to reset override ## [approach_f32_signed](#approach_f32_signed) ### Lua Example -`local integerValue = approach_f32_signed(value, target, increment)` +`local integerValue, value = approach_f32_signed(value, target, increment)` ### Parameters | Field | Type | | ----- | ---- | -| value | `Pointer` <`number`> | +| value | `number` | | target | `number` | | increment | `number` | ### Returns - `integer` +- `number` ### C Prototype -`s32 approach_f32_signed(f32 *value, f32 target, f32 increment);` +`s32 approach_f32_signed(INOUT f32 *value, f32 target, f32 increment);` [:arrow_up_small:](#) @@ -588,7 +593,7 @@ Overrides the current room Mario is in. Set to -1 to reset override ## [spawn_water_droplet](#spawn_water_droplet) ### Lua Example -`local ObjectValue = spawn_water_droplet(parent, params)` +`local objectValue = spawn_water_droplet(parent, params)` ### Parameters | Field | Type | @@ -597,7 +602,7 @@ Overrides the current room Mario is in. Set to -1 to reset override | params | [WaterDropletParams](structs.md#WaterDropletParams) | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *spawn_water_droplet(struct Object *parent, struct WaterDropletParams *params);` @@ -788,7 +793,7 @@ Multiplies a vector by a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ? - None ### C Prototype -`void linear_mtxf_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v);` +`void linear_mtxf_mul_vec3f(Mat4 m, VEC_OUT Vec3f dst, Vec3f v);` [:arrow_up_small:](#) @@ -813,7 +818,7 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? - None ### C Prototype -`void linear_mtxf_transpose_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v);` +`void linear_mtxf_transpose_mul_vec3f(Mat4 m, VEC_OUT Vec3f dst, Vec3f v);` [:arrow_up_small:](#) @@ -1243,7 +1248,7 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? ## [cur_obj_nearest_object_with_behavior](#cur_obj_nearest_object_with_behavior) ### Lua Example -`local ObjectValue = cur_obj_nearest_object_with_behavior(behavior)` +`local objectValue = cur_obj_nearest_object_with_behavior(behavior)` ### Parameters | Field | Type | @@ -1251,7 +1256,7 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? | behavior | `Pointer` <`BehaviorScript`> | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *cur_obj_nearest_object_with_behavior(const BehaviorScript *behavior);` @@ -1283,13 +1288,13 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? ## [cur_obj_find_nearest_pole](#cur_obj_find_nearest_pole) ### Lua Example -`local ObjectValue = cur_obj_find_nearest_pole()` +`local objectValue = cur_obj_find_nearest_pole()` ### Parameters - None ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object* cur_obj_find_nearest_pole(void);` @@ -1301,19 +1306,19 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? ## [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)` +`local objectValue, dist = cur_obj_find_nearest_object_with_behavior(behavior)` ### Parameters | Field | Type | | ----- | ---- | | behavior | `Pointer` <`BehaviorScript`> | -| dist | `Pointer` <`number`> | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) +- `number` ### C Prototype -`struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, f32 *dist);` +`struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, RET f32 *dist);` [:arrow_up_small:](#) @@ -1343,13 +1348,13 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? ## [find_unimportant_object](#find_unimportant_object) ### Lua Example -`local ObjectValue = find_unimportant_object()` +`local objectValue = find_unimportant_object()` ### Parameters - None ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *find_unimportant_object(void);` @@ -1399,7 +1404,7 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? ## [find_object_with_behavior](#find_object_with_behavior) ### Lua Example -`local ObjectValue = find_object_with_behavior(behavior)` +`local objectValue = find_object_with_behavior(behavior)` ### Parameters | Field | Type | @@ -1407,7 +1412,7 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? | behavior | `Pointer` <`BehaviorScript`> | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *find_object_with_behavior(const BehaviorScript *behavior);` @@ -1419,7 +1424,7 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? ## [cur_obj_find_nearby_held_actor](#cur_obj_find_nearby_held_actor) ### Lua Example -`local ObjectValue = cur_obj_find_nearby_held_actor(behavior, maxDist)` +`local objectValue = cur_obj_find_nearby_held_actor(behavior, maxDist)` ### Parameters | Field | Type | @@ -1428,7 +1433,7 @@ Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? | maxDist | `number` | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *cur_obj_find_nearby_held_actor(const BehaviorScript *behavior, f32 maxDist);` @@ -1931,13 +1936,13 @@ Marks an object to be unloaded at the end of the frame ## [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()` +`local surfaceValue = cur_obj_update_floor_height_and_get_floor()` ### Parameters - None ### Returns -[Surface](structs.md#Surface) +- [Surface](structs.md#Surface) ### C Prototype `struct Surface *cur_obj_update_floor_height_and_get_floor(void);` @@ -1949,19 +1954,19 @@ Marks an object to be unloaded at the end of the frame ## [apply_drag_to_value](#apply_drag_to_value) ### Lua Example -`apply_drag_to_value(value, dragStrength)` +`local value = apply_drag_to_value(value, dragStrength)` ### Parameters | Field | Type | | ----- | ---- | -| value | `Pointer` <`number`> | +| value | `number` | | dragStrength | `number` | ### Returns - None ### C Prototype -`void apply_drag_to_value(f32 *value, f32 dragStrength);` +`void apply_drag_to_value(INOUT f32 *value, f32 dragStrength);` [:arrow_up_small:](#) @@ -3730,7 +3735,7 @@ Transforms the vector at `localTranslateIndex` into the object's local coordinat ## [spawn_star_with_no_lvl_exit](#spawn_star_with_no_lvl_exit) ### Lua Example -`local ObjectValue = spawn_star_with_no_lvl_exit(sp20, sp24)` +`local objectValue = spawn_star_with_no_lvl_exit(sp20, sp24)` ### Parameters | Field | Type | @@ -3739,7 +3744,7 @@ Transforms the vector at `localTranslateIndex` into the object's local coordinat | sp24 | `integer` | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *spawn_star_with_no_lvl_exit(s32 sp20, s32 sp24);` @@ -5239,7 +5244,7 @@ Retrieves the current position of Mario's cap, if it is on the ground in the cur - `integer` ### C Prototype -`s32 save_file_get_cap_pos(OUT Vec3s capPos);` +`s32 save_file_get_cap_pos(VEC_OUT Vec3s capPos);` [:arrow_up_small:](#) @@ -5494,7 +5499,7 @@ Gets the mute volume scale of `player` Gets a vanilla mario Animation with `index` ### Lua Example -`local AnimationValue = get_mario_vanilla_animation(index)` +`local animationValue = get_mario_vanilla_animation(index)` ### Parameters | Field | Type | @@ -5502,7 +5507,7 @@ Gets a vanilla mario Animation with `index` | index | `integer` | ### Returns -[Animation](structs.md#Animation) +- [Animation](structs.md#Animation) ### C Prototype `struct Animation *get_mario_vanilla_animation(u16 index);` @@ -5617,7 +5622,7 @@ Replaces the sequence corresponding to `sequenceId` with one called `m64Name`.m6 Loads an `audio` stream by `filename` (with extension) ### Lua Example -`local ModAudioValue = audio_stream_load(filename)` +`local modAudioValue = audio_stream_load(filename)` ### Parameters | Field | Type | @@ -5625,7 +5630,7 @@ Loads an `audio` stream by `filename` (with extension) | filename | `string` | ### Returns -[ModAudio](structs.md#ModAudio) +- [ModAudio](structs.md#ModAudio) ### C Prototype `struct ModAudio* audio_stream_load(const char* filename);` @@ -5947,7 +5952,7 @@ Sets the volume of an `audio` stream Loads an `audio` sample ### Lua Example -`local ModAudioValue = audio_sample_load(filename)` +`local modAudioValue = audio_sample_load(filename)` ### Parameters | Field | Type | @@ -5955,7 +5960,7 @@ Loads an `audio` sample | filename | `string` | ### Returns -[ModAudio](structs.md#ModAudio) +- [ModAudio](structs.md#ModAudio) ### C Prototype `struct ModAudio* audio_sample_load(const char* filename);` @@ -6240,13 +6245,13 @@ Sets if the romhack camera should allow D-Pad movement
-## [rom_hack_cam_set_collisions](#rom_hack_cam_set_collisions) +## [camera_romhack_set_collisions](#camera_romhack_set_collisions) ### Description Toggles collision settings for the ROM hack camera. This enables or disables specific collision behaviors in modded levels ### Lua Example -`rom_hack_cam_set_collisions(enable)` +`camera_romhack_set_collisions(enable)` ### Parameters | Field | Type | @@ -6257,7 +6262,7 @@ Toggles collision settings for the ROM hack camera. This enables or disables spe - None ### C Prototype -`void rom_hack_cam_set_collisions(u8 enable);` +`void camera_romhack_set_collisions(u8 enable);` [:arrow_up_small:](#) @@ -6451,7 +6456,7 @@ Gets the current romhack camera override status - None ### Returns -[enum RomhackCameraOverride](constants.md#enum-RomhackCameraOverride) +- [enum RomhackCameraOverride](constants.md#enum-RomhackCameraOverride) ### C Prototype `enum RomhackCameraOverride camera_get_romhack_override(void);` @@ -7172,7 +7177,7 @@ Sets if the camera should account for surfaces Finds a potential floor at the given `x`, `y`, and `z` values ### Lua Example -`local SurfaceValue = collision_find_floor(x, y, z)` +`local surfaceValue = collision_find_floor(x, y, z)` ### Parameters | Field | Type | @@ -7182,7 +7187,7 @@ Finds a potential floor at the given `x`, `y`, and `z` values | z | `number` | ### Returns -[Surface](structs.md#Surface) +- [Surface](structs.md#Surface) ### C Prototype `struct Surface* collision_find_floor(f32 x, f32 y, f32 z);` @@ -7197,7 +7202,7 @@ Finds a potential floor at the given `x`, `y`, and `z` values Finds a potential ceiling at the given `x`, `y`, and `z` values ### Lua Example -`local SurfaceValue = collision_find_ceil(x, y, z)` +`local surfaceValue = collision_find_ceil(x, y, z)` ### Parameters | Field | Type | @@ -7207,7 +7212,7 @@ Finds a potential ceiling at the given `x`, `y`, and `z` values | z | `number` | ### Returns -[Surface](structs.md#Surface) +- [Surface](structs.md#Surface) ### C Prototype `struct Surface* collision_find_ceil(f32 x, f32 y, f32 z);` @@ -7222,13 +7227,13 @@ Finds a potential ceiling at the given `x`, `y`, and `z` values Gets the generated water floor surface used when riding a shell ### Lua Example -`local SurfaceValue = get_water_surface_pseudo_floor()` +`local surfaceValue = get_water_surface_pseudo_floor()` ### Parameters - None ### Returns -[Surface](structs.md#Surface) +- [Surface](structs.md#Surface) ### C Prototype `struct Surface* get_water_surface_pseudo_floor(void);` @@ -7243,7 +7248,7 @@ Gets the generated water floor surface used when riding a shell Gets the `Collision` with `name` ### Lua Example -`local PointerValue = smlua_collision_util_get(name)` +`local pointerValue = smlua_collision_util_get(name)` ### Parameters | Field | Type | @@ -7266,13 +7271,13 @@ Gets the `Collision` with `name` Returns a temporary wall collision data pointer ### Lua Example -`local WallCollisionDataValue = collision_get_temp_wall_collision_data()` +`local wallCollisionDataValue = collision_get_temp_wall_collision_data()` ### Parameters - None ### Returns -[WallCollisionData](structs.md#WallCollisionData) +- [WallCollisionData](structs.md#WallCollisionData) ### C Prototype `struct WallCollisionData* collision_get_temp_wall_collision_data(void);` @@ -7287,7 +7292,7 @@ Returns a temporary wall collision data pointer Gets the surface corresponding to `index` from `wcd` ### Lua Example -`local SurfaceValue = get_surface_from_wcd_index(wcd, index)` +`local surfaceValue = get_surface_from_wcd_index(wcd, index)` ### Parameters | Field | Type | @@ -7296,7 +7301,7 @@ Gets the surface corresponding to `index` from `wcd` | index | `integer` | ### Returns -[Surface](structs.md#Surface) +- [Surface](structs.md#Surface) ### C Prototype `struct Surface* get_surface_from_wcd_index(struct WallCollisionData* wcd, s8 index);` @@ -7311,7 +7316,7 @@ Gets the surface corresponding to `index` from `wcd` Gets the current level terrain collision ### Lua Example -`local PointerValue = smlua_collision_util_get_current_terrain_collision()` +`local pointerValue = smlua_collision_util_get_current_terrain_collision()` ### Parameters - None @@ -7332,7 +7337,7 @@ Gets the current level terrain collision Gets the `level` terrain collision from `area` ### Lua Example -`local PointerValue = smlua_collision_util_get_level_collision(level, area)` +`local pointerValue = smlua_collision_util_get_level_collision(level, area)` ### Parameters | Field | Type | @@ -7946,7 +7951,7 @@ Gets the op of the display list command Gets the display list from a display list command if it has the op `G_DL` ### Lua Example -`local PointerValue = gfx_get_display_list(cmd)` +`local pointerValue = gfx_get_display_list(cmd)` ### Parameters | Field | Type | @@ -7969,7 +7974,7 @@ Gets the display list from a display list command if it has the op `G_DL` Gets the vertex buffer from a display list command if it has the op `G_VTX` ### Lua Example -`local PointerValue = gfx_get_vertex_buffer(cmd)` +`local pointerValue = gfx_get_vertex_buffer(cmd)` ### Parameters | Field | Type | @@ -8015,7 +8020,7 @@ Gets the number of vertices from a display list command if it has the op `G_VTX` Gets the texture from a display list command if it has an image related op ### Lua Example -`local PointerValue = gfx_get_texture(cmd)` +`local pointerValue = gfx_get_texture(cmd)` ### Parameters | Field | Type | @@ -8032,6 +8037,30 @@ Gets the texture from a display list command if it has an image related op
+## [gfx_get_from_name](#gfx_get_from_name) + +### Description +Gets a display list of the current mod from its name. Returns a pointer to the display list and its length + +### Lua Example +`local pointerValue, length = gfx_get_from_name(name)` + +### Parameters +| Field | Type | +| ----- | ---- | +| name | `string` | + +### Returns +- `Pointer` <`Gfx`> +- `integer` + +### C Prototype +`Gfx *gfx_get_from_name(const char *name, RET u32 *length);` + +[:arrow_up_small:](#) + +
+ ## [gfx_get_name](#gfx_get_name) ### Description @@ -8084,7 +8113,7 @@ Gets the max length of a display list Gets a command of a display list at position `offset` ### Lua Example -`local PointerValue = gfx_get_command(gfx, offset)` +`local pointerValue = gfx_get_command(gfx, offset)` ### Parameters | Field | Type | @@ -8108,7 +8137,7 @@ Gets a command of a display list at position `offset` Gets the next command of a given display list pointer. Intended to use in a for loop ### Lua Example -`local PointerValue = gfx_get_next_command(gfx)` +`local pointerValue = gfx_get_next_command(gfx)` ### Parameters | Field | Type | @@ -8156,7 +8185,7 @@ Copies `length` commands from display list `src` to display list `dest` Creates a new named display list of `length` commands ### Lua Example -`local PointerValue = gfx_create(name, length)` +`local pointerValue = gfx_create(name, length)` ### Parameters | Field | Type | @@ -8242,6 +8271,30 @@ Deletes all display lists created by `gfx_create`
+## [vtx_get_from_name](#vtx_get_from_name) + +### Description +Gets a vertex buffer of the current mod from its name. Returns a pointer to the vertex buffering and its vertex count + +### Lua Example +`local pointerValue, count = vtx_get_from_name(name)` + +### Parameters +| Field | Type | +| ----- | ---- | +| name | `string` | + +### Returns +- `Pointer` <`Vtx`> +- `integer` + +### C Prototype +`Vtx *vtx_get_from_name(const char *name, RET u32 *count);` + +[:arrow_up_small:](#) + +
+ ## [vtx_get_name](#vtx_get_name) ### Description @@ -8294,7 +8347,7 @@ Gets the max count of vertices of a vertex buffer Gets a vertex of a vertex buffer at position `offset` ### Lua Example -`local PointerValue = vtx_get_vertex(vtx, offset)` +`local pointerValue = vtx_get_vertex(vtx, offset)` ### Parameters | Field | Type | @@ -8318,7 +8371,7 @@ Gets a vertex of a vertex buffer at position `offset` Gets the next vertex of a given vertex pointer. Intended to use in a for loop ### Lua Example -`local PointerValue = vtx_get_next_vertex(vtx)` +`local pointerValue = vtx_get_next_vertex(vtx)` ### Parameters | Field | Type | @@ -8366,7 +8419,7 @@ Copies `count` vertices from vertex buffer `src` to vertex buffer `dest` Creates a new named vertex buffer of `count` vertices ### Lua Example -`local PointerValue = vtx_create(name, count)` +`local pointerValue = vtx_create(name, count)` ### Parameters | Field | Type | diff --git a/docs/lua/functions-7.md b/docs/lua/functions-7.md index 3a762659f..3373d70ee 100644 --- a/docs/lua/functions-7.md +++ b/docs/lua/functions-7.md @@ -40,7 +40,7 @@ Instantly changes the current area to `areaIndex` Gets information on a custom level from `levelNum` ### Lua Example -`local CustomLevelInfoValue = smlua_level_util_get_info(levelNum)` +`local customLevelInfoValue = smlua_level_util_get_info(levelNum)` ### Parameters | Field | Type | @@ -48,7 +48,7 @@ Gets information on a custom level from `levelNum` | levelNum | `integer` | ### Returns -[CustomLevelInfo](structs.md#CustomLevelInfo) +- [CustomLevelInfo](structs.md#CustomLevelInfo) ### C Prototype `struct CustomLevelInfo* smlua_level_util_get_info(s16 levelNum);` @@ -63,7 +63,7 @@ Gets information on a custom level from `levelNum` Gets information on a custom level from `shortName` ### Lua Example -`local CustomLevelInfoValue = smlua_level_util_get_info_from_short_name(shortName)` +`local customLevelInfoValue = smlua_level_util_get_info_from_short_name(shortName)` ### Parameters | Field | Type | @@ -71,7 +71,7 @@ Gets information on a custom level from `shortName` | shortName | `string` | ### Returns -[CustomLevelInfo](structs.md#CustomLevelInfo) +- [CustomLevelInfo](structs.md#CustomLevelInfo) ### C Prototype `struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(const char* shortName);` @@ -86,7 +86,7 @@ Gets information on a custom level from `shortName` Gets information on a custom level from `courseNum` ### Lua Example -`local CustomLevelInfoValue = smlua_level_util_get_info_from_course_num(courseNum)` +`local customLevelInfoValue = smlua_level_util_get_info_from_course_num(courseNum)` ### Parameters | Field | Type | @@ -94,7 +94,7 @@ Gets information on a custom level from `courseNum` | courseNum | `integer` | ### Returns -[CustomLevelInfo](structs.md#CustomLevelInfo) +- [CustomLevelInfo](structs.md#CustomLevelInfo) ### C Prototype `struct CustomLevelInfo* smlua_level_util_get_info_from_course_num(u8 courseNum);` @@ -349,7 +349,7 @@ Gets the area update counter incremented when objects are updated Returns a temporary signed 32-bit integer pointer with its value set to `initialValue` ### Lua Example -`local PointerValue = get_temp_s32_pointer(initialValue)` +`local pointerValue = get_temp_s32_pointer(initialValue)` ### Parameters | Field | Type | @@ -574,7 +574,7 @@ Gets the DJUI menu font - None ### Returns -[enum DjuiFontType](constants.md#enum-DjuiFontType) +- [enum DjuiFontType](constants.md#enum-DjuiFontType) ### C Prototype `enum DjuiFontType djui_menu_get_font(void);` @@ -589,13 +589,13 @@ Gets the DJUI menu font Gets the DJUI menu theme ### Lua Example -`local DjuiThemeValue = djui_menu_get_theme()` +`local djuiThemeValue = djui_menu_get_theme()` ### Parameters - None ### Returns -[DjuiTheme](structs.md#DjuiTheme) +- [DjuiTheme](structs.md#DjuiTheme) ### C Prototype `struct DjuiTheme* djui_menu_get_theme(void);` @@ -1410,7 +1410,32 @@ Retrieves the animated part position associated to `animPart` from the MarioStat - `boolean` ### C Prototype -`bool get_mario_anim_part_pos(struct MarioState *m, u32 animPart, OUT Vec3f pos);` +`bool get_mario_anim_part_pos(struct MarioState *m, u32 animPart, VEC_OUT Vec3f pos);` + +[:arrow_up_small:](#) + +
+ +## [get_mario_anim_part_rot](#get_mario_anim_part_rot) + +### Description +Retrieves the animated part rotation associated to `animPart` from the MarioState `m` and stores it into `rot`. Returns `true` on success or `false` on failure + +### Lua Example +`local booleanValue = get_mario_anim_part_rot(m, animPart, rot)` + +### Parameters +| Field | Type | +| ----- | ---- | +| m | [MarioState](structs.md#MarioState) | +| animPart | `integer` | +| rot | [Vec3s](structs.md#Vec3s) | + +### Returns +- `boolean` + +### C Prototype +`bool get_mario_anim_part_rot(struct MarioState *m, u32 animPart, VEC_OUT Vec3s rot);` [:arrow_up_small:](#) @@ -1649,13 +1674,13 @@ Gets the Unix Timestamp Gets the system clock's date and time ### Lua Example -`local DateTimeValue = get_date_and_time()` +`local dateTimeValue = get_date_and_time()` ### Parameters - None ### Returns -[DateTime](structs.md#DateTime) +- [DateTime](structs.md#DateTime) ### C Prototype `struct DateTime* get_date_and_time(void);` @@ -2046,13 +2071,13 @@ Checks if a file exists inside of a mod Gets the mod currently being processed ### Lua Example -`local ModValue = get_active_mod()` +`local modValue = get_active_mod()` ### Parameters - None ### Returns -[Mod](structs.md#Mod) +- [Mod](structs.md#Mod) ### C Prototype `struct Mod* get_active_mod(void);` @@ -2132,13 +2157,13 @@ Gets the name of the operating system the game is running on Gets the current GraphNodeRoot ### Lua Example -`local GraphNodeRootValue = geo_get_current_root()` +`local graphNodeRootValue = geo_get_current_root()` ### Parameters - None ### Returns -[GraphNodeRoot](structs.md#GraphNodeRoot) +- [GraphNodeRoot](structs.md#GraphNodeRoot) ### C Prototype `struct GraphNodeRoot* geo_get_current_root(void);` @@ -2153,13 +2178,13 @@ Gets the current GraphNodeRoot Gets the current GraphNodeMasterList ### Lua Example -`local GraphNodeMasterListValue = geo_get_current_master_list()` +`local graphNodeMasterListValue = geo_get_current_master_list()` ### Parameters - None ### Returns -[GraphNodeMasterList](structs.md#GraphNodeMasterList) +- [GraphNodeMasterList](structs.md#GraphNodeMasterList) ### C Prototype `struct GraphNodeMasterList* geo_get_current_master_list(void);` @@ -2174,13 +2199,13 @@ Gets the current GraphNodeMasterList Gets the current GraphNodePerspective ### Lua Example -`local GraphNodePerspectiveValue = geo_get_current_perspective()` +`local graphNodePerspectiveValue = geo_get_current_perspective()` ### Parameters - None ### Returns -[GraphNodePerspective](structs.md#GraphNodePerspective) +- [GraphNodePerspective](structs.md#GraphNodePerspective) ### C Prototype `struct GraphNodePerspective* geo_get_current_perspective(void);` @@ -2195,13 +2220,13 @@ Gets the current GraphNodePerspective Gets the current GraphNodeCamera ### Lua Example -`local GraphNodeCameraValue = geo_get_current_camera()` +`local graphNodeCameraValue = geo_get_current_camera()` ### Parameters - None ### Returns -[GraphNodeCamera](structs.md#GraphNodeCamera) +- [GraphNodeCamera](structs.md#GraphNodeCamera) ### C Prototype `struct GraphNodeCamera* geo_get_current_camera(void);` @@ -2216,13 +2241,13 @@ Gets the current GraphNodeCamera Gets the current GraphNodeHeldObject ### Lua Example -`local GraphNodeHeldObjectValue = geo_get_current_held_object()` +`local graphNodeHeldObjectValue = geo_get_current_held_object()` ### Parameters - None ### Returns -[GraphNodeHeldObject](structs.md#GraphNodeHeldObject) +- [GraphNodeHeldObject](structs.md#GraphNodeHeldObject) ### C Prototype `struct GraphNodeHeldObject* geo_get_current_held_object(void);` @@ -2297,7 +2322,7 @@ Gets the extended model ID for the `name` of a `GeoLayout` | name | `string` | ### Returns -[enum ModelExtendedId](constants.md#enum-ModelExtendedId) +- [enum ModelExtendedId](constants.md#enum-ModelExtendedId) ### C Prototype `enum ModelExtendedId smlua_model_util_get_id(const char* name);` @@ -2318,7 +2343,7 @@ Gets the extended model ID for the `name` of a `GeoLayout` 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)` +`local objectValue = spawn_sync_object(behaviorId, modelId, x, y, z, objSetupFunction)` ### Parameters | Field | Type | @@ -2331,7 +2356,7 @@ Spawns a synchronized object at `x`, `y`, and `z` as a child object of the local | objSetupFunction | `Lua Function` () | ### Returns -[Object](structs.md#Object) +- [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);` @@ -2346,7 +2371,7 @@ Spawns a synchronized object at `x`, `y`, and `z` as a child object of the local 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)` +`local objectValue = spawn_non_sync_object(behaviorId, modelId, x, y, z, objSetupFunction)` ### Parameters | Field | Type | @@ -2359,7 +2384,7 @@ Spawns a non-synchronized object at `x`, `y`, and `z` as a child object of the l | objSetupFunction | `Lua Function` () | ### Returns -[Object](structs.md#Object) +- [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);` @@ -2430,7 +2455,7 @@ Returns an object's extended model id | o | [Object](structs.md#Object) | ### Returns -[enum ModelExtendedId](constants.md#enum-ModelExtendedId) +- [enum ModelExtendedId](constants.md#enum-ModelExtendedId) ### C Prototype `enum ModelExtendedId obj_get_model_id_extended(struct Object *o);` @@ -2469,7 +2494,7 @@ Sets an object's model to `modelId` Gets a trajectory by `name` ### Lua Example -`local PointerValue = get_trajectory(name)` +`local pointerValue = get_trajectory(name)` ### Parameters | Field | Type | @@ -2492,13 +2517,13 @@ Gets a trajectory by `name` When used in a geo function, retrieve the current processed object ### Lua Example -`local ObjectValue = geo_get_current_object()` +`local objectValue = geo_get_current_object()` ### Parameters - None ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *geo_get_current_object(void);` @@ -2513,13 +2538,13 @@ When used in a geo function, retrieve the current processed object Gets the object currently being processed ### Lua Example -`local ObjectValue = get_current_object()` +`local objectValue = get_current_object()` ### Parameters - None ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *get_current_object(void);` @@ -2534,13 +2559,13 @@ Gets the object currently being processed Gets the NPC object Mario is talking to ### Lua Example -`local ObjectValue = get_dialog_object()` +`local objectValue = get_dialog_object()` ### Parameters - None ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *get_dialog_object(void);` @@ -2555,13 +2580,13 @@ Gets the NPC object Mario is talking to Gets the cutscene focus object ### Lua Example -`local ObjectValue = get_cutscene_focus()` +`local objectValue = get_cutscene_focus()` ### Parameters - None ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *get_cutscene_focus(void);` @@ -2576,13 +2601,13 @@ Gets the cutscene focus object Gets the secondary camera focus object ### Lua Example -`local ObjectValue = get_secondary_camera_focus()` +`local objectValue = get_secondary_camera_focus()` ### Parameters - None ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *get_secondary_camera_focus(void);` @@ -2643,7 +2668,7 @@ Sets the secondary camera focus object Gets the first object in an object list ### Lua Example -`local ObjectValue = obj_get_first(objList)` +`local objectValue = obj_get_first(objList)` ### Parameters | Field | Type | @@ -2651,7 +2676,7 @@ Gets the first object in an object list | objList | [enum ObjectList](constants.md#enum-ObjectList) | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *obj_get_first(enum ObjectList objList);` @@ -2666,7 +2691,7 @@ Gets the first object in an object list Gets the first object loaded with `behaviorId` ### Lua Example -`local ObjectValue = obj_get_first_with_behavior_id(behaviorId)` +`local objectValue = obj_get_first_with_behavior_id(behaviorId)` ### Parameters | Field | Type | @@ -2674,7 +2699,7 @@ Gets the first object loaded with `behaviorId` | behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId);` @@ -2689,7 +2714,7 @@ Gets the first object loaded with `behaviorId` 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)` +`local objectValue = obj_get_first_with_behavior_id_and_field_s32(behaviorId, fieldIndex, value)` ### Parameters | Field | Type | @@ -2699,7 +2724,7 @@ Gets the first object loaded with `behaviorId` and object signed 32-bit integer | value | `integer` | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value);` @@ -2714,7 +2739,7 @@ Gets the first object loaded with `behaviorId` and object signed 32-bit integer 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)` +`local objectValue = obj_get_first_with_behavior_id_and_field_f32(behaviorId, fieldIndex, value)` ### Parameters | Field | Type | @@ -2724,7 +2749,7 @@ Gets the first object loaded with `behaviorId` and object float field (look in ` | value | `number` | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *obj_get_first_with_behavior_id_and_field_f32(enum BehaviorId behaviorId, s32 fieldIndex, f32 value);` @@ -2739,7 +2764,7 @@ Gets the first object loaded with `behaviorId` and object float field (look in ` Gets the next object in an object list ### Lua Example -`local ObjectValue = obj_get_next(o)` +`local objectValue = obj_get_next(o)` ### Parameters | Field | Type | @@ -2747,7 +2772,7 @@ Gets the next object in an object list | o | [Object](structs.md#Object) | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *obj_get_next(struct Object *o);` @@ -2762,7 +2787,7 @@ Gets the next object in an object list Gets the next object loaded with the same behavior ID ### Lua Example -`local ObjectValue = obj_get_next_with_same_behavior_id(o)` +`local objectValue = obj_get_next_with_same_behavior_id(o)` ### Parameters | Field | Type | @@ -2770,7 +2795,7 @@ Gets the next object loaded with the same behavior ID | o | [Object](structs.md#Object) | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *obj_get_next_with_same_behavior_id(struct Object *o);` @@ -2785,7 +2810,7 @@ Gets the next object loaded with the same behavior ID 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)` +`local objectValue = obj_get_next_with_same_behavior_id_and_field_s32(o, fieldIndex, value)` ### Parameters | Field | Type | @@ -2795,7 +2820,7 @@ Gets the next object loaded with the same behavior ID and object signed 32-bit i | value | `integer` | ### Returns -[Object](structs.md#Object) +- [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);` @@ -2810,7 +2835,7 @@ Gets the next object loaded with the same behavior ID and object signed 32-bit i 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)` +`local objectValue = obj_get_next_with_same_behavior_id_and_field_f32(o, fieldIndex, value)` ### Parameters | Field | Type | @@ -2820,7 +2845,7 @@ Gets the next object loaded with the same behavior ID and object float field (lo | value | `number` | ### Returns -[Object](structs.md#Object) +- [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);` @@ -2835,7 +2860,7 @@ Gets the next object loaded with the same behavior ID and object float field (lo Gets the nearest object with `behaviorId` to `o` ### Lua Example -`local ObjectValue = obj_get_nearest_object_with_behavior_id(o, behaviorId)` +`local objectValue = obj_get_nearest_object_with_behavior_id(o, behaviorId)` ### Parameters | Field | Type | @@ -2844,7 +2869,7 @@ Gets the nearest object with `behaviorId` to `o` | behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *obj_get_nearest_object_with_behavior_id(struct Object *o, enum BehaviorId behaviorId);` @@ -2882,7 +2907,7 @@ Counts every object with `behaviorId` Gets the corresponding collided object to an index from `o` ### Lua Example -`local ObjectValue = obj_get_collided_object(o, index)` +`local objectValue = obj_get_collided_object(o, index)` ### Parameters | Field | Type | @@ -2891,7 +2916,7 @@ Gets the corresponding collided object to an index from `o` | index | `integer` | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object *obj_get_collided_object(struct Object *o, s16 index);` @@ -3104,7 +3129,7 @@ Sets the signed 32-bit integer value from the sub field corresponding to `fieldS 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)` +`local spawnParticlesInfoValue = obj_get_temp_spawn_particles_info(modelId)` ### Parameters | Field | Type | @@ -3112,7 +3137,7 @@ Returns a temporary particle spawn info pointer with its model loaded in from `m | modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) | ### Returns -[SpawnParticlesInfo](structs.md#SpawnParticlesInfo) +- [SpawnParticlesInfo](structs.md#SpawnParticlesInfo) ### C Prototype `struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedId modelId);` @@ -3127,7 +3152,7 @@ Returns a temporary particle spawn info pointer with its model loaded in from `m Returns a temporary water droplet params pointer with its model and behavior loaded in from `modelId` and `behaviorId` ### Lua Example -`local WaterDropletParamsValue = obj_get_temp_water_droplet_params(modelId, behaviorId)` +`local waterDropletParamsValue = obj_get_temp_water_droplet_params(modelId, behaviorId)` ### Parameters | Field | Type | @@ -3136,7 +3161,7 @@ Returns a temporary water droplet params pointer with its model and behavior loa | behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) | ### Returns -[WaterDropletParams](structs.md#WaterDropletParams) +- [WaterDropletParams](structs.md#WaterDropletParams) ### C Prototype `struct WaterDropletParams* obj_get_temp_water_droplet_params(enum ModelExtendedId modelId, enum BehaviorId behaviorId);` @@ -3151,13 +3176,13 @@ Returns a temporary water droplet params pointer with its model and behavior loa Returns a temporary object hitbox pointer ### Lua Example -`local ObjectHitboxValue = get_temp_object_hitbox()` +`local objectHitboxValue = get_temp_object_hitbox()` ### Parameters - None ### Returns -[ObjectHitbox](structs.md#ObjectHitbox) +- [ObjectHitbox](structs.md#ObjectHitbox) ### C Prototype `struct ObjectHitbox* get_temp_object_hitbox(void);` @@ -3539,7 +3564,7 @@ Resets every modified dialog back to vanilla Gets the DialogEntry struct for the given `dialogId` ### Lua Example -`local DialogEntryValue = smlua_text_utils_dialog_get(dialogId)` +`local dialogEntryValue = smlua_text_utils_dialog_get(dialogId)` ### Parameters | Field | Type | @@ -3547,7 +3572,7 @@ Gets the DialogEntry struct for the given `dialogId` | dialogId | [enum DialogId](constants.md#enum-DialogId) | ### Returns -[DialogEntry](structs.md#DialogEntry) +- [DialogEntry](structs.md#DialogEntry) ### C Prototype `struct DialogEntry* smlua_text_utils_dialog_get(enum DialogId dialogId);` @@ -4626,6 +4651,32 @@ Detects wall collisions at a given position and adjusts the position based on th
+## [find_ceil](#find_ceil) + +### Description +Finds the height of the highest ceiling above a given position (x, y, z) and return the corresponding ceil surface. If no ceiling is found, returns the default height limit of `gLevelValues.cellHeightLimit`(20000 by default) + +### Lua Example +`local numberValue, pceil = find_ceil(posX, posY, posZ)` + +### Parameters +| Field | Type | +| ----- | ---- | +| posX | `number` | +| posY | `number` | +| posZ | `number` | + +### Returns +- `number` +- [Surface](structs.md#Surface) + +### C Prototype +`f32 find_ceil(f32 posX, f32 posY, f32 posZ, RET struct Surface **pceil);` + +[:arrow_up_small:](#) + +
+ ## [find_ceil_height](#find_ceil_height) ### Description @@ -4676,6 +4727,32 @@ Finds the height of the highest floor below a given position (x, y, z). If no fl
+## [find_floor](#find_floor) + +### Description +Finds the height of the highest floor below a given position (x, y, z) and return the corresponding floor surface. If no floor is found, returns the default floor height of `gLevelValues.floorLowerLimit`(-11000 by default) + +### Lua Example +`local numberValue, pfloor = find_floor(xPos, yPos, zPos)` + +### Parameters +| Field | Type | +| ----- | ---- | +| xPos | `number` | +| yPos | `number` | +| zPos | `number` | + +### Returns +- `number` +- [Surface](structs.md#Surface) + +### C Prototype +`f32 find_floor(f32 xPos, f32 yPos, f32 zPos, RET struct Surface **pfloor);` + +[:arrow_up_small:](#) + +
+ ## [find_water_level](#find_water_level) ### Description @@ -4768,7 +4845,7 @@ Gets the closest point of the triangle to `src` and returns it in `out`. - None ### C Prototype -`void closest_point_to_triangle(struct Surface* surf, Vec3f src, OUT Vec3f out);` +`void closest_point_to_triangle(struct Surface* surf, Vec3f src, VEC_OUT Vec3f out);` [:arrow_up_small:](#) @@ -4807,13 +4884,13 @@ Loads the object's collision data into dynamic collision. You must run this ever 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()` +`local staticObjectCollisionValue = load_static_object_collision()` ### Parameters - None ### Returns -[StaticObjectCollision](structs.md#StaticObjectCollision) +- [StaticObjectCollision](structs.md#StaticObjectCollision) ### C Prototype `struct StaticObjectCollision *load_static_object_collision();` @@ -4852,7 +4929,7 @@ Toggles a collection of static object surfaces Gets a surface corresponding to `index` from the static object collision ### Lua Example -`local SurfaceValue = get_static_object_surface(col, index)` +`local surfaceValue = get_static_object_surface(col, index)` ### Parameters | Field | Type | @@ -4861,7 +4938,7 @@ Gets a surface corresponding to `index` from the static object collision | index | `integer` | ### Returns -[Surface](structs.md#Surface) +- [Surface](structs.md#Surface) ### C Prototype `struct Surface *get_static_object_surface(struct StaticObjectCollision *col, u32 index);` @@ -4876,7 +4953,7 @@ Gets a surface corresponding to `index` from the static object collision Gets a surface corresponding to `index` from the surface pool buffer ### Lua Example -`local SurfaceValue = obj_get_surface_from_index(o, index)` +`local surfaceValue = obj_get_surface_from_index(o, index)` ### Parameters | Field | Type | @@ -4885,7 +4962,7 @@ Gets a surface corresponding to `index` from the surface pool buffer | index | `integer` | ### Returns -[Surface](structs.md#Surface) +- [Surface](structs.md#Surface) ### C Prototype `struct Surface *obj_get_surface_from_index(struct Object *o, u32 index);` @@ -4929,7 +5006,7 @@ Checks if a surface has force Retrieves an object from a sync ID ### Lua Example -`local ObjectValue = sync_object_get_object(syncId)` +`local objectValue = sync_object_get_object(syncId)` ### Parameters | Field | Type | @@ -4937,7 +5014,7 @@ Retrieves an object from a sync ID | syncId | `integer` | ### Returns -[Object](structs.md#Object) +- [Object](structs.md#Object) ### C Prototype `struct Object* sync_object_get_object(u32 syncId);` diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 672af20ac..e2cff77bf 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -964,6 +964,7 @@ - [initiate_painting_warp](functions-3.md#initiate_painting_warp) - [level_trigger_warp](functions-3.md#level_trigger_warp) - [warp_special](functions-3.md#warp_special) + - [initiate_warp](functions-3.md#initiate_warp) - [lvl_set_current_level](functions-3.md#lvl_set_current_level)
@@ -1026,6 +1027,8 @@ - [mario_get_terrain_sound_addend](functions-4.md#mario_get_terrain_sound_addend) - [resolve_and_return_wall_collisions](functions-4.md#resolve_and_return_wall_collisions) - [resolve_and_return_wall_collisions_data](functions-4.md#resolve_and_return_wall_collisions_data) + - [vec3f_find_ceil](functions-4.md#vec3f_find_ceil) + - [vec3f_mario_ceil](functions-4.md#vec3f_mario_ceil) - [mario_facing_downhill](functions-4.md#mario_facing_downhill) - [mario_floor_is_slippery](functions-4.md#mario_floor_is_slippery) - [mario_floor_is_slope](functions-4.md#mario_floor_is_slope) @@ -1285,28 +1288,28 @@
- math_util_vec3i.inl - - [vec3i_zero](functions-4.md#vec3i_zero) - - [vec3i_copy](functions-4.md#vec3i_copy) - - [vec3i_set](functions-4.md#vec3i_set) - - [vec3i_add](functions-4.md#vec3i_add) - - [vec3i_sum](functions-4.md#vec3i_sum) - - [vec3i_sub](functions-4.md#vec3i_sub) - - [vec3i_dif](functions-4.md#vec3i_dif) - - [vec3i_mul](functions-4.md#vec3i_mul) - - [vec3i_mult](functions-4.md#vec3i_mult) - - [vec3i_prod](functions-4.md#vec3i_prod) - - [vec3i_div](functions-4.md#vec3i_div) - - [vec3i_length](functions-4.md#vec3i_length) - - [vec3i_normalize](functions-4.md#vec3i_normalize) - - [vec3i_set_magnitude](functions-4.md#vec3i_set_magnitude) - - [vec3i_dot](functions-4.md#vec3i_dot) - - [vec3i_cross](functions-4.md#vec3i_cross) - - [vec3i_combine](functions-4.md#vec3i_combine) - - [vec3i_dist](functions-4.md#vec3i_dist) - - [vec3i_hdist](functions-4.md#vec3i_hdist) - - [vec3i_is_zero](functions-4.md#vec3i_is_zero) - - [vec3i_to_vec3f](functions-4.md#vec3i_to_vec3f) - - [vec3i_to_vec3s](functions-4.md#vec3i_to_vec3s) + - [vec3i_zero](functions-5.md#vec3i_zero) + - [vec3i_copy](functions-5.md#vec3i_copy) + - [vec3i_set](functions-5.md#vec3i_set) + - [vec3i_add](functions-5.md#vec3i_add) + - [vec3i_sum](functions-5.md#vec3i_sum) + - [vec3i_sub](functions-5.md#vec3i_sub) + - [vec3i_dif](functions-5.md#vec3i_dif) + - [vec3i_mul](functions-5.md#vec3i_mul) + - [vec3i_mult](functions-5.md#vec3i_mult) + - [vec3i_prod](functions-5.md#vec3i_prod) + - [vec3i_div](functions-5.md#vec3i_div) + - [vec3i_length](functions-5.md#vec3i_length) + - [vec3i_normalize](functions-5.md#vec3i_normalize) + - [vec3i_set_magnitude](functions-5.md#vec3i_set_magnitude) + - [vec3i_dot](functions-5.md#vec3i_dot) + - [vec3i_cross](functions-5.md#vec3i_cross) + - [vec3i_combine](functions-5.md#vec3i_combine) + - [vec3i_dist](functions-5.md#vec3i_dist) + - [vec3i_hdist](functions-5.md#vec3i_hdist) + - [vec3i_is_zero](functions-5.md#vec3i_is_zero) + - [vec3i_to_vec3f](functions-5.md#vec3i_to_vec3f) + - [vec3i_to_vec3s](functions-5.md#vec3i_to_vec3s)
@@ -1847,7 +1850,7 @@ - [camera_romhack_allow_centering](functions-6.md#camera_romhack_allow_centering) - [camera_allow_toxic_gas_camera](functions-6.md#camera_allow_toxic_gas_camera) - [camera_romhack_allow_dpad_usage](functions-6.md#camera_romhack_allow_dpad_usage) - - [rom_hack_cam_set_collisions](functions-6.md#rom_hack_cam_set_collisions) + - [camera_romhack_set_collisions](functions-6.md#camera_romhack_set_collisions) - [camera_romhack_set_zoomed_in_dist](functions-6.md#camera_romhack_set_zoomed_in_dist) - [camera_romhack_set_zoomed_out_dist](functions-6.md#camera_romhack_set_zoomed_out_dist) - [camera_romhack_set_zoomed_in_height](functions-6.md#camera_romhack_set_zoomed_in_height) @@ -1938,6 +1941,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_from_name](functions-6.md#gfx_get_from_name) - [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) @@ -1947,6 +1951,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_from_name](functions-6.md#vtx_get_from_name) - [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) @@ -2026,6 +2031,7 @@ - [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_mario_anim_part_rot](functions-7.md#get_mario_anim_part_rot) - [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) @@ -2188,8 +2194,10 @@ - surface_collision.h - [find_wall_collisions](functions-7.md#find_wall_collisions) + - [find_ceil](functions-7.md#find_ceil) - [find_ceil_height](functions-7.md#find_ceil_height) - [find_floor_height](functions-7.md#find_floor_height) + - [find_floor](functions-7.md#find_floor) - [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) @@ -2739,7 +2747,7 @@ Derives a `MARIO_SPAWN_*` constant from `o` Finds a warp node in the current area by its ID. The warp node must exist in the list of warp nodes for the current area. Useful for locating a specific warp point in the level, such as teleportation zones or connections to other areas ### Lua Example -`local ObjectWarpNodeValue = area_get_warp_node(id)` +`local objectWarpNodeValue = area_get_warp_node(id)` ### Parameters | Field | Type | @@ -2747,7 +2755,7 @@ Finds a warp node in the current area by its ID. The warp node must exist in the | id | `integer` | ### Returns -[ObjectWarpNode](structs.md#ObjectWarpNode) +- [ObjectWarpNode](structs.md#ObjectWarpNode) ### C Prototype `struct ObjectWarpNode *area_get_warp_node(u8 id);` @@ -2762,13 +2770,13 @@ Finds a warp node in the current area by its ID. The warp node must exist in the Gets the first warp node found in the area, otherwise returns nil ### Lua Example -`local ObjectWarpNodeValue = area_get_any_warp_node()` +`local objectWarpNodeValue = area_get_any_warp_node()` ### Parameters - None ### Returns -[ObjectWarpNode](structs.md#ObjectWarpNode) +- [ObjectWarpNode](structs.md#ObjectWarpNode) ### C Prototype `struct ObjectWarpNode *area_get_any_warp_node(void);` @@ -2783,7 +2791,7 @@ Gets the first warp node found in the area, otherwise returns nil Finds a warp node in the current area using parameters from the provided object. The object's behavior parameters are used to determine the warp node ID. Useful for associating an object (like a door or warp pipe) with its corresponding warp node in the area ### Lua Example -`local ObjectWarpNodeValue = area_get_warp_node_from_params(o)` +`local objectWarpNodeValue = area_get_warp_node_from_params(o)` ### Parameters | Field | Type | @@ -2791,7 +2799,7 @@ Finds a warp node in the current area using parameters from the provided object. | o | [Object](structs.md#Object) | ### Returns -[ObjectWarpNode](structs.md#ObjectWarpNode) +- [ObjectWarpNode](structs.md#ObjectWarpNode) ### C Prototype `struct ObjectWarpNode *area_get_warp_node_from_params(struct Object *o);` diff --git a/docs/lua/guides/lighting-engine.md b/docs/lua/guides/lighting-engine.md index 1805a4201..8c5e0e69c 100644 --- a/docs/lua/guides/lighting-engine.md +++ b/docs/lua/guides/lighting-engine.md @@ -8,25 +8,29 @@ The Lighting Engine is a vertex point lighting system built directly into sm64co To use the Lighting Engine, you need to figure out how you want to approach using it given the different modes it has. There are also 2 methods to enable the lighting engine, either by setting the ambient color, or spawning a point light in. +If you want to make a vertex buffer not be affected by the lighting engine even when it's enabled, you can use `gsSPVertexNonGlobal` in the displaylist instead of `gsSPVertex`. This tells the renderer to not apply any of the effects Lua can do. + ## Section 2: Modes The lighting engine has 3 modes you can switch between using `le_set_mode(mode)`. -1. `LE_MODE_AFFECT_ALL_SHADED_AND_COLORED`: (Default) Applies lighting to every shaded and vertex colored surface minus some geometry and menus. +1. `LE_MODE_AFFECT_ALL_SHADED_AND_COLORED`: Applies lighting to every shaded and vertex colored surface minus some geometry and menus. 2. `LE_MODE_AFFECT_ALL_SHADED`: Applies lighting to every shaded surface minus some geometry and menus. -3. `LE_MODE_AFFECT_ONLY_GEOMETRY_MODE`: Only applies lighting to geometry that has the `G_LIGHTING_ENGINE_EXT` geometry mode. +3. `LE_MODE_AFFECT_ONLY_GEOMETRY_MODE`: **(Default)** Only applies lighting to geometry that has the `G_LIGHTING_ENGINE_EXT` geometry mode. `LE_MODE_AFFECT_ONLY_GEOMETRY_MODE` was the only "mode" until djoslin0 improved the lighting engine and came up with a system for affecting shaded surfaces without needing to apply the lighting engine geometry mode to every actor and level manually. +I recommend you use `LE_MODE_AFFECT_ALL_SHADED_AND_COLORED` since that generally covers everything and doesn't require any additional effort like manually adding the lighting engine flag to everything. + ## Section 3: Tonemapping The lighting engine has 4 tonemapping modes you can switch between using `le_set_tone_mapping(toneMapping)`. 1. `LE_TONE_MAPPING_TOTAL_WEIGHTED`: Weighs the combined ambient color and lights together, can look slightly dim. -2. `LE_TONE_MAPPING_WEIGHTED`: (Default) Weights the lights on top of the ambient color instead of with it, generally looks the best with good color balance. +2. `LE_TONE_MAPPING_WEIGHTED`: **(Default)** Weights the lights on top of the ambient color instead of with it, generally looks the best with good color balance. 3. `LE_TONE_MAPPING_CLAMP`: The sum of the lights and ambient color clamped between 0 and 255. Colors can look overexposed if lights are too bright. @@ -94,4 +98,4 @@ You can also make your own light behavior and call `bhv_point_light_init()` and | `le_get_light_intensity(id)` | Gets a lighting engine point light's `intensity` | | `le_set_light_intensity(id, intensity)` | Sets a lighting engine point light's `intensity` | | `le_get_light_use_surface_normals(id)` | Gets whether a lighting engine point light will use a surface's normals to determine its brightness with `useSurfaceNormals` | -| `le_set_light_use_surface_normals(id, useSurfaceNormals)` | Sets whether a lighting engine point light will use a surface's normals to determine its brightness with `useSurfaceNormals` | \ No newline at end of file +| `le_set_light_use_surface_normals(id, useSurfaceNormals)` | Sets whether a lighting engine point light will use a surface's normals to determine its brightness with `useSurfaceNormals` | diff --git a/docs/lua/structs.md b/docs/lua/structs.md index 77a0e5f89..f189b286d 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -336,6 +336,7 @@ | RespawnShellBoxes | `integer` | | | MultipleCapCollection | `integer` | | | InfiniteRenderDistance | `integer` | | +| ProcessLODs | `integer` | | | CourtyardBoosRequirement | `integer` | | | starsNeededForDialog | [StarsNeededForDialog](structs.md#StarsNeededForDialog) | read-only | | dialogs | [BehaviorDialogs](structs.md#BehaviorDialogs) | read-only | @@ -1595,6 +1596,7 @@ | torsoPos | [Vec3f](structs.md#Vec3f) | read-only | | heldObjLastPosition | [Vec3f](structs.md#Vec3f) | read-only | | animPartsPos | `Array` <`Vec3f`> | read-only | +| animPartsRot | `Array` <`Vec3s`> | read-only | | currAnimPart | `integer` | read-only | | updateTorsoTime | `integer` | read-only | | updateHeadPosTime | `integer` | read-only | diff --git a/include/gfx_symbols.h b/include/gfx_symbols.h index b1678b102..3e1492bdc 100644 --- a/include/gfx_symbols.h +++ b/include/gfx_symbols.h @@ -58,6 +58,9 @@ 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(gsDPSetColorImage, 4, false, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT); +define_gfx_symbol(gsSPNoOp, 0, false); +define_gfx_symbol(gsSPMatrix, 2, false, GFX_PARAM_TYPE_PTR, 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/seq_toad.inc b/include/seq_toad.inc index 412feb9d0..93cd3685a 100644 --- a/include/seq_toad.inc +++ b/include/seq_toad.inc @@ -293,7 +293,7 @@ chan_setlayer 0, .layer_toad_D33 chan_end .layer_toad_D33: -layer_note1 39, 0xaa, 127 +layer_note1 39, 0xaa, 100 layer_end .sound_toad_haha: diff --git a/include/sounds.h b/include/sounds.h index 1f10bafb0..69225bd73 100644 --- a/include/sounds.h +++ b/include/sounds.h @@ -263,7 +263,7 @@ #define SOUND_PEACH_MARIO2 /* 0x243FFF80 */ SOUND_ARG_LOAD(SOUND_BANK_MARIO_VOICE, 0x3F, 0xFF, SOUND_NO_PRIORITY_LOSS | SOUND_DISCRETE) /* Mario Sound Effects (Coop) */ -#define SOUND_MARIO_LETS_A_GO /* 0x7024FF80 */ SOUND_MENU_STAR_SOUND_LETS_A_GO +#define SOUND_MARIO_LETS_A_GO /* 0x7024FF80 */ SOUND_ARG_LOAD(SOUND_BANK_MENU, 0x24, 0xFF, SOUND_DISCRETE) /* General Sound Effects */ #define SOUND_GENERAL_ACTIVATE_CAP_SWITCH /* 0x30008080 */ SOUND_ARG_LOAD(SOUND_BANK_GENERAL, 0x00, 0x80, SOUND_DISCRETE) diff --git a/include/types.h b/include/types.h index e1fcc6c67..ea64ff19b 100644 --- a/include/types.h +++ b/include/types.h @@ -420,6 +420,7 @@ struct MarioBodyState Vec3f heldObjLastPosition; /// also known as HOLP Vec3f animPartsPos[MARIO_ANIM_PART_MAX]; + Vec3s animPartsRot[MARIO_ANIM_PART_MAX]; u32 currAnimPart; u32 updateTorsoTime; diff --git a/mods/character-select-coop/a-font-handler.lua b/mods/character-select-coop/a-font-handler.lua new file mode 100644 index 000000000..e5e7f2f48 --- /dev/null +++ b/mods/character-select-coop/a-font-handler.lua @@ -0,0 +1,353 @@ +--[[ + Custom Font Handler v1 - By Squishy6094 + + This file adds custom font functionality, and does not need to be edited + Ensure this file is loaded before anything else (make the file name start with a or !) + Use djui_hud_add_font() to add fonts as shown in main.lua +]] + +FONT_HANDLER_VERSION_MAJOR = 1 +FONT_HANDLER_VERSION_MINOR = 0 +FONT_HANDLER_VERSION = "v"..FONT_HANDLER_VERSION_MAJOR.."."..FONT_HANDLER_VERSION_MINOR + +local djui_classic_hud_set_font = djui_hud_set_font +local djui_classic_hud_print_text = djui_hud_print_text +local djui_classic_hud_print_text_interpolated = djui_hud_print_text_interpolated +local djui_classic_hud_measure_text = djui_hud_measure_text + +local customFont = false + +local fontTable = {} + +CUSTOM_FONT_COUNT = FONT_COUNT +local customFontType = FONT_NORMAL + +local latinChars = { + [32] = " ", [33] = "!", [34] = "\"", [35] = "#", [36] = "$", [37] = "%", [38] = "&", [39] = "'", + [40] = "(", [41] = ")", [42] = "*", [43] = "+", [44] = ",", [45] = "-", [46] = ".", [47] = "/", + [48] = "0", [49] = "1", [50] = "2", [51] = "3", [52] = "4", [53] = "5", [54] = "6", [55] = "7", + [56] = "8", [57] = "9", [58] = ":", [59] = ";", [60] = "<", [61] = "=", [62] = ">", [63] = "?", + [64] = "@", [65] = "A", [66] = "B", [67] = "C", [68] = "D", [69] = "E", [70] = "F", [71] = "G", + [72] = "H", [73] = "I", [74] = "J", [75] = "K", [76] = "L", [77] = "M", [78] = "N", [79] = "O", + [80] = "P", [81] = "Q", [82] = "R", [83] = "S", [84] = "T", [85] = "U", [86] = "V", [87] = "W", + [88] = "X", [89] = "Y", [90] = "Z", [91] = "[", [92] = "\\", [93] = "]", [94] = "^", [95] = "_", + [96] = "`", [97] = "a", [98] = "b", [99] = "c", [100] = "d", [101] = "e", [102] = "f", [103] = "g", + [104] = "h", [105] = "i", [106] = "j", [107] = "k", [108] = "l", [109] = "m", [110] = "n", [111] = "o", + [112] = "p", [113] = "q", [114] = "r", [115] = "s", [116] = "t", [117] = "u", [118] = "v", [119] = "w", + [120] = "x", [121] = "y", [122] = "z", [123] = "{", [124] = "|", [125] = "}", [126] = "~", + -- Latin-1 Supplement + [160] = " ", [161] = "¡", [162] = "¢", [163] = "£", [164] = "¤", [165] = "¥", [166] = "¦", [167] = "§", + [168] = "¨", [169] = "©", [170] = "ª", [171] = "«", [172] = "¬", [173] = "­", [174] = "®", [175] = "¯", + [176] = "°", [177] = "±", [178] = "²", [179] = "³", [180] = "´", [181] = "µ", [182] = "¶", [183] = "·", + [184] = "¸", [185] = "¹", [186] = "º", [187] = "»", [188] = "¼", [189] = "½", [190] = "¾", [191] = "¿", + [192] = "À", [193] = "Á", [194] = "Â", [195] = "Ã", [196] = "Ä", [197] = "Å", [198] = "Æ", [199] = "Ç", + [200] = "È", [201] = "É", [202] = "Ê", [203] = "Ë", [204] = "Ì", [205] = "Í", [206] = "Î", [207] = "Ï", + [208] = "Ð", [209] = "Ñ", [210] = "Ò", [211] = "Ó", [212] = "Ô", [213] = "Õ", [214] = "Ö", [215] = "×", + [216] = "Ø", [217] = "Ù", [218] = "Ú", [219] = "Û", [220] = "Ü", [221] = "Ý", [222] = "Þ", [223] = "ß", + [224] = "à", [225] = "á", [226] = "â", [227] = "ã", [228] = "ä", [229] = "å", [230] = "æ", [231] = "ç", + [232] = "è", [233] = "é", [234] = "ê", [235] = "ë", [236] = "ì", [237] = "í", [238] = "î", [239] = "ï", + [240] = "ð", [241] = "ñ", [242] = "ò", [243] = "ó", [244] = "ô", [245] = "õ", [246] = "ö", [247] = "÷", + [248] = "ø", [249] = "ù", [250] = "ú", [251] = "û", [252] = "ü", [253] = "ý", [254] = "þ", [255] = "ÿ" +} + +local HudAnimTimer = 0 + +local function convert_unicode_table_to_string_table(input) + local output = {} + for i = 1, #input do + local letter = input[i] + if letter ~= nil and latinChars[letter.id] ~= nil then + output[latinChars[letter.id]] = letter + end + end + return output +end + +local function string_to_table(str) + local charArray = {}; + local iStart = 0; + local strLen = str:len(); + local function bit(b) + return 2 ^ (b - 1); + end + local function hasbit(w, b) + return w % (b + b) >= b + end + local checkMultiByte = function(i) + if (iStart ~= 0) then + charArray[#charArray + 1] = str:sub(iStart, i - 1) + iStart = 0 + end + end + for i = 1, strLen do + local b = str:byte(i) + local multiStart = hasbit(b, bit(7)) and hasbit(b, bit(8)) + local multiTrail = not hasbit(b, bit(7)) and hasbit(b, bit(8)) + if (multiStart) then + checkMultiByte(i) + iStart = i + elseif (not multiTrail) then + checkMultiByte(i) + charArray[#charArray + 1] = str:sub(i, i) + end + end + return charArray +end + +---@param texture TextureInfo +---@param info table +---@param spacing integer +---@param offset integer +---@param backup string +---@param scale integer +---@return DjuiFontType +function djui_hud_add_font(texture, info, spacing, offset, backup, scale) + if texture == nil then return FONT_NORMAL end + if info == nil then return FONT_NORMAL end + if spacing == nil then spacing = 1 end + if offset == nil then offset = 0 end + if backup == nil then backup = "x" end + if scale == nil then scale = 1 end + if info[1] ~= nil and info[1].id ~= nil then + info = convert_unicode_table_to_string_table(info) + end + CUSTOM_FONT_COUNT = CUSTOM_FONT_COUNT + 1 + fontTable[CUSTOM_FONT_COUNT] = { + spritesheet = texture, + spacing = spacing, + offset = offset, + info = info, + backup = backup, + scale = scale, + } + return CUSTOM_FONT_COUNT +end + +---@param fontType DjuiFontType +---@return nil +function djui_hud_set_font(fontType) + if fontType > FONT_COUNT then + customFont = true + customFontType = fontType + else + customFont = false + djui_classic_hud_set_font(fontType) + end +end + +local textShake = 0 +function djui_hud_effect_shake(intensity) + textShake = math.ceil(intensity*100)*0.01 +end + +local textWaveX = 0 +local textWaveY = 0 +local textWaveSpeed = 0 +function djui_hud_effect_wave(x, y, speed) + textWaveX = x + textWaveY = y + textWaveSpeed = speed +end + +---@param message string +---@param x number +---@param y number +---@param scale number +---@return nil +function djui_hud_print_text(message, x, y, scale) + if customFont then + if message == nil or message == "" then return end + local message = string_to_table(message) + local currFont = fontTable[customFontType] + y = y + currFont.offset + scale = scale*currFont.scale + for i = 1, #message do + local letter = message[i] + if letter and letter ~= " " then + if currFont.info[letter] == nil then + letter = currFont.backup + end + local scaleWidth = scale*(currFont.info[letter].height/currFont.info[letter].width) + djui_hud_render_texture_tile(currFont.spritesheet, + x + ((currFont.info[letter].xoffset or 0)*scale) + math.random(-textShake*100, textShake*100)*0.01 + math.sin((HudAnimTimer+i*2)*textWaveSpeed*0.1)*textWaveX, + y + ((currFont.info[letter].yoffset or 0)*scale) + math.random(-textShake*100, textShake*100)*0.01 + math.cos((HudAnimTimer+i*2)*textWaveSpeed*0.1)*textWaveY, + scaleWidth, scale, + currFont.info[letter].x, + currFont.info[letter].y, + currFont.info[letter].width, + currFont.info[letter].height) + else + letter = currFont.backup + end + x = x + (currFont.info[letter].width + currFont.spacing)*scale + end + else + djui_classic_hud_print_text(message, x, y, scale) + end +end + +---@param message string +---@param prevX number +---@param prevY number +---@param prevScale number +---@param x number +---@param y number +---@param scale number +---@return nil +-- Custom Fonts do not currently support Interpolation due to lack of RESOLUTION_N64 support +function djui_hud_print_text_interpolated(message, prevX, prevY, prevScale, x, y, scale) + if customFont then + if message == nil or message == "" then return end + local message = string_to_table(message) + local currFont = fontTable[customFontType] + prevY = prevY + currFont.offset + y = y + currFont.offset + scale = scale*currFont.scale + for i = 1, #message do + local letter = message[i] + if letter and letter ~= " " then + if currFont.info[letter] == nil then + letter = currFont.backup + end + local prevScaleWidth = prevScale*(currFont.info[letter].height/currFont.info[letter].width) + local scaleWidth = scale*(currFont.info[letter].height/currFont.info[letter].width) + local xOffset = ((currFont.info[letter].xoffset or 0)*scale) + math.random(-textShake*100, textShake*100)*0.01 + math.sin((HudAnimTimer+i*2)*textWaveSpeed*0.1)*textWaveX + local yOffset = ((currFont.info[letter].yoffset or 0)*scale) + math.random(-textShake*100, textShake*100)*0.01 + math.cos((HudAnimTimer+i*2)*textWaveSpeed*0.1)*textWaveY + djui_hud_render_texture_tile_interpolated(currFont.spritesheet, + prevX + xOffset, + prevY + yOffset, + prevScaleWidth, prevScale, + x + xOffset, + y + yOffset, + scaleWidth, scale, + currFont.info[letter].x, + currFont.info[letter].y, + currFont.info[letter].width, + currFont.info[letter].height) + else + letter = currFont.backup + end + x = x + (currFont.info[letter].width + currFont.spacing)*scale + prevX = prevX + (currFont.info[letter].width + currFont.spacing)*prevScale + end + else + djui_classic_hud_print_text_interpolated(message, prevX, prevY, prevScale, x, y, scale) + end +end + +---@param message string +---@return number +function djui_hud_measure_text(message) + if customFont then + if message == nil or message == "" then return end + local message = string_to_table(message) + local currFont = fontTable[customFontType] + local scale = 1 + local x = 0 + for i = 1, #message do + local letter = message[i] + if letter and letter ~= " " then + if currFont.info[letter] == nil then + letter = currFont.backup + end + else + letter = currFont.backup + end + x = x + (currFont.info[letter].width + currFont.spacing)*scale + end + return x + else + return djui_classic_hud_measure_text(message) + end +end + +local function hud_update() + -- Reset Values Every Frame + textShake = 0 + textWaveX = 0 + textWaveY = 0 + textWaveSpeed = 0 + + -- Update Basic Anim Timer + HudAnimTimer = HudAnimTimer + 1 +end + +hook_event(HOOK_ON_HUD_RENDER_BEHIND, hud_update) + +-- Adding custom fonts here to prevent main clutter +fontdataCharacteristic = { + ["A"] = {x = 0, y = 0, width = 26, height = 32}, + ["B"] = {x = 32, y = 0, width = 25, height = 32}, + ["C"] = {x = 32*2, y = 0, width = 25, height = 32}, + ["D"] = {x = 32*3, y = 0, width = 23, height = 32}, + ["E"] = {x = 32*4, y = 0, width = 24, height = 32}, + ["F"] = {x = 32*5, y = 0, width = 24, height = 32}, + ["G"] = {x = 32*6, y = 0, width = 26, height = 32}, + ["H"] = {x = 32*7, y = 0, width = 25, height = 32}, + + ["I"] = {x = 0, y = 32, width = 15, height = 32}, + ["J"] = {x = 32, y = 32, width = 21, height = 32}, + ["K"] = {x = 32*2, y = 32, width = 25, height = 32}, + ["L"] = {x = 32*3, y = 32, width = 22, height = 32}, + ["M"] = {x = 32*4, y = 32, width = 29, height = 32}, + ["N"] = {x = 32*5, y = 32, width = 27, height = 32}, + ["Ñ"] = {x = 32*6, y = 32, width = 27, height = 32}, + ["O"] = {x = 32*7, y = 32, width = 26, height = 32}, + + ["P"] = {x = 0, y = 32*2, width = 25, height = 32}, + ["Q"] = {x = 32, y = 32*2, width = 27, height = 32}, + ["R"] = {x = 32*2, y = 32*2, width = 25, height = 32}, + ["S"] = {x = 32*3, y = 32*2, width = 24, height = 32}, + ["T"] = {x = 32*4, y = 32*2, width = 28, height = 32}, + ["U"] = {x = 32*5, y = 32*2, width = 26, height = 32}, + ["V"] = {x = 32*6, y = 32*2, width = 27, height = 32}, + ["W"] = {x = 32*7, y = 32*2, width = 30, height = 32}, + + ["X"] = {x = 0, y = 32*3, width = 28, height = 32}, + ["Y"] = {x = 32, y = 32*3, width = 27, height = 32}, + ["Z"] = {x = 32*2, y = 32*3, width = 27, height = 32}, + ["!"] = {x = 32*3, y = 32*3, width = 30, height = 32}, + ["?"] = {x = 32*4, y = 32*3, width = 27, height = 32}, + ["@"] = {x = 32*5, y = 32*3, width = 29, height = 32}, + ["#"] = {x = 32*6, y = 32*3, width = 29, height = 32}, + ["$"] = {x = 32*7, y = 32*3, width = 23, height = 32}, + + ["%"] = {x = 0, y = 32*4, width = 27, height = 32}, + ["^"] = {x = 32, y = 32*4, width = 24, height = 32}, + ["&"] = {x = 32*2, y = 32*4, width = 29, height = 32}, + ["*"] = {x = 32*3, y = 32*4, width = 18, height = 32}, + ["("] = {x = 32*4, y = 32*4, width = 17, height = 32}, + [")"] = {x = 32*5, y = 32*4, width = 17, height = 32}, + ["_"] = {x = 32*6, y = 32*4, width = 31, height = 32}, + ["-"] = {x = 32*7, y = 32*4, width = 23, height = 32}, + + ["+"] = {x = 0, y = 32*5, width = 24, height = 32}, + ["="] = {x = 32, y = 32*5, width = 27, height = 32}, + ["<"] = {x = 32*2, y = 32*5, width = 23, height = 32}, + [">"] = {x = 32*3, y = 32*5, width = 23, height = 32}, + ["."] = {x = 32*4, y = 32*5, width = 11, height = 32}, + [","] = {x = 32*5, y = 32*5, width = 11, height = 32}, + [":"] = {x = 32*6, y = 32*5, width = 11, height = 32}, + [";"] = {x = 32*7, y = 32*5, width = 11, height = 32}, + + ["/"] = {x = 0, y = 32*6, width = 28, height = 32}, + ["\\"] = {x = 32, y = 32*6, width = 28, height = 32}, + ['"'] = {x = 32*2, y = 32*6, width = 14, height = 32}, + ["'"] = {x = 32*3, y = 32*6, width = 9, height = 32}, + ["|"] = {x = 32*4, y = 32*6, width = 10, height = 32}, + ["~"] = {x = 32*5, y = 32*6, width = 23, height = 32}, + ["1"] = {x = 32*6, y = 32*6, width = 23, height = 32}, + ["2"] = {x = 32*7, y = 32*6, width = 26, height = 32}, + + ["3"] = {x = 0, y = 32*7, width = 24, height = 32}, + ["4"] = {x = 32, y = 32*7, width = 24, height = 32}, + ["5"] = {x = 32*2, y = 32*7, width = 26, height = 32}, + ["6"] = {x = 32*3, y = 32*7, width = 26, height = 32}, + ["7"] = {x = 32*4, y = 32*7, width = 30, height = 32}, + ["8"] = {x = 32*5, y = 32*7, width = 22, height = 32}, + ["9"] = {x = 32*6, y = 32*7, width = 24, height = 32}, + ["0"] = {x = 32*7, y = 32*7, width = 24, height = 32}, + +} + +FONT_CHARACTERISTIC = djui_hud_add_font(get_texture_info("char_select_font_characteristic"), fontdataCharacteristic, -5, 0, "X", 1) \ No newline at end of file diff --git a/mods/character-select-coop/a-github.lua b/mods/character-select-coop/a-github.lua deleted file mode 100644 index 86039f611..000000000 --- a/mods/character-select-coop/a-github.lua +++ /dev/null @@ -1,3 +0,0 @@ -GITHUB_COMMIT_TIME = '05/16/2025 07:27:43 PM PST' -GITHUB_COMMIT_ID = '115b65e' -GITHUB_REPO = 'Squishy6094/character-select-coop' diff --git a/mods/character-select-coop/a-supporters.lua b/mods/character-select-coop/a-supporters.lua new file mode 100644 index 000000000..f3547551b --- /dev/null +++ b/mods/character-select-coop/a-supporters.lua @@ -0,0 +1,15 @@ +CREDIT_SUPPORTERS = { + "Saul", + "Ellie", + "Lyrae", + "Sophia", + "maemae", + "charity", + "FunkyLion", + "VioletArts", + "Nope208", + "Jack Black", + "GRAND DAD", + "Key's Artworks", + "Kale!", +} \ No newline at end of file diff --git a/mods/character-select-coop/a-utils.lua b/mods/character-select-coop/a-utils.lua index a2743c1f7..ef06fd13c 100644 --- a/mods/character-select-coop/a-utils.lua +++ b/mods/character-select-coop/a-utils.lua @@ -1,68 +1,22 @@ --- localize functions to improve performance - a-utils.lua -local string_lower,string_format,table_insert,get_date_and_time = string.lower,string.format,table.insert,get_date_and_time - -- Version Data -- MOD_VERSION_API = 1 -MOD_VERSION_MAJOR = 14 -MOD_VERSION_MINOR = 1 +MOD_VERSION_MAJOR = 16 +MOD_VERSION_MINOR = 0 MOD_VERSION_INDEV = false MOD_VERSION_STRING = tostring(MOD_VERSION_API) .. "." .. tostring(MOD_VERSION_MAJOR) .. (MOD_VERSION_MINOR > 0 and ("." .. tostring(MOD_VERSION_MINOR)) or "") .. (MOD_VERSION_INDEV and " (In-Dev)" or "") -MOD_VERSION_DEBUG = tostring(GITHUB_REPO) .. " | " .. tostring(GITHUB_COMMIT_ID) .. " | " .. tostring(GITHUB_COMMIT_TIME) -if VERSION_NUMBER < 38 then - djui_popup_create("\n\\#FFAAAA\\Character Select requires\n the latest version of CoopDX to use!\n\nYou can find CoopDX here:\n\\#6666FF\\https://sm64coopdx.com", 5) - incompatibleClient = true - return 0 -end - -local dependacyFiles = { - -- Required Lua File - --"a-github.lua", - "dialog.lua", - "main.lua", - "n-hud.lua", - "o-api.lua", - "z-moveset.lua", - "z-palettes.lua", - "z-voice.lua", - -- Required Actors - "actors/armature_geo.bin", -} -local legacyFiles = { - "voice.lua", - "palettes.lua", - "z-anims.lua", -} - -local fileErrorList = {} - --- Check for Missing Files -for i = 1, #dependacyFiles do - if not mod_file_exists(dependacyFiles[i]) then - log_to_console("Character Select file missing: '" .. dependacyFiles[i] .. "'", CONSOLE_MESSAGE_WARNING) - table_insert(fileErrorList, "Missing File '" .. dependacyFiles[i] .. "'") - end -end --- Check for Legacy Files -for i = 1, #legacyFiles do - if mod_file_exists(legacyFiles[i]) then - log_to_console("Character Select legacy file found: '" .. legacyFiles[i] .. "'", CONSOLE_MESSAGE_WARNING) - table_insert(fileErrorList, "Legacy File '" .. legacyFiles[i] .. "'") - end -end -if #fileErrorList > 0 then +-- Check CoopDX Version +VERSION_REQUIRED = 41 +if VERSION_NUMBER < VERSION_REQUIRED then incompatibleClient = true local frameCount = 0 hook_event(HOOK_UPDATE, function () frameCount = frameCount + 1 if frameCount == 5 then - local errorString = "\\#FFAAAA\\Character Select File Issues:" - djui_popup_create("\\#FFAAAA\\Character Select is having\nfile issues and cannot load!\n\nErrors have been logged in chat!", 4) - for i = 1, #fileErrorList do - errorString = errorString .. "\n" .. fileErrorList[i] - end - errorString = errorString .. "\n\nThe best way to resolve these issues is to delete your current version of Character Select and then install the latest version!" + djui_popup_create("\n\\#FFAAAA\\Character Select requires\n the latest version of CoopDX to use!\n\nYou can find CoopDX here:\n\\#AAAAFF\\https://sm64coopdx.com", 5) + djui_chat_message_create("\\#FFAAAA\\Character Select Version Issue:\nVersion " .. tostring(VERSION_NUMBER) .. " < " .. tostring(VERSION_REQUIRED)) + local errorString = "\\#FFAAAA\\The best way to resolve this issue is to reinstall SM64CoopDX from the Offical Site or Github Repo!\n\\#AAAAFF\\https://sm64coopdx.com/\nhttps://github.com/coop-deluxe/sm64coopdx/" log_to_console(errorString) djui_chat_message_create(errorString) end @@ -70,6 +24,132 @@ if #fileErrorList > 0 then return 0 end +log_to_console("Character Select "..MOD_VERSION_STRING) + +local dependacyFiles = { + --- Required Lua Files + "a-font-handler.lua", + "anims.lua", + "dialog.lua", + "hud.lua", + "main.lua", + "moveset.lua", + "palettes.lua", + "voice.lua", + "z-api.lua", + + -- Required Texture Files + "textures/char_select_album_back.tex", + "textures/char_select_album_front.tex", + "textures/char_select_album_overlay.tex", + "textures/char_select_category.tex", + "textures/char_select_caution_tape.tex", + "textures/char_select_cd_layer1.tex", + "textures/char_select_cd_layer2.tex", + "textures/char_select_cd_layer3.tex", + "textures/char_select_cd_layer4.tex", + "textures/char_select_custom_course_bottom.tex", + "textures/char_select_custom_course_top.tex", + "textures/char_select_custom_meter_left.tex", + "textures/char_select_custom_meter_pie1.tex", + "textures/char_select_custom_meter_pie2.tex", + "textures/char_select_custom_meter_pie3.tex", + "textures/char_select_custom_meter_pie4.tex", + "textures/char_select_custom_meter_pie5.tex", + "textures/char_select_custom_meter_pie6.tex", + "textures/char_select_custom_meter_pie7.tex", + "textures/char_select_custom_meter_pie8.tex", + "textures/char_select_custom_meter_right.tex", + "textures/char_select_font_brick.tex", + "textures/char_select_font_characteristic.tex", + "textures/char_select_gear.tex", + "textures/char_select_graffiti_default.tex", + "textures/char_select_graffiti_luigi.tex", + "textures/char_select_graffiti_mario.tex", + "textures/char_select_graffiti_toad.tex", + "textures/char_select_graffiti_waluigi.tex", + "textures/char_select_graffiti_wario.tex", + "textures/char_select_icon_signs.tex", + "textures/char_select_list_button.tex", + "textures/char_select_logo.tex", + "textures/char_select_luigi_meter_left.tex", + "textures/char_select_luigi_meter_right.tex", + "textures/char_select_nameplate.tex", + "textures/char_select_options_tv.tex", + "textures/char_select_palette_bucket.tex", + "textures/char_select_record.tex", + "textures/char_select_toad_meter_left.tex", + "textures/char_select_toad_meter_right.tex", + "textures/char_select_wall_left.tex", + "textures/char_select_wall_right.tex", + "textures/char_select_waluigi_meter_left.tex", + "textures/char_select_waluigi_meter_right.tex", + "textures/char_select_wario_meter_left.tex", + "textures/char_select_wario_meter_right.tex", +} +local legacyFiles = { + "z-anims.lua", + "n-hud.lua", + "o-api.lua", + "z-moveset.lua", + "z-palettes.lua", + "z-voice.lua", +} + +local fileErrorList = {} + +if network_is_server() then + -- Check for Missing Files + for i = 1, #dependacyFiles do + if not mod_file_exists(dependacyFiles[i]) then + log_to_console("Character Select file missing: '" .. dependacyFiles[i] .. "'", CONSOLE_MESSAGE_WARNING) + table.insert(fileErrorList, "Missing File '" .. dependacyFiles[i] .. "'") + end + end + -- Check for Legacy Files + for i = 1, #legacyFiles do + if mod_file_exists(legacyFiles[i]) then + log_to_console("Character Select legacy file found: '" .. legacyFiles[i] .. "'", CONSOLE_MESSAGE_WARNING) + table.insert(fileErrorList, "Legacy File '" .. legacyFiles[i] .. "'") + end + end + if #fileErrorList > 0 then + incompatibleClient = true + local frameCount = 0 + hook_event(HOOK_UPDATE, function () + frameCount = frameCount + 1 + if frameCount == 5 then + local errorString = "\\#FFAAAA\\Character Select File Issues:" + djui_popup_create("\\#FFAAAA\\Character Select is having\nfile issues and cannot load!\n\nErrors have been logged in chat!", 4) + for i = 1, #fileErrorList do + errorString = errorString .. "\n" .. fileErrorList[i] + end + log_to_console(errorString) + djui_chat_message_create(errorString) + + errorString = "\\#FFAAAA\\The best way to resolve these issues is to delete your current version of Character Select and then install the latest version from the Github Repo!\n\\#AAAAFF\\https://github.com/Squishy6094/character-select-coop/\\#FFAAAA\\" + log_to_console(errorString) + djui_chat_message_create(errorString) + end + end) + return 0 + end +end + +-- Failsafe printing nil text +local djui_hud_print_text_original = djui_hud_print_text +function djui_hud_print_text(string, x, y, scale) + djui_hud_print_text_original(tostring(string), x, y, scale) +end + +local string_sub = string.sub +function djui_hud_print_monospace_text(string, x, y, scale, space) + space = space or 16 + for i = 1, #string do + djui_hud_print_text(string_sub(string, i, i), x + space*(i - 1)*scale, y, scale) + end +end + ommActive = false for i in pairs(gActiveMods) do if gActiveMods[i].relativePath == "omm-coop" then @@ -78,8 +158,6 @@ for i in pairs(gActiveMods) do end end -E_MODEL_ARMATURE = smlua_model_util_get_id("armature_geo") - local saveableCharacters = { ["1"] = 1, ["2"] = 1, @@ -125,44 +203,44 @@ local saveableCharacters = { [" "] = 0, } ---- @param string string +---@param string string --- Replaces underscores in the string with spaces function string_underscore_to_space(string) if string == nil then return "" end return string:gsub("_", " ") end ---- @param string string +---@param string string --- Constructs a new string but only with characters from `saveableCharacters` --- * Spaces are the notable character that gets turned into an underscore function string_space_to_underscore(string) local s = '' for i = 1, #string do local c = string:sub(i,i) - if saveableCharacters[string_lower(c)] == 1 then + if saveableCharacters[string.lower(c)] == 1 then s = s .. c - elseif saveableCharacters[string_lower(c)] == 0 then + elseif saveableCharacters[string.lower(c)] == 0 then s = s .. "_" end end return s end ---- @param string string +---@param string string --- Splits a string into a table by spaces function string_split(string, splitAt) if splitAt == nil then splitAt = " " end local result = {} - for match in string:gmatch(string_format("[^%s]+", splitAt)) do - table_insert(result, match) + for match in string:gmatch(string.format("[^%s]+", splitAt)) do + table.insert(result, match) end return result end ---- @param param number ---- @param caseTable table +---@param param number +---@param caseTable table --- Switch statement function function switch(param, caseTable) local case = caseTable[param] @@ -171,17 +249,52 @@ function switch(param, caseTable) return def and def() or nil end -function clamp(num, min, max) - return math.max(math.min(num, max), min) +---@param s string +---@param v any +--- Defines a global variable by name `s` with the value `v` and indexes it if it already exists +function define_valid_global(s, v) + local name = s + local index = 1 + + while _G[name] ~= nil do + name = s .. "_" .. index + index = index + 1 + end + + _G[name] = v +end + +---@param n integer +---@return boolean +function num_power_of_two(n) + return n ~= 0 and (n & (n - 1)) == 0 +end + +function angle_from_2d_points(x1, y1, x2, y2) + return atan2s(y2 - y1, x2 - x1) - 0x4000 +end + +function hash(word) + local result = 5381 + for i = 1, #word do + result = (result << 5) + result + word:byte(i) + end + return result end function lerp(a, b, t) return a * (1 - t) + b * t end +function num_wrap(num, min, max) + if num > max then num = min end + if num < min then num = max end + return num +end + allowMenu = {} -renderInMenuTable = { +hookTableRenderInMenu = { front = {}, back = {}, } @@ -190,18 +303,13 @@ queueStorageFailsafe = false charBeingSet = false -stopPalettes = false -for i in pairs(gActiveMods) do - if (gActiveMods[i].incompatible ~= nil and gActiveMods[i].incompatible:find("gamemode")) and not (gActiveMods[i].name:find("Personal Star Counter")) then - stopPalettes = true - end -end - -stopMovesets = false +gGlobalSyncTable.charSelectRestrictPalettes = 0 +gGlobalSyncTable.charSelectRestrictMovesets = 0 seasonalEvent = 0 SEASON_EVENT_BIRTHDAY = 1 SEASON_EVENT_CHRISTMAS = 2 +SEASON_EVENT_FOOLS = 2 -- December if get_date_and_time().month == 11 then if get_date_and_time().day == 3 then @@ -211,6 +319,8 @@ if get_date_and_time().month == 11 then -- Christmas seasonalEvent = SEASON_EVENT_CHRISTMAS end +elseif get_date_and_time().month == 4 and get_date_and_time().month == 1 then + seasonalEvent = SEASON_EVENT_FOOLS end -- Dedicated Networking Table for Character Select @@ -222,8 +332,9 @@ for i = 0, MAX_PLAYERS - 1 do currAlt = 1, presetPalette = 0, offset = 0, - forceChar = 0, + baseChar = 0, modelId = E_MODEL_MARIO, + prevModelId = E_MODEL_MARIO, isUpdating = false, movesetToggle = true, modelEditOffset = 0, @@ -231,9 +342,24 @@ for i = 0, MAX_PLAYERS - 1 do } end +local stallFrame = 0 +local stallComplete = 3 +function startup_init_stall(framesBefore) + framesBefore = framesBefore or 0 + return stallFrame == (stallComplete - framesBefore) +end + local stallPacket = 0 -local function update() - stallPacket = (stallPacket+1)%3 -- refresh rate (to reduce stress) +local function network_update(m) + if m.playerIndex ~= 0 then return end + + -- Initialization Update + if stallFrame < stallComplete then + stallFrame = stallFrame + 1 + end + + -- Packet Refresh Rate + stallPacket = (stallPacket+1)%3 if stallPacket == 0 then network_send(false, gCSPlayers[0]) end @@ -245,4 +371,353 @@ local function on_packet_recieve(data) end hook_event(HOOK_ON_PACKET_RECEIVE, on_packet_recieve) -hook_event(HOOK_UPDATE, update) \ No newline at end of file +hook_event(HOOK_MARIO_UPDATE, network_update) + +-- Default Actions Check +local defaultActions = { + [ACT_UNINITIALIZED] = ACT_UNINITIALIZED, + [ACT_IDLE] = ACT_IDLE, + [ACT_START_SLEEPING] = ACT_START_SLEEPING, + [ACT_SLEEPING] = ACT_SLEEPING, + [ACT_WAKING_UP] = ACT_WAKING_UP, + [ACT_PANTING] = ACT_PANTING, + [ACT_HOLD_PANTING_UNUSED] = ACT_HOLD_PANTING_UNUSED, + [ACT_HOLD_IDLE] = ACT_HOLD_IDLE, + [ACT_HOLD_HEAVY_IDLE] = ACT_HOLD_HEAVY_IDLE, + [ACT_STANDING_AGAINST_WALL] = ACT_STANDING_AGAINST_WALL, + [ACT_COUGHING] = ACT_COUGHING, + [ACT_SHIVERING] = ACT_SHIVERING, + [ACT_IN_QUICKSAND] = ACT_IN_QUICKSAND, + [ACT_UNKNOWN_0002020E] = ACT_UNKNOWN_0002020E, + [ACT_CROUCHING] = ACT_CROUCHING, + [ACT_START_CROUCHING] = ACT_START_CROUCHING, + [ACT_STOP_CROUCHING] = ACT_STOP_CROUCHING, + [ACT_START_CRAWLING] = ACT_START_CRAWLING, + [ACT_STOP_CRAWLING] = ACT_STOP_CRAWLING, + [ACT_SLIDE_KICK_SLIDE_STOP] = ACT_SLIDE_KICK_SLIDE_STOP, + [ACT_SHOCKWAVE_BOUNCE] = ACT_SHOCKWAVE_BOUNCE, + [ACT_FIRST_PERSON] = ACT_FIRST_PERSON, + [ACT_BACKFLIP_LAND_STOP] = ACT_BACKFLIP_LAND_STOP, + [ACT_JUMP_LAND_STOP] = ACT_JUMP_LAND_STOP, + [ACT_DOUBLE_JUMP_LAND_STOP] = ACT_DOUBLE_JUMP_LAND_STOP, + [ACT_FREEFALL_LAND_STOP] = ACT_FREEFALL_LAND_STOP, + [ACT_SIDE_FLIP_LAND_STOP] = ACT_SIDE_FLIP_LAND_STOP, + [ACT_HOLD_JUMP_LAND_STOP] = ACT_HOLD_JUMP_LAND_STOP, + [ACT_HOLD_FREEFALL_LAND_STOP] = ACT_HOLD_FREEFALL_LAND_STOP, + [ACT_AIR_THROW_LAND] = ACT_AIR_THROW_LAND, + [ACT_TWIRL_LAND] = ACT_TWIRL_LAND, + [ACT_LAVA_BOOST_LAND] = ACT_LAVA_BOOST_LAND, + [ACT_TRIPLE_JUMP_LAND_STOP] = ACT_TRIPLE_JUMP_LAND_STOP, + [ACT_LONG_JUMP_LAND_STOP] = ACT_LONG_JUMP_LAND_STOP, + [ACT_GROUND_POUND_LAND] = ACT_GROUND_POUND_LAND, + [ACT_BRAKING_STOP] = ACT_BRAKING_STOP, + [ACT_BUTT_SLIDE_STOP] = ACT_BUTT_SLIDE_STOP, + [ACT_HOLD_BUTT_SLIDE_STOP] = ACT_HOLD_BUTT_SLIDE_STOP, + [ACT_WALKING] = ACT_WALKING, + [ACT_HOLD_WALKING] = ACT_HOLD_WALKING, + [ACT_TURNING_AROUND] = ACT_TURNING_AROUND, + [ACT_FINISH_TURNING_AROUND] = ACT_FINISH_TURNING_AROUND, + [ACT_BRAKING] = ACT_BRAKING, + [ACT_RIDING_SHELL_GROUND] = ACT_RIDING_SHELL_GROUND, + [ACT_HOLD_HEAVY_WALKING] = ACT_HOLD_HEAVY_WALKING, + [ACT_CRAWLING] = ACT_CRAWLING, + [ACT_BURNING_GROUND] = ACT_BURNING_GROUND, + [ACT_DECELERATING] = ACT_DECELERATING, + [ACT_HOLD_DECELERATING] = ACT_HOLD_DECELERATING, + [ACT_BEGIN_SLIDING] = ACT_BEGIN_SLIDING, + [ACT_HOLD_BEGIN_SLIDING] = ACT_HOLD_BEGIN_SLIDING, + [ACT_BUTT_SLIDE] = ACT_BUTT_SLIDE, + [ACT_STOMACH_SLIDE] = ACT_STOMACH_SLIDE, + [ACT_HOLD_BUTT_SLIDE] = ACT_HOLD_BUTT_SLIDE, + [ACT_HOLD_STOMACH_SLIDE] = ACT_HOLD_STOMACH_SLIDE, + [ACT_DIVE_SLIDE] = ACT_DIVE_SLIDE, + [ACT_MOVE_PUNCHING] = ACT_MOVE_PUNCHING, + [ACT_CROUCH_SLIDE] = ACT_CROUCH_SLIDE, + [ACT_SLIDE_KICK_SLIDE] = ACT_SLIDE_KICK_SLIDE, + [ACT_HARD_BACKWARD_GROUND_KB] = ACT_HARD_BACKWARD_GROUND_KB, + [ACT_HARD_FORWARD_GROUND_KB] = ACT_HARD_FORWARD_GROUND_KB, + [ACT_BACKWARD_GROUND_KB] = ACT_BACKWARD_GROUND_KB, + [ACT_FORWARD_GROUND_KB] = ACT_FORWARD_GROUND_KB, + [ACT_SOFT_BACKWARD_GROUND_KB] = ACT_SOFT_BACKWARD_GROUND_KB, + [ACT_SOFT_FORWARD_GROUND_KB] = ACT_SOFT_FORWARD_GROUND_KB, + [ACT_GROUND_BONK] = ACT_GROUND_BONK, + [ACT_DEATH_EXIT_LAND] = ACT_DEATH_EXIT_LAND, + [ACT_JUMP_LAND] = ACT_JUMP_LAND, + [ACT_FREEFALL_LAND] = ACT_FREEFALL_LAND, + [ACT_DOUBLE_JUMP_LAND] = ACT_DOUBLE_JUMP_LAND, + [ACT_SIDE_FLIP_LAND] = ACT_SIDE_FLIP_LAND, + [ACT_HOLD_JUMP_LAND] = ACT_HOLD_JUMP_LAND, + [ACT_HOLD_FREEFALL_LAND] = ACT_HOLD_FREEFALL_LAND, + [ACT_QUICKSAND_JUMP_LAND] = ACT_QUICKSAND_JUMP_LAND, + [ACT_HOLD_QUICKSAND_JUMP_LAND] = ACT_HOLD_QUICKSAND_JUMP_LAND, + [ACT_TRIPLE_JUMP_LAND] = ACT_TRIPLE_JUMP_LAND, + [ACT_LONG_JUMP_LAND] = ACT_LONG_JUMP_LAND, + [ACT_BACKFLIP_LAND] = ACT_BACKFLIP_LAND, + [ACT_JUMP] = ACT_JUMP, + [ACT_DOUBLE_JUMP] = ACT_DOUBLE_JUMP, + [ACT_TRIPLE_JUMP] = ACT_TRIPLE_JUMP, + [ACT_BACKFLIP] = ACT_BACKFLIP, + [ACT_STEEP_JUMP] = ACT_STEEP_JUMP, + [ACT_WALL_KICK_AIR] = ACT_WALL_KICK_AIR, + [ACT_SIDE_FLIP] = ACT_SIDE_FLIP, + [ACT_LONG_JUMP] = ACT_LONG_JUMP, + [ACT_WATER_JUMP] = ACT_WATER_JUMP, + [ACT_DIVE] = ACT_DIVE, + [ACT_FREEFALL] = ACT_FREEFALL, + [ACT_TOP_OF_POLE_JUMP] = ACT_TOP_OF_POLE_JUMP, + [ACT_BUTT_SLIDE_AIR] = ACT_BUTT_SLIDE_AIR, + [ACT_FLYING_TRIPLE_JUMP] = ACT_FLYING_TRIPLE_JUMP, + [ACT_SHOT_FROM_CANNON] = ACT_SHOT_FROM_CANNON, + [ACT_FLYING] = ACT_FLYING, + [ACT_RIDING_SHELL_JUMP] = ACT_RIDING_SHELL_JUMP, + [ACT_RIDING_SHELL_FALL] = ACT_RIDING_SHELL_FALL, + [ACT_VERTICAL_WIND] = ACT_VERTICAL_WIND, + [ACT_HOLD_JUMP] = ACT_HOLD_JUMP, + [ACT_HOLD_FREEFALL] = ACT_HOLD_FREEFALL, + [ACT_HOLD_BUTT_SLIDE_AIR] = ACT_HOLD_BUTT_SLIDE_AIR, + [ACT_HOLD_WATER_JUMP] = ACT_HOLD_WATER_JUMP, + [ACT_TWIRLING] = ACT_TWIRLING, + [ACT_FORWARD_ROLLOUT] = ACT_FORWARD_ROLLOUT, + [ACT_AIR_HIT_WALL] = ACT_AIR_HIT_WALL, + [ACT_RIDING_HOOT] = ACT_RIDING_HOOT, + [ACT_GROUND_POUND] = ACT_GROUND_POUND, + [ACT_SLIDE_KICK] = ACT_SLIDE_KICK, + [ACT_AIR_THROW] = ACT_AIR_THROW, + [ACT_JUMP_KICK] = ACT_JUMP_KICK, + [ACT_BACKWARD_ROLLOUT] = ACT_BACKWARD_ROLLOUT, + [ACT_CRAZY_BOX_BOUNCE] = ACT_CRAZY_BOX_BOUNCE, + [ACT_SPECIAL_TRIPLE_JUMP] = ACT_SPECIAL_TRIPLE_JUMP, + [ACT_BACKWARD_AIR_KB] = ACT_BACKWARD_AIR_KB, + [ACT_FORWARD_AIR_KB] = ACT_FORWARD_AIR_KB, + [ACT_HARD_FORWARD_AIR_KB] = ACT_HARD_FORWARD_AIR_KB, + [ACT_HARD_BACKWARD_AIR_KB] = ACT_HARD_BACKWARD_AIR_KB, + [ACT_BURNING_JUMP] = ACT_BURNING_JUMP, + [ACT_BURNING_FALL] = ACT_BURNING_FALL, + [ACT_SOFT_BONK] = ACT_SOFT_BONK, + [ACT_LAVA_BOOST] = ACT_LAVA_BOOST, + [ACT_GETTING_BLOWN] = ACT_GETTING_BLOWN, + [ACT_THROWN_FORWARD] = ACT_THROWN_FORWARD, + [ACT_THROWN_BACKWARD] = ACT_THROWN_BACKWARD, + [ACT_WATER_IDLE] = ACT_WATER_IDLE, + [ACT_HOLD_WATER_IDLE] = ACT_HOLD_WATER_IDLE, + [ACT_WATER_ACTION_END] = ACT_WATER_ACTION_END, + [ACT_HOLD_WATER_ACTION_END] = ACT_HOLD_WATER_ACTION_END, + [ACT_DROWNING] = ACT_DROWNING, + [ACT_BACKWARD_WATER_KB] = ACT_BACKWARD_WATER_KB, + [ACT_FORWARD_WATER_KB] = ACT_FORWARD_WATER_KB, + [ACT_WATER_DEATH] = ACT_WATER_DEATH, + [ACT_WATER_SHOCKED] = ACT_WATER_SHOCKED, + [ACT_BREASTSTROKE] = ACT_BREASTSTROKE, + [ACT_SWIMMING_END] = ACT_SWIMMING_END, + [ACT_FLUTTER_KICK] = ACT_FLUTTER_KICK, + [ACT_HOLD_BREASTSTROKE] = ACT_HOLD_BREASTSTROKE, + [ACT_HOLD_SWIMMING_END] = ACT_HOLD_SWIMMING_END, + [ACT_HOLD_FLUTTER_KICK] = ACT_HOLD_FLUTTER_KICK, + [ACT_WATER_SHELL_SWIMMING] = ACT_WATER_SHELL_SWIMMING, + [ACT_WATER_THROW] = ACT_WATER_THROW, + [ACT_WATER_PUNCH] = ACT_WATER_PUNCH, + [ACT_WATER_PLUNGE] = ACT_WATER_PLUNGE, + [ACT_CAUGHT_IN_WHIRLPOOL] = ACT_CAUGHT_IN_WHIRLPOOL, + [ACT_METAL_WATER_STANDING] = ACT_METAL_WATER_STANDING, + [ACT_HOLD_METAL_WATER_STANDING] = ACT_HOLD_METAL_WATER_STANDING, + [ACT_METAL_WATER_WALKING] = ACT_METAL_WATER_WALKING, + [ACT_HOLD_METAL_WATER_WALKING] = ACT_HOLD_METAL_WATER_WALKING, + [ACT_METAL_WATER_FALLING] = ACT_METAL_WATER_FALLING, + [ACT_HOLD_METAL_WATER_FALLING] = ACT_HOLD_METAL_WATER_FALLING, + [ACT_METAL_WATER_FALL_LAND] = ACT_METAL_WATER_FALL_LAND, + [ACT_HOLD_METAL_WATER_FALL_LAND] = ACT_HOLD_METAL_WATER_FALL_LAND, + [ACT_METAL_WATER_JUMP] = ACT_METAL_WATER_JUMP, + [ACT_HOLD_METAL_WATER_JUMP] = ACT_HOLD_METAL_WATER_JUMP, + [ACT_METAL_WATER_JUMP_LAND] = ACT_METAL_WATER_JUMP_LAND, + [ACT_HOLD_METAL_WATER_JUMP_LAND] = ACT_HOLD_METAL_WATER_JUMP_LAND, + [ACT_DISAPPEARED] = ACT_DISAPPEARED, + [ACT_INTRO_CUTSCENE] = ACT_INTRO_CUTSCENE, + [ACT_STAR_DANCE_EXIT] = ACT_STAR_DANCE_EXIT, + [ACT_STAR_DANCE_WATER] = ACT_STAR_DANCE_WATER, + [ACT_FALL_AFTER_STAR_GRAB] = ACT_FALL_AFTER_STAR_GRAB, + [ACT_READING_AUTOMATIC_DIALOG] = ACT_READING_AUTOMATIC_DIALOG, + [ACT_READING_NPC_DIALOG] = ACT_READING_NPC_DIALOG, + [ACT_STAR_DANCE_NO_EXIT] = ACT_STAR_DANCE_NO_EXIT, + [ACT_READING_SIGN] = ACT_READING_SIGN, + [ACT_JUMBO_STAR_CUTSCENE] = ACT_JUMBO_STAR_CUTSCENE, + [ACT_WAITING_FOR_DIALOG] = ACT_WAITING_FOR_DIALOG, + [ACT_DEBUG_FREE_MOVE] = ACT_DEBUG_FREE_MOVE, + [ACT_STANDING_DEATH] = ACT_STANDING_DEATH, + [ACT_QUICKSAND_DEATH] = ACT_QUICKSAND_DEATH, + [ACT_ELECTROCUTION] = ACT_ELECTROCUTION, + [ACT_SUFFOCATION] = ACT_SUFFOCATION, + [ACT_DEATH_ON_STOMACH] = ACT_DEATH_ON_STOMACH, + [ACT_DEATH_ON_BACK] = ACT_DEATH_ON_BACK, + [ACT_EATEN_BY_BUBBA] = ACT_EATEN_BY_BUBBA, + [ACT_END_PEACH_CUTSCENE] = ACT_END_PEACH_CUTSCENE, + [ACT_CREDITS_CUTSCENE] = ACT_CREDITS_CUTSCENE, + [ACT_END_WAVING_CUTSCENE] = ACT_END_WAVING_CUTSCENE, + [ACT_PULLING_DOOR] = ACT_PULLING_DOOR, + [ACT_PUSHING_DOOR] = ACT_PUSHING_DOOR, + [ACT_WARP_DOOR_SPAWN] = ACT_WARP_DOOR_SPAWN, + [ACT_EMERGE_FROM_PIPE] = ACT_EMERGE_FROM_PIPE, + [ACT_SPAWN_SPIN_AIRBORNE] = ACT_SPAWN_SPIN_AIRBORNE, + [ACT_SPAWN_SPIN_LANDING] = ACT_SPAWN_SPIN_LANDING, + [ACT_EXIT_AIRBORNE] = ACT_EXIT_AIRBORNE, + [ACT_EXIT_LAND_SAVE_DIALOG] = ACT_EXIT_LAND_SAVE_DIALOG, + [ACT_DEATH_EXIT] = ACT_DEATH_EXIT, + [ACT_UNUSED_DEATH_EXIT] = ACT_UNUSED_DEATH_EXIT, + [ACT_FALLING_DEATH_EXIT] = ACT_FALLING_DEATH_EXIT, + [ACT_SPECIAL_EXIT_AIRBORNE] = ACT_SPECIAL_EXIT_AIRBORNE, + [ACT_SPECIAL_DEATH_EXIT] = ACT_SPECIAL_DEATH_EXIT, + [ACT_FALLING_EXIT_AIRBORNE] = ACT_FALLING_EXIT_AIRBORNE, + [ACT_UNLOCKING_KEY_DOOR] = ACT_UNLOCKING_KEY_DOOR, + [ACT_UNLOCKING_STAR_DOOR] = ACT_UNLOCKING_STAR_DOOR, + [ACT_ENTERING_STAR_DOOR] = ACT_ENTERING_STAR_DOOR, + [ACT_SPAWN_NO_SPIN_AIRBORNE] = ACT_SPAWN_NO_SPIN_AIRBORNE, + [ACT_SPAWN_NO_SPIN_LANDING] = ACT_SPAWN_NO_SPIN_LANDING, + [ACT_BBH_ENTER_JUMP] = ACT_BBH_ENTER_JUMP, + [ACT_BBH_ENTER_SPIN] = ACT_BBH_ENTER_SPIN, + [ACT_TELEPORT_FADE_OUT] = ACT_TELEPORT_FADE_OUT, + [ACT_TELEPORT_FADE_IN] = ACT_TELEPORT_FADE_IN, + [ACT_SHOCKED] = ACT_SHOCKED, + [ACT_SQUISHED] = ACT_SQUISHED, + [ACT_HEAD_STUCK_IN_GROUND] = ACT_HEAD_STUCK_IN_GROUND, + [ACT_BUTT_STUCK_IN_GROUND] = ACT_BUTT_STUCK_IN_GROUND, + [ACT_FEET_STUCK_IN_GROUND] = ACT_FEET_STUCK_IN_GROUND, + [ACT_PUTTING_ON_CAP] = ACT_PUTTING_ON_CAP, + [ACT_HOLDING_POLE] = ACT_HOLDING_POLE, + [ACT_GRAB_POLE_SLOW] = ACT_GRAB_POLE_SLOW, + [ACT_GRAB_POLE_FAST] = ACT_GRAB_POLE_FAST, + [ACT_CLIMBING_POLE] = ACT_CLIMBING_POLE, + [ACT_TOP_OF_POLE_TRANSITION] = ACT_TOP_OF_POLE_TRANSITION, + [ACT_TOP_OF_POLE] = ACT_TOP_OF_POLE, + [ACT_START_HANGING] = ACT_START_HANGING, + [ACT_HANGING] = ACT_HANGING, + [ACT_HANG_MOVING] = ACT_HANG_MOVING, + [ACT_LEDGE_GRAB] = ACT_LEDGE_GRAB, + [ACT_LEDGE_CLIMB_SLOW_1] = ACT_LEDGE_CLIMB_SLOW_1, + [ACT_LEDGE_CLIMB_SLOW_2] = ACT_LEDGE_CLIMB_SLOW_2, + [ACT_LEDGE_CLIMB_DOWN] = ACT_LEDGE_CLIMB_DOWN, + [ACT_LEDGE_CLIMB_FAST] = ACT_LEDGE_CLIMB_FAST, + [ACT_GRABBED] = ACT_GRABBED, + [ACT_IN_CANNON] = ACT_IN_CANNON, + [ACT_TORNADO_TWIRLING] = ACT_TORNADO_TWIRLING, + [ACT_BUBBLED] = ACT_BUBBLED, + [ACT_PUNCHING] = ACT_PUNCHING, + [ACT_PICKING_UP] = ACT_PICKING_UP, + [ACT_DIVE_PICKING_UP] = ACT_DIVE_PICKING_UP, + [ACT_STOMACH_SLIDE_STOP] = ACT_STOMACH_SLIDE_STOP, + [ACT_PLACING_DOWN] = ACT_PLACING_DOWN, + [ACT_THROWING] = ACT_THROWING, + [ACT_HEAVY_THROW] = ACT_HEAVY_THROW, + [ACT_PICKING_UP_BOWSER] = ACT_PICKING_UP_BOWSER, + [ACT_HOLDING_BOWSER] = ACT_HOLDING_BOWSER, + [ACT_RELEASING_BOWSER] = ACT_RELEASING_BOWSER, +} + + +---@param m MarioState +function is_mario_in_vanilla_action(m) + return defaultActions[m.action] ~= nil +end + +-- Lazy automation of interpolation on HUD elements +local interpTable = {} + +function djui_set_interpolation(index, x, y, width, height) + interpTable[index] = { + x = x, + y = y, + width = width, + height = height + } +end + +function djui_get_interpolation(index, backUpX, backUpY, backUpWidth, backUpHeight) + return interpTable[index] or {x = backUpX or 0, y = backUpY or 0, width = backUpWidth or 0, height = backUpHeight or 0} +end + +function djui_hud_print_text_auto_interpolated(index, message, x, y, scale) + local interp = djui_get_interpolation(index, x, y, scale, nil) + djui_hud_print_text_interpolated(message, interp.x, interp.y, interp.width, x, y, scale) + djui_set_interpolation(index, x, y, scale, nil) +end + +function djui_hud_render_texture_auto_interpolated(index, texture, x, y, width, height) + local interp = djui_get_interpolation(index, x, y, width, height) + djui_hud_render_texture_interpolated(texture, interp.x, interp.y, interp.width, interp.height, x, y, width, height) + djui_set_interpolation(index, x, y, width, height) +end + +local hasBeenLogged = {} +---@param message string +---@param level ConsoleMessageLevel +function log_to_console_once(message, level) + if not hasBeenLogged[message] then + hasBeenLogged[message] = true + log_to_console("Character Select: "..message, level) + end +end + +function is_power_of_two(n) + return (n & (n - 1)) == 0 +end + +---@param tex TextureInfo +function is_texture_valid(tex) + if tex ~= nil then + return is_power_of_two(tex.width) and is_power_of_two(tex.height) + else + return false + end +end + +function run_func_or_get_var(x, ...) + if type(x) == "function" then + return x(...) + else + return x + end +end + +---@param x integer +function mirror_mode_number(x) + if _G.mirrorMode ~= nil and _G.mirrorMode.is_mirrored() then + return x * -1 + end + return x +end + +---@param str1 string +---@param str2 string +local function levenshtein_distance(str1, str2) + local len1 = #str1 + local len2 = #str2 + + local matrix = {} + for i = 0, len1 do + matrix[i] = {} + matrix[i][0] = i + end + for j = 0, len2 do + matrix[0][j] = j + end + + for i = 1, len1 do + for j = 1, len2 do + local cost = (str1:sub(i, i) == str2:sub(j, j)) and 0 or 1 + local del = matrix[i-1][j] + 1 + local ins = matrix[i][j-1] + 1 + local sub = matrix[i-1][j-1] + cost + matrix[i][j] = math.min(del, ins, sub) + end + end + + return matrix[len1][len2] +end + +---@param str1 string +---@param str2 string +-- Compares two strings and returns simularity (0-1) +function string_sim(str1, str2) + local distance = levenshtein_distance(str1, str2) + local maxLength = math.max(#str1, #str2) + if maxLength == 0 then return 1 end + return (distance / maxLength) +end \ No newline at end of file diff --git a/mods/character-select-coop/actors/armature_geo.bin b/mods/character-select-coop/actors/armature_geo.bin deleted file mode 100644 index 70835e7ed..000000000 Binary files a/mods/character-select-coop/actors/armature_geo.bin and /dev/null differ diff --git a/mods/character-select-coop/anims.lua b/mods/character-select-coop/anims.lua new file mode 100644 index 000000000..3b6c9b498 --- /dev/null +++ b/mods/character-select-coop/anims.lua @@ -0,0 +1,1201 @@ +MARIO_ANIM_CS_MENU = "mario_anim_cs_menu" +smlua_anim_util_register_animation(MARIO_ANIM_CS_MENU, + 0, + 0, + 0, + 0, + 83, + { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, + 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, + 0xFFFD, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFB, + 0xFFFB, 0xFFFB, 0xFFFB, 0xFFFB, 0xFFFB, 0xFFFB, 0xFFFB, 0xFFFB, 0xFFFB, + 0xFFFB, 0xFFFB, 0xFFFB, 0xFFFB, 0xFFFB, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFC, + 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, + 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x00AD, 0x00AD, 0x00AD, 0x00AC, + 0x00AC, 0x00AC, 0x00AC, 0x00AC, 0x00AC, 0x00AC, 0x00AB, 0x00AB, 0x00AB, + 0x00AB, 0x00AA, 0x00AA, 0x00AA, 0x00AA, 0x00A9, 0x00A9, 0x00A9, 0x00A8, + 0x00A8, 0x00A8, 0x00A8, 0x00A7, 0x00A7, 0x00A7, 0x00A6, 0x00A6, 0x00A6, + 0x00A6, 0x00A5, 0x00A5, 0x00A5, 0x00A5, 0x00A5, 0x00A5, 0x00A4, 0x00A4, + 0x00A4, 0x00A4, 0x00A4, 0x00A4, 0x00A4, 0x00A4, 0x00A4, 0x00A5, 0x00A5, + 0x00A5, 0x00A5, 0x00A5, 0x00A5, 0x00A6, 0x00A6, 0x00A6, 0x00A6, 0x00A7, + 0x00A7, 0x00A7, 0x00A8, 0x00A8, 0x00A8, 0x00A8, 0x00A9, 0x00A9, 0x00A9, + 0x00AA, 0x00AA, 0x00AA, 0x00AA, 0x00AB, 0x00AB, 0x00AB, 0x00AB, 0x00AC, + 0x00AC, 0x00AC, 0x00AC, 0x00AC, 0x00AC, 0x00AC, 0x00AD, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFD, + 0xFFFD, 0xFFFD, 0xFFFC, 0xFFFB, 0xFFFB, 0xFFFA, 0xFFFA, 0xFFF9, 0xFFF8, + 0xFFF8, 0xFFF7, 0xFFF7, 0xFFF6, 0xFFF5, 0xFFF5, 0xFFF4, 0xFFF4, 0xFFF3, + 0xFFF2, 0xFFF2, 0xFFF1, 0xFFF1, 0xFFF1, 0xFFF0, 0xFFF0, 0xFFEF, 0xFFEF, + 0xFFEF, 0xFFEF, 0xFFEF, 0xFFEE, 0xFFEE, 0xFFEE, 0xFFEF, 0xFFEF, 0xFFEF, + 0xFFEF, 0xFFEF, 0xFFF0, 0xFFF0, 0xFFF1, 0xFFF1, 0xFFF1, 0xFFF2, 0xFFF2, + 0xFFF3, 0xFFF4, 0xFFF4, 0xFFF5, 0xFFF5, 0xFFF6, 0xFFF7, 0xFFF7, 0xFFF8, + 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFA, 0xFFFB, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFD, + 0xFFFD, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x3FFF, + 0x0000, 0xDC72, 0x007B, 0x4067, 0xF96D, 0xF96D, 0xF96D, 0xF96D, 0xF96C, + 0xF96B, 0xF96A, 0xF96A, 0xF968, 0xF967, 0xF966, 0xF965, 0xF963, 0xF962, + 0xF960, 0xF95E, 0xF95D, 0xF95B, 0xF959, 0xF957, 0xF956, 0xF954, 0xF952, + 0xF950, 0xF94E, 0xF94D, 0xF94B, 0xF949, 0xF948, 0xF946, 0xF945, 0xF943, + 0xF942, 0xF940, 0xF93F, 0xF93E, 0xF93D, 0xF93C, 0xF93C, 0xF93B, 0xF93B, + 0xF93A, 0xF93A, 0xF93A, 0xF93B, 0xF93B, 0xF93C, 0xF93C, 0xF93D, 0xF93E, + 0xF93F, 0xF940, 0xF942, 0xF943, 0xF945, 0xF946, 0xF948, 0xF949, 0xF94B, + 0xF94D, 0xF94E, 0xF950, 0xF952, 0xF954, 0xF956, 0xF957, 0xF959, 0xF95B, + 0xF95D, 0xF95E, 0xF960, 0xF962, 0xF963, 0xF965, 0xF966, 0xF967, 0xF968, + 0xF96A, 0xF96A, 0xF96B, 0xF96C, 0xF96D, 0xFE3D, 0xFE3D, 0xFE3F, 0xFE41, + 0xFE44, 0xFE48, 0xFE4D, 0xFE52, 0xFE58, 0xFE5F, 0xFE66, 0xFE6D, 0xFE76, + 0xFE7E, 0xFE87, 0xFE90, 0xFE9A, 0xFEA3, 0xFEAD, 0xFEB7, 0xFEC1, 0xFECC, + 0xFED6, 0xFEE0, 0xFEEA, 0xFEF4, 0xFEFD, 0xFF07, 0xFF10, 0xFF19, 0xFF22, + 0xFF2A, 0xFF31, 0xFF38, 0xFF3F, 0xFF45, 0xFF4A, 0xFF4F, 0xFF53, 0xFF56, + 0xFF58, 0xFF5A, 0xFF5A, 0xFF5A, 0xFF58, 0xFF56, 0xFF53, 0xFF4F, 0xFF4A, + 0xFF45, 0xFF3F, 0xFF38, 0xFF31, 0xFF2A, 0xFF22, 0xFF19, 0xFF10, 0xFF07, + 0xFEFD, 0xFEF4, 0xFEEA, 0xFEE0, 0xFED6, 0xFECC, 0xFEC1, 0xFEB7, 0xFEAD, + 0xFEA3, 0xFE9A, 0xFE90, 0xFE87, 0xFE7E, 0xFE76, 0xFE6D, 0xFE66, 0xFE5F, + 0xFE58, 0xFE52, 0xFE4D, 0xFE48, 0xFE44, 0xFE41, 0xFE3F, 0xFE3D, 0xF4CE, + 0xF4D1, 0xF4DA, 0xF4E8, 0xF4FA, 0xF512, 0xF52E, 0xF54E, 0xF572, 0xF59A, + 0xF5C5, 0xF5F3, 0xF624, 0xF657, 0xF68D, 0xF6C5, 0xF6FE, 0xF739, 0xF774, + 0xF7B1, 0xF7EE, 0xF82C, 0xF869, 0xF8A6, 0xF8E3, 0xF91F, 0xF95A, 0xF993, + 0xF9CB, 0xFA00, 0xFA34, 0xFA65, 0xFA93, 0xFABE, 0xFAE6, 0xFB0A, 0xFB2A, + 0xFB46, 0xFB5D, 0xFB70, 0xFB7E, 0xFB86, 0xFB89, 0xFB86, 0xFB7E, 0xFB70, + 0xFB5D, 0xFB46, 0xFB2A, 0xFB0A, 0xFAE6, 0xFABE, 0xFA93, 0xFA65, 0xFA34, + 0xFA00, 0xF9CB, 0xF993, 0xF95A, 0xF91F, 0xF8E3, 0xF8A6, 0xF869, 0xF82C, + 0xF7EE, 0xF7B1, 0xF774, 0xF739, 0xF6FE, 0xF6C5, 0xF68D, 0xF657, 0xF624, + 0xF5F3, 0xF5C5, 0xF59A, 0xF572, 0xF54E, 0xF52E, 0xF512, 0xF4FA, 0xF4E8, + 0xF4DA, 0xF4D1, 0x0BA2, 0x0BA3, 0x0BA6, 0x0BAB, 0x0BB2, 0x0BBA, 0x0BC3, + 0x0BCD, 0x0BD7, 0x0BE2, 0x0BED, 0x0BF9, 0x0C04, 0x0C0E, 0x0C18, 0x0C21, + 0x0C29, 0x0C30, 0x0C34, 0x0C38, 0x0C39, 0x0C38, 0x0C37, 0x0C34, 0x0C31, + 0x0C2D, 0x0C28, 0x0C22, 0x0C1C, 0x0C15, 0x0C0E, 0x0C06, 0x0BFD, 0x0BF4, + 0x0BEB, 0x0BE2, 0x0BD8, 0x0BCE, 0x0BC4, 0x0BB9, 0x0BAF, 0x0BA5, 0x0B9B, + 0x0B90, 0x0B86, 0x0B7D, 0x0B73, 0x0B6A, 0x0B61, 0x0B59, 0x0B51, 0x0B49, + 0x0B42, 0x0B3C, 0x0B36, 0x0B31, 0x0B2D, 0x0B2A, 0x0B28, 0x0B26, 0x0B26, + 0x0B26, 0x0B28, 0x0B2B, 0x0B2F, 0x0B34, 0x0B39, 0x0B3F, 0x0B46, 0x0B4D, + 0x0B54, 0x0B5C, 0x0B64, 0x0B6C, 0x0B73, 0x0B7B, 0x0B82, 0x0B89, 0x0B8F, + 0x0B94, 0x0B99, 0x0B9D, 0x0BA0, 0x0BA2, 0xFA5B, 0xFA5E, 0xFA66, 0xFA74, + 0xFA86, 0xFA9B, 0xFAB4, 0xFACF, 0xFAEC, 0xFB0A, 0xFB29, 0xFB48, 0xFB66, + 0xFB83, 0xFB9E, 0xFBB7, 0xFBCD, 0xFBDF, 0xFBEC, 0xFBF5, 0xFBF8, 0xFBF6, + 0xFBF3, 0xFBED, 0xFBE5, 0xFBDC, 0xFBD0, 0xFBC3, 0xFBB4, 0xFBA4, 0xFB92, + 0xFB7F, 0xFB6B, 0xFB56, 0xFB41, 0xFB2A, 0xFB13, 0xFAFB, 0xFAE3, 0xFACB, + 0xFAB3, 0xFA9A, 0xFA82, 0xFA6A, 0xFA53, 0xFA3B, 0xFA25, 0xFA0F, 0xF9FA, + 0xF9E6, 0xF9D3, 0xF9C2, 0xF9B1, 0xF9A3, 0xF995, 0xF98A, 0xF980, 0xF978, + 0xF973, 0xF96F, 0xF96E, 0xF96F, 0xF972, 0xF978, 0xF97F, 0xF988, 0xF993, + 0xF99F, 0xF9AB, 0xF9B9, 0xF9C7, 0xF9D6, 0xF9E4, 0xF9F3, 0xFA02, 0xFA10, + 0xFA1D, 0xFA2A, 0xFA36, 0xFA40, 0xFA49, 0xFA51, 0xFA56, 0xFA5A, 0x0691, + 0x0687, 0x066B, 0x063E, 0x0603, 0x05BC, 0x056B, 0x0511, 0x04B1, 0x044E, + 0x03E8, 0x0382, 0x031E, 0x02BF, 0x0265, 0x0214, 0x01CD, 0x0192, 0x0165, + 0x0149, 0x013F, 0x0143, 0x014F, 0x0162, 0x017C, 0x019D, 0x01C4, 0x01F1, + 0x0223, 0x025B, 0x0296, 0x02D6, 0x0319, 0x0360, 0x03AA, 0x03F6, 0x0444, + 0x0494, 0x04E5, 0x0537, 0x0589, 0x05DC, 0x062D, 0x067E, 0x06CE, 0x071C, + 0x0769, 0x07B2, 0x07F9, 0x083C, 0x087C, 0x08B8, 0x08EF, 0x0921, 0x094E, + 0x0975, 0x0996, 0x09B0, 0x09C4, 0x09CF, 0x09D3, 0x09CF, 0x09C3, 0x09B0, + 0x0996, 0x0976, 0x0951, 0x0928, 0x08FB, 0x08CB, 0x0899, 0x0866, 0x0832, + 0x07FE, 0x07CB, 0x0799, 0x0769, 0x073C, 0x0713, 0x06EE, 0x06CF, 0x06B5, + 0x06A1, 0x0695, 0x0000, 0xFFFF, 0xBFFF, 0xFBAD, 0xFBAC, 0xFBA9, 0xFBA5, + 0xFB9E, 0xFB96, 0xFB8D, 0xFB82, 0xFB76, 0xFB68, 0xFB5A, 0xFB4A, 0xFB3A, + 0xFB28, 0xFB16, 0xFB03, 0xFAF0, 0xFADC, 0xFAC8, 0xFAB3, 0xFA9F, 0xFA8A, + 0xFA75, 0xFA60, 0xFA4C, 0xFA38, 0xFA24, 0xFA10, 0xF9FE, 0xF9EB, 0xF9DA, + 0xF9CA, 0xF9BA, 0xF9AB, 0xF99E, 0xF992, 0xF987, 0xF97D, 0xF975, 0xF96F, + 0xF96A, 0xF968, 0xF967, 0xF968, 0xF96A, 0xF96F, 0xF975, 0xF97D, 0xF987, + 0xF992, 0xF99E, 0xF9AB, 0xF9BA, 0xF9CA, 0xF9DA, 0xF9EB, 0xF9FE, 0xFA10, + 0xFA24, 0xFA38, 0xFA4C, 0xFA60, 0xFA75, 0xFA8A, 0xFA9F, 0xFAB3, 0xFAC8, + 0xFADC, 0xFAF0, 0xFB03, 0xFB16, 0xFB28, 0xFB3A, 0xFB4A, 0xFB5A, 0xFB68, + 0xFB76, 0xFB82, 0xFB8D, 0xFB96, 0xFB9E, 0xFBA5, 0xFBA9, 0xFBAC, 0xDE3A, + 0xDE3A, 0xDE3A, 0xDE3B, 0xDE3C, 0xDE3D, 0xDE3E, 0xDE3F, 0xDE41, 0xDE43, + 0xDE44, 0xDE46, 0xDE48, 0xDE4B, 0xDE4D, 0xDE4F, 0xDE52, 0xDE54, 0xDE57, + 0xDE59, 0xDE5C, 0xDE5E, 0xDE61, 0xDE63, 0xDE66, 0xDE68, 0xDE6B, 0xDE6D, + 0xDE70, 0xDE72, 0xDE74, 0xDE76, 0xDE78, 0xDE7A, 0xDE7C, 0xDE7D, 0xDE7E, + 0xDE80, 0xDE81, 0xDE81, 0xDE82, 0xDE82, 0xDE82, 0xDE82, 0xDE82, 0xDE81, + 0xDE81, 0xDE80, 0xDE7E, 0xDE7D, 0xDE7C, 0xDE7A, 0xDE78, 0xDE76, 0xDE74, + 0xDE72, 0xDE70, 0xDE6D, 0xDE6B, 0xDE68, 0xDE66, 0xDE63, 0xDE61, 0xDE5E, + 0xDE5C, 0xDE59, 0xDE56, 0xDE54, 0xDE52, 0xDE4F, 0xDE4D, 0xDE4B, 0xDE48, + 0xDE46, 0xDE44, 0xDE43, 0xDE41, 0xDE3F, 0xDE3E, 0xDE3D, 0xDE3C, 0xDE3B, + 0xDE3A, 0xE9B3, 0xE9B4, 0xE9B8, 0xE9BF, 0xE9C7, 0xE9D2, 0xE9DF, 0xE9EE, + 0xE9FE, 0xEA11, 0xEA24, 0xEA3A, 0xEA50, 0xEA68, 0xEA80, 0xEA9A, 0xEAB4, + 0xEACF, 0xEAEB, 0xEB07, 0xEB23, 0xEB3F, 0xEB5C, 0xEB78, 0xEB94, 0xEBAF, + 0xEBCA, 0xEBE5, 0xEBFE, 0xEC17, 0xEC2F, 0xEC45, 0xEC5A, 0xEC6E, 0xEC80, + 0xEC91, 0xECA0, 0xECAD, 0xECB8, 0xECC0, 0xECC6, 0xECCA, 0xECCC, 0xECCA, + 0xECC6, 0xECC0, 0xECB8, 0xECAD, 0xECA0, 0xEC91, 0xEC80, 0xEC6E, 0xEC5A, + 0xEC45, 0xEC2F, 0xEC17, 0xEBFE, 0xEBE5, 0xEBCA, 0xEBAF, 0xEB94, 0xEB78, + 0xEB5C, 0xEB3F, 0xEB23, 0xEB07, 0xEAEB, 0xEACF, 0xEAB4, 0xEA9A, 0xEA80, + 0xEA68, 0xEA50, 0xEA3A, 0xEA24, 0xEA11, 0xE9FE, 0xE9EE, 0xE9DF, 0xE9D2, + 0xE9C7, 0xE9BF, 0xE9B8, 0xE9B4, 0xFFFF, 0x0000, 0x0001, 0x0001, 0x0002, + 0x0003, 0x0005, 0x0006, 0x0008, 0x000A, 0x000C, 0x000E, 0x0011, 0x0014, + 0x0016, 0x0019, 0x001C, 0x0020, 0x0023, 0x0026, 0x002A, 0x002E, 0x0031, + 0x0035, 0x0039, 0x003D, 0x0041, 0x0045, 0x0049, 0x004D, 0x0051, 0x0055, + 0x0059, 0x005D, 0x0061, 0x0065, 0x0069, 0x006D, 0x0071, 0x0074, 0x0078, + 0x007C, 0x007F, 0x0082, 0x0086, 0x0089, 0x008C, 0x008F, 0x0091, 0x0094, + 0x0096, 0x0098, 0x009A, 0x009C, 0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, + 0x00A2, 0x00A2, 0x00A1, 0x009F, 0x009B, 0x0096, 0x0090, 0x0089, 0x0081, + 0x0078, 0x006F, 0x0065, 0x005B, 0x0051, 0x0047, 0x003D, 0x0033, 0x002A, + 0x0021, 0x0019, 0x0012, 0x000C, 0x0007, 0x0003, 0x0001, 0x0000, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFD, 0xFFFD, 0xFFFC, 0xFFFB, 0xFFFB, + 0xFFFA, 0xFFF9, 0xFFF8, 0xFFF7, 0xFFF6, 0xFFF4, 0xFFF3, 0xFFF2, 0xFFF1, + 0xFFEF, 0xFFEE, 0xFFED, 0xFFEB, 0xFFEA, 0xFFE8, 0xFFE7, 0xFFE5, 0xFFE4, + 0xFFE2, 0xFFE1, 0xFFDF, 0xFFDE, 0xFFDC, 0xFFDB, 0xFFD9, 0xFFD8, 0xFFD6, + 0xFFD5, 0xFFD4, 0xFFD2, 0xFFD1, 0xFFD0, 0xFFCE, 0xFFCD, 0xFFCC, 0xFFCB, + 0xFFCA, 0xFFC9, 0xFFC8, 0xFFC7, 0xFFC6, 0xFFC5, 0xFFC5, 0xFFC4, 0xFFC4, + 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC7, + 0xFFC9, 0xFFCC, 0xFFCF, 0xFFD2, 0xFFD6, 0xFFD9, 0xFFDD, 0xFFE1, 0xFFE5, + 0xFFE8, 0xFFEC, 0xFFEF, 0xFFF3, 0xFFF6, 0xFFF8, 0xFFFB, 0xFFFC, 0xFFFE, + 0xFFFF, 0xF5BB, 0xF5BC, 0xF5BE, 0xF5C2, 0xF5C8, 0xF5CE, 0xF5D7, 0xF5E0, + 0xF5EB, 0xF5F7, 0xF604, 0xF613, 0xF622, 0xF632, 0xF644, 0xF656, 0xF669, + 0xF67D, 0xF691, 0xF6A6, 0xF6BC, 0xF6D3, 0xF6E9, 0xF701, 0xF718, 0xF730, + 0xF749, 0xF761, 0xF77A, 0xF792, 0xF7AB, 0xF7C4, 0xF7DD, 0xF7F5, 0xF80E, + 0xF826, 0xF83E, 0xF856, 0xF86D, 0xF884, 0xF89A, 0xF8B0, 0xF8C5, 0xF8DA, + 0xF8ED, 0xF900, 0xF913, 0xF924, 0xF934, 0xF944, 0xF952, 0xF95F, 0xF96B, + 0xF976, 0xF980, 0xF988, 0xF98F, 0xF994, 0xF998, 0xF99B, 0xF99C, 0xF997, + 0xF988, 0xF971, 0xF952, 0xF92C, 0xF900, 0xF8CF, 0xF89A, 0xF861, 0xF826, + 0xF7E9, 0xF7AB, 0xF76D, 0xF730, 0xF6F5, 0xF6BC, 0xF687, 0xF656, 0xF62A, + 0xF604, 0xF5E6, 0xF5CE, 0xF5C0, 0xDE6C, 0xDE6C, 0xDE6B, 0xDE6B, 0xDE6B, + 0xDE6A, 0xDE69, 0xDE68, 0xDE67, 0xDE66, 0xDE65, 0xDE64, 0xDE63, 0xDE61, + 0xDE60, 0xDE5E, 0xDE5D, 0xDE5B, 0xDE5A, 0xDE58, 0xDE56, 0xDE55, 0xDE53, + 0xDE51, 0xDE50, 0xDE4E, 0xDE4D, 0xDE4B, 0xDE4A, 0xDE48, 0xDE47, 0xDE45, + 0xDE44, 0xDE43, 0xDE42, 0xDE41, 0xDE40, 0xDE3F, 0xDE3F, 0xDE3E, 0xDE3E, + 0xDE3E, 0xDE3E, 0xDE3E, 0xDE3E, 0xDE3E, 0xDE3F, 0xDE3F, 0xDE40, 0xDE41, + 0xDE42, 0xDE43, 0xDE44, 0xDE45, 0xDE47, 0xDE48, 0xDE4A, 0xDE4B, 0xDE4D, + 0xDE4E, 0xDE50, 0xDE51, 0xDE53, 0xDE55, 0xDE56, 0xDE58, 0xDE5A, 0xDE5B, + 0xDE5D, 0xDE5E, 0xDE60, 0xDE61, 0xDE63, 0xDE64, 0xDE65, 0xDE66, 0xDE67, + 0xDE68, 0xDE69, 0xDE6A, 0xDE6B, 0xDE6B, 0xDE6B, 0xDE6C, 0xFA75, 0xFA75, + 0xFA77, 0xFA7B, 0xFA80, 0xFA85, 0xFA8D, 0xFA95, 0xFA9E, 0xFAA8, 0xFAB3, + 0xFABE, 0xFACB, 0xFAD7, 0xFAE5, 0xFAF3, 0xFB01, 0xFB10, 0xFB1F, 0xFB2F, + 0xFB3E, 0xFB4D, 0xFB5D, 0xFB6C, 0xFB7C, 0xFB8B, 0xFB99, 0xFBA8, 0xFBB6, + 0xFBC3, 0xFBD0, 0xFBDD, 0xFBE8, 0xFBF3, 0xFBFD, 0xFC06, 0xFC0E, 0xFC15, + 0xFC1B, 0xFC20, 0xFC23, 0xFC26, 0xFC26, 0xFC26, 0xFC23, 0xFC20, 0xFC1B, + 0xFC15, 0xFC0E, 0xFC06, 0xFBFD, 0xFBF3, 0xFBE8, 0xFBDD, 0xFBD0, 0xFBC3, + 0xFBB6, 0xFBA8, 0xFB99, 0xFB8B, 0xFB7C, 0xFB6C, 0xFB5D, 0xFB4D, 0xFB3E, + 0xFB2F, 0xFB1F, 0xFB10, 0xFB01, 0xFAF3, 0xFAE5, 0xFAD7, 0xFACB, 0xFABE, + 0xFAB3, 0xFAA8, 0xFA9E, 0xFA95, 0xFA8D, 0xFA85, 0xFA80, 0xFA7B, 0xFA77, + 0xFA75, 0xF33D, 0xF33D, 0xF33F, 0xF343, 0xF347, 0xF34D, 0xF353, 0xF35B, + 0xF363, 0xF36C, 0xF376, 0xF381, 0xF38D, 0xF399, 0xF3A5, 0xF3B2, 0xF3BF, + 0xF3CD, 0xF3DB, 0xF3E9, 0xF3F8, 0xF406, 0xF414, 0xF423, 0xF431, 0xF43F, + 0xF44C, 0xF45A, 0xF467, 0xF473, 0xF47F, 0xF48B, 0xF496, 0xF4A0, 0xF4A9, + 0xF4B1, 0xF4B9, 0xF4BF, 0xF4C5, 0xF4C9, 0xF4CC, 0xF4CE, 0xF4CF, 0xF4CE, + 0xF4CC, 0xF4C9, 0xF4C5, 0xF4BF, 0xF4B9, 0xF4B1, 0xF4A9, 0xF4A0, 0xF496, + 0xF48B, 0xF47F, 0xF473, 0xF467, 0xF45A, 0xF44C, 0xF43F, 0xF431, 0xF423, + 0xF414, 0xF406, 0xF3F8, 0xF3E9, 0xF3DB, 0xF3CD, 0xF3BF, 0xF3B2, 0xF3A5, + 0xF399, 0xF38D, 0xF381, 0xF376, 0xF36C, 0xF363, 0xF35B, 0xF353, 0xF34D, + 0xF347, 0xF343, 0xF33F, 0xF33D, 0x0000, 0xFFFF, 0xBFFF, 0xEBA7, 0xEBAD, + 0xEBBC, 0xEBD5, 0xEBF8, 0xEC23, 0xEC56, 0xEC91, 0xECD3, 0xED1B, 0xED6A, + 0xEDBF, 0xEE18, 0xEE76, 0xEED8, 0xEF3E, 0xEFA7, 0xF012, 0xF080, 0xF0EE, + 0xF15E, 0xF1CF, 0xF23F, 0xF2AF, 0xF31E, 0xF38C, 0xF3F7, 0xF460, 0xF4C5, + 0xF528, 0xF586, 0xF5DF, 0xF633, 0xF682, 0xF6CB, 0xF70D, 0xF748, 0xF77B, + 0xF7A6, 0xF7C8, 0xF7E1, 0xF7F1, 0xF7F6, 0xF7F1, 0xF7E1, 0xF7C8, 0xF7A6, + 0xF77B, 0xF748, 0xF70D, 0xF6CB, 0xF682, 0xF633, 0xF5DF, 0xF586, 0xF528, + 0xF4C5, 0xF460, 0xF3F7, 0xF38C, 0xF31E, 0xF2AF, 0xF23F, 0xF1CF, 0xF15E, + 0xF0EE, 0xF080, 0xF012, 0xEFA7, 0xEF3E, 0xEED8, 0xEE76, 0xEE18, 0xEDBF, + 0xED6A, 0xED1B, 0xECD3, 0xEC91, 0xEC56, 0xEC23, 0xEBF8, 0xEBD5, 0xEBBC, + 0xEBAD, 0x1A7E, 0x1A7F, 0x1A83, 0x1A89, 0x1A91, 0x1A9B, 0x1AA7, 0x1AB5, + 0x1AC5, 0x1AD7, 0x1AE9, 0x1AFE, 0x1B13, 0x1B2A, 0x1B41, 0x1B59, 0x1B72, + 0x1B8C, 0x1BA6, 0x1BC1, 0x1BDC, 0x1BF6, 0x1C11, 0x1C2C, 0x1C47, 0x1C61, + 0x1C7A, 0x1C93, 0x1CAC, 0x1CC3, 0x1CDA, 0x1CEF, 0x1D03, 0x1D16, 0x1D28, + 0x1D37, 0x1D45, 0x1D52, 0x1D5C, 0x1D64, 0x1D6A, 0x1D6E, 0x1D6F, 0x1D6E, + 0x1D6A, 0x1D64, 0x1D5C, 0x1D52, 0x1D45, 0x1D37, 0x1D28, 0x1D16, 0x1D03, + 0x1CEF, 0x1CDA, 0x1CC3, 0x1CAC, 0x1C93, 0x1C7A, 0x1C61, 0x1C47, 0x1C2C, + 0x1C11, 0x1BF6, 0x1BDC, 0x1BC1, 0x1BA6, 0x1B8C, 0x1B72, 0x1B59, 0x1B41, + 0x1B2A, 0x1B13, 0x1AFE, 0x1AE9, 0x1AD7, 0x1AC5, 0x1AB5, 0x1AA7, 0x1A9B, + 0x1A91, 0x1A89, 0x1A83, 0x1A7F, 0xA99A, 0xA99A, 0xA99A, 0xA99A, 0xA99A, + 0xA99A, 0xA99A, 0xA999, 0xA999, 0xA999, 0xA998, 0xA998, 0xA997, 0xA997, + 0xA996, 0xA996, 0xA995, 0xA995, 0xA994, 0xA994, 0xA993, 0xA993, 0xA992, + 0xA992, 0xA991, 0xA991, 0xA990, 0xA990, 0xA98F, 0xA98F, 0xA98E, 0xA98E, + 0xA98D, 0xA98D, 0xA98C, 0xA98C, 0xA98C, 0xA98C, 0xA98B, 0xA98B, 0xA98B, + 0xA98B, 0xA98B, 0xA98B, 0xA98B, 0xA98B, 0xA98B, 0xA98C, 0xA98C, 0xA98C, + 0xA98C, 0xA98D, 0xA98D, 0xA98E, 0xA98E, 0xA98F, 0xA98F, 0xA990, 0xA990, + 0xA991, 0xA991, 0xA992, 0xA992, 0xA993, 0xA993, 0xA994, 0xA994, 0xA995, + 0xA995, 0xA996, 0xA996, 0xA997, 0xA997, 0xA998, 0xA998, 0xA999, 0xA999, + 0xA999, 0xA99A, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, + 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, + 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, + 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xD584, 0x20F5, 0x0D6D, + 0xDAD7, 0xFFFF, 0x0000, 0xBF5E, 0xE6B9, 0xE6B9, 0xE6B8, 0xE6B7, 0xE6B6, + 0xE6B4, 0xE6B2, 0xE6B0, 0xE6AE, 0xE6AB, 0xE6A8, 0xE6A5, 0xE6A2, 0xE69E, + 0xE69A, 0xE697, 0xE693, 0xE68F, 0xE68B, 0xE687, 0xE683, 0xE67E, 0xE67A, + 0xE676, 0xE672, 0xE66E, 0xE66A, 0xE666, 0xE662, 0xE65F, 0xE65B, 0xE658, + 0xE655, 0xE652, 0xE64F, 0xE64D, 0xE64A, 0xE649, 0xE647, 0xE646, 0xE645, + 0xE644, 0xE644, 0xE644, 0xE645, 0xE646, 0xE647, 0xE649, 0xE64A, 0xE64D, + 0xE64F, 0xE652, 0xE655, 0xE658, 0xE65B, 0xE65F, 0xE662, 0xE666, 0xE66A, + 0xE66E, 0xE672, 0xE676, 0xE67A, 0xE67E, 0xE683, 0xE687, 0xE68B, 0xE68F, + 0xE693, 0xE697, 0xE69A, 0xE69E, 0xE6A2, 0xE6A5, 0xE6A8, 0xE6AB, 0xE6AE, + 0xE6B0, 0xE6B2, 0xE6B4, 0xE6B6, 0xE6B7, 0xE6B8, 0xE6B9, 0xED8D, 0xED8A, + 0xED83, 0xED78, 0xED68, 0xED55, 0xED3E, 0xED23, 0xED05, 0xECE4, 0xECC0, + 0xEC9A, 0xEC71, 0xEC46, 0xEC1A, 0xEBEC, 0xEBBC, 0xEB8B, 0xEB5A, 0xEB27, + 0xEAF4, 0xEAC1, 0xEA8E, 0xEA5B, 0xEA29, 0xE9F7, 0xE9C7, 0xE997, 0xE969, + 0xE93C, 0xE911, 0xE8E9, 0xE8C3, 0xE89F, 0xE87E, 0xE860, 0xE845, 0xE82E, + 0xE81A, 0xE80B, 0xE7FF, 0xE7F8, 0xE7F6, 0xE7F8, 0xE7FF, 0xE80B, 0xE81A, + 0xE82E, 0xE845, 0xE860, 0xE87E, 0xE89F, 0xE8C3, 0xE8E9, 0xE911, 0xE93C, + 0xE969, 0xE997, 0xE9C7, 0xE9F7, 0xEA29, 0xEA5B, 0xEA8E, 0xEAC1, 0xEAF4, + 0xEB27, 0xEB5A, 0xEB8B, 0xEBBC, 0xEBEC, 0xEC1A, 0xEC46, 0xEC71, 0xEC9A, + 0xECC0, 0xECE4, 0xED05, 0xED23, 0xED3D, 0xED55, 0xED68, 0xED78, 0xED83, + 0xED8A, 0xC09C, 0xC09A, 0xC095, 0xC08C, 0xC081, 0xC072, 0xC061, 0xC04D, + 0xC036, 0xC01D, 0xC003, 0xBFE6, 0xBFC7, 0xBFA7, 0xBF86, 0xBF63, 0xBF40, + 0xBF1B, 0xBEF6, 0xBED0, 0xBEAA, 0xBE84, 0xBE5E, 0xBE38, 0xBE12, 0xBDED, + 0xBDC8, 0xBDA5, 0xBD82, 0xBD61, 0xBD41, 0xBD22, 0xBD06, 0xBCEB, 0xBCD2, + 0xBCBC, 0xBCA8, 0xBC96, 0xBC88, 0xBC7C, 0xBC73, 0xBC6E, 0xBC6C, 0xBC6E, + 0xBC73, 0xBC7C, 0xBC88, 0xBC96, 0xBCA8, 0xBCBC, 0xBCD2, 0xBCEB, 0xBD06, + 0xBD22, 0xBD41, 0xBD61, 0xBD82, 0xBDA5, 0xBDC8, 0xBDED, 0xBE12, 0xBE38, + 0xBE5E, 0xBE84, 0xBEAA, 0xBED0, 0xBEF6, 0xBF1B, 0xBF40, 0xBF63, 0xBF86, + 0xBFA7, 0xBFC7, 0xBFE6, 0xC003, 0xC01D, 0xC036, 0xC04D, 0xC061, 0xC072, + 0xC081, 0xC08C, 0xC095, 0xC09A, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, + 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, + 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, + 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, + 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, + 0x0002, 0x0006, 0x000D, 0x0017, 0x0024, 0x0033, 0x0044, 0x0057, 0x006D, + 0x0084, 0x009C, 0x00B6, 0x00D2, 0x00EE, 0x010C, 0x012B, 0x014A, 0x016A, + 0x018A, 0x01AB, 0x01CC, 0x01ED, 0x020D, 0x022E, 0x024E, 0x026D, 0x028C, + 0x02A9, 0x02C6, 0x02E1, 0x02FC, 0x0314, 0x032B, 0x0340, 0x0354, 0x0365, + 0x0374, 0x0380, 0x038A, 0x0392, 0x0396, 0x0398, 0x0396, 0x0392, 0x038A, + 0x0380, 0x0374, 0x0365, 0x0354, 0x0340, 0x032B, 0x0314, 0x02FC, 0x02E1, + 0x02C6, 0x02A9, 0x028C, 0x026D, 0x024E, 0x022E, 0x020D, 0x01ED, 0x01CC, + 0x01AB, 0x018A, 0x016A, 0x014A, 0x012B, 0x010C, 0x00EE, 0x00D2, 0x00B6, + 0x009C, 0x0084, 0x006D, 0x0057, 0x0044, 0x0033, 0x0024, 0x0017, 0x000D, + 0x0006, 0x0002, 0xEE35, 0xEE34, 0xEE34, 0xEE34, 0xEE33, 0xEE33, 0xEE32, + 0xEE31, 0xEE30, 0xEE2F, 0xEE2E, 0xEE2D, 0xEE2C, 0xEE2A, 0xEE29, 0xEE27, + 0xEE26, 0xEE24, 0xEE23, 0xEE21, 0xEE1F, 0xEE1E, 0xEE1C, 0xEE1A, 0xEE19, + 0xEE17, 0xEE16, 0xEE14, 0xEE13, 0xEE11, 0xEE10, 0xEE0F, 0xEE0D, 0xEE0C, + 0xEE0B, 0xEE0A, 0xEE09, 0xEE09, 0xEE08, 0xEE08, 0xEE07, 0xEE07, 0xEE07, + 0xEE07, 0xEE07, 0xEE08, 0xEE08, 0xEE09, 0xEE09, 0xEE0A, 0xEE0B, 0xEE0C, + 0xEE0D, 0xEE0F, 0xEE10, 0xEE11, 0xEE13, 0xEE14, 0xEE16, 0xEE17, 0xEE19, + 0xEE1A, 0xEE1C, 0xEE1E, 0xEE1F, 0xEE21, 0xEE23, 0xEE24, 0xEE26, 0xEE27, + 0xEE29, 0xEE2A, 0xEE2C, 0xEE2D, 0xEE2E, 0xEE2F, 0xEE30, 0xEE31, 0xEE32, + 0xEE33, 0xEE33, 0xEE34, 0xFB94, 0xFB94, 0xFB97, 0xFB9C, 0xFBA2, 0xFBA9, + 0xFBB2, 0xFBBD, 0xFBC9, 0xFBD5, 0xFBE3, 0xFBF2, 0xFC02, 0xFC13, 0xFC24, + 0xFC36, 0xFC49, 0xFC5C, 0xFC6F, 0xFC83, 0xFC97, 0xFCAB, 0xFCBF, 0xFCD3, + 0xFCE6, 0xFCFA, 0xFD0D, 0xFD1F, 0xFD31, 0xFD43, 0xFD53, 0xFD63, 0xFD72, + 0xFD80, 0xFD8D, 0xFD99, 0xFDA3, 0xFDAC, 0xFDB4, 0xFDBA, 0xFDBE, 0xFDC1, + 0xFDC2, 0xFDC1, 0xFDBE, 0xFDBA, 0xFDB4, 0xFDAC, 0xFDA3, 0xFD99, 0xFD8D, + 0xFD80, 0xFD72, 0xFD63, 0xFD53, 0xFD43, 0xFD31, 0xFD1F, 0xFD0D, 0xFCFA, + 0xFCE6, 0xFCD3, 0xFCBF, 0xFCAB, 0xFC97, 0xFC83, 0xFC6F, 0xFC5C, 0xFC49, + 0xFC36, 0xFC24, 0xFC13, 0xFC02, 0xFBF2, 0xFBE3, 0xFBD5, 0xFBC9, 0xFBBD, + 0xFBB2, 0xFBA9, 0xFBA2, 0xFB9C, 0xFB97, 0xFB94, 0xDC44, 0xDC46, 0xDC4A, + 0xDC51, 0xDC5A, 0xDC66, 0xDC74, 0xDC84, 0xDC96, 0xDCAA, 0xDCC0, 0xDCD7, + 0xDCEF, 0xDD09, 0xDD24, 0xDD40, 0xDD5C, 0xDD7A, 0xDD98, 0xDDB6, 0xDDD5, + 0xDDF3, 0xDE12, 0xDE31, 0xDE4F, 0xDE6D, 0xDE8A, 0xDEA7, 0xDEC3, 0xDEDE, + 0xDEF7, 0xDF10, 0xDF27, 0xDF3D, 0xDF50, 0xDF62, 0xDF73, 0xDF81, 0xDF8C, + 0xDF96, 0xDF9D, 0xDFA1, 0xDFA2, 0xDFA1, 0xDF9D, 0xDF96, 0xDF8C, 0xDF81, + 0xDF73, 0xDF62, 0xDF50, 0xDF3D, 0xDF27, 0xDF10, 0xDEF7, 0xDEDE, 0xDEC3, + 0xDEA7, 0xDE8A, 0xDE6D, 0xDE4F, 0xDE31, 0xDE12, 0xDDF3, 0xDDD5, 0xDDB6, + 0xDD98, 0xDD7A, 0xDD5C, 0xDD40, 0xDD24, 0xDD09, 0xDCEF, 0xDCD7, 0xDCC0, + 0xDCAA, 0xDC96, 0xDC84, 0xDC74, 0xDC66, 0xDC5A, 0xDC51, 0xDC4A, 0xDC46, + 0xFFFF, 0x0000, 0xBF5E, 0x08EE, 0x08EE, 0x08EF, 0x08F0, 0x08F1, 0x08F2, + 0x08F4, 0x08F5, 0x08F7, 0x08FA, 0x08FC, 0x08FF, 0x0901, 0x0904, 0x0907, + 0x090A, 0x090D, 0x0911, 0x0914, 0x0917, 0x091B, 0x091E, 0x0922, 0x0925, + 0x0928, 0x092C, 0x092F, 0x0932, 0x0935, 0x0938, 0x093B, 0x093E, 0x0940, + 0x0943, 0x0945, 0x0947, 0x0949, 0x094A, 0x094C, 0x094D, 0x094D, 0x094E, + 0x094E, 0x094E, 0x094D, 0x094D, 0x094C, 0x094A, 0x0949, 0x0947, 0x0945, + 0x0943, 0x0940, 0x093E, 0x093B, 0x0938, 0x0935, 0x0932, 0x092F, 0x092C, + 0x0928, 0x0925, 0x0922, 0x091E, 0x091B, 0x0917, 0x0914, 0x0911, 0x090D, + 0x090A, 0x0907, 0x0904, 0x0901, 0x08FF, 0x08FC, 0x08FA, 0x08F7, 0x08F5, + 0x08F4, 0x08F2, 0x08F1, 0x08F0, 0x08EF, 0x08EE, 0x049F, 0x049D, 0x0498, + 0x0490, 0x0485, 0x0477, 0x0467, 0x0454, 0x043E, 0x0427, 0x040D, 0x03F2, + 0x03D5, 0x03B7, 0x0397, 0x0376, 0x0354, 0x0332, 0x030E, 0x02EA, 0x02C6, + 0x02A2, 0x027E, 0x0259, 0x0236, 0x0212, 0x01EF, 0x01CE, 0x01AD, 0x018D, + 0x016F, 0x0152, 0x0136, 0x011D, 0x0106, 0x00F0, 0x00DD, 0x00CD, 0x00BF, + 0x00B4, 0x00AB, 0x00A6, 0x00A5, 0x00A6, 0x00AB, 0x00B4, 0x00BF, 0x00CD, + 0x00DD, 0x00F0, 0x0106, 0x011D, 0x0136, 0x0152, 0x016F, 0x018D, 0x01AD, + 0x01CE, 0x01EF, 0x0212, 0x0236, 0x0259, 0x027E, 0x02A2, 0x02C6, 0x02EA, + 0x030E, 0x0332, 0x0354, 0x0376, 0x0397, 0x03B7, 0x03D5, 0x03F2, 0x040D, + 0x0427, 0x043E, 0x0454, 0x0467, 0x0477, 0x0485, 0x0490, 0x0498, 0x049D, + 0xACD4, 0xACD2, 0xACCB, 0xACC0, 0xACB0, 0xAC9D, 0xAC86, 0xAC6C, 0xAC4F, + 0xAC2E, 0xAC0B, 0xABE6, 0xABBE, 0xAB94, 0xAB68, 0xAB3B, 0xAB0C, 0xAADC, + 0xAAAB, 0xAA7A, 0xAA48, 0xAA16, 0xA9E3, 0xA9B2, 0xA980, 0xA94F, 0xA91F, + 0xA8F1, 0xA8C3, 0xA898, 0xA86E, 0xA846, 0xA820, 0xA7FD, 0xA7DD, 0xA7BF, + 0xA7A5, 0xA78E, 0xA77B, 0xA76C, 0xA760, 0xA759, 0xA757, 0xA759, 0xA760, + 0xA76C, 0xA77B, 0xA78E, 0xA7A5, 0xA7BF, 0xA7DD, 0xA7FD, 0xA820, 0xA846, + 0xA86E, 0xA898, 0xA8C3, 0xA8F1, 0xA91F, 0xA94F, 0xA980, 0xA9B2, 0xA9E3, + 0xAA16, 0xAA48, 0xAA7A, 0xAAAB, 0xAADC, 0xAB0C, 0xAB3B, 0xAB68, 0xAB94, + 0xABBE, 0xABE6, 0xAC0B, 0xAC2E, 0xAC4F, 0xAC6C, 0xAC86, 0xAC9D, 0xACB0, + 0xACC0, 0xACCB, 0xACD2, 0x0000, 0x0000, 0x0002, 0x0003, 0x0006, 0x0009, + 0x000D, 0x0012, 0x0017, 0x001C, 0x0022, 0x0029, 0x002F, 0x0036, 0x003E, + 0x0046, 0x004E, 0x0056, 0x005E, 0x0066, 0x006F, 0x0077, 0x0080, 0x0088, + 0x0091, 0x0099, 0x00A1, 0x00A9, 0x00B1, 0x00B8, 0x00BF, 0x00C6, 0x00CD, + 0x00D3, 0x00D8, 0x00DD, 0x00E1, 0x00E5, 0x00E9, 0x00EB, 0x00ED, 0x00EE, + 0x00EF, 0x00EE, 0x00ED, 0x00EB, 0x00E9, 0x00E5, 0x00E1, 0x00DD, 0x00D8, + 0x00D3, 0x00CD, 0x00C6, 0x00BF, 0x00B8, 0x00B1, 0x00A9, 0x00A1, 0x0099, + 0x0091, 0x0088, 0x0080, 0x0077, 0x006F, 0x0066, 0x005E, 0x0056, 0x004E, + 0x0046, 0x003E, 0x0036, 0x002F, 0x0029, 0x0022, 0x001C, 0x0017, 0x0012, + 0x000D, 0x0009, 0x0006, 0x0003, 0x0002, 0x0000, 0xFFFF, 0x0001, 0x0003, + 0x0007, 0x000C, 0x0012, 0x001A, 0x0023, 0x002D, 0x0038, 0x0043, 0x0050, + 0x005E, 0x006C, 0x007A, 0x008A, 0x0099, 0x00A9, 0x00BA, 0x00CA, 0x00DB, + 0x00EC, 0x00FD, 0x010D, 0x011E, 0x012E, 0x013F, 0x014E, 0x015D, 0x016C, + 0x017A, 0x0188, 0x0194, 0x01A0, 0x01AB, 0x01B5, 0x01BE, 0x01C5, 0x01CC, + 0x01D1, 0x01D5, 0x01D7, 0x01D8, 0x01D7, 0x01D5, 0x01D1, 0x01CC, 0x01C5, + 0x01BE, 0x01B5, 0x01AB, 0x01A0, 0x0194, 0x0188, 0x017A, 0x016C, 0x015D, + 0x014E, 0x013F, 0x012E, 0x011E, 0x010D, 0x00FD, 0x00EC, 0x00DB, 0x00CA, + 0x00BA, 0x00A9, 0x0099, 0x008A, 0x007A, 0x006C, 0x005E, 0x0050, 0x0043, + 0x0038, 0x002D, 0x0023, 0x001A, 0x0012, 0x000C, 0x0007, 0x0003, 0x0001, + 0x25EE, 0x25F1, 0x25FB, 0x260C, 0x2623, 0x263F, 0x2661, 0x2687, 0x26B3, + 0x26E3, 0x2716, 0x274E, 0x2789, 0x27C7, 0x2807, 0x284A, 0x288F, 0x28D6, + 0x291E, 0x2967, 0x29B1, 0x29FB, 0x2A45, 0x2A8E, 0x2AD7, 0x2B1F, 0x2B66, + 0x2BAB, 0x2BEE, 0x2C2E, 0x2C6C, 0x2CA7, 0x2CDF, 0x2D12, 0x2D42, 0x2D6E, + 0x2D94, 0x2DB6, 0x2DD2, 0x2DE9, 0x2DFA, 0x2E04, 0x2E07, 0x2E04, 0x2DFA, + 0x2DE9, 0x2DD2, 0x2DB6, 0x2D94, 0x2D6E, 0x2D42, 0x2D12, 0x2CDF, 0x2CA7, + 0x2C6C, 0x2C2E, 0x2BEE, 0x2BAB, 0x2B66, 0x2B1F, 0x2AD7, 0x2A8E, 0x2A45, + 0x29FB, 0x29B1, 0x2967, 0x291E, 0x28D6, 0x288F, 0x284A, 0x2807, 0x27C7, + 0x2789, 0x274E, 0x2716, 0x26E3, 0x26B3, 0x2687, 0x2661, 0x263F, 0x2623, + 0x260C, 0x25FB, 0x25F1, 0x0047, 0x0046, 0x0043, 0x003D, 0x0036, 0x002D, + 0x0022, 0x0016, 0x0008, 0xFFF8, 0xFFE7, 0xFFD6, 0xFFC3, 0xFFAF, 0xFF9B, + 0xFF85, 0xFF6F, 0xFF59, 0xFF42, 0xFF2B, 0xFF13, 0xFEFC, 0xFEE4, 0xFECD, + 0xFEB5, 0xFE9E, 0xFE88, 0xFE72, 0xFE5D, 0xFE48, 0xFE34, 0xFE22, 0xFE10, + 0xFDFF, 0xFDF0, 0xFDE2, 0xFDD6, 0xFDCB, 0xFDC2, 0xFDBB, 0xFDB6, 0xFDB3, + 0xFDB1, 0xFDB3, 0xFDB6, 0xFDBB, 0xFDC2, 0xFDCB, 0xFDD6, 0xFDE2, 0xFDF0, + 0xFDFF, 0xFE10, 0xFE22, 0xFE34, 0xFE48, 0xFE5D, 0xFE72, 0xFE88, 0xFE9E, + 0xFEB5, 0xFECD, 0xFEE4, 0xFEFC, 0xFF13, 0xFF2B, 0xFF42, 0xFF59, 0xFF6F, + 0xFF85, 0xFF9B, 0xFFAF, 0xFFC3, 0xFFD6, 0xFFE7, 0xFFF8, 0x0008, 0x0016, + 0x0022, 0x002D, 0x0036, 0x003D, 0x0043, 0x0046, 0xFF3B, 0xFF3C, 0xFF3D, + 0xFF40, 0xFF43, 0xFF47, 0xFF4C, 0xFF51, 0xFF58, 0xFF5E, 0xFF66, 0xFF6E, + 0xFF76, 0xFF7F, 0xFF88, 0xFF92, 0xFF9B, 0xFFA5, 0xFFB0, 0xFFBA, 0xFFC5, + 0xFFCF, 0xFFDA, 0xFFE4, 0xFFEF, 0xFFF9, 0x0004, 0x000E, 0x0017, 0x0020, + 0x0029, 0x0032, 0x003A, 0x0041, 0x0048, 0x004E, 0x0053, 0x0058, 0x005C, + 0x005F, 0x0062, 0x0063, 0x0064, 0x0063, 0x0062, 0x005F, 0x005C, 0x0058, + 0x0053, 0x004E, 0x0048, 0x0041, 0x003A, 0x0032, 0x0029, 0x0020, 0x0017, + 0x000E, 0x0004, 0xFFF9, 0xFFEF, 0xFFE4, 0xFFDA, 0xFFCF, 0xFFC5, 0xFFBA, + 0xFFB0, 0xFFA5, 0xFF9B, 0xFF92, 0xFF88, 0xFF7F, 0xFF76, 0xFF6E, 0xFF66, + 0xFF5E, 0xFF58, 0xFF51, 0xFF4C, 0xFF47, 0xFF43, 0xFF40, 0xFF3D, 0xFF3C, + 0xBBA8, 0xBBA7, 0xBBA2, 0xBB9A, 0xBB90, 0xBB82, 0xBB72, 0xBB60, 0xBB4C, + 0xBB35, 0xBB1D, 0xBB02, 0xBAE7, 0xBAC9, 0xBAAB, 0xBA8B, 0xBA6B, 0xBA49, + 0xBA27, 0xBA05, 0xB9E2, 0xB9BF, 0xB99C, 0xB97A, 0xB957, 0xB935, 0xB914, + 0xB8F3, 0xB8D4, 0xB8B5, 0xB898, 0xB87C, 0xB862, 0xB84A, 0xB833, 0xB81F, + 0xB80C, 0xB7FD, 0xB7EF, 0xB7E4, 0xB7DD, 0xB7D8, 0xB7D6, 0xB7D8, 0xB7DD, + 0xB7E4, 0xB7EF, 0xB7FD, 0xB80C, 0xB81F, 0xB833, 0xB84A, 0xB862, 0xB87C, + 0xB898, 0xB8B5, 0xB8D4, 0xB8F3, 0xB914, 0xB935, 0xB957, 0xB97A, 0xB99C, + 0xB9BF, 0xB9E2, 0xBA05, 0xBA27, 0xBA49, 0xBA6B, 0xBA8B, 0xBAAB, 0xBAC9, + 0xBAE7, 0xBB02, 0xBB1D, 0xBB35, 0xBB4C, 0xBB60, 0xBB72, 0xBB82, 0xBB90, + 0xBB9A, 0xBBA2, 0xBBA7, + },{ + 0x004D, 0x0000, 0x0053, 0x004D, 0x0051, 0x00A0, 0x0001, 0x00F1, 0x0001, + 0x00F2, 0x0001, 0x00F3, 0x0001, 0x00F4, 0x0001, 0x00F5, 0x0001, 0x00F6, + 0x0052, 0x00F7, 0x0054, 0x0149, 0x0054, 0x019D, 0x0054, 0x01F1, 0x0054, + 0x0245, 0x0054, 0x0299, 0x0001, 0x02ED, 0x0001, 0x02EE, 0x0001, 0x02EF, + 0x0054, 0x02F0, 0x0053, 0x0344, 0x0054, 0x0397, 0x0054, 0x03EB, 0x0054, + 0x043F, 0x0054, 0x0493, 0x0054, 0x04E7, 0x0054, 0x053B, 0x0054, 0x058F, + 0x0001, 0x05E3, 0x0001, 0x05E4, 0x0001, 0x05E5, 0x0054, 0x05E6, 0x0054, + 0x063A, 0x004F, 0x068E, 0x004F, 0x06DD, 0x004E, 0x072C, 0x0001, 0x077A, + 0x0001, 0x077B, 0x0001, 0x077C, 0x0001, 0x077D, 0x0001, 0x077E, 0x0001, + 0x077F, 0x0001, 0x0780, 0x0054, 0x0781, 0x0054, 0x07D5, 0x0054, 0x0829, + 0x0054, 0x087D, 0x0052, 0x08D1, 0x0054, 0x0923, 0x0052, 0x0977, 0x0054, + 0x09C9, 0x0054, 0x0A1D, 0x0001, 0x0A71, 0x0001, 0x0A72, 0x0001, 0x0A73, + 0x0054, 0x0A74, 0x0054, 0x0AC8, 0x0054, 0x0B1C, 0x0054, 0x0B70, 0x0054, + 0x0BC4, 0x0054, 0x0C18, 0x0054, 0x0C6C, 0x0054, 0x0CC0, 0x0054, 0x0D14, +}) + +LUIGI_ANIM_CS_MENU = "luigi_anim_cs_menu" +smlua_anim_util_register_animation(LUIGI_ANIM_CS_MENU, + 0, + 0, + 0, + 0, + 41, + { + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, + 0xFFFE, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFC, 0xFFFC, 0xFFFB, 0xFFFB, 0xFFFB, + 0xFFFB, 0xFFFA, 0xFFFA, 0xFFFA, 0xFFFA, 0xFFFA, 0xFFFB, 0xFFFB, 0xFFFB, + 0xFFFB, 0xFFFC, 0xFFFC, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFE, 0xFFFE, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0093, 0x0093, 0x0093, 0x0093, 0x0092, + 0x0092, 0x0091, 0x0091, 0x0090, 0x0090, 0x008F, 0x008E, 0x008E, 0x008D, + 0x008C, 0x008C, 0x008B, 0x008B, 0x008A, 0x008A, 0x008A, 0x008A, 0x008A, + 0x008A, 0x008A, 0x008B, 0x008B, 0x008C, 0x008C, 0x008D, 0x008E, 0x008E, + 0x008F, 0x0090, 0x0090, 0x0091, 0x0091, 0x0092, 0x0092, 0x0093, 0x0000, + 0x0000, 0x3FFF, 0x0000, 0xE332, 0x0F58, 0x5092, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, + 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, + 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, + 0xF904, 0xF8FA, 0xF8DE, 0xF8B2, 0xF877, 0xF830, 0xF7DE, 0xF784, 0xF723, + 0xF6BD, 0xF654, 0xF5EA, 0xF581, 0xF51B, 0xF4BA, 0xF460, 0xF40E, 0xF3C7, + 0xF38C, 0xF360, 0xF344, 0xF33A, 0xF344, 0xF360, 0xF38C, 0xF3C7, 0xF40E, + 0xF460, 0xF4BA, 0xF51B, 0xF581, 0xF5EA, 0xF654, 0xF6BD, 0xF723, 0xF784, + 0xF7DE, 0xF830, 0xF877, 0xF8B2, 0xF8DE, 0xF8FA, 0x0000, 0xFFFF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, + 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, + 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, + 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, + 0x0000, 0xFFFF, 0x0000, 0xEEFC, 0xEF0E, 0xEF3F, 0xEF8E, 0xEFF7, 0xF076, + 0xF107, 0xF1A8, 0xF255, 0xF30A, 0xF3C5, 0xF481, 0xF53C, 0xF5F1, 0xF69E, + 0xF73F, 0xF7D1, 0xF850, 0xF8B8, 0xF907, 0xF939, 0xF94A, 0xF939, 0xF907, + 0xF8B8, 0xF850, 0xF7D1, 0xF73F, 0xF69E, 0xF5F1, 0xF53C, 0xF481, 0xF3C5, + 0xF30A, 0xF255, 0xF1A8, 0xF107, 0xF076, 0xEFF7, 0xEF8E, 0xEF3F, 0xEF0E, + 0x0000, 0xFFFF, 0xBFFF, 0xD4CC, 0xD4D5, 0xD4EE, 0xD514, 0xD548, 0xD586, + 0xD5CE, 0xD61D, 0xD672, 0xD6CB, 0xD727, 0xD784, 0xD7E0, 0xD839, 0xD88E, + 0xD8DD, 0xD925, 0xD963, 0xD997, 0xD9BD, 0xD9D6, 0xD9DE, 0xD9D6, 0xD9BD, + 0xD997, 0xD963, 0xD925, 0xD8DD, 0xD88E, 0xD839, 0xD7E0, 0xD784, 0xD727, + 0xD6CB, 0xD672, 0xD61D, 0xD5CE, 0xD586, 0xD548, 0xD514, 0xD4EE, 0xD4D5, + 0xD877, 0xD86F, 0xD858, 0xD834, 0xD804, 0xD7C9, 0xD786, 0xD73C, 0xD6ED, + 0xD699, 0xD644, 0xD5ED, 0xD597, 0xD544, 0xD4F4, 0xD4AA, 0xD467, 0xD42D, + 0xD3FD, 0xD3D9, 0xD3C2, 0xD3BA, 0xD3C2, 0xD3D9, 0xD3FD, 0xD42D, 0xD467, + 0xD4AA, 0xD4F4, 0xD544, 0xD597, 0xD5ED, 0xD644, 0xD699, 0xD6ED, 0xD73C, + 0xD786, 0xD7C9, 0xD804, 0xD834, 0xD858, 0xD86F, 0xE45A, 0xE450, 0xE433, + 0xE406, 0xE3CA, 0xE381, 0xE32E, 0xE2D2, 0xE26E, 0xE206, 0xE19B, 0xE130, + 0xE0C5, 0xE05D, 0xDFF9, 0xDF9D, 0xDF4A, 0xDF01, 0xDEC5, 0xDE98, 0xDE7B, + 0xDE71, 0xDE7B, 0xDE98, 0xDEC5, 0xDF01, 0xDF4A, 0xDF9D, 0xDFF9, 0xE05D, + 0xE0C5, 0xE130, 0xE19B, 0xE206, 0xE26E, 0xE2D2, 0xE32E, 0xE381, 0xE3CA, + 0xE406, 0xE433, 0xE450, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, + 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFF8, 0xFFE3, + 0xFFC1, 0xFF94, 0xFF5B, 0xFF19, 0xFECE, 0xFE7B, 0xFE21, 0xFDC2, 0xFD5D, + 0xFCF5, 0xFC89, 0xFC1C, 0xFBAE, 0xFB3F, 0xFAD2, 0xFA66, 0xF9FE, 0xF999, + 0xF93A, 0xF8E0, 0xF88D, 0xF842, 0xF800, 0xF7C8, 0xF79A, 0xF778, 0xF763, + 0xF75C, 0xF788, 0xF800, 0xF8B6, 0xF999, 0xFA9C, 0xFBAE, 0xFCBF, 0xFDC2, + 0xFEA6, 0xFF5B, 0xFFD4, 0xDA3F, 0xDA47, 0xDA5D, 0xDA81, 0xDAB2, 0xDAEE, + 0xDB34, 0xDB84, 0xDBDC, 0xDC3B, 0xDCA1, 0xDD0C, 0xDD7B, 0xDDED, 0xDE62, + 0xDED7, 0xDF4D, 0xDFC1, 0xE033, 0xE0A2, 0xE10D, 0xE173, 0xE1D3, 0xE22B, + 0xE27B, 0xE2C1, 0xE2FD, 0xE32D, 0xE351, 0xE367, 0xE36F, 0xE341, 0xE2C1, + 0xE200, 0xE10D, 0xDFFB, 0xDED7, 0xDDB4, 0xDCA1, 0xDBAF, 0xDAEE, 0xDA6E, + 0xE991, 0xE999, 0xE9B0, 0xE9D6, 0xEA09, 0xEA48, 0xEA92, 0xEAE6, 0xEB43, + 0xEBA8, 0xEC13, 0xEC84, 0xECF9, 0xED71, 0xEDEC, 0xEE68, 0xEEE3, 0xEF5E, + 0xEFD6, 0xF04B, 0xF0BC, 0xF127, 0xF18C, 0xF1E9, 0xF23D, 0xF287, 0xF2C6, + 0xF2F9, 0xF31F, 0xF336, 0xF33E, 0xF30E, 0xF287, 0xF1BB, 0xF0BC, 0xEF9A, + 0xEE68, 0xED35, 0xEC13, 0xEB14, 0xEA48, 0xE9C1, 0xFD43, 0xFD39, 0xFD1D, + 0xFCF0, 0xFCB3, 0xFC67, 0xFC0F, 0xFBAA, 0xFB3B, 0xFAC3, 0xFA43, 0xF9BC, + 0xF930, 0xF8A0, 0xF80D, 0xF779, 0xF6E5, 0xF652, 0xF5C2, 0xF536, 0xF4B0, + 0xF42F, 0xF3B7, 0xF348, 0xF2E3, 0xF28B, 0xF23F, 0xF202, 0xF1D5, 0xF1B9, + 0xF1AF, 0xF1E9, 0xF28B, 0xF37E, 0xF4B0, 0xF60A, 0xF779, 0xF8E8, 0xFA43, + 0xFB74, 0xFC67, 0xFD09, 0x0000, 0xFFFF, 0xBFFF, 0xF0C9, 0xF0DC, 0xF115, + 0xF16D, 0xF1E3, 0xF272, 0xF316, 0xF3CB, 0xF48E, 0xF55A, 0xF62C, 0xF700, + 0xF7D3, 0xF89F, 0xF962, 0xFA17, 0xFABB, 0xFB4A, 0xFBBF, 0xFC18, 0xFC50, + 0xFC64, 0xFC50, 0xFC18, 0xFBBF, 0xFB4A, 0xFABB, 0xFA17, 0xF962, 0xF89F, + 0xF7D3, 0xF700, 0xF62C, 0xF55A, 0xF48E, 0xF3CB, 0xF316, 0xF272, 0xF1E3, + 0xF16D, 0xF115, 0xF0DC, 0x1465, 0x1460, 0x1453, 0x143D, 0x1421, 0x13FF, + 0x13D7, 0x13AB, 0x137C, 0x134B, 0x1318, 0x12E5, 0x12B2, 0x1281, 0x1252, + 0x1226, 0x11FF, 0x11DC, 0x11C0, 0x11AA, 0x119D, 0x1198, 0x119D, 0x11AA, + 0x11C0, 0x11DC, 0x11FF, 0x1226, 0x1252, 0x1281, 0x12B2, 0x12E5, 0x1318, + 0x134B, 0x137C, 0x13AB, 0x13D7, 0x13FF, 0x1421, 0x143D, 0x1453, 0x1460, + 0x5DB3, 0x5DC7, 0x5DFF, 0x5E58, 0x5ECE, 0x5F5C, 0x6000, 0x60B5, 0x6178, + 0x6245, 0x6317, 0x63EB, 0x64BD, 0x6589, 0x664C, 0x6701, 0x67A5, 0x6834, + 0x68AA, 0x6903, 0x693B, 0x694E, 0x693B, 0x6903, 0x68AA, 0x6834, 0x67A5, + 0x6701, 0x664C, 0x6589, 0x64BD, 0x63EB, 0x6317, 0x6245, 0x6178, 0x60B6, + 0x6000, 0x5F5C, 0x5ECE, 0x5E58, 0x5DFF, 0x5DC7, 0xFFFF, 0x0000, 0xE171, + 0xE16F, 0xE16A, 0xE162, 0xE157, 0xE14A, 0xE13B, 0xE12B, 0xE119, 0xE106, + 0xE0F3, 0xE0E0, 0xE0CD, 0xE0BA, 0xE0A9, 0xE098, 0xE089, 0xE07C, 0xE072, + 0xE06A, 0xE064, 0xE063, 0xE064, 0xE06A, 0xE072, 0xE07C, 0xE089, 0xE098, + 0xE0A9, 0xE0BA, 0xE0CD, 0xE0E0, 0xE0F3, 0xE106, 0xE119, 0xE12B, 0xE13B, + 0xE14A, 0xE157, 0xE162, 0xE16A, 0xE16F, 0x0E24, 0x0E24, 0x0E24, 0x0E25, + 0x0E26, 0x0E27, 0x0E29, 0x0E2A, 0x0E2C, 0x0E2E, 0x0E30, 0x0E32, 0x0E33, + 0x0E35, 0x0E37, 0x0E39, 0x0E3A, 0x0E3B, 0x0E3C, 0x0E3D, 0x0E3E, 0x0E3E, + 0x0E3E, 0x0E3D, 0x0E3C, 0x0E3B, 0x0E3A, 0x0E39, 0x0E37, 0x0E35, 0x0E33, + 0x0E32, 0x0E30, 0x0E2E, 0x0E2C, 0x0E2A, 0x0E29, 0x0E27, 0x0E26, 0x0E25, + 0x0E24, 0x02BF, 0x02BE, 0x02B9, 0x02B2, 0x02A8, 0x029D, 0x028F, 0x0281, + 0x0271, 0x0260, 0x024F, 0x023E, 0x022D, 0x021D, 0x020D, 0x01FE, 0x01F1, + 0x01E6, 0x01DC, 0x01D5, 0x01D0, 0x01CF, 0x01D0, 0x01D5, 0x01DC, 0x01E6, + 0x01F1, 0x01FE, 0x020D, 0x021D, 0x022D, 0x023E, 0x024F, 0x0260, 0x0271, + 0x0281, 0x028F, 0x029D, 0x02A8, 0x02B2, 0x02B9, 0x02BE, 0xF6AE, 0xF6A1, + 0xF67C, 0xF641, 0xF5F4, 0xF596, 0xF52A, 0xF4B3, 0xF433, 0xF3AC, 0xF322, + 0xF297, 0xF20C, 0xF186, 0xF106, 0xF08F, 0xF023, 0xEFC5, 0xEF77, 0xEF3D, + 0xEF18, 0xEF0B, 0xEF18, 0xEF3D, 0xEF77, 0xEFC5, 0xF023, 0xF08F, 0xF106, + 0xF186, 0xF20C, 0xF297, 0xF322, 0xF3AC, 0xF433, 0xF4B3, 0xF52A, 0xF596, + 0xF5F4, 0xF641, 0xF67C, 0xF6A1, 0x0000, 0xFFFF, 0xBF5E, 0xB180, 0xB176, + 0xB15B, 0xB131, 0xB0F8, 0xB0B3, 0xB064, 0xB00D, 0xAFAF, 0xAF4D, 0xAEE8, + 0xAE82, 0xAE1D, 0xADBB, 0xAD5D, 0xAD06, 0xACB7, 0xAC72, 0xAC39, 0xAC0F, + 0xABF4, 0xABEA, 0xABF4, 0xAC0F, 0xAC39, 0xAC72, 0xACB7, 0xAD06, 0xAD5D, + 0xADBB, 0xAE1D, 0xAE82, 0xAEE8, 0xAF4D, 0xAFAF, 0xB00D, 0xB064, 0xB0B3, + 0xB0F8, 0xB131, 0xB15B, 0xB176, 0xE760, 0xE754, 0xE72F, 0xE6F5, 0xE6A8, + 0xE64B, 0xE5E0, 0xE56A, 0xE4EB, 0xE466, 0xE3DD, 0xE352, 0xE2C9, 0xE244, + 0xE1C5, 0xE14F, 0xE0E4, 0xE087, 0xE03A, 0xE000, 0xDFDC, 0xDFCF, 0xDFDC, + 0xE000, 0xE03A, 0xE087, 0xE0E4, 0xE14F, 0xE1C5, 0xE244, 0xE2C9, 0xE352, + 0xE3DD, 0xE466, 0xE4EB, 0xE56A, 0xE5E0, 0xE64B, 0xE6A8, 0xE6F5, 0xE72F, + 0xE754, 0xBA08, 0xBA12, 0xBA2F, 0xBA5D, 0xBA99, 0xBAE3, 0xBB38, 0xBB95, + 0xBBFA, 0xBC63, 0xBCD0, 0xBD3D, 0xBDAA, 0xBE13, 0xBE78, 0xBED5, 0xBF2A, + 0xBF74, 0xBFB1, 0xBFDE, 0xBFFB, 0xC006, 0xBFFB, 0xBFDE, 0xBFB1, 0xBF74, + 0xBF2A, 0xBED5, 0xBE78, 0xBE13, 0xBDAA, 0xBD3D, 0xBCD0, 0xBC63, 0xBBFA, + 0xBB95, 0xBB38, 0xBAE3, 0xBA99, 0xBA5D, 0xBA2F, 0xBA12, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, + 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0018, 0x005C, 0x00C7, 0x0156, + 0x0203, 0x02C9, 0x03A4, 0x0490, 0x0588, 0x0686, 0x0787, 0x0885, 0x097C, + 0x0A68, 0x0B44, 0x0C0A, 0x0CB7, 0x0D45, 0x0DB1, 0x0DF5, 0x0E0D, 0x0DF5, + 0x0DB1, 0x0D45, 0x0CB7, 0x0C0A, 0x0B44, 0x0A68, 0x097C, 0x0885, 0x0787, + 0x0686, 0x0588, 0x0490, 0x03A4, 0x02C9, 0x0203, 0x0156, 0x00C7, 0x005C, + 0x0018, 0xF9B8, 0xF9B8, 0xF9B8, 0xF9B9, 0xF9BA, 0xF9BB, 0xF9BC, 0xF9BD, + 0xF9BF, 0xF9C0, 0xF9C2, 0xF9C3, 0xF9C5, 0xF9C6, 0xF9C8, 0xF9C9, 0xF9CA, + 0xF9CB, 0xF9CC, 0xF9CD, 0xF9CD, 0xF9CD, 0xF9CD, 0xF9CD, 0xF9CC, 0xF9CB, + 0xF9CA, 0xF9C9, 0xF9C8, 0xF9C6, 0xF9C5, 0xF9C3, 0xF9C2, 0xF9C0, 0xF9BF, + 0xF9BD, 0xF9BC, 0xF9BB, 0xF9BA, 0xF9B9, 0xF9B8, 0x01DD, 0x01DA, 0x01D3, + 0x01C7, 0x01B8, 0x01A5, 0x0190, 0x0178, 0x015E, 0x0144, 0x0128, 0x010C, + 0x00F1, 0x00D6, 0x00BD, 0x00A5, 0x0090, 0x007D, 0x006E, 0x0062, 0x005B, + 0x0058, 0x005B, 0x0062, 0x006E, 0x007D, 0x0090, 0x00A5, 0x00BD, 0x00D6, + 0x00F1, 0x010C, 0x0128, 0x0144, 0x015E, 0x0178, 0x0190, 0x01A5, 0x01B8, + 0x01C7, 0x01D3, 0x01DA, 0xEA21, 0xEA19, 0xEA02, 0xE9DE, 0xE9AF, 0xE976, + 0xE934, 0xE8EB, 0xE89C, 0xE84A, 0xE7F6, 0xE7A0, 0xE74C, 0xE6FA, 0xE6AB, + 0xE663, 0xE621, 0xE5E7, 0xE5B8, 0xE594, 0xE57E, 0xE576, 0xE57E, 0xE594, + 0xE5B8, 0xE5E7, 0xE621, 0xE663, 0xE6AB, 0xE6FA, 0xE74C, 0xE7A0, 0xE7F6, + 0xE84A, 0xE89C, 0xE8EB, 0xE934, 0xE976, 0xE9AF, 0xE9DE, 0xEA02, 0xEA19, + 0x0000, 0xFFFF, 0xBF5E, 0x1644, 0x1641, 0x1639, 0x162D, 0x161D, 0x160A, + 0x15F4, 0x15DB, 0x15C1, 0x15A5, 0x1589, 0x156C, 0x1550, 0x1534, 0x151A, + 0x1501, 0x14EB, 0x14D8, 0x14C8, 0x14BC, 0x14B4, 0x14B2, 0x14B4, 0x14BC, + 0x14C8, 0x14D8, 0x14EB, 0x1501, 0x151A, 0x1534, 0x1550, 0x156C, 0x1589, + 0x15A5, 0x15C1, 0x15DB, 0x15F4, 0x160A, 0x161D, 0x162D, 0x1639, 0x1641, + 0x1617, 0x1619, 0x1621, 0x162C, 0x163B, 0x164D, 0x1662, 0x1679, 0x1692, + 0x16AD, 0x16C7, 0x16E3, 0x16FD, 0x1718, 0x1730, 0x1748, 0x175D, 0x176F, + 0x177E, 0x1789, 0x1791, 0x1793, 0x1791, 0x1789, 0x177E, 0x176F, 0x175D, + 0x1748, 0x1730, 0x1718, 0x16FD, 0x16E3, 0x16C7, 0x16AD, 0x1692, 0x1679, + 0x1662, 0x164D, 0x163B, 0x162C, 0x1621, 0x1619, 0x8DFE, 0x8DF9, 0x8DEC, + 0x8DD6, 0x8DB9, 0x8D96, 0x8D6F, 0x8D42, 0x8D13, 0x8CE1, 0x8CAE, 0x8C7A, + 0x8C47, 0x8C15, 0x8BE6, 0x8BBA, 0x8B92, 0x8B6F, 0x8B52, 0x8B3D, 0x8B2F, + 0x8B2A, 0x8B2F, 0x8B3D, 0x8B52, 0x8B6F, 0x8B92, 0x8BBA, 0x8BE6, 0x8C15, + 0x8C47, 0x8C7A, 0x8CAE, 0x8CE1, 0x8D13, 0x8D42, 0x8D6F, 0x8D96, 0x8DB9, + 0x8DD6, 0x8DEC, 0x8DF9, 0xFEDD, 0xFEDD, 0xFEDC, 0xFEDB, 0xFED9, 0xFED7, + 0xFED4, 0xFED2, 0xFECF, 0xFECC, 0xFEC9, 0xFEC5, 0xFEC2, 0xFEBF, 0xFEBC, + 0xFEBA, 0xFEB7, 0xFEB5, 0xFEB3, 0xFEB2, 0xFEB1, 0xFEB1, 0xFEB1, 0xFEB2, + 0xFEB3, 0xFEB5, 0xFEB7, 0xFEBA, 0xFEBC, 0xFEBF, 0xFEC2, 0xFEC5, 0xFEC9, + 0xFECC, 0xFECF, 0xFED2, 0xFED4, 0xFED7, 0xFED9, 0xFEDB, 0xFEDC, 0xFEDD, + 0x0204, 0x0204, 0x0203, 0x0201, 0x01FF, 0x01FC, 0x01FA, 0x01F6, 0x01F3, + 0x01EF, 0x01EB, 0x01E8, 0x01E4, 0x01E0, 0x01DD, 0x01DA, 0x01D7, 0x01D4, + 0x01D2, 0x01D0, 0x01CF, 0x01CF, 0x01CF, 0x01D0, 0x01D2, 0x01D4, 0x01D7, + 0x01DA, 0x01DD, 0x01E0, 0x01E4, 0x01E8, 0x01EB, 0x01EF, 0x01F3, 0x01F6, + 0x01FA, 0x01FC, 0x01FF, 0x0201, 0x0203, 0x0204, 0x3560, 0x356C, 0x3591, + 0x35CA, 0x3616, 0x3673, 0x36DD, 0x3752, 0x37D0, 0x3854, 0x38DC, 0x3966, + 0x39ED, 0x3A72, 0x3AF0, 0x3B65, 0x3BCF, 0x3C2B, 0x3C78, 0x3CB1, 0x3CD5, + 0x3CE2, 0x3CD5, 0x3CB1, 0x3C78, 0x3C2B, 0x3BCF, 0x3B65, 0x3AF0, 0x3A72, + 0x39ED, 0x3966, 0x38DC, 0x3854, 0x37D0, 0x3752, 0x36DD, 0x3673, 0x3616, + 0x35CA, 0x3591, 0x356C, 0x026C, 0x026C, 0x026A, 0x0268, 0x0265, 0x0261, + 0x025C, 0x0257, 0x0252, 0x024D, 0x0247, 0x0241, 0x023B, 0x0236, 0x0231, + 0x022C, 0x0227, 0x0223, 0x0220, 0x021E, 0x021C, 0x021C, 0x021C, 0x021E, + 0x0220, 0x0223, 0x0227, 0x022C, 0x0231, 0x0236, 0x023B, 0x0241, 0x0247, + 0x024D, 0x0252, 0x0257, 0x025C, 0x0261, 0x0265, 0x0268, 0x026A, 0x026C, + 0x00C0, 0x00C0, 0x00C1, 0x00C3, 0x00C6, 0x00CA, 0x00CD, 0x00D2, 0x00D6, + 0x00DB, 0x00E0, 0x00E5, 0x00EA, 0x00EE, 0x00F3, 0x00F7, 0x00FB, 0x00FE, + 0x0101, 0x0103, 0x0104, 0x0105, 0x0104, 0x0103, 0x0101, 0x00FE, 0x00FB, + 0x00F7, 0x00F3, 0x00EE, 0x00EA, 0x00E5, 0x00E0, 0x00DB, 0x00D6, 0x00D2, + 0x00CD, 0x00CA, 0x00C6, 0x00C3, 0x00C1, 0x00C0, 0xBB3A, 0xBB33, 0xBB1C, + 0xBAF9, 0xBACB, 0xBA92, 0xBA52, 0xBA0A, 0xB9BD, 0xB96D, 0xB91A, 0xB8C6, + 0xB873, 0xB822, 0xB7D6, 0xB78E, 0xB74D, 0xB715, 0xB6E7, 0xB6C3, 0xB6AD, + 0xB6A6, 0xB6AD, 0xB6C3, 0xB6E7, 0xB715, 0xB74D, 0xB78E, 0xB7D6, 0xB822, + 0xB873, 0xB8C6, 0xB91A, 0xB96D, 0xB9BD, 0xBA0A, 0xBA52, 0xBA92, 0xBACB, + 0xBAF9, 0xBB1C, 0xBB33, + },{ + 0x0028, 0x0000, 0x0028, 0x0028, 0x0001, 0x0050, 0x0001, 0x0051, 0x0001, + 0x0052, 0x0001, 0x0053, 0x0001, 0x0054, 0x0001, 0x0055, 0x0001, 0x0056, + 0x0024, 0x0057, 0x0015, 0x007B, 0x002A, 0x0090, 0x0029, 0x00BA, 0x0001, + 0x00E3, 0x002A, 0x00E4, 0x0001, 0x010E, 0x0001, 0x010F, 0x0001, 0x0110, + 0x002A, 0x0111, 0x002A, 0x013B, 0x002A, 0x0165, 0x0029, 0x018F, 0x0019, + 0x01B8, 0x002A, 0x01D1, 0x002A, 0x01FB, 0x002A, 0x0225, 0x002A, 0x024F, + 0x0001, 0x0279, 0x0001, 0x027A, 0x0001, 0x027B, 0x002A, 0x027C, 0x002A, + 0x02A6, 0x002A, 0x02D0, 0x0001, 0x02FA, 0x0001, 0x02FB, 0x002A, 0x02FC, + 0x0029, 0x0326, 0x002A, 0x034F, 0x002A, 0x0379, 0x0001, 0x03A3, 0x0001, + 0x03A4, 0x0001, 0x03A5, 0x002A, 0x03A6, 0x002A, 0x03D0, 0x002A, 0x03FA, + 0x0016, 0x0424, 0x0014, 0x043A, 0x002A, 0x044E, 0x0029, 0x0478, 0x002A, + 0x04A1, 0x002A, 0x04CB, 0x0001, 0x04F5, 0x0001, 0x04F6, 0x0001, 0x04F7, + 0x002A, 0x04F8, 0x002A, 0x0522, 0x002A, 0x054C, 0x002A, 0x0576, 0x002A, + 0x05A0, 0x002A, 0x05CA, 0x002A, 0x05F4, 0x002A, 0x061E, 0x002A, 0x0648, +}) + +TOAD_PLAYER_ANIM_CS_MENU = "toad_anim_cs_menu" +smlua_anim_util_register_animation(TOAD_PLAYER_ANIM_CS_MENU, + 0, + 0, + 0, + 0, + 41, + { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0002, 0x0002, 0x0002, 0x0003, 0x0003, 0x0003, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x012C, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, + 0xFFFF, 0xFFFE, 0xFFFE, 0xFFFD, 0xFFFD, 0xFFFC, 0xFFFB, 0xFFFB, 0xFFFA, + 0xFFFA, 0xFFF9, 0xFFF8, 0xFFF8, 0xFFF8, 0xFFF7, 0xFFF7, 0xFFF7, 0xFFF7, + 0xFFF7, 0xFFF8, 0xFFF8, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFA, 0xFFFB, 0xFFFB, + 0xFFFC, 0xFFFD, 0xFFFD, 0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, + 0x3FFF, 0xFFFF, 0xFFE3, 0xFFE3, 0xFFE2, 0xFFE2, 0xFFE1, 0xFFE1, 0xFFE0, + 0xFFDF, 0xFFDE, 0xFFDD, 0xFFDC, 0xFFDB, 0xFFDA, 0xFFD9, 0xFFD8, 0xFFD7, + 0xFFD6, 0xFFD5, 0xFFD5, 0xFFD4, 0xFFD4, 0xFFD4, 0xFFD4, 0xFFD4, 0xFFD5, + 0xFFD5, 0xFFD6, 0xFFD7, 0xFFD8, 0xFFD9, 0xFFDA, 0xFFDB, 0xFFDC, 0xFFDD, + 0xFFDE, 0xFFDF, 0xFFE0, 0xFFE1, 0xFFE1, 0xFFE2, 0xFFE2, 0xFFE3, 0xF8E3, + 0xF8DD, 0xF8CC, 0xF8B0, 0xF88C, 0xF861, 0xF82E, 0xF7F7, 0xF7BB, 0xF77D, + 0xF73C, 0xF6FB, 0xF6BB, 0xF67C, 0xF641, 0xF609, 0xF5D7, 0xF5AB, 0xF587, + 0xF56C, 0xF55B, 0xF555, 0xF55B, 0xF56C, 0xF587, 0xF5AB, 0xF5D7, 0xF609, + 0xF641, 0xF67C, 0xF6BB, 0xF6FB, 0xF73C, 0xF77D, 0xF7BB, 0xF7F7, 0xF82E, + 0xF861, 0xF88C, 0xF8B0, 0xF8CC, 0xF8DD, 0x40A3, 0x40A3, 0x40A3, 0x40A3, + 0x40A3, 0x40A3, 0x40A4, 0x40A4, 0x40A4, 0x40A4, 0x40A4, 0x40A5, 0x40A5, + 0x40A5, 0x40A5, 0x40A6, 0x40A6, 0x40A6, 0x40A6, 0x40A6, 0x40A6, 0x40A6, + 0x40A6, 0x40A6, 0x40A6, 0x40A6, 0x40A6, 0x40A6, 0x40A5, 0x40A5, 0x40A5, + 0x40A5, 0x40A4, 0x40A4, 0x40A4, 0x40A4, 0x40A4, 0x40A3, 0xFFFF, 0xFFFF, + 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, + 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, + 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, + 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, + 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, + 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, + 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, + 0x0000, 0x0884, 0xFC56, 0xFC54, 0xFC50, 0xFC49, 0xFC3F, 0xFC34, 0xFC27, + 0xFC19, 0xFC0A, 0xFBFA, 0xFBE9, 0xFBD8, 0xFBC8, 0xFBB8, 0xFBA9, 0xFB9A, + 0xFB8D, 0xFB82, 0xFB79, 0xFB72, 0xFB6E, 0xFB6C, 0xFB6E, 0xFB72, 0xFB79, + 0xFB82, 0xFB8D, 0xFB9A, 0xFBA9, 0xFBB8, 0xFBC8, 0xFBD8, 0xFBE9, 0xFBFA, + 0xFC0A, 0xFC19, 0xFC27, 0xFC34, 0xFC3F, 0xFC49, 0xFC50, 0xFC54, 0x0A28, + 0x0A31, 0x0A4D, 0x0A78, 0x0AB2, 0x0AF7, 0x0B47, 0x0BA0, 0x0BFF, 0x0C62, + 0x0CC9, 0x0D31, 0x0D97, 0x0DFB, 0x0E5A, 0x0EB2, 0x0F02, 0x0F48, 0x0F81, + 0x0FAD, 0x0FC8, 0x0FD2, 0x0FC8, 0x0FAD, 0x0F81, 0x0F48, 0x0F02, 0x0EB2, + 0x0E5A, 0x0DFB, 0x0D97, 0x0D31, 0x0CC9, 0x0C62, 0x0BFF, 0x0BA0, 0x0B47, + 0x0AF7, 0x0AB2, 0x0A78, 0x0A4D, 0x0A31, 0xF89E, 0xF898, 0xF884, 0xF866, + 0xF83D, 0xF80C, 0xF7D3, 0xF795, 0xF751, 0xF70B, 0xF6C2, 0xF679, 0xF630, + 0xF5EA, 0xF5A7, 0xF568, 0xF530, 0xF4FE, 0xF4D6, 0xF4B7, 0xF4A4, 0xF49D, + 0xF4A4, 0xF4B7, 0xF4D6, 0xF4FE, 0xF530, 0xF568, 0xF5A7, 0xF5EA, 0xF630, + 0xF679, 0xF6C2, 0xF70B, 0xF751, 0xF795, 0xF7D3, 0xF80C, 0xF83D, 0xF866, + 0xF884, 0xF898, 0xFFFE, 0x0001, 0xC170, 0x3654, 0xE59C, 0x3B9C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, + 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFC3, + 0xFF20, 0xFE31, 0xFD0E, 0xFBD1, 0xFA94, 0xF971, 0xF881, 0xF7DE, 0xF7A3, + 0xF7BD, 0xF80A, 0xF884, 0xF924, 0xF9E6, 0xFAC4, 0xFBB9, 0xFCBE, 0xFDD0, + 0xFEE7, 0x0000, 0x0113, 0x021D, 0x0319, 0x0402, 0x04D4, 0x058A, 0x061F, + 0x0690, 0x06D7, 0x06EF, 0x06C6, 0x0654, 0x05AB, 0x04DA, 0x03F0, 0x02FF, + 0x0215, 0x0144, 0x009B, 0x0029, 0x0000, 0x0023, 0x0044, 0x0065, 0x0083, + 0x009F, 0x00B7, 0x00CB, 0x00DA, 0x00E4, 0x00E7, 0x00E5, 0x00DE, 0x00D3, + 0x00C4, 0x00B1, 0x009B, 0x0082, 0x0065, 0x0046, 0x0024, 0x0000, 0xFFD9, + 0xFFB2, 0xFF8C, 0xFF67, 0xFF44, 0xFF26, 0xFF0C, 0xFEF8, 0xFEEB, 0xFEE6, + 0xFEEA, 0xFEF4, 0xFF03, 0xFF17, 0xFF30, 0xFF4D, 0xFF6D, 0xFF8F, 0xFFB3, + 0xFFD9, 0xF97B, 0xF97D, 0xF980, 0xF982, 0xF984, 0xF986, 0xF988, 0xF989, + 0xF98A, 0xF98B, 0xF98B, 0xF98B, 0xF98A, 0xF988, 0xF986, 0xF984, 0xF982, + 0xF980, 0xF97E, 0xF97C, 0xF97B, 0xF97B, 0xF97C, 0xF97D, 0xF980, 0xF983, + 0xF987, 0xF98A, 0xF98E, 0xF990, 0xF992, 0xF993, 0xF992, 0xF991, 0xF990, + 0xF98E, 0xF98C, 0xF98A, 0xF987, 0xF984, 0xF981, 0xF97E, 0xED8B, 0xECB1, + 0xEBDC, 0xEB0F, 0xEA50, 0xE9A2, 0xE90A, 0xE88C, 0xE82C, 0xE7F0, 0xE7DB, + 0xE7E9, 0xE814, 0xE859, 0xE8B8, 0xE92E, 0xE9BA, 0xEA5B, 0xEB0E, 0xEBD3, + 0xECA8, 0xED8B, 0xEE7A, 0xEF6E, 0xF061, 0xF14B, 0xF224, 0xF2E6, 0xF38A, + 0xF408, 0xF459, 0xF475, 0xF460, 0xF423, 0xF3C2, 0xF341, 0xF2A4, 0xF1EF, + 0xF126, 0xF04D, 0xEF68, 0xEE7C, 0xFFFE, 0x0001, 0xC170, 0x20DC, 0x20E4, + 0x20FA, 0x211D, 0x214C, 0x2184, 0x21C5, 0x220D, 0x225B, 0x22AC, 0x22FF, + 0x2353, 0x23A6, 0x23F7, 0x2445, 0x248C, 0x24CD, 0x2506, 0x2535, 0x2558, + 0x256E, 0x2576, 0x256E, 0x2558, 0x2535, 0x2506, 0x24CD, 0x248C, 0x2445, + 0x23F7, 0x23A6, 0x2353, 0x22FF, 0x22AC, 0x225B, 0x220D, 0x21C5, 0x2184, + 0x214C, 0x211D, 0x20FA, 0x20E4, 0x20E0, 0x20DF, 0x20DB, 0x20D6, 0x20CF, + 0x20C7, 0x20BD, 0x20B3, 0x20A8, 0x209C, 0x208F, 0x2083, 0x2077, 0x206B, + 0x205F, 0x2055, 0x204B, 0x2043, 0x203C, 0x2037, 0x2034, 0x2032, 0x2034, + 0x2037, 0x203C, 0x2043, 0x204B, 0x2055, 0x205F, 0x206B, 0x2077, 0x2083, + 0x208F, 0x209C, 0x20A7, 0x20B3, 0x20BD, 0x20C7, 0x20CF, 0x20D6, 0x20DB, + 0x20DF, 0xD0CB, 0xD0DB, 0xD109, 0xD152, 0xD1B2, 0xD226, 0xD2AC, 0xD340, + 0xD3DF, 0xD485, 0xD531, 0xD5DE, 0xD689, 0xD730, 0xD7CF, 0xD863, 0xD8E8, + 0xD95D, 0xD9BD, 0xDA05, 0xDA33, 0xDA43, 0xDA33, 0xDA05, 0xD9BD, 0xD95D, + 0xD8E8, 0xD863, 0xD7CF, 0xD730, 0xD689, 0xD5DE, 0xD531, 0xD485, 0xD3DF, + 0xD340, 0xD2AC, 0xD226, 0xD1B2, 0xD152, 0xD109, 0xD0DB, 0x0000, 0x0000, + 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, + 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, + 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, + 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFF9, 0xFFE7, 0xFFCA, + 0xFFA4, 0xFF76, 0xFF42, 0xFF07, 0xFEC9, 0xFE87, 0xFE44, 0xFDFF, 0xFDBC, + 0xFD7A, 0xFD3C, 0xFD01, 0xFCCD, 0xFC9F, 0xFC79, 0xFC5C, 0xFC4A, 0xFC44, + 0xFC4A, 0xFC5C, 0xFC79, 0xFC9F, 0xFCCD, 0xFD01, 0xFD3C, 0xFD7A, 0xFDBC, + 0xFDFF, 0xFE44, 0xFE87, 0xFEC9, 0xFF07, 0xFF42, 0xFF76, 0xFFA4, 0xFFCA, + 0xFFE7, 0xFFF9, 0xFFFF, 0x0016, 0x0056, 0x00BB, 0x0141, 0x01E3, 0x029E, + 0x036C, 0x0449, 0x0531, 0x0620, 0x0711, 0x0800, 0x08E9, 0x09C6, 0x0A94, + 0x0B4E, 0x0BF1, 0x0C76, 0x0CDC, 0x0D1B, 0x0D32, 0x0D1B, 0x0CDC, 0x0C76, + 0x0BF1, 0x0B4E, 0x0A94, 0x09C6, 0x08E9, 0x0800, 0x0711, 0x0620, 0x0531, + 0x0449, 0x036C, 0x029E, 0x01E3, 0x0141, 0x00BB, 0x0056, 0x0016, 0xF548, + 0xF547, 0xF544, 0xF540, 0xF53A, 0xF532, 0xF52A, 0xF521, 0xF517, 0xF50C, + 0xF502, 0xF4F7, 0xF4EC, 0xF4E2, 0xF4D8, 0xF4CF, 0xF4C6, 0xF4BF, 0xF4B9, + 0xF4B5, 0xF4B2, 0xF4B1, 0xF4B2, 0xF4B5, 0xF4B9, 0xF4BF, 0xF4C6, 0xF4CF, + 0xF4D8, 0xF4E2, 0xF4EC, 0xF4F7, 0xF502, 0xF50C, 0xF517, 0xF521, 0xF52A, + 0xF532, 0xF53A, 0xF540, 0xF544, 0xF547, 0x0000, 0xFFFF, 0x0000, 0xFFFF, + 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, + 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, + 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, + 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xBF5E, 0xD227, + 0xF622, 0xBEC5, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, + 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x2537, + 0x1DEE, 0x1DEB, 0x1DE0, 0x1DCF, 0x1DB9, 0x1D9E, 0x1D7F, 0x1D5D, 0x1D38, + 0x1D12, 0x1CEA, 0x1CC2, 0x1C9B, 0x1C74, 0x1C50, 0x1C2D, 0x1C0F, 0x1BF4, + 0x1BDD, 0x1BCD, 0x1BC2, 0x1BBE, 0x1BC2, 0x1BCD, 0x1BDD, 0x1BF4, 0x1C0F, + 0x1C2D, 0x1C50, 0x1C74, 0x1C9B, 0x1CC2, 0x1CEA, 0x1D12, 0x1D38, 0x1D5D, + 0x1D7F, 0x1D9E, 0x1DB9, 0x1DCF, 0x1DE0, 0x1DEB, 0x105C, 0x1063, 0x1075, + 0x1093, 0x10BA, 0x10EA, 0x1121, 0x115E, 0x119F, 0x11E3, 0x1229, 0x1270, + 0x12B7, 0x12FB, 0x133C, 0x1379, 0x13AF, 0x13DF, 0x1407, 0x1424, 0x1437, + 0x143E, 0x1437, 0x1424, 0x1407, 0x13DF, 0x13AF, 0x1379, 0x133C, 0x12FB, + 0x12B7, 0x1270, 0x1229, 0x11E3, 0x119F, 0x115E, 0x1121, 0x10EA, 0x10BA, + 0x1093, 0x1075, 0x1063, 0xCCA9, 0xCCA0, 0xCC88, 0xCC62, 0xCC2F, 0xCBF1, + 0xCBAA, 0xCB5B, 0xCB07, 0xCAAE, 0xCA53, 0xC9F8, 0xC99D, 0xC944, 0xC8F0, + 0xC8A1, 0xC85A, 0xC81C, 0xC7E9, 0xC7C3, 0xC7AB, 0xC7A2, 0xC7AB, 0xC7C3, + 0xC7E9, 0xC81C, 0xC85A, 0xC8A1, 0xC8F0, 0xC944, 0xC99D, 0xC9F8, 0xCA53, + 0xCAAE, 0xCB07, 0xCB5B, 0xCBAA, 0xCBF1, 0xCC2F, 0xCC62, 0xCC88, 0xCCA0, + 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, + 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, + 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, + 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, + 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, + 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, + 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, + 0xFFFF, 0x0000, 0xBF5E, 0x0C12, 0x0C13, 0x0C17, 0x0C1C, 0x0C23, 0x0C2C, + 0x0C36, 0x0C41, 0x0C4D, 0x0C59, 0x0C66, 0x0C73, 0x0C80, 0x0C8C, 0x0C98, + 0x0CA3, 0x0CAD, 0x0CB6, 0x0CBD, 0x0CC2, 0x0CC6, 0x0CC7, 0x0CC6, 0x0CC2, + 0x0CBD, 0x0CB6, 0x0CAD, 0x0CA3, 0x0C98, 0x0C8C, 0x0C80, 0x0C73, 0x0C66, + 0x0C59, 0x0C4D, 0x0C41, 0x0C36, 0x0C2C, 0x0C23, 0x0C1C, 0x0C17, 0x0C13, + 0x052E, 0x0520, 0x04F9, 0x04BB, 0x0468, 0x0404, 0x0391, 0x0312, 0x0289, + 0x01FA, 0x0166, 0x00D1, 0x003E, 0xFFAE, 0xFF25, 0xFEA6, 0xFE33, 0xFDCF, + 0xFD7C, 0xFD3E, 0xFD16, 0xFD08, 0xFD16, 0xFD3E, 0xFD7C, 0xFDCF, 0xFE33, + 0xFEA6, 0xFF25, 0xFFAE, 0x003E, 0x00D1, 0x0166, 0x01FA, 0x0289, 0x0312, + 0x0391, 0x0404, 0x0468, 0x04BB, 0x04F9, 0x0520, 0xAFF2, 0xB01C, 0xB095, + 0xB154, 0xB252, 0xB386, 0xB4E7, 0xB66E, 0xB812, 0xB9CB, 0xBB90, 0xBD59, + 0xBF1E, 0xC0D6, 0xC27A, 0xC401, 0xC562, 0xC696, 0xC794, 0xC853, 0xC8CC, + 0xC8F7, 0xC8CC, 0xC853, 0xC794, 0xC696, 0xC562, 0xC401, 0xC27A, 0xC0D6, + 0xBF1E, 0xBD59, 0xBB90, 0xB9CB, 0xB812, 0xB66E, 0xB4E7, 0xB386, 0xB252, + 0xB154, 0xB095, 0xB01C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFC2, 0x00E3, 0x00E6, + 0x00EF, 0x00FD, 0x010F, 0x0125, 0x013E, 0x015A, 0x0178, 0x0198, 0x01B8, + 0x01D9, 0x01FA, 0x0219, 0x0237, 0x0253, 0x026D, 0x0283, 0x0295, 0x02A3, + 0x02AB, 0x02AE, 0x02AB, 0x02A3, 0x0295, 0x0283, 0x026D, 0x0253, 0x0237, + 0x0219, 0x01FA, 0x01D9, 0x01B8, 0x0198, 0x0178, 0x015A, 0x013E, 0x0125, + 0x010F, 0x00FD, 0x00EF, 0x00E6, 0x0633, 0x0632, 0x0630, 0x062B, 0x0626, + 0x061F, 0x0618, 0x060F, 0x0606, 0x05FD, 0x05F3, 0x05E9, 0x05E0, 0x05D6, + 0x05CD, 0x05C5, 0x05BD, 0x05B7, 0x05B1, 0x05AD, 0x05AB, 0x05AA, 0x05AB, + 0x05AD, 0x05B1, 0x05B7, 0x05BD, 0x05C5, 0x05CD, 0x05D6, 0x05E0, 0x05E9, + 0x05F3, 0x05FD, 0x0606, 0x060F, 0x0618, 0x061F, 0x0626, 0x062B, 0x0630, + 0x0632, 0xBF73, 0xBF88, 0xBFC3, 0xC021, 0xC09E, 0xC135, 0xC1E2, 0xC2A2, + 0xC370, 0xC448, 0xC526, 0xC606, 0xC6E4, 0xC7BD, 0xC88A, 0xC94A, 0xC9F7, + 0xCA8E, 0xCB0B, 0xCB69, 0xCBA4, 0xCBB9, 0xCBA4, 0xCB69, 0xCB0B, 0xCA8E, + 0xC9F7, 0xC94A, 0xC88A, 0xC7BD, 0xC6E4, 0xC606, 0xC526, 0xC448, 0xC370, + 0xC2A2, 0xC1E2, 0xC135, 0xC09E, 0xC021, 0xBFC3, 0xBF88, + },{ + 0x0027, 0x0000, 0x0001, 0x0027, 0x0028, 0x0028, 0x0001, 0x0050, 0x0001, + 0x0051, 0x0001, 0x0052, 0x002A, 0x0053, 0x002A, 0x007D, 0x0026, 0x00A7, + 0x002A, 0x00CD, 0x002A, 0x00F7, 0x0001, 0x0121, 0x002A, 0x0122, 0x002A, + 0x014C, 0x002A, 0x0176, 0x0001, 0x01A0, 0x0001, 0x01A1, 0x0001, 0x01A2, + 0x0001, 0x01A3, 0x0001, 0x01A4, 0x0001, 0x01A5, 0x0028, 0x01A6, 0x0028, + 0x01CE, 0x002A, 0x01F6, 0x002A, 0x0220, 0x002A, 0x024A, 0x002A, 0x0274, + 0x0001, 0x029E, 0x0001, 0x029F, 0x0001, 0x02A0, 0x002A, 0x02A1, 0x002A, + 0x02CB, 0x002A, 0x02F5, 0x002A, 0x031F, 0x002A, 0x0349, 0x0028, 0x0373, + 0x002A, 0x039B, 0x002A, 0x03C5, 0x002A, 0x03EF, 0x002A, 0x0419, 0x0029, + 0x0443, 0x0001, 0x046C, 0x0001, 0x046D, 0x0001, 0x046E, 0x0001, 0x046F, + 0x0028, 0x0470, 0x0026, 0x0498, 0x0001, 0x04BE, 0x002A, 0x04BF, 0x002A, + 0x04E9, 0x002A, 0x0513, 0x002A, 0x053D, 0x0029, 0x0567, 0x0001, 0x0590, + 0x002A, 0x0591, 0x002A, 0x05BB, 0x002A, 0x05E5, 0x0026, 0x060F, 0x0001, + 0x0635, 0x0001, 0x0636, 0x002A, 0x0637, 0x002A, 0x0661, 0x002A, 0x068B, +}) + +WALUIGI_ANIM_CS_MENU = "waluigi_anim_cs_menu" +smlua_anim_util_register_animation(WALUIGI_ANIM_CS_MENU, + 0, + 0, + 0, + 0, + 41, + { + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFE, + 0xFFFD, 0xFFFD, 0xFFFC, 0xFFFB, 0xFFFB, 0xFFFA, 0xFFFA, 0xFFFA, 0xFFF9, + 0xFFF9, 0xFFF9, 0xFFF9, 0xFFF8, 0xFFF9, 0xFFF9, 0xFFF9, 0xFFF9, 0xFFFA, + 0xFFFA, 0xFFFA, 0xFFFB, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFD, 0xFFFE, 0xFFFE, + 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x006A, 0x006A, 0x006A, 0x006A, 0x006A, + 0x006A, 0x006A, 0x006A, 0x006A, 0x006A, 0x006A, 0x006A, 0x006A, 0x0069, + 0x0069, 0x0069, 0x0069, 0x0069, 0x0069, 0x0069, 0x0069, 0x0069, 0x0069, + 0x0069, 0x0069, 0x0069, 0x0069, 0x0069, 0x0069, 0x0069, 0x006A, 0x0000, + 0x0000, 0x36B8, 0x0000, 0xFFFF, 0xFFFF, 0x40A1, 0x0D70, 0x0D77, 0x0D8A, + 0x0DA9, 0x0DD2, 0x0E04, 0x0E3D, 0x0E7C, 0x0EC0, 0x0F07, 0x0F51, 0x0F9B, + 0x0FE4, 0x102B, 0x106F, 0x10AE, 0x10E7, 0x1119, 0x1142, 0x1161, 0x1174, + 0x117B, 0x1174, 0x1161, 0x1142, 0x1119, 0x10E7, 0x10AE, 0x106F, 0x102B, + 0x0FE4, 0x0F9B, 0x0F51, 0x0F07, 0x0EC0, 0x0E7C, 0x0E3D, 0x0E04, 0x0DD2, + 0x0DA9, 0x0D8A, 0x0D77, 0x0C44, 0x0C48, 0x0C53, 0x0C64, 0x0C7B, 0x0C97, + 0x0CB7, 0x0CDA, 0x0D00, 0x0D28, 0x0D51, 0x0D7B, 0x0DA4, 0x0DCC, 0x0DF2, + 0x0E15, 0x0E35, 0x0E51, 0x0E68, 0x0E79, 0x0E84, 0x0E88, 0x0E84, 0x0E79, + 0x0E68, 0x0E51, 0x0E35, 0x0E15, 0x0DF2, 0x0DCC, 0x0DA4, 0x0D7B, 0x0D51, + 0x0D28, 0x0D00, 0x0CDA, 0x0CB7, 0x0C97, 0x0C7B, 0x0C64, 0x0C53, 0x0C48, + 0x27F5, 0x27F9, 0x2805, 0x2818, 0x2832, 0x2850, 0x2873, 0x289A, 0x28C4, + 0x28F0, 0x291D, 0x294B, 0x2978, 0x29A4, 0x29CE, 0x29F4, 0x2A18, 0x2A36, + 0x2A50, 0x2A63, 0x2A6F, 0x2A73, 0x2A6F, 0x2A63, 0x2A50, 0x2A36, 0x2A18, + 0x29F4, 0x29CE, 0x29A4, 0x2978, 0x294B, 0x291D, 0x28F0, 0x28C4, 0x289A, + 0x2873, 0x2850, 0x2832, 0x2818, 0x2805, 0x27F9, 0xF280, 0xF2AF, 0xF2DA, + 0xF2FE, 0xF316, 0xF31F, 0xF31A, 0xF30D, 0xF2F9, 0xF2DE, 0xF2BD, 0xF298, + 0xF270, 0xF245, 0xF218, 0xF1EB, 0xF1BF, 0xF194, 0xF16C, 0xF147, 0xF126, + 0xF10C, 0xF0F7, 0xF0E8, 0xF0DD, 0xF0D7, 0xF0D3, 0xF0D2, 0xF0D1, 0xF0D5, + 0xF0DE, 0xF0ED, 0xF101, 0xF11A, 0xF137, 0xF158, 0xF17C, 0xF1A3, 0xF1CC, + 0xF1F8, 0xF224, 0xF252, 0xF722, 0xF6DF, 0xF6A1, 0xF66F, 0xF64D, 0xF640, + 0xF647, 0xF65C, 0xF67D, 0xF6A8, 0xF6DD, 0xF71A, 0xF75E, 0xF7A7, 0xF7F3, + 0xF842, 0xF892, 0xF8E2, 0xF92F, 0xF97A, 0xF9C0, 0xFA00, 0xFA39, 0xFA6B, + 0xFA94, 0xFAB5, 0xFACD, 0xFADB, 0xFAE0, 0xFAD9, 0xFAC4, 0xFAA3, 0xFA76, + 0xFA3F, 0xF9FE, 0xF9B5, 0xF964, 0xF90D, 0xF8B1, 0xF851, 0xF7EE, 0xF788, + 0xE0D7, 0xE009, 0xDF4C, 0xDEB0, 0xDE46, 0xDE1F, 0xDE34, 0xDE71, 0xDED2, + 0xDF52, 0xDFED, 0xE09F, 0xE163, 0xE236, 0xE313, 0xE3F6, 0xE4DA, 0xE5BC, + 0xE697, 0xE767, 0xE827, 0xE8D4, 0xE96A, 0xE9E8, 0xEA4F, 0xEA9F, 0xEAD8, + 0xEAF9, 0xEB05, 0xEAF1, 0xEAB9, 0xEA5E, 0xE9E4, 0xE94D, 0xE89D, 0xE7D6, + 0xE6FC, 0xE610, 0xE516, 0xE410, 0xE302, 0xE1EE, 0xFFFE, 0x0001, 0xC170, + 0x26EA, 0x26F6, 0x271A, 0x2752, 0x279C, 0x27F6, 0x285D, 0x28D0, 0x294A, + 0x29CB, 0x2A4F, 0x2AD5, 0x2B59, 0x2BDA, 0x2C55, 0x2CC7, 0x2D2F, 0x2D88, + 0x2DD3, 0x2E0B, 0x2E2E, 0x2E3A, 0x2E2E, 0x2E0B, 0x2DD3, 0x2D88, 0x2D2F, + 0x2CC7, 0x2C55, 0x2BDA, 0x2B59, 0x2AD5, 0x2A4F, 0x29CB, 0x294A, 0x28D0, + 0x285D, 0x27F6, 0x279C, 0x2752, 0x271A, 0x26F6, 0xCA92, 0xCA98, 0xCAAC, + 0xCACB, 0xCAF4, 0xCB25, 0xCB5E, 0xCB9D, 0xCBE1, 0xCC28, 0xCC70, 0xCCBA, + 0xCD03, 0xCD4A, 0xCD8E, 0xCDCD, 0xCE05, 0xCE37, 0xCE60, 0xCE7F, 0xCE92, + 0xCE99, 0xCE92, 0xCE7F, 0xCE60, 0xCE37, 0xCE05, 0xCDCD, 0xCD8E, 0xCD4A, + 0xCD03, 0xCCBA, 0xCC70, 0xCC28, 0xCBE1, 0xCB9D, 0xCB5E, 0xCB25, 0xCAF4, + 0xCACB, 0xCAAC, 0xCA98, 0xAF0D, 0xAF01, 0xAEDB, 0xAEA1, 0xAE53, 0xADF5, + 0xAD88, 0xAD11, 0xAC90, 0xAC09, 0xAB7E, 0xAAF2, 0xAA67, 0xA9E0, 0xA960, + 0xA8E8, 0xA87C, 0xA81D, 0xA7D0, 0xA795, 0xA770, 0xA763, 0xA770, 0xA795, + 0xA7D0, 0xA81D, 0xA87C, 0xA8E8, 0xA960, 0xA9E0, 0xAA67, 0xAAF2, 0xAB7E, + 0xAC09, 0xAC90, 0xAD11, 0xAD88, 0xADF5, 0xAE53, 0xAEA1, 0xAEDB, 0xAF00, + 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xBE3D, 0xBE42, 0xBE50, 0xBE65, 0xBE82, + 0xBEA5, 0xBECC, 0xBEF8, 0xBF28, 0xBF59, 0xBF8C, 0xBFC0, 0xBFF3, 0xC024, + 0xC053, 0xC07F, 0xC0A7, 0xC0CA, 0xC0E6, 0xC0FC, 0xC10A, 0xC10E, 0xC10A, + 0xC0FC, 0xC0E6, 0xC0CA, 0xC0A7, 0xC07F, 0xC053, 0xC024, 0xBFF3, 0xBFC0, + 0xBF8C, 0xBF59, 0xBF28, 0xBEF8, 0xBECC, 0xBEA5, 0xBE82, 0xBE65, 0xBE50, + 0xBE42, 0x0F42, 0xFBB0, 0xDC2A, 0xFFFE, 0x0001, 0xC170, 0x4E55, 0x4E5E, + 0x4E77, 0x4E9F, 0x4ED4, 0xCF14, 0xCF5E, 0xCFB0, 0xD007, 0xD063, 0xD0C2, + 0xD121, 0xD180, 0xD1DC, 0xD233, 0xD285, 0xD2CF, 0xD30F, 0xD344, 0xD36C, + 0xD385, 0xD38E, 0xD385, 0xD36C, 0xD344, 0xD30F, 0xD2CF, 0xD285, 0xD233, + 0xD1DC, 0xD180, 0xD121, 0xD0C2, 0xD063, 0xD007, 0xCFB0, 0xCF5E, 0xCF14, + 0x4ED4, 0x4E9F, 0x4E77, 0x4E5E, 0x58A6, 0x589A, 0x5879, 0x5845, 0x5800, + 0x2853, 0x28B3, 0x291D, 0x298F, 0x2A06, 0x2A81, 0x2AFD, 0x2B78, 0x2BF0, + 0x2C62, 0x2CCC, 0x2D2C, 0x2D7F, 0x2DC4, 0x2DF8, 0x2E19, 0x2E24, 0x2E19, + 0x2DF8, 0x2DC4, 0x2D7F, 0x2D2C, 0x2CCC, 0x2C62, 0x2BF0, 0x2B78, 0x2AFD, + 0x2A81, 0x2A06, 0x298F, 0x291D, 0x28B3, 0x2853, 0x5800, 0x5845, 0x5879, + 0x589A, 0x1897, 0x18A1, 0x18BE, 0x18EC, 0x1929, 0x9972, 0x99C7, 0x9A24, + 0x9A89, 0x9AF3, 0x9B60, 0x9BCD, 0x9C3A, 0x9CA4, 0x9D08, 0x9D66, 0x9DBB, + 0x9E05, 0x9E41, 0x9E6F, 0x9E8C, 0x9E97, 0x9E8C, 0x9E6F, 0x9E41, 0x9E05, + 0x9DBB, 0x9D66, 0x9D08, 0x9CA4, 0x9C3A, 0x9BCD, 0x9B60, 0x9AF3, 0x9A89, + 0x9A24, 0x99C7, 0x9972, 0x1929, 0x18EC, 0x18BE, 0x18A1, 0x0000, 0xFFFF, + 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, + 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, + 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, + 0x0000, 0xFFFF, 0x0000, 0xB7ED, 0xB7DE, 0xB7B5, 0xB774, 0xB71E, 0xB6B6, + 0xB63E, 0xB5B9, 0xB52B, 0xB496, 0xB3FC, 0xB361, 0xB2C7, 0xB232, 0xB1A4, + 0xB11F, 0xB0A7, 0xB03F, 0xAFE9, 0xAFA8, 0xAF7F, 0xAF70, 0xAF7F, 0xAFA8, + 0xAFE9, 0xB03F, 0xB0A7, 0xB11F, 0xB1A4, 0xB232, 0xB2C7, 0xB361, 0xB3FC, + 0xB496, 0xB52B, 0xB5B9, 0xB63E, 0xB6B6, 0xB71E, 0xB774, 0xB7B5, 0xB7DE, + 0xE202, 0xE1FC, 0xE1EA, 0xE1CE, 0xE1AA, 0xE17D, 0xE14A, 0xE111, 0xE0D4, + 0xE094, 0xE052, 0xE010, 0xDFCE, 0xDF8E, 0xDF51, 0xDF18, 0xDEE5, 0xDEB8, + 0xDE93, 0xDE78, 0xDE66, 0xDE60, 0xDE66, 0xDE78, 0xDE93, 0xDEB8, 0xDEE5, + 0xDF18, 0xDF51, 0xDF8E, 0xDFCE, 0xE010, 0xE052, 0xE094, 0xE0D4, 0xE111, + 0xE14A, 0xE17D, 0xE1AA, 0xE1CE, 0xE1EA, 0xE1FC, 0xF2BC, 0xF2BF, 0xF2C9, + 0xF2D9, 0xF2EE, 0xF307, 0xF324, 0xF344, 0xF366, 0xF38B, 0xF3B0, 0xF3D5, + 0xF3FB, 0xF41F, 0xF441, 0xF461, 0xF47F, 0xF498, 0xF4AD, 0xF4BC, 0xF4C6, + 0xF4CA, 0xF4C6, 0xF4BC, 0xF4AD, 0xF498, 0xF47F, 0xF461, 0xF441, 0xF41F, + 0xF3FB, 0xF3D5, 0xF3B0, 0xF38B, 0xF366, 0xF344, 0xF324, 0xF307, 0xF2EE, + 0xF2D9, 0xF2C9, 0xF2BF, 0x0B5C, 0x0B62, 0x0B75, 0x0B94, 0x0BBC, 0x0BEC, + 0x0C24, 0x0C61, 0x0CA4, 0x0CE9, 0x0D30, 0x0D78, 0x0DC0, 0x0E05, 0x0E47, + 0x0E85, 0x0EBD, 0x0EED, 0x0F15, 0x0F33, 0x0F46, 0x0F4D, 0x0F46, 0x0F33, + 0x0F15, 0x0EED, 0x0EBD, 0x0E85, 0x0E47, 0x0E05, 0x0DC0, 0x0D78, 0x0D30, + 0x0CE9, 0x0CA4, 0x0C61, 0x0C24, 0x0BEC, 0x0BBC, 0x0B94, 0x0B75, 0x0B62, + 0xFFFF, 0x0000, 0xBF5E, 0xFBBD, 0xD39A, 0x85AE, 0xFFFF, 0x0002, 0x0006, + 0x000D, 0x0017, 0x0022, 0x002F, 0x003E, 0x004E, 0x005E, 0x006F, 0x0080, + 0x0091, 0x00A1, 0x00B1, 0x00C0, 0x00CD, 0x00D8, 0x00E2, 0x00E9, 0x00ED, + 0x00EF, 0x00ED, 0x00E9, 0x00E2, 0x00D8, 0x00CD, 0x00C0, 0x00B1, 0x00A1, + 0x0091, 0x0080, 0x006F, 0x005E, 0x004E, 0x003E, 0x002F, 0x0022, 0x0017, + 0x000D, 0x0006, 0x0002, 0x0000, 0xFFFA, 0xFFEC, 0xFFD6, 0xFFB8, 0xFF94, + 0xFF6B, 0xFF3E, 0xFF0D, 0xFEDA, 0xFEA5, 0xFE70, 0xFE3B, 0xFE08, 0xFDD7, + 0xFDA9, 0xFD80, 0xFD5C, 0xFD3F, 0xFD28, 0xFD1A, 0xFD15, 0xFD1A, 0xFD28, + 0xFD3F, 0xFD5C, 0xFD80, 0xFDA9, 0xFDD7, 0xFE08, 0xFE3B, 0xFE70, 0xFEA5, + 0xFEDA, 0xFF0D, 0xFF3E, 0xFF6B, 0xFF94, 0xFFB8, 0xFFD6, 0xFFEC, 0xFFFA, + 0x35B3, 0x35AD, 0x359F, 0x3588, 0x356A, 0x3545, 0x351A, 0x34EC, 0x34B9, + 0x3485, 0x344E, 0x3418, 0x33E1, 0x33AD, 0x337A, 0x334B, 0x3321, 0x32FC, + 0x32DE, 0x32C7, 0x32B8, 0x32B3, 0x32B8, 0x32C7, 0x32DE, 0x32FC, 0x3321, + 0x334B, 0x337A, 0x33AD, 0x33E1, 0x3418, 0x344E, 0x3485, 0x34B9, 0x34EC, + 0x351A, 0x3545, 0x356A, 0x3588, 0x359F, 0x35AD, 0x0000, 0xFFFA, 0xFFED, + 0xFFD7, 0xFFBB, 0xFF9A, 0xFF74, 0xFF4B, 0xFF20, 0xFEF4, 0xFEC8, 0xFE9D, + 0xFE74, 0xFE4C, 0xFE27, 0xFE04, 0xFDE4, 0xFDC8, 0xFDAE, 0xFD99, 0xFD88, + 0xFD7B, 0xFD73, 0xFD71, 0xFD82, 0xFDAA, 0xFDDA, 0xFE02, 0xFE13, 0xFE02, + 0xFDDA, 0xFDAA, 0xFD82, 0xFD71, 0xFD77, 0xFD90, 0xFDC2, 0xFE13, 0xFE86, + 0xFF08, 0xFF82, 0xFFDC, 0xFFFF, 0x0000, 0x0001, 0x0002, 0x0004, 0x0005, + 0x0007, 0x0009, 0x000A, 0x000B, 0x000B, 0x0008, 0x0001, 0xFFF5, 0xFFE7, + 0xFFD7, 0xFFC6, 0xFFB4, 0xFFA3, 0xFF93, 0xFF85, 0xFF7A, 0xFF73, 0xFF71, + 0xFF86, 0xFFBA, 0xFFF8, 0x002D, 0x0043, 0x002D, 0xFFF8, 0xFFBA, 0xFF86, + 0xFF71, 0xFF91, 0xFFD9, 0x0022, 0x0043, 0x003C, 0x002B, 0x0017, 0x0007, + 0xD567, 0xD576, 0xD59F, 0xD5DC, 0xD625, 0xD675, 0xD6C6, 0xD70F, 0xD74C, + 0xD775, 0xD784, 0xD731, 0xD647, 0xD4E4, 0xD321, 0xD11B, 0xCEEC, 0xCCAF, + 0xCA7F, 0xC879, 0xC6B6, 0xC553, 0xC46A, 0xC416, 0xC608, 0xCAAB, 0xD034, + 0xD4D7, 0xD6C9, 0xD4D7, 0xD034, 0xCAAB, 0xC608, 0xC416, 0xC702, 0xCD6F, + 0xD3DD, 0xD6C9, 0xD6A4, 0xD64C, 0xD5E3, 0xD58B, 0xFFFF, 0x0000, 0xBF5E, + 0x0E87, 0x0E8C, 0x0E9A, 0x0EB1, 0x0ECF, 0x0EF3, 0x0F1D, 0x0F4B, 0x0F7D, + 0x0FB1, 0x0FE7, 0x101D, 0x1052, 0x1086, 0x10B8, 0x10E6, 0x1110, 0x1134, + 0x1152, 0x1169, 0x1177, 0x117C, 0x1177, 0x1169, 0x1152, 0x1134, 0x1110, + 0x10E6, 0x10B8, 0x1086, 0x1052, 0x101D, 0x0FE7, 0x0FB1, 0x0F7D, 0x0F4B, + 0x0F1D, 0x0EF3, 0x0ECF, 0x0EB1, 0x0E9A, 0x0E8C, 0x1C6D, 0x1C6A, 0x1C63, + 0x1C58, 0x1C49, 0x1C36, 0x1C21, 0x1C0A, 0x1BF1, 0x1BD6, 0x1BBB, 0x1BA0, + 0x1B85, 0x1B6B, 0x1B52, 0x1B3A, 0x1B25, 0x1B13, 0x1B04, 0x1AF8, 0x1AF1, + 0x1AEF, 0x1AF1, 0x1AF8, 0x1B04, 0x1B13, 0x1B25, 0x1B3A, 0x1B52, 0x1B6B, + 0x1B85, 0x1BA0, 0x1BBB, 0x1BD6, 0x1BF1, 0x1C0A, 0x1C21, 0x1C36, 0x1C49, + 0x1C58, 0x1C63, 0x1C6A, 0x9566, 0x9569, 0x9572, 0x957F, 0x9591, 0x95A6, + 0x95BE, 0x95D9, 0x95F6, 0x9615, 0x9634, 0x9654, 0x9673, 0x9692, 0x96AF, + 0x96CA, 0x96E2, 0x96F7, 0x9709, 0x9716, 0x971F, 0x9721, 0x971F, 0x9716, + 0x9709, 0x96F7, 0x96E2, 0x96CA, 0x96AF, 0x9692, 0x9673, 0x9654, 0x9634, + 0x9615, 0x95F6, 0x95D9, 0x95BE, 0x95A6, 0x9591, 0x957F, 0x9572, 0x9569, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x520C, 0x5210, + 0x521B, 0x522C, 0x5243, 0x525E, 0x527E, 0x52A1, 0x52C6, 0x52EE, 0x5316, + 0x533F, 0x5368, 0x538F, 0x53B5, 0x53D8, 0x53F7, 0x5413, 0x5429, 0x543B, + 0x5445, 0x5449, 0x5445, 0x543B, 0x5429, 0x5413, 0x53F7, 0x53D8, 0x53B5, + 0x538F, 0x5368, 0x533F, 0x5316, 0x52EE, 0x52C6, 0x52A1, 0x527E, 0x525E, + 0x5243, 0x522C, 0x521B, 0x5210, 0x008D, 0x0089, 0x007F, 0x0070, 0x005B, + 0x0041, 0x0024, 0x0003, 0xFFE0, 0xFFBB, 0xFF96, 0xFF70, 0xFF4A, 0xFF26, + 0xFF03, 0xFEE3, 0xFEC6, 0xFEAC, 0xFE97, 0xFE87, 0xFE7D, 0xFE7A, 0xFE7D, + 0xFE87, 0xFE97, 0xFEAC, 0xFEC6, 0xFEE3, 0xFF03, 0xFF26, 0xFF4A, 0xFF70, + 0xFF96, 0xFFBB, 0xFFE0, 0x0003, 0x0024, 0x0041, 0x005B, 0x0070, 0x007F, + 0x0089, 0xFF66, 0xFF68, 0xFF6C, 0xFF73, 0xFF7C, 0xFF87, 0xFF93, 0xFFA1, + 0xFFB0, 0xFFC0, 0xFFD0, 0xFFE0, 0xFFF0, 0x0001, 0x0010, 0x001E, 0x002A, + 0x0035, 0x003E, 0x0045, 0x0049, 0x004B, 0x0049, 0x0045, 0x003E, 0x0035, + 0x002A, 0x001E, 0x0010, 0x0001, 0xFFF0, 0xFFE0, 0xFFD0, 0xFFC0, 0xFFB0, + 0xFFA1, 0xFF93, 0xFF87, 0xFF7C, 0xFF73, 0xFF6C, 0xFF68, 0xAB83, 0xAB7D, + 0xAB6D, 0xAB53, 0xAB31, 0xAB08, 0xAAD9, 0xAAA5, 0xAA6D, 0xAA33, 0xA9F6, + 0xA9B9, 0xA97D, 0xA942, 0xA90A, 0xA8D6, 0xA8A7, 0xA87E, 0xA85C, 0xA843, + 0xA833, 0xA82D, 0xA833, 0xA843, 0xA85C, 0xA87E, 0xA8A7, 0xA8D6, 0xA90A, + 0xA942, 0xA97D, 0xA9B9, 0xA9F6, 0xAA33, 0xAA6D, 0xAAA5, 0xAAD9, 0xAB08, + 0xAB31, 0xAB53, 0xAB6D, 0xAB7D, + },{ + 0x0028, 0x0000, 0x001F, 0x0028, 0x0001, 0x0047, 0x0001, 0x0048, 0x0001, + 0x0049, 0x0001, 0x004A, 0x0001, 0x004B, 0x0001, 0x004C, 0x0001, 0x004D, + 0x002A, 0x004E, 0x002A, 0x0078, 0x002A, 0x00A2, 0x002A, 0x00CC, 0x002A, + 0x00F6, 0x002A, 0x0120, 0x0001, 0x014A, 0x0001, 0x014B, 0x0001, 0x014C, + 0x002A, 0x014D, 0x002A, 0x0177, 0x002A, 0x01A1, 0x0027, 0x01CB, 0x0001, + 0x01F2, 0x002A, 0x01F3, 0x0001, 0x021D, 0x0001, 0x021E, 0x0001, 0x021F, + 0x0001, 0x0220, 0x0001, 0x0221, 0x0001, 0x0222, 0x002A, 0x0223, 0x002A, + 0x024D, 0x002A, 0x0277, 0x0001, 0x02A1, 0x0028, 0x02A2, 0x002A, 0x02CA, + 0x002A, 0x02F4, 0x002A, 0x031E, 0x002A, 0x0348, 0x0001, 0x0372, 0x0001, + 0x0373, 0x0001, 0x0374, 0x0001, 0x0375, 0x0001, 0x0376, 0x0001, 0x0377, + 0x002A, 0x0378, 0x002A, 0x03A2, 0x002A, 0x03CC, 0x002A, 0x03F6, 0x002A, + 0x0420, 0x002A, 0x044A, 0x0001, 0x0474, 0x0001, 0x0475, 0x0001, 0x0476, + 0x002A, 0x0477, 0x002A, 0x04A1, 0x002A, 0x04CB, 0x0027, 0x04F5, 0x000D, + 0x051C, 0x002A, 0x0529, 0x002A, 0x0553, 0x002A, 0x057D, 0x002A, 0x05A7, +}); + +WARIO_ANIM_CS_MENU = "wario_anim_cs_menu" +smlua_anim_util_register_animation(WARIO_ANIM_CS_MENU, + 0, + 0, + 0, + 0, + 41, + { + 0x0000, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B2, 0x00B1, 0x00B1, 0x00B0, + 0x00B0, 0x00AF, 0x00AE, 0x00AE, 0x00AD, 0x00AD, 0x00AC, 0x00AB, 0x00AB, + 0x00AB, 0x00AA, 0x00AA, 0x00AA, 0x00AA, 0x00AA, 0x00AA, 0x00AA, 0x00AB, + 0x00AB, 0x00AB, 0x00AC, 0x00AD, 0x00AD, 0x00AE, 0x00AE, 0x00AF, 0x00B0, + 0x00B0, 0x00B1, 0x00B1, 0x00B2, 0x0000, 0x0000, 0x3FFF, 0x0000, 0x5905, + 0xFF7B, 0x3FA3, 0xC1C1, 0xC1C1, 0xC1C1, 0xC1C2, 0xC1C2, 0xC1C3, 0xC1C4, + 0xC1C5, 0xC1C7, 0xC1C8, 0xC1C9, 0xC1CB, 0xC1CC, 0xC1CD, 0xC1CE, 0xC1D0, + 0xC1D1, 0xC1D1, 0xC1D2, 0xC1D3, 0xC1D3, 0xC1D3, 0xC1D3, 0xC1D3, 0xC1D2, + 0xC1D1, 0xC1D1, 0xC1D0, 0xC1CE, 0xC1CD, 0xC1CC, 0xC1CB, 0xC1C9, 0xC1C8, + 0xC1C7, 0xC1C5, 0xC1C4, 0xC1C3, 0xC1C2, 0xC1C2, 0xC1C1, 0xFF11, 0xFF00, + 0xFECC, 0xFE7A, 0xFE0E, 0xFD8B, 0xFCF5, 0xFC4E, 0xFB9B, 0xFAE0, 0xFA1F, + 0xF95C, 0xF89B, 0xF7E0, 0xF72D, 0xF686, 0xF5F0, 0xF56D, 0xF501, 0xF4AF, + 0xF47B, 0xF469, 0xF47B, 0xF4AF, 0xF501, 0xF56D, 0xF5F0, 0xF686, 0xF72D, + 0xF7E0, 0xF89B, 0xF95C, 0xFA1F, 0xFAE0, 0xFB9B, 0xFC4E, 0xFCF5, 0xFD8B, + 0xFE0E, 0xFE7A, 0xFECC, 0xFF00, 0xF9D9, 0xF9D8, 0xF9D6, 0xF9D2, 0xF9CE, + 0xF9C8, 0xF9C1, 0xF9BA, 0xF9B2, 0xF9A9, 0xF9A1, 0xF998, 0xF990, 0xF987, + 0xF97F, 0xF978, 0xF971, 0xF96B, 0xF967, 0xF963, 0xF961, 0xF960, 0xF961, + 0xF963, 0xF967, 0xF96B, 0xF971, 0xF978, 0xF97F, 0xF987, 0xF990, 0xF998, + 0xF9A1, 0xF9A9, 0xF9B2, 0xF9BA, 0xF9C1, 0xF9C8, 0xF9CE, 0xF9D2, 0xF9D6, + 0xF9D8, 0x0A3A, 0x0A39, 0x0A37, 0x0A33, 0x0A2F, 0x0A29, 0x0A23, 0x0A1C, + 0x0A14, 0x0A0C, 0x0A04, 0x09FC, 0x09F4, 0x09EC, 0x09E5, 0x09DE, 0x09D7, + 0x09D2, 0x09CD, 0x09CA, 0x09C8, 0x09C7, 0x09C8, 0x09CA, 0x09CD, 0x09D2, + 0x09D7, 0x09DE, 0x09E5, 0x09EC, 0x09F4, 0x09FC, 0x0A04, 0x0A0C, 0x0A14, + 0x0A1C, 0x0A23, 0x0A29, 0x0A2F, 0x0A33, 0x0A37, 0x0A39, 0xFF75, 0xFF6B, + 0xFF4C, 0xFF1C, 0xFEDC, 0xFE8E, 0xFE35, 0xFDD2, 0xFD68, 0xFCF9, 0xFC87, + 0xFC14, 0xFBA1, 0xFB32, 0xFAC8, 0xFA66, 0xFA0D, 0xF9BF, 0xF97F, 0xF94F, + 0xF930, 0xF925, 0xF930, 0xF94F, 0xF97F, 0xF9BF, 0xFA0D, 0xFA66, 0xFAC8, + 0xFB32, 0xFBA1, 0xFC14, 0xFC87, 0xFCF9, 0xFD68, 0xFDD2, 0xFE35, 0xFE8E, + 0xFEDC, 0xFF1C, 0xFF4C, 0xFF6B, 0xFDB4, 0xFDC7, 0xFDFC, 0xFE51, 0xFEC2, + 0xFF4B, 0xFFE8, 0x0096, 0x0151, 0x0214, 0x02DE, 0x03A9, 0x0472, 0x0535, + 0x05F0, 0x069D, 0x073A, 0x07C3, 0x0834, 0x0889, 0x08BF, 0x08D1, 0x08BF, + 0x0889, 0x0834, 0x07C3, 0x073A, 0x069D, 0x05F0, 0x0535, 0x0472, 0x03A9, + 0x02DE, 0x0214, 0x0151, 0x0096, 0xFFE8, 0xFF4B, 0xFEC2, 0xFE51, 0xFDFC, + 0xFDC7, 0xFFFE, 0x0001, 0xC170, 0xD482, 0xD490, 0xD4B9, 0xD4FD, 0xD55A, + 0xD5CF, 0xD65A, 0xD6FB, 0xD7B1, 0xD879, 0xD954, 0xDA40, 0xDB3B, 0xDC45, + 0xDD5D, 0xDE80, 0xDFAF, 0xE0E8, 0xE22A, 0xE304, 0xE22A, 0xE400, 0xE22A, + 0xE304, 0xE22A, 0xE0E8, 0xDFAF, 0xDE80, 0xDD5D, 0xDC45, 0xDB3B, 0xDA40, + 0xD954, 0xD879, 0xD7B1, 0xD6FB, 0xD65A, 0xD5CF, 0xD55A, 0xD4FD, 0xD4B9, + 0xD490, 0xD13B, 0xD131, 0xD116, 0xD0EB, 0xD0B1, 0xD06B, 0xD01A, 0xCFBF, + 0xCF5C, 0xCEF4, 0xCE87, 0xCE18, 0xCDA7, 0xCD37, 0xCCCA, 0xCC61, 0xCBFD, + 0xCBA1, 0xCB4E, 0xCB1C, 0xCB4E, 0xCAE1, 0xCB4E, 0xCB1C, 0xCB4E, 0xCBA1, + 0xCBFD, 0xCC61, 0xCCCA, 0xCD38, 0xCDA7, 0xCE18, 0xCE87, 0xCEF4, 0xCF5C, + 0xCFBF, 0xD01A, 0xD06B, 0xD0B1, 0xD0EB, 0xD116, 0xD131, 0xB677, 0xB677, + 0xB674, 0xB66E, 0xB662, 0xB64F, 0xB632, 0xB609, 0xB5D3, 0xB58D, 0xB537, + 0xB4CD, 0xB44D, 0xB3B7, 0xB308, 0xB23E, 0xB157, 0xB051, 0xAF2B, 0xAE3C, + 0xAF2B, 0xAD37, 0xAF2B, 0xAE3C, 0xAF2B, 0xB051, 0xB157, 0xB23E, 0xB308, + 0xB3B7, 0xB44D, 0xB4CD, 0xB537, 0xB58D, 0xB5D3, 0xB609, 0xB632, 0xB64F, + 0xB662, 0xB66E, 0xB674, 0xB677, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, + 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, + 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, + 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xCFE0, 0xCFC7, 0xCF7F, + 0xCF0E, 0xCE79, 0xCDC4, 0xCCF4, 0xCC10, 0xCB1B, 0xCA1A, 0xC914, 0xC80C, + 0xC709, 0xC60E, 0xC521, 0xC447, 0xC385, 0xC2E0, 0xC25D, 0xC219, 0xC25D, + 0xC1BE, 0xC25D, 0xC219, 0xC25D, 0xC2E0, 0xC385, 0xC447, 0xC521, 0xC60E, + 0xC709, 0xC80C, 0xC914, 0xCA1A, 0xCB1B, 0xCC10, 0xCCF4, 0xCDC4, 0xCE79, + 0xCF0E, 0xCF7F, 0xCFC7, 0xBDF0, 0xF19F, 0xE2DE, 0xFFFE, 0x0001, 0xC170, + 0x3C6D, 0x3B58, 0x3844, 0x3371, 0x2D1F, 0x258E, 0x1CFD, 0x13AC, 0x09DC, + 0xFFCA, 0x75BB, 0x6BEA, 0x629A, 0x5A09, 0x5277, 0x4C25, 0x4752, 0x443E, + 0x4329, 0x437C, 0x4329, 0x431C, 0x4329, 0x437C, 0x4329, 0x443E, 0x4752, + 0x4C25, 0x5277, 0x5A09, 0x629A, 0x6BEA, 0x75BB, 0xFFCA, 0x09DC, 0x13AC, + 0x1CFD, 0x258E, 0x2D1F, 0x3371, 0x3844, 0x3B58, 0x3B00, 0x3B06, 0x3B15, + 0x3B2E, 0x3B4E, 0x3B75, 0x3BA1, 0x3BD0, 0x3C02, 0x3C36, 0x4396, 0x4364, + 0x4335, 0x4309, 0x42E2, 0x42C2, 0x42AA, 0x429A, 0x4294, 0x42F3, 0x4294, + 0x434E, 0x4294, 0x42F3, 0x4294, 0x429A, 0x42AA, 0x42C2, 0x42E2, 0x4309, + 0x4335, 0x4364, 0x4396, 0x3C36, 0x3C02, 0x3BD0, 0x3BA1, 0x3B75, 0x3B4E, + 0x3B2E, 0x3B15, 0x3B06, 0xC81A, 0xC715, 0xC42F, 0xBFA4, 0xB9B1, 0xB290, + 0xAA7F, 0xA1BA, 0x987C, 0x8F02, 0x0588, 0xFC49, 0xF384, 0xEB73, 0xE452, + 0xDE5E, 0xD9D3, 0xD6EE, 0xD5E9, 0xD62F, 0xD5E9, 0xD5CF, 0xD5E9, 0xD62F, + 0xD5E9, 0xD6EE, 0xD9D3, 0xDE5E, 0xE452, 0xEB73, 0xF384, 0xFC49, 0x0588, + 0x8F02, 0x987C, 0xA1BA, 0xAA7F, 0xB290, 0xB9B1, 0xBFA4, 0xC42F, 0xC715, + 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xD5E1, 0xD5C8, + 0xD581, 0xD510, 0xD47A, 0xD3C5, 0xD2F6, 0xD211, 0xD11C, 0xD01C, 0xCF15, + 0xCE0E, 0xCD0A, 0xCC0F, 0xCB22, 0xCA48, 0xC986, 0xC8E1, 0xC85E, 0xC81A, + 0xC85E, 0xC7BF, 0xC85E, 0xC81A, 0xC85E, 0xC8E1, 0xC986, 0xCA48, 0xCB22, + 0xCC0F, 0xCD0A, 0xCE0E, 0xCF15, 0xD01C, 0xD11C, 0xD211, 0xD2F6, 0xD3C5, + 0xD47A, 0xD510, 0xD581, 0xD5C8, 0x4330, 0x04EE, 0xE37A, 0x0000, 0xFFFF, + 0xBF5E, 0x1C79, 0x1C7A, 0x1C7B, 0x1C7E, 0x1C82, 0x1C86, 0x1C8B, 0x1C91, + 0x1C97, 0x1C9D, 0x1CA4, 0x1CAB, 0x1CB1, 0x1CB7, 0x1CBE, 0x1CC3, 0x1CC8, + 0x1CCD, 0x1CD0, 0x1CD3, 0x1CD5, 0x1CD6, 0x1CD5, 0x1CD3, 0x1CD0, 0x1CCD, + 0x1CC8, 0x1CC3, 0x1CBE, 0x1CB7, 0x1CB1, 0x1CAB, 0x1CA4, 0x1C9D, 0x1C97, + 0x1C91, 0x1C8B, 0x1C86, 0x1C82, 0x1C7E, 0x1C7B, 0x1C7A, 0xF46A, 0xF46C, + 0xF471, 0xF47A, 0xF485, 0xF493, 0xF4A2, 0xF4B4, 0xF4C6, 0xF4DA, 0xF4EE, + 0xF502, 0xF516, 0xF529, 0xF53C, 0xF54D, 0xF55D, 0xF56A, 0xF575, 0xF57E, + 0xF583, 0xF585, 0xF583, 0xF57E, 0xF575, 0xF56A, 0xF55D, 0xF54D, 0xF53C, + 0xF529, 0xF516, 0xF502, 0xF4EE, 0xF4DA, 0xF4C6, 0xF4B4, 0xF4A2, 0xF493, + 0xF485, 0xF47A, 0xF471, 0xF46C, 0xCBF7, 0xCBF5, 0xCBEE, 0xCBE4, 0xCBD6, + 0xCBC6, 0xCBB3, 0xCB9E, 0xCB87, 0xCB6F, 0xCB57, 0xCB3E, 0xCB25, 0xCB0E, + 0xCAF7, 0xCAE2, 0xCACF, 0xCABE, 0xCAB0, 0xCAA6, 0xCAA0, 0xCA9D, 0xCAA0, + 0xCAA6, 0xCAB0, 0xCABE, 0xCACF, 0xCAE2, 0xCAF7, 0xCB0E, 0xCB25, 0xCB3E, + 0xCB57, 0xCB6F, 0xCB87, 0xCB9E, 0xCBB3, 0xCBC6, 0xCBD6, 0xCBE4, 0xCBEE, + 0xCBF5, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x328E, 0x32A9, 0x32F4, + 0x336C, 0x340B, 0x34CB, 0x35A8, 0x369C, 0x37A2, 0x38B5, 0x39D0, 0x3AEE, + 0x3C09, 0x3D1C, 0x3E23, 0x3F17, 0x3FF4, 0x40B4, 0x4153, 0x41CA, 0x4216, + 0x4230, 0x4216, 0x41CA, 0x4153, 0x40B4, 0x3FF4, 0x3F17, 0x3E23, 0x3D1C, + 0x3C09, 0x3AEE, 0x39D0, 0x38B5, 0x37A2, 0x369C, 0x35A8, 0x34CB, 0x340B, + 0x336C, 0x32F4, 0x32A9, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, + 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0xAD50, + 0xAD40, 0xAD12, 0xACCA, 0xAC69, 0xABF4, 0xAB6E, 0xAADA, 0xAA3A, 0xA993, + 0xA8E7, 0xA839, 0xA78D, 0xA6E6, 0xA647, 0xA5B2, 0xA52C, 0xA4B7, 0xA457, + 0xA40E, 0xA3E0, 0xA3D0, 0xA3E0, 0xA40E, 0xA457, 0xA4B7, 0xA52C, 0xA5B2, + 0xA647, 0xA6E6, 0xA78D, 0xA839, 0xA8E7, 0xA993, 0xAA3A, 0xAADA, 0xAB6E, + 0xABF4, 0xAC69, 0xACCA, 0xAD12, 0xAD40, 0x0000, 0xFFFF, 0xBF5E, 0x22E0, + 0x22DB, 0x22CB, 0x22B1, 0x2290, 0x2267, 0x2238, 0x2204, 0x21CD, 0x2192, + 0x2156, 0x211A, 0x20DE, 0x20A4, 0x206C, 0x2038, 0x2009, 0x1FE1, 0x1FBF, + 0x1FA6, 0x1F96, 0x1F90, 0x1F96, 0x1FA6, 0x1FBF, 0x1FE1, 0x2009, 0x2038, + 0x206C, 0x20A4, 0x20DE, 0x211A, 0x2156, 0x2192, 0x21CD, 0x2204, 0x2238, + 0x2267, 0x2290, 0x22B1, 0x22CB, 0x22DB, 0x1496, 0x149F, 0x14BA, 0x14E4, + 0x151B, 0x155E, 0x15AB, 0x1600, 0x165C, 0x16BC, 0x171F, 0x1783, 0x17E5, + 0x1845, 0x18A1, 0x18F6, 0x1943, 0x1986, 0x19BE, 0x19E8, 0x1A02, 0x1A0B, + 0x1A02, 0x19E8, 0x19BE, 0x1986, 0x1943, 0x18F6, 0x18A1, 0x1845, 0x17E5, + 0x1783, 0x171F, 0x16BC, 0x165C, 0x1600, 0x15AB, 0x155E, 0x151B, 0x14E4, + 0x14BA, 0x149F, 0xAFCA, 0xAFBF, 0xAFA2, 0xAF73, 0xAF35, 0xAEEA, 0xAE94, + 0xAE35, 0xADCF, 0xAD63, 0xACF5, 0xAC85, 0xAC17, 0xABAC, 0xAB45, 0xAAE6, + 0xAA90, 0xAA45, 0xAA07, 0xA9D8, 0xA9BB, 0xA9B1, 0xA9BB, 0xA9D8, 0xAA07, + 0xAA45, 0xAA90, 0xAAE6, 0xAB45, 0xABAC, 0xAC17, 0xAC85, 0xACF5, 0xAD63, + 0xADCF, 0xAE35, 0xAE94, 0xAEEA, 0xAF35, 0xAF73, 0xAFA2, 0xAFBF, 0xFFFF, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, + 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xFFFF, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, + 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x1E4A, 0x1E63, + 0x1EAB, 0x1F1D, 0x1FB4, 0x206A, 0x213D, 0x2225, 0x231E, 0x2424, 0x2531, + 0x2641, 0x274E, 0x2854, 0x294E, 0x2A36, 0x2B08, 0x2BBF, 0x2C56, 0x2CC7, + 0x2D0F, 0x2D28, 0x2D0F, 0x2CC7, 0x2C56, 0x2BBF, 0x2B08, 0x2A36, 0x294E, + 0x2854, 0x274E, 0x2641, 0x2531, 0x2424, 0x231E, 0x2225, 0x213D, 0x206A, + 0x1FB4, 0x1F1D, 0x1EAB, 0x1E63, 0xFFFF, 0x0000, 0x0001, 0x0002, 0x0004, + 0x0005, 0x0008, 0x000A, 0x000C, 0x000F, 0x0012, 0x0014, 0x0017, 0x001A, + 0x001C, 0x001F, 0x0021, 0x0022, 0x0024, 0x0025, 0x0026, 0x0026, 0x0026, + 0x0025, 0x0024, 0x0022, 0x0021, 0x001F, 0x001C, 0x001A, 0x0017, 0x0014, + 0x0012, 0x000F, 0x000C, 0x000A, 0x0008, 0x0005, 0x0004, 0x0002, 0x0001, + 0x0000, 0xFF2F, 0xFF2F, 0xFF2F, 0xFF2F, 0xFF2F, 0xFF30, 0xFF30, 0xFF30, + 0xFF30, 0xFF30, 0xFF31, 0xFF31, 0xFF31, 0xFF31, 0xFF32, 0xFF32, 0xFF32, + 0xFF32, 0xFF32, 0xFF32, 0xFF33, 0xFF33, 0xFF32, 0xFF32, 0xFF32, 0xFF32, + 0xFF32, 0xFF32, 0xFF32, 0xFF31, 0xFF31, 0xFF31, 0xFF31, 0xFF30, 0xFF30, + 0xFF30, 0xFF30, 0xFF30, 0xFF2F, 0xC9D7, 0xC9CB, 0xC9A6, 0xC96D, 0xC921, + 0xC8C4, 0xC85A, 0xC7E5, 0xC767, 0xC6E3, 0xC65C, 0xC5D2, 0xC54B, 0xC4C7, + 0xC449, 0xC3D4, 0xC36A, 0xC30D, 0xC2C1, 0xC288, 0xC263, 0xC257, 0xC263, + 0xC288, 0xC2C1, 0xC30D, 0xC36A, 0xC3D4, 0xC449, 0xC4C7, 0xC54B, 0xC5D2, + 0xC65C, 0xC6E3, 0xC767, 0xC7E5, 0xC85A, 0xC8C4, 0xC921, 0xC96D, 0xC9A6, + 0xC9CB, + },{ + 0x0001, 0x0000, 0x0027, 0x0001, 0x0001, 0x0028, 0x0001, 0x0029, 0x0001, + 0x002A, 0x0001, 0x002B, 0x0001, 0x002C, 0x0001, 0x002D, 0x0001, 0x002E, + 0x0029, 0x002F, 0x002A, 0x0058, 0x002A, 0x0082, 0x002A, 0x00AC, 0x002A, + 0x00D6, 0x002A, 0x0100, 0x0001, 0x012A, 0x0001, 0x012B, 0x0001, 0x012C, + 0x002A, 0x012D, 0x002A, 0x0157, 0x002A, 0x0181, 0x002A, 0x01AB, 0x000E, + 0x01D5, 0x002A, 0x01E3, 0x0001, 0x020D, 0x0001, 0x020E, 0x0001, 0x020F, + 0x0001, 0x0210, 0x0001, 0x0211, 0x0001, 0x0212, 0x002A, 0x0213, 0x002A, + 0x023D, 0x002A, 0x0267, 0x0001, 0x0291, 0x002A, 0x0292, 0x002A, 0x02BC, + 0x0001, 0x02E6, 0x0001, 0x02E7, 0x0001, 0x02E8, 0x0001, 0x02E9, 0x0001, + 0x02EA, 0x0001, 0x02EB, 0x002A, 0x02EC, 0x002A, 0x0316, 0x002A, 0x0340, + 0x0001, 0x036A, 0x0016, 0x036B, 0x002A, 0x0381, 0x0014, 0x03AB, 0x0015, + 0x03BF, 0x002A, 0x03D4, 0x0001, 0x03FE, 0x0001, 0x03FF, 0x0001, 0x0400, + 0x002A, 0x0401, 0x002A, 0x042B, 0x002A, 0x0455, 0x0029, 0x047F, 0x0015, + 0x04A8, 0x002A, 0x04BD, 0x002A, 0x04E7, 0x0027, 0x0511, 0x002A, 0x0538, +}); diff --git a/mods/character-select-coop/dialog.lua b/mods/character-select-coop/dialog.lua index 25c55666f..059945d4d 100644 --- a/mods/character-select-coop/dialog.lua +++ b/mods/character-select-coop/dialog.lua @@ -1,222 +1,54 @@ if incompatibleClient then return 0 end --- Original Made by EliteMasterEric along with CoopDX PR #321 to replace dialog depending on character -- --- https://github.com/coop-deluxe/sm64coopdx/pull/321 -- --- Eric's Original stuffs will be added as soon as there is some way to directly get dialog strings +DEFAULT_DIALOG_NAME = "Mario" -local dialogTable = {} -local function define_cs_dialog(dialogId, unused, linesPerBox, leftOffset, width, str) - dialogTable[dialogId] = { - unused = unused, - linesPerBox = linesPerBox, - leftOffset = leftOffset, - width = width, - str = str, - } -end +local ogDialog = {} -local real_dialog_replace = smlua_text_utils_dialog_replace -_G.smlua_text_utils_dialog_replace = define_cs_dialog - --- All Base SM64 Dialog added to the Dialog Table -define_cs_dialog(DIALOG_000, 1, 6, 30, 200, ("Wow! You're smack in the\nmiddle of the battlefield.\nYou'll find the Power\nStars that Bowser stole\ninside the painting\nworlds.\nFirst, talk to the\nBob-omb Buddy. (Press [B]\nto talk.) He'll certainly\nhelp you out, and so will\nhis comrades in other\nareas.\nTo read signs, stop, face\nthem and press [B]. Press [A]\nor [B] to scroll ahead. You\ncan talk to some other\ncharacters by facing them\nand pressing [B].")) -define_cs_dialog(DIALOG_001, 1, 4, 95, 200, ("Watch out! If you wander\naround here, you're liable\nto be plastered by a\nwater bomb!\nThose enemy Bob-ombs love\nto fight, and they're\nalways finding ways to\nattack.\nThis meadow has become\na battlefield ever since\nthe Big Bob-omb got his\npaws on the Power Star.\nCan you recover the Star\nfor us? Cross the bridge\nand go left up the path\nto find the Big Bob-omb.\nPlease come back to see\nme after you've retrieved\nthe Power Star!")) -define_cs_dialog(DIALOG_002, 1, 4, 95, 200, ("Hey, you! It's dangerous\nahead, so listen up! Take\nmy advice.\n\nCross the two\nbridges ahead, then\nwatch for falling\nwater bombs.\nThe Big Bob-omb at the\ntop of the mountain is\nvery powerful--don't let\nhim grab you!\nWe're Bob-omb Buddies,\nand we're on your side.\nYou can talk to us\nwhenever you'd like to!")) -define_cs_dialog(DIALOG_003, 1, 5, 95, 200, ("Thank you, Mario! The Big\nBob-omb is nothing but a\nbig dud now! But the\nbattle for the castle has\njust begun.\nOther enemies are holding\nthe other Power Stars. If\nyou recover more Stars,\nyou can open new doors\nthat lead to new worlds!\nMy Bob-omb Buddies are\nwaiting for you. Be sure\nto talk to them--they'll\nset up cannons for you.")) -define_cs_dialog(DIALOG_004, 1, 3, 95, 200, ("We're peace-loving\nBob-ombs, so we don't use\ncannons.\nBut if you'd like\nto blast off, we don't\nmind. Help yourself.\nWe'll prepare all of the\ncannons in this course for\nyou to use. Bon Voyage!")) -define_cs_dialog(DIALOG_005, 1, 3, 30, 200, ("Hey, Mario! Is it true\nthat you beat the Big\nBob-omb? Cool!\nYou must be strong. And\npretty fast. So, how fast\nare you, anyway?\nFast enough to beat me...\nKoopa the Quick? I don't\nthink so. Just try me.\nHow about a race to the\nmountaintop, where the\nBig Bob-omb was?\nWhaddya say? When I say\n『Go,』 let the race begin!\n\nReady....\n\n//Go!////Don't Go")) -define_cs_dialog(DIALOG_006, 1, 3, 30, 200, ("Hey!!! Don't try to scam\nME. You've gotta run\nthe whole course.\nLater. Look me up when\nyou want to race for\nreal.")) -define_cs_dialog(DIALOG_007, 1, 5, 30, 200, ("Hufff...fff...pufff...\nWhoa! You...really...are...\nfast! A human blur!\nHere you go--you've won\nit, fair and square!")) -define_cs_dialog(DIALOG_008, 1, 4, 30, 200, ("BEWARE OF CHAIN CHOMP\nExtreme Danger!\nGet close and press [C]▲\nfor a better look.\nScary, huh?\nSee the Red Coin on top\nof the stake?\n\nWhen you collect eight of\nthem, a Power Star will\nappear in the meadow\nacross the bridge.")) -define_cs_dialog(DIALOG_009, 1, 5, 30, 200, ("Long time, no see! Wow,\nhave you gotten fast!\nHave you been training\non the sly, or is it the\npower of the Stars?\nI've been feeling down\nabout losing the last\nrace. This is my home\ncourse--how about a\nrematch?\nThe goal is in\nWindswept Valley.\nReady?\n\n//Go//// Don't Go")) -define_cs_dialog(DIALOG_010, 1, 4, 30, 200, ("You've stepped on the\nWing Cap Switch. Wearing\nthe Wing Cap, you can\nsoar through the sky.\nNow Wing Caps will pop\nout of all the red blocks\nyou find.\n\nWould you like to Save?\n\n//Yes////No")) -define_cs_dialog(DIALOG_011, 1, 4, 30, 200, ("You've just stepped on\nthe Metal Cap Switch!\nThe Metal Cap makes\nMario invincible.\nNow Metal Caps will\npop out of all of the\ngreen blocks you find.\n\nWould you like to Save?\n\n//Yes////No")) -define_cs_dialog(DIALOG_012, 1, 4, 30, 200, ("You've just stepped on\nthe Vanish Cap Switch.\nThe Vanish Cap makes\nMario disappear.\nNow Vanish Caps will pop\nfrom all of the blue\nblocks you find.\n\nWould you like to Save?\n\n//Yes////No")) -define_cs_dialog(DIALOG_013, 1, 5, 30, 200, ("You've collected 100\ncoins! Mario gains more\npower from the castle.\nDo you want to Save?\n//Yes////No")) -define_cs_dialog(DIALOG_014, 1, 4, 30, 200, ("Wow! Another Power Star!\nMario gains more courage\nfrom the power of the\ncastle.\nDo you want to Save?\n\n//You Bet//Not Now")) -define_cs_dialog(DIALOG_015, 1, 4, 30, 200, ("You can punch enemies to\nknock them down. Press [A]\nto jump, [B] to punch.\nPress [A] then [B] to Kick.\nTo pick something up,\npress [B], too. To throw\nsomething you're holding,\npress [B] again.")) -define_cs_dialog(DIALOG_016, 1, 3, 30, 200, ("Hop on the shiny shell and\nride wherever you want to\ngo! Shred those enemies!")) -define_cs_dialog(DIALOG_017, 1, 4, 30, 200, ("I'm the Big Bob-omb, lord\nof all blasting matter,\nking of ka-booms the\nworld over!\nHow dare you scale my\nmountain? By what right\ndo you set foot on my\nimperial mountaintop?\nYou may have eluded my\nguards, but you'll never\nescape my grasp...\n\n...and you'll never take\naway my Power Star. I\nhereby challenge you,\nMario!\nIf you want the Star I\nhold, you must prove\nyourself in battle.\n\nCan you pick me up from\nthe back and hurl me to\nthis royal turf? I think\nthat you cannot!")) -define_cs_dialog(DIALOG_018, 1, 4, 30, 200, ("I'm sleeping because...\n...I'm sleepy. I don't\nlike being disturbed.\nPlease walk quietly.")) -define_cs_dialog(DIALOG_019, 1, 2, 30, 200, ("Shhh! Please walk\nquietly in the hallway!")) -define_cs_dialog(DIALOG_020, 1, 6, 95, 150, ("Dear Mario:\nPlease come to the\ncastle. I've baked\na cake for you.\nYours truly--\nPrincess Toadstool")) -define_cs_dialog(DIALOG_021, 1, 5, 95, 200, ("Welcome.\nNo one's home!\nNow scram--\nand don't come back!\nGwa ha ha!")) -define_cs_dialog(DIALOG_022, 1, 2, 95, 200, ("You need a key to open\nthis door.")) -define_cs_dialog(DIALOG_023, 1, 3, 95, 200, ("This key doesn't fit!\nMaybe it's for the\nbasement...")) -define_cs_dialog(DIALOG_024, 1, 5, 95, 200, ("You need Star power to\nopen this door. Recover a\nPower Star from an enemy\ninside one of the castle's\npaintings.")) -define_cs_dialog(DIALOG_025, 1, 4, 95, 200, ("It takes the power of\n3 Stars to open this\ndoor. You need [%] more\nStars.")) -define_cs_dialog(DIALOG_026, 1, 4, 95, 200, ("It takes the power of\n8 Stars to open this\ndoor. You need [%] more\nStars.")) -define_cs_dialog(DIALOG_027, 1, 4, 95, 200, ("It takes the power of\n30 Stars to open this\ndoor. You need [%] more\nStars.")) -define_cs_dialog(DIALOG_028, 1, 4, 95, 200, ("It takes the power of\n50 Stars to open this\ndoor. You need [%] more\nStars.")) -define_cs_dialog(DIALOG_029, 1, 5, 95, 200, ("To open the door that\nleads to the 『endless』\nstairs, you need 70\nStars.\nBwa ha ha!")) -define_cs_dialog(DIALOG_030, 1, 6, 30, 200, ("Hello! The Lakitu Bros.,\ncutting in with a live\nupdate on Mario's\nprogress. He's about to\nlearn a technique for\nsneaking up on enemies.\nThe trick is this: He has\nto walk very slowly in\norder to walk quietly.\n\n\n\nAnd wrapping up filming\ntechniques reported on\nearlier, you can take a\nlook around using [C]▶ and\n[C]◀. Press [C]▼ to view the\naction from a distance.\nWhen you can't move the\ncamera any farther, the\nbuzzer will sound. This is\nthe Lakitu Bros.,\nsigning off.")) -define_cs_dialog(DIALOG_031, 1, 5, 30, 200, ("No way! You beat me...\nagain!! And I just spent\nmy entire savings on\nthese new Koopa\nMach 1 Sprint shoes!\nHere, I guess I have to\nhand over this Star to\nthe winner of the race.\nCongrats, Mario!")) -define_cs_dialog(DIALOG_032, 1, 5, 30, 200, ("If you get the Wing Cap,\nyou can fly! Put the cap\non, then do a Triple\nJump--jump three times\nin a row--to take off.\nYou can fly even higher\nif you blast out of a\ncannon wearing the\nWing Cap!\n\nUse the [C] Buttons to look\naround while flying, and\npress [Z] to land.")) -define_cs_dialog(DIALOG_033, 1, 6, 30, 200, ("Ciao! You've reached\nPrincess Toadstool's\ncastle via a warp pipe.\nUsing the controller is a\npiece of cake. Press [A] to\njump and [B] to attack.\nPress [B] to read signs,\ntoo. Use the Control Stick\nin the center of the\ncontroller to move Mario\naround. Now, head for\nthe castle.")) -define_cs_dialog(DIALOG_034, 1, 6, 30, 200, ("Good afternoon. The\nLakitu Bros., here,\nreporting live from just\noutside the Princess's\ncastle.\n\nMario has just arrived\non the scene, and we'll\nbe filming the action live\nas he enters the castle\nand pursues the missing\nPower Stars.\nAs seasoned cameramen,\nwe'll be shooting from the\nrecommended angle, but\nyou can change the\ncamera angle by pressing\nthe [C] Buttons.\nIf we can't adjust the\nview any further, we'll\nbuzz. To take a look at\nthe surroundings, stop\nand press [C]▲.\n\nPress [A] to resume play.\nSwitch camera modes with\nthe [R] Button. Signs along\nthe way will review these\ninstructions.\n\nFor now, reporting live,\nthis has been the\nLakitu Bros.")) -define_cs_dialog(DIALOG_035, 1, 5, 30, 200, ("There are four camera, or\n『[C],』 Buttons. Press [C]▲\nto look around using the\nControl Stick.\n\nYou'll usually see Mario\nthrough Lakitu's camera.\nIt is the camera\nrecommended for normal\nplay.\nYou can change angles by\npressing [C]▶. If you press\n[R], the view switches to\nMario's camera, which\nis directly behind him.\nPress [R] again to return\nto Lakitu's camera. Press\n[C]▼ to see Mario from\nafar, using either\nLakitu's or Mario's view.")) -define_cs_dialog(DIALOG_036, 1, 5, 30, 200, ("OBSERVATION PLATFORM\nPress [C]▲ to take a look\naround. Don't miss\nanything!\n\nPress [R] to switch to\nMario's camera. It\nalways follows Mario.\nPress [R] again to switch\nto Lakitu's camera.\nPause the game and\nswitch the mode to 『fix』\nthe camera in place while\nholding [R]. Give it a try!")) -define_cs_dialog(DIALOG_037, 1, 2, 30, 200, ("I win! You lose!\nHa ha ha ha!\nYou're no slouch, but I'm\na better sledder!\nBetter luck next time!")) -define_cs_dialog(DIALOG_038, 1, 3, 95, 200, ("Reacting to the Star\npower, the door slowly\nopens.")) -define_cs_dialog(DIALOG_039, 1, 4, 30, 200, ("No visitors allowed,\nby decree of\nthe Big Bob-omb\n\nI shall never surrender my\nStars, for they hold the\npower of the castle in\ntheir glow.\nThey were a gift from\nBowser, the Koopa King\nhimself, and they lie well\nhidden within my realm.\nNot a whisper of their\nwhereabouts shall leave\nmy lips. Oh, all right,\nperhaps one hint:\nHeed the Star names at\nthe beginning of the\ncourse.\n//--The Big Bob-omb")) -define_cs_dialog(DIALOG_040, 1, 3, 30, 200, ("Warning!\nCold, Cold Crevasse\nBelow!")) -define_cs_dialog(DIALOG_041, 1, 3, 30, 200, ("I win! You lose!\nHa ha ha!\n\nThat's what you get for\nmessin' with Koopa the\nQuick.\nBetter luck next time!")) -define_cs_dialog(DIALOG_042, 1, 4, 30, 200, ("Caution! Narrow Bridge!\nCross slowly!\n\n\nYou can jump to the edge\nof the cliff and hang on,\nand you can climb off the\nedge if you move slowly.\nWhen you want to let go,\neither press [Z] or press\nthe Control Stick in the\ndirection of Mario's back.\nTo climb up, press Up on\nthe Control Stick. To\nscurry up quickly, press\nthe [A] Button.")) -define_cs_dialog(DIALOG_043, 1, 5, 30, 200, ("If you jump and hold the\n[A] Button, you can hang on\nto some objects overhead.\nIt's the same as grabbing\na flying bird!")) -define_cs_dialog(DIALOG_044, 1, 5, 95, 200, ("Whooo's there? Whooo\nwoke me up? It's still\ndaylight--I should be\nsleeping!\n\nHey, as long as I'm\nawake, why not take a\nshort flight with me?\nPress and hold [A] to grab\non. Release [A] to let go.\nI'll take you wherever\nyou want to go, as long\nas my wings hold out.\nWatch my shadow, and\ngrab on.")) -define_cs_dialog(DIALOG_045, 1, 6, 95, 200, ("Whew! I'm just about\nflapped out. You should\nlay off the pasta, Mario!\nThat's it for now. Press\n[A] to let go. Okay,\nbye byyyyyyeeee!")) -define_cs_dialog(DIALOG_046, 1, 5, 30, 200, ("You have to master three\nimportant jumping\ntechniques.\nFirst try the Triple Jump.\n\nRun fast, then jump three\ntimes, one, two, three.\nIf you time the jumps\nright, you'll hop, skip,\nthen jump really high.\nNext, go for distance\nwith the Long Jump. Run,\npress [Z] to crouch then [A]\nto jump really far.\n\nTo do the Wall Kick, press\n[A] to jump at a wall, then\njump again when you hit\nthe wall.\n\nGot that? Triple Jump,\nLong Jump, Wall Kick.\nPractice, practice,\npractice. You don't stand\na chance without them.")) -define_cs_dialog(DIALOG_047, 1, 2, 95, 200, ("Hi! I'll prepare the\ncannon for you!")) -define_cs_dialog(DIALOG_048, 1, 4, 30, 200, ("Snow Mountain Summit\nWatch for slippery\nconditions! Please enter\nthe cottage first.")) -define_cs_dialog(DIALOG_049, 1, 5, 30, 200, ("Remember that tricky Wall\nKick jump? It's a\ntechnique you'll have to\nmaster in order to reach\nhigh places.\nUse it to jump from wall\nto wall. Press the\nControl Stick in the\ndirection you want to\nbounce to gain momentum.\nPractice makes perfect!")) -define_cs_dialog(DIALOG_050, 1, 4, 30, 200, ("Hold [Z] to crouch and\nslide down a slope.\nOr press [Z] while in the\nair to Pound the Ground!\nIf you stop, crouch, then\njump, you'll do a\nBackward Somersault!\nGot that?\nThere's more. Crouch and\nthen jump to do a\nLong Jump! Or crouch and\nwalk to...never mind.")) -define_cs_dialog(DIALOG_051, 1, 6, 30, 200, ("Climbing's easy! When you\njump at trees, poles or\npillars, you'll grab them\nautomatically. Press [A] to\njump off backward.\n\nTo rotate around the\nobject, press Right or\nLeft on the Control Stick.\nWhen you reach the top,\npress Up to do a\nhandstand!\nJump off from the\nhandstand for a high,\nstylin' dismount.")) -define_cs_dialog(DIALOG_052, 1, 5, 30, 200, ("Stop and press [Z] to\ncrouch, then press [A]\nto do a high, Backward\nSomersault!\n\nTo perform a Side\nSomersault, run, do a\nsharp U-turn and jump.\nYou can catch lots of\nair with both jumps.")) -define_cs_dialog(DIALOG_053, 1, 5, 30, 200, ("Sometimes, if you pass\nthrough a coin ring or\nfind a secret point in a\ncourse, a red number will\nappear.\nIf you trigger five red\nnumbers, a secret Star\nwill show up.")) -define_cs_dialog(DIALOG_054, 1, 5, 30, 200, ("Welcome to the snow\nslide! Hop on! To speed\nup, press forward on the\nControl Stick. To slow\ndown, pull back.")) -define_cs_dialog(DIALOG_055, 1, 4, 30, 200, ("Hey-ey, Mario, buddy,\nhowzit goin'? Step right\nup. You look like a fast\nsleddin' kind of guy.\nI know speed when I see\nit, yes siree--I'm the\nworld champion sledder,\nyou know. Whaddya say?\nHow about a race?\nReady...\n\n//Go//// Don't Go")) -define_cs_dialog(DIALOG_056, 1, 6, 30, 200, ("You brrrr-oke my record!\nUnbelievable! I knew\nthat you were the coolest.\nNow you've proven\nthat you're also the\nfastest!\nI can't award you a gold\nmedal, but here, take this\nStar instead. You've\nearned it!")) -define_cs_dialog(DIALOG_057, 1, 4, 30, 200, ("Egad! My baby!! Have you\nseen my baby??? She's\nthe most precious baby in\nthe whole wide world.\n(They say she has my\nbeak...) I just can't\nremember where I left\nher.\nLet's see...I stopped\nfor herring and ice cubes,\nthen I...oohh! I just\ndon't know!")) -define_cs_dialog(DIALOG_058, 1, 4, 30, 200, ("You found my precious,\nprecious baby! Where\nhave you been? How can\nI ever thank you, Mario?\nOh, I do have this...\n...Star. Here, take it\nwith my eternal\ngratitude.")) -define_cs_dialog(DIALOG_059, 1, 4, 30, 200, ("That's not my baby! She\nlooks nothing like me!\nHer parents must be\nworried sick!")) -define_cs_dialog(DIALOG_060, 1, 4, 30, 200, ("ATTENTION!\nRead Before Diving In!\n\n\nIf you stay under the\nwater for too long, you'll\nrun out of oxygen.\n\nReturn to the surface for\nair or find an air bubble\nor coins to breathe while\nunderwater.\nPress [A] to swim. Hold [A]\nto swim slow and steady.\nTap [A] with smooth timing\nto gain speed.\nPress Up on the\nControl Stick and press [A]\nto dive.\n\nPress Down on the Control\nStick and press [A] to\nreturn to the surface.\n\nHold Down and press [A]\nwhile on the surface near\nthe edge of the water to\njump out.")) -define_cs_dialog(DIALOG_061, 1, 4, 30, 200, ("BRRR! Frostbite Danger!\nDo not swim here.\nI'm serious.\n/--The Penguin")) -define_cs_dialog(DIALOG_062, 1, 3, 30, 200, ("Hidden inside the green\nblock is the amazing\nMetal Cap.\nWearing it, you won't\ncatch fire or be hurt\nby enemy attacks.\nYou don't even have to\nbreathe while wearing it.\n\nThe only problem:\nYou can't swim in it.")) -define_cs_dialog(DIALOG_063, 1, 5, 30, 200, ("The Vanish Cap is inside\nthe blue block. Mr. I.\nwill be surprised, since\nyou'll be invisible when\nyou wear it!\nEven the Big Boo will be\nfooled--and you can walk\nthrough secret walls, too.")) -define_cs_dialog(DIALOG_064, 1, 5, 30, 200, ("When you put on the Wing\nCap that comes from a\nred block, do the Triple\nJump to soar high into\nthe sky.\nUse the Control Stick to\nguide Mario. Pull back to\nto fly up, press forward\nto nose down, and press [Z]\nto land.")) -define_cs_dialog(DIALOG_065, 1, 6, 30, 200, ("Swimming Lessons!\nTap [A] to do the breast\nstroke. If you time the\ntaps right, you'll swim\nfast.\n\nPress and hold [A] to do a\nslow, steady flutter kick.\nPress Up on the Control\nStick to dive, and pull\nback on the stick to head\nfor the surface.\nTo jump out of the water,\nhold Down on the Control\nStick, then press [A].\nEasy as pie, right?\n\n\nBut remember:\nMario can't breathe under\nthe water! Return to the\nsurface for air when the\nPower Meter runs low.\n\nAnd one last thing: You\ncan't open doors that\nare underwater.")) -define_cs_dialog(DIALOG_066, 1, 5, 30, 200, ("Mario, it's Peach!\nPlease be careful! Bowser\nis so wicked! He will try\nto burn you with his\nhorrible flame breath.\nRun around behind and\ngrab him by the tail with\nthe [B] Button. Once you\ngrab hold, swing him\naround in great circles.\nRotate the Control Stick\nto go faster and faster.\nThe faster you swing him,\nthe farther he'll fly.\n\nUse the [C] Buttons to look\naround, Mario. You have\nto throw Bowser into one\nof the bombs in the four\ncorners.\nAim well, then press [B]\nagain to launch Bowser.\nGood luck, Mario! Our\nfate is in your hands.")) -define_cs_dialog(DIALOG_067, 1, 5, 30, 200, ("Tough luck, Mario!\nPrincess Toadstool isn't\nhere...Gwa ha ha!! Go\nahead--just try to grab\nme by the tail!\nYou'll never be able to\nswing ME around! A wimp\nlike you won't throw me\nout of here! Never! Ha!")) -define_cs_dialog(DIALOG_068, 1, 5, 30, 200, ("It's Lethal Lava Land!\nIf you catch fire or fall\ninto a pool of flames,\nyou'll be hopping mad, but\ndon't lose your cool.\nYou can still control\nMario--just try to keep\ncalm!")) -define_cs_dialog(DIALOG_069, 1, 6, 30, 200, ("Sometimes you'll bump into\ninvisible walls at the\nedges of the painting\nworlds. If you hit a wall\nwhile flying, you'll bounce\nback.")) -define_cs_dialog(DIALOG_070, 1, 5, 30, 200, ("You can return to the\ncastle's main hall at any\ntime from the painting\nworlds where the enemies\nlive.\nJust stop, stand still,\npress Start to pause the\ngame, then select\n『Exit Course.』\n\nYou don't have to collect\nall Power Stars in one\ncourse before going on to\nthe next.\n\nReturn later, when you're\nmore experienced, to pick\nup difficult ones.\n\n\nWhenever you find a Star,\na hint for finding the\nnext one will appear on\nthe course's start screen.\n\nYou can, however, collect\nany of the remaining\nStars next. You don't\nhave to recover the one\ndescribed by the hint.")) -define_cs_dialog(DIALOG_071, 1, 3, 30, 200, ("Danger Ahead!\nBeware of the strange\ncloud! Don't inhale!\nIf you feel faint, run for\nhigher ground and fresh\nair!\nCircle: Shelter\nArrow: Entrance-Exit")) -define_cs_dialog(DIALOG_072, 1, 5, 30, 200, ("High winds ahead!\nPull your Cap down tight.\nIf it blows off, you'll\nhave to find it on this\nmountain.")) -define_cs_dialog(DIALOG_073, 1, 4, 95, 200, ("Aarrgh! Ahoy, matey. I\nhave sunken treasure,\nhere, I do.\n\nBut to pluck the plunder,\nyou must open the\nTreasure Chests in the\nright order.\nWhat order is that,\nye say?\n\n\nI'll never tell!\n\n//--The Cap'n")) -define_cs_dialog(DIALOG_074, 1, 5, 30, 200, ("You can grab on to the\nedge of a cliff or ledge\nwith your fingertips and\nhang down from it.\n\nTo drop from the edge,\neither press the Control\nStick in the direction of\nMario's back or press the\n[Z] Button.\nTo get up onto the ledge,\neither press Up on the\nControl Stick or press [A]\nas soon as you grab the\nledge to climb up quickly.")) -define_cs_dialog(DIALOG_075, 1, 5, 30, 200, ("Mario!! My castle is in\ngreat peril. I know that\nBowser is the cause...and\nI know that only you can\nstop him!\nThe doors in the castle\nthat have been sealed by\nBowser can be opened only\nwith Star Power.\n\nBut there are secret\npaths in the castle,\npaths that Bowser hasn't\nfound.\n\nOne of those paths is in\nthis room, and it holds\none of the castle's Secret\nStars!\n\nFind that Secret Star,\nMario! It will help you\non your quest. Please,\nMario, you have to\nhelp us!\nRetrieve all of the\nPower Stars in the castle\nand free us from this\nawful prison!\nPlease!")) -define_cs_dialog(DIALOG_076, 1, 6, 30, 200, ("Thanks to the power of\nthe Stars, life is\nreturning to the castle.\nPlease, Mario, you have\nto give Bowser the boot!\n\nHere, let me tell you a\nlittle something about the\ncastle. In the room with\nthe mirrors, look carefully\nfor anything that's not\nreflected in the mirror.\nAnd when you go to the\nwater town, you can flood\nit with a high jump into\nthe painting. Oh, by the\nway, look what I found!")) -define_cs_dialog(DIALOG_077, 1, 2, 150, 200, ("It is decreed that one\nshall pound the pillars.")) -define_cs_dialog(DIALOG_078, 1, 5, 30, 200, ("Break open the Blue Coin\nBlock by Pounding the\nGround with the [Z] Button.\nOne Blue Coin is worth\nfive Yellow Coins.\nBut you have to hurry!\nThe coins will disappear\nif you're not quick to\ncollect them! Too bad.")) -define_cs_dialog(DIALOG_079, 1, 4, 30, 200, ("Owwwuu! Let me go!\nUukee-kee! I was only\nteasing! Can't you take\na joke?\nI'll tell you what, let's\ntrade. If you let me go,\nI'll give you something\nreally good.\nSo, how about it?\n\n//Free him/ Hold on")) -define_cs_dialog(DIALOG_080, 1, 1, 30, 200, ("Eeeh hee hee hee!")) -define_cs_dialog(DIALOG_081, 1, 4, 30, 200, ("The mystery is of Wet\nor Dry.\nAnd where does the\nsolution lie?\nThe city welcomes visitors\nwith the depth they bring\nas they enter.")) -define_cs_dialog(DIALOG_082, 1, 4, 30, 200, ("Hold on to your hat! If\nyou lose it, you'll be\ninjured easily.\n\nIf you do lose your Cap,\nyou'll have to find it in\nthe course where you\nlost it.\nOh, boy, it's not looking\ngood for Peach. She's\nstill trapped somewhere\ninside the walls.\nPlease, Mario, you have\nto help her! Did you know\nthat there are enemy\nworlds inside the walls?\nYup. It's true. Bowser's\ntroops are there, too.\nOh, here, take this. I've\nbeen keeping it for you.")) -define_cs_dialog(DIALOG_083, 1, 6, 30, 200, ("There's something strange\nabout that clock. As you\njump inside, watch the\nposition of the big hand.\nOh, look what I found!\nHere, Mario, catch!")) -define_cs_dialog(DIALOG_084, 1, 3, 30, 200, ("Yeeoww! Unhand me,\nbrute! I'm late, so late,\nI must make haste!\nThis shiny thing? Mine!\nIt's mine. Finders,\nkeepers, losers...\nLate, late, late...\nOuch! Take it then! A\ngift from Bowser, it was.\nNow let me be! I have a\ndate! I cannot be late\nfor tea!")) -define_cs_dialog(DIALOG_085, 1, 5, 30, 200, ("You don't stand a ghost\nof a chance in this house.\nIf you walk out of here,\nyou deserve...\n...a Ghoul Medal...")) -define_cs_dialog(DIALOG_086, 1, 3, 30, 200, ("Running around in circles\nmakes some bad guys roll\ntheir eyes.")) -define_cs_dialog(DIALOG_087, 1, 4, 30, 200, ("Santa Claus isn't the only\none who can go down a\nchimney! Come on in!\n/--Cabin Proprietor")) -define_cs_dialog(DIALOG_088, 1, 5, 30, 200, ("Work Elevator\nFor those who get off\nhere: Grab the pole to the\nleft and slide carefully\ndown.")) -define_cs_dialog(DIALOG_089, 1, 5, 95, 200, ("Both ways fraught with\ndanger! Watch your feet!\nThose who can't do the\nLong Jump, tsk, tsk. Make\nyour way to the right.\nRight: Work Elevator\n/// Cloudy Maze\nLeft: Black Hole\n///Underground Lake\n\nRed Circle: Elevator 2\n//// Underground Lake\nArrow: You are here")) -define_cs_dialog(DIALOG_090, 1, 6, 30, 200, ("Bwa ha ha ha!\nYou've stepped right into\nmy trap, just as I knew\nyou would! I warn you,\n" .. ' "Friend," ' .. "watch your\nstep!")) -define_cs_dialog(DIALOG_091, 2, 2, 30, 200, ("Danger!\nStrong Gusts!\nBut the wind makes a\ncomfy ride.")) -define_cs_dialog(DIALOG_092, 1, 5, 30, 200, ("Pestering me again, are\nyou, Mario? Can't you see\nthat I'm having a merry\nlittle time, making\nmischief with my minions?\nNow, return those Stars!\nMy troops in the walls\nneed them! Bwa ha ha!")) -define_cs_dialog(DIALOG_093, 1, 5, 30, 200, ("Mario! You again! Well\nthat's just fine--I've\nbeen looking for something\nto fry with my fire\nbreath!\nYour Star Power is\nuseless against me!\nYour friends are all\ntrapped within the\nwalls...\nAnd you'll never see the\nPrincess again!\nBwa ha ha ha!")) -define_cs_dialog(DIALOG_094, 1, 4, 30, 200, ("Get a good run up the\nslope! Do you remember\nthe Long Jump? Run, press\n[Z], then jump!")) -define_cs_dialog(DIALOG_095, 1, 4, 30, 200, ("To read a sign, stand in\nfront of it and press [B],\nlike you did just now.\n\nWhen you want to talk to\na Koopa Troopa or other\nanimal, stand right in\nfront of it.\nPlease recover the Stars\nthat were stolen by\nBowser in this course.")) -define_cs_dialog(DIALOG_096, 1, 4, 30, 200, ("The path is narrow here.\nEasy does it! No one is\nallowed on top of the\nmountain!\nAnd if you know what's\ngood for you, you won't\nwake anyone who's\nsleeping!\nMove slowly,\ntread lightly.")) -define_cs_dialog(DIALOG_097, 1, 5, 30, 200, ("Don't be a pushover!\nIf anyone tries to shove\nyou around, push back!\nIt's one-on-one, with a\nfiery finish for the loser!")) -define_cs_dialog(DIALOG_098, 1, 2, 95, 200, ("Come on in here...\n...heh, heh, heh...")) -define_cs_dialog(DIALOG_099, 1, 5, 95, 200, ("Eh he he...\nYou're mine, now, hee hee!\nI'll pass right through\nthis wall. Can you do\nthat? Heh, heh, heh!")) -- unused -define_cs_dialog(DIALOG_100, 1, 3, 95, 200, ("Ukkiki...Wakkiki...kee kee!\nHa! I snagged it!\nIt's mine! Heeheeheeee!")) -define_cs_dialog(DIALOG_101, 1, 3, 95, 200, ("Ackk! Let...go...\nYou're...choking...me...\nCough...I've been framed!\nThis Cap? Oh, all right,\ntake it. It's a cool Cap,\nbut I'll give it back.\nI think it looks better on\nme than it does on you,\nthough! Eeeee! Kee keee!")) -define_cs_dialog(DIALOG_102, 1, 5, 30, 200, ("Pssst! The Boos are super\nshy. If you look them\nin the eyes, they fade\naway, but if you turn\nyour back, they reappear.\nIt's no use trying to hit\nthem when they're fading\naway. Instead, sneak up\nbehind them and punch.")) -define_cs_dialog(DIALOG_103, 1, 4, 95, 200, ("Upon four towers\none must alight...\nThen at the peak\nshall shine the light...")) -define_cs_dialog(DIALOG_104, 1, 5, 30, 200, ("The shadowy star in front\nof you is a 『Star\nMarker.』 When you collect\nall 8 Red Coins, the Star\nwill appear here.")) -define_cs_dialog(DIALOG_105, 1, 3, 95, 200, ("Ready for blastoff! Come\non, hop into the cannon!\n\nYou can reach the Star on\nthe floating island by\nusing the four cannons.\nUse the Control Stick to\naim, then press [A] to fire.\n\nIf you're handy, you can\ngrab on to trees or poles\nto land.")) -define_cs_dialog(DIALOG_106, 1, 2, 95, 200, ("Ready for blastoff! Come\non, hop into the cannon!")) -define_cs_dialog(DIALOG_107, 1, 3, 95, 200, ("Ghosts...\n...don't...\n...DIE!\nHeh, heh, heh!\nCan you get out of here...\n...alive?")) -define_cs_dialog(DIALOG_108, 1, 2, 95, 200, ("Boooooo-m! Here comes\nthe master of mischief,\nthe tower of terror,\nthe Big Boo!\nKa ha ha ha...")) -define_cs_dialog(DIALOG_109, 1, 4, 95, 200, ("Ooooo Nooooo!\nTalk about out-of-body\nexperiences--my body\nhas melted away!\nHave you run in to any\nheadhunters lately??\nI could sure use a new\nbody!\nBrrr! My face might\nfreeze like this!")) -define_cs_dialog(DIALOG_110, 1, 5, 95, 200, ("I need a good head on my\nshoulders. Do you know of\nanybody in need of a good\nbody? Please! I'll follow\nyou if you do!")) -define_cs_dialog(DIALOG_111, 1, 4, 95, 200, ("Perfect! What a great\nnew body! Here--this is a\npresent for you. It's sure\nto warm you up.")) -define_cs_dialog(DIALOG_112, 1, 4, 30, 200, ("Collect as many coins as\npossible! They'll refill\nyour Power Meter.\n\nYou can check to see how\nmany coins you've\ncollected in each of the\n15 enemy worlds.\nYou can also recover\npower by touching the\nSpinning Heart.\n\nThe faster you run\nthrough the heart, the\nmore power you'll recover.")) -define_cs_dialog(DIALOG_113, 1, 6, 30, 200, ("There are special Caps in\nthe red, green and blue\nblocks. Step on the\nswitches in the hidden\ncourses to activate the\nCap Blocks.")) -define_cs_dialog(DIALOG_114, 1, 5, 95, 200, ("It makes me so mad! We\nbuild your houses, your\ncastles. We pave your\nroads, and still you\nwalk all over us.\nDo you ever say thank\nyou? No! Well, you're not\ngoing to wipe your feet\non me! I think I'll crush\nyou just for fun!\nDo you have a problem\nwith that? Just try to\npound me, wimp! Ha!")) -define_cs_dialog(DIALOG_115, 1, 5, 95, 200, ("No! Crushed again!\nI'm just a stepping stone,\nafter all. I won't gravel,\ner, grovel. Here, you win.\nTake this with you!")) -define_cs_dialog(DIALOG_116, 1, 5, 95, 200, ("Whaaa....Whaaat?\nCan it be that a\npipsqueak like you has\ndefused the Bob-omb\nking????\nYou might be fast enough\nto ground me, but you'll\nhave to pick up the pace\nif you want to take King\nBowser by the tail.\nMethinks my troops could\nlearn a lesson from you!\nHere is your Star, as I\npromised, Mario.\n\nIf you want to see me\nagain, select this Star\nfrom the menu. For now,\nfarewell.")) -define_cs_dialog(DIALOG_117, 1, 1, 95, 200, ("Who...walk...here?\nWho...break...seal?\nWake..ancient..ones?\nWe no like light...\nRrrrummbbble...\nWe no like...intruders!\nNow battle...\n...hand...\n...to...\n...hand!")) -define_cs_dialog(DIALOG_118, 1, 6, 95, 200, ("Grrrrumbbble!\nWhat...happen?\nWe...crushed like pebble.\nYou so strong!\nYou rule ancient pyramid!\nFor today...\nNow, take Star of Power.\nWe...sleep...darkness.")) -define_cs_dialog(DIALOG_119, 1, 6, 30, 200, ("Grrr! I was a bit\ncareless. This is not as I\nhad planned...but I still\nhold the power of the\nStars, and I still have\nPeach.\nBwa ha ha! You'll get no\nmore Stars from me! I'm\nnot finished with you yet,\nbut I'll let you go for\nnow. You'll pay for this...\nlater!")) -define_cs_dialog(DIALOG_120, 1, 4, 30, 200, ("Ooowaah! Can it be that\nI've lost??? The power of\nthe Stars has failed me...\nthis time.\nConsider this a draw.\nNext time, I'll be in\nperfect condition.\n\nNow, if you want to see\nyour precious Princess,\ncome to the top of the\ntower.\nI'll be waiting!\nGwa ha ha ha!")) -define_cs_dialog(DIALOG_121, 1, 5, 30, 200, ("Nooo! It can't be!\nYou've really beaten me,\nMario?!! I gave those\ntroops power, but now\nit's fading away!\nArrgghh! I can see peace\nreturning to the world! I\ncan't stand it! Hmmm...\nIt's not over yet...\n\nC'mon troops! Let's watch\nthe ending together!\nBwa ha ha!")) -define_cs_dialog(DIALOG_122, 1, 4, 30, 200, ("The Black Hole\nRight: Work Elevator\n/// Cloudy Maze\nLeft: Underground Lake")) -define_cs_dialog(DIALOG_123, 1, 4, 30, 200, ("Metal Cavern\nRight: To Waterfall\nLeft: Metal Cap Switch")) -define_cs_dialog(DIALOG_124, 1, 4, 30, 200, ("Work Elevator\nDanger!!\nRead instructions\nthoroughly!\nElevator continues in the\ndirection of the arrow\nactivated.")) -define_cs_dialog(DIALOG_125, 1, 3, 30, 200, ("Hazy Maze-Exit\nDanger! Closed.\nTurn back now.")) -define_cs_dialog(DIALOG_126, 2, 3, 30, 200, ("Up: Black Hole\nRight: Work Elevator\n/// Hazy Maze")) -define_cs_dialog(DIALOG_127, 3, 4, 30, 200, ("Underground Lake\nRight: Metal Cave\nLeft: Abandoned Mine\n///(Closed)\nA gentle sea dragon lives\nhere. Pound on his back to\nmake him lower his head.\nDon't become his lunch.")) -define_cs_dialog(DIALOG_128, 1, 4, 95, 200, ("You must fight with\nhonor! It is against the\nroyal rules to throw the\nking out of the ring!")) -define_cs_dialog(DIALOG_129, 1, 5, 30, 200, ("Welcome to the Vanish\nCap Switch Course! All of\nthe blue blocks you find\nwill become solid once you\nstep on the Cap Switch.\nYou'll disappear when you\nput on the Vanish Cap, so\nyou'll be able to elude\nenemies and walk through\nmany things. Try it out!")) -define_cs_dialog(DIALOG_130, 1, 5, 30, 200, ("Welcome to the Metal Cap\nSwitch Course! Once you\nstep on the Cap Switch,\nthe green blocks will\nbecome solid.\nWhen you turn your body\ninto metal with the Metal\nCap, you can walk\nunderwater! Try it!")) -define_cs_dialog(DIALOG_131, 1, 5, 30, 200, ("Welcome to the Wing Cap\nCourse! Step on the red\nswitch at the top of the\ntower, in the center of\nthe rainbow ring.\nWhen you trigger the\nswitch, all of the red\nblocks you find will\nbecome solid.\n\nTry out the Wing Cap! Do\nthe Triple Jump to take\noff and press [Z] to land.\n\n\nPull back on the Control\nStick to go up and push\nforward to nose down,\njust as you would when\nflying an airplane.")) -define_cs_dialog(DIALOG_132, 1, 4, 30, 200, ("Whoa, Mario, pal, you\naren't trying to cheat,\nare you? Shortcuts aren't\nallowed.\nNow, I know that you\nknow better. You're\ndisqualified! Next time,\nplay fair!")) -define_cs_dialog(DIALOG_133, 1, 6, 30, 200, ("Am I glad to see you! The\nPrincess...and I...and,\nwell, everybody...we're all\ntrapped inside the castle\nwalls.\n\nBowser has stolen the\ncastle's Stars, and he's\nusing their power to\ncreate his own world in\nthe paintings and walls.\n\nPlease recover the Power\nStars! As you find them,\nyou can use their power\nto open the doors that\nBowser has sealed.\n\nThere are four rooms on\nthe first floor. Start in\nthe one with the painting\nof Bob-omb inside. It's\nthe only room that Bowser\nhasn't sealed.\nWhen you collect eight\nPower Stars, you'll be\nable to open the door\nwith the big star. The\nPrincess must be inside!")) -define_cs_dialog(DIALOG_134, 1, 5, 30, 200, ("The names of the Stars\nare also hints for\nfinding them. They are\ndisplayed at the beginning\nof each course.\nYou can collect the Stars\nin any order. You won't\nfind some Stars, enemies\nor items unless you select\na specific Star.\nAfter you collect some\nStars, you can try\nanother course.\nWe're all waiting for\nyour help!")) -define_cs_dialog(DIALOG_135, 1, 5, 30, 200, ("It was Bowser who stole\nthe Stars. I saw him with\nmy own eyes!\n\n\nHe's hidden six Stars in\neach course, but you\nwon't find all of them in\nsome courses until you\npress the Cap Switches.\nThe Stars you've found\nwill show on each course's\nstarting screen.\n\n\nIf you want to see some\nof the enemies you've\nalready defeated, select\nthe Stars you recovered\nfrom them.")) -define_cs_dialog(DIALOG_136, 1, 6, 30, 200, ("Wow! You've already\nrecovered that many\nStars? Way to go, Mario!\nI'll bet you'll have us out\nof here in no time!\n\nBe careful, though.\nBowser and his band\nwrote the book on 『bad.』\nTake my advice: When you\nneed to recover from\ninjuries, collect coins.\nYellow Coins refill one\npiece of the Power Meter,\nRed Coins refill two\npieces, and Blue Coins\nrefill five.\n\nTo make Blue Coins\nappear, pound on Blue\nCoin Blocks.\n\n\n\nAlso, if you fall from\nhigh places, you'll\nminimize damage if you\nPound the Ground as you\nland.")) -define_cs_dialog(DIALOG_137, 1, 6, 30, 200, ("Thanks, Mario! The castle\nis recovering its energy\nas you retrieve Power\nStars, and you've chased\nBowser right out of here,\non to some area ahead.\nOh, by the by, are you\ncollecting coins? Special\nStars appear when you\ncollect 100 coins in each\nof the 15 courses!")) -define_cs_dialog(DIALOG_138, 1, 3, 30, 200, ("Down: Underground Lake\nLeft: Black Hole\nRight: Hazy Maze (Closed)")) -define_cs_dialog(DIALOG_139, 1, 6, 30, 200, ("Above: Automatic Elevator\nElevator begins\nautomatically and follows\npre-set course.\nIt disappears\nautomatically, too.")) -define_cs_dialog(DIALOG_140, 1, 6, 30, 200, ("Elevator Area\nRight: Hazy Maze\n/// Entrance\nLeft: Black Hole\n///Elevator 1\nArrow: You are here")) -define_cs_dialog(DIALOG_141, 1, 5, 150, 200, ("You've recovered one of\nthe stolen Power Stars!\nNow you can open some of\nthe sealed doors in the\ncastle.\nTry the Princess's room\non the second floor and\nthe room with the\npainting of Whomp's\nFortress on Floor 1.\nBowser's troops are still\ngaining power, so you\ncan't give up. Save us,\nMario! Keep searching for\nStars!")) -define_cs_dialog(DIALOG_142, 1, 5, 150, 200, ("You've recovered three\nPower Stars! Now you can\nopen any door with a 3\non its star.\n\nYou can come and go from\nthe open courses as you\nplease. The enemies ahead\nare even meaner, so be\ncareful!")) -define_cs_dialog(DIALOG_143, 1, 6, 150, 200, ("You've recovered eight of\nthe Power Stars! Now you\ncan open the door with\nthe big Star! But Bowser\nis just ahead...can you\nhear the Princess calling?")) -define_cs_dialog(DIALOG_144, 1, 6, 150, 200, ("You've recovered 30\nPower Stars! Now you can\nopen the door with the\nbig Star! But before you\nmove on, how's it going\notherwise?\nDid you pound the two\ncolumns down? You didn't\nlose your hat, did you?\nIf you did, you'll have to\nstomp on the condor to\nget it back!\nThey say that Bowser has\nsneaked out of the sea\nand into the underground.\nHave you finally\ncornered him?")) -define_cs_dialog(DIALOG_145, 1, 6, 150, 200, ("You've recovered 50\nPower Stars! Now you can\nopen the Star Door on the\nthird floor. Bowser's\nthere, you know.\n\nOh! You've found all of\nthe Cap Switches, haven't\nyou? Red, green and blue?\nThe Caps you get from the\ncolored blocks are really\nhelpful.\nHurry along, now. The\nthird floor is just ahead.")) -define_cs_dialog(DIALOG_146, 1, 6, 150, 200, ("You've found 70 Power\nStars! The mystery of the\nendless stairs is solved,\nthanks to you--and is\nBowser ever upset! Now,\non to the final bout!")) -define_cs_dialog(DIALOG_147, 1, 5, 30, 200, ("Are you using the Cap\nBlocks? You really should,\nyou know.\n\n\nTo make them solid so you\ncan break them, you have\nto press the colored Cap\nSwitches in the castle's\nhidden courses.\nYou'll find the hidden\ncourses only after\nregaining some of the\nPower Stars.\n\nThe Cap Blocks are a big\nhelp! Red for the Wing\nCap, green for the Metal\nCap, blue for the Vanish\nCap.")) -define_cs_dialog(DIALOG_148, 1, 6, 30, 200, ("Snowman Mountain ahead.\nKeep out! And don't try\nthe Triple Jump over the\nice block shooter.\n\n\nIf you fall into the\nfreezing pond, your power\ndecreases quickly, and\nyou won't recover\nautomatically.\n//--The Snowman")) -define_cs_dialog(DIALOG_149, 1, 3, 30, 200, ("Welcome to\nPrincess Toadstool's\nsecret slide!\nThere's a Star hidden\nhere that Bowser couldn't\nfind.\nWhen you slide, press\nforward to speed up,\npull back to slow down.\nIf you slide really\nfast, you'll win the Star!")) -define_cs_dialog(DIALOG_150, 1, 5, 30, 200, ("Waaaa! You've flooded my\nhouse! Wh-why?? Look at\nthis mess! What am I\ngoing to do now?\n\nThe ceiling's ruined, the\nfloor is soaked...what to\ndo, what to do? Huff...\nhuff...it makes me so...\nMAD!!!\nEverything's been going\nwrong ever since I got\nthis Star...It's so shiny,\nbut it makes me feel...\nstrange...")) -define_cs_dialog(DIALOG_151, 1, 4, 30, 200, ("I can't take this\nanymore! First you get\nme all wet, then you\nstomp on me!\nNow I'm really, really,\nREALLY mad!\nWaaaaaaaaaaaaaaaaa!!!")) -define_cs_dialog(DIALOG_152, 1, 3, 30, 200, ("Owwch! Uncle! Uncle!\nOkay, I give. Take this\nStar!\nWhew! I feel better now.\nI don't really need it\nanymore, anyway--\nI can see the stars\nthrough my ceiling at\nnight.\nThey make me feel...\n...peaceful. Please, come\nback and visit anytime.")) -define_cs_dialog(DIALOG_153, 1, 4, 30, 200, ("Hey! Who's there?\nWhat's climbing on me?\nIs it an ice ant?\nA snow flea?\nWhatever it is, it's\nbugging me! I think I'll\nblow it away!")) -define_cs_dialog(DIALOG_154, 1, 5, 30, 200, ("Hold on to your hat! If\nyou lose it, you'll be\neasily injured. If you\nlose it, look for it in the\ncourse where you lost it.\nSpeaking of lost, the\nPrincess is still stuck in\nthe walls somewhere.\nPlease help, Mario!\n\nOh, you know that there\nare secret worlds in the\nwalls as well as in the\npaintings, right?")) -define_cs_dialog(DIALOG_155, 1, 6, 30, 200, ("Thanks to the power of\nthe Stars, life is\nreturning to the castle.\nPlease, Mario, you have\nto give Bowser the boot!\n\nHere, let me tell you a\nlittle something about the\ncastle. In the room with\nthe mirrors, look carefully\nfor anything that's not\nreflected in the mirror.\nAnd when you go to the\nwater town, you can flood\nit with a high jump into\nthe painting.")) -define_cs_dialog(DIALOG_156, 1, 5, 30, 200, ("The world inside the\nclock is so strange!\nWhen you jump inside,\nwatch the position of\nthe big hand!")) -define_cs_dialog(DIALOG_157, 1, 5, 30, 200, ("Watch out! Don't let\nyourself be swallowed by\nquicksand.\n\n\nIf you sink into the sand,\nyou won't be able to\njump, and if your head\ngoes under, you'll be\nsmothered.\nThe dark areas are\nbottomless pits.")) -define_cs_dialog(DIALOG_158, 1, 6, 30, 200, ("1. If you jump repeatedly\nand time it right, you'll\njump higher and higher.\nIf you run really fast and\ntime three jumps right,\nyou can do a Triple Jump.\n2. Jump into a solid wall,\nthen jump again when you\nhit the wall. You can\nbounce to a higher level\nusing this Wall Kick.")) -define_cs_dialog(DIALOG_159, 1, 6, 30, 200, ("3. If you stop, press [Z]\nto crouch, then jump, you\ncan perform a Backward\nSomersault. To do a Long\nJump, run fast, press [Z],\nthen jump.")) -define_cs_dialog(DIALOG_160, 1, 4, 30, 200, ("Press [B] while running\nfast to do a Body Slide\nattack. To stand while\nsliding, press [A] or [B].")) -define_cs_dialog(DIALOG_161, 1, 4, 30, 200, ("Mario!!!\nIt that really you???\nIt has been so long since\nour last adventure!\nThey told me that I might\nsee you if I waited here,\nbut I'd just about given\nup hope!\nIs it true? Have you\nreally beaten Bowser? And\nrestored the Stars to the\ncastle?\nAnd saved the Princess?\nI knew you could do it!\nNow I have a very special\nmessage for you.\nThanks for playing Super\nMario 64! This is the\nend of the game, but not\nthe end of the fun.\nWe want you to keep on\nplaying, so we have a\nlittle something for you.\nWe hope that you like it!\nEnjoy!!!\n\nThe Super Mario 64 Team")) -define_cs_dialog(DIALOG_162, 1, 4, 30, 200, ("No, no, no! Not you\nagain! I'm in a great\nhurry, can't you see?\n\nI've no time to squabble\nover Stars. Here, have it.\nI never meant to hide it\nfrom you...\nIt's just that I'm in such\na rush. That's it, that's\nall. Now, I must be off.\nOwww! Let me go!")) -define_cs_dialog(DIALOG_163, 1, 5, 30, 200, ("Noooo! You've really\nbeaten me this time,\nMario! I can't stand\nlosing to you!\n\nMy troops...worthless!\nThey've turned over all\nthe Power Stars! What?!\nThere are 120 in all???\n\nAmazing! There were some\nin the castle that I\nmissed??!!\n\n\nNow I see peace\nreturning to the world...\nOooo! I really hate that!\nI can't watch--\nI'm outta here!\nJust you wait until next\ntime. Until then, keep\nthat Control Stick\nsmokin'!\nBuwaa ha ha!")) -define_cs_dialog(DIALOG_164, 1, 4, 30, 200, ("Mario! What's up, pal?\nI haven't been on the\nslide lately, so I'm out\nof shape.\nStill, I'm always up for a\ngood race, especially\nagainst an old sleddin'\nbuddy.\nWhaddya say?\nReady...set...\n\n//Go//// Don't Go")) -define_cs_dialog(DIALOG_165, 1, 5, 30, 200, ("I take no responsibility\nwhatsoever for those who\nget dizzy and pass out\nfrom running around\nthis post.")) -define_cs_dialog(DIALOG_166, 1, 4, 30, 200, ("I'll be back soon.\nI'm out training now,\nso come back later.\n//--Koopa the Quick")) -define_cs_dialog(DIALOG_167, 1, 4, 30, 200, ("Princess Toadstool's\ncastle is just ahead.\n\n\nPress [A] to jump, [Z] to\ncrouch, and [B] to punch,\nread a sign, or grab\nsomething.\nPress [B] again to throw\nsomething you're holding.")) -define_cs_dialog(DIALOG_168, 1, 5, 30, 200, ("Hey! Knock it off! That's\nthe second time you've\nnailed me. Now you're\nasking for it, linguine\nbreath!")) -define_cs_dialog(DIALOG_169, 1, 4, 30, 200, ("Keep out!\nThat means you!\nArrgghh!\n\nAnyone entering this cave\nwithout permission will\nmeet certain disaster.")) - -local DIALOG_NAME = "Mario" - ----@param name string -function dialog_set_replace_name(name) - DIALOG_NAME = name -end - -local prevCharName = "" - -local function dialog_swap(charName) - for i = DIALOG_000, #dialogTable do - if dialogTable[i] ~= nil then - local dialog = dialogTable[i] - charName = charName:gsub('"', "''") - local replaced_dialog = dialog.str:gsub(DIALOG_NAME, charName) - real_dialog_replace(i, dialog.unused, dialog.linesPerBox, dialog.leftOffset, dialog.width, replaced_dialog) - end +local function dialog_update(dialogId) + -- Save Original Dialog + if ogDialog[dialogId] == nil then + local dialog = smlua_text_utils_dialog_get(dialogId) + ogDialog[dialogId] = { + unused = dialog.unused, + linesPerBox = dialog.linesPerBox, + leftOffset = dialog.leftOffset, + width = dialog.width, + text = dialog.text + } end -end -local function update() - -- Query Character Swapped - local charName = characterTable[currChar][characterTable[currChar].currAlt].name - if prevCharName ~= charName then - dialog_swap(charName) - prevCharName = charName + local dialog = ogDialog[dialogId] + local charName = characterTable[currChar].nickname + local charAuto = characterTable[currChar].autoDialog + -- Check for Override Dialog and use it instead + local colorDialog = false + if characterDialog[currChar] ~= nil and characterDialog[currChar][dialogId] ~= nil then + dialog = characterDialog[currChar][dialogId] + colorDialog = true + elseif charAuto then + dialog.text = dialog.text:gsub(DEFAULT_DIALOG_NAME, charName) + colorDialog = true end + + -- Set color if Dialog has Character's Name + reset_dialog_override_color() + if colorDialog then + local charColor = characterTable[currChar][characterTable[currChar].currAlt].color + set_dialog_override_color(charColor.r*0.3, charColor.g*0.3, charColor.b*0.3, 150, 255, 255, 255, 255) + end + + -- Apply Text Changes + smlua_text_utils_dialog_replace( + dialogId, + dialog.unused, + dialog.linesPerBox, + dialog.leftOffset, + dialog.width, + dialog.text + ) + + -- Reminder to later change this to true, string + return true end -hook_event(HOOK_UPDATE, update) \ No newline at end of file +hook_event(HOOK_ON_DIALOG, dialog_update) \ No newline at end of file diff --git a/mods/character-select-coop/n-hud.lua b/mods/character-select-coop/hud.lua similarity index 57% rename from mods/character-select-coop/n-hud.lua rename to mods/character-select-coop/hud.lua index 57f1aa4cc..f3b79400c 100644 --- a/mods/character-select-coop/n-hud.lua +++ b/mods/character-select-coop/hud.lua @@ -4,20 +4,14 @@ if incompatibleClient then return 0 end --- localize functions to improve performance - n-hud.lua -local og_hud_get_value,og_hud_set_value,djui_hud_print_text,tostring,hud_set_flash,get_global_timer,hud_get_flash,djui_hud_get_screen_width,math_ceil,obj_get_first_with_behavior_id,get_behavior_from_id,count_objects_with_behavior,djui_hud_render_rect,djui_hud_set_resolution,djui_hud_get_screen_height,djui_hud_set_color,djui_hud_set_font,djui_hud_measure_text,djui_chat_message_create,hud_is_hidden,djui_is_playerlist_open = hud_get_value,hud_set_value,djui_hud_print_text,tostring,hud_set_flash,get_global_timer,hud_get_flash,djui_hud_get_screen_width,math.ceil,obj_get_first_with_behavior_id,get_behavior_from_id,count_objects_with_behavior,djui_hud_render_rect,djui_hud_set_resolution,djui_hud_get_screen_height,djui_hud_set_color,djui_hud_set_font,djui_hud_measure_text,djui_chat_message_create,hud_is_hidden,djui_is_playerlist_open - ---[[ - Some functions we need for the hud - Color hud code written by EmilyEmmi - Djui box code written by xLuigiGamerx (Use outside of character select is forbidden as these functions were made for another mod I'm planning to release) -]] +local og_hud_get_value = hud_get_value +local og_hud_set_value = hud_set_value ---@param text string ----@return nil, number, number, number, number +---@return number?, number?, number?, number? local function convert_color(text) if text:sub(2, 2) ~= "#" then - return nil + return end text = text:sub(3, -2) local rstring, gstring, bstring = "", "", "" @@ -39,7 +33,7 @@ end ---@param text string ---@param get_color boolean|nil ----@return string, string, string, boolean +---@return string, string?, string? local function remove_color(text, get_color) local start = text:find("\\") local next = 1 @@ -137,12 +131,12 @@ local function djui_hud_print_text_with_color(text, x, y, scale, red, green, blu while render ~= nil do local r, g, b, a = convert_color(color) if alpha then a = alpha end - djui_hud_print_text(render, x + space, y, scale); + djui_hud_print_text(render, x + space, y, scale) if r then djui_hud_set_color(r, g, b, a) end space = space + djui_hud_measure_text(render) * scale text, color, render = remove_color(text, true) end - djui_hud_print_text(text, x + space, y, scale); + djui_hud_print_text(text, x + space, y, scale) end ---@param text string Message @@ -175,36 +169,39 @@ end -- Real HUD Stuffs -- --------------------- +-- Updates the Chracter Select hud flags along with the vanilla hud flags + +local hiddenList = HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA | HUD_DISPLAY_FLAG_POWER +local sCharSelectHudDisplayFlags = og_hud_get_value(HUD_DISPLAY_FLAGS) | hiddenList -- Initializes custom hud flags + +function flags_update() + sCharSelectHudDisplayFlags = sCharSelectHudDisplayFlags & (og_hud_get_value(HUD_DISPLAY_FLAGS) | hiddenList) -- Updated the custom flags + og_hud_set_value(HUD_DISPLAY_FLAGS, og_hud_get_value(HUD_DISPLAY_FLAGS) & ~(hiddenList)) -- Update the vanilla flags +end +hook_event(HOOK_ON_HUD_RENDER_BEHIND, flags_update) + -- Modified Vanilla Functions -- --[[ These are `_G` on their own to replace vanilla functions ]] -local sCharSelectHudDisplayFlags -- `local` because we aren't exposing this - --- Here to make sure the flags are at the default state -hook_event(HOOK_UPDATE, function () - if not sCharSelectHudDisplayFlags or sCharSelectHudDisplayFlags == 0 then - sCharSelectHudDisplayFlags = og_hud_get_value(HUD_DISPLAY_FLAGS) | HUD_DISPLAY_DEFAULT - end -end) - ---- @param type HudDisplayValue ---- @return integer +---@param type HudDisplayValue +---@return integer function _G.hud_get_value(type) if type == HUD_DISPLAY_FLAGS then - return sCharSelectHudDisplayFlags + return sCharSelectHudDisplayFlags | og_hud_get_value(HUD_DISPLAY_FLAGS) else return og_hud_get_value(type) end end ---- @param type HudDisplayValue ---- @param value integer +---@param type HudDisplayValue +---@param value integer --- Sets a HUD display value function _G.hud_set_value(type, value) if type == HUD_DISPLAY_FLAGS then sCharSelectHudDisplayFlags = value + og_hud_set_value(type, value & ~(hiddenList)) else og_hud_set_value(type, value) end @@ -215,7 +212,7 @@ end ---Hides the specified custom hud element ---@param hudElement HUDDisplayFlag function hud_hide_element(hudElement) - --log_to_console("The `charSelect.hud_hide_element()` function is deprecated, please use normal vanilla functions as they have been modified to work with Character Select.", CONSOLE_MESSAGE_WARNING) + log_to_console_once("`charSelect.hud_hide_element` function is deprecated, please use 'hud_set_value'", CONSOLE_MESSAGE_WARNING) hud_set_value(HUD_DISPLAY_FLAGS, hud_get_value(HUD_DISPLAY_FLAGS) & ~hudElement) return true end @@ -223,7 +220,7 @@ end ---Shows the specified custom hud element ---@param hudElement HUDDisplayFlag function hud_show_element(hudElement) - --log_to_console("The `charSelect.hud_show_element()` function is deprecated, please use normal vanilla functions as they have been modified to work with Character Select.", CONSOLE_MESSAGE_WARNING) + log_to_console_once("`hud_show_element` function is deprecated, please use 'hud_set_value'", CONSOLE_MESSAGE_WARNING) hud_set_value(HUD_DISPLAY_FLAGS, hud_get_value(HUD_DISPLAY_FLAGS) | hudElement) return true end @@ -232,26 +229,24 @@ end ---@param hudElement HUDDisplayFlag ---@return boolean function hud_get_element(hudElement) - --log_to_console("The `charSelect.hud_get_element()` function is deprecated, please use normal vanilla functions as they have been modified to work with Character Select.", CONSOLE_MESSAGE_WARNING) - djui_chat_message_create(tostring(sCharSelectHudDisplayFlags)) + log_to_console_once("`charSelect.hud_get_element` function is deprecated, please use 'hud_set_value'", CONSOLE_MESSAGE_WARNING) return (hud_get_value(HUD_DISPLAY_FLAGS) & hudElement) ~= 0 end local MATH_DIVIDE_16 = 1/16 local MATH_DIVIDE_32 = 1/32 local MATH_DIVIDE_64 = 1/64 -local MATH_DIVIDE_HEALTH = 1/0x100 local FONT_USER = FONT_NORMAL ---- @param localIndex integer ---- @return string +---@param localIndex integer +---@return string --- This assumes multiple characters will not have the same model, --- Icons can only be seen by users who have the character avalible to them function name_from_local_index(localIndex) if localIndex == nil then localIndex = 0 end local p = gCSPlayers[localIndex] - for i = 1, #characterTable do + for i = 0, #characterTable do if characterTable[i].saveName == p.saveName then return characterTable[i][(p.currAlt and p.currAlt or 1)].name end @@ -259,14 +254,14 @@ function name_from_local_index(localIndex) return "???" end ---- @param localIndex integer ---- @return table +---@param localIndex integer +---@return table --- This assumes multiple characters will not have the same model, --- Icons can only be seen by users who have the character avalible to them function color_from_local_index(localIndex) if localIndex == nil then localIndex = 0 end local p = gCSPlayers[localIndex] - for i = 1, #characterTable do + for i = 0, #characterTable do if characterTable[i].saveName == p.saveName then return characterTable[i][(p.currAlt and p.currAlt or 1)].color end @@ -274,15 +269,15 @@ function color_from_local_index(localIndex) return {r = 255, g = 255, b = 255} end ---- @param localIndex integer ---- @return TextureInfo|string +---@param localIndex integer +---@return TextureInfo|string --- This assumes multiple characters will not have the same model, --- Icons can only be seen by users who have the character avalible to them. --- This function can return nil. if this is the case, render `djui_hud_print_text("?", x, y, 1)` function life_icon_from_local_index(localIndex) if localIndex == nil then localIndex = 0 end local p = gCSPlayers[localIndex] - for i = 1, #characterTable do + for i = 0, #characterTable do local char = characterTable[i] if char.saveName == p.saveName then return char[(p.currAlt and p.currAlt or 1)].lifeIcon @@ -291,14 +286,14 @@ function life_icon_from_local_index(localIndex) return "?" end ---- @param localIndex integer ---- @return TextureInfo +---@param localIndex integer +---@return TextureInfo --- This assumes multiple characters will not have the same model, --- Icons can only be seen by users who have the character avalible to them function star_icon_from_local_index(localIndex) if localIndex == nil then localIndex = 0 end local p = gCSPlayers[localIndex] - for i = 1, #characterTable do + for i = 0, #characterTable do local char = characterTable[i] if char.saveName == p.saveName then return char[(p.currAlt and p.currAlt or 1)].starIcon @@ -308,10 +303,10 @@ function star_icon_from_local_index(localIndex) end local TYPE_STRING = "string" ---- @param localIndex integer ---- @param x integer ---- @param y integer ---- @param scale integer +---@param localIndex integer +---@param x integer +---@param y integer +---@param scale integer function render_life_icon_from_local_index(localIndex, x, y, scale) if localIndex == nil then localIndex = 0 end local lifeIcon = life_icon_from_local_index(localIndex) @@ -331,13 +326,13 @@ function render_life_icon_from_local_index(localIndex, x, y, scale) end end ---- @param localIndex integer ---- @param prevX integer ---- @param prevY integer ---- @param prevScale integer ---- @param x integer ---- @param y integer ---- @param scale integer +---@param localIndex integer +---@param prevX integer +---@param prevY integer +---@param prevScale integer +---@param x integer +---@param y integer +---@param scale integer function render_life_icon_from_local_index_interpolated(localIndex, prevX, prevY, prevScale, x, y, scale) if localIndex == nil then localIndex = 0 end local lifeIcon = life_icon_from_local_index(localIndex) @@ -357,20 +352,20 @@ function render_life_icon_from_local_index_interpolated(localIndex, prevX, prevY end end ---- @param localIndex integer ---- @param x integer ---- @param y integer ---- @param scale integer +---@param localIndex integer +---@param x integer +---@param y integer +---@param scale integer function render_star_icon_from_local_index(localIndex, x, y, scale) if localIndex == nil then localIndex = 0 end local starIcon = star_icon_from_local_index(localIndex) djui_hud_render_texture(starIcon, x, y, scale / (starIcon.width * MATH_DIVIDE_16), scale / (starIcon.height * MATH_DIVIDE_16)) end ---- @param localIndex integer ---- @param x integer ---- @param y integer ---- @param scale integer +---@param localIndex integer +---@param x integer +---@param y integer +---@param scale integer function render_star_icon_from_local_index_interpolated(localIndex, prevX, prevY, prevScale, x, y, scale) if localIndex == nil then localIndex = 0 end local starIcon = star_icon_from_local_index(localIndex) @@ -378,7 +373,7 @@ function render_star_icon_from_local_index_interpolated(localIndex, prevX, prevY end -- Health Meter -- -local TEXT_DEFAULT_METER_PREFIX = "char-select-custom-meter-" +local TEXT_DEFAULT_METER_PREFIX = "char_select_custom_meter_" local TEX_DEFAULT_METER_LEFT = get_texture_info(TEXT_DEFAULT_METER_PREFIX.."left") local TEX_DEFAULT_METER_RIGHT = get_texture_info(TEXT_DEFAULT_METER_PREFIX.."right") local TEX_DEFAULT_METER_PIE1 = get_texture_info(TEXT_DEFAULT_METER_PREFIX.."pie1") @@ -389,7 +384,7 @@ local TEX_DEFAULT_METER_PIE5 = get_texture_info(TEXT_DEFAULT_METER_PREFIX.."pie5 local TEX_DEFAULT_METER_PIE6 = get_texture_info(TEXT_DEFAULT_METER_PREFIX.."pie6") local TEX_DEFAULT_METER_PIE7 = get_texture_info(TEXT_DEFAULT_METER_PREFIX.."pie7") local TEX_DEFAULT_METER_PIE8 = get_texture_info(TEXT_DEFAULT_METER_PREFIX.."pie8") -local defaultMeterInfo = { +defaultMeterInfo = { label = { left = TEX_DEFAULT_METER_LEFT, right = TEX_DEFAULT_METER_RIGHT, @@ -406,85 +401,230 @@ local defaultMeterInfo = { } } -local TEXT_DEFAULT_COURSE_PREFIX = "char-select-custom-course-" -local TEX_DEFAULT_METER_LEFT = get_texture_info(TEXT_DEFAULT_COURSE_PREFIX.."top") -local TEX_DEFAULT_METER_RIGHT = get_texture_info(TEXT_DEFAULT_COURSE_PREFIX.."bottom") +local TEXT_DEFAULT_COURSE_PREFIX = "char_select_custom_course_" +local TEX_DEFAULT_COURSE_TOP = get_texture_info(TEXT_DEFAULT_COURSE_PREFIX.."top") +local TEX_DEFAULT_COURSE_BOTTOM = get_texture_info(TEXT_DEFAULT_COURSE_PREFIX.."bottom") local defaultCourseInfo = { - top = TEX_DEFAULT_METER_LEFT, - bottom = TEX_DEFAULT_METER_RIGHT, + top = TEX_DEFAULT_COURSE_TOP, + bottom = TEX_DEFAULT_COURSE_BOTTOM, } ---- @param localIndex integer ---- @return table +---@param localIndex integer +---@return table --- This assumes multiple characters will not have the same model, --- Icons can only be seen by users who have the character avalible to them function health_meter_from_local_index(localIndex) - if localIndex == nil then localIndex = 0 end + localIndex = localIndex or 0 local p = gCSPlayers[localIndex] - for i = 1, #characterTable do + for i = 0, #characterTable do local char = characterTable[i] - if char.saveName == p.saveName and char[(p.currAlt and p.currAlt or 1)].healthTexture ~= nil then - return char[(p.currAlt and p.currAlt or 1)].healthTexture + local healthMeter = (char[p.currAlt] and char[p.currAlt].healthMeter) or char[1].healthMeter + if char.saveName == p.saveName and healthMeter ~= nil then + return healthMeter end end return defaultMeterInfo end ---- @param localIndex integer ---- @param x integer ---- @param y integer ---- @param scaleX integer ---- @param scaleY integer +---@param localIndex integer +---@param health integer +---@param x integer +---@param y integer +---@param scaleX integer +---@param scaleY integer function render_health_meter_from_local_index(localIndex, health, x, y, scaleX, scaleY) - if localIndex == nil then localIndex = 0 end - local health = math.floor(health*MATH_DIVIDE_HEALTH) - local textureTable = health_meter_from_local_index(localIndex) - local tex = textureTable.label.left - djui_hud_render_texture(tex, x, y, scaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, scaleY / (tex.height * MATH_DIVIDE_64) * MATH_DIVIDE_64) - local tex = textureTable.label.right - djui_hud_render_texture(tex, x + 31*scaleX*MATH_DIVIDE_64, y, scaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, scaleY / (tex.height * MATH_DIVIDE_64) * MATH_DIVIDE_64) - if health > 0 then - local tex = textureTable.pie[health] - djui_hud_render_texture(tex, x + 15*scaleX*MATH_DIVIDE_64, y + 16*scaleY*MATH_DIVIDE_64, scaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, scaleY / (tex.height * MATH_DIVIDE_32) * MATH_DIVIDE_64) + local color = djui_hud_get_color() + localIndex = localIndex or 0 + local meter = health_meter_from_local_index(localIndex) + if type(meter) == "function" then + meter(localIndex, health, x, y, scaleX, scaleY, x, y, scaleX, scaleY) + else + health = health >> 8 + local tex = meter.label.left + djui_hud_render_texture(tex, x, y, scaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, scaleY / (tex.height * MATH_DIVIDE_64) * MATH_DIVIDE_64) + tex = meter.label.right + djui_hud_render_texture(tex, x + 31*scaleX*MATH_DIVIDE_64, y, scaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, scaleY / (tex.height * MATH_DIVIDE_64) * MATH_DIVIDE_64) + if health > 0 then + tex = meter.pie[health] + djui_hud_render_texture(tex, x + 15*scaleX*MATH_DIVIDE_64, y + 16*scaleY*MATH_DIVIDE_64, scaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, scaleY / (tex.height * MATH_DIVIDE_32) * MATH_DIVIDE_64) + end + end + djui_hud_set_color(color.r, color.g, color.b, color.a) +end + +---@param localIndex integer +---@param health integer +---@param prevX integer +---@param prevY integer +---@param prevScaleX integer +---@param prevScaleY integer +---@param x integer +---@param y integer +---@param scaleX integer +---@param scaleY integer +function render_health_meter_from_local_index_interpolated(localIndex, health, prevX, prevY, prevScaleX, prevScaleY, x, y, scaleX, scaleY) + local color = djui_hud_get_color() + localIndex = localIndex or 0 + local meter = health_meter_from_local_index(localIndex) + if type(meter) == "function" then + meter(localIndex, health, prevX, prevY, prevScaleX, prevScaleY, x, y, scaleX, scaleY) + else + health = health >> 8 + local tex = meter.label.left + djui_hud_render_texture_interpolated(tex, prevX, prevY, prevScaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, prevScaleY / (tex.height * MATH_DIVIDE_64) * MATH_DIVIDE_64, x, y, scaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, scaleY / (tex.height * MATH_DIVIDE_64) * MATH_DIVIDE_64) + tex = meter.label.right + djui_hud_render_texture_interpolated(tex, prevX + 31*prevScaleX*MATH_DIVIDE_64, prevY, prevScaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, prevScaleY / (tex.height * MATH_DIVIDE_64) * MATH_DIVIDE_64, x + 31*scaleX*MATH_DIVIDE_64, y, scaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, scaleY / (tex.height * MATH_DIVIDE_64) * MATH_DIVIDE_64) + if health > 0 then + tex = meter.pie[health] + djui_hud_render_texture_interpolated(tex, prevX + 15*prevScaleX*MATH_DIVIDE_64, prevY + 16*scaleY*MATH_DIVIDE_64, prevScaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, prevScaleY / (tex.height * MATH_DIVIDE_32) * MATH_DIVIDE_64, x + 15*scaleX*MATH_DIVIDE_64, y + 16*scaleY*MATH_DIVIDE_64, scaleX / (tex.width * MATH_DIVIDE_32) * MATH_DIVIDE_64, scaleY / (tex.height * MATH_DIVIDE_32) * MATH_DIVIDE_64) + end + end + djui_hud_set_color(color.r, color.g, color.b, color.a) +end + +-- Force Default Health function to render CS' Meter + +_G.hud_render_power_meter = function(health, x, y, scaleX, scaleY) + render_health_meter_from_local_index(0, health, x, y, scaleX, scaleY) +end +_G.hud_render_power_meter_interpolated = function(health, prevX, prevY, prevScaleX, prevScaleY, x, y, scaleX, scaleY) + render_health_meter_from_local_index_interpolated(0, health, prevX, prevY, prevScaleX, prevScaleY, x, y, scaleX, scaleY) +end + +-- Health Meter Code +local POWER_METER_HIDDEN = 0 +local POWER_METER_EMPHASIZED = 1 +local POWER_METER_DEEMPHASIZING = 2 +local POWER_METER_HIDING = 3 +local POWER_METER_VISIBLE = 4 + +local sPowerMeterHUD = { + animation = POWER_METER_HIDDEN, + x = 140, + y = 166, + unused = 1.0, +}; +local sPowerMeterVisibleTimer = 0 +local sPowerMeterStoredHealth = 0 + +local function animate_power_meter_emphasized() + local hudDisplayFlags = hud_get_value(HUD_DISPLAY_FLAGS) + + if ((hudDisplayFlags & HUD_DISPLAY_FLAG_EMPHASIZE_POWER) == 0) then + if (sPowerMeterVisibleTimer == 45.0) then + sPowerMeterHUD.animation = POWER_METER_DEEMPHASIZING; + end + else + sPowerMeterVisibleTimer = 0; end end -local pieTextureNames = { - "one_segments", - "two_segments", - "three_segments", - "four_segments", - "five_segments", - "six_segments", - "seven_segments", - "full", -} -local function render_hud_health() - if currChar == 1 and characterTable[1].currAlt == 1 then - texture_override_reset("texture_power_meter_left_side") - texture_override_reset("texture_power_meter_right_side") - for i = 1, 8 do - texture_override_reset("texture_power_meter_" .. pieTextureNames[i]) - end - return +-- Power meter animation called after emphasized mode. +-- Moves power meter y pos speed until it's at 200 to be visible. +local function animate_power_meter_deemphasizing() + local speed = 5; + + if (sPowerMeterHUD.y >= 181) then + speed = 3; end - local textureTable = characterTable[currChar][characterTable[currChar].currAlt].healthTexture - if textureTable then -- sets health HUD to custom textures - if textureTable.label.left and textureTable.label.right then -- if left and right label textures exist. BOTH have to exist to be set! - texture_override_set("texture_power_meter_left_side", textureTable.label.left) - texture_override_set("texture_power_meter_right_side", textureTable.label.right) - end - for i = 1, 8 do - texture_override_set("texture_power_meter_" .. pieTextureNames[i], (textureTable.pie and textureTable.pie[i]) and textureTable.pie[i] or defaultMeterInfo.pie[i]) + + if (sPowerMeterHUD.y >= 191) then + speed = 2; + end + + if (sPowerMeterHUD.y >= 196) then + speed = 1; + end + + sPowerMeterHUD.y = sPowerMeterHUD.y + speed; + + if (sPowerMeterHUD.y >= 201) then + sPowerMeterHUD.y = 200; + sPowerMeterPrevY = 200; + sPowerMeterHUD.animation = POWER_METER_VISIBLE; + end +end + + +-- Power meter animation called when there's 8 health segments. +-- Moves power meter y pos quickly until it's at 301 to be hidden. + +local function animate_power_meter_hiding() + sPowerMeterHUD.y = sPowerMeterHUD.y + 20; + if (sPowerMeterHUD.y >= 301) then + sPowerMeterHUD.animation = POWER_METER_HIDDEN; + sPowerMeterVisibleTimer = 0; + end +end + +-- Handles power meter actions depending of the health segments values. +local function handle_power_meter_actions(numHealthWedges) + local gPlayerCameraState = gMarioStates[0].statusForCamera + + -- Show power meter if health is not full, less than 8 + if (numHealthWedges < 8 and sPowerMeterStoredHealth == 8 and sPowerMeterHUD.animation == POWER_METER_HIDDEN) then + sPowerMeterHUD.animation = POWER_METER_EMPHASIZED; + sPowerMeterHUD.y = 166; + sPowerMeterPrevY = 166; + end + + -- Show power meter if health is full, has 8 + if (numHealthWedges == 8 and sPowerMeterStoredHealth == 7) then + sPowerMeterVisibleTimer = 0; + end + + -- After health is full, hide power meter + if (numHealthWedges == 8 and sPowerMeterVisibleTimer > 45.0) then + sPowerMeterHUD.animation = POWER_METER_HIDING; + end + + -- Update to match health value + sPowerMeterStoredHealth = numHealthWedges; + + -- If Mario is swimming, keep power meter visible + if (gPlayerCameraState.action & ACT_FLAG_SWIMMING ~= 0) then + if (sPowerMeterHUD.animation == POWER_METER_HIDDEN + or sPowerMeterHUD.animation == POWER_METER_EMPHASIZED) then + sPowerMeterHUD.animation = POWER_METER_DEEMPHASIZING; + sPowerMeterHUD.y = 166; + sPowerMeterPrevY = 166; end - else -- resets the health HUD - texture_override_set("texture_power_meter_left_side", defaultMeterInfo.label.left) - texture_override_set("texture_power_meter_right_side", defaultMeterInfo.label.right) - for i = 1, 8 do - texture_override_set("texture_power_meter_" .. pieTextureNames[i], defaultMeterInfo.pie[i]) - end - end + sPowerMeterVisibleTimer = 0; + end +end + + +-- Renders the power meter that shows when Mario is in underwater +-- or has taken damage and has less than 8 health segments. +-- And calls a power meter animation function depending of the value defined. +local function render_hud_power_meter() + local shownHealthWedges = hud_get_value(HUD_DISPLAY_WEDGES); + sPowerMeterHUD.x = djui_hud_get_screen_width()*0.5 - 51 + + if (sPowerMeterHUD.animation ~= POWER_METER_HIDING) then + handle_power_meter_actions(shownHealthWedges); + end + + if (sPowerMeterHUD.animation == POWER_METER_HIDDEN) then + return; + end + + local powerMeterPrevY = sPowerMeterHUD.y + + local anim = sPowerMeterHUD.animation + if anim == POWER_METER_EMPHASIZED then + animate_power_meter_emphasized(); + elseif anim == POWER_METER_DEEMPHASIZING then + animate_power_meter_deemphasizing(); + elseif anim == POWER_METER_HIDING then + animate_power_meter_hiding(); + end + + --render_dl_power_meter(shownHealthWedges); + render_health_meter_from_local_index_interpolated(0, gMarioStates[0].health, sPowerMeterHUD.x, 208 - powerMeterPrevY, 64, 64, sPowerMeterHUD.x, 208 - sPowerMeterHUD.y, 64, 64) + + sPowerMeterVisibleTimer = sPowerMeterVisibleTimer + 1; end local function render_hud_act_select_course() @@ -506,8 +646,6 @@ local function render_hud_act_select_course() end local function render_hud_mario_lives() - og_hud_set_value(HUD_DISPLAY_FLAGS, og_hud_get_value(HUD_DISPLAY_FLAGS) & ~HUD_DISPLAY_FLAG_LIVES) - if (hud_get_value(HUD_DISPLAY_FLAGS) & HUD_DISPLAY_FLAG_LIVES) == 0 then return end local x = 22 @@ -518,8 +656,6 @@ local function render_hud_mario_lives() end local function render_hud_stars() - og_hud_set_value(HUD_DISPLAY_FLAGS, og_hud_get_value(HUD_DISPLAY_FLAGS) & ~HUD_DISPLAY_FLAG_STAR_COUNT) - if (hud_get_value(HUD_DISPLAY_FLAGS) & HUD_DISPLAY_FLAG_STAR_COUNT) == 0 then return end if hud_get_flash ~= nil then -- prevent star count from flashing outside of castle @@ -530,11 +666,11 @@ local function render_hud_stars() end end - local x = math_ceil(djui_hud_get_screen_width() - 76) + local x = math.ceil(djui_hud_get_screen_width() - 76) if x % 2 ~= 0 then x = x - 1 end - local y = math_ceil(240 - 209 - 16) + local y = math.ceil(240 - 209 - 16) local showX = 0 local hudDisplayStars = hud_get_value(HUD_DISPLAY_STARS) @@ -548,15 +684,11 @@ local function render_hud_stars() end local function render_hud_camera_status() - if not HUD_DISPLAY_CAMERA_STATUS then return end - - og_hud_set_value(HUD_DISPLAY_FLAGS, og_hud_get_value(HUD_DISPLAY_FLAGS) & ~HUD_DISPLAY_FLAG_CAMERA) - - if (hud_get_value(HUD_DISPLAY_FLAGS) & HUD_DISPLAY_FLAG_CAMERA) == 0 then return end + if (hud_get_value(HUD_DISPLAY_FLAGS) & HUD_DISPLAY_FLAG_CAMERA) == 0 or (hud_get_value(HUD_DISPLAY_FLAGS) & HUD_DISPLAY_FLAG_CAMERA_AND_POWER) == 0 then return end local x = djui_hud_get_screen_width() - 54 local y = 205 - local cameraHudStatus = hud_get_value(HUD_DISPLAY_CAMERA_STATUS) + local cameraHudStatus = hud_get_value(HUD_DISPLAY_CAMERA_STATUS) -- doesn't show the status of freecam because it's currently bugged when we hide the hud camera -- TODO: keep nagging the coopers to "fix `hud_get_value(HUD_DISPLAY_CAMERA_STATUS)` when using freecam and hiding the hud camera" :trollface: if cameraHudStatus == CAM_STATUS_NONE then return end @@ -585,24 +717,86 @@ local function render_hud_camera_status() end -- Act Select Hud -- + +local STAR_SELECTOR_NOT_SELECTED = 0 +local STAR_SELECTOR_SELECTED = 1 +local STAR_SELECTOR_100_COINS = 2 + +local sVisibleStars = 0 local function render_act_select_hud() local course = gNetworkPlayers[0].currCourseNum - if gServerSettings.enablePlayersInLevelDisplay == 0 or course == 0 or obj_get_first_with_behavior_id(id_bhvActSelector) == nil or act_select_hud_is_hidden(ACT_SELECT_HUD_PLAYERS_IN_LEVEL) then return end + if course == 0 or not obj_get_first_with_behavior_id(id_bhvActSelector) then return end - local starBhvCount = count_objects_with_behavior(get_behavior_from_id(id_bhvActSelectorStarType)) - local sVisibleStars = starBhvCount < 6 and starBhvCount or 6 + if sVisibleStars == 0 then + local starObj = obj_get_first_with_behavior_id(id_bhvActSelectorStarType) + while starObj do + if starObj.oStarSelectorType ~= STAR_SELECTOR_100_COINS then + sVisibleStars = sVisibleStars + 1 + end + starObj = obj_get_next_with_same_behavior_id(starObj) + end + end for a = 1, sVisibleStars do local x = (139 - sVisibleStars * 17 + a * 34) + (djui_hud_get_screen_width() / 2) - 160 + 0.5 - for j = 1, MAX_PLAYERS - 1 do -- 0 is not needed due to the due to the fact that you are never supposed to see yourself in the act + for j = 1, MAX_PLAYERS - 1 do -- 0 is not needed, you're never supposed to see yourself in act select local np = gNetworkPlayers[j] if np and np.connected and np.currCourseNum == course and np.currActNum == a then - djui_hud_render_rect(x - 4, 17, 16, 16) render_life_icon_from_local_index(j, x - 4, 17, 1) break end end end + + local selectedStar = obj_get_first_with_behavior_id(id_bhvActSelectorStarType) + local starsList = {} + while selectedStar do + table.insert(starsList, selectedStar) + selectedStar = obj_get_next_with_same_behavior_id(selectedStar) + end + + if (sVisibleStars > 0) then + local playersInAct = 0 + local sSelectedActIndex = 0 + for i = 1, #starsList do + local curStar = starsList[i] + if curStar.oStarSelectorType == STAR_SELECTOR_SELECTED then + sSelectedActIndex = i - 1 + end + end + local gCurrCourseNum = gNetworkPlayers[0].currCourseNum + for j = 1, MAX_PLAYERS - 1 do + local np = gNetworkPlayers[j] + if not (np or np.connected) then goto continue end + if (np.currCourseNum ~= gCurrCourseNum) then goto continue end + if (np.currActNum ~= sSelectedActIndex + 1) then goto continue end + playersInAct = playersInAct + 1 + ::continue:: + end + + if (playersInAct > 0) then + local message = "" + if (playersInAct == 1) then + message = message .. " Join " + else + message = message .. string.format("%d Players", playersInAct) + end + + djui_hud_set_font(FONT_NORMAL) + djui_hud_set_color(100, 100, 100, 255) + local textScale = .5 + local textWidth = djui_hud_measure_text(message) * textScale + + local xPos = ((sSelectedActIndex + 1) * 34 - sVisibleStars * 17 + 139 - (textWidth / 2) + 4) + (djui_hud_get_screen_width() / 2) - 160 + 2 + local yPos = -1 + + if message:find("Players") then + message = string.format("%d Player", playersInAct) + end + djui_hud_print_text(message, xPos, yPos, textScale) -- Not fully accurate because the font in act select is stretched in a way unachievable with normal fonts, will revisit in the future + + end + end end ---@param table table @@ -670,10 +864,11 @@ function render_playerlist_and_modlist() local entryY = y + 88 + ((entryHeight + 4) * (i-1)) djui_hud_render_rect(entryX, entryY, entryWidth, entryHeight) + local capColor = network_player_get_override_palette_color(np, CAP) playerNameColor = { - r = 127 + network_player_get_override_palette_color_channel(np, CAP, 0) / 2, - g = 127 + network_player_get_override_palette_color_channel(np, CAP, 1) / 2, - b = 127 + network_player_get_override_palette_color_channel(np, CAP, 2) / 2 + r = 127 + capColor.r/2, + g = 127 + capColor.g/2, + b = 127 + capColor.b/2 } djui_hud_set_color(255, 255, 255, 255) @@ -733,7 +928,6 @@ function render_playerlist_and_modlist() end -- Yes the ending stuffs is hardcoded, no there's not much of a better way to do it - local DIALOG_ENDING_REPLACE_1 = "$CHARNAME!" local DIALOG_ENDING_REPLACE_2 = "Thank you $CHARNAME!" local DIALOG_ENDING_REPLACE_3 = "...for $CHARNAME..." @@ -751,7 +945,7 @@ local function render_hud_ending_dialog() local width = djui_hud_get_screen_width() - local charName = characterTable[currChar][characterTable[currChar].currAlt].name + local charName = characterTable[currChar].nickname local string = "" local startTime = 0 local endTime = 0 @@ -792,47 +986,184 @@ local function render_hud_ending_dialog() end end +-- Nametags Powermeter Hud -- + +local nametagsActionBlacklist = { + [ACT_START_CROUCHING] = true, + [ACT_CROUCHING] = true, + [ACT_STOP_CROUCHING] = true, + [ACT_START_CRAWLING] = true, + [ACT_CRAWLING] = true, + [ACT_STOP_CRAWLING] = true, + [ACT_IN_CANNON] = true, + [ACT_DISAPPEARED] = true, +} + +local FADE_SCALE = 4.0 + +--- @class StateExtras +--- @field public prevPos Vec3f +--- @field public prevScale number +--- @field public inited boolean + +--- @type StateExtras[] +local sStateExtras = {} + +for i = 0, MAX_PLAYERS - 1 do + sStateExtras[i] = {} + local _ENV = setmetatable(sStateExtras[i], { __index = _G }) + prevPos = gVec3fZero() + prevScale = 0.0 + inited = false +end + +local function render_nametag_powermeter() + local sGlobalTimer = get_global_timer() + for i = 1, MAX_PLAYERS - 1 do + local m = gMarioStates[i] + if is_player_active(m) == 0 then goto continue end + local np = gNetworkPlayers[i] + if not np.currAreaSyncValid then goto continue end + + if nametagsActionBlacklist[m.action] then goto continue end + + if (m.marioBodyState.mirrorMario or m.marioBodyState.updateHeadPosTime ~= sGlobalTimer) then goto continue end + + local pos = gVec3fZero() + local out = gVec3fZero() + + vec3f_copy(pos, m.marioBodyState.headPos) + pos.y = pos.y + 100 + + if not djui_hud_world_pos_to_screen_pos(pos, out) then + goto continue + end + + local scale = -300 / out.z * djui_hud_get_fov_coeff() + + out.y = out.y - 16 * scale + + local alpha = (math.min(np.fadeOpacity << 3, 255)) * math.clamp(FADE_SCALE - scale, 0.0, 1.0) + + local e = sStateExtras[i] + if not e.inited then + vec3f_copy(e.prevPos, out) + e.prevScale = scale + e.inited = true + end + + if gNametagsSettings.showHealth then + djui_hud_set_color(255, 255, 255, alpha) + local healthScale = 90 * scale + local prevHealthScale = 90 * e.prevScale + render_health_meter_from_local_index_interpolated(i, m.health, + e.prevPos.x - (prevHealthScale * 0.5), e.prevPos.y - 72 * scale, prevHealthScale, prevHealthScale, + out.x - ( healthScale * 0.5), out.y - 72 * scale, healthScale, healthScale + ) + end + + vec3f_copy(e.prevPos, out) + e.prevScale = scale + + ::continue:: + end +end + +local function nametags_reset() + for i = 0, MAX_PLAYERS - 1 do + sStateExtras[i].inited = false + end +end + +local function on_level_init() + nametags_reset() +end + +hook_event(HOOK_ON_LEVEL_INIT, on_level_init) + +local sServerSettings = gServerSettings +local sNametagsSettings = gNametagsSettings + +_G.gServerSettings = { + enablePlayerList = sServerSettings.enablePlayerList, + enablePlayersInLevelDisplay = sServerSettings.enablePlayersInLevelDisplay, +} + +_G.gNametagsSettings = { + showHealth = sNametagsSettings.showHealth, +} + +local _ServerSettingsMetaTable = { + __index = function (t, k) + return rawget(t, k) or sServerSettings[k] + end, + __newindex = function (_, k, v) + sServerSettings[k] = v + end, +} + +local _NametagsSettingsMetaTable = { + __index = function (t, k) + return rawget(t, k) or sNametagsSettings[k] + end, + __newindex = function (_, k, v) + sNametagsSettings[k] = v + end, +} + +setmetatable(gServerSettings, _ServerSettingsMetaTable) +setmetatable(gNametagsSettings, _NametagsSettingsMetaTable) + +function nametags_settings() + if sNametagsSettings.showHealth then + gNametagsSettings.showHealth = not gNametagsSettings.showHealth + end + sNametagsSettings.showHealth = false +end + +hook_event(HOOK_ON_NAMETAGS_RENDER, nametags_settings) + local function on_hud_render_behind() FONT_USER = djui_menu_get_font() djui_hud_set_resolution(RESOLUTION_N64) djui_hud_set_font(FONT_HUD) + + render_nametag_powermeter() -- Render before setting the color, it sets its own + djui_hud_set_color(255, 255, 255, 255) - if gNetworkPlayers[0].currActNum == 99 or gMarioStates[0].action == ACT_INTRO_CUTSCENE or hud_is_hidden() then - return - end + if gNetworkPlayers[0].currActNum == 99 or gMarioStates[0].action == ACT_INTRO_CUTSCENE or hud_is_hidden() then return end - if obj_get_first_with_behavior_id(id_bhvActSelector) == nil then + sServerSettings.enablePlayersInLevelDisplay = 0 -- Disables the original playersInLevel Display + + local enablePlayersInLevelDisplay = gServerSettings.enablePlayersInLevelDisplay + if not obj_get_first_with_behavior_id(id_bhvActSelector) then render_hud_mario_lives() render_hud_stars() render_hud_camera_status() - render_hud_health() + render_hud_power_meter() + sVisibleStars = 0 else + if enablePlayersInLevelDisplay then + render_act_select_hud() + end render_hud_act_select_course() end end --- Can't name this charSelect due to o-api.lua overriding it, if I did so, using character select with no packs would make it nil -_G.gServerSettingsCS = { - enablePlayerList = true -- Set to false to disable the playerlist -} local function on_hud_render() djui_hud_set_resolution(RESOLUTION_N64) djui_hud_set_font(FONT_HUD) djui_hud_set_color(255, 255, 255, 255) - if obj_get_first_with_behavior_id(id_bhvActSelector) ~= nil then - render_act_select_hud() - end - if gNetworkPlayers[0].currActNum == 99 then render_hud_ending_dialog() end - gServerSettings.enablePlayerList = false -- Disables the original playerlist and modlist + sServerSettings.enablePlayerList = 0 -- Disables the original playerlist and modlist - local enablePlayerList = gServerSettingsCS.enablePlayerList -- gServerSettings.enablePlayerList but for the character select playerlist + local enablePlayerList = gServerSettings.enablePlayerList djui_hud_set_resolution(RESOLUTION_DJUI) if djui_attempting_to_open_playerlist() and enablePlayerList then diff --git a/mods/character-select-coop/main.lua b/mods/character-select-coop/main.lua index 6cc963dae..e15e77b6b 100644 --- a/mods/character-select-coop/main.lua +++ b/mods/character-select-coop/main.lua @@ -1,11 +1,11 @@ -- name: Character Select --- description:\\#ffff33\\-- Character Select Coop v1.14.1 --\n\n\\#dcdcdc\\A Library / API made to make adding and using Custom Characters as simple as possible!\nUse\\#ffff33\\ /char-select\\#dcdcdc\\ to get started!\n\nCreated by:\\#008800\\ Squishy6094\n\n\\#AAAAFF\\Updates can be found on\nCharacter Select's Github:\n\\#6666FF\\Squishy6094/character-select-coop +-- description:\\#ffff33\\-- Character Select Coop v1.16 --\n\n\\#dcdcdc\\A Library / API made to make adding and using Custom Characters as simple as possible!\nUse\\#ffff33\\ /char-select\\#dcdcdc\\ to get started!\n\nCreated by:\\#008800\\ Squishy6094\n\n\\#AAAAFF\\Updates can be found on\nCharacter Select's Github:\n\\#6666FF\\Squishy6094/character-select-coop -- pausable: false -- category: cs if incompatibleClient then return 0 end ---- @param hookEventType LuaHookedEventType +---@param hookEventType LuaHookedEventType local function create_hook_wrapper(hookEventType) local callbacks = {} @@ -22,37 +22,98 @@ end cs_hook_mario_update = create_hook_wrapper(HOOK_MARIO_UPDATE) --- localize functions to improve performance - main.lua -local mod_storage_load,tonumber,mod_storage_save,djui_popup_create,tostring,djui_chat_message_create,is_game_paused,obj_get_first_with_behavior_id,djui_hud_is_pause_menu_created,camera_freeze,hud_hide,vec3f_copy,set_mario_action,set_mario_animation,camera_unfreeze,hud_show,type,get_id_from_behavior,obj_has_behavior_id,network_local_index_from_global,obj_has_model_extended,obj_set_model_extended,nearest_player_to_object,math_random,djui_hud_set_resolution,djui_hud_set_font,djui_hud_get_screen_width,maxf,djui_hud_set_color,djui_hud_render_rect,djui_hud_measure_text,djui_hud_print_text,min,math_min,math_ceil,math_abs,math_sin,minf,djui_hud_set_rotation,table_insert,djui_hud_print_text_interpolated,math_max,play_sound,play_character_sound,string_lower = mod_storage_load,tonumber,mod_storage_save,djui_popup_create,tostring,djui_chat_message_create,is_game_paused,obj_get_first_with_behavior_id,djui_hud_is_pause_menu_created,camera_freeze,hud_hide,vec3f_copy,set_mario_action,set_mario_animation,camera_unfreeze,hud_show,type,get_id_from_behavior,obj_has_behavior_id,network_local_index_from_global,obj_has_model_extended,obj_set_model_extended,nearest_player_to_object,math.random,djui_hud_set_resolution,djui_hud_set_font,djui_hud_get_screen_width,maxf,djui_hud_set_color,djui_hud_render_rect,djui_hud_measure_text,djui_hud_print_text,min,math.min,math.ceil,math.abs,math.sin,minf,djui_hud_set_rotation,table.insert,djui_hud_print_text_interpolated,math.max,play_sound,play_character_sound,string.lower - menu = false menuAndTransition = false -options = false -local credits = false -local creditsAndTransition = false -currChar = 1 -currCharRender = 1 +gridMenu = mod_storage_load_bool("PrefGridView") +options = nil; OPTIONS_MAIN = 0; OPTIONS_CREDITS = 1 +prevOptions = nil; optionsTimer = 0 +bootChar = CT_MARIO +if gMarioStates[0].character ~= nil then + bootChar = gMarioStates[0].character.type +end +currChar = bootChar +local prevChar = bootChar +currCharRender = bootChar currCategory = 1 local currOption = 1 -local creditScroll = 0 -local prevCreditScroll = creditScroll -local creditScrollRange = 0 +local currCredits = 1 +local currCreditScroll = 0 +local creditScrollMin = 6 +local totalPlaytime = 0 local menuCrossFade = 7 local menuCrossFadeCap = menuCrossFade local menuCrossFadeMath = 255 / menuCrossFade -local creditsCrossFade = 7 -local creditsCrossFadeCap = creditsCrossFade -local creditsCrossFadeMath = 255 / creditsCrossFade +local TYPE_FUNCTION = "function" +local TYPE_BOOLEAN = "boolean" +local TYPE_STRING = "string" +local TYPE_INTEGER = "number" +local TYPE_TABLE = "table" -local TEX_HEADER = get_texture_info("char-select-text") -local TEX_OVERRIDE_HEADER = nil +local MENU_BINDS_DEFAULT = 1 +local MENU_BINDS_GRID = 2 +local MENU_BINDS_OPTIONS = 3 +local MENU_BINDS_CREDITS = 4 +local TEXT_TABLE_MENU_BINDS = { + [MENU_BINDS_DEFAULT] = { + {bind = "Up / Down", desc = "Change Character"}, + {bind = "Left / Right", desc = "Change Costume"}, + {bind = "A Button", desc = "Set Preferred Character"}, + {bind = "B Button", desc = "Exit Menu"}, + {bind = "X Button", desc = "Toggle Grid View"}, + {bind = "Y Button", desc = "Toggle Palette"}, + {bind = "L/R Triggers", desc = "Change Categories"}, + {bind = "Start Button", desc = "Options Menu"}, + }, + [MENU_BINDS_GRID] = { + {bind = "Up / Down / Left / Right", desc = "Change Character"}, + {bind = "A Button", desc = "Set Preferred Character"}, + {bind = "B Button", desc = "Exit Menu"}, + {bind = "X Button", desc = "Toggle List View"}, + {bind = "Y Button", desc = "Toggle Palette"}, + {bind = "L/R Triggers", desc = "Change Categories"}, + {bind = "Start Button", desc = "Options Menu"}, + }, + [MENU_BINDS_OPTIONS] = { + {bind = "Up / Down", desc = "Scroll Options"}, + {bind = "Left / Right", desc = "Toggle Option"}, + {bind = "B Button", desc = "Exit Options Menu"}, + }, + [MENU_BINDS_CREDITS] = { + {bind = "Up / Down", desc = "Scroll Credits"}, + {bind = "Left / Right", desc = "Switch Page"}, + {bind = "B Button", desc = "Exit Credits Menu"}, + }, +} ----@param texture TextureInfo|nil -function header_set_texture(texture) - TEX_OVERRIDE_HEADER = texture -end +local TEX_LOGO = get_texture_info("char_select_logo") +local TEX_WALL_LEFT = get_texture_info("char_select_wall_left") +local TEX_WALL_RIGHT = get_texture_info("char_select_wall_right") +TEX_GRAFFITI_DEFAULT = get_texture_info("char_select_graffiti_default") +local TEX_NAMEPLATE = get_texture_info("char_select_list_button") +local TEX_ALBUM_LAYER1 = get_texture_info("char_select_album_back") +local TEX_ALBUM_LAYER2 = get_texture_info("char_select_album_front") +local TEX_ALBUM_LAYER3 = get_texture_info("char_select_album_overlay") +local TEX_CD_LAYER1 = get_texture_info("char_select_cd_layer1") +local TEX_CD_LAYER2 = get_texture_info("char_select_cd_layer2") +local TEX_CD_LAYER3 = get_texture_info("char_select_cd_layer3") +local TEX_CD_LAYER4 = get_texture_info("char_select_cd_layer4") +local TEX_RECORD = get_texture_info("char_select_record") +local TEX_PALETTE_BUCKET = get_texture_info("char_select_palette_bucket") +local TEX_OPTIONS_TV = get_texture_info("char_select_options_tv") +local TEX_GEAR = get_texture_info("char_select_gear") + +LOCKED_NEVER = 0 +LOCKED_TRUE = 1 +LOCKED_FALSE = 2 + +local SOUND_CHAR_SELECT_THEME = audio_stream_load("char_select_menu_theme.ogg") +local SOUND_CHAR_SELECT_DIAL = audio_stream_load("char_select_dial_wind.ogg") +local menuThemeTargetVolume = 0 +local menuThemeVolume = menuThemeTargetVolume +audio_stream_set_looping(SOUND_CHAR_SELECT_THEME, true) +audio_stream_set_loop_points(SOUND_CHAR_SELECT_THEME, 0, 93.659*22050) CS_ANIM_MENU = CHAR_ANIM_MAX + 1 @@ -67,169 +128,227 @@ local TEXT_PREF_LOAD_ALT = 1 ]] characterTable = { - [1] = { - saveName = "Default", + [CT_MARIO] = { + saveName = "Mario_CoopDX", + nickname = "Mario", category = "All_CoopDX", - ogNum = 1, + ogNum = CT_MARIO, currAlt = 1, hasMoveset = false, - locked = false, + locked = LOCKED_NEVER, + playtime = 0, + autoDialog = true, + replaceModels = {}, [1] = { name = "Mario", - description = { - "The iconic Italian plumber himself!", - "He's quite confident and brave,", - "always prepared to jump into action", - "to save the Mushroom Kingdom!", - }, - credit = "Nintendo / Coop Team", + description = "The iconic Italian plumber himself! He's quite confident and brave, always prepared to jump into action to save the Mushroom Kingdom!", + credit = "Nintendo/CoopDX", color = { r = 255, g = 50, b = 50 }, model = E_MODEL_MARIO, ogModel = E_MODEL_MARIO, - forceChar = CT_MARIO, + baseChar = CT_MARIO, lifeIcon = gTextures.mario_head, starIcon = gTextures.star, camScale = 1.0, + healthMeter = { + label = { + left = get_texture_info("texture_power_meter_left_side"), + right = get_texture_info("texture_power_meter_right_side"), + }, + pie = { + [1] = get_texture_info("texture_power_meter_one_segments"), + [2] = get_texture_info("texture_power_meter_two_segments"), + [3] = get_texture_info("texture_power_meter_three_segments"), + [4] = get_texture_info("texture_power_meter_four_segments"), + [5] = get_texture_info("texture_power_meter_five_segments"), + [6] = get_texture_info("texture_power_meter_six_segments"), + [7] = get_texture_info("texture_power_meter_seven_segments"), + [8] = get_texture_info("texture_power_meter_full"), + } + } }, - [2] = { + }, + [CT_LUIGI] = { + saveName = "Luigi_CoopDX", + nickname = "Luigi", + category = "All_CoopDX", + ogNum = CT_LUIGI, + currAlt = 1, + hasMoveset = false, + locked = LOCKED_NEVER, + playtime = 0, + autoDialog = true, + replaceModels = {}, + [1] = { name = "Luigi", - description = { - "The other iconic Italian plumber!", - "He's a bit shy and scares easily,", - "but he's willing to follow his brother", - "Mario through any battle that may", - "come their way!", - }, - credit = "Nintendo / Coop Team", + description = "The other iconic Italian plumber! He's a bit shy and scares easily, but he's willing to follow his brother Mario through any battle that may come their way!", + credit = "Nintendo/CoopDX", color = { r = 50, g = 255, b = 50 }, model = E_MODEL_LUIGI, ogModel = E_MODEL_LUIGI, - forceChar = CT_LUIGI, + baseChar = CT_LUIGI, lifeIcon = gTextures.luigi_head, starIcon = gTextures.star, camScale = 1.0, - healthTexture = { + healthMeter = { label = { - left = get_texture_info("char-select-luigi-meter-left"), - right = get_texture_info("char-select-luigi-meter-right"), - } + left = get_texture_info("char_select_luigi_meter_left"), + right = get_texture_info("char_select_luigi_meter_right"), + }, + pie = defaultMeterInfo.pie } }, - [3] = { + }, + [CT_TOAD] = { + saveName = "Toad_CoopDX", + nickname = "Toad", + category = "All_CoopDX", + ogNum = CT_TOAD, + currAlt = 1, + hasMoveset = false, + locked = LOCKED_NEVER, + playtime = 0, + autoDialog = true, + replaceModels = {}, + [1] = { name = "Toad", - description = { - "Princess Peach's little attendant!", - "He's an energetic little mushroom", - "that's never afraid to follow", - "Mario and Luigi on their adventures!", - }, - credit = "Nintendo / Coop Team", + description = "Princess Peach's little attendant! He's an energetic little mushroom that's never afraid to follow Mario and Luigi on their adventures!", + credit = "Nintendo/CoopDX", color = { r = 50, g = 50, b = 255 }, model = E_MODEL_TOAD_PLAYER, ogModel = E_MODEL_TOAD_PLAYER, - forceChar = CT_TOAD, + baseChar = CT_TOAD, lifeIcon = gTextures.toad_head, starIcon = gTextures.star, camScale = 0.8, - healthTexture = { + healthMeter = { label = { - left = get_texture_info("char-select-toad-meter-left"), - right = get_texture_info("char-select-toad-meter-right"), - } + left = get_texture_info("char_select_toad_meter_left"), + right = get_texture_info("char_select_toad_meter_right"), + }, + pie = defaultMeterInfo.pie } }, - [4] = { + }, + [CT_WALUIGI] = { + saveName = "Waluigi_CoopDX", + nickname = "Waluigi", + category = "All_CoopDX", + ogNum = CT_WALUIGI, + currAlt = 1, + hasMoveset = false, + locked = LOCKED_NEVER, + playtime = 0, + autoDialog = true, + replaceModels = {}, + [1] = { name = "Waluigi", - description = { - "The mischievous rival of Luigi!", - "He's a narcissistic competitor", - "that takes great taste in others", - "getting pummeled from his success!", - }, - credit = "Nintendo / Coop Team", + description = "The mischievous rival of Luigi! He's a narcissistic competitor that takes great taste in others getting pummeled from his success!", + credit = "Nintendo/CoopDX", color = { r = 130, g = 25, b = 130 }, model = E_MODEL_WALUIGI, ogModel = E_MODEL_WALUIGI, - forceChar = CT_WALUIGI, + baseChar = CT_WALUIGI, lifeIcon = gTextures.waluigi_head, starIcon = gTextures.star, camScale = 1.1, - healthTexture = { + healthMeter = { label = { - left = get_texture_info("char-select-waluigi-meter-left"), - right = get_texture_info("char-select-waluigi-meter-right"), - } + left = get_texture_info("char_select_waluigi_meter_left"), + right = get_texture_info("char_select_waluigi_meter_right"), + }, + pie = defaultMeterInfo.pie } }, - [5] = { + }, + [CT_WARIO] = { + saveName = "Wario_CoopDX", + nickname = "Wario", + category = "All_CoopDX", + ogNum = CT_WARIO, + currAlt = 1, + hasMoveset = false, + locked = LOCKED_NEVER, + playtime = 0, + autoDialog = true, + replaceModels = {}, + [1] = { name = "Wario", - description = { - "The mischievous rival of Mario!", - "He's a greed-filled treasure hunter", - "obsessed with money and gold coins.", - "He's always ready for a brawl if his", - "money is on the line!", - }, - credit = "Nintendo / Coop Team", + description = "The mischievous rival of Mario! He's a greed-filled treasure hunter obsessed with money and gold coins. He's always ready for a brawl if his money is on the line!", + credit = "Nintendo/CoopDX", color = { r = 255, g = 255, b = 50 }, model = E_MODEL_WARIO, ogModel = E_MODEL_WARIO, - forceChar = CT_WARIO, + baseChar = CT_WARIO, lifeIcon = gTextures.wario_head, starIcon = gTextures.star, - camScale = 1.0, - healthTexture = { + camScale = 1.1, + healthMeter = { label = { - left = get_texture_info("char-select-wario-meter-left"), - right = get_texture_info("char-select-wario-meter-right"), - } + left = get_texture_info("char_select_wario_meter_left"), + right = get_texture_info("char_select_wario_meter_right"), + }, + pie = defaultMeterInfo.pie } }, }, } +function character_is_vanilla(charNum) + if charNum == nil then charNum = currChar end + return charNum < CT_MAX +end + characterCategories = { - "All", - "CoopDX", - "Locked", + {name = "All", icon1 = CT_MARIO, icon2 = CT_LUIGI}, + {name = "CoopDX", icon1 = CT_WARIO, icon2 = CT_WALUIGI}, } local characterTableRender = {} -local function update_character_render_table() - local ogNum = currChar - currChar = 1 - currCharRender = 1 - local category = characterCategories[currCategory] - if category == nil then return false end - characterTableRender = {} - local listCount = 0 - for i = 1, #characterTable do - local charCategories = string_split(characterTable[i].category, "_") - for c = 1, #charCategories do - if category == charCategories[c] and not characterTable[i].locked then - table_insert(characterTableRender, characterTable[i]) - if ogNum == i then - currChar = ogNum - currCharRender = #characterTableRender - end - end - end - end - if #characterTableRender > 0 then - currChar = (characterTableRender[currCharRender] and characterTableRender[currCharRender].ogNum or characterTableRender[1].ogNum) - return true - else - return false - end -end - characterCaps = {} -characterCelebrationStar = {} characterColorPresets = {} -characterAnims = {} -characterMovesets = {[1] = {}} +characterpeachletter = {} --the custom texture a character uses for peach's letter in the opening +characterAnims = { + [E_MODEL_MARIO] = { + anims = {[CS_ANIM_MENU] = MARIO_ANIM_CS_MENU}, + eyes = {[CS_ANIM_MENU] = MARIO_EYES_LOOK_RIGHT}, + }, + [E_MODEL_LUIGI] = { + anims = {[CS_ANIM_MENU] = LUIGI_ANIM_CS_MENU}, + eyes = {[CS_ANIM_MENU] = MARIO_EYES_LOOK_RIGHT}, + hands = {[CS_ANIM_MENU] = MARIO_HAND_OPEN} + }, + [E_MODEL_TOAD_PLAYER] = { + anims = {[CS_ANIM_MENU] = TOAD_PLAYER_ANIM_CS_MENU}, + hands = {[CS_ANIM_MENU] = MARIO_HAND_OPEN} + }, + [E_MODEL_WALUIGI] = { + anims = {[CS_ANIM_MENU] = WALUIGI_ANIM_CS_MENU}, + eyes = {[CS_ANIM_MENU] = MARIO_EYES_LOOK_RIGHT}, + }, + [E_MODEL_WARIO] = { + anims = {[CS_ANIM_MENU] = WARIO_ANIM_CS_MENU}, + eyes = {[CS_ANIM_MENU] = MARIO_EYES_LOOK_LEFT}, + }, +} +characterMovesets = { + [CT_MARIO] = {}, + [CT_LUIGI] = {}, + [CT_TOAD] = {}, + [CT_WALUIGI] = {}, + [CT_WARIO] = {}, +} characterUnlock = {} +characterInstrumentals = {} +characterGraffiti = { + [CT_MARIO] = get_texture_info("char_select_graffiti_mario"), + [CT_LUIGI] = get_texture_info("char_select_graffiti_luigi"), + [CT_TOAD] = get_texture_info("char_select_graffiti_toad"), + [CT_WALUIGI] = get_texture_info("char_select_graffiti_waluigi"), + [CT_WARIO] = get_texture_info("char_select_graffiti_wario"), +} +characterDialog = {} tableRefNum = 0 local function make_table_ref_num() @@ -237,26 +356,35 @@ local function make_table_ref_num() return tableRefNum end +OPTION_MENU = "Menu" +OPTION_CHAR = "Character" +OPTION_MISC = "Misc" +OPTION_MOD = "Host" +OPTION_API = "Packs" + optionTableRef = { -- Menu openInputs = make_table_ref_num(), notification = make_table_ref_num(), menuColor = make_table_ref_num(), - anims = make_table_ref_num(), + music = make_table_ref_num(), inputLatency = make_table_ref_num(), -- Characters localMoveset = make_table_ref_num(), - localModels = make_table_ref_num(), localVoices = make_table_ref_num(), + localVisuals = make_table_ref_num(), -- CS credits = make_table_ref_num(), - debugInfo = make_table_ref_num(), resetSaveData = make_table_ref_num(), + -- Moderation + --restrictPalettes = make_table_ref_num(), + restrictMovesets = make_table_ref_num(), } optionTable = { [optionTableRef.openInputs] = { - name = "Open Binds", + name = "Menu Bind", + category = OPTION_MENU, toggle = tonumber(mod_storage_load("MenuInput")), toggleSaveName = "MenuInput", toggleDefault = 1, @@ -266,15 +394,17 @@ optionTable = { }, [optionTableRef.notification] = { name = "Notifications", + category = OPTION_MENU, toggle = tonumber(mod_storage_load("notifs")), toggleSaveName = "notifs", toggleDefault = 1, toggleMax = 2, toggleNames = {"Off", "On", "Pop-ups Only"}, - description = {"Toggles whether Pop-ups and", "Chat Messages display"} + description = {"Toggles whether Pop-ups and", "Chat Messages display."} }, [optionTableRef.menuColor] = { name = "Menu Color", + category = OPTION_MENU, toggle = tonumber(mod_storage_load("MenuColor")), toggleSaveName = "MenuColor", toggleDefault = 0, @@ -282,17 +412,19 @@ optionTable = { toggleNames = {"Auto", "Saved", "Red", "Orange", "Yellow", "Green", "Blue", "Pink", "Purple", "White", "Black"}, description = {"Toggles the Menu Color"} }, - [optionTableRef.anims] = { - name = "Menu Anims", - toggle = tonumber(mod_storage_load("Anims")), - toggleSaveName = "Anims", + [optionTableRef.music] = { + name = "Menu Music", + category = OPTION_MENU, + toggle = tonumber(mod_storage_load("Music")), + toggleSaveName = "Music", toggleDefault = 1, - toggleMax = 1, - toggleNames = {"Off", "On"}, - description = {"Toggles Animations In-Menu,", "Turning these off may", "Save Performance"} + toggleMax = 3, + toggleNames = {"Off", "On", "Breakroom Only", "Character Only"}, + description = {"Toggles which music plays", "in the menu."} }, [optionTableRef.inputLatency] = { - name = "Scroll Speed", + name = "Menu Scroll Speed", + category = OPTION_MENU, toggle = tonumber(mod_storage_load("Latency")), toggleSaveName = "Latency", toggleDefault = 1, @@ -300,70 +432,175 @@ optionTable = { toggleNames = {"Slow", "Normal", "Fast"}, description = {"Sets how fast you scroll", "throughout the Menu"} }, + [optionTableRef.localVoices] = { + name = "Character Voices", + category = OPTION_CHAR, + toggle = tonumber(mod_storage_load("localVoices")), + toggleSaveName = "localVoices", + toggleDefault = 1, + toggleMax = 2, + toggleNames = {"Off", "On", "Local Only"}, + description = {"Toggle if Custom Voicelines play", "for Characters who support it"} + }, + [optionTableRef.localVisuals] = { + name = "Character Visuals", + category = OPTION_CHAR, + toggle = tonumber(mod_storage_load("localVisuals")), + toggleSaveName = "localVisuals", + toggleDefault = 1, + toggleMax = 1, + description = {"Toggle if Characters can", "change how objects/textures appear"} + }, [optionTableRef.localMoveset] = { name = "Character Moveset", + category = OPTION_CHAR, toggle = tonumber(mod_storage_load("localMoveset")), toggleSaveName = "localMoveset", toggleDefault = 1, toggleMax = 1, - description = {"Toggles if Custom Movesets", "are active on compatible", "characters"} - }, - [optionTableRef.localModels] = { - name = "Locally Display Models", - toggle = tonumber(mod_storage_load("localModels")), - toggleSaveName = "localModels", - toggleDefault = 1, - toggleMax = 1, - description = {"Toggles if Custom Models display", "on your client, practically", "disables Character Select if", "Toggled Off"} - }, - [optionTableRef.localVoices] = { - name = "Custom Voices", - toggle = tonumber(mod_storage_load("localVoices")), - toggleSaveName = "localVoices", - toggleDefault = 1, - toggleMax = 1, - description = {"Toggle if Custom Voicelines play", "for Characters who support it"} + description = {"Toggles if Custom Movesets", "are active on compatible", "characters"}, + lock = function () + if gGlobalSyncTable.charSelectRestrictMovesets ~= 0 then + return "Forced Off" + end + end, }, [optionTableRef.credits] = { name = "Credits", + category = OPTION_MISC, toggle = 0, toggleDefault = 0, toggleMax = 1, - toggleNames = {"", ""}, + toggleNames = {"Open Credits", "Open Credits"}, description = {"Thank you for choosing", "Character Select!"} }, - [optionTableRef.debugInfo] = { - name = "Debugging Info", - toggle = tonumber(mod_storage_load("debuginfo")), - toggleSaveName = "debuginfo", - toggleDefault = 0, - toggleMax = 1, - description = {"Replaces the Character", "Description with Character", "Debugging Information"} - }, [optionTableRef.resetSaveData] = { name = "Reset Save Data", + category = OPTION_MISC, toggle = 0, toggleDefault = 0, toggleMax = 1, - toggleNames = {"", ""}, + toggleNames = {"Reset Save Data", "Reset Save Data"}, description = {"Resets Character Select's", "Save Data"} }, + [optionTableRef.restrictMovesets] = { + name = "Restrict Movesets", + category = OPTION_MOD, + toggle = 0, + toggleDefault = 1, + toggleMax = 1, + description = {"Restricts turning on movesets", "(Host Only)"}, + lock = function () + if gGlobalSyncTable.charSelectRestrictMovesets < 2 then + if not network_is_server() then + return "Host Only" + end + else + return "API Only" + end + end, + }, } +local gridYOffset = 0 +local function update_character_render_table() + gridYOffset = -100 + local ogNum = currChar + local insertNum = 0 + currChar = 0 + currCharRender = 0 + local category = characterCategories[currCategory] + if category == nil then return false end + characterTableRender = {} + for i = 0, #characterTable do + local charCategories = string_split(characterTable[i].category, "_") + if characterTable[i].locked ~= LOCKED_TRUE then + for c = 1, #charCategories do + if category.name == charCategories[c] then + characterTableRender[insertNum] = characterTable[i] + characterTableRender[insertNum].UIOffset = 0 + if ogNum == i then + currChar = ogNum + currCharRender = num_wrap(insertNum, 0, #characterTableRender) + end + insertNum = insertNum + 1 + end + end + end + end + + if #characterTableRender > 0 then + -- Get icons for category based on name similarity + if category.icon1 == nil or category.icon2 == nil then + local sorted = {} + for i = 0, #characterTableRender do + local char = characterTableRender[i] + table.insert(sorted, {ogNum = char.ogNum, sim = string_sim(char.saveName, category.name)}) + end + table.sort(sorted, function(a, b) + log_to_console_once(tostring(a.ogNum) .. " - " .. tostring(a.sim), CONSOLE_MESSAGE_INFO) + log_to_console_once(tostring(b.ogNum) .. " - " .. tostring(b.sim), CONSOLE_MESSAGE_INFO) + return a.sim < b.sim + end) + category.icon1 = category.icon1 or sorted[1].ogNum + category.icon2 = category.icon2 or sorted[2].ogNum + end + -- Set Character if they are in the category + currChar = (characterTableRender[currCharRender] and characterTableRender[currCharRender].ogNum or characterTableRender[0].ogNum) + return true + else + return false + end +end + +function force_set_character(charNum, charAlt) + if not charNum then charNum = gNetworkPlayers[0].modelIndex end + if not charAlt then charAlt = 1 end + currCategory = 1 + currChar = charNum + characterTable[currChar].currAlt = charAlt + currCharRender = charNum + charBeingSet = true + update_character_render_table() +end + +---@description A function that gets an option's status from the Character Select Options Menu +---@param tableNum integer The table position of the option +---@return number? +function get_options_status(tableNum) + if type(tableNum) ~= TYPE_INTEGER then return nil end + return optionTable[tableNum].toggle +end + +---@class Credits +---@field packName string + +---@class Credit +---@field creditee string +---@field credit string + +---@type Credits[] creditTable = { - { + [1] = { packName = "Character Select Coop", - {creditTo = "Squishy6094", creditFor = "Creator"}, - {creditTo = "AngelicMiracles", creditFor = "Concepts / CoopDX"}, - {creditTo = "AgentX", creditFor = "Main Contributer / CoopDX"}, - {creditTo = "xLuigiGamerx", creditFor = "Main Contributer"}, - {creditTo = "OneCalledRPG", creditFor = "Contributer"}, - {creditTo = "SuperKirbyLover", creditFor = "Custom Health Meters"}, - {creditTo = "EliteMasterEric", creditFor = "Dialog Replacement"} + { creditee = "Squishy6094", credit = "Creator" }, + { creditee = "JerThePear", credit = "Menu Assets/Anims" }, + { creditee = "Trashcam", credit = "Menu Music" }, + { creditee = "Charity", credit = "Sound Design" }, + { creditee = "WinbowBreaker", credit = "Menu Asset Renders" }, + { creditee = "xLuigiGamerx", credit = "HUD Accuracy" }, + { creditee = "Wibblus", credit = "Menu Anims Code" }, } } -local defaultOptionCount = #optionTable +if CREDIT_SUPPORTERS ~= nil then + creditTable[0] = { + packName = "Character Select Supporters", + } + for i = 1, #CREDIT_SUPPORTERS do + table.insert(creditTable[0], { creditee = CREDIT_SUPPORTERS[i]}) + end +end local latencyValueTable = {12, 6, 3} @@ -407,45 +644,50 @@ end local prefCharColor = {r = 255, g = 50, b = 50} local function load_preferred_char() + local m = gMarioStates[0] local savedChar = mod_storage_load("PrefChar") + local savedNick = mod_storage_load("PrefNick") local savedAlt = tonumber(mod_storage_load("PrefAlt")) local savedPalette = tonumber(mod_storage_load("PrefPalette")) if savedChar == nil or savedChar == "" then - mod_storage_save("PrefChar", "Default") - savedChar = "Default" + mod_storage_save("PrefChar", characterTable[bootChar].saveName) + savedChar = characterTable[bootChar].saveName end if savedAlt == nil then mod_storage_save("PrefAlt", "1") savedAlt = 1 end if savedPalette == nil then - local paletteSave = savedChar ~= "Default" and 1 or 0 + local paletteSave = 0 mod_storage_save("PrefAlt", tostring(paletteSave)) savedPalette = paletteSave end - if savedChar ~= "Default" and optionTable[optionTableRef.localModels].toggle == 1 then - for i = 2, #characterTable do - local char = characterTable[i] - if char.saveName == savedChar and not char.locked then - currChar = i - currCharRender = i - if savedAlt > 0 and savedAlt <= #char then - char.currAlt = savedAlt - end - local model = characterTable[currChar][savedAlt].model - if characterColorPresets[model] ~= nil then - gCSPlayers[0].presetPalette = savedPalette - characterColorPresets[model].currPalette = savedPalette - end - if optionTable[optionTableRef.notification].toggle > 0 then - djui_popup_create('Character Select:\nYour Preferred Character\n"' .. string_underscore_to_space(char[char.currAlt].name) .. '"\nwas applied successfully!', 4) - end - break + + -- Find Saved Character + local charFound = false + for i = 0, #characterTable do + local char = characterTable[i] + if char.saveName == savedChar and char.locked ~= LOCKED_TRUE then + currChar = i + currCharRender = i + charFound = true + if optionTable[optionTableRef.notification].toggle > 0 then + djui_popup_create('Character Select:\nYour Preferred Character\n"' .. string_underscore_to_space(char[char.currAlt].name) .. '"\nwas applied successfully!', 4) end + break end end - - characterTable[1].currAlt = gNetworkPlayers[0].modelIndex + 1 + + -- Set Alt + savedAlt = math.clamp(savedAlt, 1, #characterTable[currChar]) + characterTable[currChar].currAlt = savedAlt + + -- Set Palette + local model = characterTable[currChar][savedAlt].model + if characterColorPresets[model] ~= nil then + gCSPlayers[0].presetPalette = charFound and savedPalette or 0 + characterColorPresets[model].currPalette = gCSPlayers[0].presetPalette + end local savedCharColors = mod_storage_load("PrefCharColor") if savedCharColors ~= nil and savedCharColors ~= "" then @@ -459,22 +701,32 @@ local function load_preferred_char() mod_storage_save("PrefCharColor", "255_50_50") end - if #characterTable == 1 then + if #characterTable < CT_MAX then if optionTable[optionTableRef.notification].toggle > 0 then djui_popup_create("Character Select:\nNo Characters were Found", 2) end + else + if not charFound then + if savedNick ~= nil then + djui_popup_create('Character Select:\nYour Preferred Character\n"' .. string_underscore_to_space(savedNick) .. '"\nwas not found.', 4) + else + djui_popup_create('Character Select:\nYour Preferred Character\nwas not found.', 3) + end + end end - TEXT_PREF_LOAD_NAME = savedChar + TEXT_PREF_LOAD_NAME = string_space_to_underscore(savedNick or savedChar) TEXT_PREF_LOAD_ALT = savedAlt update_character_render_table() end local function mod_storage_save_pref_char(charTable) + charTable = charTable or characterTable[bootChar] mod_storage_save("PrefChar", charTable.saveName) + mod_storage_save("PrefNick", string_space_to_underscore(charTable.nickname)) mod_storage_save("PrefAlt", tostring(charTable.currAlt)) - mod_storage_save("PrefCharColor", tostring(charTable[charTable.currAlt].color.r) .. "_" .. tostring(charTable[charTable.currAlt].color.g) .. "_" .. tostring(charTable[charTable.currAlt].color.b)) mod_storage_save("PrefPalette", tostring(gCSPlayers[0].presetPalette)) - TEXT_PREF_LOAD_NAME = charTable.saveName + mod_storage_save("PrefCharColor", tostring(charTable[charTable.currAlt].color.r) .. "_" .. tostring(charTable[charTable.currAlt].color.g) .. "_" .. tostring(charTable[charTable.currAlt].color.b)) + TEXT_PREF_LOAD_NAME = string_space_to_underscore(charTable.nickname) TEXT_PREF_LOAD_ALT = charTable.currAlt prefCharColor = charTable[charTable.currAlt].color end @@ -497,15 +749,13 @@ function failsafe_options() end end +hookTableOnReset = {} local promptedAreYouSure = false - local function reset_options(wasChatTriggered) if not promptedAreYouSure then djui_chat_message_create("\\#ffdcdc\\Are you sure you want to reset your Save Data for Character Select, including your Preferred Character\nand Settings?\n" .. (wasChatTriggered and "Type \\#ff3333\\/char-select reset\\#ffdcdc\\ to confirm." or "Press the \\#ff3333\\" .. optionTable[optionTableRef.resetSaveData].name .. "\\#ffdcdc\\ Option again to confirm." )) promptedAreYouSure = true else - djui_chat_message_create("\\#ff3333\\Character Select Save Data Reset!") - djui_chat_message_create("Note: If your issue has not been resolved, you may need to manually delete your save data via the directory below:\n\\#dcdcFF\\%appdata%/sm64coopdx/sav/character-select-coop.sav") for i = 1, #optionTable do optionTable[i].toggle = optionTable[i].toggleDefault if optionTable[i].toggleSaveName ~= nil then @@ -515,20 +765,32 @@ local function reset_options(wasChatTriggered) optionTable[i].toggleNames = { "Off", "On" } end end - currChar = 1 - for i = 1, #characterTable do + for i = 0, #characterTable do characterTable[i].currAlt = 1 + characterTable[i].locked = characterTable[i].locked == LOCKED_NEVER and LOCKED_NEVER or LOCKED_TRUE end - mod_storage_save_pref_char(characterTable[1]) + mod_storage_save_pref_char() + + if #hookTableOnReset > 0 then + for i = 1, #hookTableOnReset do + hookTableOnReset[i]() + end + end + + force_set_character() + + djui_chat_message_create("\\#ff3333\\Character Select Save Data Reset!") + djui_chat_message_create("Note: If your issue has not been resolved, you may need to manually delete your save data via the directory below:\n\\#dcdcFF\\%appdata%/sm64coopdx/sav/character-select-coop.sav") promptedAreYouSure = false end end local function boot_note() - if #characterTable > 1 then - djui_chat_message_create("Character Select has " .. (#characterTable - 1) .. " character" .. (#characterTable > 2 and "s" or "") .." available!\nYou can use \\#ffff33\\/char-select \\#ffffff\\to open the menu!") - if #characterTable > 32 and network_is_server() then - djui_chat_message_create("\\#FFAAAA\\Warning: Having more than 32 Characters\nmay be unstable, For a better experience please\ndisable a few packs!") + local charCount = (#characterTable + 1) - CT_MAX + if charCount > 0 then + djui_chat_message_create("Character Select has " .. charCount .. " character" .. (charCount > 1 and "s" or "") .." available!\nYou can use \\#ffff33\\/char-select \\#ffffff\\to open the menu!") + if charCount > 32 and network_is_server() then + djui_chat_message_create("\\#FFAAAA\\Warning: Having a lot of characters\nmay be unstable, For a better experience please\ndisable a few packs!") end else djui_chat_message_create("Character Select is active!\nYou can use \\#ffff33\\/char-select \\#ffffff\\to open the menu!") @@ -552,6 +814,7 @@ local function menu_is_allowed(m) end -- Cutscene Check + if m.action & ACT_GROUP_CUTSCENE ~= 0 then return false end if gNetworkPlayers[0].currActNum == 99 then return false end if m.action == ACT_INTRO_CUTSCENE then return false end if obj_get_first_with_behavior_id(id_bhvActSelector) ~= nil then return false end @@ -559,54 +822,93 @@ local function menu_is_allowed(m) return true end ---[[ -local function get_next_unlocked_char() - for i = currChar, #characterTable do - if not characterTable[i].locked then - return i +hookTableOnCharacterChange = { + [1] = function (prevChar, currChar) + -- Check for Non-Vanilla Actions when switching Characters + local m = gMarioStates[0] + if is_mario_in_vanilla_action(m) or m.health < 256 then return end + if m.action & ACT_FLAG_RIDING_SHELL ~= 0 then + set_mario_action(m, ACT_RIDING_SHELL_FALL, 0) + elseif m.action & ACT_FLAG_ALLOW_FIRST_PERSON ~= 0 then + set_mario_action(m, ACT_IDLE, 0) + elseif m.action & ACT_GROUP_MOVING ~= 0 or m.action & ACT_FLAG_MOVING ~= 0 then + set_mario_action(m, ACT_WALKING, 0) + elseif m.action & ACT_GROUP_SUBMERGED ~= 0 or m.action & ACT_FLAG_SWIMMING ~= 0 then + -- Need to fix upwarping + set_mario_action(m, ACT_WATER_IDLE, 0) + else + set_mario_action(m, ACT_FREEFALL, 0) end - end - return 1 -end -local function get_last_unlocked_char() - for i = currChar, 1, -1 do - if not characterTable[i].locked then - return i - end + -- Switch all models to either Vanilla or the Character's + set_all_models() + end +} + +local function on_character_change(prevChar, currChar) + for i = 1, #hookTableOnCharacterChange do + hookTableOnCharacterChange[i](prevChar, currChar) end - return 1 end -]] ------------------- -- Model Handler -- ------------------- -local stallFrame = 0 +-- Port of SM64's idle action without transistion bs +local ACT_CS_MENU_IDLE = allocate_mario_action(ACT_FLAG_STATIONARY | ACT_FLAG_IDLE | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT) +---@param m MarioState +local function act_cs_menu_idle(m) + if not m then return 0 end + local p = gCSPlayers[m.playerIndex] + if (m.quicksandDepth > 30.0) then + return set_mario_action(m, ACT_IN_QUICKSAND, 0); + end + + if (check_common_idle_cancels(m) ~= 0) then + return 1; + end + + m.actionState = 0 + m.actionTimer = 0 + + local customIdleExists = (characterAnims[p.modelId] and characterAnims[p.modelId].anims and characterAnims[p.modelId].anims[CS_ANIM_MENU]) + set_character_animation(m, customIdleExists and CS_ANIM_MENU or CHAR_ANIM_FIRST_PERSON) + + stationary_ground_step(m); + + return 0 +end +hook_mario_action(ACT_CS_MENU_IDLE, act_cs_menu_idle) CUTSCENE_CS_MENU = 0xFA -local TYPE_FUNCTION = "function" -local TYPE_BOOLEAN = "boolean" -local TYPE_STRING = "string" -local TYPE_INTEGER = "number" -local TYPE_TABLE = "table" - -local MATH_PI = math.pi - local prevBaseCharFrame = gNetworkPlayers[0].modelIndex -local prevAnim = 0 -local animTimer = 0 -local faceAngle = 0 -local eyeState = MARIO_EYES_OPEN -local prevFOV = 40 -local menuFOV = 45 ---- @param m MarioState +local prevBasePalette = { + [PANTS] = network_player_get_palette_color(gNetworkPlayers[0], PANTS), + [SHIRT] = network_player_get_palette_color(gNetworkPlayers[0], SHIRT), + [GLOVES] = network_player_get_palette_color(gNetworkPlayers[0], GLOVES), + [SHOES] = network_player_get_palette_color(gNetworkPlayers[0], SHOES), + [HAIR] = network_player_get_palette_color(gNetworkPlayers[0], HAIR), + [SKIN] = network_player_get_palette_color(gNetworkPlayers[0], SKIN), + [CAP] = network_player_get_palette_color(gNetworkPlayers[0], CAP), + [EMBLEM] = network_player_get_palette_color(gNetworkPlayers[0], EMBLEM), +} +local worldColor = { + lighting = {r = 255, g = 255, b = 255}, + skybox = {r = 255, g = 255, b = 255}, + fog = {r = 255, g = 255, b = 255}, + vertex = {r = 255, g = 255, b = 255}, + ambient = {r = 255, g = 255, b = 255} +} +local menuOffsetX = 0 +local menuOffsetY = 0 +local camScale = 1 +local prevMusicToggle = 1 +local prevVisualToggle = 1 +---@param m MarioState local function mario_update(m) - local np = gNetworkPlayers[m.playerIndex] - local p = gCSPlayers[m.playerIndex] - if stallFrame == 1 or queueStorageFailsafe then + if m.playerIndex == 0 and (startup_init_stall(1) or queueStorageFailsafe) then failsafe_options() if not queueStorageFailsafe then load_preferred_char() @@ -614,104 +916,254 @@ local function mario_update(m) boot_note() end end + set_all_models() queueStorageFailsafe = false end - - if stallFrame < 3 then - stallFrame = stallFrame + 1 - end - - if m.playerIndex == 0 and stallFrame > 1 then - if djui_hud_is_pause_menu_created() and prevBaseCharFrame ~= np.modelIndex then - characterTable[1].currAlt = np.modelIndex + 1 - currChar = 1 - p.presetPalette = 0 - end - prevBaseCharFrame = np.modelIndex - - if optionTable[optionTableRef.localModels].toggle == 0 then - currCategory = 1 - currChar = 1 - currCharRender = 1 - end - - local charTable = characterTable[currChar] - p.saveName = charTable.saveName - p.currAlt = charTable.currAlt - p.modelId = charTable[charTable.currAlt].model - if charTable[charTable.currAlt].forceChar ~= nil then - p.forceChar = charTable[charTable.currAlt].forceChar - end - p.modelEditOffset = charTable[charTable.currAlt].model - charTable[charTable.currAlt].ogModel - m.marioObj.hookRender = 1 + local np = gNetworkPlayers[m.playerIndex] + local p = gCSPlayers[m.playerIndex] - if menuAndTransition then - --play_secondary_music(0, 0, 0.5, 0) - camera_freeze() - hud_hide() - if m.area.camera.cutscene == 0 then - m.area.camera.cutscene = CUTSCENE_CS_MENU - end - local camScale = charTable[charTable.currAlt].camScale - local focusPos = { - x = m.pos.x, - y = m.pos.y + 120 * camScale, - z = m.pos.z, - } - set_override_fov(menuFOV) - vec3f_copy(gLakituState.focus, focusPos) - m.marioBodyState.eyeState = eyeState - gLakituState.pos.x = m.pos.x + sins(faceAngle) * 500 * camScale - gLakituState.pos.y = m.pos.y + 100 * camScale - gLakituState.pos.z = m.pos.z + coss(faceAngle) * 500 * camScale - set_window_title("Character Select v".. MOD_VERSION_STRING .. " - " .. string_underscore_to_space(charTable[charTable.currAlt].name) .. " (CoopDX)") - p.inMenu = true - else - if p.inMenu then - --stop_secondary_music(50) - camera_unfreeze() - hud_show() - set_override_fov(prevFOV) - if m.area.camera.cutscene == CUTSCENE_CS_MENU then - m.area.camera.cutscene = CUTSCENE_STOP - end - p.inMenu = false - reset_window_title() - end - local currFOV = get_current_fov() - if currFOV ~= menuFOV then - prevFOV = currFOV - end - end + if m.playerIndex == 0 then + -- Used for Viewport stuffs + m.marioObj.header.gfx.sharedChild.hookProcess = 1 -- Check for Locked Chars - for i = 2, #characterTable do - local currChar = characterTable[i] - if currChar.locked then + for i = CT_MAX, #characterTable do + local char = characterTable[i] + if char.locked ~= LOCKED_NEVER then local unlock = characterUnlock[i].check local notif = characterUnlock[i].notif + local prevLockState = char.locked if type(unlock) == TYPE_FUNCTION then - if unlock() then - currChar.locked = false - end + char.locked = (unlock() ~= false) and LOCKED_FALSE or LOCKED_TRUE elseif type(unlock) == TYPE_BOOLEAN then - currChar.locked = not unlock + char.locked = (unlock ~= false) and LOCKED_FALSE or LOCKED_TRUE end - if not currChar.locked then -- Character was unlocked + if char.locked ~= prevLockState then update_character_render_table() - if stallFrame == 3 and notif then - if optionTable[optionTableRef.notification].toggle > 0 then - djui_popup_create('Character Select:\nUnlocked '..tostring(currChar[1].name)..'\nas a Playable Character!', 3) + if prevLockState == LOCKED_TRUE then -- Character was unlocked + if startup_init_stall() and notif then + if optionTable[optionTableRef.notification].toggle > 0 then + djui_popup_create('Character Select:\nUnlocked '..tostring(char[1].name)..'\nas a Playable Character!', 3) + end end end end end end + if djui_hud_is_pause_menu_created() then + if prevBaseCharFrame ~= np.modelIndex then + force_set_character(np.modelIndex) + p.presetPalette = 0 + end + + if gCSPlayers[0].presetPalette ~= 0 then + for i = PANTS, EMBLEM do + local prevColor = prevBasePalette[i] + local currColor = network_player_get_palette_color(np, i) + if prevColor.r ~= currColor.r or prevColor.g ~= currColor.g or prevColor.b ~= currColor.b then + local model = characterTable[currChar][characterTable[currChar].currAlt].model + gCSPlayers[0].presetPalette = 0 + characterColorPresets[model].currPalette = 0 + prevColor.r = currColor.r + prevColor.g = currColor.g + prevColor.b = currColor.b + end + end + end + end + prevBaseCharFrame = np.modelIndex + + local charTable = characterTable[currChar] + p.saveName = charTable.saveName + p.currAlt = charTable.currAlt + + p.modelId = charTable[charTable.currAlt].model + if charTable[charTable.currAlt].baseChar ~= nil then + p.baseChar = charTable[charTable.currAlt].baseChar + end + p.modelEditOffset = charTable[charTable.currAlt].model - charTable[charTable.currAlt].ogModel + m.marioObj.hookRender = 1 + + if menu and m.action == ACT_SLEEPING then + set_mario_action(m, ACT_WAKING_UP, m.actionArg) + end + + if menu and options == OPTIONS_MAIN then + if (network_is_server() or network_is_moderator()) and gGlobalSyncTable.charSelectRestrictMovesets < 2 then + gGlobalSyncTable.charSelectRestrictMovesets = optionTable[optionTableRef.restrictMovesets].toggle + end + else + optionTable[optionTableRef.restrictMovesets].toggle = gGlobalSyncTable.charSelectRestrictMovesets + end + + if prevVisualToggle ~= optionTable[optionTableRef.localVisuals].toggle then + set_all_models() + prevVisualToggle = optionTable[optionTableRef.localVisuals].toggle + end + + if menuAndTransition then + local musicToggle = optionTable[optionTableRef.music].toggle + local charInst = characterInstrumentals[currChar] + if not p.inMenu or prevMusicToggle ~= musicToggle or prevChar ~= currChar then + local levelMusic = false + if musicToggle == 0 then + levelMusic = true + end + audio_stream_play(SOUND_CHAR_SELECT_THEME, false, 0) + if musicToggle ~= 0 and musicToggle ~= 3 then + menuThemeTargetVolume = 1 + levelMusic = false + else + menuThemeTargetVolume = 0 + end + + -- Set Target Volumes + for i = 0, #characterTable do + local charInst = characterInstrumentals[i] + if charInst ~= nil then + audio_stream_play(charInst.audio, false, 1) + charInst.targetVolume = 0 + end + end + if musicToggle ~= 0 and musicToggle ~= 2 then + if charInst ~= nil then + charInst.targetVolume = 1 + levelMusic = false + elseif menuThemeTargetVolume == 0 then + levelMusic = true + end + end + + if levelMusic then + stop_secondary_music(50) + else + play_secondary_music(0, 0, 0, 50) + end + prevMusicToggle = musicToggle + p.inMenu = true + end + + -- Update Volumes + menuThemeVolume = math.lerp(menuThemeVolume, menuThemeTargetVolume, 0.1) + audio_stream_set_volume(SOUND_CHAR_SELECT_THEME, menuThemeVolume) + + for i = 0, #characterTable do + local charInst = characterInstrumentals[i] + if charInst ~= nil then + charInst.volume = math.lerp(charInst.volume, charInst.targetVolume, 0.1) + audio_stream_set_volume(charInst.audio, charInst.volume) + end + end + + camera_freeze() + hud_hide() + djui_hud_set_resolution(RESOLUTION_N64) + local widthScale = djui_hud_get_screen_width()/320 + if m.area.camera.cutscene == 0 then + m.area.camera.cutscene = CUTSCENE_CS_MENU + end + m.marioBodyState.eyeState = MARIO_EYES_OPEN + camScale = math.lerp(camScale, charTable[charTable.currAlt].camScale, 0.1) + local camDist = 400 * camScale + local camAngle = m.faceAngle.y + 0x800 + local camOffsetX = mirror_mode_number(-menuOffsetX) + local focusPos = { + x = m.pos.x + sins(camAngle - 0x4000)*camOffsetX*camScale, + y = m.pos.y + (100 - menuOffsetY) * camScale , + z = m.pos.z + coss(camAngle - 0x4000)*camOffsetX*camScale, + } + vec3f_copy(gLakituState.focus, focusPos) + + local camPos = { + x = (m.pos.x + sins(camAngle) * camDist + sins(camAngle - 0x4000)*camOffsetX), + y = m.pos.y - (menuOffsetY*camScale), + z = (m.pos.z + coss(camAngle) * camDist + sins(camAngle - 0x4000)*camOffsetX), + } + camPos.y = collision_find_surface_on_ray(camPos.x, camPos.y + 300, camPos.z, 0, -300, 0).hitPos.y + 20 + + local camHit = collision_find_surface_on_ray(focusPos.x, focusPos.y, focusPos.z, camPos.x - focusPos.x, camPos.y - focusPos.y, camPos.z - focusPos.z).hitPos + vec3f_copy(gLakituState.pos, camHit) + set_override_fov(45/widthScale) + + set_lighting_color(0, (menuColor.r*0.33 + 255*0.66) * worldColor.lighting.r/255) + set_lighting_color(1, (menuColor.g*0.33 + 255*0.66) * worldColor.lighting.g/255) + set_lighting_color(2, (menuColor.b*0.33 + 255*0.66) * worldColor.lighting.b/255) + set_lighting_color_ambient(0, (menuColor.r*0.33 + 255*0.66) * worldColor.ambient.r/127) + set_lighting_color_ambient(1, (menuColor.g*0.33 + 255*0.66) * worldColor.ambient.g/127) + set_lighting_color_ambient(2, (menuColor.b*0.33 + 255*0.66) * worldColor.ambient.b/127) + set_skybox_color(0, menuColor.r * worldColor.lighting.r/255) + set_skybox_color(1, menuColor.g * worldColor.lighting.g/255) + set_skybox_color(2, menuColor.b * worldColor.lighting.b/255) + set_fog_color(0, menuColor.r * worldColor.lighting.r/255) + set_fog_color(1, menuColor.g * worldColor.lighting.g/255) + set_fog_color(2, menuColor.b * worldColor.lighting.b/255) + set_vertex_color(0, menuColor.r * worldColor.lighting.r/255) + set_vertex_color(1, menuColor.g * worldColor.lighting.g/255) + set_vertex_color(2, menuColor.b * worldColor.lighting.b/255) + else + if p.inMenu then + audio_stream_stop(SOUND_CHAR_SELECT_THEME) + for i = 0, #characterTable do + local charInst = characterInstrumentals[i] + if charInst ~= nil then + audio_stream_stop(charInst.audio) + end + end + stop_secondary_music(50) + m.marioObj.header.gfx.sharedChild.hookProcess = 1 + camera_unfreeze() + hud_show() + set_override_fov(0) + if m.area.camera.cutscene == CUTSCENE_CS_MENU then + m.area.camera.cutscene = CUTSCENE_STOP + end + set_lighting_color(0, worldColor.lighting.r) + set_lighting_color(1, worldColor.lighting.g) + set_lighting_color(2, worldColor.lighting.b) + set_lighting_color_ambient(0, worldColor.ambient.r) + set_lighting_color_ambient(1, worldColor.ambient.g) + set_lighting_color_ambient(2, worldColor.ambient.b) + set_skybox_color(0, worldColor.skybox.r) + set_skybox_color(1, worldColor.skybox.g) + set_skybox_color(2, worldColor.skybox.b) + set_fog_color(0, worldColor.fog.r) + set_fog_color(1, worldColor.fog.g) + set_fog_color(2, worldColor.fog.b) + set_vertex_color(0, worldColor.vertex.r) + set_vertex_color(1, worldColor.vertex.g) + set_vertex_color(2, worldColor.vertex.b) + p.inMenu = false + end + + worldColor.lighting.r = get_lighting_color(0) + worldColor.lighting.g = get_lighting_color(1) + worldColor.lighting.b = get_lighting_color(2) + worldColor.ambient.r = get_lighting_color_ambient(0) + worldColor.ambient.g = get_lighting_color_ambient(1) + worldColor.ambient.b = get_lighting_color_ambient(2) + worldColor.skybox.r = get_skybox_color(0) + worldColor.skybox.g = get_skybox_color(1) + worldColor.skybox.b = get_skybox_color(2) + worldColor.fog.r = get_fog_color(0) + worldColor.fog.g = get_fog_color(1) + worldColor.fog.b = get_fog_color(2) + worldColor.vertex.r = get_vertex_color(0) + worldColor.vertex.g = get_vertex_color(1) + worldColor.vertex.b = get_vertex_color(2) + + if startup_init_stall() then + -- Update playtime + characterTable[currChar].playtime = characterTable[currChar].playtime + 1 + totalPlaytime = totalPlaytime + 1 + end + end + --Open Credits if optionTable[optionTableRef.credits].toggle > 0 then - credits = true + options = OPTIONS_CREDITS + currOption = 1 optionTable[optionTableRef.credits].toggle = 0 end @@ -726,63 +1178,94 @@ local function mario_update(m) end p.movesetToggle = optionTable[optionTableRef.localMoveset].toggle ~= 0 - end - - if p.inMenu and m.action & ACT_FLAG_ALLOW_FIRST_PERSON ~= 0 then - set_mario_animation(m, (characterAnims[p.modelId] and characterAnims[p.modelId][CS_ANIM_MENU]) and CS_ANIM_MENU or MARIO_ANIM_IDLE_HEAD_LEFT) - set_anim_to_frame(m, 0) - m.marioObj.header.gfx.angle.y = m.faceAngle.y + if prevChar ~= currChar then + on_character_change(prevChar, currChar) + prevChar = currChar + end end - local marioGfx = m.marioObj.header.gfx - if prevAnim ~= marioGfx.animInfo.animID then - prevAnim = marioGfx.animInfo.animID - animTimer = 0 + if p.inMenu and m.action & ACT_FLAG_ALLOW_FIRST_PERSON ~= 0 then + set_mario_action(m, ACT_CS_MENU_IDLE, 0) + m.actionArg = 0 + m.actionState = 0xFFFF + + -- reset menu anim on character change, starts them at frame 0 and prevents lua anim issues + if p.prevModelId ~= p.modelId then + p.prevModelId = p.modelId + m.marioObj.header.gfx.animInfo.animID = -1 + end + + m.marioObj.header.gfx.angle.y = m.faceAngle.y + elseif m.action == ACT_CS_MENU_IDLE then + set_mario_action(m, ACT_IDLE, 0) end - animTimer = animTimer + 1 - - np.overrideModelIndex = p.forceChar ~= nil and p.forceChar or CT_MARIO + + np.overrideModelIndex = p.baseChar ~= nil and p.baseChar or CT_MARIO -- Character Animations if characterAnims[p.modelId] then - local animID = characterAnims[p.modelId][m.marioObj.header.gfx.animInfo.animID] + local animInfo = m.marioObj.header.gfx.animInfo + local animID = characterAnims[p.modelId].anims and run_func_or_get_var(characterAnims[p.modelId].anims[animInfo.animID], m, animInfo.animFrame) if animID then smlua_anim_util_set_animation(m.marioObj, animID) end - end -end - -local sCapBhvs = { - [id_bhvWingCap] = true, - [id_bhvVanishCap] = true, - [id_bhvMetalCap] = true -} - ---- @param o Object ---- @param model integer -local BowserKey = false -local function on_star_or_key_grab(m, o, type) - if type == INTERACT_STAR_OR_KEY then - if get_id_from_behavior(o.behavior) == id_bhvBowserKey then - BowserKey = true - else - BowserKey = false + local eyeState = characterAnims[p.modelId].eyes and run_func_or_get_var(characterAnims[p.modelId].eyes[animInfo.animID], m, animInfo.animFrame) + if eyeState then + m.marioBodyState.eyeState = eyeState + end + local handState = characterAnims[p.modelId].hands and run_func_or_get_var(characterAnims[p.modelId].hands[animInfo.animID], m, animInfo.animFrame) + if handState then + m.marioBodyState.handState = handState end end end +function geo_function() + local viewport = geo_get_current_root() + if menuAndTransition then + djui_hud_set_resolution(RESOLUTION_N64) + viewport.x = 320*0.85 + viewport.y = 205*0.5 + viewport.width = 320*0.15 + viewport.height = 205*0.5 + else + viewport.x = 320*0.5 + viewport.y = 240*0.5 + viewport.width = 320*0.5 + viewport.height = 240*0.5 + end +end + +hook_event(HOOK_ON_GEO_PROCESS, geo_function) + +local sCapBhvs = { + [id_bhvNormalCap] = true, + [id_bhvWingCap] = true, + [id_bhvVanishCap] = true, + [id_bhvMetalCap] = true, +} + +define_custom_obj_fields({ + oOriginalModel = 'u32', + oModelHasBeenReplaced = 'u32', +}) + +---@param o Object function set_model(o, model) - if optionTable[optionTableRef.localModels].toggle == 0 then return end + -- Extended Model Incompatible + if obj_get_model_id_extended(o) == E_MODEL_ERROR_MODEL then return end + + local visualToggle = optionTable[optionTableRef.localVisuals].toggle == 1 -- Player Models if obj_has_behavior_id(o, id_bhvMario) ~= 0 then local i = network_local_index_from_global(o.globalPlayerIndex) - local prevModelData = obj_get_model_id_extended(o) local localModelData = nil - for c = 1, #characterTable do + for c = 0, #characterTable do if gCSPlayers[i].saveName == characterTable[c].saveName then if gCSPlayers[i].currAlt <= #characterTable[c] then localModelData = characterTable[c][gCSPlayers[i].currAlt].ogModel + gCSPlayers[i].modelEditOffset + break end end end @@ -797,176 +1280,216 @@ function set_model(o, model) end end return - end + elseif sCapBhvs[get_id_from_behavior(o.behavior)] then -- Cap Behaviors + local playerToObj = nearest_player_to_object(o.parentObj) + o.globalPlayerIndex = playerToObj and playerToObj.globalPlayerIndex or 0 - -- Star Models - if obj_has_behavior_id(o, id_bhvCelebrationStar) ~= 0 and o.parentObj ~= nil then - local i = network_local_index_from_global(o.parentObj.globalPlayerIndex) - local starModel = characterCelebrationStar[gCSPlayers[i].modelId] - if gCSPlayers[i].modelId ~= nil and starModel ~= nil and obj_has_model_extended(o, starModel) == 0 and not BowserKey then - obj_set_model_extended(o, starModel) + local i = network_local_index_from_global(o.globalPlayerIndex) + + local c = gMarioStates[i].character + if model == c.capModelId or + model == c.capWingModelId or + model == c.capMetalModelId or + model == c.capMetalWingModelId then + local capModels = characterCaps[gCSPlayers[i].modelId] + if capModels ~= nil then + local capModel = E_MODEL_NONE + if model == c.capModelId then + capModel = capModels.normal + elseif model == c.capWingModelId then + capModel = capModels.wing + elseif model == c.capMetalModelId then + capModel = capModels.metal + elseif model == c.capMetalWingModelId then + capModel = capModels.metalWing + end + if capModel ~= E_MODEL_NONE and capModel ~= E_MODEL_ERROR_MODEL and capModel ~= nil then + if obj_has_model_extended(o, capModel) == 0 then + obj_set_model_extended(o, capModel) + end + return + end + end + end + elseif characterTable[currChar].replaceModels ~= nil then -- Other Custom Models + local currReplace = characterTable[currChar].replaceModels[get_id_from_behavior(o.behavior)] + if o.oOriginalModel == 0 then + o.oOriginalModel = obj_get_model_id_extended(o) + end + + local model = run_func_or_get_var(currReplace, o, o.oOriginalModel) + + if model ~= nil and visualToggle then + o.oModelHasBeenReplaced = 1 + if obj_has_model_extended(o, model) == 0 then + obj_set_model_extended(o, model) + end + elseif o.oModelHasBeenReplaced ~= 0 then + if obj_has_model_extended(o, o.oOriginalModel) == 0 then + obj_set_model_extended(o, o.oOriginalModel) + end end return end +end - if sCapBhvs[get_id_from_behavior(o.behavior)] then - o.globalPlayerIndex = nearest_player_to_object(o.parentObj).globalPlayerIndex - end - local i = network_local_index_from_global(o.globalPlayerIndex) - - local c = gMarioStates[i].character - if model == c.capModelId or - model == c.capWingModelId or - model == c.capMetalModelId or - model == c.capMetalWingModelId then - local capModels = characterCaps[gCSPlayers[i].modelId] - if capModels ~= nil then - local capModel = E_MODEL_NONE - if model == c.capModelId then - capModel = capModels.normal - elseif model == c.capWingModelId then - capModel = capModels.wing - elseif model == c.capMetalModelId then - capModel = capModels.metal - elseif model == c.capMetalWingModelId then - capModel = capModels.metalWing +function set_all_models() + for i = 0, NUM_OBJ_LISTS - 1 do + local o = obj_get_first(i) + repeat + if o ~= nil then + set_model(o, o.oOriginalModel) end - if capModel ~= E_MODEL_NONE and capModel ~= E_MODEL_ERROR_MODEL and capModel ~= nil then - obj_set_model_extended(o, capModel) - end - end + o = obj_get_next(o) + until o == nil end end ---hook_event(HOOK_MARIO_UPDATE, mario_update) +local function koopa_model_update(o) + if o.oKoopaMovementType == KOOPA_BP_UNSHELLED then + o.oOriginalModel = E_MODEL_KOOPA_WITHOUT_SHELL + else + o.oOriginalModel = E_MODEL_KOOPA_WITH_SHELL + end + set_model(o) +end +hook_behavior(id_bhvKoopa, OBJ_LIST_PUSHABLE, false, nil, koopa_model_update) + cs_hook_mario_update(mario_update) -hook_event(HOOK_ON_INTERACT, on_star_or_key_grab) hook_event(HOOK_OBJECT_SET_MODEL, set_model) ------------------ -- Menu Handler -- ------------------ -local buttonAnimTimer = 0 -local buttonScroll = 0 -local buttonScrollCap = 30 +local function button_to_analog(controller, negInput, posInput) + local num = 0 + num = num - (controller.buttonDown & negInput ~= 0 and 127 or 0) + num = num + (controller.buttonDown & posInput ~= 0 and 127 or 0) + return num +end + +local TEX_CAUTION_TAPE = get_texture_info("char_select_caution_tape") +-- Renders caution tape from xy1 to xy2, tape extends based on dist (0 - 1) +local function djui_hud_render_caution_tape(x1, y1, x2, y2, dist, scale) + if not scale then scale = 0.5 end + local totalDist = math.sqrt((y2 - y1)^2 + (x2 - x1)^2) * dist + local angle = angle_from_2d_points(x1, y1, x2, y2) + djui_hud_set_rotation(angle, 0, 0.5) + local texWidth = TEX_CAUTION_TAPE.width*scale + local texHeight = TEX_CAUTION_TAPE.height*scale + local tapeSegments = totalDist/texWidth + local tapeRemainder = tapeSegments + while tapeRemainder > 1 do + tapeRemainder = tapeRemainder - 1 + end + for i = 0, math.floor(tapeSegments) do + local remainder = i == math.floor(tapeSegments) and tapeRemainder or 1 + djui_hud_render_texture_tile(TEX_CAUTION_TAPE, + x1 + texWidth*coss(angle)*i, + y1 - texWidth*sins(angle)*i, + TEX_CAUTION_TAPE.height/TEX_CAUTION_TAPE.width*scale, 1*scale, 0, 0, TEX_CAUTION_TAPE.width*remainder, TEX_CAUTION_TAPE.height) + end + djui_hud_set_rotation(0, 0, 0) +end local optionAnimTimer = -200 local optionAnimTimerCap = optionAnimTimer -local inputStallTimerButton = 0 -local inputStallTimerDirectional = 0 -local inputStallToDirectional = 12 -local inputStallToButton = 10 - --Basic Menu Text -local TEXT_OPTIONS_HEADER = "Menu Options" -local TEXT_OPTIONS_HEADER_API = "API Options" local yearsOfCS = get_date_and_time().year - 123 -- Zero years as of 2023 local TEXT_VERSION = "Version: " .. MOD_VERSION_STRING .. " | sm64coopdx" .. (seasonalEvent == SEASON_EVENT_BIRTHDAY and (" | " .. tostring(yearsOfCS) .. " year" .. (yearsOfCS > 1 and "s" or "") .. " of Character Select!") or "") local TEXT_RATIO_UNSUPPORTED = "Your Current Aspect-Ratio isn't Supported!" -local TEXT_DESCRIPTION = "Character Description:" -local TEXT_PREF_SAVE = "Preferred Char (A)" -local TEXT_PREF_PALETTE = "Toggle Palette (Y)" -local TEXT_MOVESET_INFO = "Moveset Info (Z)" local TEXT_PAUSE_Z_OPEN = "Z Button - Character Select" local TEXT_PAUSE_UNAVAILABLE = "Character Select is Unavailable" local TEXT_PAUSE_CURR_CHAR = "Current Character: " local TEXT_MOVESET_RESTRICTED = "Movesets are Restricted" local TEXT_PALETTE_RESTRICTED = "Palettes are Restricted" local TEXT_MOVESET_AND_PALETTE_RESTRICTED = "Moveset and Palettes are Restricted" -local TEXT_CHAR_LOCKED = "Locked" -- Easter Egg if you get lucky loading the mod -- Referencing the original sm64ex DynOS options by PeachyPeach >v< -if math_random(100) == 64 then +if math.random(100) == 64 then TEXT_PAUSE_Z_OPEN = "Z - DynOS" TEXT_PAUSE_CURR_CHAR = "Model: " end ---Debug Text -local TEXT_DEBUGGING = "Character Debug" -local TEXT_DESCRIPTION_SHORT = "Description:" -local TEXT_LIFE_ICON = "Life Icon:" -local TEXT_STAR_ICON = "Star Icon:" -local TEXT_FORCED_CHAR = "Forced: " -local TEXT_TABLE_POS = "Table Position: " -local TEXT_PALETTE = "Palette: " - ---Options Text -local TEXT_OPTIONS_OPEN = "Press START to open Options" -local TEXT_MENU_CLOSE = "Press B to Exit Menu" -local TEXT_OPTIONS_SELECT = "A - Select | B - Exit " -local TEXT_LOCAL_MODEL_OFF = "Locally Display Models is Off" -local TEXT_LOCAL_MODEL_OFF_OPTIONS = "You can turn it back on in the Options Menu" +--Options/Credits Text local TEXT_LOCAL_MODEL_ERROR = "Failed to find a Character Model" local TEXT_LOCAL_MODEL_ERROR_FIX = "Please Verify the Integrity of the Pack!" - ---Credit Text -local TEXT_CREDITS_HEADER = "Credits" - -local forceCharStrings = { - [CT_MARIO] = "CT_MARIO", - [CT_LUIGI] = "CT_LUIGI", - [CT_TOAD] = "CT_TOAD", - [CT_WALUIGI] = "CT_WALUIGI", - [CT_WARIO] = "CT_WARIO" -} +local TEXT_KOFI_LINK = "ko-fi.com/squishy6094" +local TEXT_CREDITS_HEADER = "CREDITS" local MATH_DIVIDE_320 = 1/320 -local MATH_DIVIDE_64 = 1/64 -local MATH_DIVIDE_32 = 1/32 -local MATH_DIVIDE_30 = 1/30 local MATH_DIVIDE_16 = 1/16 local targetMenuColor = {r = 0 , g = 0, b = 0} menuColor = targetMenuColor local menuColorHalf = menuColor +local menuColorTint = menuColor local transSpeed = 0.1 -local prevBindText = "" -local bindText = 1 -local bindTextTimerLoop = 150 -local bindTextTimer = 0 -local bindTextOpacity = -255 +local playerShirt = network_player_get_override_palette_color(gNetworkPlayers[0], SHIRT) +local playerPants = network_player_get_override_palette_color(gNetworkPlayers[0], PANTS) function update_menu_color() if optionTable[optionTableRef.menuColor].toggle == nil then return end - if optionTable[optionTableRef.localModels].toggle == 1 then - if optionTable[optionTableRef.menuColor].toggle > 1 then - targetMenuColor = menuColorTable[optionTable[optionTableRef.menuColor].toggle - 1] - elseif optionTable[optionTableRef.menuColor].toggle == 1 then - optionTable[optionTableRef.menuColor].toggleNames[2] = string_underscore_to_space(TEXT_PREF_LOAD_NAME) .. ((TEXT_PREF_LOAD_ALT ~= 1 and currChar ~= 1) and " ("..TEXT_PREF_LOAD_ALT..")" or "") .. " (Pref)" - targetMenuColor = prefCharColor - elseif characterTable[currChar] ~= nil then - local char = characterTable[currChar] - targetMenuColor = char[char.currAlt].color - end - else - targetMenuColor = menuColorTable[9] - end - if optionTable[optionTableRef.anims].toggle > 0 then - menuColor.r = lerp(menuColor.r, targetMenuColor.r, transSpeed) - menuColor.g = lerp(menuColor.g, targetMenuColor.g, transSpeed) - menuColor.b = lerp(menuColor.b, targetMenuColor.b, transSpeed) - else - menuColor.r = targetMenuColor.r - menuColor.g = targetMenuColor.g - menuColor.b = targetMenuColor.b + if optionTable[optionTableRef.menuColor].toggle > 1 then + targetMenuColor = menuColorTable[optionTable[optionTableRef.menuColor].toggle - 1] + elseif optionTable[optionTableRef.menuColor].toggle == 1 then + optionTable[optionTableRef.menuColor].toggleNames[2] = TEXT_PREF_LOAD_NAME .. ((TEXT_PREF_LOAD_ALT ~= 1 and currChar ~= 1) and " ("..TEXT_PREF_LOAD_ALT..")" or "") .. " (Pref)" + targetMenuColor = prefCharColor + elseif characterTable[currChar] ~= nil then + local char = characterTable[currChar] + targetMenuColor = char[char.currAlt].color end + menuColor.r = math.lerp(menuColor.r, targetMenuColor.r, transSpeed) + menuColor.g = math.lerp(menuColor.g, targetMenuColor.g, transSpeed) + menuColor.b = math.lerp(menuColor.b, targetMenuColor.b, transSpeed) menuColorHalf = { r = menuColor.r * 0.5 + 127, g = menuColor.g * 0.5 + 127, b = menuColor.b * 0.5 + 127 } + menuColorTint = { + r = 205 + 50*menuColor.r/256, + g = 205 + 50*menuColor.g/256, + b = 205 + 50*menuColor.b/256 + } + + -- Update BG Wall Color + local shirtColor = network_player_get_override_palette_color(gNetworkPlayers[0], SHIRT) + local pantsColor = network_player_get_override_palette_color(gNetworkPlayers[0], PANTS) + playerShirt.r = math.lerp(playerShirt.r, shirtColor.r, transSpeed) + playerShirt.g = math.lerp(playerShirt.g, shirtColor.g, transSpeed) + playerShirt.b = math.lerp(playerShirt.b, shirtColor.b, transSpeed) + playerPants.r = math.lerp(playerPants.r, pantsColor.r, transSpeed) + playerPants.g = math.lerp(playerPants.g, pantsColor.g, transSpeed) + playerPants.b = math.lerp(playerPants.b, pantsColor.b, transSpeed) return menuColor end -local TEX_TRIANGLE = get_texture_info("char-select-triangle") -local function djui_hud_render_triangle(x, y, width, height) - djui_hud_render_texture(TEX_TRIANGLE, x, y, width*MATH_DIVIDE_64, height*MATH_DIVIDE_32) +local function djui_hud_render_life_icon(char, x, y, scale) + local icon = char and char.lifeIcon or "?" + local color = char and char.color or {r = 255, g = 255, b = 255} + local djuiColor = djui_hud_get_color() + if type(icon) == TYPE_STRING then + local font = djui_hud_get_font() + djui_hud_set_font(FONT_RECOLOR_HUD) + djui_hud_set_color(color.r * djuiColor.r/255, color.g * djuiColor.g/255, color.b * djuiColor.b/255, djuiColor.a) + djui_hud_print_text(icon, x, y, scale) + djui_hud_set_font(font) + else + djui_hud_set_color(djuiColor.r, djuiColor.g, djuiColor.b, djuiColor.a) + djui_hud_render_texture(icon, x, y, scale / (icon.width * MATH_DIVIDE_16), scale / (icon.height * MATH_DIVIDE_16)) + end + djui_hud_set_color(djuiColor.r, djuiColor.g, djuiColor.b, djuiColor.a) end -local buttonAltAnim = 0 -local menuOpacity = 245 -local menuText = {} +local gridButtonsPerRow = 5 +local paletteXOffset = 0 +local gearRotationTarget = 0 +local gearRotation = 0 +local paletteTrans = 0 +local optionsMenuOffset = 0 +local optionsMenuOffsetMax = 210 local function on_hud_render() local FONT_USER = djui_menu_get_font() djui_hud_set_font(FONT_ALIASED) @@ -974,577 +1497,476 @@ local function on_hud_render() local djuiWidth = djui_hud_get_screen_width() local djuiHeight = djui_hud_get_screen_height() djui_hud_set_resolution(RESOLUTION_N64) - local width = djuiWidth * (240/djuiHeight) -- Get accurate, unrounded width + local width = math.max(djuiWidth * (240/djuiHeight), 320) -- Get accurate, unrounded width local height = 240 - local widthHalf = width * 0.5 - local heightHalf = height * 0.5 - local widthScale = maxf(width, 320) * MATH_DIVIDE_320 + local widthScale = math.max(width, 320) * MATH_DIVIDE_320 - update_menu_color() + if startup_init_stall() then + update_menu_color() + if not menu_is_allowed() then + menu = false + end + end if menuAndTransition then - - if optionTable[optionTableRef.localModels].toggle == 0 then + if characterTable[currChar][characterTable[currChar].currAlt].model == E_MODEL_ERROR_MODEL then djui_hud_set_color(0, 0, 0, 200) djui_hud_render_rect(0, 0, width, height) djui_hud_set_color(255, 255, 255, 255) - djui_hud_print_text(TEXT_LOCAL_MODEL_OFF, widthHalf - djui_hud_measure_text(TEXT_LOCAL_MODEL_OFF) * 0.15 * widthScale, heightHalf, 0.3 * widthScale) - djui_hud_print_text(TEXT_LOCAL_MODEL_OFF_OPTIONS, widthHalf - djui_hud_measure_text(TEXT_LOCAL_MODEL_OFF_OPTIONS) * 0.1 * widthScale, heightHalf + 10 * widthScale, 0.2 * widthScale) + djui_hud_print_text(TEXT_LOCAL_MODEL_ERROR, width*0.85 - djui_hud_measure_text(TEXT_LOCAL_MODEL_ERROR) * 0.15 * widthScale, height * 0.5, 0.3 * widthScale) + djui_hud_print_text(TEXT_LOCAL_MODEL_ERROR_FIX, width*0.85 - djui_hud_measure_text(TEXT_LOCAL_MODEL_ERROR_FIX) * 0.1 * widthScale, height * 0.5 + 10 * widthScale, 0.2 * widthScale) end - if characterTable[currChar][characterTable[currChar].currAlt].model == E_MODEL_ARMATURE then - djui_hud_set_color(0, 0, 0, 200) - djui_hud_render_rect(0, 0, width, height) - djui_hud_set_color(255, 255, 255, 255) - djui_hud_print_text(TEXT_LOCAL_MODEL_ERROR, widthHalf - djui_hud_measure_text(TEXT_LOCAL_MODEL_ERROR) * 0.15 * widthScale, heightHalf, 0.3 * widthScale) - djui_hud_print_text(TEXT_LOCAL_MODEL_ERROR_FIX, widthHalf - djui_hud_measure_text(TEXT_LOCAL_MODEL_ERROR_FIX) * 0.1 * widthScale, heightHalf + 10 * widthScale, 0.2 * widthScale) - end - - local x = 135 * widthScale * 0.8 - - -- Render All Black Squares Behind Below API - djui_hud_set_color(menuColorHalf.r * 0.1, menuColorHalf.g * 0.1, menuColorHalf.b * 0.1, menuOpacity) - -- Description - djui_hud_render_rect(width - x + 2, 2 + 46, x - 4, height - 4 - 46) - -- Buttons - djui_hud_render_rect(2, 2 + 46, x - 4, height - 4 - 46) - -- Header - djui_hud_render_rect(2, 2, width - 4, 46) - - -- API Rendering (Below Text) - if #renderInMenuTable.back > 0 then - for i = 1, #renderInMenuTable.back do - renderInMenuTable.back[i]() - end - end - - --Character Description - djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) - djui_hud_render_rect(width - x, 50, 2, height - 50) - djui_hud_render_rect(width - x, height - 2, x, 2) - djui_hud_render_rect(width - 2, 50, 2, height - 50) - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - djui_hud_set_font(FONT_ALIASED) - local character = characterTable[currChar] - local TEXT_SAVE_NAME = "Save Name: " .. character.saveName - local TEXT_MOVESET = "Has Moveset: "..(character.hasMoveset and "Yes" or "No") - local TEXT_ALT = "Alt: " .. character.currAlt .. "/" .. #character - character = characterTable[currChar][character.currAlt] - local paletteCount = characterColorPresets[gCSPlayers[0].modelId] ~= nil and #characterColorPresets[gCSPlayers[0].modelId] or 0 - local currPaletteTable = characterColorPresets[gCSPlayers[0].modelId] and characterColorPresets[gCSPlayers[0].modelId] or {currPalette = 0} - if optionTable[optionTableRef.debugInfo].toggle == 0 then - -- Actual Description -- - local TEXT_NAME = string_underscore_to_space(character.name) - local TEXT_CREDIT = "Credit: " .. character.credit - local TEXT_DESCRIPTION_TABLE = character.description - local TEXT_PREF_LOAD_NAME = string_underscore_to_space(TEXT_PREF_LOAD_NAME) .. ((TEXT_PREF_LOAD_ALT ~= 1 and TEXT_PREF_LOAD_NAME ~= "Default" and currChar ~= 1) and " ("..TEXT_PREF_LOAD_ALT..")" or "") - - local textX = x * 0.5 - djui_hud_print_text(TEXT_NAME, width - textX - djui_hud_measure_text(TEXT_NAME) * 0.3, 55, 0.6) - djui_hud_set_font(FONT_TINY) - local creditScale = 0.6 - creditScale = math_min(creditScale, 100/djui_hud_measure_text(TEXT_CREDIT)) - djui_hud_print_text(TEXT_CREDIT, width - textX - djui_hud_measure_text(TEXT_CREDIT) * creditScale *0.5, 74, creditScale) - djui_hud_set_font(FONT_ALIASED) - djui_hud_print_text(TEXT_DESCRIPTION, width - textX - djui_hud_measure_text(TEXT_DESCRIPTION) * 0.2, 85, 0.4) - if widthScale < 1.65 then - for i = 1, #TEXT_DESCRIPTION_TABLE do - djui_hud_print_text(TEXT_DESCRIPTION_TABLE[i], width - textX - djui_hud_measure_text(TEXT_DESCRIPTION_TABLE[i]) * 0.15, 90 + i * 9, 0.3) - end - else - for i = 1, math_ceil(#TEXT_DESCRIPTION_TABLE*0.5) do - local tablePos = (i * 2) - 1 - if TEXT_DESCRIPTION_TABLE[tablePos] and TEXT_DESCRIPTION_TABLE[tablePos + 1] then - local TEXT_STRING = TEXT_DESCRIPTION_TABLE[tablePos] .. " " .. TEXT_DESCRIPTION_TABLE[tablePos + 1] - djui_hud_print_text(TEXT_STRING, width - textX - djui_hud_measure_text(TEXT_STRING) * 0.15, 90 + i * 9, 0.3) - elseif TEXT_DESCRIPTION_TABLE[tablePos] then - local TEXT_STRING = TEXT_DESCRIPTION_TABLE[tablePos] - djui_hud_print_text(TEXT_STRING, width - textX - djui_hud_measure_text(TEXT_STRING) * 0.15, 90 + i * 9, 0.3) - end - end - end - - menuText = { - TEXT_PREF_SAVE .. " - " .. TEXT_PREF_LOAD_NAME - } - local modelId = gCSPlayers[0].modelId - local TEXT_PRESET_TOGGLE = ((currPaletteTable[currPaletteTable.currPalette] ~= nil and currPaletteTable[currPaletteTable.currPalette].name ~= nil) and (currPaletteTable[currPaletteTable.currPalette].name .. " - ") or "") .. ((paletteCount > 1 and "("..currPaletteTable.currPalette.."/"..paletteCount..")" or (currPaletteTable.currPalette > 0 and "On" or "Off")) or "Off") - if characterColorPresets[modelId] and not stopPalettes then - table_insert(menuText, TEXT_PREF_PALETTE .. " - " .. TEXT_PRESET_TOGGLE) - elseif stopPalettes then - table_insert(menuText, TEXT_PALETTE_RESTRICTED) - end - if #menuText > 1 then - bindTextTimer = (bindTextTimer + 1)%(bindTextTimerLoop) - end - if bindTextTimer == 0 then - bindText = bindText + 1 - bindTextOpacity = -254 - end - if bindText > #menuText or not menuText[bindText] then - bindText = 1 - end - if menuText[bindText] ~= prevBindText and bindTextOpacity == -255 then - bindTextOpacity = -254 - end - if bindTextOpacity > -255 and bindTextOpacity < 255 then - bindTextOpacity = math.min(bindTextOpacity + 25, 255) - if bindTextOpacity == 255 then - bindTextOpacity = -255 - prevBindText = menuText[bindText] - end - end - --local bindTextOpacity = clamp(math.abs(math.sin(bindTextTimer*MATH_PI/bindTextTimerLoop)), 0, 0.2) * 5 * 255 - local fadeOut = math_abs(clamp(bindTextOpacity, -255, 0)) - local fadeIn = math_abs(clamp(bindTextOpacity, 0, 255)) - local bindTextScale = math.min((x - 10)/(djui_hud_measure_text(menuText[bindText]) * 0.3), 1)*0.3 - local prevBindTextScale = math.min((x - 10)/(djui_hud_measure_text(prevBindText) * 0.3), 1)*0.3 - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, fadeOut) - djui_hud_print_text(prevBindText, width - textX - djui_hud_measure_text(prevBindText) * prevBindTextScale*0.5, height - 15, prevBindTextScale) - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, fadeIn) - djui_hud_print_text(menuText[bindText], width - textX - djui_hud_measure_text(menuText[bindText]) * bindTextScale*0.5, height - 15, bindTextScale) - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - else - -- Debugging Info -- - local TEXT_NAME = "Name: " .. character.name - local TEXT_CREDIT = "Credit: " .. character.credit - local TEXT_DESCRIPTION_TABLE = character.description - local TEXT_COLOR = "Color: R-" .. character.color.r ..", G-" ..character.color.g ..", B-"..character.color.b - local TEX_LIFE_ICON = character.lifeIcon - local TEX_STAR_ICON = character.starIcon - local TEXT_SCALE = "Camera Scale: " .. character.camScale - local TEXT_PRESET = "Preset Palette: ("..currPaletteTable.currPalette.."/"..paletteCount..")" - local TEXT_PREF = "Preferred: " .. TEXT_PREF_LOAD_NAME .. " ("..TEXT_PREF_LOAD_ALT..")" - local TEXT_PREF_COLOR = "Pref Color: R-" .. prefCharColor.r .. ", G-" .. prefCharColor.g .. ", B-" .. prefCharColor.b - - local textX = x * 0.5 - djui_hud_print_text(TEXT_DEBUGGING, width - textX - djui_hud_measure_text(TEXT_DEBUGGING) * 0.3, 55, 0.6) - djui_hud_set_font(FONT_TINY) - local y = 72 - djui_hud_print_text(TEXT_NAME, width - x + 8, y, 0.5) - y = y + 7 - djui_hud_print_text(TEXT_SAVE_NAME, width - x + 8, y, 0.5) - y = y + 7 - djui_hud_print_text(TEXT_ALT, width - x + 8, y, 0.5) - y = y + 7 - djui_hud_print_text(TEXT_CREDIT, width - x + 8, y, 0.5) - y = y + 7 - if TEXT_DESCRIPTION_TABLE[1] ~= "No description has been provided" then - djui_hud_print_text(TEXT_DESCRIPTION_SHORT, width - x + 8, y, 0.5) - y = y + 2 - local removeLine = 0 - for i = 1, #TEXT_DESCRIPTION_TABLE do - if TEXT_DESCRIPTION_TABLE[i] ~= "" then - djui_hud_set_font(FONT_ALIASED) - local TEXT_DESCRIPTION_LINE = TEXT_DESCRIPTION_TABLE[i] - if (djui_hud_measure_text(TEXT_DESCRIPTION_TABLE[i]) * 0.3 > 100) then - TEXT_DESCRIPTION_LINE = "(!) " .. TEXT_DESCRIPTION_LINE - else - TEXT_DESCRIPTION_LINE = " " .. TEXT_DESCRIPTION_LINE - end - djui_hud_set_font(FONT_TINY) - djui_hud_print_text(TEXT_DESCRIPTION_LINE, width - x + 5, y + (i-removeLine) * 5, 0.4) - else - removeLine = removeLine + 1 - end - end - local descriptionOffset = (#TEXT_DESCRIPTION_TABLE - removeLine) * 5 - y = y + 5 + descriptionOffset - end - djui_hud_set_color(character.color.r, character.color.g, character.color.b, 255) - djui_hud_print_text(TEXT_COLOR, width - x + 8, y, 0.5) - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - y = y + 7 - if type(TEX_LIFE_ICON) ~= TYPE_STRING then - djui_hud_print_text(TEXT_LIFE_ICON .. " (" .. TEX_LIFE_ICON.width .. "x" .. TEX_LIFE_ICON.height .. ")", width - x + 8, y, 0.5) - djui_hud_set_color(255, 255, 255, 255) - djui_hud_render_texture(TEX_LIFE_ICON, width - x + 33, y + 1, 0.4 / (TEX_LIFE_ICON.width * MATH_DIVIDE_16), 0.4 / (TEX_LIFE_ICON.height * MATH_DIVIDE_16)) - else - djui_hud_print_text(TEXT_LIFE_ICON .. " (FONT_HUD)", width - x + 8, y, 0.5) - djui_hud_set_font(FONT_HUD) - djui_hud_set_color(255, 255, 255, 255) - djui_hud_print_text(TEX_LIFE_ICON, width - x + 33, y + 1, 0.4) - djui_hud_set_font(FONT_TINY) - end - y = y + 7 - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - djui_hud_print_text(TEXT_STAR_ICON .. " (" .. TEX_STAR_ICON.width .. "x" .. TEX_STAR_ICON.height .. ")", width - x + 8, y, 0.5) - djui_hud_set_color(255, 255, 255, 255) - djui_hud_render_texture(TEX_STAR_ICON, width - x + 35, y + 1, 0.4 / (TEX_STAR_ICON.width * MATH_DIVIDE_16), 0.4 / (TEX_STAR_ICON.height * MATH_DIVIDE_16)) - y = y + 7 - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - djui_hud_print_text(TEXT_FORCED_CHAR .. forceCharStrings[character.forceChar], width - x + 8, y, 0.5) - y = y + 7 - djui_hud_print_text(TEXT_TABLE_POS .. currChar, width - x + 8, y, 0.5) - y = y + 7 - djui_hud_print_text(TEXT_SCALE, width - x + 8, y, 0.5) - local modelId = gCSPlayers[0].modelId - y = y + 7 - if characterColorPresets[modelId] ~= nil then - djui_hud_print_text(TEXT_PALETTE, width - x + 8, y, 0.5) - local x = x - djui_hud_measure_text(TEXT_PALETTE)*0.5 - local currPalette = currPaletteTable.currPalette > 0 and currPaletteTable.currPalette or 1 - local paletteTable = currPaletteTable[currPalette] - for i = 0, #paletteTable do - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - djui_hud_render_rect(width - x + 6.5 + (6.5 * i), y + 1.5, 6, 6) - djui_hud_set_color(paletteTable[i].r, paletteTable[i].g, paletteTable[i].b, 255) - djui_hud_render_rect(width - x + 7 + (6.5 * i), y + 2, 5, 5) - end - y = y + 7 - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - end - djui_hud_print_text(TEXT_MOVESET, width - x + 8, y, 0.5) - y = y + 7 - djui_hud_print_text(TEXT_PRESET, width - x + 8, height - 29, 0.5) - djui_hud_print_text(TEXT_PREF, width - x + 8, height - 22, 0.5) - djui_hud_set_color(prefCharColor.r, prefCharColor.g, prefCharColor.b, 255) - djui_hud_print_text(TEXT_PREF_COLOR, width - x + 8, height - 15, 0.5) - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - end - - --Character Buttons - djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) - djui_hud_render_rect(0, 50, 2, height - 50) - djui_hud_render_rect(x - 2, 50, 2, height - 50) - djui_hud_render_rect(0, height - 2, x, 2) - - local leftRightAnim = 0 - if optionTable[optionTableRef.anims].toggle > 0 then - buttonAnimTimer = buttonAnimTimer + 1 - leftRightAnim = buttonAltAnim/inputStallToDirectional - if buttonAltAnim ~= 0 then - if buttonAltAnim > 0 then - buttonAltAnim = buttonAltAnim - 3 - else - buttonAltAnim = buttonAltAnim + 3 - end - end - end - if optionTable[optionTableRef.anims].toggle == 0 then - buttonScroll = 0 - elseif math_abs(buttonScroll) > 0.1 then - buttonScroll = buttonScroll * 0.05 * inputStallToDirectional - end - - local buttonColor = {} - local buttonX = 20 * widthScale - local buttonAnimX = buttonX + math_sin(buttonAnimTimer * 0.05) * 2.5 + 5 - local charNum = -1 - for i = -1, 4 do - -- Hide Locked Characters based on Toggle - charNum = currCharRender + i - local char = characterTableRender[charNum] - if char ~= nil then - if not char.locked then - buttonColor = char[char.currAlt].color - else - buttonColor = {r = char[char.currAlt].color.r*0.5, g = char[char.currAlt].color.g*0.5, b = char[char.currAlt].color.b*0.5} - end - djui_hud_set_color(buttonColor.r, buttonColor.g, buttonColor.b, 255) - local x = buttonX - local y = 104 + buttonScroll - if i == 0 then - if optionTable[optionTableRef.anims].toggle > 0 then - x = buttonAnimX - else - x = buttonX + 5 - end - if #char > 1 then - djui_hud_set_rotation(0x4000, 0, 0) - djui_hud_render_triangle(x - 6 + math_min(leftRightAnim, 0), y, 8, 4) - djui_hud_set_rotation(-0x4000, 0, 0) - djui_hud_render_triangle(x + 76 + math_max(leftRightAnim, 0), y - 8 - 1*MATH_DIVIDE_16, 8, 4) - djui_hud_set_rotation(0, 0, 0) - end - end - local y = (i + 3) * 30 + buttonScroll - djui_hud_render_rect(x, y, 1, 20) - djui_hud_render_rect(x, y, 70, 1) - djui_hud_render_rect(x + 69, y, 1, 20) - djui_hud_render_rect(x, y + 19, 70, 1) - djui_hud_set_color(buttonColor.r * 0.1, buttonColor.g * 0.1, buttonColor.b * 0.1, menuOpacity) - djui_hud_render_rect(x + 1, y + 1, 68, 18) - djui_hud_set_font(FONT_TINY) - djui_hud_set_color(buttonColor.r, buttonColor.g, buttonColor.b, 255) - local charName = char[char.currAlt].name - if char.locked then - charName = TEXT_CHAR_LOCKED - end - djui_hud_set_color(buttonColor.r * 0.5 + 127, buttonColor.g * 0.5 + 127, buttonColor.b * 0.5 + 127, 255) - djui_hud_print_text(charName, x + 5, y + 5, 0.6) - end - end - - -- Scroll Bar - local MATH_DIVIDE_CHARACTERS = 1/#characterTableRender - local MATH_7_WIDTHSCALE = 7 * widthScale - djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) - djui_hud_render_rect(MATH_7_WIDTHSCALE, 55, 1, 170) - djui_hud_render_rect(MATH_7_WIDTHSCALE, 55, 7, 1) - djui_hud_render_rect(MATH_7_WIDTHSCALE + 6, 55, 1, 170) - djui_hud_render_rect(MATH_7_WIDTHSCALE, 224, 7, 1) - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - djui_hud_render_rect(MATH_7_WIDTHSCALE + 2, 57 + 166 * ((currCharRender - 1) * MATH_DIVIDE_CHARACTERS) - (buttonScroll * MATH_DIVIDE_30) * (166 * MATH_DIVIDE_CHARACTERS), 3, 166 * MATH_DIVIDE_CHARACTERS) - djui_hud_set_font(FONT_TINY) - local TEXT_CHAR_COUNT = currCharRender .. "/" .. #characterTableRender - djui_hud_print_text(TEXT_CHAR_COUNT, (11 - djui_hud_measure_text(TEXT_CHAR_COUNT) * 0.2) * widthScale, height - 12, 0.4) - djui_hud_print_text("- "..characterCategories[currCategory] .. " (L/R)", (11 + djui_hud_measure_text(TEXT_CHAR_COUNT) * 0.2) * widthScale, height - 12, 0.4) - - --Character Select Header - djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) - djui_hud_render_rect(0, 0, width, 2) - djui_hud_render_rect(0, 0, 2, 50) - djui_hud_render_rect(0, 48, width, 2) - djui_hud_render_rect(width - 2, 0, 2, 50) - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - if TEX_OVERRIDE_HEADER ~= nil then -- Render Override Header - djui_hud_render_texture(TEX_OVERRIDE_HEADER, widthHalf - 128, 10, 1 / (TEX_OVERRIDE_HEADER.height*MATH_DIVIDE_32), 1 / (TEX_OVERRIDE_HEADER.height*MATH_DIVIDE_32)) - else - djui_hud_render_texture(TEX_HEADER, widthHalf - 128, 10, 1, 1) - end - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - djui_hud_set_font(FONT_TINY) - djui_hud_print_text(optionTable[optionTableRef.debugInfo].toggle == 0 and TEXT_VERSION or MOD_VERSION_DEBUG, 5, 3, 0.5) + optionsMenuOffset = lerp(optionsMenuOffset, options and optionsMenuOffsetMax or 0, 0.1) --Unsupported Res Warning if width < 319 or width > 575 then djui_hud_print_text(TEXT_RATIO_UNSUPPORTED, 5, 39, 0.5) end - -- API Rendering (Above Text) - djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) - if #renderInMenuTable.front > 0 then - for i = 1, #renderInMenuTable.front do - renderInMenuTable.front[i]() - end - end djui_hud_set_resolution(RESOLUTION_N64) - --Options display - local optionTableCount = #optionTable - if options or optionAnimTimer > optionAnimTimerCap then - djui_hud_set_color(menuColor.r * 0.25, menuColor.g * 0.25, menuColor.b * 0.25, 205 + maxf(-200, optionAnimTimer)) - djui_hud_render_rect(0, 0, width, height) - djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) - djui_hud_render_rect(width * 0.5 - 50 * widthScale, minf(55 - optionAnimTimer, height - 25 * widthScale), 100 * widthScale, 200) - djui_hud_set_color(menuColor.r * 0.1, menuColor.g * 0.1, menuColor.b * 0.1, menuOpacity) - djui_hud_render_rect(width * 0.5 - 50 * widthScale + 2, minf(55 - optionAnimTimer + 2, height - 25 * widthScale + 2), 100 * widthScale - 4, 196) - djui_hud_set_font(FONT_ALIASED) - - if not creditsAndTransition then - local widthScaleLimited = minf(widthScale, 1.5) - -- Up Arrow - if currOption > 3 then - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - djui_hud_render_triangle(widthHalf - 3.5*widthScaleLimited, 94 - optionAnimTimer, 6*widthScaleLimited, 3*widthScaleLimited) - end - - -- Down Arrow - if currOption < optionTableCount - 2 then - local yOffset = 90 - optionAnimTimer + 45 * widthScaleLimited - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - djui_hud_set_rotation(0x8000, 0.5, 0.5) - djui_hud_render_triangle(widthHalf - 3.5*widthScaleLimited, yOffset + 10 + 3*widthScaleLimited, 6*widthScaleLimited, 3*widthScaleLimited) - djui_hud_set_rotation(0, 0, 0) - end - - -- Options - for i = currOption - 2, currOption + 2 do - if not (i < 1 or i > optionTableCount) then - local toggleName = optionTable[i].name - local scale = 0.5 - local yOffset = 100 - optionAnimTimer + (i - currOption + 2) * 9 * widthScaleLimited - if i == currOption then - djui_hud_set_font(FONT_ALIASED) - scale = 0.3 - yOffset = yOffset - 1 - local currToggleName = optionTable[i].toggleNames[optionTable[i].toggle + 1] - currToggleName = currToggleName and currToggleName or "???" - if currToggleName ~= "" then - toggleName = toggleName .. " - " .. currToggleName - else - toggleName = toggleName - end - else - djui_hud_set_font(FONT_TINY) - end - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - scale = scale * widthScaleLimited - djui_hud_print_text(toggleName, widthHalf - djui_hud_measure_text(toggleName) * scale * 0.5, yOffset, scale) - end - end - - -- Description - if optionTable[currOption].description ~= nil then - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - for i = 1, #optionTable[currOption].description do - djui_hud_set_font(FONT_ALIASED) - local line = optionTable[currOption].description[i] - djui_hud_print_text(line, widthHalf - djui_hud_measure_text(line) * 0.15, 180 - optionAnimTimer + 15 * widthScaleLimited + 8 * i - 8 * #optionTable[currOption].description, 0.3) - end - end - -- Footer - djui_hud_set_font(FONT_TINY) - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - djui_hud_print_text(TEXT_OPTIONS_SELECT, widthHalf - djui_hud_measure_text(TEXT_OPTIONS_SELECT) * 0.3, height - 20 - optionAnimTimer, 0.6) - else - local renderList = {} - for i = 1, #creditTable do - local credit = creditTable[i] - table_insert(renderList, {textLeft = credit.packName, font = FONT_ALIASED}) - for i = 1, #credit do - local credit = credit[i] - table_insert(renderList, {textLeft = credit.creditTo, textRight = credit.creditFor, font = FONT_NORMAL}) - end - end - - local xLeft = widthHalf - 50 * widthScale + 8 - local xRight = widthHalf + 50 * widthScale - 8 - local y = 80 + 10*widthScale - optionAnimTimer - creditScroll - local prevY = 80 + 10*widthScale - optionAnimTimer - prevCreditScroll - for i = 1, #renderList do - local credit = renderList[i] - local header = (credit.font == FONT_ALIASED) - if y > 62 and y < height then - djui_hud_set_font(credit.font) - if not header then - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - else - djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) - end - local x = xLeft - (header and 3 or 0) - local scale = (header and 0.3 or 0.2)*widthScale - djui_hud_print_text_interpolated(credit.textLeft, x, prevY, scale, x, y, scale) - if credit.textRight then - local x = xRight - djui_hud_measure_text(credit.textRight)*scale - local scale = 0.2*widthScale - djui_hud_print_text_interpolated(credit.textRight, x, prevY, scale, x, y, scale) - end - end - y = y + (header and 9 or 6)*widthScale - prevY = prevY + (header and 9 or 6)*widthScale - if renderList[i + 1] ~= nil and renderList[i + 1].font == FONT_ALIASED then - y = y + 2 - prevY = prevY + 2 - end - end - creditScrollRange = math_max(((y + creditScroll)) - (height - 36), 0) - prevCreditScroll = creditScroll - - for i = 1, 8 do - djui_hud_set_color(menuColor.r * 0.1, menuColor.g * 0.1, menuColor.b * 0.1, 100) - djui_hud_render_rect(widthHalf - 50 * widthScale + 2, 60 - optionAnimTimer, 100 * widthScale - 4, i*4) - djui_hud_render_rect(widthHalf - 50 * widthScale + 2, height - 2 - i*4, 96 * widthScale, i*4) - end - end - - -- Render Header - djui_hud_set_font(FONT_ALIASED) - djui_hud_set_color(menuColor.r * 0.5 + 127, menuColor.g * 0.5 + 127, menuColor.b * 0.5 + 127, 255) - local text = TEXT_OPTIONS_HEADER - if creditsAndTransition then - text = TEXT_CREDITS_HEADER - elseif currOption > defaultOptionCount then - text = TEXT_OPTIONS_HEADER_API - end - djui_hud_print_text(text, widthHalf - djui_hud_measure_text(text) * 0.3 * minf(widthScale, 1.5), 65 + optionAnimTimer * -1, 0.6 * minf(widthScale, 1.5)) - - -- Fade in/out of credits - if optionTable[optionTableRef.anims].toggle == 1 then - if credits and creditsCrossFade > -creditsCrossFadeCap then - creditsCrossFade = creditsCrossFade - 1 - if creditsCrossFade == 0 then creditsCrossFade = creditsCrossFade - 1 end - end - if not credits and creditsCrossFade < creditsCrossFadeCap then - creditsCrossFade = creditsCrossFade + 1 - if creditsCrossFade == 0 then creditsCrossFade = creditsCrossFade + 1 end - end - if creditsCrossFade < 0 then - creditsAndTransition = true - else - creditsAndTransition = false - end - else - if credits then - creditsCrossFade = -creditsCrossFadeCap - else - creditsCrossFade = creditsCrossFadeCap - end - creditsAndTransition = credits - end - - djui_hud_set_resolution(RESOLUTION_N64) - djui_hud_set_color(0, 0, 0, (math_abs(creditsCrossFade)) * -creditsCrossFadeMath) - djui_hud_render_rect(width * 0.5 - 50 * widthScale + 2, minf(55 - optionAnimTimer + 2, height - 25 * widthScale + 2), 100 * widthScale - 4, 196) - else - -- How to open options display - local widthScaleLimited = minf(widthScale, 1.42) - djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) - djui_hud_render_rect(widthHalf - 50 * widthScale, height - 25 * widthScaleLimited, 100 * widthScale, 26 * widthScaleLimited) - djui_hud_set_color(menuColorHalf.r * 0.1, menuColorHalf.g * 0.1, menuColorHalf.b * 0.1, menuOpacity) - djui_hud_render_rect(widthHalf - 50 * widthScale + 2, height - 25 * widthScaleLimited + 2, 100 * widthScale - 4, 22 * widthScaleLimited) - djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) - djui_hud_render_rect(widthHalf - 50 * widthScale, height - 2, 100 * widthScale, 2) - djui_hud_set_font(FONT_ALIASED) - djui_hud_print_text(TEXT_OPTIONS_OPEN, widthHalf - djui_hud_measure_text(TEXT_OPTIONS_OPEN) * 0.175 * widthScaleLimited, height - 23 * widthScaleLimited + optionAnimTimer + 202, 0.35 * widthScaleLimited) - djui_hud_set_font(FONT_TINY) - djui_hud_print_text(TEXT_MENU_CLOSE, widthHalf - djui_hud_measure_text(TEXT_MENU_CLOSE) * 0.25 * widthScaleLimited, height - 13 * widthScaleLimited + optionAnimTimer + 202, 0.5 * widthScaleLimited) - end djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) djui_hud_render_rect(width * 0.5 - 50 * widthScale, height - 2, 100 * widthScale, 2) + -- Render Character Name + local angle1 = angle_from_2d_points(width*0.7, 8, width*1.1, 30) + local angle2 = angle_from_2d_points(width*0.7, 40, width*1.1, 35) + djui_hud_set_color(menuColor.r*0.1, menuColor.g*0.1, menuColor.b*0.1, 200) + djui_hud_set_rotation(angle1, 0, 1) + djui_hud_render_rect(width*0.7, -50, width*0.4, 59) + djui_hud_set_rotation(angle2, 0, 1) + djui_hud_render_rect(width*0.7, -50, width*0.4, 96) + djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) + djui_hud_set_rotation(angle1, 0, 1) + djui_hud_render_caution_tape(width*0.7, 8, width*1.1, 30, 1) + djui_hud_set_rotation(angle2, 0, 1) + djui_hud_render_caution_tape(width*0.7, 40, width*1.1, 35, 1) + + djui_hud_set_font(FONT_CHARACTERISTIC) + local charName = string.upper(characterTable[currChar][characterTable[currChar].currAlt].name) + local nameScale = math.min(width*0.23/djui_hud_measure_text(charName), 1) + local charCreator = string.upper(characterTable[currChar][characterTable[currChar].currAlt].credit) + local creatorScale = math.min(width*0.23/djui_hud_measure_text(charCreator), 0.4) + djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) + djui_hud_print_text_auto_interpolated("topName", charName, width*0.85 - djui_hud_measure_text(charName)*0.5*nameScale - 2 + menuOffsetX*0.3, 21 - 16*nameScale + menuOffsetY*0.3, nameScale) + djui_hud_print_text_auto_interpolated("topCreator", charCreator, width*0.85 - djui_hud_measure_text(charCreator)*0.5*creatorScale - 2 + menuOffsetX*0.2, 42 - 16*creatorScale + menuOffsetY*0.2, creatorScale) + + -- Palette Selection + local charColor = characterTableRender[currCharRender][characterTableRender[currCharRender].currAlt].color + local palettes = characterColorPresets[characterTableRender[currCharRender][characterTableRender[currCharRender].currAlt].model] + if palettes then + local bucketSpacing = 24 + paletteXOffset = lerp(paletteXOffset, palettes.currPalette*bucketSpacing, 0.1) + paletteTrans = math.max(paletteTrans - 6, 0) + local bottomTapeAngle = angle_from_2d_points(-10, height - 50, width + 10, height - 35) + + for i = 0, #palettes do + local x = width*0.85 - 16 - paletteXOffset + coss(bottomTapeAngle)*bucketSpacing*i + local y = height*0.72 - math.abs(math.cos((get_global_timer() - i*10)*0.05))*3 - sins(bottomTapeAngle)*bucketSpacing*(i - paletteXOffset/bucketSpacing) + local paletteShirt = nil + local palettePants = nil + if i == 0 then + paletteShirt = network_player_get_palette_color(gNetworkPlayers[0], SHIRT) + palettePants = network_player_get_palette_color(gNetworkPlayers[0], PANTS) + paletteName = "Custom" + else + paletteShirt = palettes[i][SHIRT] + palettePants = palettes[i][PANTS] + paletteName = palettes[i].name + end + if paletteShirt and palettePants then + local bucketFrame = (math.floor((get_global_timer() + i*10)*0.2)%10) * 32 + local bucketPaintFrame = (math.floor(get_global_timer()*0.3)%10) * 32 + djui_hud_set_color(charColor.r*0.5 + 127, charColor.g*0.5 + 127, charColor.b*0.5 + 127, math.min(paletteTrans, 255)) + djui_hud_render_texture_tile(TEX_PALETTE_BUCKET, x, y, 1, 1, 0, bucketFrame, 32, 32) + djui_hud_set_color(paletteShirt.r, paletteShirt.g, paletteShirt.b, math.min(paletteTrans, 255)) + djui_hud_render_texture_tile(TEX_PALETTE_BUCKET, x, y, 1, 1, 32, bucketFrame, 32, 32) + djui_hud_set_color(palettePants.r, palettePants.g, palettePants.b, math.min(paletteTrans, 255)) + djui_hud_render_texture_tile(TEX_PALETTE_BUCKET, x, y, 1, 1, 64, bucketFrame, 32, 32) + + if i == palettes.currPalette then + djui_hud_set_color(paletteShirt.r, paletteShirt.g, paletteShirt.b, math.min(paletteTrans, 255)) + djui_hud_render_texture_tile(TEX_PALETTE_BUCKET, x, y, 1, 1, 96, bucketPaintFrame, 32, 32) + djui_hud_set_color(palettePants.r, palettePants.g, palettePants.b, math.min(paletteTrans, 255)) + djui_hud_render_texture_tile(TEX_PALETTE_BUCKET, x, y, 1, 1, 128, bucketPaintFrame, 32, 32) + end + end + end + + local paletteName = (palettes.currPalette == 0) and "Custom" or (palettes[palettes.currPalette].name or ("Palette "..palettes.currPalette)) + djui_hud_set_font(FONT_RECOLOR_HUD) + local x = width*0.85 - djui_hud_measure_text(paletteName)*0.25 + local y = height*0.68 - math.abs(math.cos((get_global_timer() - palettes.currPalette*10)*0.05))*3 + djui_hud_set_color(charColor.r*0.5 + 127, charColor.g*0.5 + 127, charColor.b*0.5 + 127, math.min(paletteTrans, 255)) + djui_hud_print_text(paletteName, x, y, 0.5) + end + + -- Render Background Wall + local wallWidth = TEX_WALL_LEFT.width + local wallHeight = TEX_WALL_LEFT.height + local wallScale = 0.4 * widthScale + local wallMiddle = width*(0.35 - ((optionsMenuOffset - optionsMenuOffsetMax*0.5)/optionsMenuOffsetMax)*0.3) + local x = wallMiddle - wallWidth*wallScale*0.5 - menuOffsetX + local y = height*0.42 - wallHeight*wallScale*0.5 - menuOffsetY + local scissorWidth = math.max(320/djui_hud_get_screen_width(), 1)*320*0.7 -- Ensure Wall Space doesn't break when under 4:3 + djui_hud_set_scissor(0, 0, scissorWidth, height) + djui_hud_set_color(playerShirt.r, playerShirt.g, playerShirt.b, 255) + djui_hud_render_texture_auto_interpolated("wall-l", TEX_WALL_LEFT, x, y, wallScale, wallScale) + djui_hud_set_color(playerPants.r, playerPants.g, playerPants.b, 255) + djui_hud_render_texture_auto_interpolated("wall-r", TEX_WALL_RIGHT, x, y, wallScale, wallScale) + + -- Render Graffiti + local graffiti = characterGraffiti[currChar] or TEX_GRAFFITI_DEFAULT + local graffitiWidthScale = 120/graffiti.width + local graffitiHeightScale = 120/graffiti.width + djui_hud_set_color(255, 255, 255, 150) + djui_hud_render_texture_auto_interpolated("graffiti", graffiti, wallMiddle - graffiti.width*0.5*graffitiWidthScale - menuOffsetX, height*0.5 - graffiti.height*0.5*graffitiHeightScale - menuOffsetY, graffitiWidthScale, graffitiHeightScale) + + -- API Rendering (Below Text) + if #hookTableRenderInMenu.back > 0 then + for i = 1, #hookTableRenderInMenu.back do + hookTableRenderInMenu.back[i]() + end + end + + if prevOptions ~= options then + optionsTimer = 0 + prevOptions = options + end + + local scale = 0.35 + local textScale = scale*1.5 + local buttonSpacing = 32 + + if not gridMenu then + -- Render Character List + gridYOffset = lerp(gridYOffset, currCharRender*buttonSpacing, 0.1) + djui_hud_set_font(FONT_SPECIAL) + for i = 0, #characterTableRender do + local currCharScoll = math.floor(gridYOffset/buttonSpacing) + if i >= currCharScoll - 3 and i <= currCharScoll + 3 then -- Only render if visible + local charTable = characterTableRender[i] + local currAlt = characterTableRender[i].currAlt + local char = characterTableRender[i][currAlt] + local charName = charTable.nickname + local charAltName = char.name + local charNameLength = djui_hud_measure_text(charName) + local charColor = char.color + local x = -(math.abs(i - gridYOffset/buttonSpacing)^2)*5 + 32 - menuOffsetX*0.2 - optionsMenuOffset + local y = height*0.45 - buttonSpacing*0.5 + i*buttonSpacing - gridYOffset - menuOffsetY*0.2 + local segmentsMeasured = (math.ceil(((charNameLength*textScale + 16*scale))/(16*scale))) + local segments = segmentsMeasured + local charAltCount = #characterTableRender[i] + local channel = characterInstrumentals[i] and tostring(math.floor(879 + hash(characterTableRender[i].saveName)%(1029 - 879))*0.1) .. " FM " or "---.- -- " + channel = channel .. tostring(math.ceil(charTable.playtime / totalPlaytime * 100)) .. "%" + -- Backlight + djui_hud_set_color(charColor.r*0.5 + 127, charColor.g*0.5 + 127, charColor.b*0.5 + 127, 255) + djui_hud_render_rect(x + 96*scale, y + 24*scale, (128*scale + segments*16*scale), 80*scale) + -- Name Screen + djui_hud_set_color(charColor.r*0.5, charColor.g*0.5, charColor.b*0.5, 255) + djui_hud_print_text(charName, x + 112*scale + segments*16*scale*0.5 - charNameLength*textScale*0.5, y + 32*scale, textScale) + + -- Bottom Info + djui_hud_render_rect(x + 112*scale, y + 84*scale, segments*16*scale, scale) + djui_hud_print_text(channel, x + 112*scale, y + 85*scale, 0.3*scale) + djui_hud_print_text(charAltName, x + segments*16*scale + 112*scale - djui_hud_measure_text(charAltName)*0.3*scale, y + 85*scale, 0.3*scale) + + -- Icon + djui_hud_set_color(charColor.r, charColor.g, charColor.b, 150) + djui_hud_render_life_icon(char, x + 112*scale + segments*16*scale + 45*scale, y + 40*scale, scale*3) + -- Nameplate Rendering + djui_hud_set_color(menuColorTint.r, menuColorTint.g, menuColorTint.b, 255) + djui_hud_render_texture_tile(TEX_NAMEPLATE, 0, y, (128/8)*x*0.5*scale, scale, 0, 0, 8, 128) -- stretch to left side of screen + djui_hud_render_texture_tile(TEX_NAMEPLATE, x, y, (128/112)*scale, scale, 0, 0, 112, 128) + for s = 1, segments do + djui_hud_render_texture_tile(TEX_NAMEPLATE, x + (112 + (s-1)*16)*scale, y, scale*8, scale, 112, 0, 16, 128) + end + djui_hud_render_texture_tile(TEX_NAMEPLATE, x + (112 + segments*16)*scale, y, scale*128/192, scale, 128, 0, 192, 128) + local angle = -0x10000*((characterTableRender[i].currAlt - 1)/charAltCount) + if i == currCharRender then + djui_hud_render_texture_tile(TEX_NAMEPLATE, x + 33*scale, y + 48*scale, scale, scale, 320, 48, 32, 32) + end + if charTable.dialAnim == nil then charTable.dialAnim = 0 end + angleAnim = -0x10000*((1/charAltCount))*charTable.dialAnim/10 + charTable.dialAnim = math.lerp(charTable.dialAnim, 0, 0.2) + djui_hud_set_rotation(angle + angleAnim, 0.5, 0.5) + djui_hud_render_texture_tile(TEX_NAMEPLATE, x + (112 + segments*16 + 134)*scale, y + 48*scale, scale, scale, 352, 48, 32, 32) + djui_hud_set_rotation(0, 0, 0) + for a = 1, charAltCount do + local angle = -0x10000*((a - 1)/charAltCount) + 0x8000 + local altColor = characterTableRender[i][a].color + djui_hud_set_color(altColor.r * 0.5 + 127, altColor.g * 0.5 + 127, altColor.b * 0.5 + 127, 255) + djui_hud_render_texture_tile(TEX_NAMEPLATE, x + (112 + segments*16 + (134 + 14) + sins(angle)*16)*scale, y + (62 + coss(angle)*16)*scale, scale, scale, 384, 48 + (currAlt ~= a and 16 or 0), 4, 4) + end + end + end + else + -- Render Character Grid + local currRow = math.floor((currCharRender)/gridButtonsPerRow) + gridYOffset = lerp(gridYOffset, currRow*buttonSpacing, 0.1) + for i = 0, #characterTableRender do + local row = math.floor(i/gridButtonsPerRow) + local column = i%gridButtonsPerRow + local charIcon = characterTableRender[i][characterTableRender[i].currAlt].lifeIcon + local charColor = characterTableRender[i][characterTableRender[i].currAlt].color + local x = 40 + buttonSpacing*column - math.abs(row - gridYOffset/buttonSpacing)^2*3 + math.sin((get_global_timer() + i*10)*0.1) - menuOffsetX*0.5 - optionsMenuOffset + 4 + local y = height*0.5 - buttonSpacing*0.5 + row*buttonSpacing - gridYOffset + math.cos((get_global_timer() + i*10)*0.1) - characterTableRender[i].UIOffset*0.5 - menuOffsetY*0.5 + 4 + djui_hud_set_color(charColor.r, charColor.g, charColor.b, 255) + if characterInstrumentals[i] ~= nil then + djui_hud_render_texture(TEX_ALBUM_LAYER1, x + 3, y, 0.1875, 0.1875) + local discColors = {charColor, charColor, charColor} + local palettes = characterColorPresets[characterTableRender[i][characterTableRender[i].currAlt].model] + if palettes ~= nil then + local paletteIndex = math.max(palettes.currPalette, 1) + discColors = {palettes[paletteIndex][PANTS], palettes[paletteIndex][CAP], palettes[paletteIndex][EMBLEM]} + end + local discX = x + 6 + local discY = y + 2 + if (i == currCharRender) then + discX = x + 13 + discY = y + 2 + djui_hud_set_rotation(math.s16(get_global_timer()*-0x1000), 0.5, 0.5) + x = x - 4 + end + djui_hud_set_color(discColors[1].r, discColors[1].g, discColors[1].b, 255) + djui_hud_render_texture(TEX_CD_LAYER1, discX, discY, 0.15625, 0.15625) + djui_hud_set_color(discColors[2].r, discColors[2].g, discColors[2].b, 255) + djui_hud_render_texture(TEX_CD_LAYER2, discX, discY, 0.15625, 0.15625) + djui_hud_set_color(discColors[3].r, discColors[3].g, discColors[3].b, 255) + djui_hud_render_texture(TEX_CD_LAYER3, discX, discY, 0.15625, 0.15625) + djui_hud_set_color(255, 255, 255, 255) + djui_hud_render_texture(TEX_CD_LAYER4, discX, discY, 0.15625, 0.15625) + djui_hud_set_rotation(0, 0.5, 0.5) + elseif i == currCharRender then + djui_hud_render_texture(TEX_ALBUM_LAYER1, x + 6, y, 0.1875, 0.1875) + x = x - 4 + else + djui_hud_render_texture(TEX_ALBUM_LAYER1, x + 3, y, 0.1875, 0.1875) + end + djui_hud_set_color(charColor.r, charColor.g, charColor.b, 255) + djui_hud_render_texture(TEX_ALBUM_LAYER2, x, y, 0.1875, 0.1875) + x = x + 4 + y = y + 4 + djui_hud_set_color(255, 255, 255, 255) + if type(charIcon) == TYPE_STRING then + djui_hud_set_font(FONT_RECOLOR_HUD) + djui_hud_set_color(charColor.r, charColor.g, charColor.b, 255) + djui_hud_print_text(charIcon, x, y, 1) + else + djui_hud_render_texture(charIcon, x, y, 1 / (charIcon.width * MATH_DIVIDE_16), 1 / (charIcon.height * MATH_DIVIDE_16)) + end + djui_hud_render_texture(TEX_ALBUM_LAYER3, x - 4, y - 4, 0.1875, 0.1875) + + characterTableRender[i].UIOffset = lerp(characterTableRender[i].UIOffset, currCharRender == i and 15 or 0, 0.1) + end + end + + -- Render OST Record + djui_hud_set_color(255, 255, 255, 255) + djui_hud_set_rotation(get_global_timer() * 0x10, 0.5, 0.5) + djui_hud_render_texture(TEX_RECORD, -152 - menuOffsetX*0.1 - optionsMenuOffset, height*0.5 - 96 - menuOffsetY*0.1, 0.75, 0.75) + djui_hud_set_rotation(0, 0, 0) + + -- Render Category Gear + djui_hud_set_color(menuColorTint.r, menuColorTint.g, menuColorTint.b, 255) + djui_hud_set_rotation(gearRotation, 0.5, 0.5) + gearRotation = math.lerp(gearRotation, gearRotationTarget, 0.1) + djui_hud_render_texture(TEX_GEAR, width*0.7 - 15 - TEX_GEAR.width*0.175 - menuOffsetX*0.1, -TEX_GEAR.height*0.175 - menuOffsetY*0.1, 0.35, 0.35) + djui_hud_set_rotation(0, 0, 0) + local icon1 = characterCategories[currCategory].icon1 + local icon2 = characterCategories[currCategory].icon2 + local name = characterCategories[currCategory].name + local char1 = characterTable[icon1] and characterTable[icon1][1] + local char2 = characterTable[icon2] and characterTable[icon2][1] + djui_hud_render_life_icon(char1, width*0.7 - 30 - 4 - menuOffsetX*0.1, 10 - 4 - menuOffsetY*0.1, 1) + djui_hud_render_life_icon(char2, width*0.7 - 30 + 4 - menuOffsetX*0.1, 10 + 4 - menuOffsetY*0.1, 1) + djui_hud_set_font(FONT_NORMAL) + djui_hud_print_text(name, width*0.7 - 65 - djui_hud_measure_text(name)*0.4 - menuOffsetX*0.1, 2 - menuOffsetY*0.1, 0.4) + djui_hud_set_color(255, 255, 255, 255) + + -- Render Options Menu + local tvScale = 0.5 + local tvX = width*0.7 - 170 + (optionsMenuOffsetMax - optionsMenuOffset) + 15 - menuOffsetX*0.2 + local tvY = 70 + (optionsMenuOffsetMax - optionsMenuOffset)*0.2 - menuOffsetY*0.2 + local tvWidth = (320 - 133)*tvScale + local tvHeight = (323 - 168)*tvScale + local optionData = optionTable[currOption] + djui_hud_set_color(255, 255, 255, 255) + djui_hud_render_rect(tvX, tvY, tvWidth, tvHeight) + if options == OPTIONS_MAIN then + djui_hud_set_font(FONT_TINY) + djui_hud_set_color(0, 0, 0, 255) + djui_hud_print_text(optionData.name, tvX + 12 + (tvWidth - 12)*0.5 - djui_hud_measure_text(optionData.name)*0.35, tvY + 20, 0.7) + local locked = optionTable[currOption].lock ~= nil and optionTable[currOption].lock() or nil + local toggleString = (locked == nil and "< " .. optionData.toggleNames[optionData.toggle + 1] .. " >" or locked) + djui_hud_print_text(toggleString, tvX + 12 + (tvWidth - 12)*0.5 - djui_hud_measure_text(toggleString)*0.25, tvY + 30, 0.5) + + for i = 1, #optionData.description do + local textMeasure = djui_hud_measure_text(optionData.description[i]) + local x = tvX + 12 + (tvWidth - 12)*0.5 - textMeasure*0.225 + local y = tvY + tvHeight - 7*(#optionData.description + 2) + 7*i + djui_hud_set_color(0, 0, 0, 255) + djui_hud_render_rect(x - 2, y, textMeasure*0.45 + 4, 8) + djui_hud_set_color(255, 255, 255, 255) + djui_hud_print_text(optionData.description[i], x, y, 0.45) + end + + -- Render Header + djui_hud_set_color(0, 0, 0, 255) + djui_hud_render_rect(tvX, tvY, tvWidth, 18) + djui_hud_set_font(FONT_ALIASED) + djui_hud_set_color(255, 255, 255, 255) + djui_hud_print_text("OPTIONS", tvX + 13, tvY + 2, 0.5) + djui_hud_set_font(FONT_NORMAL) + local optionCategory = "... " .. string.upper(optionData.category) + djui_hud_print_text(optionCategory, tvX + 13 + djui_hud_measure_text("OPTIONS")*0.5, tvY + 8, 0.25) + + -- Render Sidebar + djui_hud_set_color(0, 0, 0, 255) + djui_hud_render_rect(tvX, tvY, 10, tvHeight) + for i = 1, #optionTable do + if i == currOption then + djui_hud_set_color(255, 255, 255, 255) + else + djui_hud_set_color(100, 100, 100, 255) + end + djui_hud_render_rect(tvX + 4, tvY + (tvHeight - 10)*(i/#optionTable), 2, 2) + end + elseif options == OPTIONS_CREDITS then + -- Render Scroll Bar + djui_hud_set_color(0, 0, 0, 255) + djui_hud_render_rect(tvX + 3, tvY + 24, 1, 40) + local creditSize = math.min(1, creditScrollMin/(#creditTable[currCredits] / (currCredits > 0 and 1 or 3))) + djui_hud_render_rect(tvX + 2, tvY + 24 + (currCreditScroll/(#creditTable[currCredits] - creditScrollMin))*(40*(1 - creditSize)), 3, 40*creditSize) + -- Render Credits + djui_hud_set_color(0, 0, 0, 255) + djui_hud_set_font(FONT_TINY) + if currCredits > 0 then + for i = 1, #creditTable[currCredits] do + local creditData = creditTable[currCredits][i] + djui_hud_print_text(creditData.creditee, tvX + tvWidth*0.5 - 1 - djui_hud_measure_text(creditData.creditee)*0.4, tvY + 19 + creditScrollMin*(i - currCreditScroll), 0.4) + djui_hud_print_text(creditData.credit, tvX + tvWidth*0.5 + 1, tvY + 19 + creditScrollMin*(i - currCreditScroll), 0.4) + end + else + for i = 1, #creditTable[currCredits] do + local creditData = creditTable[currCredits][i] + djui_hud_print_text(creditData.creditee, tvX - tvWidth*0.1 + tvWidth*0.3*(((i - 1)%3) + 1) - djui_hud_measure_text(creditData.creditee)*0.2, tvY + 19 + creditScrollMin*(math.ceil(i/3) - currCreditScroll), 0.4) + end + + -- Render Support Link + djui_hud_set_color(0, 0, 0, 255) + djui_hud_render_rect(tvX, tvY + tvHeight - 10, tvWidth, 11) + djui_hud_set_color(255, 255, 255, 255) + djui_hud_set_font(FONT_TINY) + djui_hud_print_text(TEXT_KOFI_LINK, tvX + tvWidth*0.5 - djui_hud_measure_text(TEXT_KOFI_LINK)*0.25, tvY + tvHeight - 10, 0.5) + end + -- Render Pack Name + djui_hud_set_color(0, 0, 0, 255) + djui_hud_render_rect(tvX, tvY, tvWidth, 21) + djui_hud_set_color(255, 255, 255, 255) + djui_hud_set_font(FONT_ALIASED) + djui_hud_print_text(TEXT_CREDITS_HEADER, tvX + tvWidth*0.5 - djui_hud_measure_text(TEXT_CREDITS_HEADER)*0.2, tvY + 2, 0.4) + djui_hud_set_font(FONT_SPECIAL) + djui_hud_print_text(creditTable[currCredits].packName, tvX + tvWidth*0.5 - djui_hud_measure_text(creditTable[currCredits].packName)*0.1, tvY + 14, 0.2) + else + local tvShutOffHeight = tvHeight*0.5*(optionsMenuOffsetMax^3.5 - optionsMenuOffset^3.5)/optionsMenuOffsetMax^3.5 + djui_hud_set_color(0, 0, 0, 255) + djui_hud_render_rect(tvX, tvY, tvWidth, tvShutOffHeight) + djui_hud_render_rect(tvX, tvY + tvHeight - tvShutOffHeight, tvWidth, tvShutOffHeight) + end + + djui_hud_set_color(menuColorTint.r, menuColorTint.g, menuColorTint.b, 255) + djui_hud_render_texture_auto_interpolated("tvBoarder", TEX_OPTIONS_TV, tvX - 133*tvScale, tvY - 168*tvScale, tvScale, tvScale) + + djui_hud_reset_scissor() + + -- Render Character Description + djui_hud_set_rotation(angle_from_2d_points(-10, height - 50, width + 10, height - 35), 0, 0) + djui_hud_set_color(0, 0, 0, 255) + djui_hud_render_rect(-10, height - 50, width*1.5, 100) + djui_hud_set_rotation(0, 0, 0) + + djui_hud_set_font(FONT_TINY) + djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) + local credit = characterTable[currChar][characterTable[currChar].currAlt].credit + local desc = characterTable[currChar][characterTable[currChar].currAlt].description + local descRender = desc .. " - " .. desc + while djui_hud_measure_text(descRender)*0.8 < width do + descRender = descRender .. " - " .. desc + end + descRender = descRender .. " - " .. desc + djui_hud_print_text_interpolated(descRender, 5 - (get_global_timer()%djui_hud_measure_text(desc .. " - ") - 1)*0.8 - menuOffsetX*0.1, height - 25 + menuOffsetY*0.15, 0.8, 5 - get_global_timer()%djui_hud_measure_text(desc .. " - ")*0.8 - menuOffsetX*0.1, height - 25 + menuOffsetY*0.15, 0.8) + + djui_hud_set_rotation(angle_from_2d_points(-10, height - 50, width + 10, height - 35), 0, 0) + djui_hud_set_color(0, 0, 0, 255) + djui_hud_render_rect(0, height - 45, width*0.3, 100) + djui_hud_set_rotation(0, 0, 0) + + djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) + djui_hud_print_text(TEXT_VERSION, 2, height - 7, 0.4) + local currMenu = gridMenu and MENU_BINDS_GRID or MENU_BINDS_DEFAULT + if options == OPTIONS_MAIN then + currMenu = MENU_BINDS_OPTIONS + elseif options == OPTIONS_CREDITS then + currMenu = MENU_BINDS_GRID + end + local bindInfo = TEXT_TABLE_MENU_BINDS[currMenu][math.floor(get_global_timer()/150)%(#TEXT_TABLE_MENU_BINDS[currMenu]) + 1] + djui_hud_print_text(bindInfo.bind, width*0.15 - djui_hud_measure_text(bindInfo.bind)*0.4, height - 35, 0.8) + djui_hud_print_text(bindInfo.desc, width*0.15 - djui_hud_measure_text(bindInfo.desc)*0.4, height - 25, 0.8) + + -- API Rendering (Above Text) + djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) + if #hookTableRenderInMenu.front > 0 then + for i = 1, #hookTableRenderInMenu.front do + hookTableRenderInMenu.front[i]() + end + end + + -- Render Header BG + djui_hud_set_rotation(angle_from_2d_points(-10, 50, 160, -10), 0.5, 0.5) + djui_hud_set_color(0, 0, 0, 255) + djui_hud_render_rect(-150, -50, 300, 100) + + -- Render Tape + djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255) + djui_hud_render_caution_tape(-10, 50, 160, -10, 1) -- Top Tape + djui_hud_render_caution_tape(width*0.7 - 5, -10, width*0.7 + 5, height - 35, 1, 0.6) -- Right Tape + djui_hud_render_caution_tape(width*0.3, height - 45, width*0.3 - 5, height, 1, 0.5) -- Left Bottom Tape + djui_hud_render_caution_tape(-10, height - 50, width + 10, height - 35, 1) -- Bottom Tape + + -- Render Header + djui_hud_set_rotation(0, 0, 0) + djui_hud_set_color(menuColorHalf.r, menuColorHalf.g, menuColorHalf.b, 255) + djui_hud_render_texture_auto_interpolated("logo", TEX_LOGO, menuOffsetX*0.1, menuOffsetY*0.1, 0.25, 0.25) -- Anim logic if options then - if optionTable[optionTableRef.anims].toggle > 0 then - if optionAnimTimer < -1 then - optionAnimTimer = optionAnimTimer * 0.9 - end - else - optionAnimTimer = -1 + if optionAnimTimer < -1 then + optionAnimTimer = optionAnimTimer * 0.9 end else - if optionTable[optionTableRef.anims].toggle > 0 then - if optionAnimTimer > optionAnimTimerCap then - optionAnimTimer = optionAnimTimer * 1.3 - end - else - optionAnimTimer = optionAnimTimerCap + if optionAnimTimer > optionAnimTimerCap then + optionAnimTimer = optionAnimTimer * 1.3 end end - optionAnimTimer = maxf(optionAnimTimer, -200) + optionAnimTimer = math.max(optionAnimTimer, -200) else - options = false + options = nil optionAnimTimer = optionAnimTimerCap - credits = false - creditsCrossFade = 0 bindTextTimer = 0 end -- Fade in/out of menu - if optionTable[optionTableRef.anims].toggle == 1 then - if menu and menuCrossFade > -menuCrossFadeCap then - menuCrossFade = menuCrossFade - 1 - if menuCrossFade == 0 then menuCrossFade = menuCrossFade - 1 end - end - if not menu and menuCrossFade < menuCrossFadeCap then - menuCrossFade = menuCrossFade + 1 - if menuCrossFade == 0 then menuCrossFade = menuCrossFade + 1 end - end - if menuCrossFade < 0 then - menuAndTransition = true - else - menuAndTransition = false - end - else - if menu then - menuCrossFade = -menuCrossFadeCap - else - menuCrossFade = menuCrossFadeCap - end - menuAndTransition = menu + if menu and menuCrossFade > -menuCrossFadeCap then + menuCrossFade = menuCrossFade - 1 + if menuCrossFade == 0 then menuCrossFade = menuCrossFade - 1 end end + if not menu and menuCrossFade < menuCrossFadeCap then + menuCrossFade = menuCrossFade + 1 + if menuCrossFade == 0 then menuCrossFade = menuCrossFade + 1 end + end + menuAndTransition = menuCrossFade < 0 -- Info / Z Open Bind on Pause Menu if is_game_paused() and not djui_hud_is_pause_menu_created() and gMarioStates[0].action ~= ACT_EXIT_LAND_SAVE_DIALOG then @@ -1559,28 +1981,22 @@ local function on_hud_render() djui_hud_print_text(text, width - 20, 16, 1) end - if optionTable[optionTableRef.localModels].toggle == 1 then - local character = characterTable[currChar][characterTable[currChar].currAlt] - local charName = string_underscore_to_space(character.name) - local TEXT_PAUSE_CURR_CHAR_WITH_NAME = TEXT_PAUSE_CURR_CHAR .. charName - width = djui_hud_get_screen_width() - djui_hud_measure_text(TEXT_PAUSE_CURR_CHAR_WITH_NAME) - local charColor = character.color - djui_hud_set_color(255, 255, 255, 255) - djui_hud_print_text(TEXT_PAUSE_CURR_CHAR, width - 20, 16 + currCharY, 1) - djui_hud_set_color(charColor.r, charColor.g, charColor.b, 255) - djui_hud_print_text(charName, djui_hud_get_screen_width() - djui_hud_measure_text(charName) - 20, 16 + currCharY, 1) - else - width = djui_hud_get_screen_width() - djui_hud_measure_text(TEXT_LOCAL_MODEL_OFF) - djui_hud_set_color(255, 255, 255, 255) - djui_hud_print_text(TEXT_LOCAL_MODEL_OFF, width - 20, 16 + currCharY, 1) - end + local character = characterTable[currChar][characterTable[currChar].currAlt] + local charName = string_underscore_to_space(character.name) + local TEXT_PAUSE_CURR_CHAR_WITH_NAME = TEXT_PAUSE_CURR_CHAR .. charName + width = djui_hud_get_screen_width() - djui_hud_measure_text(TEXT_PAUSE_CURR_CHAR_WITH_NAME) + local charColor = character.color + djui_hud_set_color(255, 255, 255, 255) + djui_hud_print_text(TEXT_PAUSE_CURR_CHAR, width - 20, 16 + currCharY, 1) + djui_hud_set_color(charColor.r, charColor.g, charColor.b, 255) + djui_hud_print_text(charName, djui_hud_get_screen_width() - djui_hud_measure_text(charName) - 20, 16 + currCharY, 1) local text = nil - if stopMovesets and stopPalettes then + if gGlobalSyncTable.charSelectRestrictMovesets > 0 and gGlobalSyncTable.charSelectRestrictPalettes > 0 then text = TEXT_MOVESET_AND_PALETTE_RESTRICTED - elseif stopMovesets then + elseif gGlobalSyncTable.charSelectRestrictMovesets > 0 then text = TEXT_MOVESET_RESTRICTED - elseif stopPalettes then + elseif gGlobalSyncTable.charSelectRestrictPalettes > 0 then text = TEXT_PALETTE_RESTRICTED end if text ~= nil then @@ -1593,20 +2009,43 @@ local function on_hud_render() -- Cross Fade to Menu djui_hud_set_resolution(RESOLUTION_N64) - djui_hud_set_color(0, 0, 0, (math_abs(menuCrossFade)) * -menuCrossFadeMath) + djui_hud_set_color(0, 0, 0, (math.abs(menuCrossFade)) * -menuCrossFadeMath) djui_hud_render_rect(0, 0, width, height) end -local prevMouseScroll = 0 +local FUNC_INDEX_MISC = 0 +local FUNC_INDEX_HORIZONTAL = 1 +local FUNC_INDEX_VERTICAL = 2 +local FUNC_INDEX_CATEGORY = 3 +local FUNC_INDEX_PREFERENCE = 4 +local FUNC_INDEX_PALETTE = 5 +local FUNC_INDEX_ALT = 6 +local FUNC_INDEX_GRID = 7 + +local menuInputCooldowns = {} +function run_func_with_condition_and_cooldown(funcIndex, condition, func, cooldown) + if menuInputCooldowns[funcIndex] == nil then + menuInputCooldowns[funcIndex] = 0 + end + if not condition then return end + local cooldown = cooldown and cooldown or latencyValueTable[optionTable[optionTableRef.inputLatency].toggle + 1] + if menuInputCooldowns[funcIndex] == 0 then + func() + menuInputCooldowns[funcIndex] = cooldown + end +end + local mouseScroll = 0 +---@param m MarioState local function before_mario_update(m) if m.playerIndex ~= 0 then return end + if not startup_init_stall() then return end local controller = m.controller - if inputStallTimerButton > 0 then inputStallTimerButton = inputStallTimerButton - 1 end - if inputStallTimerDirectional > 0 then inputStallTimerDirectional = inputStallTimerDirectional - 1 end - - if menu and inputStallToDirectional ~= latencyValueTable[optionTable[optionTableRef.inputLatency].toggle + 1] then - inputStallToDirectional = latencyValueTable[optionTable[optionTableRef.inputLatency].toggle + 1] + local character = characterTable[currChar] + for index, num in pairs(menuInputCooldowns) do + if num and num > 0 then + menuInputCooldowns[index] = num - 1 + end end -- Menu Inputs @@ -1617,7 +2056,6 @@ local function before_mario_update(m) if (controller.buttonDown & R_TRIG) ~= 0 or not ommActive then menu = true end - inputStallTimerDirectional = inputStallToDirectional end if not menu_is_allowed(m) then @@ -1625,226 +2063,315 @@ local function before_mario_update(m) return end - mouseScroll = mouseScroll + djui_hud_get_mouse_scroll_y() + mouseScroll = mouseScroll - djui_hud_get_mouse_scroll_y() + + -- Yo Melee called + local menuOffsetXRaw = (m.controller.extStickX ~= 0 and m.controller.extStickX or button_to_analog(charSelect.controller, L_CBUTTONS, R_CBUTTONS))*0.1 + local menuOffsetYRaw = (m.controller.extStickY ~= 0 and -m.controller.extStickY or button_to_analog(charSelect.controller, U_CBUTTONS, D_CBUTTONS))*0.1 + menuOffsetX = lerp(menuOffsetX, menuOffsetXRaw, 0.2) + menuOffsetY = lerp(menuOffsetY, menuOffsetYRaw, 0.2) local cameraToObject = m.marioObj.header.gfx.cameraToObject if menuAndTransition and not options then + run_func_with_condition_and_cooldown(FUNC_INDEX_GRID, + (controller.buttonPressed & X_BUTTON) ~= 0, + function () + gridMenu = not gridMenu + mod_storage_save_bool("PrefGridView", gridMenu) + play_sound(SOUND_MENU_CLICK_CHANGE_VIEW, cameraToObject) + end + ) if menu then - if inputStallTimerDirectional == 0 and not charBeingSet then + -- Category Switching + run_func_with_condition_and_cooldown(FUNC_INDEX_CATEGORY, + (controller.buttonPressed & L_TRIG) ~= 0, + function () + repeat + currCategory = num_wrap(currCategory - 1, 1, #characterCategories) + until update_character_render_table() + gearRotationTarget = gearRotationTarget + 0x10000/#characterCategories + categoryOpenTimer = 150 + + play_sound(SOUND_MENU_CAMERA_TURN, cameraToObject) + end + ) + + run_func_with_condition_and_cooldown(FUNC_INDEX_CATEGORY, + (controller.buttonPressed & R_TRIG) ~= 0, + function () + repeat + currCategory = num_wrap(currCategory + 1, 1, #characterCategories) + until update_character_render_table() + gearRotationTarget = gearRotationTarget - 0x10000/#characterCategories + categoryOpenTimer = 150 + update_character_render_table() + play_sound(SOUND_MENU_CAMERA_TURN, cameraToObject) + end + ) + + if not gridMenu then + -- List Controls + run_func_with_condition_and_cooldown(FUNC_INDEX_VERTICAL, + (controller.buttonPressed & D_JPAD) ~= 0 or controller.stickY < -45 --[[or prevMouseScroll < mouseScroll]], + function () + currCharRender = num_wrap(currCharRender + 1, 0, #characterTableRender) + play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) + end + ) + + run_func_with_condition_and_cooldown(FUNC_INDEX_VERTICAL, + (controller.buttonPressed & U_JPAD) ~= 0 or controller.stickY > 45 --[[or prevMouseScroll > mouseScroll]], + function () + currCharRender = num_wrap(currCharRender - 1, 0, #characterTableRender) + play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) + end + ) + -- Alt switcher if #characterTable[currChar] > 1 then - local character = characterTable[currChar] - if (controller.buttonPressed & R_JPAD) ~= 0 or controller.stickX > 60 then - character.currAlt = character.currAlt + 1 - inputStallTimerDirectional = inputStallToDirectional - play_sound(SOUND_MENU_CLICK_CHANGE_VIEW, cameraToObject) - buttonAltAnim = inputStallToDirectional - end - if (controller.buttonPressed & L_JPAD) ~= 0 or controller.stickX < -60 then - character.currAlt = character.currAlt ~= 0 and character.currAlt - 1 or #character - inputStallTimerDirectional = inputStallToDirectional - play_sound(SOUND_MENU_CLICK_CHANGE_VIEW, cameraToObject) - buttonAltAnim = -inputStallToDirectional - end - if character.currAlt > #character then character.currAlt = 1 end - if character.currAlt < 1 then character.currAlt = #character end + if characterTableRender[currCharRender].dialAnim == nil then characterTableRender[currCharRender].dialAnim = 0 end + run_func_with_condition_and_cooldown(FUNC_INDEX_HORIZONTAL, + (controller.buttonPressed & R_JPAD) ~= 0 or controller.stickX > 60, + function () + character.currAlt = num_wrap(character.currAlt + 1, 1, #character) + characterTableRender[currCharRender].dialAnim = characterTableRender[currCharRender].dialAnim - 10 + audio_stream_set_frequency(SOUND_CHAR_SELECT_DIAL, math.random(20, 80)*0.01 + 0.5) + audio_stream_play(SOUND_CHAR_SELECT_DIAL, true, 0.75) + end + ) + + run_func_with_condition_and_cooldown(FUNC_INDEX_HORIZONTAL, + (controller.buttonPressed & L_JPAD) ~= 0 or controller.stickX < -60, + function () + character.currAlt = num_wrap(character.currAlt - 1, 1, #character) + characterTableRender[currCharRender].dialAnim = characterTableRender[currCharRender].dialAnim + 10 + audio_stream_set_frequency(SOUND_CHAR_SELECT_DIAL, math.random(20, 80)*0.01 + 0.5) + audio_stream_play(SOUND_CHAR_SELECT_DIAL, true, 0.75) + end + ) end - - if optionTable[optionTableRef.localModels].toggle ~= 0 then - if (controller.buttonPressed & D_JPAD) ~= 0 or (controller.buttonPressed & D_CBUTTONS) ~= 0 or controller.stickY < -60 or prevMouseScroll < mouseScroll then - currCharRender = currCharRender + 1 - --[[ - local character = characterTableRender[currCharRender] - if character ~= nil and character.locked then - currCharRender = get_next_unlocked_char() - end - ]] - if (controller.buttonPressed & D_CBUTTONS) == 0 then - inputStallTimerDirectional = inputStallToDirectional - else - inputStallTimerDirectional = 3 -- C-Scrolling - end - if currCharRender > #characterTableRender then - buttonScroll = -buttonScrollCap * #characterTableRender - else - buttonScroll = buttonScrollCap - end + + else + -- Grid Controls + run_func_with_condition_and_cooldown(FUNC_INDEX_VERTICAL, + (controller.buttonPressed & D_JPAD) ~= 0 or controller.stickY < -45 --[[or prevMouseScroll < mouseScroll]], + function () + currCharRender = num_wrap(currCharRender + 5, currCharRender%5, #characterTableRender) play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) - if currCharRender > #characterTableRender then currCharRender = 1 end - currChar = characterTableRender[currCharRender].ogNum - if characterColorPresets[characterTable[currChar]] ~= nil then - characterColorPresets[characterTable[currChar]].currPalette = 0 - end - prevMouseScroll = mouseScroll - end - if (controller.buttonPressed & U_JPAD) ~= 0 or (controller.buttonPressed & U_CBUTTONS) ~= 0 or controller.stickY > 60 or prevMouseScroll > mouseScroll then - currCharRender = currCharRender - 1 - --[[ - local character = characterTableRender[currCharRender] - if character ~= nil and character.locked then - currCharRender = get_last_unlocked_char() - end - ]] - if (controller.buttonPressed & U_CBUTTONS) == 0 then - inputStallTimerDirectional = inputStallToDirectional - else - inputStallTimerDirectional = 3 -- C-Scrolling - end - if currCharRender < 1 then - buttonScroll = buttonScrollCap * (#characterTableRender - 1) - else - buttonScroll = -buttonScrollCap - end - play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) - if currCharRender < 1 then currCharRender = #characterTableRender end - currChar = characterTableRender[currCharRender].ogNum - if characterColorPresets[characterTable[currChar]] ~= nil then - characterColorPresets[characterTable[currChar]].currPalette = 0 - end - prevMouseScroll = mouseScroll end + ) - -- Tab Switcher - if (controller.buttonPressed & L_TRIG) ~= 0 then - local renderEmpty = true - while renderEmpty do - currCategory = currCategory - 1 - if currCategory < 1 then currCategory = #characterCategories end - renderEmpty = not update_character_render_table() - end - inputStallTimerDirectional = inputStallToDirectional - play_sound(SOUND_MENU_CAMERA_TURN, cameraToObject) + run_func_with_condition_and_cooldown(FUNC_INDEX_VERTICAL, + (controller.buttonPressed & U_JPAD) ~= 0 or controller.stickY > 45 --[[or prevMouseScroll > mouseScroll]], + function () + local tableCap = #characterTableRender - #characterTableRender%5 + currCharRender%5 + tableCap = tableCap - (tableCap > #characterTable and 5 or 0) + currCharRender = num_wrap(currCharRender - 5, currCharRender%5, tableCap) + play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) end - if (controller.buttonPressed & R_TRIG) ~= 0 then - local renderEmpty = true - while renderEmpty do - currCategory = currCategory + 1 - if currCategory > #characterCategories then currCategory = 1 end - renderEmpty = not update_character_render_table() - end - inputStallTimerDirectional = inputStallToDirectional - play_sound(SOUND_MENU_CAMERA_TURN, cameraToObject) + ) + + run_func_with_condition_and_cooldown(FUNC_INDEX_HORIZONTAL, + (controller.buttonPressed & R_JPAD) ~= 0 or controller.stickX > 60, + function () + currCharRender = num_wrap(currCharRender + 1, 0, #characterTableRender) + play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) end + ) + + run_func_with_condition_and_cooldown(FUNC_INDEX_HORIZONTAL, + (controller.buttonPressed & L_JPAD) ~= 0 or controller.stickX < -60, + function () + currCharRender = num_wrap(currCharRender - 1, 0, #characterTableRender) + play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) + end + ) + + -- Alt switcher + if #characterTable[currChar] > 1 then + run_func_with_condition_and_cooldown(FUNC_INDEX_ALT, + (controller.buttonPressed & R_CBUTTONS) ~= 0, + function () + character.currAlt = num_wrap(character.currAlt + 1, 1, #character) + audio_stream_set_frequency(SOUND_CHAR_SELECT_DIAL, math.random(20, 80)*0.01 + 0.5) + audio_stream_play(SOUND_CHAR_SELECT_DIAL, true, 0.75) + end + ) + + run_func_with_condition_and_cooldown(FUNC_INDEX_ALT, + (controller.buttonPressed & L_CBUTTONS) ~= 0, + function () + character.currAlt = num_wrap(character.currAlt - 1, 1, #character) + audio_stream_set_frequency(SOUND_CHAR_SELECT_DIAL, math.random(20, 80)*0.01 + 0.5) + audio_stream_play(SOUND_CHAR_SELECT_DIAL, true, 0.75) + end + ) end end - if inputStallTimerButton == 0 then - if (controller.buttonPressed & A_BUTTON) ~= 0 then + + run_func_with_condition_and_cooldown(FUNC_INDEX_PREFERENCE, + (controller.buttonPressed & A_BUTTON) ~= 0, + function () if characterTable[currChar] ~= nil then mod_storage_save_pref_char(characterTable[currChar]) - inputStallTimerButton = inputStallToButton play_sound(SOUND_MENU_CLICK_FILE_SELECT, cameraToObject) + play_character_sound(m, CHAR_SOUND_LETS_A_GO) else play_sound(SOUND_MENU_CAMERA_BUZZ, cameraToObject) end - - -- Set bottom right text - bindText = 1 - bindTextTimer = 1 end - if (controller.buttonPressed & B_BUTTON) ~= 0 then - menu = false - end - if (controller.buttonPressed & START_BUTTON) ~= 0 then - options = true - end - local modelId = gCSPlayers[0].modelId - local paletteCount = characterColorPresets[gCSPlayers[0].modelId] ~= nil and #characterColorPresets[gCSPlayers[0].modelId] or 0 - local currPaletteTable = characterColorPresets[gCSPlayers[0].modelId] and characterColorPresets[gCSPlayers[0].modelId] or {currPalette = 0} + ) - if (controller.buttonPressed & Y_BUTTON) ~= 0 then - if characterColorPresets[modelId] and optionTable[optionTableRef.localModels].toggle > 0 and not stopPalettes then + run_func_with_condition_and_cooldown(FUNC_INDEX_PALETTE, + (controller.buttonPressed & Y_BUTTON) ~= 0, + function () + local currPaletteTable = characterColorPresets[gCSPlayers[0].modelId] and characterColorPresets[gCSPlayers[0].modelId] or {currPalette = 0} + if #currPaletteTable > 0 and gGlobalSyncTable.charSelectRestrictPalettes == 0 then play_sound(SOUND_MENU_CLICK_FILE_SELECT, cameraToObject) currPaletteTable.currPalette = currPaletteTable.currPalette + 1 - inputStallTimerButton = inputStallToButton else play_sound(SOUND_MENU_CAMERA_BUZZ, cameraToObject) - inputStallTimerButton = inputStallToButton end + paletteTrans = 1000 + currPaletteTable.currPalette = num_wrap(currPaletteTable.currPalette, 0, #currPaletteTable) + end + ) - -- Set bottom right text - bindText = 2 - bindTextTimer = 1 + run_func_with_condition_and_cooldown(FUNC_INDEX_MISC, + (controller.buttonPressed & B_BUTTON) ~= 0, + function () + menu = false end - if characterColorPresets[gCSPlayers[0].modelId] ~= nil then - if paletteCount < currPaletteTable.currPalette then currPaletteTable.currPalette = 0 end + ) + + run_func_with_condition_and_cooldown(FUNC_INDEX_MISC, + (controller.buttonPressed & START_BUTTON) ~= 0, + function () + options = OPTIONS_MAIN end - end + ) end -- Handles Camera Posistioning - faceAngle = m.faceAngle.y + camAngle = m.faceAngle.y + 0x800 eyeState = MARIO_EYES_OPEN - if controller.buttonPressed & R_CBUTTONS ~= 0 then - faceAngle = faceAngle + 0x1000 - eyeState = MARIO_EYES_LOOK_RIGHT - end - if controller.buttonPressed & L_CBUTTONS ~= 0 then - faceAngle = faceAngle - 0x1000 - eyeState = MARIO_EYES_LOOK_LEFT - end nullify_inputs(m) if is_game_paused() then - controller.buttonPressed = START_BUTTON + game_unpause() end end - if options and not creditsAndTransition then - if inputStallTimerDirectional == 0 then - if (controller.buttonPressed & D_JPAD) ~= 0 or controller.stickY < -60 then - currOption = currOption + 1 - inputStallTimerDirectional = inputStallToDirectional + if options == OPTIONS_MAIN then + run_func_with_condition_and_cooldown(FUNC_INDEX_VERTICAL, + (controller.buttonPressed & D_JPAD) ~= 0 or controller.stickY < -60, + function () + currOption = num_wrap(currOption + 1, 1, #optionTable) play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) end - if (controller.buttonPressed & U_JPAD) ~= 0 or controller.stickY > 60 then - currOption = currOption - 1 - inputStallTimerDirectional = inputStallToDirectional - play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) - end - end + ) - if inputStallTimerButton == 0 then - if (controller.buttonPressed & A_BUTTON) ~= 0 and not optionTable[currOption].optionBeingSet then - optionTable[currOption].toggle = optionTable[currOption].toggle + 1 - if optionTable[currOption].toggle > optionTable[currOption].toggleMax then optionTable[currOption].toggle = 0 end - if optionTable[currOption].toggleSaveName ~= nil then - mod_storage_save(optionTable[currOption].toggleSaveName, tostring(optionTable[currOption].toggle)) + run_func_with_condition_and_cooldown(FUNC_INDEX_VERTICAL, + (controller.buttonPressed & U_JPAD) ~= 0 or controller.stickY > 60, + function () + currOption = num_wrap(currOption - 1, 1, #optionTable) + play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) + end + ) + + + run_func_with_condition_and_cooldown(FUNC_INDEX_HORIZONTAL, + (controller.buttonPressed & L_JPAD) ~= 0 or controller.stickX < -60, + function () + local locked = optionTable[currOption].lock ~= nil and optionTable[currOption].lock() or nil + if locked == nil then + optionTable[currOption].toggle = num_wrap(optionTable[currOption].toggle - 1, 0, optionTable[currOption].toggleMax) + if optionTable[currOption].toggleSaveName ~= nil then + mod_storage_save(optionTable[currOption].toggleSaveName, tostring(optionTable[currOption].toggle)) + end + play_sound(SOUND_MENU_CHANGE_SELECT, cameraToObject) + else + play_sound(SOUND_MENU_CAMERA_BUZZ, cameraToObject) end - inputStallTimerButton = inputStallToButton - play_sound(SOUND_MENU_CHANGE_SELECT, cameraToObject) end - if (controller.buttonPressed & B_BUTTON) ~= 0 then - options = false - inputStallTimerButton = inputStallToButton + ) + + run_func_with_condition_and_cooldown(FUNC_INDEX_HORIZONTAL, + (controller.buttonPressed & R_JPAD) ~= 0 or controller.stickX > 60, + function () + local locked = optionTable[currOption].lock ~= nil and optionTable[currOption].lock() or nil + if locked == nil then + optionTable[currOption].toggle = num_wrap(optionTable[currOption].toggle + 1, 0, optionTable[currOption].toggleMax) + if optionTable[currOption].toggleSaveName ~= nil then + mod_storage_save(optionTable[currOption].toggleSaveName, tostring(optionTable[currOption].toggle)) + end + play_sound(SOUND_MENU_CHANGE_SELECT, cameraToObject) + else + play_sound(SOUND_MENU_CAMERA_BUZZ, cameraToObject) + end end + ) + + run_func_with_condition_and_cooldown(FUNC_INDEX_MISC, + (controller.buttonPressed & B_BUTTON) ~= 0, + function () + options = nil + end + ) + + nullify_inputs(m) + + elseif options == OPTIONS_CREDITS then + run_func_with_condition_and_cooldown(FUNC_INDEX_HORIZONTAL, + (controller.buttonPressed & L_JPAD) ~= 0 or controller.stickX < -60, + function () + currCredits = num_wrap(currCredits - 1, 0, #creditTable) + currCreditScroll = 0 + play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) + end + ) + + run_func_with_condition_and_cooldown(FUNC_INDEX_HORIZONTAL, + (controller.buttonPressed & R_JPAD) ~= 0 or controller.stickX > 60, + function () + currCredits = num_wrap(currCredits + 1, 0, #creditTable) + currCreditScroll = 0 + play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) + end + ) + + if #creditTable[currCredits] > creditScrollMin then + run_func_with_condition_and_cooldown(FUNC_INDEX_VERTICAL, + (controller.buttonPressed & U_JPAD) ~= 0 or controller.stickY > 60, + function () + currCreditScroll = num_wrap(currCreditScroll - 1, 0, math.max(0, math.ceil(#creditTable[currCredits] / (currCredits > 0 and 1 or 3)) - creditScrollMin)) + play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) + end + ) + + run_func_with_condition_and_cooldown(FUNC_INDEX_VERTICAL, + (controller.buttonPressed & D_JPAD) ~= 0 or controller.stickY < -60, + function () + currCreditScroll = num_wrap(currCreditScroll + 1, 0, math.max(0, #creditTable[currCredits] / math.ceil(currCredits > 0 and 1 or 3) - creditScrollMin)) + play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject) + end + ) end - if currOption > #optionTable then currOption = 1 end - if currOption < 1 then currOption = #optionTable end + + run_func_with_condition_and_cooldown(FUNC_INDEX_MISC, + (controller.buttonPressed & (B_BUTTON | Z_TRIG)) ~= 0, + function () + options = OPTIONS_MAIN + currOption = optionTableRef.credits + end + ) + nullify_inputs(m) end - if creditsAndTransition then - if (controller.buttonDown & U_JPAD) ~= 0 then - creditScroll = creditScroll - 1.5 - elseif (controller.buttonDown & D_JPAD) ~= 0 then - creditScroll = creditScroll + 1.5 - elseif math.abs(controller.stickY) > 30 then - creditScroll = creditScroll + controller.stickY*-0.03 - end - - if inputStallTimerButton == 0 then - if (controller.buttonPressed & A_BUTTON) ~= 0 or (controller.buttonPressed & B_BUTTON) ~= 0 or (controller.buttonPressed & START_BUTTON) ~= 0 then - credits = false - end - end - nullify_inputs(m) - if creditScroll < 0 then creditScroll = 0 end - if creditScroll > creditScrollRange then creditScroll = creditScrollRange end - else - creditScroll = 0 - end - + -- Checks + currChar = characterTableRender[currCharRender].ogNum end hook_event(HOOK_BEFORE_MARIO_UPDATE, before_mario_update) @@ -1857,7 +2384,7 @@ hook_event(HOOK_ON_HUD_RENDER, on_hud_render) promptedAreYouSure = false local function chat_command(msg) - msg = string_lower(msg) + msg = string.lower(msg) -- Open Menu Check if (msg == "" or msg == "menu") then @@ -1893,17 +2420,12 @@ local function chat_command(msg) end -- Name Check - for i = 1, #characterTable do - if not characterTable[i].locked then - local saveName = string_underscore_to_space(string_lower(characterTable[i].saveName)) + for i = 0, #characterTable do + if characterTable[i].locked ~= LOCKED_TRUE then + local saveName = string_underscore_to_space(string.lower(characterTable[i].saveName)) for a = 1, #characterTable[i] do - if msg == string_lower(characterTable[i][a].name) or msg == saveName then - currCategory = 1 - currChar = i - update_character_render_table() - if msg ~= saveName then - characterTable[i].currAlt = a - end + if msg == string.lower(characterTable[i][a].name) or msg == saveName then + force_set_character(i, msg ~= saveName and a or 1) djui_chat_message_create('Character set to "' .. characterTable[i][characterTable[i].currAlt].name .. '" Successfully!') return true end @@ -1917,28 +2439,15 @@ local function chat_command(msg) local charNum = tonumber(msgSplit[1]) local altNum = tonumber(msgSplit[2]) altNum = altNum and altNum or 1 - if charNum > 0 and charNum <= #characterTable and not characterTable[charNum].locked then - currChar = charNum - characterTable[charNum].currAlt = altNum + if charNum > 0 and charNum <= #characterTable and characterTable[charNum].locked ~= LOCKED_TRUE then + force_set_character(charNum, altNum) djui_chat_message_create('Character set to "' .. characterTable[charNum][altNum].name .. '" Successfully!') return true end end + djui_chat_message_create("Character Not Found") return true end hook_chat_command("char-select", "- Opens the Character Select Menu", chat_command) - ---[[ -local function mod_menu_open_cs() - local m = gMarioStates[0] - if menu_is_allowed(m) then - gMarioStates[0].controller.buttonPressed = START_BUTTON - menu = true - else - play_sound(SOUND_MENU_CAMERA_BUZZ, m.pos) - end -end -hook_mod_menu_button("Open Menu", mod_menu_open_cs) -]] \ No newline at end of file diff --git a/mods/character-select-coop/z-moveset.lua b/mods/character-select-coop/moveset.lua similarity index 53% rename from mods/character-select-coop/z-moveset.lua rename to mods/character-select-coop/moveset.lua index ea5bc9087..9ef60a227 100644 --- a/mods/character-select-coop/z-moveset.lua +++ b/mods/character-select-coop/moveset.lua @@ -2,173 +2,245 @@ if incompatibleClient then return 0 end local function find_character_number(index) + if not startup_init_stall() then return 0 end if index == nil then index = 0 end for i = 1, #characterTable do if characterTable[i].saveName == gCSPlayers[index].saveName then return i end end - return 1 + return 0 +end + +local function is_moveset_restricted() + return gGlobalSyncTable.charSelectRestrictMovesets > 0 end local function mario_update(m) - if stopMovesets or not gCSPlayers[m.playerIndex].movesetToggle then return end + if is_moveset_restricted() or not gCSPlayers[m.playerIndex].movesetToggle then return end local hook = HOOK_MARIO_UPDATE local currMoveset = characterMovesets[find_character_number(m.playerIndex)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook](m) + local returnVar = currMoveset[hook](m) + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_MARIO_UPDATE, mario_update) local function before_mario_update(m) - if stopMovesets or not gCSPlayers[m.playerIndex].movesetToggle then return end + if is_moveset_restricted() or not gCSPlayers[m.playerIndex].movesetToggle then return end local hook = HOOK_BEFORE_MARIO_UPDATE local currMoveset = characterMovesets[find_character_number(m.playerIndex)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook](m) + local returnVar = currMoveset[hook](m) + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_BEFORE_MARIO_UPDATE, before_mario_update) -local function before_phys_step(m, stepType) - if stopMovesets or not gCSPlayers[m.playerIndex].movesetToggle then return end +local function before_phys_step(m, stepType, stepArg) + if is_moveset_restricted() or not gCSPlayers[m.playerIndex].movesetToggle then return end local hook = HOOK_BEFORE_PHYS_STEP local currMoveset = characterMovesets[find_character_number(m.playerIndex)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook](m, stepType) + local returnVar = currMoveset[hook](m, stepType, stepArg) + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_BEFORE_PHYS_STEP, before_phys_step) local function allow_pvp_attack(attacker, victim, int) - if stopMovesets then return end + if is_moveset_restricted() then return end local hook = HOOK_ALLOW_PVP_ATTACK local attackerMoveset = characterMovesets[find_character_number(attacker.playerIndex)] local victimMoveset = characterMovesets[find_character_number(victim.playerIndex)] + local returnVar if gCSPlayers[attacker.playerIndex].movesetToggle then if (attackerMoveset ~= nil and attackerMoveset[hook] ~= nil) then - attackerMoveset[hook](attacker, victim, int) + returnVar = attackerMoveset[hook](attacker, victim, int) + if returnVar ~= nil then + return returnVar + end end end if gCSPlayers[victim.playerIndex].movesetToggle then if (victimMoveset ~= nil and victimMoveset[hook] ~= nil) then - victimMoveset[hook](attacker, victim, int) + returnVar = victimMoveset[hook](attacker, victim, int) + if returnVar ~= nil then + return returnVar + end end end end hook_event(HOOK_ALLOW_PVP_ATTACK, allow_pvp_attack) local function on_pvp_attack(attacker, victim, int) - if stopMovesets then return end + if is_moveset_restricted() then return end local hook = HOOK_ON_PVP_ATTACK local attackerMoveset = characterMovesets[find_character_number(attacker.playerIndex)] local victimMoveset = characterMovesets[find_character_number(victim.playerIndex)] if gCSPlayers[attacker.playerIndex].movesetToggle then if (attackerMoveset ~= nil and attackerMoveset[hook] ~= nil) then - attackerMoveset[hook](attacker, victim, int) + local returnVar = attackerMoveset[hook](attacker, victim, int) + if returnVar ~= nil then + return returnVar + end end end if gCSPlayers[victim.playerIndex].movesetToggle then if (victimMoveset ~= nil and victimMoveset[hook] ~= nil) then - victimMoveset[hook](attacker, victim, int) + local returnVar = victimMoveset[hook](attacker, victim, int) + if returnVar ~= nil then + return returnVar + end end end end hook_event(HOOK_ON_PVP_ATTACK, on_pvp_attack) local function on_interact(m, o, intType, intValue) - if stopMovesets or not gCSPlayers[m.playerIndex].movesetToggle then return end + if is_moveset_restricted() or not gCSPlayers[m.playerIndex].movesetToggle then return end local hook = HOOK_ON_INTERACT local currMoveset = characterMovesets[find_character_number(m.playerIndex)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook](m, o, intType, intValue) + local returnVar = currMoveset[hook](m, o, intType, intValue) + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_ON_INTERACT, on_interact) local function allow_interact(m, o, intType) - if stopMovesets or not gCSPlayers[m.playerIndex].movesetToggle then return end + if is_moveset_restricted() or not gCSPlayers[m.playerIndex].movesetToggle then return end local hook = HOOK_ALLOW_INTERACT local currMoveset = characterMovesets[find_character_number(m.playerIndex)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook](m, o, intType) + local returnVar = currMoveset[hook](m, o, intType) + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_ALLOW_INTERACT, allow_interact) local function on_set_mario_action(m) - if stopMovesets or not gCSPlayers[m.playerIndex].movesetToggle then return end + if is_moveset_restricted() or not gCSPlayers[m.playerIndex].movesetToggle then return end local hook = HOOK_ON_SET_MARIO_ACTION local currMoveset = characterMovesets[find_character_number(m.playerIndex)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook](m) + local returnVar = currMoveset[hook](m) + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_ON_SET_MARIO_ACTION, on_set_mario_action) -local function before_set_mario_action(m, nextAct) - if stopMovesets or not gCSPlayers[m.playerIndex].movesetToggle then return end +local function before_set_mario_action(m, nextAct, actionArg) + if is_moveset_restricted() or not gCSPlayers[m.playerIndex].movesetToggle then return end local hook = HOOK_BEFORE_SET_MARIO_ACTION local currMoveset = characterMovesets[find_character_number(m.playerIndex)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook](m, nextAct) + local returnVar = currMoveset[hook](m, nextAct, actionArg) + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_BEFORE_SET_MARIO_ACTION, before_set_mario_action) local function on_death(m) - if stopMovesets or not gCSPlayers[m.playerIndex].movesetToggle then return end + if is_moveset_restricted() or not gCSPlayers[m.playerIndex].movesetToggle then return end local hook = HOOK_ON_DEATH local currMoveset = characterMovesets[find_character_number(m.playerIndex)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook](m) + local returnVar = currMoveset[hook](m) + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_ON_DEATH, on_death) local function hud_render() - if stopMovesets or not gCSPlayers[0].movesetToggle then return end + if is_moveset_restricted() or not gCSPlayers[0].movesetToggle then return end local hook = HOOK_ON_HUD_RENDER local currMoveset = characterMovesets[find_character_number(0)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook]() + local returnVar = currMoveset[hook]() + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_ON_HUD_RENDER, hud_render) local function hud_render_behind() - if stopMovesets or not gCSPlayers[0].movesetToggle then return end + if is_moveset_restricted() or not gCSPlayers[0].movesetToggle then return end local hook = HOOK_ON_HUD_RENDER_BEHIND local currMoveset = characterMovesets[find_character_number(0)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook]() + local returnVar = currMoveset[hook]() + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_ON_HUD_RENDER_BEHIND, hud_render_behind) -local function level_init() - if stopMovesets or not gCSPlayers[0].movesetToggle then return end +local function level_init(type, levelNum, areaIdx, nodeId, arg) + if is_moveset_restricted() or not gCSPlayers[0].movesetToggle then return end local hook = HOOK_ON_LEVEL_INIT local currMoveset = characterMovesets[find_character_number(0)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook]() + local returnVar = currMoveset[hook](type, levelNum, areaIdx, nodeId, arg) + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_ON_LEVEL_INIT, level_init) local function sync_valid() - if stopMovesets or not gCSPlayers[0].movesetToggle then return end + if is_moveset_restricted() or not gCSPlayers[0].movesetToggle then return end local hook = HOOK_ON_SYNC_VALID local currMoveset = characterMovesets[find_character_number(0)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook]() + local returnVar = currMoveset[hook]() + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_ON_SYNC_VALID, sync_valid) local function object_render(obj) - if stopMovesets or not gCSPlayers[0].movesetToggle then return end + if is_moveset_restricted() or not gCSPlayers[0].movesetToggle then return end local hook = HOOK_ON_OBJECT_RENDER local currMoveset = characterMovesets[find_character_number(0)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook](obj) + local returnVar = currMoveset[hook](obj) + if returnVar ~= nil then + return returnVar + end end hook_event(HOOK_ON_OBJECT_RENDER, object_render) local function allow_water_action(m, water) - if stopMovesets or not gCSPlayers[0].movesetToggle then return end + if is_moveset_restricted() or not gCSPlayers[0].movesetToggle then return end local hook = HOOK_ALLOW_FORCE_WATER_ACTION local currMoveset = characterMovesets[find_character_number(0)] if currMoveset == nil or currMoveset[hook] == nil then return end - return currMoveset[hook](m, water) + local returnVar = currMoveset[hook](m, water) + if returnVar ~= nil then + return returnVar + end end -hook_event(HOOK_ALLOW_FORCE_WATER_ACTION, allow_water_action) \ No newline at end of file +hook_event(HOOK_ALLOW_FORCE_WATER_ACTION, allow_water_action) + +local function mario_override_floor_class(m, floorClass) + if is_moveset_restricted() or not gCSPlayers[0].movesetToggle then return end + local hook = HOOK_ALLOW_FORCE_WATER_ACTION + local currMoveset = characterMovesets[find_character_number(0)] + if currMoveset == nil or currMoveset[hook] == nil then return end + local returnVar = currMoveset[hook](m, floorClass) + if returnVar ~= nil then + return returnVar + end +end +hook_event(HOOK_MARIO_OVERRIDE_FLOOR_CLASS, mario_override_floor_class) diff --git a/mods/character-select-coop/palettes.lua b/mods/character-select-coop/palettes.lua new file mode 100644 index 000000000..779d2ead0 --- /dev/null +++ b/mods/character-select-coop/palettes.lua @@ -0,0 +1,391 @@ +if incompatibleClient then return 0 end + +-- localize functions to improve performance - z-palettes.lua +local network_player_set_override_palette_color,network_player_reset_override_palette = network_player_set_override_palette_color,network_player_reset_override_palette + +characterColorPresets = { + [E_MODEL_MARIO] = { + currPalette = 1, + { + name = "Default", + [PANTS] = { r = 0x00, g = 0x00, b = 0xff }, + [SHIRT] = { r = 0xff, g = 0x00, b = 0x00 }, + [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, + [SHOES] = { r = 0x72, g = 0x1c, b = 0x0e }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, + [CAP] = { r = 0xff, g = 0x00, b = 0x00 }, + [EMBLEM] = { r = 0xff, g = 0x00, b = 0x00 }, + }, + { + name = "New Game +", + [PANTS] = { r = 0x19, g = 0x4b, b = 0xa3 }, + [SHIRT] = { r = 0xff, g = 0x30, b = 0x33 }, + [GLOVES] = { r = 0xdd, g = 0xdd, b = 0xdd }, + [SHOES] = { r = 0x51, g = 0x28, b = 0x00 }, + [HAIR] = { r = 0x58, g = 0x09, b = 0x00 }, + [SKIN] = { r = 0xff, g = 0xaf, b = 0x8c }, + [CAP] = { r = 0xff, g = 0x30, b = 0x33 }, + [EMBLEM] = { r = 0xff, g = 0x30, b = 0x33 }, + }, + { + name = "Fire Flower", + [PANTS] = { r = 0xb2, g = 0x28, b = 0x18 }, + [SHIRT] = { r = 0xff, g = 0xe0, b = 0xe0 }, + [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, + [SHOES] = { r = 0x72, g = 0x1c, b = 0x0e }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, + [CAP] = { r = 0xff, g = 0xe0, b = 0xe0 }, + [EMBLEM] = { r = 0xff, g = 0x00, b = 0x00 }, + }, + { + name = "Burgundy", + [PANTS] = { r = 0x23, g = 0x11, b = 0x03 }, + [SHIRT] = { r = 0x68, g = 0x0A, b = 0x17 }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x72, g = 0x1C, b = 0x0E }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0x68, g = 0x0A, b = 0x17 }, + [EMBLEM] = { r = 0x68, g = 0x0A, b = 0x17 }, + }, + { + name = "Raspberry", + [PANTS] = { r = 0xD6, g = 0x35, b = 0x4D }, + [SHIRT] = { r = 0x3B, g = 0x8F, b = 0xF7 }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x72, g = 0x1C, b = 0x0E }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0x3B, g = 0x8F, b = 0xF7 }, + [EMBLEM] = { r = 0x3B, g = 0x8F, b = 0xF7 }, + }, + + }, + [E_MODEL_LUIGI] = { + currPalette = 1, + { + name = "Default", + [PANTS] = { r = 0x00, g = 0x00, b = 0xff }, + [SHIRT] = { r = 0x00, g = 0xff, b = 0x00 }, + [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, + [SHOES] = { r = 0x72, g = 0x1c, b = 0x0e }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, + [CAP] = { r = 0x00, g = 0xff, b = 0x00 }, + [EMBLEM] = { r = 0x00, g = 0xff, b = 0x00 }, + }, + { + name = "Mint", + [PANTS] = { r = 0x53, g = 0x39, b = 0x3D }, + [SHIRT] = { r = 0x95, g = 0xD0, b = 0x8F }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x72, g = 0x1C, b = 0x0E }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0x95, g = 0xD0, b = 0x8F }, + [EMBLEM] = { r = 0x95, g = 0xD0, b = 0x8F }, + }, + { + name = "Cold Crevase", + [PANTS] = { r = 0xD4, g = 0xDF, b = 0xE7 }, + [SHIRT] = { r = 0x51, g = 0xA9, b = 0x9C }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x6B, g = 0x41, b = 0x00 }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0xD4, g = 0xDF, b = 0xE7 }, + [EMBLEM] = { r = 0x51, g = 0xA9, b = 0x9C }, + }, + { + name = "Greedy", + [PANTS] = { r = 0x00, g = 0x48, b = 0x8a }, + [SHIRT] = { r = 0xf7, g = 0xaf, b = 0x25 }, + [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, + [SHOES] = { r = 0xc0, g = 0x21, b = 0x00 }, + [HAIR] = { r = 0x00, g = 0x00, b = 0x00 }, + [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, + [CAP] = { r = 0x00, g = 0x48, b = 0x8a }, + [EMBLEM] = { r = 0x00, g = 0x00, b = 0x00 }, + }, + { + name = "Kindness", + [PANTS] = { r = 0xff, g = 0x44, b = 0xff }, + [SHIRT] = { r = 0x93, g = 0x00, b = 0x90 }, + [GLOVES] = { r = 0xff, g = 0x99, b = 0xff }, + [SHOES] = { r = 0xaa, g = 0x2c, b = 0x66 }, + [HAIR] = { r = 0xf3, g = 0x65, b = 0xda }, + [SKIN] = { r = 0xc8, g = 0x6b, b = 0x9d }, + [CAP] = { r = 0xef, g = 0x2b, b = 0xea }, + [EMBLEM] = { r = 0xef, g = 0x2b, b = 0xea }, + }, + }, + [E_MODEL_TOAD_PLAYER] = { + currPalette = 1, + { + name = "Default", + [PANTS] = { r = 0xff, g = 0xff, b = 0xff }, + [SHIRT] = { r = 0x4c, g = 0x2c, b = 0xd3 }, + [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, + [SHOES] = { r = 0x68, g = 0x40, b = 0x1b }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xfe, g = 0xd5, b = 0xa1 }, + [CAP] = { r = 0xff, g = 0x00, b = 0x00 }, + [EMBLEM] = { r = 0xff, g = 0x00, b = 0x00 }, + }, + { + name = "Bucken Berry", + [PANTS] = { r = 0xff, g = 0xff, b = 0xff }, + [SHIRT] = { r = 0x00, g = 0x00, b = 0xff }, + [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, + [SHOES] = { r = 0x68, g = 0x40, b = 0x1b }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xfe, g = 0xd5, b = 0xa1 }, + [CAP] = { r = 0x00, g = 0x00, b = 0xff }, + [EMBLEM] = { r = 0x00, g = 0x00, b = 0xff }, + }, + { + name = "Ala Gold", + [PANTS] = { r = 0xff, g = 0xff, b = 0xff }, + [SHIRT] = { r = 0xff, g = 0xff, b = 0x00 }, + [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, + [SHOES] = { r = 0x68, g = 0x40, b = 0x1b }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xfe, g = 0xd5, b = 0xa1 }, + [CAP] = { r = 0xff, g = 0xff, b = 0x00 }, + [EMBLEM] = { r = 0xff, g = 0xff, b = 0x00 }, + }, + { + name = "Jet Black", + [PANTS] = { r = 0x1A, g = 0x1A, b = 0x1A }, + [SHIRT] = { r = 0x2C, g = 0x2C, b = 0x2C }, + [GLOVES] = { r = 0x64, g = 0x64, b = 0x64 }, + [SHOES] = { r = 0x64, g = 0x64, b = 0x64 }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0x1A, g = 0x1A, b = 0x1A }, + [EMBLEM] = { r = 0x1A, g = 0x1A, b = 0x1A }, + }, + { + name = "Hot Pink", + [PANTS] = { r = 0x34, g = 0x16, b = 0x0D }, + [SHIRT] = { r = 0xC1, g = 0x2C, b = 0x72 }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x72, g = 0x1C, b = 0x0E }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0xC1, g = 0x2C, b = 0x72 }, + [EMBLEM] = { r = 0xC1, g = 0x2C, b = 0x72 }, + }, + { + name = "Goomba", + [PANTS] = { r = 0xC6, g = 0xB1, b = 0x32 }, + [SHIRT] = { r = 0x95, g = 0x43, b = 0x01 }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x72, g = 0x1C, b = 0x0E }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0x95, g = 0x43, b = 0x01 }, + [EMBLEM] = { r = 0x95, g = 0x43, b = 0x01 }, + }, + + }, + [E_MODEL_WALUIGI] = { + currPalette = 1, + { + name = "Default", + [PANTS] = { r = 0x16, g = 0x16, b = 0x27 }, + [SHIRT] = { r = 0x61, g = 0x26, b = 0xb0 }, + [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, + [SHOES] = { r = 0xfe, g = 0x76, b = 0x00 }, + [HAIR] = { r = 0x73, g = 0x53, b = 0x00 }, + [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, + [CAP] = { r = 0x61, g = 0x26, b = 0xb0 }, + [EMBLEM] = { r = 0xff, g = 0xde, b = 0x00 }, + }, + { + name = "Cobalt", + [PANTS] = { r = 0x3F, g = 0x3F, b = 0xFF }, + [SHIRT] = { r = 0x0A, g = 0x0A, b = 0x28 }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x39, g = 0x0E, b = 0x07 }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0x3F, g = 0x3F, b = 0xFF }, + [EMBLEM] = { r = 0x3F, g = 0x3F, b = 0xFF }, + }, + { + name = "Clover", + [PANTS] = { r = 0x14, g = 0x19, b = 0x14 }, + [SHIRT] = { r = 0x4C, g = 0x5F, b = 0x20 }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x72, g = 0x1C, b = 0x0E }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0x4C, g = 0x5F, b = 0x20 }, + [EMBLEM] = { r = 0x4C, g = 0x5F, b = 0x20 }, + }, + { + name = "Blueberry Pie", + [PANTS] = { r = 0xEB, g = 0x8A, b = 0x4B }, + [SHIRT] = { r = 0x10, g = 0x1B, b = 0x2E }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x72, g = 0x1C, b = 0x0E }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0x10, g = 0x1B, b = 0x2E }, + [EMBLEM] = { r = 0x10, g = 0x1B, b = 0x2E }, + }, + { + name = "Tennis Loser", + [PANTS] = { r = 0x16, g = 0x16, b = 0x27 }, + [SHIRT] = { r = 0x5A, g = 0x39, b = 0x21 }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x5A, g = 0x00, b = 0xCE }, + [HAIR] = { r = 0x29, g = 0x10, b = 0x00 }, + [SKIN] = { r = 0xE7, g = 0xB5, b = 0x94 }, + [CAP] = { r = 0x5A, g = 0x39, b = 0x21 }, + [EMBLEM] = { r = 0xFF, g = 0xDE, b = 0x00 }, + }, + { + name = "Sealed Away", + [PANTS] = { r = 0x00, g = 0x98, b = 0x00 }, + [SHIRT] = { r = 0x47, g = 0xc5, b = 0xff }, + [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, + [SHOES] = { r = 0x72, g = 0x1c, b = 0x0e }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, + [CAP] = { r = 0x47, g = 0xc5, b = 0xff }, + [EMBLEM] = { r = 0xff, g = 0xde, b = 0x00 }, + }, + + }, + [E_MODEL_WARIO] = { + currPalette = 1, + { + name = "Default", + [PANTS] = { r = 0x7f, g = 0x20, b = 0x7a }, + [SHIRT] = { r = 0xff, g = 0xbd, b = 0x00 }, + [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, + [SHOES] = { r = 0x0e, g = 0x72, b = 0x1c }, + [HAIR] = { r = 0x73, g = 0x53, b = 0x00 }, + [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, + [CAP] = { r = 0xff, g = 0xbd, b = 0x00 }, + [EMBLEM] = { r = 0x00, g = 0x00, b = 0xff }, + }, + { + name = "Ruby", + [PANTS] = { r = 0xE1, g = 0x05, b = 0x31 }, + [SHIRT] = { r = 0x28, g = 0x0A, b = 0x0A }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x39, g = 0x0E, b = 0x07 }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0xE1, g = 0x05, b = 0x31 }, + [EMBLEM] = { r = 0xE1, g = 0x05, b = 0x31 }, + }, + { + name = "Eggplant", + [PANTS] = { r = 0xE6, g = 0xE3, b = 0xFF }, + [SHIRT] = { r = 0x37, g = 0x32, b = 0x42 }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x72, g = 0x1C, b = 0x0E }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0x37, g = 0x32, b = 0x42 }, + [EMBLEM] = { r = 0x37, g = 0x32, b = 0x42 }, + }, + { + name = "Battlements", + [PANTS] = { r = 0xF7, g = 0xC2, b = 0x45 }, + [SHIRT] = { r = 0x55, g = 0x92, b = 0xB2 }, + [GLOVES] = { r = 0xFF, g = 0xFF, b = 0xFF }, + [SHOES] = { r = 0x72, g = 0x1C, b = 0x0E }, + [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, + [SKIN] = { r = 0xFE, g = 0xC1, b = 0x79 }, + [CAP] = { r = 0x55, g = 0x92, b = 0xB2 }, + [EMBLEM] = { r = 0x55, g = 0x92, b = 0xB2 }, + }, + { + name = "Cotten Candy", + [PANTS] = { r = 0x69, g = 0xa1, b = 0xff }, + [SHIRT] = { r = 0xff, g = 0x7d, b = 0x89 }, + [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, + [SHOES] = { r = 0xb9, g = 0x48, b = 0xff }, + [HAIR] = { r = 0x73, g = 0x53, b = 0x00 }, + [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, + [CAP] = { r = 0x69, g = 0xa1, b = 0xff }, + [EMBLEM] = { r = 0xb9, g = 0x48, b = 0xff }, + }, + } +} + +local paletteLoop = #characterColorPresets[E_MODEL_MARIO][1] + +local function network_player_set_full_override_palette(networkPlayer, colorTable) + if colorTable == nil then return end + for i = 0, paletteLoop do + network_player_set_override_palette_color(networkPlayer, i, colorTable[i]) + end +end + +---@param np NetworkPlayer +function update_preset_palette(np) + local p = gCSPlayers[np.localIndex] + local modelId = p.modelId + if np.connected and gCSPlayers[0].presetPalette > 0 and characterColorPresets[modelId] and gGlobalSyncTable.charSelectRestrictPalettes == 0 then + network_player_set_full_override_palette(np, characterColorPresets[modelId][p.presetPalette]) + end +end + +local prevPresetPalette = {} +local prevModel = {} + +local function mario_update(m) + local np = gNetworkPlayers[m.playerIndex] + local p = gCSPlayers[m.playerIndex] + if not startup_init_stall() then return end + + if m.playerIndex == 0 and not p.isUpdating then + p.isUpdating = true + for i = 1, MAX_PLAYERS - 1 do + prevPresetPalette[i] = gCSPlayers[i].presetPalette + prevModel[i] = gCSPlayers[i].modelId + end + end + + if m.playerIndex == 0 then + if gGlobalSyncTable.charSelectRestrictPalettes == 0 then + gCSPlayers[0].presetPalette = characterColorPresets[gCSPlayers[0].modelId] ~= nil and characterColorPresets[gCSPlayers[0].modelId].currPalette or 0 + end + end + + if np.connected then + if p.presetPalette == nil or characterColorPresets[p.modelId] == nil then + if p.presetPalette == nil then + prevPresetPalette[m.playerIndex] = 0 + end + p.presetPalette = 0 + end + + if (prevPresetPalette[m.playerIndex] ~= p.presetPalette or prevModel[m.playerIndex] ~= p.modelId) then + if p.presetPalette == 0 or not characterColorPresets[p.modelId] then + network_player_reset_override_palette(np) + end + end + + prevPresetPalette[m.playerIndex] = p.presetPalette + prevModel[m.playerIndex] = p.modelId + + if p.presetPalette > 0 and characterColorPresets[p.modelId] and gGlobalSyncTable.charSelectRestrictPalettes == 0 then + network_player_set_full_override_palette(np, characterColorPresets[p.modelId][p.presetPalette]) + end + else + if p.isUpdating then + p.isUpdating = false + end + end +end + +hook_event(HOOK_MARIO_UPDATE, mario_update) diff --git a/mods/character-select-coop/sound/00_waluigi_jump_hoo.aiff b/mods/character-select-coop/sound/00_waluigi_jump_hoo.aiff new file mode 100644 index 000000000..78c4055e6 Binary files /dev/null and b/mods/character-select-coop/sound/00_waluigi_jump_hoo.aiff differ diff --git a/mods/character-select-coop/sound/00_waluigi_waaaooow.aiff b/mods/character-select-coop/sound/00_waluigi_waaaooow.aiff new file mode 100644 index 000000000..877c49398 Binary files /dev/null and b/mods/character-select-coop/sound/00_waluigi_waaaooow.aiff differ diff --git a/mods/character-select-coop/sound/01_waluigi_hoohoo.aiff b/mods/character-select-coop/sound/01_waluigi_hoohoo.aiff new file mode 100644 index 000000000..2ef1f6918 Binary files /dev/null and b/mods/character-select-coop/sound/01_waluigi_hoohoo.aiff differ diff --git a/mods/character-select-coop/sound/01_waluigi_jump_wah.aiff b/mods/character-select-coop/sound/01_waluigi_jump_wah.aiff new file mode 100644 index 000000000..ad4f2dd2b Binary files /dev/null and b/mods/character-select-coop/sound/01_waluigi_jump_wah.aiff differ diff --git a/mods/character-select-coop/sound/02_waluigi_panting.aiff b/mods/character-select-coop/sound/02_waluigi_panting.aiff new file mode 100644 index 000000000..7e85371a0 Binary files /dev/null and b/mods/character-select-coop/sound/02_waluigi_panting.aiff differ diff --git a/mods/character-select-coop/sound/02_waluigi_yah.aiff b/mods/character-select-coop/sound/02_waluigi_yah.aiff new file mode 100644 index 000000000..c3ac89a9b Binary files /dev/null and b/mods/character-select-coop/sound/02_waluigi_yah.aiff differ diff --git a/mods/character-select-coop/sound/03_waluigi_dying.aiff b/mods/character-select-coop/sound/03_waluigi_dying.aiff new file mode 100644 index 000000000..0eed8f920 Binary files /dev/null and b/mods/character-select-coop/sound/03_waluigi_dying.aiff differ diff --git a/mods/character-select-coop/sound/03_waluigi_haha.aiff b/mods/character-select-coop/sound/03_waluigi_haha.aiff new file mode 100644 index 000000000..2452e58c2 Binary files /dev/null and b/mods/character-select-coop/sound/03_waluigi_haha.aiff differ diff --git a/mods/character-select-coop/sound/04_waluigi_on_fire.aiff b/mods/character-select-coop/sound/04_waluigi_on_fire.aiff new file mode 100644 index 000000000..381e143e9 Binary files /dev/null and b/mods/character-select-coop/sound/04_waluigi_on_fire.aiff differ diff --git a/mods/character-select-coop/sound/04_waluigi_yahoo.aiff b/mods/character-select-coop/sound/04_waluigi_yahoo.aiff new file mode 100644 index 000000000..386ff8b0c Binary files /dev/null and b/mods/character-select-coop/sound/04_waluigi_yahoo.aiff differ diff --git a/mods/character-select-coop/sound/05_waluigi_uh.aiff b/mods/character-select-coop/sound/05_waluigi_uh.aiff new file mode 100644 index 000000000..5f42e68ba Binary files /dev/null and b/mods/character-select-coop/sound/05_waluigi_uh.aiff differ diff --git a/mods/character-select-coop/sound/05_waluigi_uh2.aiff b/mods/character-select-coop/sound/05_waluigi_uh2.aiff new file mode 100644 index 000000000..0a3632979 Binary files /dev/null and b/mods/character-select-coop/sound/05_waluigi_uh2.aiff differ diff --git a/mods/character-select-coop/sound/06_waluigi_coughing.aiff b/mods/character-select-coop/sound/06_waluigi_coughing.aiff new file mode 100644 index 000000000..7a1efc6e3 Binary files /dev/null and b/mods/character-select-coop/sound/06_waluigi_coughing.aiff differ diff --git a/mods/character-select-coop/sound/06_waluigi_hrmm.aiff b/mods/character-select-coop/sound/06_waluigi_hrmm.aiff new file mode 100644 index 000000000..0335421d6 Binary files /dev/null and b/mods/character-select-coop/sound/06_waluigi_hrmm.aiff differ diff --git a/mods/character-select-coop/sound/07_waluigi_its_a_me_mario.aiff b/mods/character-select-coop/sound/07_waluigi_its_a_me_mario.aiff new file mode 100644 index 000000000..86303bf2b Binary files /dev/null and b/mods/character-select-coop/sound/07_waluigi_its_a_me_mario.aiff differ diff --git a/mods/character-select-coop/sound/07_waluigi_wah2.aiff b/mods/character-select-coop/sound/07_waluigi_wah2.aiff new file mode 100644 index 000000000..891804a47 Binary files /dev/null and b/mods/character-select-coop/sound/07_waluigi_wah2.aiff differ diff --git a/mods/character-select-coop/sound/08_waluigi_punch_yah.aiff b/mods/character-select-coop/sound/08_waluigi_punch_yah.aiff new file mode 100644 index 000000000..cc5399d62 Binary files /dev/null and b/mods/character-select-coop/sound/08_waluigi_punch_yah.aiff differ diff --git a/mods/character-select-coop/sound/08_waluigi_whoa.aiff b/mods/character-select-coop/sound/08_waluigi_whoa.aiff new file mode 100644 index 000000000..e8d0b493f Binary files /dev/null and b/mods/character-select-coop/sound/08_waluigi_whoa.aiff differ diff --git a/mods/character-select-coop/sound/09_waluigi_eeuh.aiff b/mods/character-select-coop/sound/09_waluigi_eeuh.aiff new file mode 100644 index 000000000..c353bc689 Binary files /dev/null and b/mods/character-select-coop/sound/09_waluigi_eeuh.aiff differ diff --git a/mods/character-select-coop/sound/09_waluigi_punch_hoo.aiff b/mods/character-select-coop/sound/09_waluigi_punch_hoo.aiff new file mode 100644 index 000000000..8cf50f618 Binary files /dev/null and b/mods/character-select-coop/sound/09_waluigi_punch_hoo.aiff differ diff --git a/mods/character-select-coop/sound/0A_waluigi_attacked.aiff b/mods/character-select-coop/sound/0A_waluigi_attacked.aiff new file mode 100644 index 000000000..eea71e9ca Binary files /dev/null and b/mods/character-select-coop/sound/0A_waluigi_attacked.aiff differ diff --git a/mods/character-select-coop/sound/0A_waluigi_mama_mia.aiff b/mods/character-select-coop/sound/0A_waluigi_mama_mia.aiff new file mode 100644 index 000000000..7d5b3594d Binary files /dev/null and b/mods/character-select-coop/sound/0A_waluigi_mama_mia.aiff differ diff --git a/mods/character-select-coop/sound/0B_waluigi_okey_dokey.aiff b/mods/character-select-coop/sound/0B_waluigi_okey_dokey.aiff new file mode 100644 index 000000000..d020e3c9a Binary files /dev/null and b/mods/character-select-coop/sound/0B_waluigi_okey_dokey.aiff differ diff --git a/mods/character-select-coop/sound/0B_waluigi_ooof.aiff b/mods/character-select-coop/sound/0B_waluigi_ooof.aiff new file mode 100644 index 000000000..258e4d1a2 Binary files /dev/null and b/mods/character-select-coop/sound/0B_waluigi_ooof.aiff differ diff --git a/mods/character-select-coop/sound/0C_waluigi_drowning.aiff b/mods/character-select-coop/sound/0C_waluigi_drowning.aiff new file mode 100644 index 000000000..40a5f31ed Binary files /dev/null and b/mods/character-select-coop/sound/0C_waluigi_drowning.aiff differ diff --git a/mods/character-select-coop/sound/0C_waluigi_here_we_go.aiff b/mods/character-select-coop/sound/0C_waluigi_here_we_go.aiff new file mode 100644 index 000000000..32fb36905 Binary files /dev/null and b/mods/character-select-coop/sound/0C_waluigi_here_we_go.aiff differ diff --git a/mods/character-select-coop/sound/0D_waluigi_thank_you_playing_my_game.aiff b/mods/character-select-coop/sound/0D_waluigi_thank_you_playing_my_game.aiff new file mode 100644 index 000000000..f014b950b Binary files /dev/null and b/mods/character-select-coop/sound/0D_waluigi_thank_you_playing_my_game.aiff differ diff --git a/mods/character-select-coop/sound/0D_waluigi_yawning.aiff b/mods/character-select-coop/sound/0D_waluigi_yawning.aiff new file mode 100644 index 000000000..ecabd0d4c Binary files /dev/null and b/mods/character-select-coop/sound/0D_waluigi_yawning.aiff differ diff --git a/mods/character-select-coop/sound/0E_waluigi_snoring1.aiff b/mods/character-select-coop/sound/0E_waluigi_snoring1.aiff new file mode 100644 index 000000000..069878bf1 Binary files /dev/null and b/mods/character-select-coop/sound/0E_waluigi_snoring1.aiff differ diff --git a/mods/character-select-coop/sound/0F_waluigi_snoring2.aiff b/mods/character-select-coop/sound/0F_waluigi_snoring2.aiff new file mode 100644 index 000000000..a57f3c8cb Binary files /dev/null and b/mods/character-select-coop/sound/0F_waluigi_snoring2.aiff differ diff --git a/mods/character-select-coop/sound/10_waluigi_doh.aiff b/mods/character-select-coop/sound/10_waluigi_doh.aiff new file mode 100644 index 000000000..94f22e3be Binary files /dev/null and b/mods/character-select-coop/sound/10_waluigi_doh.aiff differ diff --git a/mods/character-select-coop/sound/11_waluigi_game_over.aiff b/mods/character-select-coop/sound/11_waluigi_game_over.aiff new file mode 100644 index 000000000..bd70bc2dc Binary files /dev/null and b/mods/character-select-coop/sound/11_waluigi_game_over.aiff differ diff --git a/mods/character-select-coop/sound/12_waluigi_hello.aiff b/mods/character-select-coop/sound/12_waluigi_hello.aiff new file mode 100644 index 000000000..e3defaf7d Binary files /dev/null and b/mods/character-select-coop/sound/12_waluigi_hello.aiff differ diff --git a/mods/character-select-coop/sound/13_waluigi_press_start_to_play.aiff b/mods/character-select-coop/sound/13_waluigi_press_start_to_play.aiff new file mode 100644 index 000000000..5d8aebd3c Binary files /dev/null and b/mods/character-select-coop/sound/13_waluigi_press_start_to_play.aiff differ diff --git a/mods/character-select-coop/sound/14_waluigi_twirl_bounce.aiff b/mods/character-select-coop/sound/14_waluigi_twirl_bounce.aiff new file mode 100644 index 000000000..a0a60e296 Binary files /dev/null and b/mods/character-select-coop/sound/14_waluigi_twirl_bounce.aiff differ diff --git a/mods/character-select-coop/sound/15_waluigi_snoring3.aiff b/mods/character-select-coop/sound/15_waluigi_snoring3.aiff new file mode 100644 index 000000000..04c5a4390 Binary files /dev/null and b/mods/character-select-coop/sound/15_waluigi_snoring3.aiff differ diff --git a/mods/character-select-coop/sound/16_waluigi_so_longa_bowser.aiff b/mods/character-select-coop/sound/16_waluigi_so_longa_bowser.aiff new file mode 100644 index 000000000..e9ef5989f Binary files /dev/null and b/mods/character-select-coop/sound/16_waluigi_so_longa_bowser.aiff differ diff --git a/mods/character-select-coop/sound/17_waluigi_tired.aiff b/mods/character-select-coop/sound/17_waluigi_tired.aiff new file mode 100644 index 000000000..9c61ce7b5 Binary files /dev/null and b/mods/character-select-coop/sound/17_waluigi_tired.aiff differ diff --git a/mods/character-select-coop/sound/18_waluigi_waha.aiff b/mods/character-select-coop/sound/18_waluigi_waha.aiff new file mode 100644 index 000000000..397c7c0ce Binary files /dev/null and b/mods/character-select-coop/sound/18_waluigi_waha.aiff differ diff --git a/mods/character-select-coop/sound/19_waluigi_yippee.aiff b/mods/character-select-coop/sound/19_waluigi_yippee.aiff new file mode 100644 index 000000000..26a1883e3 Binary files /dev/null and b/mods/character-select-coop/sound/19_waluigi_yippee.aiff differ diff --git a/mods/character-select-coop/sound/1A_waluigi_lets_a_go.aiff b/mods/character-select-coop/sound/1A_waluigi_lets_a_go.aiff new file mode 100644 index 000000000..38d5d2193 Binary files /dev/null and b/mods/character-select-coop/sound/1A_waluigi_lets_a_go.aiff differ diff --git a/mods/character-select-coop/sound/char_select_dial_wind.ogg b/mods/character-select-coop/sound/char_select_dial_wind.ogg new file mode 100644 index 000000000..624c841c0 Binary files /dev/null and b/mods/character-select-coop/sound/char_select_dial_wind.ogg differ diff --git a/mods/character-select-coop/sound/char_select_menu_theme.ogg b/mods/character-select-coop/sound/char_select_menu_theme.ogg new file mode 100644 index 000000000..4de7bd194 Binary files /dev/null and b/mods/character-select-coop/sound/char_select_menu_theme.ogg differ diff --git a/mods/character-select-coop/textures/char-select-luigi-meter-left.tex b/mods/character-select-coop/textures/char-select-luigi-meter-left.tex deleted file mode 100644 index 08c151266..000000000 Binary files a/mods/character-select-coop/textures/char-select-luigi-meter-left.tex and /dev/null differ diff --git a/mods/character-select-coop/textures/char-select-luigi-meter-right.tex b/mods/character-select-coop/textures/char-select-luigi-meter-right.tex deleted file mode 100644 index 5fabcaab5..000000000 Binary files a/mods/character-select-coop/textures/char-select-luigi-meter-right.tex and /dev/null differ diff --git a/mods/character-select-coop/textures/char-select-text.tex b/mods/character-select-coop/textures/char-select-text.tex deleted file mode 100644 index f679a2db4..000000000 Binary files a/mods/character-select-coop/textures/char-select-text.tex and /dev/null differ diff --git a/mods/character-select-coop/textures/char-select-toad-meter-left.tex b/mods/character-select-coop/textures/char-select-toad-meter-left.tex deleted file mode 100644 index b2dcc45c9..000000000 Binary files a/mods/character-select-coop/textures/char-select-toad-meter-left.tex and /dev/null differ diff --git a/mods/character-select-coop/textures/char-select-toad-meter-right.tex b/mods/character-select-coop/textures/char-select-toad-meter-right.tex deleted file mode 100644 index b796d4495..000000000 Binary files a/mods/character-select-coop/textures/char-select-toad-meter-right.tex and /dev/null differ diff --git a/mods/character-select-coop/textures/char-select-triangle.tex b/mods/character-select-coop/textures/char-select-triangle.tex deleted file mode 100644 index 339ea23de..000000000 Binary files a/mods/character-select-coop/textures/char-select-triangle.tex and /dev/null differ diff --git a/mods/character-select-coop/textures/char-select-waluigi-meter-left.tex b/mods/character-select-coop/textures/char-select-waluigi-meter-left.tex deleted file mode 100644 index 800402e81..000000000 Binary files a/mods/character-select-coop/textures/char-select-waluigi-meter-left.tex and /dev/null differ diff --git a/mods/character-select-coop/textures/char-select-waluigi-meter-right.tex b/mods/character-select-coop/textures/char-select-waluigi-meter-right.tex deleted file mode 100644 index a6dff0e79..000000000 Binary files a/mods/character-select-coop/textures/char-select-waluigi-meter-right.tex and /dev/null differ diff --git a/mods/character-select-coop/textures/char-select-wario-meter-left.tex b/mods/character-select-coop/textures/char-select-wario-meter-left.tex deleted file mode 100644 index c36242673..000000000 Binary files a/mods/character-select-coop/textures/char-select-wario-meter-left.tex and /dev/null differ diff --git a/mods/character-select-coop/textures/char-select-wario-meter-right.tex b/mods/character-select-coop/textures/char-select-wario-meter-right.tex deleted file mode 100644 index 41e0f7119..000000000 Binary files a/mods/character-select-coop/textures/char-select-wario-meter-right.tex and /dev/null differ diff --git a/mods/character-select-coop/textures/char_select_album_back.tex b/mods/character-select-coop/textures/char_select_album_back.tex new file mode 100644 index 000000000..4294d3bb3 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_album_back.tex differ diff --git a/mods/character-select-coop/textures/char_select_album_front.tex b/mods/character-select-coop/textures/char_select_album_front.tex new file mode 100644 index 000000000..36d5d728a Binary files /dev/null and b/mods/character-select-coop/textures/char_select_album_front.tex differ diff --git a/mods/character-select-coop/textures/char_select_album_overlay.tex b/mods/character-select-coop/textures/char_select_album_overlay.tex new file mode 100644 index 000000000..40a4c8fa6 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_album_overlay.tex differ diff --git a/mods/character-select-coop/textures/char_select_category.tex b/mods/character-select-coop/textures/char_select_category.tex new file mode 100644 index 000000000..bdfdc1380 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_category.tex differ diff --git a/mods/character-select-coop/textures/char_select_caution_tape.tex b/mods/character-select-coop/textures/char_select_caution_tape.tex new file mode 100644 index 000000000..e4ec0292a Binary files /dev/null and b/mods/character-select-coop/textures/char_select_caution_tape.tex differ diff --git a/mods/character-select-coop/textures/char_select_cd_layer1.tex b/mods/character-select-coop/textures/char_select_cd_layer1.tex new file mode 100644 index 000000000..a4ef216aa Binary files /dev/null and b/mods/character-select-coop/textures/char_select_cd_layer1.tex differ diff --git a/mods/character-select-coop/textures/char_select_cd_layer2.tex b/mods/character-select-coop/textures/char_select_cd_layer2.tex new file mode 100644 index 000000000..5366e59b2 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_cd_layer2.tex differ diff --git a/mods/character-select-coop/textures/char_select_cd_layer3.tex b/mods/character-select-coop/textures/char_select_cd_layer3.tex new file mode 100644 index 000000000..0c063241f Binary files /dev/null and b/mods/character-select-coop/textures/char_select_cd_layer3.tex differ diff --git a/mods/character-select-coop/textures/char_select_cd_layer4.tex b/mods/character-select-coop/textures/char_select_cd_layer4.tex new file mode 100644 index 000000000..546654433 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_cd_layer4.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-course-bottom.tex b/mods/character-select-coop/textures/char_select_custom_course_bottom.tex similarity index 98% rename from mods/character-select-coop/textures/char-select-custom-course-bottom.tex rename to mods/character-select-coop/textures/char_select_custom_course_bottom.tex index 05ed93274..a947596f2 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-course-bottom.tex and b/mods/character-select-coop/textures/char_select_custom_course_bottom.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-course-top.tex b/mods/character-select-coop/textures/char_select_custom_course_top.tex similarity index 99% rename from mods/character-select-coop/textures/char-select-custom-course-top.tex rename to mods/character-select-coop/textures/char_select_custom_course_top.tex index 259fc4f16..4e0a07de0 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-course-top.tex and b/mods/character-select-coop/textures/char_select_custom_course_top.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-meter-left.tex b/mods/character-select-coop/textures/char_select_custom_meter_left.tex similarity index 97% rename from mods/character-select-coop/textures/char-select-custom-meter-left.tex rename to mods/character-select-coop/textures/char_select_custom_meter_left.tex index 228d3d0d5..2e6fe7821 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-meter-left.tex and b/mods/character-select-coop/textures/char_select_custom_meter_left.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-meter-pie1.tex b/mods/character-select-coop/textures/char_select_custom_meter_pie1.tex similarity index 96% rename from mods/character-select-coop/textures/char-select-custom-meter-pie1.tex rename to mods/character-select-coop/textures/char_select_custom_meter_pie1.tex index a835772fc..6e1925084 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-meter-pie1.tex and b/mods/character-select-coop/textures/char_select_custom_meter_pie1.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-meter-pie2.tex b/mods/character-select-coop/textures/char_select_custom_meter_pie2.tex similarity index 96% rename from mods/character-select-coop/textures/char-select-custom-meter-pie2.tex rename to mods/character-select-coop/textures/char_select_custom_meter_pie2.tex index bcd8e25b5..7dd6de86d 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-meter-pie2.tex and b/mods/character-select-coop/textures/char_select_custom_meter_pie2.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-meter-pie3.tex b/mods/character-select-coop/textures/char_select_custom_meter_pie3.tex similarity index 96% rename from mods/character-select-coop/textures/char-select-custom-meter-pie3.tex rename to mods/character-select-coop/textures/char_select_custom_meter_pie3.tex index 18e45d7b9..1309ea3e9 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-meter-pie3.tex and b/mods/character-select-coop/textures/char_select_custom_meter_pie3.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-meter-pie4.tex b/mods/character-select-coop/textures/char_select_custom_meter_pie4.tex similarity index 96% rename from mods/character-select-coop/textures/char-select-custom-meter-pie4.tex rename to mods/character-select-coop/textures/char_select_custom_meter_pie4.tex index 3fd474be7..86ffca8cb 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-meter-pie4.tex and b/mods/character-select-coop/textures/char_select_custom_meter_pie4.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-meter-pie5.tex b/mods/character-select-coop/textures/char_select_custom_meter_pie5.tex similarity index 96% rename from mods/character-select-coop/textures/char-select-custom-meter-pie5.tex rename to mods/character-select-coop/textures/char_select_custom_meter_pie5.tex index 3fb01c880..4cd145b57 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-meter-pie5.tex and b/mods/character-select-coop/textures/char_select_custom_meter_pie5.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-meter-pie6.tex b/mods/character-select-coop/textures/char_select_custom_meter_pie6.tex similarity index 96% rename from mods/character-select-coop/textures/char-select-custom-meter-pie6.tex rename to mods/character-select-coop/textures/char_select_custom_meter_pie6.tex index fbf2f59d5..c20718be8 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-meter-pie6.tex and b/mods/character-select-coop/textures/char_select_custom_meter_pie6.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-meter-pie7.tex b/mods/character-select-coop/textures/char_select_custom_meter_pie7.tex similarity index 97% rename from mods/character-select-coop/textures/char-select-custom-meter-pie7.tex rename to mods/character-select-coop/textures/char_select_custom_meter_pie7.tex index 2c9e6c634..b9eab15fb 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-meter-pie7.tex and b/mods/character-select-coop/textures/char_select_custom_meter_pie7.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-meter-pie8.tex b/mods/character-select-coop/textures/char_select_custom_meter_pie8.tex similarity index 97% rename from mods/character-select-coop/textures/char-select-custom-meter-pie8.tex rename to mods/character-select-coop/textures/char_select_custom_meter_pie8.tex index 07acd535b..ecb1b59d6 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-meter-pie8.tex and b/mods/character-select-coop/textures/char_select_custom_meter_pie8.tex differ diff --git a/mods/character-select-coop/textures/char-select-custom-meter-right.tex b/mods/character-select-coop/textures/char_select_custom_meter_right.tex similarity index 97% rename from mods/character-select-coop/textures/char-select-custom-meter-right.tex rename to mods/character-select-coop/textures/char_select_custom_meter_right.tex index 94047be19..ce552f94d 100644 Binary files a/mods/character-select-coop/textures/char-select-custom-meter-right.tex and b/mods/character-select-coop/textures/char_select_custom_meter_right.tex differ diff --git a/mods/character-select-coop/textures/char_select_font_brick.tex b/mods/character-select-coop/textures/char_select_font_brick.tex new file mode 100644 index 000000000..ec9dfa3b1 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_font_brick.tex differ diff --git a/mods/character-select-coop/textures/char_select_font_characteristic.tex b/mods/character-select-coop/textures/char_select_font_characteristic.tex new file mode 100644 index 000000000..f4f785bcf Binary files /dev/null and b/mods/character-select-coop/textures/char_select_font_characteristic.tex differ diff --git a/mods/character-select-coop/textures/char_select_gear.tex b/mods/character-select-coop/textures/char_select_gear.tex new file mode 100644 index 000000000..fac9453fa Binary files /dev/null and b/mods/character-select-coop/textures/char_select_gear.tex differ diff --git a/mods/character-select-coop/textures/char_select_graffiti_default.tex b/mods/character-select-coop/textures/char_select_graffiti_default.tex new file mode 100644 index 000000000..4c153abfc Binary files /dev/null and b/mods/character-select-coop/textures/char_select_graffiti_default.tex differ diff --git a/mods/character-select-coop/textures/char_select_graffiti_luigi.tex b/mods/character-select-coop/textures/char_select_graffiti_luigi.tex new file mode 100644 index 000000000..95683dba7 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_graffiti_luigi.tex differ diff --git a/mods/character-select-coop/textures/char_select_graffiti_mario.tex b/mods/character-select-coop/textures/char_select_graffiti_mario.tex new file mode 100644 index 000000000..3aa877572 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_graffiti_mario.tex differ diff --git a/mods/character-select-coop/textures/char_select_graffiti_toad.tex b/mods/character-select-coop/textures/char_select_graffiti_toad.tex new file mode 100644 index 000000000..aaa4eadd2 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_graffiti_toad.tex differ diff --git a/mods/character-select-coop/textures/char_select_graffiti_waluigi.tex b/mods/character-select-coop/textures/char_select_graffiti_waluigi.tex new file mode 100644 index 000000000..d616c1956 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_graffiti_waluigi.tex differ diff --git a/mods/character-select-coop/textures/char_select_graffiti_wario.tex b/mods/character-select-coop/textures/char_select_graffiti_wario.tex new file mode 100644 index 000000000..6f65b8869 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_graffiti_wario.tex differ diff --git a/mods/character-select-coop/textures/char_select_icon_signs.tex b/mods/character-select-coop/textures/char_select_icon_signs.tex new file mode 100644 index 000000000..2a61eb5a6 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_icon_signs.tex differ diff --git a/mods/character-select-coop/textures/char_select_list_button.tex b/mods/character-select-coop/textures/char_select_list_button.tex new file mode 100644 index 000000000..620ee55d9 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_list_button.tex differ diff --git a/mods/character-select-coop/textures/char_select_logo.tex b/mods/character-select-coop/textures/char_select_logo.tex new file mode 100644 index 000000000..045b3d9d3 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_logo.tex differ diff --git a/mods/character-select-coop/textures/char_select_luigi_meter_left.tex b/mods/character-select-coop/textures/char_select_luigi_meter_left.tex new file mode 100644 index 000000000..5cad15deb Binary files /dev/null and b/mods/character-select-coop/textures/char_select_luigi_meter_left.tex differ diff --git a/mods/character-select-coop/textures/char_select_luigi_meter_right.tex b/mods/character-select-coop/textures/char_select_luigi_meter_right.tex new file mode 100644 index 000000000..0b0b3d242 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_luigi_meter_right.tex differ diff --git a/mods/character-select-coop/textures/char_select_nameplate.tex b/mods/character-select-coop/textures/char_select_nameplate.tex new file mode 100644 index 000000000..9e5c9cdb3 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_nameplate.tex differ diff --git a/mods/character-select-coop/textures/char_select_options_tv.tex b/mods/character-select-coop/textures/char_select_options_tv.tex new file mode 100644 index 000000000..b2f0e8b8c Binary files /dev/null and b/mods/character-select-coop/textures/char_select_options_tv.tex differ diff --git a/mods/character-select-coop/textures/char_select_palette_bucket.tex b/mods/character-select-coop/textures/char_select_palette_bucket.tex new file mode 100644 index 000000000..431685d07 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_palette_bucket.tex differ diff --git a/mods/character-select-coop/textures/char_select_record.tex b/mods/character-select-coop/textures/char_select_record.tex new file mode 100644 index 000000000..9ed0c0976 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_record.tex differ diff --git a/mods/character-select-coop/textures/char_select_toad_meter_left.tex b/mods/character-select-coop/textures/char_select_toad_meter_left.tex new file mode 100644 index 000000000..3b12f4560 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_toad_meter_left.tex differ diff --git a/mods/character-select-coop/textures/char_select_toad_meter_right.tex b/mods/character-select-coop/textures/char_select_toad_meter_right.tex new file mode 100644 index 000000000..5934bc310 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_toad_meter_right.tex differ diff --git a/mods/character-select-coop/textures/char_select_wall_left.tex b/mods/character-select-coop/textures/char_select_wall_left.tex new file mode 100644 index 000000000..502ea34b9 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_wall_left.tex differ diff --git a/mods/character-select-coop/textures/char_select_wall_right.tex b/mods/character-select-coop/textures/char_select_wall_right.tex new file mode 100644 index 000000000..e5e557e56 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_wall_right.tex differ diff --git a/mods/character-select-coop/textures/char_select_waluigi_meter_left.tex b/mods/character-select-coop/textures/char_select_waluigi_meter_left.tex new file mode 100644 index 000000000..2b07ec117 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_waluigi_meter_left.tex differ diff --git a/mods/character-select-coop/textures/char_select_waluigi_meter_right.tex b/mods/character-select-coop/textures/char_select_waluigi_meter_right.tex new file mode 100644 index 000000000..27daf6c44 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_waluigi_meter_right.tex differ diff --git a/mods/character-select-coop/textures/char_select_wario_meter_left.tex b/mods/character-select-coop/textures/char_select_wario_meter_left.tex new file mode 100644 index 000000000..636030a33 Binary files /dev/null and b/mods/character-select-coop/textures/char_select_wario_meter_left.tex differ diff --git a/mods/character-select-coop/textures/char_select_wario_meter_right.tex b/mods/character-select-coop/textures/char_select_wario_meter_right.tex new file mode 100644 index 000000000..e07d6f95d Binary files /dev/null and b/mods/character-select-coop/textures/char_select_wario_meter_right.tex differ diff --git a/mods/character-select-coop/voice.lua b/mods/character-select-coop/voice.lua new file mode 100644 index 000000000..5f9f9be1c --- /dev/null +++ b/mods/character-select-coop/voice.lua @@ -0,0 +1,385 @@ +if incompatibleClient then return 0 end + +local TYPE_TABLE = "table" +local TYPE_USERDATA = "userdata" +local TYPE_STRING = "string" + +local SLEEP_TALK_SNORES = 8 +local STARTING_SNORE = 46 +local SLEEP_TALK_START = STARTING_SNORE + 49 +local SLEEP_TALK_END = SLEEP_TALK_START + SLEEP_TALK_SNORES +local stallTimer = 0 +local stallSayLine = 5 + +characterVoices = { + [E_MODEL_WALUIGI] = { + [CHAR_SOUND_OKEY_DOKEY] = audio_sample_load('0B_waluigi_okey_dokey.aiff'), + [CHAR_SOUND_LETS_A_GO] = audio_sample_load('1A_waluigi_lets_a_go.aiff'), + [CHAR_SOUND_GAME_OVER] = audio_sample_load('11_waluigi_game_over.aiff'), + [CHAR_SOUND_PUNCH_YAH] = audio_sample_load('08_waluigi_punch_yah.aiff'), + [CHAR_SOUND_PUNCH_WAH] = audio_sample_load('01_waluigi_jump_wah.aiff'), + [CHAR_SOUND_PUNCH_HOO] = audio_sample_load('09_waluigi_punch_hoo.aiff'), + [CHAR_SOUND_YAH_WAH_HOO] = {audio_sample_load('00_waluigi_jump_hoo.aiff'), audio_sample_load('01_waluigi_jump_wah.aiff'), audio_sample_load('02_waluigi_yah.aiff')}, + [CHAR_SOUND_HOOHOO] = audio_sample_load('01_waluigi_hoohoo.aiff'), + [CHAR_SOUND_YAHOO_WAHA_YIPPEE] = {audio_sample_load('04_waluigi_yahoo.aiff'), audio_sample_load('18_waluigi_waha.aiff'), audio_sample_load('19_waluigi_yippee.aiff')}, + [CHAR_SOUND_UH] = audio_sample_load('05_waluigi_uh.aiff'), + [CHAR_SOUND_UH2] = audio_sample_load('05_waluigi_uh2.aiff'), + [CHAR_SOUND_UH2_2] = audio_sample_load('05_waluigi_uh2.aiff'), + [CHAR_SOUND_DOH] = audio_sample_load('10_waluigi_doh.aiff'), + [CHAR_SOUND_OOOF] = audio_sample_load('0B_waluigi_ooof.aiff'), + [CHAR_SOUND_OOOF2] = audio_sample_load('0B_waluigi_ooof.aiff'), + [CHAR_SOUND_HAHA] = audio_sample_load('03_waluigi_haha.aiff'), + [CHAR_SOUND_HAHA_2] = audio_sample_load('03_waluigi_haha.aiff'), + [CHAR_SOUND_YAHOO] = audio_sample_load('04_waluigi_yahoo.aiff'), + [CHAR_SOUND_DOH] = audio_sample_load('10_waluigi_doh.aiff'), + [CHAR_SOUND_WHOA] = audio_sample_load('08_waluigi_whoa.aiff'), + [CHAR_SOUND_EEUH] = audio_sample_load('09_waluigi_eeuh.aiff'), + [CHAR_SOUND_WAAAOOOW] = audio_sample_load('00_waluigi_waaaooow.aiff'), + [CHAR_SOUND_TWIRL_BOUNCE] = audio_sample_load('14_waluigi_twirl_bounce.aiff'), + [CHAR_SOUND_GROUND_POUND_WAH] = audio_sample_load('01_waluigi_jump_wah.aiff'), + [CHAR_SOUND_WAH2] = audio_sample_load('07_waluigi_wah2.aiff'), + [CHAR_SOUND_HRMM] = audio_sample_load('06_waluigi_hrmm.aiff'), + [CHAR_SOUND_HERE_WE_GO] = audio_sample_load('0C_waluigi_here_we_go.aiff'), + [CHAR_SOUND_SO_LONGA_BOWSER] = audio_sample_load('16_waluigi_so_longa_bowser.aiff'), + -- DAMAGE + [CHAR_SOUND_ATTACKED] = audio_sample_load('0A_waluigi_attacked.aiff'), + [CHAR_SOUND_PANTING] = audio_sample_load('02_waluigi_panting.aiff'), + [CHAR_SOUND_PANTING_COLD] = audio_sample_load('02_waluigi_panting.aiff'), + [CHAR_SOUND_ON_FIRE] = audio_sample_load('04_waluigi_on_fire.aiff'), + -- SLEEP SOUNDS + [CHAR_SOUND_IMA_TIRED] = audio_sample_load('17_waluigi_tired.aiff'), + [CHAR_SOUND_YAWNING] = audio_sample_load('0D_waluigi_yawning.aiff'), + [CHAR_SOUND_SNORING1] = audio_sample_load('0E_waluigi_snoring1.aiff'), + [CHAR_SOUND_SNORING2] = audio_sample_load('0F_waluigi_snoring2.aiff'), + [CHAR_SOUND_SNORING3] = audio_sample_load('15_waluigi_snoring3.aiff'), + -- COUGHING + [CHAR_SOUND_COUGHING1] = audio_sample_load('06_waluigi_coughing.aiff'), + [CHAR_SOUND_COUGHING2] = audio_sample_load('06_waluigi_coughing.aiff'), + [CHAR_SOUND_COUGHING3] = audio_sample_load('06_waluigi_coughing.aiff'), + -- DEATH + [CHAR_SOUND_DYING] = audio_sample_load('03_waluigi_dying.aiff'), + [CHAR_SOUND_DROWNING] = audio_sample_load('0C_waluigi_drowning.aiff'), + [CHAR_SOUND_MAMA_MIA] = audio_sample_load('0A_waluigi_mama_mia.aiff') + } +} + +local levelReverbs = { + [LEVEL_NONE] = { 0x00, 0x00, 0x00 }, + [LEVEL_UNKNOWN_1] = { 0x00, 0x00, 0x00 }, + [LEVEL_UNKNOWN_2] = { 0x00, 0x00, 0x00 }, + [LEVEL_UNKNOWN_3] = { 0x00, 0x00, 0x00 }, + [LEVEL_BBH] = { 0x28, 0x28, 0x28 }, + [LEVEL_CCM] = { 0x10, 0x38, 0x38 }, + [LEVEL_CASTLE] = { 0x20, 0x20, 0x30 }, + [LEVEL_HMC] = { 0x28, 0x28, 0x28 }, + [LEVEL_SSL] = { 0x08, 0x30, 0x30 }, + [LEVEL_BOB] = { 0x08, 0x08, 0x08 }, + [LEVEL_SL] = { 0x10, 0x28, 0x28 }, + [LEVEL_WDW] = { 0x10, 0x18, 0x18 }, + [LEVEL_JRB] = { 0x10, 0x18, 0x18 }, + [LEVEL_THI] = { 0x0c, 0x0c, 0x20 }, + [LEVEL_TTC] = { 0x18, 0x18, 0x18 }, + [LEVEL_RR] = { 0x20, 0x20, 0x20 }, + [LEVEL_CASTLE_GROUNDS] = { 0x08, 0x08, 0x08 }, + [LEVEL_BITDW] = { 0x28, 0x28, 0x28 }, + [LEVEL_VCUTM] = { 0x28, 0x28, 0x28 }, + [LEVEL_BITFS] = { 0x28, 0x28, 0x28 }, + [LEVEL_SA] = { 0x10, 0x10, 0x10 }, + [LEVEL_BITS] = { 0x28, 0x28, 0x28 }, + [LEVEL_LLL] = { 0x08, 0x30, 0x30 }, + [LEVEL_DDD] = { 0x10, 0x20, 0x20 }, + [LEVEL_WF] = { 0x08, 0x08, 0x08 }, + [LEVEL_ENDING] = { 0x00, 0x00, 0x00 }, + [LEVEL_CASTLE_COURTYARD] = { 0x08, 0x08, 0x08 }, + [LEVEL_PSS] = { 0x28, 0x28, 0x28 }, + [LEVEL_COTMC] = { 0x28, 0x28, 0x28 }, + [LEVEL_TOTWC] = { 0x20, 0x20, 0x20 }, + [LEVEL_BOWSER_1] = { 0x40, 0x40, 0x40 }, + [LEVEL_WMOTR] = { 0x28, 0x28, 0x28 }, + [LEVEL_UNKNOWN_32] = { 0x70, 0x00, 0x00 }, + [LEVEL_BOWSER_2] = { 0x40, 0x40, 0x40 }, + [LEVEL_BOWSER_3] = { 0x40, 0x40, 0x40 }, + [LEVEL_UNKNOWN_35] = { 0x00, 0x00, 0x00 }, + [LEVEL_TTM] = { 0x08, 0x08, 0x08 }, + [LEVEL_UNKNOWN_37] = { 0x00, 0x00, 0x00 }, + [LEVEL_UNKNOWN_38] = { 0x00, 0x00, 0x00 }, +} + +local stalledAudio = {} + +---@param sample ModAudio +---@param pos Vec3f +---@param baseVolume number +---@param reverbAmount number (0 to 1, where 1 = full echo effect) +local function play_sound_with_reverb(sample, pos, baseVolume, reverbAmount) + if is_game_paused() or optionTable[optionTableRef.localVoices].toggle == 0 then return end + -- Play the original sample + audio_sample_play(sample, pos, baseVolume) + + -- Define simple fake reverb delays and volume reductions + local echoDelays = { 0.1, 0.2, 0.35, 0.5 } + local echoVolumes = { + baseVolume * reverbAmount * 0.6, + baseVolume * reverbAmount * 0.4, + baseVolume * reverbAmount * 0.25, + baseVolume * reverbAmount * 0.15, + } + + for i = 1, #echoDelays do + table.insert(stalledAudio, { + path = sample.filepath, + frame = (get_global_timer() + math.floor(echoDelays[i]*30)), + sample = sample, + pos = pos, + volume = echoVolumes[i] + }) + end +end + + +---@param sample ModAudio +local function stop_sound_with_reverb(sample) + audio_sample_stop(sample) + if #stalledAudio > 0 then + for i = #stalledAudio, 1, -1 do + if stalledAudio[i] ~= nil and stalledAudio[i].path == sample.filepath then + audio_sample_stop(stalledAudio[i].sample) + table.remove(stalledAudio, i) + end + end + end +end + +local function stop_all_custom_character_sounds() + -- run through each player + for i = 0, MAX_PLAYERS - 1 do + local m = gMarioStates[i] + -- get the voice table, if there is one + local voiceTable = character_get_voice(m) + if voiceTable ~= nil then + -- run through each sample + for sound in pairs(voiceTable) do + -- if the sample is found, try to stop it + if voiceTable[sound] ~= nil and type(voiceTable[sound]) ~= "string" then + -- if there's no pointer then it must be a sound clip table + if voiceTable[sound]._pointer == nil then + for voice in pairs(voiceTable[sound]) do + if type(voiceTable[sound][voice]) == "string" then + break + end + stop_sound_with_reverb(voiceTable[sound][voice]) + end + else + stop_sound_with_reverb(voiceTable[sound]) + end + end + end + end + end +end + +local playerSample = {} +for i = 0, MAX_PLAYERS - 1 do + playerSample[i] = nil +end + +local characterAddonSounds = { + [CHAR_SOUND_PUNCH_YAH] = {sound = SOUND_ACTION_THROW, pitch = 1.1}, + [CHAR_SOUND_PUNCH_WAH] = {sound = SOUND_ACTION_THROW, pitch = 1.0}, + [CHAR_SOUND_PUNCH_HOO] = {sound = SOUND_ACTION_THROW, pitch = 0.9}, +} + +---@param m MarioState +---@param sound CharacterSound +---@param pos Vec3f? +function custom_character_sound(m, sound, pos) + local np = gNetworkPlayers[m.playerIndex] + local voiceTable = character_get_voice(m) + local voiceToggle = optionTable[optionTableRef.localVoices].toggle + local voiceOff = (voiceToggle == 0 or (voiceToggle == 2 and m.playerIndex ~= 0)) + if m.playerIndex == 0 then + if not startup_init_stall() then + return NO_SOUND + end + end + local index = m.playerIndex + if playerSample[index] ~= nil and type(playerSample[index]) ~= TYPE_STRING then + stop_sound_with_reverb(playerSample[index]) + end + + -- Add punch "woosh" since NO_SOUND removes it + if characterAddonSounds[sound] and (voiceTable ~= nil or voiceOff) then + local soundInfo = characterAddonSounds[sound] + play_sound_with_freq_scale(soundInfo.sound, m.marioObj.header.gfx.cameraToObject, soundInfo.pitch); + end + + -- Voice Toggle + if voiceOff then return NO_SOUND end + + -- Vanilla Voicelines + if voiceTable == nil then return end + + -- Load the appropriate sample + local voice = character_get_voice(m)[sound] + if voice == nil then return NO_SOUND end + if type(voice) == TYPE_TABLE then + if #voice > 0 then + playerSample[index] = voice[math.random(1, #voice)] + else + return NO_SOUND + end + else + playerSample[index] = voice + end + + -- Play the sample + -- Volume based on sound type + local baseVolume = 1.0 + if sound == CHAR_SOUND_SNORING1 or sound == CHAR_SOUND_SNORING2 or sound == CHAR_SOUND_SNORING3 then + baseVolume = 0.5 + end + + local position = pos or m.pos + local reverbAmount = 0x08 + if levelReverbs[np.currLevelNum] ~= nil and levelReverbs[np.currLevelNum][np.currAreaIndex] ~= nil then + reverbAmount = levelReverbs[np.currLevelNum][np.currAreaIndex]/127 + elseif smlua_level_util_get_info(np.currLevelNum) ~= nil then + local levelInfo = smlua_level_util_get_info(np.currLevelNum) + levelReverbs[np.currLevelNum] = {} + levelReverbs[np.currLevelNum][1] = levelInfo.echoLevel1 or reverbAmount + levelReverbs[np.currLevelNum][2] = levelInfo.echoLevel2 or reverbAmount + levelReverbs[np.currLevelNum][3] = levelInfo.echoLevel3 or reverbAmount + reverbAmount = levelReverbs[np.currLevelNum][np.currAreaIndex]/127 + else + reverbAmount = levelReverbs[np.currLevelNum][1]/127 + end + + play_sound_with_reverb(playerSample[index], position, baseVolume, reverbAmount) + + return NO_SOUND +end + +---@param m MarioState +function custom_character_snore(m) + if is_game_paused() or optionTable[optionTableRef.localVoices].toggle == 0 or (optionTable[optionTableRef.localVoices].toggle == 2 and m.playerIndex ~= 0) then + -- Remove echo lines that should have played while paused + if #stalledAudio > 0 then + for i = 1, #stalledAudio do + if stalledAudio[i] ~= nil and stalledAudio[i].frame <= get_global_timer() then + table.remove(stalledAudio, i) + end + end + end + return + end + + -- Putting echo stuffs in snore since it's on update + if #stalledAudio > 0 then + for i = 1, #stalledAudio do + if stalledAudio[i] ~= nil and stalledAudio[i].frame <= get_global_timer() then + local voice = stalledAudio[i] + audio_sample_play(voice.sample, voice.pos, voice.volume) + table.remove(stalledAudio, i) + end + end + end + + if m.action ~= ACT_SLEEPING then + return + elseif m.actionState ~= 2 or (m.flags & MARIO_MARIO_SOUND_PLAYED) == 0 then + return + end + + -- get the voice table + local voiceTable = character_get_voice(m) + -- Check nil table for vanilla voices + if voiceTable == nil then return end + -- Check empty table for no sound + if voiceTable == nil then return NO_SOUND end + + local snoreTable = voiceTable[CHAR_SOUND_SNORING3] + if snoreTable == nil or snoreTable._pointer ~= nil then + snoreTable = {} + for i = CHAR_SOUND_SNORING1, CHAR_SOUND_SNORING3 do + if voiceTable[i] ~= nil then + table.insert(snoreTable, voiceTable[i]) + end + end + end + + local animFrame = m.marioObj.header.gfx.animInfo.animFrame + if snoreTable ~= nil and #snoreTable >= 2 then + if animFrame == 2 and m.actionTimer < SLEEP_TALK_START then + custom_character_sound(m, snoreTable[2]) + elseif animFrame == 25 then + if #snoreTable >= 3 then + m.actionTimer = m.actionTimer + 1 + if m.actionTimer >= SLEEP_TALK_END then + m.actionTimer = STARTING_SNORE + end + if m.actionTimer == SLEEP_TALK_START then + play_character_sound(m, CHAR_SOUND_SNORING3) + elseif m.actionTimer < SLEEP_TALK_START then + play_character_sound(m, CHAR_SOUND_SNORING1) + end + else + play_character_sound(m, CHAR_SOUND_SNORING1) + end + end + elseif animFrame == 2 then + play_character_sound(m, CHAR_SOUND_SNORING2) + + elseif animFrame == 25 then + play_character_sound(m, CHAR_SOUND_SNORING1) + end +end + +local function update() + if is_game_paused() then + stop_all_custom_character_sounds() + end +end + +hook_event(HOOK_UPDATE, update) +hook_event(HOOK_ON_LEVEL_INIT, stop_all_custom_character_sounds) + +function config_character_sounds() + log_to_console_once("'config_character_sounds' is deprecated, and functionality is now baked into `character_add_voice`", CONSOLE_MESSAGE_WARNING) +end + +-- Join sound +introLine = false +local function mario_update(m) + if m.playerIndex ~= 0 then return end + if startup_init_stall() and not introLine then + if m.action ~= ACT_INTRO_CUTSCENE then + play_character_sound(m, CHAR_SOUND_OKEY_DOKEY) + end + introLine = true + end + + custom_character_snore(m) +end + +hook_event(HOOK_CHARACTER_SOUND, custom_character_sound) +cs_hook_mario_update(mario_update) + +-- Peach Line Replacements +---@param soundbits integer +---@param pos Vec3f +local function on_play_sound(soundbits,pos) + local endpeachsoundtable = {[SOUND_PEACH_MARIO] = true,[SOUND_PEACH_POWER_OF_THE_STARS] = true,[SOUND_PEACH_THANKS_TO_YOU] = true, [SOUND_PEACH_THANK_YOU_MARIO] = true,[SOUND_PEACH_SOMETHING_SPECIAL] = true,[SOUND_PEACH_BAKE_A_CAKE] = true,[SOUND_PEACH_FOR_MARIO] = true,[SOUND_PEACH_MARIO2] = true} + local m = gMarioStates[0] + if endpeachsoundtable[soundbits] and (character_get_voice(m) ~= nil) and (character_get_voice(m)[soundbits] ~= nil) then --ending peach cutscene sounds + custom_character_sound(m,soundbits,pos) + return NO_SOUND + elseif (soundbits == SOUND_PEACH_DEAR_MARIO) and (character_get_voice(m) ~= nil) and (character_get_voice(m)[soundbits] ~= nil) then --introduction peach sounds + custom_character_sound(m,soundbits,pos) + return NO_SOUND + elseif (soundbits == SOUND_MENU_THANK_YOU_PLAYING_MY_GAME) and (character_get_voice(m) ~= nil) and (character_get_voice(m)[soundbits] ~= nil) then --cake screen thank you for playing my game voice + custom_character_sound(m,soundbits,pos) + return NO_SOUND + end +end + +hook_event(HOOK_ON_PLAY_SOUND, on_play_sound) diff --git a/mods/character-select-coop/o-api.lua b/mods/character-select-coop/z-api.lua similarity index 52% rename from mods/character-select-coop/o-api.lua rename to mods/character-select-coop/z-api.lua index b939f5447..77f7df648 100644 --- a/mods/character-select-coop/o-api.lua +++ b/mods/character-select-coop/z-api.lua @@ -1,48 +1,15 @@ if incompatibleClient then return 0 end --- localize functions to improve performance - o-api.lua -local table_insert,djui_hud_measure_text,smlua_model_util_get_id,type,tonumber = table.insert,djui_hud_measure_text,smlua_model_util_get_id,type,tonumber - ---- @class CharacterTable ---- @field public name string ---- @field public saveName string ---- @field public description table ---- @field public credit string ---- @field public color Color ---- @field public model ModelExtendedId|integer ---- @field public forceChar CharacterType ---- @field public lifeIcon TextureInfo ---- @field public camScale integer - -local characterVoices = {} -local saveNameTable = {} - --- Here for functions below api ----@ignore -local function placeholder() end - ----@ignore -local function split_text_into_lines(text) - local words = {} - for word in text:gmatch("%S+") do - table_insert(words, word) - end - - local lines = {} - local currentLine = "" - for i, word in ipairs(words) do - local measuredWidth = djui_hud_measure_text(currentLine .. " " .. word)*0.3 - if measuredWidth <= 100 then - currentLine = currentLine .. " " .. word - else - table_insert(lines, currentLine) - currentLine = word - end - end - table_insert(lines, currentLine) -- add the last line - - return lines -end +---@class CharacterTable +---@field public name string +---@field public saveName string +---@field public description table +---@field public credit string +---@field public color Color +---@field public model ModelExtendedId|integer +---@field public baseChar CharacterType +---@field public lifeIcon TextureInfo +---@field public camScale integer local TYPE_INTEGER = "number" local TYPE_STRING = "string" @@ -59,90 +26,111 @@ local TYPE_FUNCTION = "function" ---@description A function that adds a Character to the Character Table ---@added 1 ----@param name string|nil `"Custom Model"` ----@param description table|string|nil `{"string"}` ----@param credit string|nil `"You!"`, Credit the creators ----@param color Color|string|nil `{r, g, b}` ----@param modelInfo ModelExtendedId|integer|nil Use `smlua_model_util_get_id` ----@param forceChar CharacterType|nil Character Type, such as `CT_MARIO` ----@param lifeIcon TextureInfo|string|nil Use get_texture_info ----@param camScale integer|nil Zooms the camera based on a multiplier (Default `1`) +---@param name string? `"Custom Model"` +---@param description string|table? `{"string"}` +---@param credit string? `"You!"`, Credit the creators +---@param color Color|string? `{r, g, b}` +---@param modelInfo ModelExtendedId|integer? Use `smlua_model_util_get_id` +---@param baseChar CharacterType? Character Type, such as `CT_MARIO` +---@param lifeIcon TextureInfo|string? Use get_texture_info +---@param camScale integer? Zooms the camera based on a multiplier (Default `1`) ---@return integer --The index of the character in the character table -local function character_add(name, description, credit, color, modelInfo, forceChar, lifeIcon, camScale) - if type(description) == TYPE_STRING then - description = split_text_into_lines(description) +local function character_add(name, description, credit, color, modelInfo, baseChar, lifeIcon, camScale) + name = type(name) == TYPE_STRING and name or "Untitled" + credit = type(credit) == TYPE_STRING and credit or "Unknown" + if type(description) == TYPE_TABLE then + local table = description + description = "" + for i = 1, #table do + description = description .. table[i] .. (i ~= #table and " " or "") + end end if color ~= nil and type(color) == TYPE_STRING then color = {r = tonumber(color:sub(1,2), 16), g = tonumber(color:sub(3,4), 16), b = tonumber(color:sub(5,6), 16) } end - if lifeIcon ~= nil and type(lifeIcon) == TYPE_STRING then + if lifeIcon and type(lifeIcon) == TYPE_STRING then lifeIcon = lifeIcon:sub(1,1) end - local addedModel = (modelInfo and modelInfo ~= E_MODEL_ERROR_MODEL) and modelInfo or E_MODEL_ARMATURE + + local addedModel = (modelInfo and modelInfo ~= E_MODEL_ERROR_MODEL) and modelInfo or E_MODEL_ERROR_MODEL local charNum = #characterTable + 1 - table_insert(characterTable, { - saveName = type(name) == TYPE_STRING and string_space_to_underscore(name) or "Untitled", + + if name and type(name) == TYPE_STRING and not _G["CT_"..name:upper():gsub(" ", "_")] then + local charNum = charNum ---@type CharacterType + define_valid_global("CT_"..name:upper():gsub(" ", "_"), charNum) + end + + table.insert(characterTable, { + saveName = type(name) == TYPE_STRING and string_space_to_underscore(name.."_"..credit) or "Untitled", + nickname = type(name) == TYPE_STRING and name or "Untitled", currAlt = 1, hasMoveset = false, - locked = false, + locked = LOCKED_NEVER, category = "All", ogNum = charNum, + playtime = 0, + autoDialog = true, + replaceModels = {}, [1] = { - name = type(name) == TYPE_STRING and name or "Untitled", - description = type(description) == TYPE_TABLE and description or {"No description has been provided"}, - credit = type(credit) == TYPE_STRING and credit or "Unknown", + name = name, + description = type(description) == TYPE_STRING and description or "No description has been provided", + credit = credit, color = type(color) == TYPE_TABLE and color or {r = 255, g = 255, b = 255}, model = addedModel, ogModel = addedModel, - forceChar = forceChar and forceChar or CT_MARIO, + baseChar = baseChar and baseChar or CT_MARIO, lifeIcon = (type(lifeIcon) == TYPE_TABLE or type(lifeIcon) == TYPE_TEX_INFO or type(lifeIcon) == TYPE_STRING) and lifeIcon or "?", starIcon = gTextures.star, camScale = type(camScale) == TYPE_INTEGER and camScale or 1, - healthTexture = nil, + healthMeter = nil, }, }) - saveNameTable[charNum] = characterTable[charNum].saveName characterMovesets[charNum] = {} + characterDialog[charNum] = {} return charNum end ---@description A function that adds a Costume to an Existing Character, all inputs mimic character_edit ---@added 1.11 ---@param charNum integer The number/table position of the Character you want to add a costume to ----@param name string|nil `"Custom Model"` ----@param description table|string|nil `{"string"}` ----@param credit string|nil `"You!"`, Credit the creators ----@param color Color|string|nil `{r, g, b}` ----@param modelInfo ModelExtendedId|integer|nil Use `smlua_model_util_get_id` ----@param forceChar CharacterType|nil Character Type, such as `CT_MARIO` ----@param lifeIcon TextureInfo|string|nil Use get_texture_info ----@param camScale integer|nil Zooms the camera based on a multiplier (Default `1`) ----@return integer --The index of the costume in the character's table -local function character_add_costume(charNum, name, description, credit, color, modelInfo, forceChar, lifeIcon, camScale) - if tonumber(charNum) == nil or charNum > #characterTable or charNum < 0 then return end - if type(description) == TYPE_STRING then - description = split_text_into_lines(description) +---@param name string? `"Custom Model"` +---@param description table|string? `{"string"}` +---@param credit string? `"You!"`, Credit the creators +---@param color Color|string? `{r, g, b}` +---@param modelInfo ModelExtendedId|integer? Use `smlua_model_util_get_id` +---@param baseChar CharacterType? Character Type, such as `CT_MARIO` +---@param lifeIcon TextureInfo|string? Use get_texture_info +---@param camScale integer? Zooms the camera based on a multiplier (Default `1`) +---@return integer? --The index of the costume in the character's table +local function character_add_costume(charNum, name, description, credit, color, modelInfo, baseChar, lifeIcon, camScale) + if not tonumber(charNum) or charNum > #characterTable or charNum < 0 then return end + if description ~= nil and type(description) == TYPE_TABLE then + local table = description + description = "" + for i = 1, #table do + description = description .. table[i] .. (i ~= #table and " " or "") + end end - if type(color) == TYPE_STRING then + if color ~= nil and type(color) == TYPE_STRING then color = {r = tonumber(color:sub(1,2), 16), g = tonumber(color:sub(3,4), 16), b = tonumber(color:sub(5,6), 16) } end - if lifeIcon ~= nil and type(lifeIcon) == TYPE_STRING then + if lifeIcon and type(lifeIcon) == TYPE_STRING then lifeIcon = lifeIcon:sub(1,1) end - local addedModel = (modelInfo and modelInfo ~= E_MODEL_ERROR_MODEL) and modelInfo or tableCache.model local tableCache = characterTable[charNum][1] - table_insert(characterTable[charNum], { + local addedModel = (modelInfo and modelInfo ~= E_MODEL_ERROR_MODEL) and modelInfo or tableCache.model + table.insert(characterTable[charNum], { name = type(name) == TYPE_STRING and name or tableCache.name, - description = type(description) == TYPE_TABLE and description or tableCache.description, + description = type(description) == TYPE_STRING and description or tableCache.description, credit = type(credit) == TYPE_STRING and credit or tableCache.credit, color = type(color) == TYPE_TABLE and color or tableCache.color, model = addedModel, ogModel = addedModel, - forceChar = type(forceChar) == TYPE_INTEGER and forceChar or tableCache.forceChar, + baseChar = type(baseChar) == TYPE_INTEGER and baseChar or tableCache.baseChar, lifeIcon = (type(lifeIcon) == TYPE_TABLE or type(lifeIcon) == TYPE_TEX_INFO or type(lifeIcon) == TYPE_STRING) and lifeIcon or tableCache.lifeIcon, starIcon = tableCache.starIcon, -- Done to prevent it getting lost in the sauce camScale = type(camScale) == TYPE_INTEGER and camScale or tableCache.camScale, - healthTexture = tableCache.healthTexture, + healthMeter = tableCache.healthMeter, }) return #characterTable[charNum] end @@ -151,39 +139,42 @@ end ---@added 1.11 ---@param charNum integer The number/table position of the Character you want to edit the costume of ---@param charAlt integer The number/table position of the Costume you want to edit, this can be found by making a variable equal ----@param name string|nil `"Custom Model"` ----@param description table|string|nil `{"string"}` ----@param credit string|nil `"You!"`, Credit the creators ----@param color Color|string|nil `{r, g, b}` ----@param modelInfo ModelExtendedId|integer|nil Use `smlua_model_util_get_id` ----@param forceChar CharacterType|nil Character Type, such as `CT_MARIO` ----@param lifeIcon TextureInfo|string|nil Use get_texture_info ----@param camScale integer|nil Zooms the camera based on a multiplier (Default `1`) -local function character_edit_costume(charNum, charAlt, name, description, credit, color, modelInfo, forceChar, lifeIcon, camScale) +---@param name string? `"Custom Model"` +---@param description table|string? `{"string"}` +---@param credit string? `"You!"`, Credit the creators +---@param color Color|string? `{r, g, b}` +---@param modelInfo ModelExtendedId|integer? Use `smlua_model_util_get_id` +---@param baseChar CharacterType? Character Type, such as `CT_MARIO` +---@param lifeIcon TextureInfo|string? Use get_texture_info +---@param camScale integer? Zooms the camera based on a multiplier (Default `1`) +local function character_edit_costume(charNum, charAlt, name, description, credit, color, modelInfo, baseChar, lifeIcon, camScale) if tonumber(charNum) == nil or charNum > #characterTable or charNum < 0 then return end - if type(description) == TYPE_STRING then - description = split_text_into_lines(description) + if description ~= nil and type(description) == TYPE_TABLE then + local table = description + description = "" + for i = 1, #table do + description = description .. table[i] .. (i ~= #table and " " or "") + end end - if type(color) == TYPE_STRING then + if color ~= nil and type(color) == TYPE_STRING then color = {r = tonumber(color:sub(1,2), 16), g = tonumber(color:sub(3,4), 16), b = tonumber(color:sub(5,6), 16) } end - if lifeIcon ~= nil and type(lifeIcon) == TYPE_STRING then + if lifeIcon and type(lifeIcon) == TYPE_STRING then lifeIcon = lifeIcon:sub(1,1) end local tableCache = characterTable[charNum][charAlt] characterTable[charNum][charAlt] = characterTable[charNum][charAlt] and { name = type(name) == TYPE_STRING and name or tableCache.name, - saveName = saveNameTable[charNum], - description = type(description) == TYPE_TABLE and description or tableCache.description, + description = type(description) == TYPE_STRING and description or tableCache.description, credit = type(credit) == TYPE_STRING and credit or tableCache.credit, color = type(color) == TYPE_TABLE and color or tableCache.color, model = (modelInfo and modelInfo ~= E_MODEL_ERROR_MODEL) and modelInfo or tableCache.model, ogModel = tableCache.ogModel, - forceChar = type(forceChar) == TYPE_INTEGER and forceChar or tableCache.forceChar, + baseChar = type(baseChar) == TYPE_INTEGER and baseChar or tableCache.baseChar, lifeIcon = (type(lifeIcon) == TYPE_TABLE or type(lifeIcon) == TYPE_TEX_INFO or type(lifeIcon) == TYPE_STRING) and lifeIcon or tableCache.lifeIcon, starIcon = tableCache.starIcon, -- Done to prevent it getting lost in the sauce camScale = type(camScale) == TYPE_INTEGER and camScale or tableCache.camScale, - healthTexture = tableCache.healthTexture, + healthMeter = tableCache.healthMeter, } or nil if modelInfo and characterColorPresets[modelInfo] and tableCache.model and characterColorPresets[tableCache.model] and #characterColorPresets[modelInfo] == #characterColorPresets[tableCache.model] then @@ -194,16 +185,37 @@ end ---@description A function that Edits an Existing Character ---@added 1 ---@param charNum integer The number/table position of the Character you want to edit ----@param name string|nil `"Custom Model"` ----@param description table|string|nil `{"string"}` ----@param credit string|nil `"You!"`, Credit the creators ----@param color Color|string|nil `{r, g, b}` ----@param modelInfo ModelExtendedId|integer|nil Use `smlua_model_util_get_id` ----@param forceChar CharacterType|nil Character Type, such as `CT_MARIO` ----@param lifeIcon TextureInfo|string|nil Use get_texture_info ----@param camScale integer|nil Zooms the camera based on a multiplier (Default `1`) -local function character_edit(charNum, name, description, credit, color, modelInfo, forceChar, lifeIcon, camScale) - character_edit_costume(charNum, characterTable[charNum] and characterTable[charNum].currAlt or 1, name, description, credit, color, modelInfo, forceChar, lifeIcon, camScale) +---@param name string? `"Custom Model"` +---@param description table|string? `{"string"}` +---@param credit string? `"You!"`, Credit the creators +---@param color Color|string? `{r, g, b}` +---@param modelInfo ModelExtendedId|integer? Use `smlua_model_util_get_id` +---@param baseChar CharacterType? Character Type, such as `CT_MARIO` +---@param lifeIcon TextureInfo|string? Use get_texture_info +---@param camScale integer? Zooms the camera based on a multiplier (Default `1`) +local function character_edit(charNum, name, description, credit, color, modelInfo, baseChar, lifeIcon, camScale) + character_edit_costume(charNum, characterTable[charNum] and characterTable[charNum].currAlt or 1, name, description, credit, color, modelInfo, baseChar, lifeIcon, camScale) +end + +---@description A function to set a Character's Nickname, used for Dialog Replacement +---@added 1.16 +---@param charNum integer The number/table position of the Character you want to nickname +---@param nickname string The Character's new nickname +---@param autoSetDialog boolean Wheather dialog is automatically set (Defaults to `true`) +local function character_set_nickname(charNum, nickname, autoSetDialog) + if autoSetDialog == nil then autoSetDialog = true end + if characterTable[charNum] == nil or type(nickname) == TYPE_STRING then + characterTable[charNum].nickname = nickname + characterTable[charNum].autoDialog = autoSetDialog + end +end + + +---@description A function to get a Character's Nickname, used for Dialog Replacement +---@added 1.16 +---@param charNum integer The number/table position of the Character you want to get the nickname of +local function character_get_nickname(charNum) + return characterTable[charNum] ~= nil and characterTable[charNum].nickname end ---@description A function that adds a voice table to a character @@ -244,7 +256,47 @@ end ---@note } ---@note ``` local function character_add_voice(modelInfo, clips) - characterVoices[modelInfo] = type(clips) == TYPE_TABLE and clips or nil + --hook_event(HOOK_ON_MODS_LOADED, function () + local voiceTable = {} + -- Check nil table for vanilla voices + if clips == nil then return end + -- Check empty table for no sound + if clips == nil then return NO_SOUND end + + -- Load samples that haven't been loaded + for voice, sound in pairs(clips) do + if sound then + if type(sound) == TYPE_STRING then + local load = audio_sample_load(sound) + if load ~= nil then + voiceTable[voice] = load + end + elseif type(sound) == TYPE_TABLE then + -- load RNG/Table Samples + voiceTable[voice] = {} + for i, subsound in pairs(sound) do + if type(subsound) == TYPE_STRING then + local load = audio_sample_load(subsound) + if load ~= nil then + voiceTable[voice][i] = load + end + end + end + end + end + end + + characterVoices[modelInfo] = voiceTable + --end) +end +hook_event(HOOK_ON_MODS_LOADED, character_add_voice) + +---@description A function that gets the current character's voice table +---@added 1.5 +---@param model integer|MarioState Can use Model and/or MarioState +function character_get_voice(model) + local model = (type(model) == TYPE_INTEGER) and model or gCSPlayers[model.playerIndex].modelId + return characterVoices[model] end ---@description A function that adds a caps table to a character @@ -265,7 +317,7 @@ end ---@description A function that gets a model's cap table ---@added 1.13 ----@param modelInfo ModelExtendedId|integer|nil Model Information Received from smlua_model_util_get_id +---@param modelInfo ModelExtendedId|integer? Model Information Received from smlua_model_util_get_id local function character_get_caps(modelInfo) if modelInfo == nil then modelInfo = characterTable[currChar][characterTable[currChar].currAlt].model end return characterCaps[modelInfo] @@ -275,45 +327,75 @@ end ---@added 1.12 ---@param charNum integer The number/table position of the Character you want to add a meter to ---@param charAlt integer The number/table position of the Costume you want to add a meter to ----@param healthTexture table|nil A Table with your Character's Health Textures (Table Shown in character_add_health_meter) -local function character_add_costume_health_meter(charNum, charAlt, healthTexture) +---@param healthMeter table|function? A Table with your Character's Health Textures (Table Shown in character_add_health_meter) or Rendering Function +local function character_add_costume_health_meter(charNum, charAlt, healthMeter) if type(charNum) ~= TYPE_INTEGER or charNum == nil then return end if type(charAlt) ~= TYPE_INTEGER or charAlt == nil then return end - characterTable[charNum][charAlt].healthTexture = type(healthTexture) == TYPE_TABLE and healthTexture or nil + if healthMeter == nil then + return + elseif type(healthMeter) == TYPE_FUNCTION then + characterTable[charNum][charAlt].healthMeter = healthMeter + elseif type(healthMeter) == TYPE_TABLE then + characterTable[charNum][charAlt].healthMeter = { + label = { + left = is_texture_valid(healthMeter.label.left) and healthMeter.label.left or defaultMeterInfo.label.left, + right = is_texture_valid(healthMeter.label.right) and healthMeter.label.right or defaultMeterInfo.label.right, + }, + pie = { + is_texture_valid(healthMeter.pie[1]) and healthMeter.pie[1] or defaultMeterInfo.pie[1], + is_texture_valid(healthMeter.pie[2]) and healthMeter.pie[2] or defaultMeterInfo.pie[2], + is_texture_valid(healthMeter.pie[3]) and healthMeter.pie[3] or defaultMeterInfo.pie[3], + is_texture_valid(healthMeter.pie[4]) and healthMeter.pie[4] or defaultMeterInfo.pie[4], + is_texture_valid(healthMeter.pie[5]) and healthMeter.pie[5] or defaultMeterInfo.pie[5], + is_texture_valid(healthMeter.pie[6]) and healthMeter.pie[6] or defaultMeterInfo.pie[6], + is_texture_valid(healthMeter.pie[7]) and healthMeter.pie[7] or defaultMeterInfo.pie[7], + is_texture_valid(healthMeter.pie[8]) and healthMeter.pie[8] or defaultMeterInfo.pie[8], + } + } + end end ---@description A function that adds health meter textures to a character ---@added 1.9 ---@param charNum integer The number/table position of the Character you want to add a meter to ----@param healthTexture table|nil A Table with your Character's Health Textures (Table Shown Below) +---@param healthMeter table|function? A Table with your Character's Health Textures (Table Shown Below) or Rendering Function ---@note ```lua ---@note local HEALTH_METER_CHAR = { ---@note label = { ----@note left = get_texture_info("hp-back-left"), ----@note right = get_texture_info("hp-back-right"), +---@note left = get_texture_info("char_hp_pie_left"), +---@note right = get_texture_info("char_hp_pie_right"), ---@note }, ---@note pie = { ----@note [1] = get_texture_info("hp-pie-1"), ----@note [2] = get_texture_info("hp-pie-2"), ----@note [3] = get_texture_info("hp-pie-3"), ----@note [4] = get_texture_info("hp-pie-4"), ----@note [5] = get_texture_info("hp-pie-5"), ----@note [6] = get_texture_info("hp-pie-6"), ----@note [7] = get_texture_info("hp-pie-7"), ----@note [8] = get_texture_info("hp-pie-8"), +---@note [1] = get_texture_info("char_hp_pie_1"), +---@note [2] = get_texture_info("char_hp_pie_2"), +---@note [3] = get_texture_info("char_hp_pie_3"), +---@note [4] = get_texture_info("char_hp_pie_4"), +---@note [5] = get_texture_info("char_hp_pie_5"), +---@note [6] = get_texture_info("char_hp_pie_6"), +---@note [7] = get_texture_info("char_hp_pie_7"), +---@note [8] = get_texture_info("char_hp_pie_8"), ---@note } ---@note } +---@note +---@note -- or -- +---@note +---@note local function char_meter_render (localIndex, health, prevX, prevY, prevScaleX, prevScaleY, x, y, scaleX, scaleY) +---@note local squares = health >> 8 +---@note for i = 1, squares do +---@note djui_hud_render_rect(x + (i * 17), y, 16, 16) +---@note end +---@note end ---@note ``` -local function character_add_health_meter(charNum, healthTexture) - character_add_costume_health_meter(charNum, 1, healthTexture) +local function character_add_health_meter(charNum, healthMeter) + character_add_costume_health_meter(charNum, 1, healthMeter) end ---@description A function that adds course textures to a costume in the Star Select ---@added 1.12 ---@param charNum integer The number/table position of the Character you want to add a course textures to ---@param charAlt integer The number/table position of the Costume you want to add a course textures to ----@param courseTexture table|nil A Table with your Character's Health Textures (Table Shown in character_add_course) -local function character_add_costume_course(charNum, charAlt, courseTexture) +---@param courseTexture table? A Table with your Character's Health Textures (Table Shown in character_add_course) +local function character_add_costume_course_texture(charNum, charAlt, courseTexture) if type(charNum) ~= TYPE_INTEGER or charNum == nil then return end if type(charAlt) ~= TYPE_INTEGER or charAlt == nil then return end characterTable[charNum][charAlt].courseTexture = type(courseTexture) == TYPE_TABLE and courseTexture or nil @@ -322,27 +404,46 @@ end ---@description A function that adds course textures to a character in the Star Select ---@added 1.12 ---@param charNum integer The number/table position of the Character you want to add a course textures to ----@param courseTexture table|nil A Table with your Character's Health Textures (Table Shown Below) +---@param courseTexture table? A Table with your Character's Health Textures (Table Shown Below) ---@note ```lua ---@note local COURSE_CHAR = { ----@note top = get_texture_info("char-course-top"), ----@note bottom = get_texture_info("char-course-bottom"), +---@note top = get_texture_info("char_course_top"), +---@note bottom = get_texture_info("char_course_bottom"), ---@note } ---@note ``` -local function character_add_course(charNum, courseTexture) - character_add_costume_course(charNum, 1, courseTexture) +local function character_add_course_texture(charNum, courseTexture) + character_add_costume_course_texture(charNum, 1, courseTexture) +end + +-- Here because the model replacement feature is unstable +local bhvAllowReplace = { + [id_bhvEndToad] = true, + [id_bhvBeginningPeach] = true, + [id_bhvEndPeach] = true, + --[id_bhvGoomba] = true, + [id_bhvCelebrationStar] = true, +} + +---@param charNum ModelExtendedId|integer Player Model ID +---@param bhvId BehaviorId|integer Behavior ID of the type of objects you want to replace +---@param replaceModel ModelExtendedId|integer|function? Model ID +local function character_add_model_replacement(charNum, bhvId, replaceModel) + if not bhvAllowReplace[bhvId] then + log_to_console_once("Using `character_add_model_replacement` on untested behaviors such as '" .. get_behavior_name_from_id(bhvId) .. "' may be unstable!", CONSOLE_MESSAGE_WARNING) + end + characterTable[charNum].replaceModels[bhvId] = replaceModel end ---@description A function that adds a celebration star model to a character ---@added 1.7 ----@param modelInfo ModelExtendedId|integer Model Information Received from smlua_model_util_get_id() ----@param starModel ModelExtendedId|integer Model Information Received from smlua_model_util_get_id() ----@param starIcon TextureInfo|nil Texture Information Received from get_texture_info() +---@param modelInfo ModelExtendedId|integer Player Model ID +---@param starModel ModelExtendedId|integer Custom Star Model ID +---@param starIcon TextureInfo? Custom Star Texture local function character_add_celebration_star(modelInfo, starModel, starIcon) - characterCelebrationStar[modelInfo] = starModel - for i = 2, #characterTable do + for i = 0, #characterTable do for a = 1, #characterTable[i] do if characterTable[i][a].model == modelInfo then + character_add_model_replacement(i, id_bhvCelebrationStar, starModel) characterTable[i][a].starIcon = type(starIcon) == TYPE_TABLE and starIcon or gTextures.star return end @@ -351,11 +452,44 @@ local function character_add_celebration_star(modelInfo, starModel, starIcon) return false end +---@description A function that adds a peach model to a character for the opening letter and ending cutscene.Can also change peach's letter for the character +---@added 1.16 +---@param modelInfo ModelExtendedId|integer Model Information Received from smlua_model_util_get_id() +---@param peachmodelstart ModelExtendedId? Model Information Received from smlua_model_util_get_id() the model used for peach in the opening if left blank will use default peach model +---@param peachmodelend ModelExtendedId? Model Information Received from smlua_model_util_get_id() the model used for peach in the ending if left blank will use default peach model +---@param peachletterleft TextureInfo? left side of the texture to replace peach's letter texture in the intro +---@param peachletterright TextureInfo? right side of the texture to replace peach's letter texture in the intro +---@param peachlettersig TextureInfo? texture to replace peach's letter texture in the intro +local function character_add_peach_custom(modelInfo, peachmodelstart, peachmodelend, peachletterleft, peachletterright, peachlettersig) + character_add_model_replacement(character_get_number_from_model(modelInfo), id_bhvBeginningPeach, peachmodelstart) + character_add_model_replacement(character_get_number_from_model(modelInfo), id_bhvEndPeach, peachmodelend) + if (peachletterleft ~= nil) and (peachletterright ~= nil) and (peachlettersig ~= nil) then + characterpeachletter[modelInfo] = {left = peachletterleft, right = peachletterright, sig = peachlettersig} + end +end + +---@description A function that sets the toad models during the ending cutscene +---@added 1.16 +---@param modelInfo ModelExtendedId|integer Model Information Received from smlua_model_util_get_id() +---@param toadModelRight ModelExtendedId Model Information Received from smlua_model_util_get_id(), the model used for the right toad in the ending if left blank said toad will use the default npc toad model +---@param toadModelLeft ModelExtendedId Model Information Received from smlua_model_util_get_id(), the model used for the left toad in the ending if left blank said toad will use the default npc toad model +local function character_add_ending_toad_model(modelInfo, toadModelRight, toadModelLeft) + local settingRightToad = false + character_add_model_replacement(character_get_number_from_model(modelInfo), id_bhvEndToad, function (o) + -- Only difference between the two objects is positions + settingRightToad = not settingRightToad + if settingRightToad then + return toadModelRight + end + return toadModelLeft + end) +end + ---@description A function that adds a palette preset to a character ---@added 1.8 ---@param modelInfo ModelExtendedId|integer ---@param paletteTable table ----@param paletteName string|nil +---@param paletteName string? ---@note ```lua ---@note local PALETTE_CHAR = { ---@note [PANTS] = {r = 0x00, g = 0x00, b = 0xff}, @@ -369,6 +503,13 @@ end ---@note ``` ---@note Strings can also be used rather than RGB tables, ex. `[PANTS] = "0000ff"` local function character_add_palette_preset(modelInfo, paletteTable, paletteName) + if paletteName == nil then + if characterColorPresets[modelInfo] == nil then + paletteName = "Default" + else + paletteName = "Alt " .. tostring(#characterColorPresets[modelInfo]) + end + end local paletteTableOut = { name = paletteName, } @@ -382,9 +523,9 @@ local function character_add_palette_preset(modelInfo, paletteTable, paletteName paletteTableOut[i].b = tonumber(color:sub(5,6), 16) and tonumber(color:sub(5,6), 16) or defaultColors[i].b end if type(color) == TYPE_TABLE then - paletteTableOut[i].r = (type(color) == TYPE_TABLE and color.r ~= nil) and color.r or defaultColors[i].r - paletteTableOut[i].g = (type(color) == TYPE_TABLE and color.g ~= nil) and color.g or defaultColors[i].g - paletteTableOut[i].b = (type(color) == TYPE_TABLE and color.b ~= nil) and color.b or defaultColors[i].b + paletteTableOut[i].r = (type(color) == TYPE_TABLE and color.r) and color.r or defaultColors[i].r + paletteTableOut[i].g = (type(color) == TYPE_TABLE and color.g) and color.g or defaultColors[i].g + paletteTableOut[i].b = (type(color) == TYPE_TABLE and color.b) and color.b or defaultColors[i].b end end if characterColorPresets[modelInfo] == nil then @@ -392,15 +533,21 @@ local function character_add_palette_preset(modelInfo, paletteTable, paletteName currPalette = 1, } end - table_insert(characterColorPresets[modelInfo], paletteTableOut) + table.insert(characterColorPresets[modelInfo], paletteTableOut) end ---@description A function that adds animations to a model ---@added 1.10 ---@param modelInfo ModelExtendedId|integer ----@param animTable table -local function character_add_animations(modelInfo, animTable) - characterAnims[modelInfo] = type(animTable) == TYPE_TABLE and animTable or nil +---@param animTable? table +---@param eyeTable? table +---@param handTable? table +local function character_add_animations(modelInfo, animTable, eyeTable, handTable) + characterAnims[modelInfo] = { + anims = type(animTable) == TYPE_TABLE and animTable or nil, + eyes = type(eyeTable) == TYPE_TABLE and eyeTable or nil, + hands = type(handTable) == TYPE_TABLE and handTable or nil, + } end ---@description A function that gets any animation table from a model @@ -412,8 +559,8 @@ end ---@description A function that gets a character's full Character Select Table ---@added 1 ----@param tablePos integer|nil ----@param charAlt integer|nil +---@param tablePos integer? +---@param charAlt integer? ---@return CharacterTable local function character_get_current_table(tablePos, charAlt) tablePos = tablePos and tablePos or currChar @@ -430,9 +577,10 @@ end ---@description A function that gets the current character's table position in CS ---@added 1 ---- @param localIndex integer|nil ---- @return integer|nil +---@param localIndex integer? The local player index you want to get the character number from, Default is `0` +---@return integer? local function character_get_current_number(localIndex) + if not startup_init_stall() then return end if localIndex == nil or localIndex == 0 then return currChar else @@ -447,8 +595,8 @@ end ---@description A function that gets the current costumes's table position in CS ---@added 1.12 ----@param localIndex integer|nil ----@return integer|nil +---@param localIndex integer? +---@return integer? local function character_get_current_costume(localIndex) if localIndex == nil or localIndex == 0 then return characterTable[currChar].currAlt @@ -462,27 +610,30 @@ local function character_get_current_costume(localIndex) end end ----@description A function that sets the current character based only table position +---@description A function that sets the current character based only table position with an optional second argument for setting a specific costume ---@added 1.9 ----@param charNum integer|nil -local function character_set_current_number(charNum) +---@param charNum integer The number/table position of the Character you want the local player to become +---@param charAlt integer? The number/table position of a costume in the corresponding character's costume table to switch to. If nil will use the 1st costume +local function character_set_current_number(charNum, charAlt) if type(charNum) ~= TYPE_INTEGER or characterTable[charNum] == nil then return end - currChar = charNum + if charAlt == nil then charAlt = 1 end + charAlt = math.clamp(charAlt, 1, #characterTable[charNum]) + force_set_character(charNum, charAlt) charBeingSet = true end ---@description A function that gets the current character's palette data ---@added 1.12 ---- @return table|nil +---@return table? local function character_get_current_palette() local model = characterTable[currChar][characterTable[currChar].currAlt].model - return characterColorPresets[model][gCSPlayers[0].presetPalette] + return characterColorPresets[model] ~= nil and characterColorPresets[model][gCSPlayers[0].presetPalette] or nil end ---@description A function that gets the current character's palette number ---@added 1.12 ---- @param localIndex integer|nil ---- @return integer|nil +---@param localIndex integer? +---@return integer? local function character_get_current_palette_number(localIndex) if localIndex == nil then localIndex = 0 end return gCSPlayers[localIndex].presetPalette @@ -491,9 +642,10 @@ end ---@description A function that searches for a character's table posision based on name ---@added 1 ---@param name string -local function character_get_number_from_string(name) +---@return integer? +function character_get_number_from_string(name) if type(name) ~= TYPE_STRING then return nil end - for i = 2, #characterTable do + for i = 0, #characterTable do for a = 1, #characterTable[i] do if characterTable[i][a].name == name or characterTable[i][a].name == string_space_to_underscore(name) then return i @@ -503,11 +655,19 @@ local function character_get_number_from_string(name) return nil end ----@description A function that gets the current character's voice table ----@added 1.5 ----@param m MarioState -function character_get_voice(m) - return characterVoices[gCSPlayers[m.playerIndex].modelId] +---@description A function that searches for a character's table posision based on model +---@added 1.16 +---@param model integer|ModelExtendedId +---@return integer? +function character_get_number_from_model(model) + if type(model) ~= TYPE_INTEGER then return nil end + for i = 0, #characterTable do + for a = 1, #characterTable[i] do + if characterTable[i][a].model == model or characterTable[i][a].ogModel == model then + return i + end + end + end end -- Located in n-hud.lua @@ -574,24 +734,39 @@ end ---@description A function that renders a persons health meter texture table ---@added 1.12 ---@param localIndex integer +---@param health integer ---@param x integer ---@param y integer ---@param scaleX integer ---@param scaleY integer ---@forcedoc character_render_health_meter +---@description A function that renders a persons health meter texture table, with interpolation +---@added 1.16 +---@param localIndex integer +---@param health integer +---@param prevX integer +---@param prevY integer +---@param prevScaleX integer +---@param prevScaleY integer +---@param x integer +---@param y integer +---@param scaleX integer +---@param scaleY integer +---@forcedoc character_render_health_meter_interpolated + ---@description A function that locks a character under an unlock condition ---@added 1.10 ----@param charNum integer|nil The number of the Character you want to Lock ----@param unlockCondition function|boolean|nil The condition for if the character stays locked ----@param notify boolean|nil Toggles whether Character Select should notify the user when the character is unlocked +---@param charNum integer? The number of the Character you want to Lock +---@param unlockCondition function|boolean? The condition for if the character stays locked +---@param notify boolean? Toggles whether Character Select should notify the user when the character is unlocked local function character_set_locked(charNum, unlockCondition, notify) - if charNum == nil or charNum > #characterTable or charNum < 2 then return end + if charNum == nil or charNum > #characterTable or charNum < CT_MAX then return end if unlockCondition == nil then unlockCondition = false end if notify == nil then notify = true end - characterTable[charNum].locked = true + characterTable[charNum].locked = LOCKED_TRUE if currChar == charNum then - currChar = 1 + force_set_character() end characterUnlock[charNum] = { check = unlockCondition, @@ -601,28 +776,59 @@ end ---@description A function that sets a character under a specific category ---@added 1.14 ----@param charNum integer|nil The number of the Character you want to Lock ----@param category string The Category Name (Will create a new category if category does not exist) -local function character_set_category(charNum, category) - category = string_underscore_to_space(category) - local foundCategory = false +---@param charNum integer The number of the Character you want to set the category for +---@param categoryName string The Category Name (Will create a new category if category does not exist) +---@param forceIcon boolean Forces the icon to be used as a category icon +local function character_set_category(charNum, categoryName, forceIcon) + if not charNum then return end + if not categoryName then return end + categoryName = string_underscore_to_space(categoryName) + local foundCategory = nil for i = 1, #characterCategories do - if characterCategories[i] == category then - foundCategory = true + if characterCategories[i].name == categoryName then + foundCategory = characterCategories[i] end end - if not foundCategory then - table_insert(characterCategories, category) + if not foundCategory then + table.insert(characterCategories, {name = categoryName, icon1 = nil, icon2 = nil}) + foundCategory = characterCategories[#characterCategories] end - characterTable[charNum].category = characterTable[charNum].category .. "_" .. category + if forceIcon then + if not foundCategory.icon1 then + foundCategory.icon1 = charNum + elseif not foundCategory.icon2 then + foundCategory.icon2 = charNum + end + end + characterTable[charNum].category = characterTable[charNum].category .. "_" .. categoryName +end + +---@description A function that replaces dialog if you are playing as a specific character +---@added 1.16 +---@param charNum integer The number of the Character you want to replace dislog for +---@param dialogId integer|DialogId The ID of the dialog you want to replace +---@param unused integer Unused Dialog Variable +---@param linesPerBox integer Lines of text that appear in a single dialog +---@param leftOffset integer Dialog Box Posistion relitive to the left side of the screen +---@param width integer Verticle Position on screen (Dispite Variable Name) +---@param text string Dialog to be replaced with +local function character_replace_dialog(charNum, dialogId, unused, linesPerBox, leftOffset, width, text) + if modded == nil then modded = true end + characterDialog[charNum][dialogId] = { + unused = unused, + linesPerBox = linesPerBox, + leftOffset = leftOffset, + width = width, + text = text, + } end ---@header ---@forcedoc Menu_Functions ----@description A function that sets the big "Character Select" texture in the Character Select Menu +---@description (Deprecated) A function that sets the big "Character Select" texture in the Character Select Menu ---@added 1.7 ----@param texture TextureInfo|nil +---@param texture TextureInfo? ---@forcedoc header_set_texture ---@description A function that returns the version string @@ -662,7 +868,7 @@ end ---@description A function that forces they Character Select Menu state ---@added 1.8 ----@param bool boolean|nil Sets if the menu is open +---@param bool boolean? Sets if the menu is open local function set_menu_open(bool) if bool == nil then bool = true end menu = bool @@ -702,44 +908,64 @@ end ---@added 1 ---@return boolean local function is_options_open() - return options + return options ~= nil end ----@description A function that adds a line of credit to the CS Options' Credit section +---@description A function that adds credits to the CS Options' Credits section ---@added 1.10 ---@param modName string The Name of your Character Select Mod ----@param creditTo string The person you want to Credit ----@param creditFor string What the Person helped with -local function credit_add(modName, creditTo, creditFor) - if #creditTable > 1 then - for i = 2, #creditTable do - if modName == creditTable[i].packName then - table_insert(creditTable[i], {creditTo = creditTo, creditFor = creditFor}) - return - end +---@param creditee string The person you want to Credit +---@param credit string What the Person helped with +---@overload fun(modName: string, credits: string[][]) +local function credit_add(modName, creditee, credit) + local credits + for i = 2, #creditTable do + if modName == creditTable[i].packName then + credits = creditTable[i] end end - local i = #creditTable + 1 - creditTable[i] = { - packName = modName - } - table_insert(creditTable[i], {creditTo = creditTo, creditFor = creditFor}) + if not credits then + credits = { packName = modName } + table.insert(creditTable, credits) + end + + if type(creditee) == "table" then + for _, credit in ipairs(creditee) do + table.insert(credits, { creditee = credit[1], credit = credit[2] }) + end + else table.insert(credits, { creditee = creditee, credit = credit }) end end ---@description A function that sets if palettes are restricted (Default `false` unless a mod with the incompatible `gamemode` is on) ---@added 1.8 ---@param bool boolean local function restrict_palettes(bool) + if not network_is_server() then return end if bool == nil then bool = true end - stopPalettes = bool + gGlobalSyncTable.charSelectRestrictPalettes = bool and 2 or 0 end ---@description A function that sets if movesets are restricted (Default `false`) ---@added 1.10 ---@param bool boolean local function restrict_movesets(bool) + if not network_is_server() then return end if bool == nil then bool = true end - stopMovesets = bool + gGlobalSyncTable.charSelectRestrictMovesets = bool and 2 or optionTable[optionTableRef.restrictMovesets].toggle +end + +---@description A function that checks if palettes are restricted +---@added 1.15 +---@return boolean +local function are_palettes_restricted() + return gGlobalSyncTable.charSelectRestrictPalettes > 0 +end + +---@description A function that checks if movesets are restricted +---@added 1.15 +---@return boolean +local function are_movesets_restricted() + return gGlobalSyncTable.charSelectRestrictMovesets > 0 end ---@description A table that contains the local mario's controller before Character Select's menu cancels them @@ -759,17 +985,18 @@ local controller = { ---@description A function that adds an option to the Character Select Options Menu ---@added 1.9 ---@param name string The Name of the Option ----@param toggleDefault number|nil The default number that the option toggles to (Defaults to `0`) ----@param toggleMax number|nil The max number the option can be toggled to (Defaults to `1`) ----@param toggleNames table|nil A table of strings, each entry being for a toggle's name `{"Off", "On"}` ----@param description table|nil A table of strings, each entry being a new line `{"This toggle allows your", "character to feel everything."}` ----@param save boolean|nil Toggles whether the option retains between sessions (Defaults to `true`) +---@param toggleDefault number? The default number that the option toggles to (Defaults to `0`) +---@param toggleMax number? The max number the option can be toggled to (Defaults to `1`) +---@param toggleNames table? A table of strings, each entry being for a toggle's name `{"Off", "On"}` +---@param description table? A table of strings, each entry being a new line `{"This toggle allows your", "character to feel everything."}` +---@param save boolean? Toggles whether the option retains between sessions (Defaults to `true`) ---@return number --The table position of the option added local function add_option(name, toggleDefault, toggleMax, toggleNames, description, save) if save == nil then save = true end local saveName = string_space_to_underscore(name) - table_insert(optionTable, { + table.insert(optionTable, { name = type(name) == TYPE_STRING and name or "Unknown Toggle", + category = OPTION_API, toggle = nil, -- Set as nil for Failsafe to Catch toggleSaveName = save and saveName or nil, toggleDefault = type(toggleDefault) == TYPE_INTEGER and toggleDefault or 0, @@ -784,7 +1011,7 @@ end ---@description A function that gets an option's data from the Character Select Options Menu ---@added 1.9 ---@param tableNum integer The table position of the option ----@return table|nil +---@return table? local function get_option(tableNum) if type(tableNum) ~= TYPE_INTEGER then return nil end return optionTable[tableNum] @@ -793,11 +1020,8 @@ end ---@description A function that gets an option's status from the Character Select Options Menu ---@added 1.9 ---@param tableNum integer The table position of the option ----@return number|nil -local function get_options_status(tableNum) - if type(tableNum) ~= TYPE_INTEGER then return nil end - return optionTable[tableNum].toggle -end +---@return number? +---@forcedoc get_options_status ---@description A function that sets an option's status from the Character Select Options Menu ---@added 1.9 @@ -816,10 +1040,12 @@ end ---@description A function that sets the name to be replaced in Dialog, Default is `"Mario"` ---@added 1.10 ---@param name string ----@note This function does *NOT* change what NPCs will refer to your character as, this function is intended for Rom-Hack ports with alternate protagonists. ----@forcedoc dialog_set_replace_name +---@note This function does *NOT* change what NPCs will refer to your character as, this function is intended for Rom-Hack ports with alternate protagonists such as `"Luigi"`. +function dialog_set_replace_name(name) + DEFAULT_DIALOG_NAME = name +end ----@description A function that sets the preset palette for a network player forcefully +---@description A function that sets the preset palette for a network player forcefully their current Preset Palette ---@added 1.11 ---@param np NetworkPlayer ---@forcedoc update_preset_palette @@ -855,7 +1081,7 @@ end ---@param func function local function hook_allow_menu_open(func) if type(func) ~= TYPE_FUNCTION then return end - table_insert(allowMenu, func) + table.insert(allowMenu, func) end ---@description A function that allows you to render HUD Elements in the menu (Behind transistions such as Option and going in/out of menu) @@ -864,20 +1090,29 @@ end local function hook_render_in_menu(func, underText) if type(func) ~= TYPE_FUNCTION then return end if underText then - table_insert(renderInMenuTable.back, func) + table.insert(hookTableRenderInMenu.back, func) else - table_insert(renderInMenuTable.front, func) + table.insert(hookTableRenderInMenu.front, func) end end +---@description A function that runs the inputted function when the character is changed +---@added 1.15 +---@param func function +---@note Function gives `currChar` and `prevChar` as function inputs +local function hook_on_character_change(func) + if type(func) ~= TYPE_FUNCTION then return end + table.insert(hookTableOnCharacterChange, func) +end + ---@description A function that adds the necessary hooks in order for your pack to have function voicelines ---@added 1.12 ---@forcedoc config_character_sounds ----@description A function that allows you to hook a function, much like hook_event, to a specific character number +---@description A function that allows you to hook a function, much like `hook_event`, to a specific character number ---@added 1.10 ----@param charNum integer|nil ----@param hookEventType LuaHookedEventType|integer +---@param charNum integer +---@param hookEventType LuaHookedEventType|integer The hook event tied to a specific character. Supports the following hooks: `HOOK_MARIO_UPDATE`, `HOOK_BEFORE_MARIO_UPDATE`, `HOOK_BEFORE_PHYS_STEP`, `HOOK_ALLOW_PVP_ATTACK`, `HOOK_ON_PVP_ATTACK`, `HOOK_ON_INTERACT`, `HOOK_ALLOW_INTERACT`, `HOOK_ON_SET_MARIO_ACTION`, `HOOK_BEFORE_SET_MARIO_ACTION`, `HOOK_ON_DEATH`, `HOOK_ON_HUD_RENDER`, `HOOK_ON_HUD_RENDER_BEHIND`, `HOOK_ON_LEVEL_INIT`, `HOOK_ON_SYNC_VALID`, `HOOK_ON_OBJECT_RENDER`, `HOOK_ALLOW_FORCE_WATER_ACTION`, `HOOK_MARIO_OVERRIDE_FLOOR_CLASS` ` ---@param func function local function character_hook_moveset(charNum, hookEventType, func) if charNum > #characterTable then return end @@ -893,6 +1128,51 @@ local function character_get_moveset(charNum) return characterMovesets[charNum] end +---@description A function that returns if the character number is of a character that is included with CoopDX +---@added 1.15.1 +---@param charNum integer? The character number you want to check, Default is the local character +---@note Function was made in preperation for v1.16, in which the Base Cast are individual characters rather than Costumes of each other. +---@forcedoc character_is_vanilla + +---@description A function that adds an instrument track to a specific character +---@added 1.16 +---@param charNum integer The character number you want to add instruments for +---@param loadedAudio ModAudio The loaded instrumental audio file +---@note Original Song is `.ogg` File Format, `Mono` Channel, `G# Major Key`, `82` BPM, `93.659` Seconds Long, and is set to a sample rate of `22050`. If these requirements are not met then the song will not properly play, or incorrectly fit with the base theme. +local function character_add_menu_instrumental(charNum, loadedAudio) + audio_stream_set_looping(loadedAudio, true) + audio_stream_set_loop_points(loadedAudio, 0, 93.659*22050) + characterInstrumentals[charNum] = { + audio = loadedAudio, + volume = 0, + targetVolume = 0, + } +end + +---@description A function that adds graffiti art to the background of the menu +---@added 1.16 +---@param charNum integer +---@param texture TextureInfo +local function character_add_graffiti(charNum, texture) + characterGraffiti[charNum] = texture +end + +---@description A function that adds graffiti art to the background of the menu +---@added 1.16 +---@param charNum integer +local function character_get_graffiti(charNum) + return characterGraffiti[charNum] and characterGraffiti[charNum] or TEX_GRAFFITI_DEFAULT +end + +---@description A function that runs when Character Select Resets it's save data +---@added 1.16 +---@param func function +---@note Function gives `currChar` and `prevChar` as function inputs +local function hook_on_save_data_reset(func) + if type(func) ~= TYPE_FUNCTION then return end + table.insert(hookTableOnReset, func) +end + _G.charSelectExists = true _G.charSelect = { -- Character Functions -- @@ -900,14 +1180,19 @@ _G.charSelect = { character_add_costume = character_add_costume, character_edit = character_edit, character_edit_costume = character_edit_costume, + character_set_nickname = character_set_nickname, + character_get_nickname = character_get_nickname, character_add_voice = character_add_voice, character_add_caps = character_add_caps, character_get_caps = character_get_caps, + character_add_model_replacement = character_add_model_replacement, character_add_celebration_star = character_add_celebration_star, + character_add_peach_custom = character_add_peach_custom, + character_add_ending_toad_model = character_add_ending_toad_model, character_add_health_meter = character_add_health_meter, character_add_costume_health_meter = character_add_costume_health_meter, - character_add_course_texture = character_add_course, - character_add_costume_course_texture = character_add_costume_course, + character_add_course_texture = character_add_course_texture, + character_add_costume_course_texture = character_add_costume_course_texture, character_add_palette_preset = character_add_palette_preset, character_add_animations = character_add_animations, character_get_animations = character_get_animations, @@ -920,6 +1205,7 @@ _G.charSelect = { character_get_current_palette = character_get_current_palette, character_get_current_palette_number = character_get_current_palette_number, character_get_number_from_string = character_get_number_from_string, + character_get_number_from_model = character_get_number_from_model, character_get_voice = character_get_voice, character_get_life_icon = life_icon_from_local_index, -- Function located in n-hud.lua character_render_life_icon = render_life_icon_from_local_index, -- Function located in n-hud.lua @@ -929,17 +1215,27 @@ _G.charSelect = { character_render_star_icon_interpolated = render_star_icon_from_local_index_interpolated, -- Function located in n-hud.lua character_get_health_meter = health_meter_from_local_index, -- Function located in n-hud.lua character_render_health_meter = render_health_meter_from_local_index, -- Function located in n-hud.lua + character_render_health_meter_interpolated = render_health_meter_from_local_index_interpolated, -- Function located in n-hud.lua character_set_locked = character_set_locked, character_set_category = character_set_category, + character_replace_dialog = character_replace_dialog, character_get_moveset = character_get_moveset, + character_is_vanilla = character_is_vanilla, -- Function located in main.lua + character_add_menu_instrumental = character_add_menu_instrumental, + character_add_graffiti = character_add_graffiti, + character_get_graffiti = character_get_graffiti, + -- Located in voice.lua + voice = { + sound = custom_character_sound, + snore = custom_character_snore, + }, -- Hud Element Functions -- - hud_hide_element = hud_hide_element, -- Function located in n-hud.lua - hud_show_element = hud_show_element, -- Function located in n-hud.lua - hud_get_element = hud_get_element, -- Function located in n-hud.lua + hud_hide_element = hud_hide_element, -- Function located in hud.lua + hud_show_element = hud_show_element, -- Function located in hud.lua + hud_get_element = hud_get_element, -- Function located in hud.lua -- Menu Functions -- - header_set_texture = header_set_texture, -- Function located in main.lua version_get = version_get, version_get_full = version_get_full, is_menu_open = is_menu_open, @@ -953,10 +1249,12 @@ _G.charSelect = { credit_add = credit_add, restrict_palettes = restrict_palettes, restrict_movesets = restrict_movesets, + are_palettes_restricted = are_palettes_restricted, + are_movesets_restricted = are_movesets_restricted, -- Misc -- dialog_set_replace_name = dialog_set_replace_name, -- Function located in dialog.lua - update_preset_palette = placeholder, -- Function located in z-palettes.lua + update_preset_palette = update_preset_palette, -- Function located in palettes.lua -- Tables & Variables -- optionTableRef = optionTableRef, @@ -968,22 +1266,24 @@ _G.charSelect = { -- Character Select Hooks -- hook_allow_menu_open = hook_allow_menu_open, hook_render_in_menu = hook_render_in_menu, - config_character_sounds = placeholder, -- Function located in z-voice.lua + hook_on_character_change = hook_on_character_change, + hook_on_save_data_reset = hook_on_save_data_reset, + config_character_sounds = config_character_sounds, -- Function located in voice.lua character_hook_moveset = character_hook_moveset, } -- Replace base functions local obj_set_model_extended_original = obj_set_model_extended --- Replace obj_set_model_extended to error for mario models +-- Replace obj_set_model_extended to warn for mario models ---@ignore local function obj_set_model_extended(obj, modelInfo) for i = 0, MAX_PLAYERS - 1 do if gMarioStates[i].marioObj == obj then - log_to_console("Character Select: Mario Object cannot be changed with 'obj_set_model_extended' while Character Select is Active, please use 'character_edit'!!", CONSOLE_MESSAGE_WARNING) + log_to_console_once("Character Select: Mario Object cannot be changed with 'obj_set_model_extended' while Character Select is Active, please use 'character_edit'!!", CONSOLE_MESSAGE_WARNING) end end return obj_set_model_extended_original(obj, modelInfo) end -_G.obj_set_model_extended = obj_set_model_extended \ No newline at end of file +_G.obj_set_model_extended = obj_set_model_extended diff --git a/mods/character-select-coop/z-palettes.lua b/mods/character-select-coop/z-palettes.lua deleted file mode 100644 index 2300dd070..000000000 --- a/mods/character-select-coop/z-palettes.lua +++ /dev/null @@ -1,153 +0,0 @@ -if incompatibleClient then return 0 end - --- localize functions to improve performance - z-palettes.lua -local network_player_set_override_palette_color,network_player_reset_override_palette = network_player_set_override_palette_color,network_player_reset_override_palette - - -characterColorPresets = { - [E_MODEL_MARIO] = { - currPalette = 0, - [1] = { - [PANTS] = { r = 0x00, g = 0x00, b = 0xff }, - [SHIRT] = { r = 0xff, g = 0x00, b = 0x00 }, - [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, - [SHOES] = { r = 0x72, g = 0x1c, b = 0x0e }, - [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, - [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, - [CAP] = { r = 0xff, g = 0x00, b = 0x00 }, - [EMBLEM] = { r = 0xff, g = 0x00, b = 0x00 }, - }, - }, - [E_MODEL_LUIGI] = { - currPalette = 0, - [1] = { - [PANTS] = { r = 0x00, g = 0x00, b = 0xff }, - [SHIRT] = { r = 0x00, g = 0xff, b = 0x00 }, - [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, - [SHOES] = { r = 0x72, g = 0x1c, b = 0x0e }, - [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, - [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, - [CAP] = { r = 0x00, g = 0xff, b = 0x00 }, - [EMBLEM] = { r = 0x00, g = 0xff, b = 0x00 }, - }, - }, - [E_MODEL_TOAD_PLAYER] = { - currPalette = 0, - [1] = { - [PANTS] = { r = 0xff, g = 0xff, b = 0xff }, - [SHIRT] = { r = 0x4c, g = 0x2c, b = 0xd3 }, - [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, - [SHOES] = { r = 0x68, g = 0x40, b = 0x1b }, - [HAIR] = { r = 0x73, g = 0x06, b = 0x00 }, - [SKIN] = { r = 0xfe, g = 0xd5, b = 0xa1 }, - [CAP] = { r = 0xff, g = 0x00, b = 0x00 }, - [EMBLEM] = { r = 0xff, g = 0x00, b = 0x00 }, - }, - }, - [E_MODEL_WALUIGI] = { - currPalette = 0, - [1] = { - [PANTS] = { r = 0x16, g = 0x16, b = 0x27 }, - [SHIRT] = { r = 0x61, g = 0x26, b = 0xb0 }, - [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, - [SHOES] = { r = 0xfe, g = 0x76, b = 0x00 }, - [HAIR] = { r = 0x73, g = 0x53, b = 0x00 }, - [SHOES] = { r = 0xfe, g = 0x76, b = 0x00 }, - [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, - [CAP] = { r = 0x61, g = 0x26, b = 0xb0 }, - [EMBLEM] = { r = 0xff, g = 0xde, b = 0x00 }, - }, - }, - [E_MODEL_WARIO] = { - currPalette = 0, - [1] = { - [PANTS] = { r = 0x7f, g = 0x20, b = 0x7a }, - [SHIRT] = { r = 0xff, g = 0xbd, b = 0x00 }, - [GLOVES] = { r = 0xff, g = 0xff, b = 0xff }, - [SHOES] = { r = 0x0e, g = 0x72, b = 0x1c }, - [HAIR] = { r = 0x73, g = 0x53, b = 0x00 }, - [SHOES] = { r = 0x0e, g = 0x72, b = 0x1c }, - [SKIN] = { r = 0xfe, g = 0xc1, b = 0x79 }, - [CAP] = { r = 0xff, g = 0xbd, b = 0x00 }, - [EMBLEM] = { r = 0x00, g = 0x00, b = 0xff }, - }, - } -} - -local paletteLoop = #characterColorPresets[E_MODEL_MARIO][1] - -local function network_player_set_full_override_palette(networkPlayer, colorTable) - if colorTable == nil then return end - for i = 0, paletteLoop do - network_player_set_override_palette_color(networkPlayer, i, colorTable[i]) - end -end - ---- @param np NetworkPlayer -local function update_preset_palette(np) - local p = gCSPlayers[np.localIndex] - local modelId = p.modelId - if np.connected and gCSPlayers[0].presetPalette > 0 and characterColorPresets[modelId] and not stopPalettes then - network_player_set_full_override_palette(np, characterColorPresets[modelId][p.presetPalette]) - end -end - --- API funcs -_G.charSelect.update_preset_palette = update_preset_palette - -local stallTimer = 5 - -local prevPresetPalette = {} -local prevModel = {} - -local function mario_update(m) - local np = gNetworkPlayers[m.playerIndex] - local p = gCSPlayers[m.playerIndex] - local currAlt = characterTable[currChar].currAlt - - if m.playerIndex == 0 and not p.isUpdating then - p.isUpdating = true - for i = 1, MAX_PLAYERS - 1 do - prevPresetPalette[i] = gCSPlayers[i].presetPalette - prevModel[i] = gCSPlayers[i].modelId - end - end - - if m.playerIndex == 0 then - if not stopPalettes then - gCSPlayers[0].presetPalette = characterColorPresets[gCSPlayers[0].modelId] ~= nil and characterColorPresets[gCSPlayers[0].modelId].currPalette or 0 - end - - if stallTimer > 0 then - stallTimer = stallTimer - 1 - end - end - - if np.connected then - if p.presetPalette == nil or characterColorPresets[p.modelId] == nil then - if p.presetPalette == nil then - prevPresetPalette[m.playerIndex] = 0 - end - p.presetPalette = 0 - end - - if (prevPresetPalette[m.playerIndex] ~= p.presetPalette or prevModel[m.playerIndex] ~= p.modelId) then - if p.presetPalette == 0 or not characterColorPresets[p.modelId] then - network_player_reset_override_palette(np) - end - end - - prevPresetPalette[m.playerIndex] = p.presetPalette - prevModel[m.playerIndex] = p.modelId - - if p.presetPalette > 0 and characterColorPresets[p.modelId] and not stopPalettes then - network_player_set_full_override_palette(np, characterColorPresets[p.modelId][p.presetPalette]) - end - else - if p.isUpdating then - p.isUpdating = false - end - end -end - -hook_event(HOOK_MARIO_UPDATE, mario_update) diff --git a/mods/character-select-coop/z-voice.lua b/mods/character-select-coop/z-voice.lua deleted file mode 100644 index 8a9c353cb..000000000 --- a/mods/character-select-coop/z-voice.lua +++ /dev/null @@ -1,223 +0,0 @@ -if incompatibleClient then return 0 end - --- localize functions to improve performance - z-voice.lua -local type,audio_sample_stop,audio_sample_load,math_random,audio_sample_play,is_game_paused,table_insert,play_character_sound = type,audio_sample_stop,audio_sample_load,math.random,audio_sample_play,is_game_paused,table.insert,play_character_sound - --- rewritten custom voice system for Character Select --- by Agent X - --- will need some revising in the future, but this will do for now. - -local SLEEP_TALK_SNORES = 8 -local STARTING_SNORE = 46 -local SLEEP_TALK_START = STARTING_SNORE + 49 -local SLEEP_TALK_END = SLEEP_TALK_START + SLEEP_TALK_SNORES -local stallTimer = 0 -local stallSayLine = 5 - -local TYPE_TABLE = "table" -local TYPE_USERDATA = "userdata" -local TYPE_STRING = "string" -local function check_sound_exists(sound) - if sound == nil then return false end - local soundType = type(sound) - if soundType == TYPE_USERDATA and sound._pointer ~= nil then - return true - elseif soundType == TYPE_STRING then - sound = "sound/"..sound - return (mod_file_exists(sound)) - end - return false -end - -local function stop_all_custom_character_sounds() - -- run through each player - for i = 0, MAX_PLAYERS - 1 do - local m = gMarioStates[i] - -- get the voice table, if there is one - local voiceTable = character_get_voice(m) - if voiceTable ~= nil then - -- run through each sample - for sound in pairs(voiceTable) do - -- if the sample is found, try to stop it - if voiceTable[sound] ~= nil and type(voiceTable[sound]) ~= "string" then - -- if there's no pointer then it must be a sound clip table - if voiceTable[sound]._pointer == nil then - for voice in pairs(voiceTable[sound]) do - if type(voiceTable[sound][voice]) == "string" then - break - end - audio_sample_stop(voiceTable[sound][voice]) - end - else - audio_sample_stop(voiceTable[sound]) - end - end - end - end - end -end - ---[[local function stop_custom_character_sound(m, sound) - local voiceTable = character_get_voice(m) - -- if there's no pointer then it must be a sound clip table - if type(voiceTable[sound]) == "string" then return end - if voiceTable[sound]._pointer == nil then - for voice in pairs(voiceTable[sound]) do - if type(voiceTable[voice]) == "string" then - break - end - audio_sample_stop(voiceTable[sound][voice]) - end - else - audio_sample_stop(voiceTable[sound]) - end -end]] - -local playerSample = {} -for i = 0, MAX_PLAYERS - 1 do - playerSample[i] = nil -end - ---- @param m MarioState ---- @param sound CharacterSound -local function custom_character_sound(m, sound) - if m.playerIndex == 0 then - if stallTimer < stallSayLine then - return NO_SOUND - end - end - local index = m.playerIndex - if check_sound_exists(playerSample[index]) and type(playerSample[index]) ~= TYPE_STRING then - audio_sample_stop(playerSample[index]) - end - if optionTable[optionTableRef.localVoices].toggle == 0 then return NO_SOUND end - - -- get the voice table - local voiceTable = character_get_voice(m) - if voiceTable == nil then return end - -- load samples that haven't been loaded - for voice, name in pairs(voiceTable) do - if check_sound_exists(voiceTable[voice]) and type(voiceTable[voice]) == "string" then - local load = audio_sample_load(name) - if load ~= nil then - voiceTable[voice] = load - end - end - end - - -- get the sample to play - local voice = voiceTable[sound] - if voice == nil then return NO_SOUND end - playerSample[index] = voice - -- if there's no pointer then it must be a sound clip table - if voice._pointer == nil and type(voice) ~= TYPE_STRING then - -- run through each sample and load in any samples that haven't been loaded - for i, name in pairs(voice) do - if check_sound_exists(voice[i]) and type(voice[i]) == "string" then - local load = audio_sample_load(name) - if load ~= nil then - voice[i] = load - end - end - end - if #voice ~= 0 then - -- choose a random sample - playerSample[index] = voice[math_random(#voice)] - end - end - - -- Play the sample - if check_sound_exists(playerSample[index]) then - if sound == CHAR_SOUND_SNORING1 or sound == CHAR_SOUND_SNORING2 or sound == CHAR_SOUND_SNORING3 then - audio_sample_play(playerSample[index], m.pos, 0.5) - else - audio_sample_play(playerSample[index], m.pos, 1.0) - end - return NO_SOUND - end -end - ---- @param m MarioState -local function custom_character_snore(m) - if is_game_paused() or optionTable[optionTableRef.localVoices].toggle == 0 then return end - - if m.action ~= ACT_SLEEPING then - return - elseif m.actionState ~= 2 or (m.flags & MARIO_MARIO_SOUND_PLAYED) == 0 then - return - end - - local voice = character_get_voice(m) - if voice == nil then return end - local snoreTable = voice[CHAR_SOUND_SNORING3] - if snoreTable == nil or snoreTable._pointer ~= nil then - snoreTable = {} - for i = CHAR_SOUND_SNORING1, CHAR_SOUND_SNORING3 do - if voice[i] ~= nil then - table_insert(snoreTable, voice[i]) - end - end - end - - local animFrame = m.marioObj.header.gfx.animInfo.animFrame - if snoreTable ~= nil and #snoreTable >= 2 then - if animFrame == 2 and m.actionTimer < SLEEP_TALK_START then - custom_character_sound(m, snoreTable[2]) - elseif animFrame == 25 then - if #snoreTable >= 3 then - m.actionTimer = m.actionTimer + 1 - if m.actionTimer >= SLEEP_TALK_END then - m.actionTimer = STARTING_SNORE - end - if m.actionTimer == SLEEP_TALK_START then - play_character_sound(m, CHAR_SOUND_SNORING3) - elseif m.actionTimer < SLEEP_TALK_START then - play_character_sound(m, CHAR_SOUND_SNORING1) - end - else - play_character_sound(m, CHAR_SOUND_SNORING1) - end - end - elseif animFrame == 2 then - play_character_sound(m, CHAR_SOUND_SNORING2) - - elseif animFrame == 25 then - play_character_sound(m, CHAR_SOUND_SNORING1) - end -end - -local function update() - if is_game_paused() then - stop_all_custom_character_sounds() - end -end - -hook_event(HOOK_UPDATE, update) -hook_event(HOOK_ON_LEVEL_INIT, stop_all_custom_character_sounds) - -_G.charSelect.voice = { - sound = custom_character_sound, - snore = custom_character_snore, -} - --- Must be ran on startup -local function config_character_sounds() - hook_event(HOOK_CHARACTER_SOUND, custom_character_sound) - --hook_event(HOOK_MARIO_UPDATE, custom_character_snore) - cs_hook_mario_update(custom_character_snore) -end -_G.charSelect.config_character_sounds = config_character_sounds - --- Join sound -local function mario_update(m) - if m.playerIndex ~= 0 then return end - if stallTimer == stallSayLine then - play_character_sound(m, CHAR_SOUND_OKEY_DOKEY) - stallTimer = stallTimer + 1 - elseif stallTimer < stallSayLine then - stallTimer = stallTimer + 1 - end -end ---hook_event(HOOK_MARIO_UPDATE, mario_update) -cs_hook_mario_update(mario_update) \ No newline at end of file diff --git a/src/engine/lighting_engine.c b/src/engine/lighting_engine.c index c6f010a04..7466a5d80 100644 --- a/src/engine/lighting_engine.c +++ b/src/engine/lighting_engine.c @@ -52,7 +52,7 @@ void le_set_tone_mapping(enum LEToneMapping toneMapping) { sToneMapping = toneMapping; } -void le_get_ambient_color(OUT Color out) { +void le_get_ambient_color(VEC_OUT Color out) { color_copy(out, gLEAmbientColor); } @@ -282,7 +282,7 @@ bool le_light_exists(s16 id) { return sLights[id].added; } -void le_get_light_pos(s16 id, OUT Vec3f out) { +void le_get_light_pos(s16 id, VEC_OUT Vec3f out) { if (id < 0 || id >= LE_MAX_LIGHTS) { return; } struct LELight* light = &sLights[id]; @@ -300,7 +300,7 @@ void le_set_light_pos(s16 id, f32 x, f32 y, f32 z) { light->posZ = z; } -void le_get_light_color(s16 id, OUT Color out) { +void le_get_light_color(s16 id, VEC_OUT Color out) { if (id < 0 || id >= LE_MAX_LIGHTS) { return; } struct LELight* light = &sLights[id]; diff --git a/src/engine/lighting_engine.h b/src/engine/lighting_engine.h index 0b5388027..669e31d63 100644 --- a/src/engine/lighting_engine.h +++ b/src/engine/lighting_engine.h @@ -3,7 +3,7 @@ #include "types.h" -#define LE_MAX_LIGHTS 256 +#define LE_MAX_LIGHTS 512 enum LEMode { LE_MODE_AFFECT_ALL_SHADED_AND_COLORED, @@ -29,17 +29,17 @@ enum LEMode le_get_mode(void); /* |description|Sets the lighting engine's tone mapping mode to `toneMapping`|descriptionEnd|*/ void le_set_tone_mapping(enum LEToneMapping toneMapping); /* |description|Outputs the lighting engine's ambient color to `out`|descriptionEnd| */ -void le_get_ambient_color(OUT Color out); +void le_get_ambient_color(VEC_OUT Color out); /* |description|Sets the lighting engine ambient color|descriptionEnd| */ void le_set_ambient_color(u8 r, u8 g, u8 b); -void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, OUT Color out); +void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, VEC_OUT Color out); /* |description|Calculates the lighting with `lightIntensityScalar` at a position and outputs the color in `out`|descriptionEnd|*/ -void le_calculate_lighting_color(Vec3f pos, OUT Color out, f32 lightIntensityScalar); +void le_calculate_lighting_color(Vec3f pos, VEC_OUT Color out, f32 lightIntensityScalar); /* |description|Calculates the lighting with `lightIntensityScalar` at a position and with a normal and outputs the color in `out`|descriptionEnd|*/ -void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, OUT Color out, f32 lightIntensityScalar); +void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, VEC_OUT Color out, f32 lightIntensityScalar); /* |description|Calculates the lighting direction from a position and outputs the result in `out`|descriptionEnd| */ -void le_calculate_lighting_dir(Vec3f pos, OUT Vec3f out); +void le_calculate_lighting_dir(Vec3f pos, VEC_OUT Vec3f out); /* |description|Adds a lighting engine point light at `x`, `y`, `z` with color `r`, `g`, `b` and `radius` with `intensity`|descriptionEnd| */ s16 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity); /* |description|Removes a lighting engine point light corresponding to `id`|descriptionEnd| */ @@ -49,11 +49,11 @@ s16 le_get_light_count(void); /* |description|Checks if a lighting engine point light corresponding to `id` exists|descriptionEnd| */ bool le_light_exists(s16 id); /* |description|Outputs a lighting engine point light's position to `out`|descriptionEnd| */ -void le_get_light_pos(s16 id, OUT Vec3f out); +void le_get_light_pos(s16 id, VEC_OUT Vec3f out); /* |description|Sets a lighting engine point light's position to `x`, `y`, `z`|descriptionEnd| */ void le_set_light_pos(s16 id, f32 x, f32 y, f32 z); /* |description|Outputs a lighting engine point light's color to `out`|descriptionEnd| */ -void le_get_light_color(s16 id, OUT Color out); +void le_get_light_color(s16 id, VEC_OUT Color out); /* |description|Sets a lighting engine point light's color to `r`, `g`, `b`|descriptionEnd| */ void le_set_light_color(s16 id, u8 r, u8 g, u8 b); /* |description|Gets a lighting engine point light's `radius`|descriptionEnd| */ diff --git a/src/engine/math_util.c b/src/engine/math_util.c index a5a82e602..f13dc051f 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -133,7 +133,7 @@ OPTIMIZE_O3 f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec) { * [0, 0, 0, 0, 1, 2, ... n-1, n, n, n, n] * TODO: verify the classification of the spline / figure out how polynomials were computed */ -OPTIMIZE_O3 void spline_get_weights(struct MarioState* m, OUT Vec4f result, f32 t, UNUSED s32 c) { +OPTIMIZE_O3 void spline_get_weights(struct MarioState* m, VEC_OUT Vec4f result, f32 t, UNUSED s32 c) { if (!m) { return; } f32 tinv = 1 - t; f32 tinv2 = tinv * tinv; @@ -195,7 +195,7 @@ OPTIMIZE_O3 void anim_spline_init(struct MarioState* m, Vec4s *keyFrames) { * anim_spline_init should be called before polling for vectors. * Returns TRUE when the last point is reached, FALSE otherwise. */ -OPTIMIZE_O3 s32 anim_spline_poll(struct MarioState* m, OUT Vec3f result) { +OPTIMIZE_O3 s32 anim_spline_poll(struct MarioState* m, VEC_OUT Vec3f result) { if (!m) { return 0; } Vec4f weights = { 0 }; s32 i; @@ -269,7 +269,7 @@ Vec3f gVec3fOne = { 1.0f, 1.0f, 1.0f }; * Returns a vector rotated around the z axis, then the x axis, then the y * axis. */ -OPTIMIZE_O3 Vec3fp vec3f_rotate_zxy(OUT Vec3f dest, Vec3s rotate) { +OPTIMIZE_O3 Vec3fp vec3f_rotate_zxy(VEC_OUT Vec3f dest, Vec3s rotate) { Vec3f v = { dest[0], dest[1], dest[2] }; f32 sx = sins(rotate[0]); @@ -294,7 +294,7 @@ OPTIMIZE_O3 Vec3fp vec3f_rotate_zxy(OUT Vec3f dest, Vec3s rotate) { // Rodrigues' formula // dest = v * cos(r) + (n x v) * sin(r) + n * (n . v) * (1 - cos(r)) -OPTIMIZE_O3 Vec3fp vec3f_rotate_around_n(OUT Vec3f dest, Vec3f v, Vec3f n, s16 r) { +OPTIMIZE_O3 Vec3fp vec3f_rotate_around_n(VEC_OUT Vec3f dest, Vec3f v, Vec3f n, s16 r) { Vec3f nvCross; vec3f_cross(nvCross, n, v); f32 nvDot = vec3f_dot(n, v); @@ -306,7 +306,7 @@ OPTIMIZE_O3 Vec3fp vec3f_rotate_around_n(OUT Vec3f dest, Vec3f v, Vec3f n, s16 r return dest; } -OPTIMIZE_O3 Vec3fp vec3f_project(OUT Vec3f dest, Vec3f v, Vec3f onto) { +OPTIMIZE_O3 Vec3fp vec3f_project(VEC_OUT Vec3f dest, Vec3f v, Vec3f onto) { f32 numerator = vec3f_dot(v, onto); f32 denominator = vec3f_dot(onto, onto); if (denominator == 0) { @@ -318,7 +318,7 @@ OPTIMIZE_O3 Vec3fp vec3f_project(OUT Vec3f dest, Vec3f v, Vec3f onto) { return dest; } -OPTIMIZE_O3 Vec3fp vec3f_transform(OUT Vec3f dest, Vec3f v, Vec3f translation, Vec3s rotation, Vec3f scale) { +OPTIMIZE_O3 Vec3fp vec3f_transform(VEC_OUT Vec3f dest, Vec3f v, Vec3f translation, Vec3s rotation, Vec3f scale) { vec3f_copy(dest, v); // scale @@ -340,7 +340,7 @@ OPTIMIZE_O3 Vec3fp vec3f_transform(OUT Vec3f dest, Vec3f v, Vec3f translation, V * of that vector, as well as the yaw and pitch angles. * Basically it converts the direction to spherical coordinates. */ -OPTIMIZE_O3 void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw) { +OPTIMIZE_O3 void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, RET f32 *dist, RET s16 *pitch, RET s16 *yaw) { f32 x = to[0] - from[0]; f32 y = to[1] - from[1]; f32 z = to[2] - from[2]; @@ -354,7 +354,7 @@ OPTIMIZE_O3 void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 * * Construct the 'to' point which is distance 'dist' away from the 'from' position, * and has the angles pitch and yaw. */ -OPTIMIZE_O3 void vec3f_set_dist_and_angle(Vec3f from, OUT Vec3f to, f32 dist, s16 pitch, s16 yaw) { +OPTIMIZE_O3 void vec3f_set_dist_and_angle(Vec3f from, VEC_OUT Vec3f to, f32 dist, s16 pitch, s16 yaw) { to[0] = from[0] + dist * coss(pitch) * sins(yaw); to[1] = from[1] + dist * sins(pitch); to[2] = from[2] + dist * coss(pitch) * coss(yaw); @@ -365,7 +365,7 @@ OPTIMIZE_O3 void vec3f_set_dist_and_angle(Vec3f from, OUT Vec3f to, f32 dist, s1 * It is similar to vec3f_cross, but it calculates the vectors (c-b) and (b-a) * at the same time. */ -OPTIMIZE_O3 Vec3fp find_vector_perpendicular_to_plane(OUT Vec3f dest, Vec3f a, Vec3f b, Vec3f c) { +OPTIMIZE_O3 Vec3fp find_vector_perpendicular_to_plane(VEC_OUT Vec3f dest, Vec3f a, Vec3f b, Vec3f c) { dest[0] = (b[1] - a[1]) * (c[2] - b[2]) - (c[1] - b[1]) * (b[2] - a[2]); dest[1] = (b[2] - a[2]) * (c[0] - b[0]) - (c[2] - b[2]) * (b[0] - a[0]); dest[2] = (b[0] - a[0]) * (c[1] - b[1]) - (c[0] - b[0]) * (b[1] - a[1]); @@ -412,7 +412,7 @@ Mat4 gMat4Zero = { * at the position 'to'. The up-vector is assumed to be (0, 1, 0), but the 'roll' * angle allows a bank rotation of the camera. */ -OPTIMIZE_O3 void mtxf_lookat(OUT Mat4 mtx, Vec3f from, Vec3f to, s16 roll) { +OPTIMIZE_O3 void mtxf_lookat(VEC_OUT Mat4 mtx, Vec3f from, Vec3f to, s16 roll) { Vec3f forward, right, up; f32 sinRoll, cosRoll; f32 dx, dz, xzDist; @@ -480,7 +480,7 @@ OPTIMIZE_O3 void mtxf_lookat(OUT Mat4 mtx, Vec3f from, Vec3f to, s16 roll) { * Build a matrix that rotates around the z axis, then the x axis, then the y * axis, and then translates. */ -OPTIMIZE_O3 void mtxf_rotate_zxy_and_translate(OUT Mat4 dest, Vec3f translate, Vec3s rotate) { +OPTIMIZE_O3 void mtxf_rotate_zxy_and_translate(VEC_OUT Mat4 dest, Vec3f translate, Vec3s rotate) { f32 sx = sins(rotate[0]); f32 cx = coss(rotate[0]); @@ -513,7 +513,7 @@ OPTIMIZE_O3 void mtxf_rotate_zxy_and_translate(OUT Mat4 dest, Vec3f translate, V * Build a matrix that rotates around the x axis, then the y axis, then the z * axis, and then translates. */ -OPTIMIZE_O3 void mtxf_rotate_xyz_and_translate(OUT Mat4 dest, Vec3f b, Vec3s c) { +OPTIMIZE_O3 void mtxf_rotate_xyz_and_translate(VEC_OUT Mat4 dest, Vec3f b, Vec3s c) { f32 sx = sins(c[0]); f32 cx = coss(c[0]); @@ -550,7 +550,7 @@ OPTIMIZE_O3 void mtxf_rotate_xyz_and_translate(OUT Mat4 dest, Vec3f b, Vec3s c) * 'position' is the position of the object in the world * 'angle' rotates the object while still facing the camera. */ -OPTIMIZE_O3 void mtxf_billboard(OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) { +OPTIMIZE_O3 void mtxf_billboard(VEC_OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) { dest[0][0] = coss(angle); dest[0][1] = sins(angle); dest[0][2] = 0; @@ -573,7 +573,7 @@ OPTIMIZE_O3 void mtxf_billboard(OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 ang } // straight up mtxf_billboard but minus the dest[1][n] lines. transform for cylindrical billboards -OPTIMIZE_O3 void mtxf_cylboard(OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) { +OPTIMIZE_O3 void mtxf_cylboard(VEC_OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) { dest[0][0] = coss(angle); dest[0][1] = sins(angle); dest[0][2] = 0; @@ -602,7 +602,7 @@ OPTIMIZE_O3 void mtxf_cylboard(OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angl * 'yaw' is the angle which it should face * 'pos' is the object's position in the world */ -OPTIMIZE_O3 void mtxf_align_terrain_normal(OUT Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw) { +OPTIMIZE_O3 void mtxf_align_terrain_normal(VEC_OUT Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw) { Vec3f lateralDir; Vec3f leftDir; Vec3f forwardDir; @@ -645,7 +645,7 @@ OPTIMIZE_O3 void mtxf_align_terrain_normal(OUT Mat4 dest, Vec3f upDir, Vec3f pos * 'pos' is the object's position in the world * 'radius' is the distance from each triangle vertex to the center */ -OPTIMIZE_O3 void mtxf_align_terrain_triangle(OUT Mat4 mtx, Vec3f pos, s16 yaw, f32 radius) { +OPTIMIZE_O3 void mtxf_align_terrain_triangle(VEC_OUT Mat4 mtx, Vec3f pos, s16 yaw, f32 radius) { struct Surface *sp74; Vec3f point0; Vec3f point1; @@ -716,7 +716,7 @@ OPTIMIZE_O3 void mtxf_align_terrain_triangle(OUT Mat4 mtx, Vec3f pos, s16 yaw, f * The resulting matrix represents first applying transformation b and * then a. */ -OPTIMIZE_O3 void mtxf_mul(OUT Mat4 dest, Mat4 a, Mat4 b) { +OPTIMIZE_O3 void mtxf_mul(VEC_OUT Mat4 dest, Mat4 a, Mat4 b) { Mat4 tmp; for (s32 i = 0; i < 4; i++) { for (s32 j = 0; j < 4; j++) { @@ -734,7 +734,7 @@ OPTIMIZE_O3 void mtxf_mul(OUT Mat4 dest, Mat4 a, Mat4 b) { * to the point. Note that the bottom row is assumed to be [0, 0, 0, 1], which is * true for transformation matrices if the translation has a w component of 1. */ -OPTIMIZE_O3 Vec3sp mtxf_mul_vec3s(Mat4 mtx, OUT Vec3s b) { +OPTIMIZE_O3 Vec3sp mtxf_mul_vec3s(Mat4 mtx, VEC_OUT Vec3s b) { f32 x = b[0]; f32 y = b[1]; f32 z = b[2]; @@ -749,7 +749,7 @@ OPTIMIZE_O3 Vec3sp mtxf_mul_vec3s(Mat4 mtx, OUT Vec3s b) { /** * Set 'mtx' to a transformation matrix that rotates around the z axis. */ -OPTIMIZE_O3 void mtxf_rotate_xy(OUT Mat4 mtx, s16 angle) { +OPTIMIZE_O3 void mtxf_rotate_xy(VEC_OUT Mat4 mtx, s16 angle) { mtxf_identity(mtx); mtx[0][0] = coss(angle); mtx[0][1] = sins(angle); @@ -770,7 +770,7 @@ OPTIMIZE_O3 void mtxf_rotate_xy(OUT Mat4 mtx, s16 angle) { * furthermore, this is currently only used to get the inverse of the camera transform * because that is always orthonormal, the determinant will never be 0, so that check is removed */ -OPTIMIZE_O3 void mtxf_inverse(OUT Mat4 dest, Mat4 src) { +OPTIMIZE_O3 void mtxf_inverse(VEC_OUT Mat4 dest, Mat4 src) { Mat4 buf; // calculating the determinant has been reduced since the check is removed @@ -809,7 +809,7 @@ OPTIMIZE_O3 void mtxf_inverse(OUT Mat4 dest, Mat4 src) { * Compute the inverse of 'src' and put it into 'dest' but it can be a non-affine matrix. * Obtains the inverse via Gauss-Jordan elimination. */ -OPTIMIZE_O3 bool mtxf_inverse_non_affine(OUT Mat4 dest, Mat4 src) { +OPTIMIZE_O3 bool mtxf_inverse_non_affine(VEC_OUT Mat4 dest, Mat4 src) { // augmented matrix [ src | I ] f32 aug[4][8]; for (s32 i = 0; i < 4; i++) { @@ -871,7 +871,7 @@ OPTIMIZE_O3 bool mtxf_inverse_non_affine(OUT Mat4 dest, Mat4 src) { * objMtx back from screen orientation to world orientation, and then subtracting * the camera position. */ -OPTIMIZE_O3 Vec3fp get_pos_from_transform_mtx(OUT Vec3f dest, Mat4 objMtx, Mat4 camMtx) { +OPTIMIZE_O3 Vec3fp get_pos_from_transform_mtx(VEC_OUT Vec3f dest, Mat4 objMtx, Mat4 camMtx) { f32 camX = camMtx[3][0] * camMtx[0][0] + camMtx[3][1] * camMtx[0][1] + camMtx[3][2] * camMtx[0][2]; f32 camY = camMtx[3][0] * camMtx[1][0] + camMtx[3][1] * camMtx[1][1] + camMtx[3][2] * camMtx[1][2]; f32 camZ = camMtx[3][0] * camMtx[2][0] + camMtx[3][1] * camMtx[2][1] + camMtx[3][2] * camMtx[2][2]; diff --git a/src/engine/math_util.h b/src/engine/math_util.h index 16e30eba2..888a64adf 100644 --- a/src/engine/math_util.h +++ b/src/engine/math_util.h @@ -137,7 +137,7 @@ OPTIMIZE_O3 f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec); /* |description| Computes spline interpolation weights for a given parameter `t` and stores these weights in `result`. This is used in spline-based animations to find intermediate positions between keyframes |descriptionEnd| */ -OPTIMIZE_O3 void spline_get_weights(struct MarioState* m, OUT Vec4f result, f32 t, UNUSED s32 c); +OPTIMIZE_O3 void spline_get_weights(struct MarioState* m, VEC_OUT Vec4f result, f32 t, UNUSED s32 c); /* |description| Initializes a spline-based animation for the `MarioState` structure `m` using the provided array of 3D signed-integer vectors `keyFrames`. This sets up the animation so that it can be advanced by polling @@ -147,7 +147,7 @@ OPTIMIZE_O3 void anim_spline_init(struct MarioState* m, Vec4s *keyFrames); /* |description| Advances the spline-based animation associated with `m` and stores the current interpolated position in `result`. It returns the animation's status, allowing the caller to determine if the animation is ongoing or has completed |descriptionEnd| */ -OPTIMIZE_O3 s32 anim_spline_poll(struct MarioState* m, OUT Vec3f result); +OPTIMIZE_O3 s32 anim_spline_poll(struct MarioState* m, VEC_OUT Vec3f result); /////////// // Vec2f // @@ -176,37 +176,37 @@ OPTIMIZE_O3 s32 anim_spline_poll(struct MarioState* m, OUT Vec3f result); /* |description| Rotates the 3D floating-point vector `v` by the angles specified in the 3D signed-integer vector `rotate`, applying the rotations in the order Z, then X, then Y. The rotated vector replaces `v` |descriptionEnd| */ -OPTIMIZE_O3 Vec3fp vec3f_rotate_zxy(OUT Vec3f v, Vec3s rotate); +OPTIMIZE_O3 Vec3fp vec3f_rotate_zxy(VEC_OUT Vec3f v, Vec3s rotate); /* |description| Rotates the 3D floating-point vector `v` around the vector `n`, given a rotation `r` (in sm64 angle units), and stores the result in `dest` |descriptionEnd| */ -OPTIMIZE_O3 Vec3fp vec3f_rotate_around_n(OUT Vec3f dest, Vec3f v, Vec3f n, s16 r); +OPTIMIZE_O3 Vec3fp vec3f_rotate_around_n(VEC_OUT Vec3f dest, Vec3f v, Vec3f n, s16 r); /* |description| Projects the 3D floating-point vector `v` onto another 3D floating-point vector `onto`. The resulting projection, stored in `dest`, represents how much of `v` lies along the direction of `onto` |descriptionEnd| */ -OPTIMIZE_O3 Vec3fp vec3f_project(OUT Vec3f dest, Vec3f v, Vec3f onto); +OPTIMIZE_O3 Vec3fp vec3f_project(VEC_OUT Vec3f dest, Vec3f v, Vec3f onto); /* |description| Scales the 3D floating-point vector `v` by the vector `scale`, then rotates it by the rotation vector `rotation`, and finally translates it by the vector `translation`. The resulting vector is stored in `dest` |descriptionEnd| */ -OPTIMIZE_O3 Vec3fp vec3f_transform(OUT Vec3f dest, Vec3f v, Vec3f translation, Vec3s rotation, Vec3f scale); +OPTIMIZE_O3 Vec3fp vec3f_transform(VEC_OUT Vec3f dest, Vec3f v, Vec3f translation, Vec3s rotation, Vec3f scale); /* |description| -Calculates the distance between two points in 3D space (`from` and `to`), as well as the pitch and yaw angles that describe the direction from `from` to `to`. The results are stored in `dist`, `pitch`, and `yaw` +Calculates the distance between two points in 3D space (`from` and `to`), as well as the pitch and yaw angles that describe the direction from `from` to `to`. Returns the calculated distance, pitch and yaw |descriptionEnd| */ -OPTIMIZE_O3 void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw); +OPTIMIZE_O3 void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, RET f32 *dist, RET s16 *pitch, RET s16 *yaw); /* |description| Positions the point `to` at a given `dist`, `pitch`, and `yaw` relative to the point `from`. This can be used to place objects around a reference point at specific angles and distances |descriptionEnd| */ -OPTIMIZE_O3 void vec3f_set_dist_and_angle(Vec3f from, OUT Vec3f to, f32 dist, s16 pitch, s16 yaw); +OPTIMIZE_O3 void vec3f_set_dist_and_angle(Vec3f from, VEC_OUT Vec3f to, f32 dist, s16 pitch, s16 yaw); /* |description| Determines a vector that is perpendicular (normal) to the plane defined by three given 3D floating-point points `a`, `b`, and `c`. The resulting perpendicular vector is stored in `dest` |descriptionEnd| */ -OPTIMIZE_O3 Vec3fp find_vector_perpendicular_to_plane(OUT Vec3f dest, Vec3f a, Vec3f b, Vec3f c); +OPTIMIZE_O3 Vec3fp find_vector_perpendicular_to_plane(VEC_OUT Vec3f dest, Vec3f a, Vec3f b, Vec3f c); /////////// // Vec3i // @@ -229,67 +229,67 @@ OPTIMIZE_O3 Vec3fp find_vector_perpendicular_to_plane(OUT Vec3f dest, Vec3f a, V /* |description| Adjusts the 4x4 floating-point matrix `mtx` so that it represents a viewing transformation looking from the point `from` toward the point `to`, with a given roll angle. This creates a view matrix oriented toward `to` |descriptionEnd| */ -OPTIMIZE_O3 void mtxf_lookat(OUT Mat4 mtx, Vec3f from, Vec3f to, s16 roll); +OPTIMIZE_O3 void mtxf_lookat(VEC_OUT Mat4 mtx, Vec3f from, Vec3f to, s16 roll); /* |description| Rotates `dest` according to the angles in `rotate` using ZXY order, and then translates it by the 3D floating-point vector `translate`. This effectively positions and orients `dest` in 3D space |descriptionEnd| */ -OPTIMIZE_O3 void mtxf_rotate_zxy_and_translate(OUT Mat4 dest, Vec3f translate, Vec3s rotate); +OPTIMIZE_O3 void mtxf_rotate_zxy_and_translate(VEC_OUT Mat4 dest, Vec3f translate, Vec3s rotate); /* |description| Rotates `dest` using angles in XYZ order, and then translates it by the 3D floating-point vector `b` and applies the rotations described by `c`. This sets up `dest` with a specific orientation and position in space |descriptionEnd| */ -OPTIMIZE_O3 void mtxf_rotate_xyz_and_translate(OUT Mat4 dest, Vec3f b, Vec3s c); +OPTIMIZE_O3 void mtxf_rotate_xyz_and_translate(VEC_OUT Mat4 dest, Vec3f b, Vec3s c); /* |description| Transforms a 4x4 floating-point matrix `mtx` into a "billboard" oriented toward the camera or a given direction. The billboard is placed at `position` and rotated by `angle`. This is useful for objects that should always face the viewer |descriptionEnd| */ -OPTIMIZE_O3 void mtxf_billboard(OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle); +OPTIMIZE_O3 void mtxf_billboard(VEC_OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle); /* |description| Creates a "cylindrical billboard" transformation from the 4x4 matrix `mtx` placed at `position` with a given `angle`. Unlike a full billboard, this might allow rotation around one axis while still facing the viewer on others |descriptionEnd| */ -OPTIMIZE_O3 void mtxf_cylboard(OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle); +OPTIMIZE_O3 void mtxf_cylboard(VEC_OUT Mat4 dest, Mat4 mtx, Vec3f position, s16 angle); /* |description| Aligns `dest` so that it fits the orientation of a terrain surface defined by its normal vector `upDir`. The transformation is positioned at `pos` and oriented with a given `yaw`. This is often used to make objects sit naturally on uneven ground |descriptionEnd| */ -OPTIMIZE_O3 void mtxf_align_terrain_normal(OUT Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw); +OPTIMIZE_O3 void mtxf_align_terrain_normal(VEC_OUT Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw); /* |description| Aligns `mtx` to fit onto a terrain triangle at `pos`, applying a given `yaw` and scaling by `radius`. This helps position objects so they match the orientation of the terrain's surface |descriptionEnd| */ -OPTIMIZE_O3 void mtxf_align_terrain_triangle(OUT Mat4 mtx, Vec3f pos, s16 yaw, f32 radius); +OPTIMIZE_O3 void mtxf_align_terrain_triangle(VEC_OUT Mat4 mtx, Vec3f pos, s16 yaw, f32 radius); /* |description| Multiplies two 4x4 floating-point matrices `a` and `b` (in that order), storing the product in `dest`. This can be used for combining multiple transformations into one |descriptionEnd| */ -OPTIMIZE_O3 void mtxf_mul(OUT Mat4 dest, Mat4 a, Mat4 b); +OPTIMIZE_O3 void mtxf_mul(VEC_OUT Mat4 dest, Mat4 a, Mat4 b); /* |description| Multiplies the 3D signed-integer vector `b` with the 4x4 floating-point matrix `mtx`, which applies the transformation to the point |descriptionEnd| */ -OPTIMIZE_O3 Vec3sp mtxf_mul_vec3s(Mat4 mtx, OUT Vec3s b); +OPTIMIZE_O3 Vec3sp mtxf_mul_vec3s(Mat4 mtx, VEC_OUT Vec3s b); /* |description| Rotates the matrix `mtx` in the XY plane by the given `angle`. Rotating in the XY plane typically means pivoting around the Z axis |descriptionEnd| */ -OPTIMIZE_O3 void mtxf_rotate_xy(OUT Mat4 mtx, s16 angle); +OPTIMIZE_O3 void mtxf_rotate_xy(VEC_OUT Mat4 mtx, s16 angle); /* |description| Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space. The `src` matrix *must* be affine! |descriptionEnd| */ -OPTIMIZE_O3 void mtxf_inverse(OUT Mat4 dest, Mat4 src); +OPTIMIZE_O3 void mtxf_inverse(VEC_OUT Mat4 dest, Mat4 src); /* |description| Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space. Returns `false` if the inversion failed. |descriptionEnd| */ -OPTIMIZE_O3 bool mtxf_inverse_non_affine(OUT Mat4 dest, Mat4 src); +OPTIMIZE_O3 bool mtxf_inverse_non_affine(VEC_OUT Mat4 dest, Mat4 src); /* |description| Extracts the position (translation component) from the transformation matrix `objMtx` relative to the coordinate system defined by `camMtx` and stores that 3D position in `dest`. This can be used to get the object's coordinates in camera space |descriptionEnd| */ -OPTIMIZE_O3 Vec3fp get_pos_from_transform_mtx(OUT Vec3f dest, Mat4 objMtx, Mat4 camMtx); +OPTIMIZE_O3 Vec3fp get_pos_from_transform_mtx(VEC_OUT Vec3f dest, Mat4 objMtx, Mat4 camMtx); #endif // MATH_UTIL_H diff --git a/src/engine/math_util_mat4.inl b/src/engine/math_util_mat4.inl index f1fe8faef..7bf0a6b0d 100644 --- a/src/engine/math_util_mat4.inl +++ b/src/engine/math_util_mat4.inl @@ -14,28 +14,28 @@ optimizations and bug reports. Sets the 4x4 floating-point matrix `mtx` to all zeros. Unless you really need this-It's reccomended to use mtxf_identity instead. |descriptionEnd| */ -INLINE OPTIMIZE_O3 void mtxf_zero(OUT Mat4 mtx) { +INLINE OPTIMIZE_O3 void mtxf_zero(VEC_OUT Mat4 mtx) { memset(mtx, 0, sizeof(Mat4)); } /* |description| Copies the 4x4 floating-point matrix `src` into `dest`. After this operation, `dest` contains the same matrix values as `src` |descriptionEnd| */ -INLINE OPTIMIZE_O3 void mtxf_copy(OUT Mat4 dest, Mat4 src) { +INLINE OPTIMIZE_O3 void mtxf_copy(VEC_OUT Mat4 dest, Mat4 src) { memcpy(dest, src, sizeof(Mat4)); } /* |description| Sets the 4x4 floating-point matrix `mtx` to the identity matrix. The identity matrix leaves points unchanged when they are transformed by it which is useful for matrix math |descriptionEnd| */ -INLINE OPTIMIZE_O3 void mtxf_identity(OUT Mat4 mtx) { +INLINE OPTIMIZE_O3 void mtxf_identity(VEC_OUT Mat4 mtx) { mtxf_copy(mtx, gMat4Identity); } /* |description| Sets the 4x4 floating-point matrix `dest` to the translation matrix decribed by the 3D floating-point vector `b`. This matrix is used to shift any transformed point by `b` |descriptionEnd| */ -INLINE OPTIMIZE_O3 void mtxf_translate(OUT Mat4 dest, Vec3f b) { +INLINE OPTIMIZE_O3 void mtxf_translate(VEC_OUT Mat4 dest, Vec3f b) { mtxf_identity(dest); vec3f_copy(dest[3], b); } @@ -43,7 +43,7 @@ INLINE OPTIMIZE_O3 void mtxf_translate(OUT Mat4 dest, Vec3f b) { /* |description| Scales the 4x4 floating-point matrix `mtx` by the scaling factors found in the 3D floating-point vector `s`, and stores the result in `dest`. This enlarges or shrinks objects in 3D space |descriptionEnd| */ -INLINE OPTIMIZE_O3 void mtxf_scale_vec3f(OUT Mat4 dest, Mat4 mtx, Vec3f s) { +INLINE OPTIMIZE_O3 void mtxf_scale_vec3f(VEC_OUT Mat4 dest, Mat4 mtx, Vec3f s) { mtxf_copy(dest, mtx); vec3f_mul(dest[0], s[0]); vec3f_mul(dest[1], s[1]); diff --git a/src/engine/math_util_vec2.tmpl b/src/engine/math_util_vec2.tmpl index bfb24f14a..69e1d2cfc 100644 --- a/src/engine/math_util_vec2.tmpl +++ b/src/engine/math_util_vec2.tmpl @@ -3,7 +3,7 @@ /* |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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_zero(VEC_OUT Vec2{{suffix}} v) { memset(v, 0, sizeof(Vec2{{suffix}})); return v; } @@ -11,7 +11,7 @@ INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_zero(OUT Vec2{{suffix}} 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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_copy(VEC_OUT Vec2{{suffix}} dest, Vec2{{suffix}} src) { dest[0] = src[0]; dest[1] = src[1]; return dest; @@ -20,7 +20,7 @@ INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_copy(OUT Vec2{{suffix}} 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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_set(VEC_OUT Vec2{{suffix}} dest, {{type}} x, {{type}} y) { dest[0] = x; dest[1] = y; return dest; @@ -29,7 +29,7 @@ INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_set(OUT Vec2{{suffix}} 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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_add(VEC_OUT Vec2{{suffix}} dest, Vec2{{suffix}} a) { dest[0] += a[0]; dest[1] += a[1]; return dest; @@ -38,7 +38,7 @@ INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_add(OUT Vec2{{suffix}} dest, V /* |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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_sum(VEC_OUT Vec2{{suffix}} dest, Vec2{{suffix}} a, Vec2{{suffix}} b) { dest[0] = a[0] + b[0]; dest[1] = a[1] + b[1]; return dest; @@ -47,7 +47,7 @@ INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_sum(OUT Vec2{{suffix}} dest, V /* |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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_sub(VEC_OUT Vec2{{suffix}} dest, Vec2{{suffix}} a) { dest[0] -= a[0]; dest[1] -= a[1]; return dest; @@ -56,7 +56,7 @@ INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_sub(OUT Vec2{{suffix}} dest, V /* |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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_dif(VEC_OUT Vec2{{suffix}} dest, Vec2{{suffix}} a, Vec2{{suffix}} b) { dest[0] = a[0] - b[0]; dest[1] = a[1] - b[1]; return dest; @@ -65,7 +65,7 @@ INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_dif(OUT Vec2{{suffix}} dest, V /* |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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_mul(VEC_OUT Vec2{{suffix}} dest, f32 a) { dest[0] *= a; dest[1] *= a; return dest; @@ -74,7 +74,7 @@ INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_mul(OUT Vec2{{suffix}} dest, f /* |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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_mult(VEC_OUT Vec2{{suffix}} dest, Vec2{{suffix}} a) { dest[0] *= a[0]; dest[1] *= a[1]; return dest; @@ -83,7 +83,7 @@ INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_mult(OUT Vec2{{suffix}} 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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_prod(VEC_OUT Vec2{{suffix}} dest, Vec2{{suffix}} a, Vec2{{suffix}} b) { dest[0] = a[0] * b[0]; dest[1] = a[1] * b[1]; return dest; @@ -92,7 +92,7 @@ INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_prod(OUT Vec2{{suffix}} 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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_div(VEC_OUT Vec2{{suffix}} dest, f32 a) { if (a == 0) { return dest; } dest[0] /= a; dest[1] /= a; @@ -109,7 +109,7 @@ INLINE OPTIMIZE_O3 f32 vec2{{suffix}}_length(Vec2{{suffix}} a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_normalize(VEC_OUT Vec2{{suffix}} v) { f32 mag = vec2{{suffix}}_length(v); vec2{{suffix}}_div(v, mag); return v; @@ -118,7 +118,7 @@ INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_normalize(OUT Vec2{{suffix}} 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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_set_magnitude(VEC_OUT Vec2{{suffix}} v, f32 mag) { vec2{{suffix}}_normalize(v); vec2{{suffix}}_mul(v, mag); return v; @@ -134,7 +134,7 @@ INLINE OPTIMIZE_O3 f32 vec2{{suffix}}_dot(Vec2{{suffix}} a, Vec2{{suffix}} b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_combine(VEC_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; diff --git a/src/engine/math_util_vec2f.inl b/src/engine/math_util_vec2f.inl index edea0385b..3674ec3b9 100644 --- a/src/engine/math_util_vec2f.inl +++ b/src/engine/math_util_vec2f.inl @@ -6,7 +6,7 @@ /* |description| Sets the components of the 2D floating-point vector `v` to 0 |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec2fp vec2f_zero(OUT Vec2f v) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_zero(VEC_OUT Vec2f v) { memset(v, 0, sizeof(Vec2f)); return v; } @@ -14,7 +14,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2f_zero(OUT Vec2f 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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_copy(VEC_OUT Vec2f dest, Vec2f src) { dest[0] = src[0]; dest[1] = src[1]; return dest; @@ -23,7 +23,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2f_copy(OUT Vec2f dest, Vec2f src) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_set(VEC_OUT Vec2f dest, f32 x, f32 y) { dest[0] = x; dest[1] = y; return dest; @@ -32,7 +32,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2f_set(OUT Vec2f dest, f32 x, f32 y) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_add(VEC_OUT Vec2f dest, Vec2f a) { dest[0] += a[0]; dest[1] += a[1]; return dest; @@ -41,7 +41,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2f_add(OUT Vec2f dest, Vec2f a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_sum(VEC_OUT Vec2f dest, Vec2f a, Vec2f b) { dest[0] = a[0] + b[0]; dest[1] = a[1] + b[1]; return dest; @@ -50,7 +50,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2f_sum(OUT Vec2f dest, Vec2f a, Vec2f b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_sub(VEC_OUT Vec2f dest, Vec2f a) { dest[0] -= a[0]; dest[1] -= a[1]; return dest; @@ -59,7 +59,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2f_sub(OUT Vec2f dest, Vec2f a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_dif(VEC_OUT Vec2f dest, Vec2f a, Vec2f b) { dest[0] = a[0] - b[0]; dest[1] = a[1] - b[1]; return dest; @@ -68,7 +68,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2f_dif(OUT Vec2f dest, Vec2f a, Vec2f b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_mul(VEC_OUT Vec2f dest, f32 a) { dest[0] *= a; dest[1] *= a; return dest; @@ -77,7 +77,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2f_mul(OUT Vec2f dest, f32 a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_mult(VEC_OUT Vec2f dest, Vec2f a) { dest[0] *= a[0]; dest[1] *= a[1]; return dest; @@ -86,7 +86,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2f_mult(OUT Vec2f dest, Vec2f a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_prod(VEC_OUT Vec2f dest, Vec2f a, Vec2f b) { dest[0] = a[0] * b[0]; dest[1] = a[1] * b[1]; return dest; @@ -95,7 +95,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2f_prod(OUT Vec2f dest, Vec2f a, Vec2f b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_div(VEC_OUT Vec2f dest, f32 a) { if (a == 0) { return dest; } dest[0] /= a; dest[1] /= a; @@ -112,7 +112,7 @@ INLINE OPTIMIZE_O3 f32 vec2f_length(Vec2f a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_normalize(VEC_OUT Vec2f v) { f32 mag = vec2f_length(v); vec2f_div(v, mag); return v; @@ -121,7 +121,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2f_normalize(OUT Vec2f 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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_set_magnitude(VEC_OUT Vec2f v, f32 mag) { vec2f_normalize(v); vec2f_mul(v, mag); return v; @@ -137,7 +137,7 @@ INLINE OPTIMIZE_O3 f32 vec2f_dot(Vec2f a, Vec2f b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2f_combine(VEC_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; @@ -162,7 +162,7 @@ INLINE OPTIMIZE_O3 bool vec2f_is_zero(Vec2f v) { /* |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) { +INLINE OPTIMIZE_O3 Vec2ip vec2f_to_vec2i(VEC_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; @@ -171,7 +171,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2f_to_vec2i(OUT Vec2i dest, Vec2f a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2f_to_vec2s(VEC_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 index 774bedb38..7bc480961 100644 --- a/src/engine/math_util_vec2i.inl +++ b/src/engine/math_util_vec2i.inl @@ -6,7 +6,7 @@ /* |description| Sets the components of the 2D integer vector `v` to 0 |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec2ip vec2i_zero(OUT Vec2i v) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_zero(VEC_OUT Vec2i v) { memset(v, 0, sizeof(Vec2i)); return v; } @@ -14,7 +14,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2i_zero(OUT Vec2i 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) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_copy(VEC_OUT Vec2i dest, Vec2i src) { dest[0] = src[0]; dest[1] = src[1]; return dest; @@ -23,7 +23,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2i_copy(OUT Vec2i dest, Vec2i src) { /* |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) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_set(VEC_OUT Vec2i dest, s32 x, s32 y) { dest[0] = x; dest[1] = y; return dest; @@ -32,7 +32,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2i_set(OUT Vec2i dest, s32 x, s32 y) { /* |description| Adds the components of the 2D integer vector `a` to `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec2ip vec2i_add(OUT Vec2i dest, Vec2i a) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_add(VEC_OUT Vec2i dest, Vec2i a) { dest[0] += a[0]; dest[1] += a[1]; return dest; @@ -41,7 +41,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2i_add(OUT Vec2i dest, Vec2i a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_sum(VEC_OUT Vec2i dest, Vec2i a, Vec2i b) { dest[0] = a[0] + b[0]; dest[1] = a[1] + b[1]; return dest; @@ -50,7 +50,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2i_sum(OUT Vec2i dest, Vec2i a, Vec2i b) { /* |description| Subtracts the components of the 2D integer vector `a` from `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec2ip vec2i_sub(OUT Vec2i dest, Vec2i a) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_sub(VEC_OUT Vec2i dest, Vec2i a) { dest[0] -= a[0]; dest[1] -= a[1]; return dest; @@ -59,7 +59,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2i_sub(OUT Vec2i dest, Vec2i a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_dif(VEC_OUT Vec2i dest, Vec2i a, Vec2i b) { dest[0] = a[0] - b[0]; dest[1] = a[1] - b[1]; return dest; @@ -68,7 +68,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2i_dif(OUT Vec2i dest, Vec2i a, Vec2i b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_mul(VEC_OUT Vec2i dest, f32 a) { dest[0] *= a; dest[1] *= a; return dest; @@ -77,7 +77,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2i_mul(OUT Vec2i dest, f32 a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_mult(VEC_OUT Vec2i dest, Vec2i a) { dest[0] *= a[0]; dest[1] *= a[1]; return dest; @@ -86,7 +86,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2i_mult(OUT Vec2i dest, Vec2i a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_prod(VEC_OUT Vec2i dest, Vec2i a, Vec2i b) { dest[0] = a[0] * b[0]; dest[1] = a[1] * b[1]; return dest; @@ -95,7 +95,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2i_prod(OUT Vec2i dest, Vec2i a, Vec2i b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_div(VEC_OUT Vec2i dest, f32 a) { if (a == 0) { return dest; } dest[0] /= a; dest[1] /= a; @@ -112,7 +112,7 @@ INLINE OPTIMIZE_O3 f32 vec2i_length(Vec2i a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_normalize(VEC_OUT Vec2i v) { f32 mag = vec2i_length(v); vec2i_div(v, mag); return v; @@ -121,7 +121,7 @@ INLINE OPTIMIZE_O3 Vec2ip vec2i_normalize(OUT Vec2i 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) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_set_magnitude(VEC_OUT Vec2i v, f32 mag) { vec2i_normalize(v); vec2i_mul(v, mag); return v; @@ -137,7 +137,7 @@ INLINE OPTIMIZE_O3 f32 vec2i_dot(Vec2i a, Vec2i b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2ip vec2i_combine(VEC_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; @@ -162,7 +162,7 @@ INLINE OPTIMIZE_O3 bool vec2i_is_zero(Vec2i v) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2i_to_vec2f(VEC_OUT Vec2f dest, Vec2i a) { dest[0] = a[0]; dest[1] = a[1]; return dest; @@ -171,7 +171,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2i_to_vec2f(OUT Vec2f dest, Vec2i a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2i_to_vec2s(VEC_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 index 2dde2fdbd..e54055785 100644 --- a/src/engine/math_util_vec2s.inl +++ b/src/engine/math_util_vec2s.inl @@ -6,7 +6,7 @@ /* |description| Sets the components of the 2D short integer vector `v` to 0 |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec2sp vec2s_zero(OUT Vec2s v) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_zero(VEC_OUT Vec2s v) { memset(v, 0, sizeof(Vec2s)); return v; } @@ -14,7 +14,7 @@ INLINE OPTIMIZE_O3 Vec2sp vec2s_zero(OUT Vec2s 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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_copy(VEC_OUT Vec2s dest, Vec2s src) { dest[0] = src[0]; dest[1] = src[1]; return dest; @@ -23,7 +23,7 @@ INLINE OPTIMIZE_O3 Vec2sp vec2s_copy(OUT Vec2s dest, Vec2s src) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_set(VEC_OUT Vec2s dest, s16 x, s16 y) { dest[0] = x; dest[1] = y; return dest; @@ -32,7 +32,7 @@ INLINE OPTIMIZE_O3 Vec2sp vec2s_set(OUT Vec2s dest, s16 x, s16 y) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_add(VEC_OUT Vec2s dest, Vec2s a) { dest[0] += a[0]; dest[1] += a[1]; return dest; @@ -41,7 +41,7 @@ INLINE OPTIMIZE_O3 Vec2sp vec2s_add(OUT Vec2s dest, Vec2s a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_sum(VEC_OUT Vec2s dest, Vec2s a, Vec2s b) { dest[0] = a[0] + b[0]; dest[1] = a[1] + b[1]; return dest; @@ -50,7 +50,7 @@ INLINE OPTIMIZE_O3 Vec2sp vec2s_sum(OUT Vec2s dest, Vec2s a, Vec2s b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_sub(VEC_OUT Vec2s dest, Vec2s a) { dest[0] -= a[0]; dest[1] -= a[1]; return dest; @@ -59,7 +59,7 @@ INLINE OPTIMIZE_O3 Vec2sp vec2s_sub(OUT Vec2s dest, Vec2s a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_dif(VEC_OUT Vec2s dest, Vec2s a, Vec2s b) { dest[0] = a[0] - b[0]; dest[1] = a[1] - b[1]; return dest; @@ -68,7 +68,7 @@ INLINE OPTIMIZE_O3 Vec2sp vec2s_dif(OUT Vec2s dest, Vec2s a, Vec2s b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_mul(VEC_OUT Vec2s dest, f32 a) { dest[0] *= a; dest[1] *= a; return dest; @@ -77,7 +77,7 @@ INLINE OPTIMIZE_O3 Vec2sp vec2s_mul(OUT Vec2s dest, f32 a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_mult(VEC_OUT Vec2s dest, Vec2s a) { dest[0] *= a[0]; dest[1] *= a[1]; return dest; @@ -86,7 +86,7 @@ INLINE OPTIMIZE_O3 Vec2sp vec2s_mult(OUT Vec2s dest, Vec2s a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_prod(VEC_OUT Vec2s dest, Vec2s a, Vec2s b) { dest[0] = a[0] * b[0]; dest[1] = a[1] * b[1]; return dest; @@ -95,7 +95,7 @@ INLINE OPTIMIZE_O3 Vec2sp vec2s_prod(OUT Vec2s dest, Vec2s a, Vec2s b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_div(VEC_OUT Vec2s dest, f32 a) { if (a == 0) { return dest; } dest[0] /= a; dest[1] /= a; @@ -112,7 +112,7 @@ INLINE OPTIMIZE_O3 f32 vec2s_length(Vec2s a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_normalize(VEC_OUT Vec2s v) { f32 mag = vec2s_length(v); vec2s_div(v, mag); return v; @@ -121,7 +121,7 @@ INLINE OPTIMIZE_O3 Vec2sp vec2s_normalize(OUT Vec2s 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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_set_magnitude(VEC_OUT Vec2s v, f32 mag) { vec2s_normalize(v); vec2s_mul(v, mag); return v; @@ -137,7 +137,7 @@ INLINE OPTIMIZE_O3 f32 vec2s_dot(Vec2s a, Vec2s b) { /* |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) { +INLINE OPTIMIZE_O3 Vec2sp vec2s_combine(VEC_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; @@ -162,7 +162,7 @@ INLINE OPTIMIZE_O3 bool vec2s_is_zero(Vec2s v) { /* |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) { +INLINE OPTIMIZE_O3 Vec2fp vec2s_to_vec2f(VEC_OUT Vec2f dest, Vec2s a) { dest[0] = a[0]; dest[1] = a[1]; return dest; @@ -171,7 +171,7 @@ INLINE OPTIMIZE_O3 Vec2fp vec2s_to_vec2f(OUT Vec2f dest, Vec2s a) { /* |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) { +INLINE OPTIMIZE_O3 Vec2ip vec2s_to_vec2i(VEC_OUT Vec2i dest, Vec2s a) { dest[0] = a[0]; dest[1] = a[1]; return dest; diff --git a/src/engine/math_util_vec3.tmpl b/src/engine/math_util_vec3.tmpl index e111079e1..8f68751d0 100644 --- a/src/engine/math_util_vec3.tmpl +++ b/src/engine/math_util_vec3.tmpl @@ -3,7 +3,7 @@ /* |description| Sets the components of the 3D {{desc}} vector `v` to 0 |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_zero(OUT Vec3{{suffix}} v) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_zero(VEC_OUT Vec3{{suffix}} v) { memset(v, 0, sizeof(Vec3{{suffix}})); return v; } @@ -11,7 +11,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_zero(OUT Vec3{{suffix}} v) { /* |description| Copies the contents of a 3D {{desc}} vector (`src`) into another 3D {{desc}} vector (`dest`) |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_copy(OUT Vec3{{suffix}} dest, Vec3{{suffix}} src) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_copy(VEC_OUT Vec3{{suffix}} dest, Vec3{{suffix}} src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; @@ -21,7 +21,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_copy(OUT Vec3{{suffix}} dest, /* |description| Sets the values of the 3D {{desc}} vector `dest` to the given x, y, and z values |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_set(OUT Vec3{{suffix}} dest, {{type}} x, {{type}} y, {{type}} z) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_set(VEC_OUT Vec3{{suffix}} dest, {{type}} x, {{type}} y, {{type}} z) { dest[0] = x; dest[1] = y; dest[2] = z; @@ -31,7 +31,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_set(OUT Vec3{{suffix}} dest, { /* |description| Adds the components of the 3D {{desc}} vector `a` to `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_add(OUT Vec3{{suffix}} dest, Vec3{{suffix}} a) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_add(VEC_OUT Vec3{{suffix}} dest, Vec3{{suffix}} a) { dest[0] += a[0]; dest[1] += a[1]; dest[2] += a[2]; @@ -41,7 +41,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_add(OUT Vec3{{suffix}} dest, V /* |description| Adds the components of two 3D {{desc}} vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_sum(OUT Vec3{{suffix}} dest, Vec3{{suffix}} a, Vec3{{suffix}} b) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_sum(VEC_OUT Vec3{{suffix}} dest, Vec3{{suffix}} a, Vec3{{suffix}} b) { dest[0] = a[0] + b[0]; dest[1] = a[1] + b[1]; dest[2] = a[2] + b[2]; @@ -51,7 +51,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_sum(OUT Vec3{{suffix}} dest, V /* |description| Subtracts the components of the 3D {{desc}} vector `a` from `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_sub(OUT Vec3{{suffix}} dest, Vec3{{suffix}} a) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_sub(VEC_OUT Vec3{{suffix}} dest, Vec3{{suffix}} a) { dest[0] -= a[0]; dest[1] -= a[1]; dest[2] -= a[2]; @@ -61,7 +61,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_sub(OUT Vec3{{suffix}} dest, V /* |description| Subtracts the components of the 3D {{desc}} vector `b` from the components of `a` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_dif(OUT Vec3{{suffix}} dest, Vec3{{suffix}} a, Vec3{{suffix}} b) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_dif(VEC_OUT Vec3{{suffix}} dest, Vec3{{suffix}} a, Vec3{{suffix}} b) { dest[0] = a[0] - b[0]; dest[1] = a[1] - b[1]; dest[2] = a[2] - b[2]; @@ -71,7 +71,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_dif(OUT Vec3{{suffix}} dest, V /* |description| Multiplies each component of the 3D {{desc}} vector `dest` by the scalar value `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_mul(OUT Vec3{{suffix}} dest, f32 a) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_mul(VEC_OUT Vec3{{suffix}} dest, f32 a) { dest[0] *= a; dest[1] *= a; dest[2] *= a; @@ -81,7 +81,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_mul(OUT Vec3{{suffix}} dest, f /* |description| Multiplies the components of the 3D {{desc}} vector `dest` with the components of `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_mult(OUT Vec3{{suffix}} dest, Vec3{{suffix}} a) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_mult(VEC_OUT Vec3{{suffix}} dest, Vec3{{suffix}} a) { dest[0] *= a[0]; dest[1] *= a[1]; dest[2] *= a[2]; @@ -91,7 +91,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_mult(OUT Vec3{{suffix}} dest, /* |description| Multiplies the components of two 3D {{desc}} vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_prod(OUT Vec3{{suffix}} dest, Vec3{{suffix}} a, Vec3{{suffix}} b) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_prod(VEC_OUT Vec3{{suffix}} dest, Vec3{{suffix}} a, Vec3{{suffix}} b) { dest[0] = a[0] * b[0]; dest[1] = a[1] * b[1]; dest[2] = a[2] * b[2]; @@ -101,7 +101,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_prod(OUT Vec3{{suffix}} dest, /* |description| Divides each component of the 3D {{desc}} vector `dest` by the scalar value `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_div(OUT Vec3{{suffix}} dest, f32 a) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_div(VEC_OUT Vec3{{suffix}} dest, f32 a) { if (a == 0) { return dest; } dest[0] /= a; dest[1] /= a; @@ -119,7 +119,7 @@ INLINE OPTIMIZE_O3 f32 vec3{{suffix}}_length(Vec3{{suffix}} a) { /* |description| Normalizes the 3D {{desc}} vector `v` so that its length (magnitude) becomes 1, while retaining its direction |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_normalize(OUT Vec3{{suffix}} v) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_normalize(VEC_OUT Vec3{{suffix}} v) { f32 mag = vec3{{suffix}}_length(v); vec3{{suffix}}_div(v, mag); return v; @@ -128,7 +128,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_normalize(OUT Vec3{{suffix}} v /* |description| Sets the length (magnitude) of 3D {{desc}} vector `v`, while retaining its direction |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_set_magnitude(OUT Vec3{{suffix}} v, f32 mag) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_set_magnitude(VEC_OUT Vec3{{suffix}} v, f32 mag) { vec3{{suffix}}_normalize(v); vec3{{suffix}}_mul(v, mag); return v; @@ -144,7 +144,7 @@ INLINE OPTIMIZE_O3 f32 vec3{{suffix}}_dot(Vec3{{suffix}} a, Vec3{{suffix}} b) { /* |description| Computes the cross product of two 3D {{desc}} vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_cross(OUT Vec3{{suffix}} dest, Vec3{{suffix}} a, Vec3{{suffix}} b) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_cross(VEC_OUT Vec3{{suffix}} dest, Vec3{{suffix}} a, Vec3{{suffix}} b) { dest[0] = a[1] * b[2] - b[1] * a[2]; dest[1] = a[2] * b[0] - b[2] * a[0]; dest[2] = a[0] * b[1] - b[0] * a[1]; @@ -154,7 +154,7 @@ INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_cross(OUT Vec3{{suffix}} dest, /* |description| Takes two 3D {{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 Vec3{{suffix}}p vec3{{suffix}}_combine(OUT Vec3{{suffix}} dest, Vec3{{suffix}} vecA, Vec3{{suffix}} vecB, f32 sclA, f32 sclB) { +INLINE OPTIMIZE_O3 Vec3{{suffix}}p vec3{{suffix}}_combine(VEC_OUT Vec3{{suffix}} dest, Vec3{{suffix}} vecA, Vec3{{suffix}} vecB, f32 sclA, f32 sclB) { dest[0] = vecA[0] * sclA + vecB[0] * sclB; dest[1] = vecA[1] * sclA + vecB[1] * sclB; dest[2] = vecA[2] * sclA + vecB[2] * sclB; diff --git a/src/engine/math_util_vec3f.inl b/src/engine/math_util_vec3f.inl index 5756cb0d4..7e0954fad 100644 --- a/src/engine/math_util_vec3f.inl +++ b/src/engine/math_util_vec3f.inl @@ -6,7 +6,7 @@ /* |description| Sets the components of the 3D floating-point vector `v` to 0 |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_zero(OUT Vec3f v) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_zero(VEC_OUT Vec3f v) { memset(v, 0, sizeof(Vec3f)); return v; } @@ -14,7 +14,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_zero(OUT Vec3f v) { /* |description| Copies the contents of a 3D floating-point vector (`src`) into another 3D floating-point vector (`dest`) |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_copy(OUT Vec3f dest, Vec3f src) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_copy(VEC_OUT Vec3f dest, Vec3f src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; @@ -24,7 +24,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_copy(OUT Vec3f dest, Vec3f src) { /* |description| Sets the values of the 3D floating-point vector `dest` to the given x, y, and z values |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_set(OUT Vec3f dest, f32 x, f32 y, f32 z) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_set(VEC_OUT Vec3f dest, f32 x, f32 y, f32 z) { dest[0] = x; dest[1] = y; dest[2] = z; @@ -34,7 +34,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_set(OUT Vec3f dest, f32 x, f32 y, f32 z) { /* |description| Adds the components of the 3D floating-point vector `a` to `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_add(OUT Vec3f dest, Vec3f a) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_add(VEC_OUT Vec3f dest, Vec3f a) { dest[0] += a[0]; dest[1] += a[1]; dest[2] += a[2]; @@ -44,7 +44,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_add(OUT Vec3f dest, Vec3f a) { /* |description| Adds the components of two 3D floating-point vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_sum(OUT Vec3f dest, Vec3f a, Vec3f b) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_sum(VEC_OUT Vec3f dest, Vec3f a, Vec3f b) { dest[0] = a[0] + b[0]; dest[1] = a[1] + b[1]; dest[2] = a[2] + b[2]; @@ -54,7 +54,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_sum(OUT Vec3f dest, Vec3f a, Vec3f b) { /* |description| Subtracts the components of the 3D floating-point vector `a` from `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_sub(OUT Vec3f dest, Vec3f a) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_sub(VEC_OUT Vec3f dest, Vec3f a) { dest[0] -= a[0]; dest[1] -= a[1]; dest[2] -= a[2]; @@ -64,7 +64,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_sub(OUT Vec3f dest, Vec3f a) { /* |description| Subtracts the components of the 3D floating-point vector `b` from the components of `a` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_dif(OUT Vec3f dest, Vec3f a, Vec3f b) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_dif(VEC_OUT Vec3f dest, Vec3f a, Vec3f b) { dest[0] = a[0] - b[0]; dest[1] = a[1] - b[1]; dest[2] = a[2] - b[2]; @@ -74,7 +74,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_dif(OUT Vec3f dest, Vec3f a, Vec3f b) { /* |description| Multiplies each component of the 3D floating-point vector `dest` by the scalar value `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_mul(OUT Vec3f dest, f32 a) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_mul(VEC_OUT Vec3f dest, f32 a) { dest[0] *= a; dest[1] *= a; dest[2] *= a; @@ -84,7 +84,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_mul(OUT Vec3f dest, f32 a) { /* |description| Multiplies the components of the 3D floating-point vector `dest` with the components of `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_mult(OUT Vec3f dest, Vec3f a) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_mult(VEC_OUT Vec3f dest, Vec3f a) { dest[0] *= a[0]; dest[1] *= a[1]; dest[2] *= a[2]; @@ -94,7 +94,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_mult(OUT Vec3f dest, Vec3f a) { /* |description| Multiplies the components of two 3D floating-point vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_prod(OUT Vec3f dest, Vec3f a, Vec3f b) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_prod(VEC_OUT Vec3f dest, Vec3f a, Vec3f b) { dest[0] = a[0] * b[0]; dest[1] = a[1] * b[1]; dest[2] = a[2] * b[2]; @@ -104,7 +104,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_prod(OUT Vec3f dest, Vec3f a, Vec3f b) { /* |description| Divides each component of the 3D floating-point vector `dest` by the scalar value `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_div(OUT Vec3f dest, f32 a) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_div(VEC_OUT Vec3f dest, f32 a) { if (a == 0) { return dest; } dest[0] /= a; dest[1] /= a; @@ -122,7 +122,7 @@ INLINE OPTIMIZE_O3 f32 vec3f_length(Vec3f a) { /* |description| Normalizes the 3D floating-point vector `v` so that its length (magnitude) becomes 1, while retaining its direction |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_normalize(OUT Vec3f v) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_normalize(VEC_OUT Vec3f v) { f32 mag = vec3f_length(v); vec3f_div(v, mag); return v; @@ -131,7 +131,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_normalize(OUT Vec3f v) { /* |description| Sets the length (magnitude) of 3D floating-point vector `v`, while retaining its direction |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_set_magnitude(OUT Vec3f v, f32 mag) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_set_magnitude(VEC_OUT Vec3f v, f32 mag) { vec3f_normalize(v); vec3f_mul(v, mag); return v; @@ -147,7 +147,7 @@ INLINE OPTIMIZE_O3 f32 vec3f_dot(Vec3f a, Vec3f b) { /* |description| Computes the cross product of two 3D floating-point vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3f_cross(OUT Vec3f dest, Vec3f a, Vec3f b) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_cross(VEC_OUT Vec3f dest, Vec3f a, Vec3f b) { dest[0] = a[1] * b[2] - b[1] * a[2]; dest[1] = a[2] * b[0] - b[2] * a[0]; dest[2] = a[0] * b[1] - b[0] * a[1]; @@ -157,7 +157,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3f_cross(OUT Vec3f dest, Vec3f a, Vec3f b) { /* |description| Takes two 3D 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 Vec3fp vec3f_combine(OUT Vec3f dest, Vec3f vecA, Vec3f vecB, f32 sclA, f32 sclB) { +INLINE OPTIMIZE_O3 Vec3fp vec3f_combine(VEC_OUT Vec3f dest, Vec3f vecA, Vec3f vecB, f32 sclA, f32 sclB) { dest[0] = vecA[0] * sclA + vecB[0] * sclB; dest[1] = vecA[1] * sclA + vecB[1] * sclB; dest[2] = vecA[2] * sclA + vecB[2] * sclB; @@ -191,7 +191,7 @@ INLINE OPTIMIZE_O3 bool vec3f_is_zero(Vec3f v) { /* |description| Converts a 3D floating-point vector `a` into a 3D integer vector and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3f_to_vec3i(OUT Vec3i dest, Vec3f a) { +INLINE OPTIMIZE_O3 Vec3ip vec3f_to_vec3i(VEC_OUT Vec3i dest, Vec3f a) { dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f); dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f); dest[2] = a[2] + ((a[2] > 0) ? 0.5f : -0.5f); @@ -201,7 +201,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3f_to_vec3i(OUT Vec3i dest, Vec3f a) { /* |description| Converts a 3D floating-point vector `a` into a 3D short integer vector and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3f_to_vec3s(OUT Vec3s dest, Vec3f a) { +INLINE OPTIMIZE_O3 Vec3sp vec3f_to_vec3s(VEC_OUT Vec3s dest, Vec3f a) { dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f); dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f); dest[2] = a[2] + ((a[2] > 0) ? 0.5f : -0.5f); diff --git a/src/engine/math_util_vec3i.inl b/src/engine/math_util_vec3i.inl index b7de7da32..8c1ada8ae 100644 --- a/src/engine/math_util_vec3i.inl +++ b/src/engine/math_util_vec3i.inl @@ -6,7 +6,7 @@ /* |description| Sets the components of the 3D integer vector `v` to 0 |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_zero(OUT Vec3i v) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_zero(VEC_OUT Vec3i v) { memset(v, 0, sizeof(Vec3i)); return v; } @@ -14,7 +14,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_zero(OUT Vec3i v) { /* |description| Copies the contents of a 3D integer vector (`src`) into another 3D integer vector (`dest`) |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_copy(OUT Vec3i dest, Vec3i src) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_copy(VEC_OUT Vec3i dest, Vec3i src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; @@ -24,7 +24,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_copy(OUT Vec3i dest, Vec3i src) { /* |description| Sets the values of the 3D integer vector `dest` to the given x, y, and z values |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_set(OUT Vec3i dest, s32 x, s32 y, s32 z) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_set(VEC_OUT Vec3i dest, s32 x, s32 y, s32 z) { dest[0] = x; dest[1] = y; dest[2] = z; @@ -34,7 +34,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_set(OUT Vec3i dest, s32 x, s32 y, s32 z) { /* |description| Adds the components of the 3D integer vector `a` to `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_add(OUT Vec3i dest, Vec3i a) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_add(VEC_OUT Vec3i dest, Vec3i a) { dest[0] += a[0]; dest[1] += a[1]; dest[2] += a[2]; @@ -44,7 +44,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_add(OUT Vec3i dest, Vec3i a) { /* |description| Adds the components of two 3D integer vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_sum(OUT Vec3i dest, Vec3i a, Vec3i b) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_sum(VEC_OUT Vec3i dest, Vec3i a, Vec3i b) { dest[0] = a[0] + b[0]; dest[1] = a[1] + b[1]; dest[2] = a[2] + b[2]; @@ -54,7 +54,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_sum(OUT Vec3i dest, Vec3i a, Vec3i b) { /* |description| Subtracts the components of the 3D integer vector `a` from `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_sub(OUT Vec3i dest, Vec3i a) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_sub(VEC_OUT Vec3i dest, Vec3i a) { dest[0] -= a[0]; dest[1] -= a[1]; dest[2] -= a[2]; @@ -64,7 +64,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_sub(OUT Vec3i dest, Vec3i a) { /* |description| Subtracts the components of the 3D integer vector `b` from the components of `a` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_dif(OUT Vec3i dest, Vec3i a, Vec3i b) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_dif(VEC_OUT Vec3i dest, Vec3i a, Vec3i b) { dest[0] = a[0] - b[0]; dest[1] = a[1] - b[1]; dest[2] = a[2] - b[2]; @@ -74,7 +74,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_dif(OUT Vec3i dest, Vec3i a, Vec3i b) { /* |description| Multiplies each component of the 3D integer vector `dest` by the scalar value `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_mul(OUT Vec3i dest, f32 a) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_mul(VEC_OUT Vec3i dest, f32 a) { dest[0] *= a; dest[1] *= a; dest[2] *= a; @@ -84,7 +84,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_mul(OUT Vec3i dest, f32 a) { /* |description| Multiplies the components of the 3D integer vector `dest` with the components of `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_mult(OUT Vec3i dest, Vec3i a) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_mult(VEC_OUT Vec3i dest, Vec3i a) { dest[0] *= a[0]; dest[1] *= a[1]; dest[2] *= a[2]; @@ -94,7 +94,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_mult(OUT Vec3i dest, Vec3i a) { /* |description| Multiplies the components of two 3D integer vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_prod(OUT Vec3i dest, Vec3i a, Vec3i b) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_prod(VEC_OUT Vec3i dest, Vec3i a, Vec3i b) { dest[0] = a[0] * b[0]; dest[1] = a[1] * b[1]; dest[2] = a[2] * b[2]; @@ -104,7 +104,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_prod(OUT Vec3i dest, Vec3i a, Vec3i b) { /* |description| Divides each component of the 3D integer vector `dest` by the scalar value `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_div(OUT Vec3i dest, f32 a) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_div(VEC_OUT Vec3i dest, f32 a) { if (a == 0) { return dest; } dest[0] /= a; dest[1] /= a; @@ -122,7 +122,7 @@ INLINE OPTIMIZE_O3 f32 vec3i_length(Vec3i a) { /* |description| Normalizes the 3D integer vector `v` so that its length (magnitude) becomes 1, while retaining its direction |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_normalize(OUT Vec3i v) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_normalize(VEC_OUT Vec3i v) { f32 mag = vec3i_length(v); vec3i_div(v, mag); return v; @@ -131,7 +131,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_normalize(OUT Vec3i v) { /* |description| Sets the length (magnitude) of 3D integer vector `v`, while retaining its direction |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_set_magnitude(OUT Vec3i v, f32 mag) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_set_magnitude(VEC_OUT Vec3i v, f32 mag) { vec3i_normalize(v); vec3i_mul(v, mag); return v; @@ -147,7 +147,7 @@ INLINE OPTIMIZE_O3 f32 vec3i_dot(Vec3i a, Vec3i b) { /* |description| Computes the cross product of two 3D integer vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3i_cross(OUT Vec3i dest, Vec3i a, Vec3i b) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_cross(VEC_OUT Vec3i dest, Vec3i a, Vec3i b) { dest[0] = a[1] * b[2] - b[1] * a[2]; dest[1] = a[2] * b[0] - b[2] * a[0]; dest[2] = a[0] * b[1] - b[0] * a[1]; @@ -157,7 +157,7 @@ INLINE OPTIMIZE_O3 Vec3ip vec3i_cross(OUT Vec3i dest, Vec3i a, Vec3i b) { /* |description| Takes two 3D 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 Vec3ip vec3i_combine(OUT Vec3i dest, Vec3i vecA, Vec3i vecB, f32 sclA, f32 sclB) { +INLINE OPTIMIZE_O3 Vec3ip vec3i_combine(VEC_OUT Vec3i dest, Vec3i vecA, Vec3i vecB, f32 sclA, f32 sclB) { dest[0] = vecA[0] * sclA + vecB[0] * sclB; dest[1] = vecA[1] * sclA + vecB[1] * sclB; dest[2] = vecA[2] * sclA + vecB[2] * sclB; @@ -191,7 +191,7 @@ INLINE OPTIMIZE_O3 bool vec3i_is_zero(Vec3i v) { /* |description| Converts a 3D integer vector `a` into a 3D floating-point vector and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3i_to_vec3f(OUT Vec3f dest, Vec3i a) { +INLINE OPTIMIZE_O3 Vec3fp vec3i_to_vec3f(VEC_OUT Vec3f dest, Vec3i a) { dest[0] = a[0]; dest[1] = a[1]; dest[2] = a[2]; @@ -201,7 +201,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3i_to_vec3f(OUT Vec3f dest, Vec3i a) { /* |description| Converts a 3D integer vector `a` into a 3D short integer vector and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3i_to_vec3s(OUT Vec3s dest, Vec3i a) { +INLINE OPTIMIZE_O3 Vec3sp vec3i_to_vec3s(VEC_OUT Vec3s dest, Vec3i a) { dest[0] = a[0]; dest[1] = a[1]; dest[2] = a[2]; diff --git a/src/engine/math_util_vec3s.inl b/src/engine/math_util_vec3s.inl index 392d87eb2..e7e7306c9 100644 --- a/src/engine/math_util_vec3s.inl +++ b/src/engine/math_util_vec3s.inl @@ -6,7 +6,7 @@ /* |description| Sets the components of the 3D short integer vector `v` to 0 |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_zero(OUT Vec3s v) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_zero(VEC_OUT Vec3s v) { memset(v, 0, sizeof(Vec3s)); return v; } @@ -14,7 +14,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_zero(OUT Vec3s v) { /* |description| Copies the contents of a 3D short integer vector (`src`) into another 3D short integer vector (`dest`) |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_copy(OUT Vec3s dest, Vec3s src) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_copy(VEC_OUT Vec3s dest, Vec3s src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; @@ -24,7 +24,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_copy(OUT Vec3s dest, Vec3s src) { /* |description| Sets the values of the 3D short integer vector `dest` to the given x, y, and z values |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_set(OUT Vec3s dest, s16 x, s16 y, s16 z) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_set(VEC_OUT Vec3s dest, s16 x, s16 y, s16 z) { dest[0] = x; dest[1] = y; dest[2] = z; @@ -34,7 +34,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_set(OUT Vec3s dest, s16 x, s16 y, s16 z) { /* |description| Adds the components of the 3D short integer vector `a` to `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_add(OUT Vec3s dest, Vec3s a) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_add(VEC_OUT Vec3s dest, Vec3s a) { dest[0] += a[0]; dest[1] += a[1]; dest[2] += a[2]; @@ -44,7 +44,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_add(OUT Vec3s dest, Vec3s a) { /* |description| Adds the components of two 3D short integer vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_sum(OUT Vec3s dest, Vec3s a, Vec3s b) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_sum(VEC_OUT Vec3s dest, Vec3s a, Vec3s b) { dest[0] = a[0] + b[0]; dest[1] = a[1] + b[1]; dest[2] = a[2] + b[2]; @@ -54,7 +54,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_sum(OUT Vec3s dest, Vec3s a, Vec3s b) { /* |description| Subtracts the components of the 3D short integer vector `a` from `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_sub(OUT Vec3s dest, Vec3s a) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_sub(VEC_OUT Vec3s dest, Vec3s a) { dest[0] -= a[0]; dest[1] -= a[1]; dest[2] -= a[2]; @@ -64,7 +64,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_sub(OUT Vec3s dest, Vec3s a) { /* |description| Subtracts the components of the 3D short integer vector `b` from the components of `a` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_dif(OUT Vec3s dest, Vec3s a, Vec3s b) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_dif(VEC_OUT Vec3s dest, Vec3s a, Vec3s b) { dest[0] = a[0] - b[0]; dest[1] = a[1] - b[1]; dest[2] = a[2] - b[2]; @@ -74,7 +74,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_dif(OUT Vec3s dest, Vec3s a, Vec3s b) { /* |description| Multiplies each component of the 3D short integer vector `dest` by the scalar value `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_mul(OUT Vec3s dest, f32 a) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_mul(VEC_OUT Vec3s dest, f32 a) { dest[0] *= a; dest[1] *= a; dest[2] *= a; @@ -84,7 +84,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_mul(OUT Vec3s dest, f32 a) { /* |description| Multiplies the components of the 3D short integer vector `dest` with the components of `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_mult(OUT Vec3s dest, Vec3s a) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_mult(VEC_OUT Vec3s dest, Vec3s a) { dest[0] *= a[0]; dest[1] *= a[1]; dest[2] *= a[2]; @@ -94,7 +94,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_mult(OUT Vec3s dest, Vec3s a) { /* |description| Multiplies the components of two 3D short integer vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_prod(OUT Vec3s dest, Vec3s a, Vec3s b) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_prod(VEC_OUT Vec3s dest, Vec3s a, Vec3s b) { dest[0] = a[0] * b[0]; dest[1] = a[1] * b[1]; dest[2] = a[2] * b[2]; @@ -104,7 +104,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_prod(OUT Vec3s dest, Vec3s a, Vec3s b) { /* |description| Divides each component of the 3D short integer vector `dest` by the scalar value `a` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_div(OUT Vec3s dest, f32 a) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_div(VEC_OUT Vec3s dest, f32 a) { if (a == 0) { return dest; } dest[0] /= a; dest[1] /= a; @@ -122,7 +122,7 @@ INLINE OPTIMIZE_O3 f32 vec3s_length(Vec3s a) { /* |description| Normalizes the 3D short integer vector `v` so that its length (magnitude) becomes 1, while retaining its direction |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_normalize(OUT Vec3s v) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_normalize(VEC_OUT Vec3s v) { f32 mag = vec3s_length(v); vec3s_div(v, mag); return v; @@ -131,7 +131,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_normalize(OUT Vec3s v) { /* |description| Sets the length (magnitude) of 3D short integer vector `v`, while retaining its direction |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_set_magnitude(OUT Vec3s v, f32 mag) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_set_magnitude(VEC_OUT Vec3s v, f32 mag) { vec3s_normalize(v); vec3s_mul(v, mag); return v; @@ -147,7 +147,7 @@ INLINE OPTIMIZE_O3 f32 vec3s_dot(Vec3s a, Vec3s b) { /* |description| Computes the cross product of two 3D short integer vectors `a` and `b` and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3sp vec3s_cross(OUT Vec3s dest, Vec3s a, Vec3s b) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_cross(VEC_OUT Vec3s dest, Vec3s a, Vec3s b) { dest[0] = a[1] * b[2] - b[1] * a[2]; dest[1] = a[2] * b[0] - b[2] * a[0]; dest[2] = a[0] * b[1] - b[0] * a[1]; @@ -157,7 +157,7 @@ INLINE OPTIMIZE_O3 Vec3sp vec3s_cross(OUT Vec3s dest, Vec3s a, Vec3s b) { /* |description| Takes two 3D 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 Vec3sp vec3s_combine(OUT Vec3s dest, Vec3s vecA, Vec3s vecB, f32 sclA, f32 sclB) { +INLINE OPTIMIZE_O3 Vec3sp vec3s_combine(VEC_OUT Vec3s dest, Vec3s vecA, Vec3s vecB, f32 sclA, f32 sclB) { dest[0] = vecA[0] * sclA + vecB[0] * sclB; dest[1] = vecA[1] * sclA + vecB[1] * sclB; dest[2] = vecA[2] * sclA + vecB[2] * sclB; @@ -191,7 +191,7 @@ INLINE OPTIMIZE_O3 bool vec3s_is_zero(Vec3s v) { /* |description| Converts a 3D short integer vector `a` into a 3D floating-point vector and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3fp vec3s_to_vec3f(OUT Vec3f dest, Vec3s a) { +INLINE OPTIMIZE_O3 Vec3fp vec3s_to_vec3f(VEC_OUT Vec3f dest, Vec3s a) { dest[0] = a[0]; dest[1] = a[1]; dest[2] = a[2]; @@ -201,7 +201,7 @@ INLINE OPTIMIZE_O3 Vec3fp vec3s_to_vec3f(OUT Vec3f dest, Vec3s a) { /* |description| Converts a 3D short integer vector `a` into a 3D integer vector and stores the result in `dest` |descriptionEnd| */ -INLINE OPTIMIZE_O3 Vec3ip vec3s_to_vec3i(OUT Vec3i dest, Vec3s a) { +INLINE OPTIMIZE_O3 Vec3ip vec3s_to_vec3i(VEC_OUT Vec3i dest, Vec3s a) { dest[0] = a[0]; dest[1] = a[1]; dest[2] = a[2]; diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c index 1e34afd7f..08971c42d 100644 --- a/src/engine/surface_collision.c +++ b/src/engine/surface_collision.c @@ -25,7 +25,7 @@ void set_find_wall_direction(Vec3f dir, bool active, bool airborne) { gFindWallDirectionAirborne = airborne; } -void closest_point_to_triangle(struct Surface* surf, Vec3f src, OUT Vec3f out) { +void closest_point_to_triangle(struct Surface* surf, Vec3f src, VEC_OUT Vec3f out) { Vec3f v1; vec3s_to_vec3f(v1, surf->vertex1); Vec3f v2; vec3s_to_vec3f(v2, surf->vertex2); Vec3f v3; vec3s_to_vec3f(v3, surf->vertex3); @@ -497,7 +497,7 @@ static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32 /** * Find the lowest ceiling above a given position and return the height. */ -f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) { +f32 find_ceil(f32 posX, f32 posY, f32 posZ, RET struct Surface **pceil) { s16 cellZ, cellX; struct Surface *ceil, *dynamicCeil; struct SurfaceNode *surfaceList; @@ -812,7 +812,7 @@ f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfl /** * Find the highest floor under a given position and return the height. */ -f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) { +f32 find_floor(f32 xPos, f32 yPos, f32 zPos, RET struct Surface **pfloor) { s16 cellZ, cellX; struct Surface *floor, *dynamicFloor; diff --git a/src/engine/surface_collision.h b/src/engine/surface_collision.h index ff5257a57..e0920578b 100644 --- a/src/engine/surface_collision.h +++ b/src/engine/surface_collision.h @@ -6,6 +6,7 @@ #include "types.h" #include "engine/extended_bounds.h" +#include "pc/lua/smlua_autogen.h" #define CELL_HEIGHT_LIMIT 20000 @@ -55,7 +56,11 @@ Detects wall collisions at a given position and adjusts the position based on th Returns the number of wall collisions detected |descriptionEnd| */ s32 find_wall_collisions(struct WallCollisionData *colData); -f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil); +/* |description| +Finds the height of the highest ceiling above a given position (x, y, z) and return the corresponding ceil surface. +If no ceiling is found, returns the default height limit of `gLevelValues.cellHeightLimit`(20000 by default) +|descriptionEnd| */ +f32 find_ceil(f32 posX, f32 posY, f32 posZ, RET struct Surface **pceil); /* |description| Finds the height of the highest ceiling above a given position (x, y, z). @@ -69,7 +74,11 @@ 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) |descriptionEnd| */ f32 find_floor_height(f32 x, f32 y, f32 z); -f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor); +/* |description| +Finds the height of the highest floor below a given position (x, y, z) and return the corresponding floor surface. +If no floor is found, returns the default floor height of `gLevelValues.floorLowerLimit`(-11000 by default) +|descriptionEnd| */ +f32 find_floor(f32 xPos, f32 yPos, f32 zPos, RET struct Surface **pfloor); /* |description| Finds the height of water at a given position (x, z), if the position is within a water region. @@ -93,6 +102,6 @@ void set_find_wall_direction(Vec3f dir, bool active, bool airborne); /* |description| Gets the closest point of the triangle to `src` and returns it in `out`. |descriptionEnd| */ -void closest_point_to_triangle(struct Surface* surf, Vec3f src, OUT Vec3f out); +void closest_point_to_triangle(struct Surface* surf, Vec3f src, VEC_OUT Vec3f out); #endif // SURFACE_COLLISION_H diff --git a/src/game/behavior_actions.h b/src/game/behavior_actions.h index 66e80725c..bfff0f99d 100644 --- a/src/game/behavior_actions.h +++ b/src/game/behavior_actions.h @@ -25,8 +25,8 @@ s32 arc_to_goal_pos(Vec3f goal, Vec3f pos, f32 yVel, f32 gravity); void tox_box_move(f32 forwardVel, f32 a1, s16 deltaPitch, s16 deltaRoll); /* |description|Plays the penguin walking sound|descriptionEnd| */ void play_penguin_walking_sound(s32 walk); -/* |description|Updates the current object's angle from its move flags|descriptionEnd| */ -s32 update_angle_from_move_flags(s32 *angle); +/* |description|Computes and returns an angle depending on the current object's angle and move flags|descriptionEnd| */ +s32 update_angle_from_move_flags(INOUT s32 *angle); /* |description|Spawns strong wind particles relative to the current object|descriptionEnd| */ void cur_obj_spawn_strong_wind_particles(s32 windSpread, f32 scale, f32 relPosX, f32 relPosY, f32 relPosZ); diff --git a/src/game/behaviors/scuttlebug.inc.c b/src/game/behaviors/scuttlebug.inc.c index 5bb6d11a4..0f96a6ac4 100644 --- a/src/game/behaviors/scuttlebug.inc.c +++ b/src/game/behaviors/scuttlebug.inc.c @@ -12,7 +12,7 @@ struct ObjectHitbox sScuttlebugHitbox = { .hurtboxHeight = 60, }; -s32 update_angle_from_move_flags(s32 *angle) { +s32 update_angle_from_move_flags(INOUT s32 *angle) { if (!angle) { return 0; } if (o->oMoveFlags & OBJ_MOVE_HIT_WALL) { *angle = o->oWallAngle; diff --git a/src/game/behaviors/texscroll.inc.c b/src/game/behaviors/texscroll.inc.c index a8a8df046..5ac1b4b69 100644 --- a/src/game/behaviors/texscroll.inc.c +++ b/src/game/behaviors/texscroll.inc.c @@ -121,7 +121,10 @@ void uv_update_scroll(void) { if (bhv == 3 || bhv > SCROLL_UV_Y) { return; } struct ScrollTarget *scroll = get_scroll_targets(vtxIndex, vertCount, offset); - if (!scroll || !scroll->vertices) { return; } + if (!scroll || !scroll->vertices || scroll->size == 0) { return; } + + vertCount = MIN(vertCount, (u16) scroll->size); + if (vertCount == 0) { return; } Vtx* *verts = scroll->vertices; diff --git a/src/game/camera.c b/src/game/camera.c index d806b3e91..9983130d9 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -3788,7 +3788,7 @@ void stub_camera_2(UNUSED struct Camera *c) { void stub_camera_3(UNUSED struct Camera *c) { } -void object_pos_to_vec3f(OUT Vec3f dst, struct Object *o) { +void object_pos_to_vec3f(VEC_OUT Vec3f dst, struct Object *o) { if (!dst || !o) { return; } dst[0] = o->oPosX; dst[1] = o->oPosY; @@ -3802,7 +3802,7 @@ void vec3f_to_object_pos(struct Object *o, Vec3f src) { o->oPosZ = src[2]; } -void object_face_angle_to_vec3s(OUT Vec3s dst, struct Object *o) { +void object_face_angle_to_vec3s(VEC_OUT Vec3s dst, struct Object *o) { if (!dst || !o) { return; } dst[0] = o->oFaceAnglePitch; dst[1] = o->oFaceAngleYaw; @@ -3816,7 +3816,7 @@ void vec3s_to_object_face_angle(struct Object *o, Vec3s src) { o->oFaceAngleRoll = src[2]; } -void object_move_angle_to_vec3s(OUT Vec3s dst, struct Object *o) { +void object_move_angle_to_vec3s(VEC_OUT Vec3s dst, struct Object *o) { if (!dst || !o) { return; } dst[0] = o->oMoveAnglePitch; dst[1] = o->oMoveAngleYaw; @@ -4061,7 +4061,7 @@ void set_handheld_shake(u8 mode) { * This function must be called every frame in order to actually apply the effect, since the effect's * mag and inc are set to 0 every frame at the end of this function. */ -void shake_camera_handheld(Vec3f pos, OUT Vec3f focus) { +void shake_camera_handheld(Vec3f pos, VEC_OUT Vec3f focus) { s32 i; Vec3f shakeOffset; Vec3f shakeSpline[4]; @@ -4195,7 +4195,7 @@ s32 update_camera_hud_status(struct Camera *c) { * * @return the number of collisions found */ -s32 collide_with_walls(OUT Vec3f pos, f32 offsetY, f32 radius) { +s32 collide_with_walls(VEC_OUT Vec3f pos, f32 offsetY, f32 radius) { struct WallCollisionData collisionData; struct Surface *wall = NULL; f32 normX; @@ -4246,7 +4246,7 @@ s32 vec3f_compare(Vec3f pos, f32 posX, f32 posY, f32 posZ) { return equal; } -s32 clamp_pitch(Vec3f from, OUT Vec3f to, s16 maxPitch, s16 minPitch) { +s32 clamp_pitch(Vec3f from, VEC_OUT Vec3f to, s16 maxPitch, s16 minPitch) { s32 outOfRange = 0; s16 pitch; s16 yaw; @@ -4276,7 +4276,7 @@ s32 is_within_100_units_of_mario(f32 posX, f32 posY, f32 posZ) { return isCloseToMario; } -s32 set_or_approach_f32_asymptotic(f32 *dst, f32 goal, f32 scale) { +s32 set_or_approach_f32_asymptotic(INOUT f32 *dst, f32 goal, f32 scale) { if (!dst) { return FALSE; } if (sStatusFlags & CAM_FLAG_SMOOTH_MOVEMENT) { approach_f32_asymptotic_bool(dst, goal, scale); @@ -4293,9 +4293,9 @@ s32 set_or_approach_f32_asymptotic(f32 *dst, f32 goal, f32 scale) { /** * Approaches an f32 value by taking the difference between the target and current value * and adding a fraction of that to the current value. - * Edits the current value directly, returns TRUE if the target has been reached, FALSE otherwise. + * Edits the current value directly, returns FALSE if the target has been reached, TRUE otherwise. */ -s32 approach_f32_asymptotic_bool(f32 *current, f32 target, f32 multiplier) { +s32 approach_f32_asymptotic_bool(INOUT f32 *current, f32 target, f32 multiplier) { if (!current) { return FALSE; } if (multiplier > 1.f) { multiplier = 1.f; @@ -4321,7 +4321,7 @@ f32 approach_f32_asymptotic(f32 current, f32 target, f32 multiplier) { * is reached. Note: Since this function takes integers as parameters, the last argument is the * reciprocal of what it would be in the previous two functions. */ -s32 approach_s16_asymptotic_bool(s16 *current, s16 target, s16 divisor) { +s32 approach_s16_asymptotic_bool(INOUT s16 *current, s16 target, s16 divisor) { if (!current) { return FALSE; } s16 temp = *current; @@ -4362,7 +4362,7 @@ s32 approach_s16_asymptotic(s16 current, s16 target, s16 divisor) { * Applies the approach_f32_asymptotic_bool function to each of the X, Y, & Z components of the given * vector. */ -void approach_vec3f_asymptotic(OUT Vec3f current, Vec3f target, f32 xMul, f32 yMul, f32 zMul) { +void approach_vec3f_asymptotic(VEC_OUT Vec3f current, Vec3f target, f32 xMul, f32 yMul, f32 zMul) { approach_f32_asymptotic_bool(¤t[0], target[0], xMul); approach_f32_asymptotic_bool(¤t[1], target[1], yMul); approach_f32_asymptotic_bool(¤t[2], target[2], zMul); @@ -4372,7 +4372,7 @@ void approach_vec3f_asymptotic(OUT Vec3f current, Vec3f target, f32 xMul, f32 yM * Applies the set_or_approach_f32_asymptotic_bool function to each of the X, Y, & Z components of the * given vector. */ -void set_or_approach_vec3f_asymptotic(OUT Vec3f dst, Vec3f goal, f32 xMul, f32 yMul, f32 zMul) { +void set_or_approach_vec3f_asymptotic(VEC_OUT Vec3f dst, Vec3f goal, f32 xMul, f32 yMul, f32 zMul) { set_or_approach_f32_asymptotic(&dst[0], goal[0], xMul); set_or_approach_f32_asymptotic(&dst[1], goal[1], yMul); set_or_approach_f32_asymptotic(&dst[2], goal[2], zMul); @@ -4382,13 +4382,13 @@ void set_or_approach_vec3f_asymptotic(OUT Vec3f dst, Vec3f goal, f32 xMul, f32 y * Applies the approach_s32_asymptotic function to each of the X, Y, & Z components of the given * vector. */ -void approach_vec3s_asymptotic(OUT Vec3s current, Vec3s target, s16 xMul, s16 yMul, s16 zMul) { +void approach_vec3s_asymptotic(VEC_OUT Vec3s current, Vec3s target, s16 xMul, s16 yMul, s16 zMul) { approach_s16_asymptotic_bool(¤t[0], target[0], xMul); approach_s16_asymptotic_bool(¤t[1], target[1], yMul); approach_s16_asymptotic_bool(¤t[2], target[2], zMul); } -s32 camera_approach_s16_symmetric_bool(s16 *current, s16 target, s16 increment) { +s32 camera_approach_s16_symmetric_bool(INOUT s16 *current, s16 target, s16 increment) { if (!current) { return FALSE; } s16 dist = target - *current; @@ -4441,7 +4441,7 @@ s32 camera_approach_s16_symmetric(s16 current, s16 target, s16 increment) { return current; } -s32 set_or_approach_s16_symmetric(s16 *current, s16 target, s16 increment) { +s32 set_or_approach_s16_symmetric(INOUT s16 *current, s16 target, s16 increment) { if (!current) { return FALSE; } if (sStatusFlags & CAM_FLAG_SMOOTH_MOVEMENT) { camera_approach_s16_symmetric_bool(current, target, increment); @@ -4460,7 +4460,7 @@ s32 set_or_approach_s16_symmetric(s16 *current, s16 target, s16 increment) { * Appears to be a strange way of implementing approach_f32_symmetric from object_helpers.c. * It could possibly be an older version of the function */ -s32 camera_approach_f32_symmetric_bool(f32 *current, f32 target, f32 increment) { +s32 camera_approach_f32_symmetric_bool(INOUT f32 *current, f32 target, f32 increment) { if (!current) { return FALSE; } f32 dist = target - *current; @@ -4520,7 +4520,7 @@ f32 camera_approach_f32_symmetric(f32 current, f32 target, f32 increment) { * Generate a vector with all three values about zero. The * three ranges determine how wide the range about zero. */ -void random_vec3s(OUT Vec3s dst, s16 xRange, s16 yRange, s16 zRange) { +void random_vec3s(VEC_OUT Vec3s dst, s16 xRange, s16 yRange, s16 zRange) { f32 randomFloat; UNUSED u8 unused[4]; f32 tempXRange; @@ -4587,7 +4587,7 @@ s16 reduce_by_dist_from_camera(s16 value, f32 maxDist, f32 posX, f32 posY, f32 p return result; } -s32 clamp_positions_and_find_yaw(OUT Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f32 zMax, f32 zMin) { +s32 clamp_positions_and_find_yaw(VEC_OUT Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f32 zMax, f32 zMin) { s16 yaw = gCamera->nextYaw; if (pos[0] >= xMax) { @@ -4767,7 +4767,7 @@ s32 is_mario_behind_surface(UNUSED struct Camera *c, struct Surface *surf) { * Calculates the distance between two points and sets a vector to a point * scaled along a line between them. Typically, somewhere in the middle. */ -void scale_along_line(OUT Vec3f dst, Vec3f from, Vec3f to, f32 scale) { +void scale_along_line(VEC_OUT Vec3f dst, Vec3f from, Vec3f to, f32 scale) { Vec3f tempVec; tempVec[0] = (to[0] - from[0]) * scale + from[0]; @@ -4818,7 +4818,7 @@ s16 calculate_yaw(Vec3f from, Vec3f to) { /** * Calculates the pitch and yaw between two vectors. */ -void calculate_angles(Vec3f from, Vec3f to, s16 *pitch, s16 *yaw) { +void calculate_angles(Vec3f from, Vec3f to, RET s16 *pitch, RET s16 *yaw) { f32 dx = to[0] - from[0]; f32 dy = to[1] - from[1]; f32 dz = to[2] - from[2]; @@ -4853,7 +4853,7 @@ f32 calc_hor_dist(Vec3f a, Vec3f b) { /** * Rotates a vector in the horizontal plane and copies it to a new vector. */ -void rotate_in_xz(OUT Vec3f dst, Vec3f src, s16 yaw) { +void rotate_in_xz(VEC_OUT Vec3f dst, Vec3f src, s16 yaw) { Vec3f tempVec; vec3f_copy(tempVec, src); @@ -4868,7 +4868,7 @@ void rotate_in_xz(OUT Vec3f dst, Vec3f src, s16 yaw) { * Note: This function also flips the Z axis, so +Z moves forward, not backward like it would in world * space. If possible, use vec3f_set_dist_and_angle() */ -void rotate_in_yz(OUT Vec3f dst, Vec3f src, s16 pitch) { +void rotate_in_yz(VEC_OUT Vec3f dst, Vec3f src, s16 pitch) { Vec3f tempVec; vec3f_copy(tempVec, src); @@ -4962,7 +4962,7 @@ void increment_shake_offset(s16 *offset, s16 increment) { /** * Apply a vertical shake to the camera by adjusting its pitch */ -void shake_camera_pitch(Vec3f pos, OUT Vec3f focus) { +void shake_camera_pitch(Vec3f pos, VEC_OUT Vec3f focus) { f32 dist; s16 pitch; s16 yaw; @@ -4982,7 +4982,7 @@ void shake_camera_pitch(Vec3f pos, OUT Vec3f focus) { /** * Apply a horizontal shake to the camera by adjusting its yaw */ -void shake_camera_yaw(Vec3f pos, OUT Vec3f focus) { +void shake_camera_yaw(Vec3f pos, VEC_OUT Vec3f focus) { f32 dist; s16 pitch; s16 yaw; @@ -5629,7 +5629,7 @@ static void unused_set_pos_rel_mario(struct Camera *c, f32 leftRight, f32 yOff, * * @warning Flips the Z axis, so that relative to `rotation`, -Z moves forwards and +Z moves backwards. */ -void offset_rotated(OUT Vec3f dst, Vec3f from, Vec3f to, Vec3s rotation) { +void offset_rotated(VEC_OUT Vec3f dst, Vec3f from, Vec3f to, Vec3s rotation) { Vec3f unusedCopy; Vec3f pitchRotated; @@ -5683,7 +5683,7 @@ void determine_pushing_or_pulling_door(s16 *rotation) { * * @return Lakitu's next yaw, which is the same as the yaw passed in if no transition happened */ -s16 next_lakitu_state(OUT Vec3f newPos, OUT Vec3f newFoc, Vec3f curPos, Vec3f curFoc, +s16 next_lakitu_state(VEC_OUT Vec3f newPos, VEC_OUT Vec3f newFoc, Vec3f curPos, Vec3f curFoc, Vec3f oldPos, Vec3f oldFoc, s16 yaw) { s16 yawVelocity; s16 pitchVelocity; @@ -7073,7 +7073,7 @@ s16 camera_course_processing(struct Camera *c) { * Move `pos` between the nearest floor and ceiling * @param lastGood unused, passed as the last position the camera was in */ -void resolve_geometry_collisions(OUT Vec3f pos, UNUSED Vec3f lastGood) { +void resolve_geometry_collisions(VEC_OUT Vec3f pos, UNUSED Vec3f lastGood) { f32 ceilY, floorY; struct Surface *surf; @@ -7120,7 +7120,7 @@ void resolve_geometry_collisions(OUT Vec3f pos, UNUSED Vec3f lastGood) { * * @return 3 if a wall is covering Mario, 1 if a wall is only near the camera. */ -s32 rotate_camera_around_walls(struct Camera *c, Vec3f cPos, s16 *avoidYaw, s16 yawRange) { +s32 rotate_camera_around_walls(struct Camera *c, Vec3f cPos, INOUT s16 *avoidYaw, s16 yawRange) { UNUSED f32 unused1; struct WallCollisionData colData; struct Surface *wall; diff --git a/src/game/camera.h b/src/game/camera.h index 2d69e5dc4..50439dbcc 100644 --- a/src/game/camera.h +++ b/src/game/camera.h @@ -788,7 +788,7 @@ void stub_camera_3(UNUSED struct Camera *c); Converts an object's position to a `Vec3f` format. Useful for aligning object behaviors or interactions with the camera system |descriptionEnd| */ -void object_pos_to_vec3f(OUT Vec3f dst, struct Object *o); +void object_pos_to_vec3f(VEC_OUT Vec3f dst, struct Object *o); /* |description| Converts a `Vec3f` position to an object's internal format. @@ -799,7 +799,7 @@ void vec3f_to_object_pos(struct Object *o, Vec3f src); /* |description| Converts an object's face angle to a `Vec3s` format |descriptionEnd| */ -void object_face_angle_to_vec3s(OUT Vec3s dst, struct Object *o); +void object_face_angle_to_vec3s(VEC_OUT Vec3s dst, struct Object *o); /* |description| Converts a `Vec3s` angle to an object's face angle internal format @@ -809,7 +809,7 @@ void vec3s_to_object_face_angle(struct Object *o, Vec3s src); /* |description| Converts an object's move angle to a `Vec3s` format |descriptionEnd| */ -void object_move_angle_to_vec3s(OUT Vec3s dst, struct Object *o); +void object_move_angle_to_vec3s(VEC_OUT Vec3s dst, struct Object *o); /* |description| Converts a `Vec3s` angle to an object's move angle internal format @@ -840,7 +840,7 @@ void set_handheld_shake(u8 mode); Activates a handheld camera shake effect. Calculates positional and focus adjustments to simulate manual movement |descriptionEnd| */ -void shake_camera_handheld(Vec3f pos, OUT Vec3f focus); +void shake_camera_handheld(Vec3f pos, VEC_OUT Vec3f focus); /* |description| Determines which C-buttons are currently pressed by the player. @@ -854,13 +854,13 @@ s32 update_camera_hud_status(struct Camera *c); Checks for collisions between the camera and level geometry. Adjusts the camera's position to avoid clipping into walls or obstacles |descriptionEnd| */ -s32 collide_with_walls(OUT Vec3f pos, f32 offsetY, f32 radius); +s32 collide_with_walls(VEC_OUT Vec3f pos, f32 offsetY, f32 radius); /* |description| Clamps the camera's pitch angle between a maximum and minimum value. Prevents over-rotation and maintains a consistent viewing angle |descriptionEnd| */ -s32 clamp_pitch(Vec3f from, OUT Vec3f to, s16 maxPitch, s16 minPitch); +s32 clamp_pitch(Vec3f from, VEC_OUT Vec3f to, s16 maxPitch, s16 minPitch); /* |description| Checks if a position is within 100 units of Mario's current position. @@ -871,16 +871,17 @@ s32 is_within_100_units_of_mario(f32 posX, f32 posY, f32 posZ); /* |description| Smoothly transitions or directly sets a floating-point value (`dst`) to approach a target (`goal`). -Uses asymptotic scaling for gradual adjustments or direct assignment +Uses asymptotic scaling for gradual adjustments or direct assignment. +Returns FALSE if `dst` reaches `goal` |descriptionEnd| */ -s32 set_or_approach_f32_asymptotic(f32 *dst, f32 goal, f32 scale); +s32 set_or_approach_f32_asymptotic(INOUT f32 *dst, f32 goal, f32 scale); /* |description| Gradually adjusts a floating-point value (`current`) towards a target (`target`) using asymptotic smoothing. -Returns true if `current` reaches the `target` and false otherwise +Returns FALSE if `current` reaches the `target` |descriptionEnd| */ -s32 approach_f32_asymptotic_bool(f32 *current, f32 target, f32 multiplier); +s32 approach_f32_asymptotic_bool(INOUT f32 *current, f32 target, f32 multiplier); /* |description| Gradually approaches a floating-point value (`target`) using asymptotic smoothing. @@ -891,9 +892,9 @@ f32 approach_f32_asymptotic(f32 current, f32 target, f32 multiplier); /* |description| Gradually adjusts a signed 16-bit integer (`current`) towards a target (`target`) using asymptotic smoothing. -Returns true if `current` reaches `target` and false otherwise +Returns FALSE if `current` reaches `target` |descriptionEnd| */ -s32 approach_s16_asymptotic_bool(s16 *current, s16 target, s16 divisor); +s32 approach_s16_asymptotic_bool(INOUT s16 *current, s16 target, s16 divisor); /* |description| Gradually approaches a signed 16-bit integer (`target`) using asymptotic smoothing. @@ -906,31 +907,32 @@ s32 approach_s16_asymptotic(s16 current, s16 target, s16 divisor); Smoothly transitions a 3D vector (`current`) towards a target vector (`target`) using asymptotic scaling. Scaling values (the `Mul` variables) for x, y, and z axes determine the speed of adjustment for each component |descriptionEnd| */ -void approach_vec3f_asymptotic(OUT Vec3f current, Vec3f target, f32 xMul, f32 yMul, f32 zMul); +void approach_vec3f_asymptotic(VEC_OUT Vec3f current, Vec3f target, f32 xMul, f32 yMul, f32 zMul); /* |description| Smoothly transitions a 3D vector (`current`) toward a target vector (`goal`) using asymptotic scaling. Allows gradual or instantaneous alignment of 3D positions. Scaling values (the `Mul` variables) for x, y, and z axes determine the speed of adjustment for each component |descriptionEnd| */ -void set_or_approach_vec3f_asymptotic(OUT Vec3f dst, Vec3f goal, f32 xMul, f32 yMul, f32 zMul); +void set_or_approach_vec3f_asymptotic(VEC_OUT Vec3f dst, Vec3f goal, f32 xMul, f32 yMul, f32 zMul); /* |description| Adjusts a signed 16-bit integer (`current`) towards a target (`target`) symmetrically with a fixed increment (`increment`). -Returns true if the value reaches the target and false otherwise +Returns FALSE if `current` reaches the `target` |descriptionEnd| */ -s32 camera_approach_s16_symmetric_bool(s16 *current, s16 target, s16 increment); +s32 camera_approach_s16_symmetric_bool(INOUT s16 *current, s16 target, s16 increment); /* |description| Smoothly transitions or directly sets a signed 16-bit value (`current`) to approach a target (`target`). -Uses symmetric scaling for gradual or immediate adjustments +Uses symmetric scaling for gradual or immediate adjustments. +Returns FALSE if `current` reaches the `target` |descriptionEnd| */ -s32 set_or_approach_s16_symmetric(s16 *current, s16 target, s16 increment); +s32 set_or_approach_s16_symmetric(INOUT s16 *current, s16 target, s16 increment); /* |description| Adjusts a floating-point value (`current`) towards a target (`target`) symmetrically with a fixed increment (`increment`). -Returns true if the value reaches the target and false otherwise +Returns FALSE if `current` reaches the `target` |descriptionEnd| */ -s32 camera_approach_f32_symmetric_bool(f32 *current, f32 target, f32 increment); +s32 camera_approach_f32_symmetric_bool(INOUT f32 *current, f32 target, f32 increment); /* |description| Symmetrically approaches a floating-point value (`target`) with a fixed increment (`increment`) per frame. @@ -942,13 +944,13 @@ f32 camera_approach_f32_symmetric(f32 value, f32 target, f32 increment); Generates a random 3D vector with short integer components. Useful for randomized offsets or environmental effects |descriptionEnd| */ -void random_vec3s(OUT Vec3s dst, s16 xRange, s16 yRange, s16 zRange); +void random_vec3s(VEC_OUT Vec3s dst, s16 xRange, s16 yRange, s16 zRange); /* |description| Clamps a position within specified X and Z bounds and calculates the yaw angle from the origin. Prevents the camera from moving outside of the designated area |descriptionEnd| */ -s32 clamp_positions_and_find_yaw(OUT Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f32 zMax, f32 zMin); +s32 clamp_positions_and_find_yaw(VEC_OUT Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f32 zMax, f32 zMin); /* |description| Determines if a range is obstructed by a surface relative to the camera. @@ -961,7 +963,7 @@ Scales a point along a line between two 3D points (`from` and `to`). The scaling factor determines how far along the line the resulting point will be. The result is stored in the destination vector (`dest`) |descriptionEnd| */ -void scale_along_line(OUT Vec3f dest, Vec3f from, Vec3f to, f32 scale); +void scale_along_line(VEC_OUT Vec3f dest, Vec3f from, Vec3f to, f32 scale); /* |description| Calculates the pitch angle (rotation around the X-axis) from one 3D point (`from`) to another (`to`). @@ -976,10 +978,9 @@ Returns the yaw as a signed 16-bit integer s16 calculate_yaw(Vec3f from, Vec3f to); /* |description| -Calculates the pitch and yaw angles from one 3D position (`from`) to another (`to`). -Updates the provided pointers with the computed pitch and yaw values +Calculates and returns the pitch and yaw angles from one 3D position (`from`) to another (`to`) |descriptionEnd| */ -void calculate_angles(Vec3f from, Vec3f to, s16 *pitch, s16 *yaw); +void calculate_angles(Vec3f from, Vec3f to, RET s16 *pitch, RET s16 *yaw); /* |description| Calculates the absolute distance between two 3D points (`a` and `b`). @@ -1000,14 +1001,14 @@ Rotates a vector around the XZ-plane by a specified yaw angle. The result is stored in the destination vector (`dst`). Useful for rotating camera positions or object coordinates horizontally |descriptionEnd| */ -void rotate_in_xz(OUT Vec3f dst, Vec3f src, s16 yaw); +void rotate_in_xz(VEC_OUT Vec3f dst, Vec3f src, s16 yaw); /* |description| Rotates a vector around the YZ-plane by a specified pitch angle. The result is stored in the destination vector (`dst`). Useful for vertical camera rotations or object transformations |descriptionEnd| */ -void rotate_in_yz(OUT Vec3f dst, Vec3f src, s16 pitch); +void rotate_in_yz(VEC_OUT Vec3f dst, Vec3f src, s16 pitch); /* |description| Applies a pitch-based shake effect to the camera. @@ -1038,19 +1039,19 @@ void set_pitch_shake_from_point(s16 mag, s16 decay, s16 inc, f32 maxDist, f32 po Activates a pitch-based shake effect. Adds vertical vibrational movement to the camera's behavior |descriptionEnd| */ -void shake_camera_pitch(Vec3f pos, OUT Vec3f focus); +void shake_camera_pitch(Vec3f pos, VEC_OUT Vec3f focus); /* |description| Activates a yaw-based shake effect. Adds horizontal vibrational movement to the camera's behavior |descriptionEnd| */ -void shake_camera_yaw(Vec3f pos, OUT Vec3f focus); +void shake_camera_yaw(Vec3f pos, VEC_OUT Vec3f focus); /* |description| Applies a roll-based shake effect to the camera. Simulates rotational disturbances caused by impacts or other events |descriptionEnd| */ -void shake_camera_roll(s16 *roll); +void shake_camera_roll(INOUT s16 *roll); /* |description| Calculates an outward radial offset based on the camera's yaw angle. @@ -1158,13 +1159,13 @@ void approach_camera_height(struct Camera *c, f32 goal, f32 inc); Offsets a vector by rotating it in 3D space relative to a reference position. This is useful for creating radial effects or dynamic transformations |descriptionEnd| */ -void offset_rotated(OUT Vec3f dst, Vec3f from, Vec3f to, Vec3s rotation); +void offset_rotated(VEC_OUT Vec3f dst, Vec3f from, Vec3f to, Vec3s rotation); /* |description| Transitions the camera to the next Lakitu state, updating position and focus. This function handles smooth transitions between different gameplay scenarios |descriptionEnd| */ -s16 next_lakitu_state(OUT Vec3f newPos, OUT Vec3f newFoc, Vec3f curPos, Vec3f curFoc, Vec3f oldPos, Vec3f oldFoc, s16 yaw); +s16 next_lakitu_state(VEC_OUT Vec3f newPos, VEC_OUT Vec3f newFoc, Vec3f curPos, Vec3f curFoc, Vec3f oldPos, Vec3f oldFoc, s16 yaw); /* |description|Set the fixed camera base pos depending on the current level area|descriptionEnd| */ void set_fixed_cam_axis_sa_lobby(UNUSED s16 preset); @@ -1178,13 +1179,13 @@ s16 camera_course_processing(struct Camera *c); Resolves collisions between the camera and level geometry. Adjusts the camera's position to prevent clipping or intersecting with objects |descriptionEnd| */ -void resolve_geometry_collisions(OUT Vec3f pos, UNUSED Vec3f lastGood); +void resolve_geometry_collisions(VEC_OUT Vec3f pos, UNUSED Vec3f lastGood); /* |description| Rotates the camera to avoid walls or other obstructions. Ensures clear visibility of the player or target objects |descriptionEnd| */ -s32 rotate_camera_around_walls(struct Camera *c, Vec3f cPos, s16 *avoidYaw, s16 yawRange); +s32 rotate_camera_around_walls(struct Camera *c, Vec3f cPos, INOUT s16 *avoidYaw, s16 yawRange); /* |description| diff --git a/src/game/hardcoded.c b/src/game/hardcoded.c index 6ce8364d8..344a370ad 100644 --- a/src/game/hardcoded.c +++ b/src/game/hardcoded.c @@ -168,6 +168,7 @@ struct BehaviorValues gDefaultBehaviorValues = { .RespawnShellBoxes = TRUE, .MultipleCapCollection = FALSE, .InfiniteRenderDistance = TRUE, + .ProcessLODs = FALSE, .CourtyardBoosRequirement = 12, .starsNeededForDialog = { 1, 3, 8, 30, 50, 70 }, .dialogs = { diff --git a/src/game/hardcoded.h b/src/game/hardcoded.h index d0c6ebb23..bb597d2a0 100644 --- a/src/game/hardcoded.h +++ b/src/game/hardcoded.h @@ -265,6 +265,7 @@ struct BehaviorValues { u8 RespawnShellBoxes; u8 MultipleCapCollection; u8 InfiniteRenderDistance; + u8 ProcessLODs; s16 CourtyardBoosRequirement; struct StarsNeededForDialog starsNeededForDialog; struct BehaviorDialogs dialogs; diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h index e2ed324df..5ea2c4f87 100644 --- a/src/game/ingame_menu.h +++ b/src/game/ingame_menu.h @@ -134,6 +134,8 @@ extern u8 gDialogTextColorG; extern u8 gDialogTextColorB; extern u8 gDialogTextColorA; +extern bool gPauseMenuHidden; + extern s16 gMenuMode; void create_dl_identity_matrix(void); diff --git a/src/game/level_update.h b/src/game/level_update.h index 5ffd5d242..704924a01 100644 --- a/src/game/level_update.h +++ b/src/game/level_update.h @@ -193,6 +193,7 @@ void initiate_painting_warp(s16 paintingIndex); /* |description|Triggers a warp (WARP_OP_*) for the level. Pass in `gMarioStates[0]` for `m`|descriptionEnd| */ s16 level_trigger_warp(struct MarioState *m, s32 warpOp); void level_set_transition(s16 length, void (*updateFunction)(s16 *)); +void set_play_mode(s16 playMode); /* |description|Special warps to arg (`SPECIAL_WARP_*`)|descriptionEnd| */ void warp_special(s32 arg); /* |description|Initiates a warp to `destLevel` in `destArea` at `destWarpNode` with `arg`. This function is unstable and it's generally recommended to use `warp_to_level` instead|descriptionEnd| */ diff --git a/src/game/mario.c b/src/game/mario.c index 99db7a0fd..2c1e6c56b 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -200,7 +200,7 @@ s32 is_anim_past_frame(struct MarioState *m, s16 animFrame) { * Rotates the animation's translation into the global coordinate system * and returns the animation's flags. */ -s16 find_mario_anim_flags_and_translation(struct Object *obj, s32 yaw, OUT Vec3s translation) { +s16 find_mario_anim_flags_and_translation(struct Object *obj, s32 yaw, VEC_OUT Vec3s translation) { if (!obj) { return 0; } f32 dx; f32 dz; @@ -620,7 +620,7 @@ u32 mario_get_terrain_sound_addend(struct MarioState *m) { /** * Collides with walls and returns the most recent wall. */ -struct Surface *resolve_and_return_wall_collisions(OUT Vec3f pos, f32 offset, f32 radius) { +struct Surface *resolve_and_return_wall_collisions(VEC_OUT Vec3f pos, f32 offset, f32 radius) { struct WallCollisionData collisionData; struct Surface *wall = NULL; @@ -645,7 +645,7 @@ struct Surface *resolve_and_return_wall_collisions(OUT Vec3f pos, f32 offset, f3 /** * Collides with walls and returns the wall collision data. */ -void resolve_and_return_wall_collisions_data(OUT Vec3f pos, f32 offset, f32 radius, struct WallCollisionData* collisionData) { +void resolve_and_return_wall_collisions_data(VEC_OUT Vec3f pos, f32 offset, f32 radius, struct WallCollisionData* collisionData) { if (!collisionData || !pos) { return; } collisionData->x = pos[0]; @@ -664,7 +664,7 @@ void resolve_and_return_wall_collisions_data(OUT Vec3f pos, f32 offset, f32 radi /** * Finds the ceiling from a vec3f horizontally and a height (with 80 vertical buffer). */ -f32 vec3f_find_ceil(Vec3f pos, f32 height, struct Surface **ceil) { +f32 vec3f_find_ceil(Vec3f pos, f32 height, RET struct Surface **ceil) { if (!ceil) { return 0; } UNUSED f32 unused; @@ -676,7 +676,7 @@ f32 vec3f_find_ceil(Vec3f pos, f32 height, struct Surface **ceil) { * Prevents exposed ceiling bug */ // Prevent exposed ceilings -f32 vec3f_mario_ceil(Vec3f pos, f32 height, struct Surface **ceil) { +f32 vec3f_mario_ceil(Vec3f pos, f32 height, RET struct Surface **ceil) { if (!ceil) { return 0; } if (gLevelValues.fixCollisionBugs) { height = MAX(height + 80.0f, pos[1] - 2); @@ -1543,6 +1543,8 @@ void update_mario_geometry_inputs(struct MarioState *m) { gasLevel = find_poison_gas_level(m->pos[0], m->pos[2]); m->waterLevel = find_water_level(m->pos[0], m->pos[2]); + if (m->action == ACT_DEBUG_FREE_MOVE) { return; } + if (m->floor != NULL) { m->floorAngle = atan2s(m->floor->normal.z, m->floor->normal.x); m->terrainSoundAddend = mario_get_terrain_sound_addend(m); @@ -1577,7 +1579,6 @@ void update_mario_geometry_inputs(struct MarioState *m) { } else { vec3s_to_vec3f(m->pos, m->spawnInfo->startPos); m->faceAngle[1] = m->spawnInfo->startAngle[1]; - if (mario_can_bubble(m)) { mario_set_bubbled(m); } struct Surface* floor = NULL; find_floor(m->pos[0], m->pos[1], m->pos[2], &floor); if (floor == NULL) { @@ -2060,7 +2061,7 @@ s32 execute_mario_action(UNUSED struct Object *o) { } // If Mario is OOB, stop executing actions. - if (gMarioState->floor == NULL) { + if (gMarioState->floor == NULL && gMarioState->action != ACT_DEBUG_FREE_MOVE) { return 0; } diff --git a/src/game/mario.h b/src/game/mario.h index e0e4656cf..897178043 100644 --- a/src/game/mario.h +++ b/src/game/mario.h @@ -58,7 +58,7 @@ s32 is_anim_past_frame(struct MarioState *m, s16 animFrame); Retrieves the current animation flags and calculates the translation for Mario's animation, rotating it into the global coordinate system based on `yaw`. Useful for determining positional offsets from animations (e.g., stepping forward in a walk animation) and applying them to Mario's position |descriptionEnd| */ -s16 find_mario_anim_flags_and_translation(struct Object *o, s32 yaw, OUT Vec3s translation); +s16 find_mario_anim_flags_and_translation(struct Object *o, s32 yaw, VEC_OUT Vec3s translation); /* |description| Applies the translation from Mario's current animation to his world position. Considers animation flags (horizontal/vertical translation) @@ -166,15 +166,25 @@ u32 mario_get_terrain_sound_addend(struct MarioState *m); Checks for and resolves wall collisions at a given position `pos`, returning the last wall encountered. Primarily used to prevent Mario from going through walls. Useful for collision detection when updating Mario's movement or adjusting his position |descriptionEnd| */ -struct Surface *resolve_and_return_wall_collisions(OUT Vec3f pos, f32 offset, f32 radius); +struct Surface *resolve_and_return_wall_collisions(VEC_OUT Vec3f pos, f32 offset, f32 radius); /* |description| Similar to `resolve_and_return_wall_collisions` but also returns detailed collision data (`WallCollisionData`). This can handle multiple walls and store them for further checks |descriptionEnd| */ -void resolve_and_return_wall_collisions_data(OUT Vec3f pos, f32 offset, f32 radius, struct WallCollisionData* collisionData); +void resolve_and_return_wall_collisions_data(VEC_OUT Vec3f pos, f32 offset, f32 radius, struct WallCollisionData* collisionData); -f32 vec3f_find_ceil(Vec3f pos, f32 height, struct Surface **ceil); -f32 vec3f_mario_ceil(Vec3f pos, f32 height, struct Surface **ceil); +/* |description| +Finds the ceiling from a vec3f horizontally and a height (with 80 vertical buffer). +Returns the ceiling height and surface +|descriptionEnd| */ +f32 vec3f_find_ceil(Vec3f pos, f32 height, RET struct Surface **ceil); + +/* |description| +Finds the ceiling from a vec3f horizontally and a height (with 80 vertical buffer). +Prevents exposed ceiling bug. +Returns the ceiling height and surface +|descriptionEnd| */ +f32 vec3f_mario_ceil(Vec3f pos, f32 height, RET struct Surface **ceil); /* |description| Determines if Mario is facing downhill relative to his floor angle, optionally accounting for forward velocity direction. Returns true if he is oriented down the slope. diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index 8c368a4ea..5bf71f395 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -2328,7 +2328,7 @@ Dispatches to the appropriate action function, such as jump, double jump, freefa |descriptionEnd| */ s32 mario_execute_airborne_action(struct MarioState *m) { if (!m) { return FALSE; } - u32 cancel; + s32 cancel; if (check_common_airborne_cancels(m)) { return TRUE; @@ -2336,7 +2336,7 @@ s32 mario_execute_airborne_action(struct MarioState *m) { play_far_fall_sound(m); - if (!smlua_call_action_hook(ACTION_HOOK_EVERY_FRAME, m, (s32*)&cancel)) { + if (!smlua_call_action_hook(ACTION_HOOK_EVERY_FRAME, m, &cancel)) { /* clang-format off */ switch (m->action) { case ACT_JUMP: cancel = act_jump(m); break; @@ -2385,9 +2385,9 @@ s32 mario_execute_airborne_action(struct MarioState *m) { case ACT_TOP_OF_POLE_JUMP: cancel = act_top_of_pole_jump(m); break; case ACT_VERTICAL_WIND: cancel = act_vertical_wind(m); break; default: - LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); + LOG_ERROR("Attempted to execute unimplemented action '%08X'", m->action); set_mario_action(m, ACT_FREEFALL, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 535d94110..af518c18e 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -344,7 +344,7 @@ s32 act_top_of_pole(struct MarioState *m) { /* |description| Performs a single step of movement while Mario is hanging from a ceiling. It handles wall collisions and checks the floor and ceiling to determine if Mario remains hanging, leaves the ceiling, or hits it |descriptionEnd| */ -s32 perform_hanging_step(struct MarioState *m, OUT Vec3f nextPos) { +s32 perform_hanging_step(struct MarioState *m, VEC_OUT Vec3f nextPos) { if (!m) { return 0; } UNUSED s32 unused; struct Surface *ceil; @@ -1219,9 +1219,9 @@ s32 mario_execute_automatic_action(struct MarioState *m) { case ACT_TORNADO_TWIRLING: cancel = act_tornado_twirling(m); break; case ACT_BUBBLED: cancel = act_bubbled(m); break; default: - LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); + LOG_ERROR("Attempted to execute unimplemented action '%08X'", m->action); set_mario_action(m, ACT_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 51026b681..8d598b313 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -693,12 +693,10 @@ s32 act_debug_free_move(struct MarioState *m) { struct Surface *surf = NULL; f32 floorHeight = find_floor(pos[0], pos[1], pos[2], &surf); - if (surf != NULL) { - if (pos[1] < floorHeight) { - pos[1] = floorHeight; - } - vec3f_copy(m->pos, pos); + if (pos[1] < floorHeight) { + pos[1] = floorHeight; } + vec3f_copy(m->pos, pos); m->faceAngle[1] = m->intendedYaw; vec3f_copy(m->marioObj->header.gfx.pos, m->pos); @@ -3190,9 +3188,9 @@ s32 mario_execute_cutscene_action(struct MarioState *m) { case ACT_FEET_STUCK_IN_GROUND: cancel = act_feet_stuck_in_ground(m); break; case ACT_PUTTING_ON_CAP: cancel = act_putting_on_cap(m); break; default: - LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); + LOG_ERROR("Attempted to execute unimplemented action '%08X'", m->action); set_mario_action(m, ACT_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index c22f2a631..6a21d45d5 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -2262,9 +2262,9 @@ s32 mario_execute_moving_action(struct MarioState *m) { case ACT_HOLD_QUICKSAND_JUMP_LAND: cancel = act_hold_quicksand_jump_land(m); break; case ACT_LONG_JUMP_LAND: cancel = act_long_jump_land(m); break; default: - LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); + LOG_ERROR("Attempted to execute unimplemented action '%08X'", m->action); set_mario_action(m, ACT_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_object.c b/src/game/mario_actions_object.c index ca66da1db..02d8dbdf0 100644 --- a/src/game/mario_actions_object.c +++ b/src/game/mario_actions_object.c @@ -534,9 +534,9 @@ s32 mario_execute_object_action(struct MarioState *m) { case ACT_HOLDING_BOWSER: cancel = act_holding_bowser(m); break; case ACT_RELEASING_BOWSER: cancel = act_releasing_bowser(m); break; default: - LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); + LOG_ERROR("Attempted to execute unimplemented action '%08X'", m->action); set_mario_action(m, ACT_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_stationary.c b/src/game/mario_actions_stationary.c index 8fe099c85..3a7ae400b 100644 --- a/src/game/mario_actions_stationary.c +++ b/src/game/mario_actions_stationary.c @@ -1300,9 +1300,9 @@ s32 mario_execute_stationary_action(struct MarioState *m) { case ACT_HOLD_BUTT_SLIDE_STOP: cancel = act_hold_butt_slide_stop(m); break; case ACT_PALETTE_EDITOR_CAP: cancel = act_palette_editor_cap(m); break; default: - LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); + LOG_ERROR("Attempted to execute unimplemented action '%08X'", m->action); set_mario_action(m, ACT_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index e573613c1..61f3a0e15 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -85,7 +85,7 @@ static f32 get_buoyancy(struct MarioState *m) { } /* |description|Performs a full water movement step where ceilings, floors, and walls are handled. Generally, you should use `perform_water_step` for the full step functionality|descriptionEnd| */ -u32 perform_water_full_step(struct MarioState *m, OUT Vec3f nextPos) { +u32 perform_water_full_step(struct MarioState *m, VEC_OUT Vec3f nextPos) { if (!m) { return 0; } struct WallCollisionData wcd = { 0 }; struct Surface *ceil; @@ -136,7 +136,7 @@ u32 perform_water_full_step(struct MarioState *m, OUT Vec3f nextPos) { } /* |description|Calculates a water current and outputs it in `step`|descriptionEnd| */ -void apply_water_current(struct MarioState *m, OUT Vec3f step) { +void apply_water_current(struct MarioState *m, VEC_OUT Vec3f step) { if (!m) { return; } s32 i; f32 whirlpoolRadius = 2000.0f; @@ -1710,9 +1710,9 @@ s32 mario_execute_submerged_action(struct MarioState *m) { case ACT_HOLD_METAL_WATER_JUMP: cancel = act_hold_metal_water_jump(m); break; case ACT_HOLD_METAL_WATER_JUMP_LAND: cancel = act_hold_metal_water_jump_land(m); break; default: - LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); + LOG_ERROR("Attempted to execute unimplemented action '%08X'", m->action); set_mario_action(m, ACT_WATER_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c index f2e742d69..4c13b7cfa 100644 --- a/src/game/mario_misc.c +++ b/src/game/mario_misc.c @@ -782,6 +782,13 @@ static struct PlayerColor geo_mario_get_player_color(const struct PlayerPalette return color; } +void get_player_color(u8 index, u8 part, f32 *out) { + const struct PlayerPalette *palette = &gNetworkPlayers[index].overridePalette; + out[0] = palette->parts[part][0] / 255.0f; + out[1] = palette->parts[part][1] / 255.0f; + out[2] = palette->parts[part][2] / 255.0f; +} + static Gfx *geo_mario_create_player_colors_dl(s32 index, Gfx *capEnemyGfx, Gfx *capEnemyDecalGfx) { s32 size = ((PLAYER_PART_MAX * 2) + 1) + (capEnemyGfx != NULL) + (capEnemyDecalGfx != NULL); Gfx *gfx = alloc_display_list(size * sizeof(Gfx)); diff --git a/src/game/mario_step.c b/src/game/mario_step.c index 5f8a84145..a01154ba8 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -675,11 +675,13 @@ u32 should_strengthen_gravity_for_jump_ascent(struct MarioState *m) { void apply_gravity(struct MarioState *m) { if (!m) { return; } - s32 result; - if (smlua_call_action_hook(ACTION_HOOK_GRAVITY, m, &result)) { - - } else if (m->action == ACT_TWIRLING && m->vel[1] < 0.0f) { + UNUSED s32 cancel; + if (smlua_call_action_hook(ACTION_HOOK_GRAVITY, m, &cancel)) { + return; + } + + if (m->action == ACT_TWIRLING && m->vel[1] < 0.0f) { apply_twirl_gravity(m); } else if (m->action == ACT_SHOT_FROM_CANNON) { m->vel[1] -= 1.0f; diff --git a/src/game/obj_behaviors.c b/src/game/obj_behaviors.c index 4860e72a1..9af5339af 100644 --- a/src/game/obj_behaviors.c +++ b/src/game/obj_behaviors.c @@ -251,10 +251,8 @@ void obj_orient_graph(struct Object *obj, f32 normalX, f32 normalY, f32 normalZ) obj->header.gfx.throwMatrix = throwMatrix; } -/** - * Determines an object's forward speed multiplier. - */ -void calc_obj_friction(f32 *objFriction, f32 floor_nY) { +/* |description|Determines an object's forward speed multiplier.|descriptionEnd| */ +void calc_obj_friction(RET f32 *objFriction, f32 floor_nY) { if (!o) { return; } if (!objFriction) { return; } if (floor_nY < 0.2 && o->oFriction < 0.9999) { @@ -760,7 +758,7 @@ s8 obj_check_if_facing_toward_angle(u32 base, u32 goal, s16 range) { } /* |description|Finds any wall collisions and returns what the displacement vector would be.|descriptionEnd| */ -s8 obj_find_wall_displacement(OUT Vec3f dist, f32 x, f32 y, f32 z, f32 radius) { +s8 obj_find_wall_displacement(VEC_OUT Vec3f dist, f32 x, f32 y, f32 z, f32 radius) { struct WallCollisionData hitbox; UNUSED u8 filler[0x20]; diff --git a/src/game/obj_behaviors_2.c b/src/game/obj_behaviors_2.c index a4380e98e..721edfb35 100644 --- a/src/game/obj_behaviors_2.c +++ b/src/game/obj_behaviors_2.c @@ -419,8 +419,8 @@ s16 obj_turn_pitch_toward_mario(struct MarioState* m, f32 targetOffsetY, s16 tur return targetPitch; } -/* |description|Approaches a `target` for `px` using `delta`|descriptionEnd| */ -s32 approach_f32_ptr(f32 *px, f32 target, f32 delta) { +/* |description|Approaches a `target` for `px` using `delta`. Returns TRUE if `px` reaches `target`|descriptionEnd| */ +s32 approach_f32_ptr(INOUT f32 *px, f32 target, f32 delta) { if (!px) { return FALSE; } if (*px > target) { delta = -delta; @@ -495,8 +495,8 @@ s32 obj_face_roll_approach(s16 targetRoll, s16 deltaRoll) { return FALSE; } -/* |description|Smoothly turns the `angle` integer pointer using parameters, although usage in Lua is difficult due to the amount of pointers needed|descriptionEnd| */ -s32 obj_smooth_turn(s16 *angleVel, s32 *angle, s16 targetAngle, f32 targetSpeedProportion, +/* |description|Smoothly turns `angle` and adjust `angleVel` using parameters. Returns TRUE if `angle` reaches `targetAngle`|descriptionEnd| */ +s32 obj_smooth_turn(INOUT s16 *angleVel, INOUT s32 *angle, s16 targetAngle, f32 targetSpeedProportion, s16 accel, s16 minSpeed, s16 maxSpeed) { s16 currentSpeed; s16 currentAngle = (s16)(*angle); @@ -537,13 +537,12 @@ s16 obj_random_fixed_turn(s16 delta) { } /* |description| -Begin by increasing the current object's scale by `*scaleVel`, and slowly decreasing -`scaleVel`. Once the object starts to shrink, wait a bit, and then begin to -scale the object toward `endScale`. The first time it reaches below -`shootFireScale` during this time, return 1. +Begin by increasing the current object's scale by `scaleVel`, and slowly decreasing `scaleVel`. +Once the object starts to shrink, wait a bit, and then begin to scale the object toward `endScale`. +The first time it reaches below `shootFireScale` during this time, return 1. Return -1 once it's reached endScale |descriptionEnd| */ -s32 obj_grow_then_shrink(f32 *scaleVel, f32 shootFireScale, f32 endScale) { +s32 obj_grow_then_shrink(INOUT f32 *scaleVel, f32 shootFireScale, f32 endScale) { if (!o) { return 0; } if (o->oTimer < 2) { o->header.gfx.scale[0] += *scaleVel; @@ -563,8 +562,8 @@ s32 obj_grow_then_shrink(f32 *scaleVel, f32 shootFireScale, f32 endScale) { return 0; } -/* |description||descriptionEnd| */ -s32 oscillate_toward(s32 *value, f32 *vel, s32 target, f32 velCloseToZero, f32 accel, +/* |description|Oscillates `value` towards `target`. Returns TRUE when `value` reaches `target`|descriptionEnd| */ +s32 oscillate_toward(INOUT s32 *value, INOUT f32 *vel, s32 target, f32 velCloseToZero, f32 accel, f32 slowdown) { if (value == NULL || vel == NULL) { return FALSE; } s32 startValue = *value; @@ -591,7 +590,7 @@ s32 oscillate_toward(s32 *value, f32 *vel, s32 target, f32 velCloseToZero, f32 a } /* |description|Update the current object's blinking through `oAnimState`|descriptionEnd| */ -void obj_update_blinking(s32 *blinkTimer, s16 baseCycleLength, s16 cycleLengthRange, +void obj_update_blinking(INOUT s32 *blinkTimer, s16 baseCycleLength, s16 cycleLengthRange, s16 blinkLength) { if (!o) { return; } if (*blinkTimer != 0) { @@ -607,8 +606,8 @@ void obj_update_blinking(s32 *blinkTimer, s16 baseCycleLength, s16 cycleLengthRa } } -/* |description|Resolves "collisions" with the current object and other objects by offsetting the current object's position|descriptionEnd| */ -s32 obj_resolve_object_collisions(s32 *targetYaw) { +/* |description|Resolves "collisions" with the current object and other objects by offsetting the current object's position. Returns TRUE and the target yaw if there is collision|descriptionEnd| */ +s32 obj_resolve_object_collisions(RET s32 *targetYaw) { if (!o) { return 0; } struct Object *otherObject; f32 dx; @@ -655,8 +654,8 @@ s32 obj_resolve_object_collisions(s32 *targetYaw) { return FALSE; } -/* |description|Bounces the current object off of walls, edges, and objects using `*targetYaw`|descriptionEnd| */ -s32 obj_bounce_off_walls_edges_objects(s32 *targetYaw) { +/* |description|Bounces the current object off of walls, edges, and objects. Returns TRUE and the target yaw if there is collision|descriptionEnd| */ +s32 obj_bounce_off_walls_edges_objects(RET s32 *targetYaw) { if (!o) { return 0; } if (o->oMoveFlags & OBJ_MOVE_HIT_WALL) { *targetYaw = cur_obj_reflect_move_angle_off_wall(); @@ -961,7 +960,8 @@ s32 obj_move_for_one_second(s32 endAction) { * attack Mario (e.g. fly guy shooting fire or lunging), especially when combined * with partial updates. */ -void treat_far_home_as_mario(f32 threshold, s32* distanceToPlayer, s32* angleToPlayer) { +/* |description|Treats far home as Mario. Returns the distance and angle to the nearest player|descriptionEnd| */ +void treat_far_home_as_mario(f32 threshold, RET s32* distanceToPlayer, RET s32* angleToPlayer) { if (!o) { return; } f32 dx = o->oHomeX - o->oPosX; f32 dy = o->oHomeY - o->oPosY; diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 6c7efd76c..695a3fbd0 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -42,7 +42,8 @@ static s8 sLevelsWithRooms[] = { LEVEL_BBH, LEVEL_CASTLE, LEVEL_HMC, -1 }; #define o gCurrentObject -s32 clear_move_flag(u32 *bitSet, s32 flag) { +/* |description|Clears the `flag` from the `bitSet`|descriptionEnd| */ +s32 clear_move_flag(INOUT u32 *bitSet, s32 flag) { if (*bitSet & flag) { *bitSet &= flag ^ 0xFFFFFFFF; return TRUE; @@ -273,7 +274,7 @@ void obj_update_pos_from_parent_transformation(Mat4 a0, struct Object *a1) { a1->oPosZ = spC * a0[0][2] + sp8 * a0[1][2] + sp4 * a0[2][2] + a0[3][2]; } -void obj_apply_scale_to_matrix(struct Object *obj, OUT Mat4 dst, Mat4 src) { +void obj_apply_scale_to_matrix(struct Object *obj, VEC_OUT Mat4 dst, Mat4 src) { if (obj == NULL) { return; } dst[0][0] = src[0][0] * obj->header.gfx.scale[0]; dst[1][0] = src[1][0] * obj->header.gfx.scale[1]; @@ -296,7 +297,7 @@ void obj_apply_scale_to_matrix(struct Object *obj, OUT Mat4 dst, Mat4 src) { dst[3][3] = src[3][3]; } -void create_transformation_from_matrices(OUT Mat4 a0, Mat4 a1, Mat4 a2) { +void create_transformation_from_matrices(VEC_OUT Mat4 a0, Mat4 a1, Mat4 a2) { f32 spC, sp8, sp4; spC = a2[3][0] * a2[0][0] + a2[3][1] * a2[0][1] + a2[3][2] * a2[0][2]; @@ -384,7 +385,7 @@ void cur_obj_forward_vel_approach_upward(f32 target, f32 increment) { } } -s32 approach_f32_signed(f32 *value, f32 target, f32 increment) { +s32 approach_f32_signed(INOUT f32 *value, f32 target, f32 increment) { if (value == NULL) { return 0; } s32 reachedTarget = FALSE; @@ -825,7 +826,7 @@ Multiplies a vector by a matrix of the form: `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space |descriptionEnd| */ -void linear_mtxf_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v) { +void linear_mtxf_mul_vec3f(Mat4 m, VEC_OUT Vec3f dst, Vec3f v) { s32 i; for (i = 0; i < 3; i++) { dst[i] = m[0][i] * v[0] + m[1][i] * v[1] + m[2][i] * v[2]; @@ -840,7 +841,7 @@ Multiplies a vector by the transpose of a matrix of the form: `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space |descriptionEnd| */ -void linear_mtxf_transpose_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v) { +void linear_mtxf_transpose_mul_vec3f(Mat4 m, VEC_OUT Vec3f dst, Vec3f v) { s32 i; for (i = 0; i < 3; i++) { dst[i] = m[i][0] * v[0] + m[i][1] * v[1] + m[i][2] * v[2]; @@ -1079,7 +1080,7 @@ struct Object* cur_obj_find_nearest_pole(void) { return closestObj; } -struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, f32 *dist) { +struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, RET f32 *dist) { if (!behavior || !dist) { return NULL; } behavior = smlua_override_behavior(behavior); @@ -1519,7 +1520,7 @@ struct Surface *cur_obj_update_floor_height_and_get_floor(void) { return floor; } -void apply_drag_to_value(f32 *value, f32 dragStrength) { +void apply_drag_to_value(INOUT f32 *value, f32 dragStrength) { f32 decel; if (*value != 0) { diff --git a/src/game/object_helpers.h b/src/game/object_helpers.h index 9e4a32df0..fc65f764a 100644 --- a/src/game/object_helpers.h +++ b/src/game/object_helpers.h @@ -73,14 +73,14 @@ Gfx *geo_switch_area(s32 callContext, struct GraphNode *node); #endif Gfx *geo_choose_area_ext(s32 callContext, UNUSED struct GraphNode *node, Mat4 mtx); void obj_update_pos_from_parent_transformation(Mat4 a0, struct Object *a1); -void obj_apply_scale_to_matrix(struct Object *obj, OUT Mat4 dst, Mat4 src); -void create_transformation_from_matrices(OUT Mat4 a0, Mat4 a1, Mat4 a2); +void obj_apply_scale_to_matrix(struct Object *obj, VEC_OUT Mat4 dst, Mat4 src); +void create_transformation_from_matrices(VEC_OUT Mat4 a0, Mat4 a1, Mat4 a2); void obj_set_held_state(struct Object *obj, const BehaviorScript *heldBehavior); f32 lateral_dist_between_objects(struct Object *obj1, struct Object *obj2); f32 dist_between_objects(struct Object *obj1, struct Object *obj2); f32 dist_between_object_and_point(struct Object *obj, f32 pointX, f32 pointY, f32 pointZ); void cur_obj_forward_vel_approach_upward(f32 target, f32 increment); -s32 approach_f32_signed(f32 *value, f32 target, f32 increment); +s32 approach_f32_signed(INOUT f32 *value, f32 target, f32 increment); f32 approach_f32_symmetric(f32 value, f32 target, f32 increment); s16 approach_s16_symmetric(s16 value, s16 target, s16 increment); s32 cur_obj_rotate_yaw_toward(s16 target, s16 increment); @@ -119,8 +119,8 @@ void obj_copy_pos_and_angle(struct Object *dst, struct Object *src); void obj_copy_pos(struct Object *dst, struct Object *src); void obj_copy_angle(struct Object *dst, struct Object *src); void obj_set_gfx_pos_from_pos(struct Object *obj); -void linear_mtxf_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v); -void linear_mtxf_transpose_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v); +void linear_mtxf_mul_vec3f(Mat4 m, VEC_OUT Vec3f dst, Vec3f v); +void linear_mtxf_transpose_mul_vec3f(Mat4 m, VEC_OUT Vec3f dst, Vec3f v); void obj_apply_scale_to_transform(struct Object *obj); void obj_copy_scale(struct Object *dst, struct Object *src); void obj_scale_xyz(struct Object* obj, f32 xScale, f32 yScale, f32 zScale); @@ -143,7 +143,7 @@ u32 get_object_list_from_behavior(const BehaviorScript *behavior); struct Object *cur_obj_nearest_object_with_behavior(const BehaviorScript *behavior); f32 cur_obj_dist_to_nearest_object_with_behavior(const BehaviorScript* behavior); struct Object* cur_obj_find_nearest_pole(void); -struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript * behavior, f32 *dist); +struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript * behavior, RET f32 *dist); u16 cur_obj_count_objects_with_behavior(const BehaviorScript* behavior, f32 dist); struct Object *find_object_with_behavior(const BehaviorScript *behavior); struct Object *find_unimportant_object(void); diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index c6631b5db..e68cb7c66 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -16,11 +16,12 @@ #include "pc/lua/smlua_hooks.h" #include "pc/utils/misc.h" #include "pc/debuglog.h" -#include "game/skybox.h" -#include "game/first_person_cam.h" +#include "skybox.h" +#include "first_person_cam.h" #include "course_table.h" #include "skybox.h" #include "mario.h" +#include "hardcoded.h" /** * This file contains the code that processes the scene graph for rendering. @@ -73,11 +74,19 @@ Mtx sPrevCamTranf, sCurrCamTranf = { }; static Gfx obj_sanitize_gfx[] = { - gsSPClearGeometryMode(G_TEXTURE_GEN | G_PACKED_NORMALS_EXT), - gsSPSetGeometryMode(G_LIGHTING), + gsSPClearGeometryMode(G_CULL_BOTH | G_FOG | G_TEXTURE_GEN + | G_TEXTURE_GEN_LINEAR | G_LOD | G_PACKED_NORMALS_EXT + | G_LIGHT_MAP_EXT | G_LIGHTING_ENGINE_EXT | G_CULL_INVERT_EXT + | G_FRESNEL_COLOR_EXT | G_FRESNEL_ALPHA_EXT), + gsSPSetGeometryMode(G_SHADE | G_SHADING_SMOOTH | G_CULL_BACK | G_LIGHTING), gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), - gsSPTexture(0xFFFF, 0xFFFF, 0, 0, G_OFF), + gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF), + gsDPSetEnvColor(0xFF, 0xFF, 0xFF, 0xFF), + gsDPSetPrimColor(0, 0, 0xFF, 0xFF, 0xFF, 0xFF), + gsDPSetFogColor(0x00, 0x00, 0x00, 0x00), gsDPSetAlphaCompare(G_AC_NONE), + gsDPSetCycleType(G_CYC_1CYCLE), + gsSPNumLights(NUMLIGHTS_1), gsSPEndDisplayList(), }; @@ -633,10 +642,10 @@ static void geo_process_perspective(struct GraphNodePerspective *node) { * range of this node. */ static void geo_process_level_of_detail(struct GraphNodeLevelOfDetail *node) { - // We assume modern hardware is powerful enough to draw the most detailed variant - s16 distanceFromCam = 0; + Mtx *mtx = gMatStackFixed[gMatStackIndex]; + f32 distanceFromCam = gBehaviorValues.ProcessLODs ? (s32) -mtx->m[3][2] : 0; // z-component of the translation column - if (node->minDistance <= distanceFromCam && distanceFromCam < node->maxDistance) { + if ((f32)node->minDistance <= distanceFromCam && distanceFromCam < (f32)node->maxDistance) { if (node->node.children != 0) { geo_process_node_and_siblings(node->node.children); } @@ -1136,13 +1145,16 @@ static void geo_process_animated_part(struct GraphNodeAnimatedPart *node) { // Increment the matrix stack, If we fail to do so. Just return. if (!increment_mat_stack()) { return; } - // Mario anim part pos + // Mario anim part pos and rot if (gCurMarioBodyState && !gCurGraphNodeHeldObject && gCurMarioBodyState->currAnimPart > MARIO_ANIM_PART_NONE && gCurMarioBodyState->currAnimPart < MARIO_ANIM_PART_MAX) { get_pos_from_transform_mtx( gCurMarioBodyState->animPartsPos[gCurMarioBodyState->currAnimPart], gMatStack[gMatStackIndex], *gCurGraphNodeCamera->matrixPtr ); + + Vec3s rot = { rotation[2], rotation[0], rotation[1] }; + vec3s_copy(gCurMarioBodyState->animPartsRot[gCurMarioBodyState->currAnimPart], rot); } if (gCurGraphNodeMarioState != NULL) { @@ -1768,13 +1780,16 @@ static void geo_process_bone(struct GraphNodeBone *node) { // Increment the matrix stack, If we fail to do so. Just return. if (!increment_mat_stack()) { return; } - // Mario anim part pos + // Mario anim part pos and rot if (gCurMarioBodyState && !gCurGraphNodeHeldObject && gCurMarioBodyState->currAnimPart > MARIO_ANIM_PART_NONE && gCurMarioBodyState->currAnimPart < MARIO_ANIM_PART_MAX) { get_pos_from_transform_mtx( gCurMarioBodyState->animPartsPos[gCurMarioBodyState->currAnimPart], gMatStack[gMatStackIndex], *gCurGraphNodeCamera->matrixPtr ); + + Vec3s rot = { rotation[2], rotation[0], rotation[1] }; + vec3s_copy(gCurMarioBodyState->animPartsRot[gCurMarioBodyState->currAnimPart], rot); } if (gCurGraphNodeMarioState != NULL) { diff --git a/src/game/save_file.c b/src/game/save_file.c index c62ae378c..91d9350fb 100644 --- a/src/game/save_file.c +++ b/src/game/save_file.c @@ -791,7 +791,7 @@ void save_file_set_cap_pos(s16 x, s16 y, s16 z) { save_file_set_flags(SAVE_FLAG_CAP_ON_GROUND); } -s32 save_file_get_cap_pos(OUT Vec3s capPos) { +s32 save_file_get_cap_pos(VEC_OUT Vec3s capPos) { if (INVALID_FILE_INDEX(gCurrSaveFileNum - 1)) { return 0; } if (INVALID_SRC_SLOT(gSaveFileUsingBackupSlot)) { return 0; } struct SaveFile *saveFile = &gSaveBuffer.files[gCurrSaveFileNum - 1][gSaveFileUsingBackupSlot]; diff --git a/src/game/save_file.h b/src/game/save_file.h index 02fd80331..a5ac6a59e 100644 --- a/src/game/save_file.h +++ b/src/game/save_file.h @@ -249,7 +249,7 @@ void save_file_set_cap_pos(s16 x, s16 y, s16 z); Retrieves the current position of Mario's cap, if it is on the ground in the current level and area. The position is stored in the provided `capPos` parameter. Useful for tracking the cap's location after it has been dropped or lost |descriptionEnd| */ -s32 save_file_get_cap_pos(OUT Vec3s capPos); +s32 save_file_get_cap_pos(VEC_OUT Vec3s capPos); void save_file_set_sound_mode(u16 mode); diff --git a/src/goddard/shape_helper.c b/src/goddard/shape_helper.c index a8d014d66..bc82f72dc 100644 --- a/src/goddard/shape_helper.c +++ b/src/goddard/shape_helper.c @@ -161,7 +161,7 @@ void calc_face_normal(struct ObjFace *face) { p3.z = vtx3->pos.z; // calculate the cross product of edges (p2 - p1) and (p3 - p2) - // not sure why each component is multiplied by 1000. maybe to avoid loss of precision when normalizing? + // not sure why each component is multiplied by 1000. maybe to avoid loss of precision when normalizing? normal.x = (((p2.y - p1.y) * (p3.z - p2.z)) - ((p2.z - p1.z) * (p3.y - p2.y))) * mul; normal.y = (((p2.z - p1.z) * (p3.x - p2.x)) - ((p2.x - p1.x) * (p3.z - p2.z))) * mul; normal.z = (((p2.x - p1.x) * (p3.y - p2.y)) - ((p2.y - p1.y) * (p3.x - p2.x))) * mul; @@ -1366,6 +1366,37 @@ s32 load_mario_head(void (*aniFn)(struct ObjAnimator *)) { particle->shapePtr = gShapeRedSpark; addto_group(gGdLightGroup, &particle->header); + f32 color[3]; + void get_player_color(u8 index, u8 part, f32 *out); + + struct ObjGroup *mtls = (struct ObjGroup *) d_use_obj("N224l"); // DYNOBJ_MARIO_FACE_MTL_GROUP + for (struct ListNode *n = mtls->firstMember; n; n = n->next) { + struct ObjMaterial *m = (struct ObjMaterial *)n->obj; + + switch (m->id) { + // skin color + case 1: + get_player_color(0, 5, color); + break; + + // hair color + case 5: + get_player_color(0, 4, color); + break; + + // cap color + case 7: + get_player_color(0, 6, color); + break; + + // skip this part + default: + continue; + } + m->Ka = (struct GdColour) { color[0], color[1], color[2] }; + m->Kd = (struct GdColour) { color[0], color[1], color[2] }; + } + mainShapesGrp = (struct ObjGroup *) d_use_obj("N1000l"); // DYNOBJ_MARIO_MAIN_SHAPES_GROUP create_gddl_for_shapes(mainShapesGrp); sp38 = gGdObjectList; diff --git a/src/pc/djui/djui_chat_message.c b/src/pc/djui/djui_chat_message.c index 6c9c9e8a8..0c0d0b958 100644 --- a/src/pc/djui/djui_chat_message.c +++ b/src/pc/djui/djui_chat_message.c @@ -86,8 +86,8 @@ void djui_chat_message_create_from(u8 globalIndex, const char* message) { } const char* playerColorString = network_get_player_text_color_string(np->localIndex); - char chatMsg[MAX_CHAT_MSG_LENGTH] = { 0 }; - snprintf(chatMsg, MAX_CHAT_MSG_LENGTH, "%s%s\\#dcdcdc\\: %s", playerColorString, (np != NULL) ? np->name : "Player", message); + char chatMsg[MAX_CHAT_PACKET_LENGTH] = { 0 }; + snprintf(chatMsg, MAX_CHAT_PACKET_LENGTH, "%s%s\\#dcdcdc\\: %s", playerColorString, (np != NULL) ? np->name : "Player", message); play_sound((globalIndex == gNetworkPlayerLocal->globalIndex) ? SOUND_MENU_MESSAGE_DISAPPEAR : SOUND_MENU_MESSAGE_APPEAR, gGlobalSoundSource); djui_chat_message_create(chatMsg); diff --git a/src/pc/djui/djui_chat_message.h b/src/pc/djui/djui_chat_message.h index 137af0ddd..7bfa59c4b 100644 --- a/src/pc/djui/djui_chat_message.h +++ b/src/pc/djui/djui_chat_message.h @@ -2,6 +2,7 @@ #include "djui.h" #define MAX_CHAT_MSG_LENGTH 500 +#define MAX_CHAT_PACKET_LENGTH (MAX_CONFIG_STRING + MAX_CHAT_MSG_LENGTH + 19) struct DjuiChatMessage { struct DjuiBase base; diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c index 06aa83e33..65e1acb31 100644 --- a/src/pc/djui/djui_hud_utils.c +++ b/src/pc/djui/djui_hud_utils.c @@ -736,7 +736,7 @@ f32 djui_hud_get_fov_coeff() { bool gDjuiHudToWorldCalcViewport = true; -bool djui_hud_world_pos_to_screen_pos(Vec3f pos, OUT Vec3f out) { +bool djui_hud_world_pos_to_screen_pos(Vec3f pos, VEC_OUT Vec3f out) { if (!gCamera) { return false; } hud_rotate_and_translate_vec3f(pos, &gCamera->mtx, out); if (out[2] >= 0.0f) { diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h index a5c176741..b4e1b9d08 100644 --- a/src/pc/djui/djui_hud_utils.h +++ b/src/pc/djui/djui_hud_utils.h @@ -141,7 +141,7 @@ f32 get_current_fov(); /* |description|Gets the camera FOV coefficient|descriptionEnd| */ f32 djui_hud_get_fov_coeff(); /* |description|Converts a world position to screen position|descriptionEnd| */ -bool djui_hud_world_pos_to_screen_pos(Vec3f pos, OUT Vec3f out); +bool djui_hud_world_pos_to_screen_pos(Vec3f pos, VEC_OUT Vec3f out); /* |description|Checks if the DJUI pause menu is created|descriptionEnd| */ bool djui_hud_is_pause_menu_created(void); diff --git a/src/pc/djui/djui_interactable.c b/src/pc/djui/djui_interactable.c index cfd77db0b..311499755 100644 --- a/src/pc/djui/djui_interactable.c +++ b/src/pc/djui/djui_interactable.c @@ -312,10 +312,6 @@ void djui_interactable_on_key_up(int scancode) { djui_panel_chat_update_shift_hint(); } - bool keyFocused = (gInteractableFocus != NULL) - && (gInteractableFocus->interactable != NULL) - && (gInteractableFocus->interactable->on_key_up != NULL); - if (!gDjuiChatBoxFocus) { for (int i = 0; i < MAX_BINDS; i++) { if (scancode == (int)configKeyConsole[i]) { djui_console_toggle(); break; } @@ -337,6 +333,10 @@ void djui_interactable_on_key_up(int scancode) { } } + bool keyFocused = (gInteractableFocus != NULL) + && (gInteractableFocus->interactable != NULL) + && (gInteractableFocus->interactable->on_key_up != NULL); + if (keyFocused) { gInteractableFocus->interactable->on_key_up(gInteractableFocus, scancode); sKeyboardHoldDirection = PAD_HOLD_DIR_NONE; diff --git a/src/pc/djui/djui_panel_display.c b/src/pc/djui/djui_panel_display.c index a052af65d..f0aecfe74 100644 --- a/src/pc/djui/djui_panel_display.c +++ b/src/pc/djui/djui_panel_display.c @@ -63,7 +63,6 @@ void djui_panel_display_create(struct DjuiBase* caller) { djui_checkbox_create(body, DLANG(DISPLAY, FULLSCREEN), &configWindow.fullscreen, djui_panel_display_apply); djui_checkbox_create(body, DLANG(DISPLAY, FORCE_4BY3), &configForce4By3, djui_panel_display_apply); djui_checkbox_create(body, DLANG(DISPLAY, SHOW_FPS), &configShowFPS, NULL); - djui_checkbox_create(body, DLANG(DISPLAY, SHOW_PING), &configShowPing, NULL); djui_checkbox_create(body, DLANG(DISPLAY, VSYNC), &configWindow.vsync, djui_panel_display_apply); char* framerateModeChoices[3] = { DLANG(DISPLAY, AUTO), DLANG(DISPLAY, MANUAL), DLANG(DISPLAY, UNCAPPED) }; diff --git a/src/pc/djui/djui_panel_misc.c b/src/pc/djui/djui_panel_misc.c index 5ce0b7762..05ca794aa 100644 --- a/src/pc/djui/djui_panel_misc.c +++ b/src/pc/djui/djui_panel_misc.c @@ -59,6 +59,7 @@ void djui_panel_misc_create(struct DjuiBase* caller) { struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(MISC, MISC_TITLE), false); struct DjuiBase* body = djui_three_panel_get_body(panel); { + djui_checkbox_create(body, DLANG(DISPLAY, SHOW_PING), &configShowPing, NULL); djui_checkbox_create(body, DLANG(MISC, DISABLE_POPUPS), &configDisablePopups, NULL); #ifndef DEVELOPMENT djui_checkbox_create(body, DLANG(MISC, LUA_PROFILER), &configLuaProfiler, NULL); diff --git a/src/pc/djui/djui_panel_player.c b/src/pc/djui/djui_panel_player.c index 48a53c8a9..9656f6552 100644 --- a/src/pc/djui/djui_panel_player.c +++ b/src/pc/djui/djui_panel_player.c @@ -205,6 +205,7 @@ static void djui_panel_player_edit_palette_destroy(struct DjuiBase* caller) { } sColorRect = NULL; + gDjuiPaletteToggle = NULL; if (sPalettePresetSelection) { sPalettePresetIndex = djui_panel_player_edit_palette_get_palette_index(configPlayerPalette); @@ -372,7 +373,7 @@ static void djui_panel_player_name_active_palette(struct DjuiBase* caller) { struct DjuiButton* button2 = djui_button_right_create(&rect3->base, DLANG(PLAYER, SAVE_PRESET), DJUI_BUTTON_STYLE_NORMAL, djui_panel_player_active_palette_export); djui_base_set_size(&button2->base, 0.485f, 32); } - + { struct DjuiText *text = djui_text_create(body, DLANG(PLAYER, CAP_TOGGLE)); djui_text_set_alignment(text, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP); diff --git a/src/pc/gfx/gfx_opengl.c b/src/pc/gfx/gfx_opengl.c index 46481fbf0..c33cb8b5b 100644 --- a/src/pc/gfx/gfx_opengl.c +++ b/src/pc/gfx/gfx_opengl.c @@ -163,12 +163,12 @@ static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_ return with_alpha ? "texVal0" : "texVal0.rgb"; case SHADER_TEXEL0A: return hint_single_element ? "texVal0.a" : - (with_alpha ? "vec4(texelVal0.a, texelVal0.a, texelVal0.a, texelVal0.a)" : "vec3(texelVal0.a, texelVal0.a, texelVal0.a)"); + (with_alpha ? "vec4(texVal0.a, texVal0.a, texVal0.a, texVal0.a)" : "vec3(texVal0.a, texVal0.a, texVal0.a)"); case SHADER_TEXEL1: return with_alpha ? "texVal1" : "texVal1.rgb"; case SHADER_TEXEL1A: return hint_single_element ? "texVal1.a" : - (with_alpha ? "vec4(texelVal1.a, texelVal1.a, texelVal1.a, texelVal1.a)" : "vec3(texelVal1.a, texelVal1.a, texelVal1.a)"); + (with_alpha ? "vec4(texVal1.a, texVal1.a, texVal1.a, texVal1.a)" : "vec3(texVal1.a, texVal1.a, texVal1.a)"); case SHADER_COMBINED: return with_alpha ? "texel" : "texel.rgb"; case SHADER_COMBINEDA: diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 18ef2966a..a89bcac74 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -356,8 +356,8 @@ static void import_texture_rgba32(int tile) { static void import_texture_rgba16(int tile) { tile = tile % RDP_TILES; if (!rdp.loaded_texture[tile].addr) { return; } - if (rdp.loaded_texture[tile].size_bytes * 2 > 8192) { return; } - uint8_t rgba32_buf[8192]; + if (rdp.loaded_texture[tile].size_bytes * 2 > 0x2000) { return; } + uint8_t rgba32_buf[0x2000]; for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes / 2; i++) { uint16_t col16 = (rdp.loaded_texture[tile].addr[2 * i] << 8) | rdp.loaded_texture[tile].addr[2 * i + 1]; @@ -380,8 +380,8 @@ static void import_texture_rgba16(int tile) { static void import_texture_ia4(int tile) { tile = tile % RDP_TILES; if (!rdp.loaded_texture[tile].addr) { return; } - if (rdp.loaded_texture[tile].size_bytes * 8 > 32768) { return; } - uint8_t rgba32_buf[32768]; + if (rdp.loaded_texture[tile].size_bytes * 8 > 0x8000) { return; } + uint8_t rgba32_buf[0x8000]; for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes * 2; i++) { uint8_t byte = rdp.loaded_texture[tile].addr[i / 2]; @@ -406,8 +406,8 @@ static void import_texture_ia4(int tile) { static void import_texture_ia8(int tile) { tile = tile % RDP_TILES; if (!rdp.loaded_texture[tile].addr) { return; } - if (rdp.loaded_texture[tile].size_bytes * 4 > 16384) { return; } - uint8_t rgba32_buf[16384]; + if (rdp.loaded_texture[tile].size_bytes * 4 > 0x4000) { return; } + uint8_t rgba32_buf[0x4000]; for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes; i++) { uint8_t intensity = rdp.loaded_texture[tile].addr[i] >> 4; @@ -430,8 +430,8 @@ static void import_texture_ia8(int tile) { static void import_texture_ia16(int tile) { tile = tile % RDP_TILES; if (!rdp.loaded_texture[tile].addr) { return; } - if (rdp.loaded_texture[tile].size_bytes * 2 > 8192) { return; } - uint8_t rgba32_buf[8192]; + if (rdp.loaded_texture[tile].size_bytes * 2 > 0x2000) { return; } + uint8_t rgba32_buf[0x2000]; for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes / 2; i++) { uint8_t intensity = rdp.loaded_texture[tile].addr[2 * i]; @@ -454,8 +454,8 @@ static void import_texture_ia16(int tile) { static void import_texture_i4(int tile) { tile = tile % RDP_TILES; if (!rdp.loaded_texture[tile].addr) { return; } - if (rdp.loaded_texture[tile].size_bytes * 8 > 32768) { return; } - uint8_t rgba32_buf[32768]; + if (rdp.loaded_texture[tile].size_bytes * 8 > 0x8000) { return; } + uint8_t rgba32_buf[0x8000]; for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes * 2; i++) { uint8_t byte = rdp.loaded_texture[tile].addr[i / 2]; @@ -475,8 +475,8 @@ static void import_texture_i4(int tile) { static void import_texture_i8(int tile) { tile = tile % RDP_TILES; if (!rdp.loaded_texture[tile].addr) { return; } - if (rdp.loaded_texture[tile].size_bytes * 4 > 16384) { return; } - uint8_t rgba32_buf[16384]; + if (rdp.loaded_texture[tile].size_bytes * 4 > 0x4000) { return; } + uint8_t rgba32_buf[0x4000]; for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes; i++) { uint8_t intensity = rdp.loaded_texture[tile].addr[i]; @@ -495,8 +495,8 @@ static void import_texture_i8(int tile) { static void import_texture_ci4(int tile) { tile = tile % RDP_TILES; if (!rdp.loaded_texture[tile].addr) { return; } - if (rdp.loaded_texture[tile].size_bytes * 8 > 32768) { return; } - uint8_t rgba32_buf[32768]; + if (rdp.loaded_texture[tile].size_bytes * 8 > 0x8000) { return; } + uint8_t rgba32_buf[0x8000]; for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes * 2; i++) { uint8_t byte = rdp.loaded_texture[tile].addr[i / 2]; @@ -521,8 +521,8 @@ static void import_texture_ci4(int tile) { static void import_texture_ci8(int tile) { tile = tile % RDP_TILES; if (!rdp.loaded_texture[tile].addr) { return; } - if (rdp.loaded_texture[tile].size_bytes * 4 > 16384) { return; } - uint8_t rgba32_buf[16384]; + if (rdp.loaded_texture[tile].size_bytes * 4 > 0x4000) { return; } + uint8_t rgba32_buf[0x4000]; for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes; i++) { uint8_t idx = rdp.loaded_texture[tile].addr[i]; @@ -608,7 +608,7 @@ static void import_texture(int tile) { //printf("Time diff: %d\n", t1 - t0); } -static void OPTIMIZE_O3 gfx_transposed_matrix_mul(OUT Vec3f res, const Vec3f a, const Mat4 b) { +static void OPTIMIZE_O3 gfx_transposed_matrix_mul(VEC_OUT Vec3f res, const Vec3f a, const Mat4 b) { res[0] = a[0] * b[0][0] + a[1] * b[0][1] + a[2] * b[0][2]; res[1] = a[0] * b[1][0] + a[1] * b[1][1] + a[2] * b[1][2]; res[2] = a[0] * b[2][0] + a[1] * b[2][1] + a[2] * b[2][2]; @@ -695,7 +695,7 @@ static float gfx_adjust_x_for_aspect_ratio(float x) { return x * gfx_current_dimensions.x_adjust_ratio; } -static OPTIMIZE_O3 void gfx_local_to_world_space(OUT Vec3f pos, OUT Vec3f normal) { +static OPTIMIZE_O3 void gfx_local_to_world_space(VEC_OUT Vec3f pos, VEC_OUT Vec3f normal) { if (!sHasInverseCameraMatrix) { return; } // strip view matrix off of the model-view matrix @@ -858,8 +858,8 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons gfx_local_to_world_space(vpos, vnormal); Vec3f viewDir = { - sInverseCameraMatrix[3][0] - vpos[0], - sInverseCameraMatrix[3][1] - vpos[1], + sInverseCameraMatrix[3][0] - vpos[0], + sInverseCameraMatrix[3][1] - vpos[1], sInverseCameraMatrix[3][2] - vpos[2] }; vec3f_normalize(viewDir); @@ -1284,6 +1284,7 @@ static void gfx_calc_and_set_viewport(const Vp_t *viewport) { } static void gfx_sp_movemem(uint8_t index, uint16_t offset, const void* data) { + if (!data) { return; } switch (index) { case G_MV_VIEWPORT: gfx_calc_and_set_viewport((const Vp_t *) data); @@ -2069,12 +2070,12 @@ static const struct { uint8_t LOAD_BLOCK; uint8_t SHIFT; uint8_t INCR; - uint8_t LINE_BYTES; + uint8_t LINE_NIBBLES; } G_IM_SIZ_[] = { - [G_IM_SIZ_4b] = { G_IM_SIZ_4b_LOAD_BLOCK, G_IM_SIZ_4b_SHIFT, G_IM_SIZ_4b_INCR, G_IM_SIZ_4b_LINE_BYTES }, - [G_IM_SIZ_8b] = { G_IM_SIZ_8b_LOAD_BLOCK, G_IM_SIZ_8b_SHIFT, G_IM_SIZ_8b_INCR, G_IM_SIZ_8b_LINE_BYTES }, - [G_IM_SIZ_16b] = { G_IM_SIZ_16b_LOAD_BLOCK, G_IM_SIZ_16b_SHIFT, G_IM_SIZ_16b_INCR, G_IM_SIZ_16b_LINE_BYTES }, - [G_IM_SIZ_32b] = { G_IM_SIZ_32b_LOAD_BLOCK, G_IM_SIZ_32b_SHIFT, G_IM_SIZ_32b_INCR, G_IM_SIZ_32b_LINE_BYTES }, + [G_IM_SIZ_4b] = { G_IM_SIZ_4b_LOAD_BLOCK, G_IM_SIZ_4b_SHIFT, G_IM_SIZ_4b_INCR, 1 }, + [G_IM_SIZ_8b] = { G_IM_SIZ_8b_LOAD_BLOCK, G_IM_SIZ_8b_SHIFT, G_IM_SIZ_8b_INCR, 2 * G_IM_SIZ_8b_LINE_BYTES }, + [G_IM_SIZ_16b] = { G_IM_SIZ_16b_LOAD_BLOCK, G_IM_SIZ_16b_SHIFT, G_IM_SIZ_16b_INCR, 2 * G_IM_SIZ_16b_LINE_BYTES }, + [G_IM_SIZ_32b] = { G_IM_SIZ_32b_LOAD_BLOCK, G_IM_SIZ_32b_SHIFT, G_IM_SIZ_32b_INCR, 2 * G_IM_SIZ_32b_LINE_BYTES }, }; static bool sDjuiClip = 0; @@ -2162,7 +2163,7 @@ static void OPTIMIZE_O3 djui_gfx_dp_execute_override(void) { gfx_dp_set_texture_image(fmt, G_IM_SIZ_[siz].LOAD_BLOCK, width, texture); gfx_dp_set_tile(fmt, siz, 0, 0, G_TX_LOADTILE, 0, 0, 0, 0, 0, 0, 0); gfx_dp_load_block(0, 0, 0, ((width * height + G_IM_SIZ_[siz].INCR) >> G_IM_SIZ_[siz].SHIFT) - 1, 0); - gfx_dp_set_tile(fmt, siz, (((width * G_IM_SIZ_[siz].LINE_BYTES) + 7) >> 3), 0, G_TX_RENDERTILE, 0, 0, 0, 0, 0, 0, 0); + gfx_dp_set_tile(fmt, siz, (((width * G_IM_SIZ_[siz].LINE_NIBBLES) + 15) >> 4), 0, G_TX_RENDERTILE, 0, rdp.texture_tile.cmt, 0, 0, rdp.texture_tile.cms, 0, 0); } static void OPTIMIZE_O3 djui_gfx_dp_execute_djui(uint32_t opcode) { diff --git a/src/pc/lua/smlua_autogen.h b/src/pc/lua/smlua_autogen.h index 5267c76e6..5373e3972 100644 --- a/src/pc/lua/smlua_autogen.h +++ b/src/pc/lua/smlua_autogen.h @@ -6,8 +6,16 @@ // // A macro to tell autogen which function parameters are modified during the function call and should be pushed again -// Only works with Vec3, Mat4 and Color types -#define OUT +// Only suitable for `Vec2`, `Vec3`, `Vec4`, `Mat4` and `Color` types +#define VEC_OUT + +// A macro to tell autogen which function parameters are return values +// Such parameters must be pointers, they don't appear in the Lua definition of the function +#define RET + +// A macro to tell autogen which function parameters are both input and output values +// Such parameters must be pointers, they appear as regular types as function parameters +#define INOUT // A macro to tell autogen this parameter can be omitted and replaced by 'nil' during a function call // Optional parameters must be contiguous until the last parameter (a mandatory parameter following an optional parameter is not allowed) diff --git a/src/pc/lua/smlua_cobject.c b/src/pc/lua/smlua_cobject.c index 4f7da423a..104c02074 100644 --- a/src/pc/lua/smlua_cobject.c +++ b/src/pc/lua/smlua_cobject.c @@ -70,38 +70,38 @@ bool smlua_valid_lvt(u16 lvt) { static const char *sLuaLvtNames[] = { [LVT_BOOL] = "bool", - [LVT_BOOL_P] = "bool Pointer", + [LVT_BOOL_P] = "bool pointer", [LVT_U8] = "u8", - [LVT_U8_P] = "u8 Pointer", + [LVT_U8_P] = "u8 pointer", [LVT_U16] = "u16", - [LVT_U16_P] = "u16 Pointer", + [LVT_U16_P] = "u16 pointer", [LVT_U32] = "u32", - [LVT_U32_P] = "u32 Pointer", + [LVT_U32_P] = "u32 pointer", [LVT_S8] = "s8", - [LVT_S8_P] = "s8 Pointer", + [LVT_S8_P] = "s8 pointer", [LVT_S16] = "s16", - [LVT_S16_P] = "s16 Pointer", + [LVT_S16_P] = "s16 pointer", [LVT_S32] = "s32", - [LVT_S32_P] = "s32 Pointer", + [LVT_S32_P] = "s32 pointer", [LVT_F32] = "f32", - [LVT_F32_P] = "f32 Pointer", + [LVT_F32_P] = "f32 pointer", [LVT_U64] = "u64", - [LVT_U64_P] = "u64 Pointer", + [LVT_U64_P] = "u64 pointer", [LVT_COBJECT] = "CObject", - [LVT_COBJECT_P] = "CObject Pointer", + [LVT_COBJECT_P] = "CObject pointer", [LVT_STRING] = "string", - [LVT_STRING_P] = "string Pointer", - [LVT_BEHAVIORSCRIPT_P] = "BehaviorScript Pointer", - [LVT_OBJECTANIMPOINTER_P] = "ObjectAnimPointer Pointer", - [LVT_COLLISION_P] = "Collision Pointer", - [LVT_LEVELSCRIPT_P] = "LevelScript Pointer", - [LVT_TRAJECTORY_P] = "Trajectory Pointer", - [LVT_TEXTURE_P] = "Texture Pointer", + [LVT_STRING_P] = "string pointer", + [LVT_BEHAVIORSCRIPT_P] = "BehaviorScript pointer", + [LVT_OBJECTANIMPOINTER_P] = "ObjectAnimPointer pointer", + [LVT_COLLISION_P] = "Collision pointer", + [LVT_LEVELSCRIPT_P] = "LevelScript pointer", + [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", + [LVT_POINTER] = "pointer", + [LVT_FUNCTION] = "function", + [LVT_MAX] = "unknown", }; const char *smlua_get_lvt_name(u16 lvt) { diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index f2a37ee00..e2cbf87ea 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -340,7 +340,7 @@ static struct LuaObjectField sBehaviorTrajectoriesFields[LUA_BEHAVIOR_TRAJECTORI { "UnagiTrajectory", LVT_TRAJECTORY_P, offsetof(struct BehaviorTrajectories, UnagiTrajectory), false, LOT_POINTER, 1, sizeof(Trajectory*) }, }; -#define LUA_BEHAVIOR_VALUES_FIELD_COUNT 32 +#define LUA_BEHAVIOR_VALUES_FIELD_COUNT 33 static struct LuaObjectField sBehaviorValuesFields[LUA_BEHAVIOR_VALUES_FIELD_COUNT] = { { "BowlingBallBob2Speed", LVT_F32, offsetof(struct BehaviorValues, BowlingBallBob2Speed), false, LOT_NONE, 1, sizeof(f32) }, { "BowlingBallBobSpeed", LVT_F32, offsetof(struct BehaviorValues, BowlingBallBobSpeed), false, LOT_NONE, 1, sizeof(f32) }, @@ -361,6 +361,7 @@ static struct LuaObjectField sBehaviorValuesFields[LUA_BEHAVIOR_VALUES_FIELD_COU { "MipsStar1Requirement", LVT_S16, offsetof(struct BehaviorValues, MipsStar1Requirement), false, LOT_NONE, 1, sizeof(s16) }, { "MipsStar2Requirement", LVT_S16, offsetof(struct BehaviorValues, MipsStar2Requirement), false, LOT_NONE, 1, sizeof(s16) }, { "MultipleCapCollection", LVT_U8, offsetof(struct BehaviorValues, MultipleCapCollection), false, LOT_NONE, 1, sizeof(u8) }, + { "ProcessLODs", LVT_U8, offsetof(struct BehaviorValues, ProcessLODs), false, LOT_NONE, 1, sizeof(u8) }, { "RacingPenguinBigHeight", LVT_F32, offsetof(struct BehaviorValues, RacingPenguinBigHeight), false, LOT_NONE, 1, sizeof(f32) }, { "RacingPenguinBigRadius", LVT_F32, offsetof(struct BehaviorValues, RacingPenguinBigRadius), false, LOT_NONE, 1, sizeof(f32) }, { "RacingPenguinHeight", LVT_F32, offsetof(struct BehaviorValues, RacingPenguinHeight), false, LOT_NONE, 1, sizeof(f32) }, @@ -1353,11 +1354,12 @@ static struct LuaObjectField sMarioAnimationFields[LUA_MARIO_ANIMATION_FIELD_COU { "targetAnim", LVT_COBJECT_P, offsetof(struct MarioAnimation, targetAnim), false, LOT_ANIMATION, 1, sizeof(struct Animation*) }, }; -#define LUA_MARIO_BODY_STATE_FIELD_COUNT 28 +#define LUA_MARIO_BODY_STATE_FIELD_COUNT 29 static struct LuaObjectField sMarioBodyStateFields[LUA_MARIO_BODY_STATE_FIELD_COUNT] = { { "action", LVT_U32, offsetof(struct MarioBodyState, action), false, LOT_NONE, 1, sizeof(u32) }, { "allowPartRotation", LVT_U8, offsetof(struct MarioBodyState, allowPartRotation), false, LOT_NONE, 1, sizeof(u8) }, { "animPartsPos", LVT_COBJECT, offsetof(struct MarioBodyState, animPartsPos), true, LOT_VEC3F, MARIO_ANIM_PART_MAX, sizeof(Vec3f) }, + { "animPartsRot", LVT_COBJECT, offsetof(struct MarioBodyState, animPartsRot), true, LOT_VEC3S, MARIO_ANIM_PART_MAX, sizeof(Vec3s) }, { "capState", LVT_S8, offsetof(struct MarioBodyState, capState), false, LOT_NONE, 1, sizeof(s8) }, { "currAnimPart", LVT_U32, offsetof(struct MarioBodyState, currAnimPart), true, LOT_NONE, 1, sizeof(u32) }, { "eyeState", LVT_S8, offsetof(struct MarioBodyState, eyeState), false, LOT_NONE, 1, sizeof(s8) }, @@ -1498,83 +1500,52 @@ static struct LuaObjectField sModAudioFields[LUA_MOD_AUDIO_FIELD_COUNT] = { { "loaded", LVT_BOOL, offsetof(struct ModAudio, loaded), true, LOT_NONE, 1, sizeof(bool) }, }; -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] = { - { "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) }, + { "clear", LVT_FUNCTION, (size_t) "mod_fs_clear", true, LOT_NONE, 1, sizeof(const char *) }, + { "copy_file", LVT_FUNCTION, (size_t) "mod_fs_copy_file", true, LOT_NONE, 1, sizeof(const char *) }, + { "create_file", LVT_FUNCTION, (size_t) "mod_fs_create_file", true, LOT_NONE, 1, sizeof(const char *) }, + { "delete", LVT_FUNCTION, (size_t) "mod_fs_delete", true, LOT_NONE, 1, sizeof(const char *) }, + { "delete_file", LVT_FUNCTION, (size_t) "mod_fs_delete_file", true, LOT_NONE, 1, sizeof(const char *) }, + { "get_file", LVT_FUNCTION, (size_t) "mod_fs_get_file", true, LOT_NONE, 1, sizeof(const char *) }, + { "get_filename", LVT_FUNCTION, (size_t) "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) "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) "mod_fs_save", true, LOT_NONE, 1, sizeof(const char *) }, + { "set_public", LVT_FUNCTION, (size_t) "mod_fs_set_public", true, LOT_NONE, 1, sizeof(const char *) }, + { "totalSize", LVT_U32, offsetof(struct ModFs, totalSize), true, LOT_NONE, 1, sizeof(u32) }, }; -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] = { - { "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 *) }, + { "erase", LVT_FUNCTION, (size_t) "mod_fs_file_erase", true, LOT_NONE, 1, sizeof(const char *) }, + { "filepath", LVT_STRING, offsetof(struct ModFsFile, filepath), true, LOT_NONE, 1, sizeof(char) }, + { "fill", LVT_FUNCTION, (size_t) "mod_fs_file_fill", true, LOT_NONE, 1, sizeof(const char *) }, + { "isPublic", LVT_BOOL, offsetof(struct ModFsFile, isPublic), true, LOT_NONE, 1, sizeof(bool) }, + { "isText", LVT_BOOL, offsetof(struct ModFsFile, isText), true, LOT_NONE, 1, sizeof(bool) }, + { "is_eof", LVT_FUNCTION, (size_t) "mod_fs_file_is_eof", true, LOT_NONE, 1, sizeof(const char *) }, + { "modFs", LVT_COBJECT_P, offsetof(struct ModFsFile, modFs), true, LOT_MODFS, 1, sizeof(struct ModFs*) }, + { "offset", LVT_U32, offsetof(struct ModFsFile, offset), true, LOT_NONE, 1, sizeof(u32) }, + { "read_bool", LVT_FUNCTION, (size_t) "mod_fs_file_read_bool", true, LOT_NONE, 1, sizeof(const char *) }, + { "read_bytes", LVT_FUNCTION, (size_t) "mod_fs_file_read_bytes", true, LOT_NONE, 1, sizeof(const char *) }, + { "read_integer", LVT_FUNCTION, (size_t) "mod_fs_file_read_integer", true, LOT_NONE, 1, sizeof(const char *) }, + { "read_line", LVT_FUNCTION, (size_t) "mod_fs_file_read_line", true, LOT_NONE, 1, sizeof(const char *) }, + { "read_number", LVT_FUNCTION, (size_t) "mod_fs_file_read_number", true, LOT_NONE, 1, sizeof(const char *) }, + { "read_string", LVT_FUNCTION, (size_t) "mod_fs_file_read_string", true, LOT_NONE, 1, sizeof(const char *) }, + { "rewind", LVT_FUNCTION, (size_t) "mod_fs_file_rewind", true, LOT_NONE, 1, sizeof(const char *) }, + { "seek", LVT_FUNCTION, (size_t) "mod_fs_file_seek", true, LOT_NONE, 1, sizeof(const char *) }, + { "set_public", LVT_FUNCTION, (size_t) "mod_fs_file_set_public", true, LOT_NONE, 1, sizeof(const char *) }, + { "set_text_mode", LVT_FUNCTION, (size_t) "mod_fs_file_set_text_mode", true, LOT_NONE, 1, sizeof(const char *) }, + { "size", LVT_U32, offsetof(struct ModFsFile, size), true, LOT_NONE, 1, sizeof(u32) }, + { "write_bool", LVT_FUNCTION, (size_t) "mod_fs_file_write_bool", true, LOT_NONE, 1, sizeof(const char *) }, + { "write_bytes", LVT_FUNCTION, (size_t) "mod_fs_file_write_bytes", true, LOT_NONE, 1, sizeof(const char *) }, + { "write_integer", LVT_FUNCTION, (size_t) "mod_fs_file_write_integer", true, LOT_NONE, 1, sizeof(const char *) }, + { "write_line", LVT_FUNCTION, (size_t) "mod_fs_file_write_line", true, LOT_NONE, 1, sizeof(const char *) }, + { "write_number", LVT_FUNCTION, (size_t) "mod_fs_file_write_number", true, LOT_NONE, 1, sizeof(const char *) }, + { "write_string", LVT_FUNCTION, (size_t) "mod_fs_file_write_string", true, LOT_NONE, 1, sizeof(const char *) }, }; #define LUA_NAMETAGS_SETTINGS_FIELD_COUNT 2 diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index f94175f1c..a55aae378 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -425,6 +425,10 @@ char gSmluaConstants[] = "" "FONT_TINY = -1\n" "--- @type integer\n" "ANIM_FLAG_FORWARD = (1 << 1)\n" +"-----------------------\n" +"-- Renamed functions --\n" +"-----------------------\n" +"rom_hack_cam_set_collisions = camera_romhack_set_collisions\n" "--------------------\n" "-- Math functions --\n" "--------------------\n" @@ -1790,7 +1794,7 @@ char gSmluaConstants[] = "" "HUD_DISPLAY_FLAG_EMPHASIZE_POWER=0x8000\n" "HUD_DISPLAY_NONE=0x0000\n" "HUD_DISPLAY_DEFAULT=HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER | HUD_DISPLAY_FLAG_CAMERA | HUD_DISPLAY_FLAG_POWER | HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020\n" -"LE_MAX_LIGHTS=256\n" +"LE_MAX_LIGHTS=512\n" "LE_MODE_AFFECT_ALL_SHADED_AND_COLORED=0\n" "LE_MODE_AFFECT_ALL_SHADED=1\n" "LE_MODE_AFFECT_ONLY_GEOMETRY_MODE=2\n" @@ -4065,7 +4069,7 @@ char gSmluaConstants[] = "" "SOUND_PEACH_BAKE_A_CAKE=SOUND_ARG_LOAD(SOUND_BANK_MARIO_VOICE, 0x3D, 0xFF, SOUND_NO_PRIORITY_LOSS | SOUND_DISCRETE)\n" "SOUND_PEACH_FOR_MARIO=SOUND_ARG_LOAD(SOUND_BANK_MARIO_VOICE, 0x3E, 0xFF, SOUND_NO_PRIORITY_LOSS | SOUND_DISCRETE)\n" "SOUND_PEACH_MARIO2=SOUND_ARG_LOAD(SOUND_BANK_MARIO_VOICE, 0x3F, 0xFF, SOUND_NO_PRIORITY_LOSS | SOUND_DISCRETE)\n" -"SOUND_MARIO_LETS_A_GO=SOUND_MENU_STAR_SOUND_LETS_A_GO\n" +"SOUND_MARIO_LETS_A_GO=SOUND_ARG_LOAD(SOUND_BANK_MENU, 0x24, 0xFF, SOUND_DISCRETE)\n" "SOUND_GENERAL_ACTIVATE_CAP_SWITCH=SOUND_ARG_LOAD(SOUND_BANK_GENERAL, 0x00, 0x80, SOUND_DISCRETE)\n" "SOUND_GENERAL_FLAME_OUT=SOUND_ARG_LOAD(SOUND_BANK_GENERAL, 0x03, 0x80, SOUND_DISCRETE)\n" "SOUND_GENERAL_OPEN_WOOD_DOOR=SOUND_ARG_LOAD(SOUND_BANK_GENERAL, 0x04, 0xC0, SOUND_DISCRETE)\n" @@ -4621,10 +4625,10 @@ char gSmluaConstants[] = "" "COOP_OBJ_FLAG_LUA=(1 << 1)\n" "COOP_OBJ_FLAG_NON_SYNC=(1 << 2)\n" "COOP_OBJ_FLAG_INITIALIZED=(1 << 3)\n" -"SM64COOPDX_VERSION='v1.4'\n" +"SM64COOPDX_VERSION='v1.4.1'\n" "VERSION_TEXT='v'\n" "VERSION_NUMBER=41\n" -"MINOR_VERSION_NUMBER=0\n" +"MINOR_VERSION_NUMBER=1\n" "GAME_NAME='sm64coopdx'\n" "WINDOW_NAME='Super Mario 64 Coop Deluxe'\n" "MAX_VERSION_LENGTH=128\n" diff --git a/src/pc/lua/smlua_functions.c b/src/pc/lua/smlua_functions.c index dadf70c51..155fcb1a0 100644 --- a/src/pc/lua/smlua_functions.c +++ b/src/pc/lua/smlua_functions.c @@ -168,24 +168,6 @@ int smlua_func_init_mario_after_warp(lua_State* L) { return 1; } -int smlua_func_initiate_warp(lua_State* L) { - if(!smlua_functions_valid_param_count(L, 4)) { return 0; } - - s16 destLevel = smlua_to_number(L, 1); - if (!gSmLuaConvertSuccess) { LOG_LUA("initiate_warp: Failed to convert parameter 1"); return 0; } - s16 destArea = smlua_to_number(L, 2); - if (!gSmLuaConvertSuccess) { LOG_LUA("initiate_warp: Failed to convert parameter 2"); return 0; } - s16 destWarpNode = smlua_to_number(L, 3); - if (!gSmLuaConvertSuccess) { LOG_LUA("initiate_warp: Failed to convert parameter 3"); return 0; } - s32 arg3 = smlua_to_number(L, 4); - if (!gSmLuaConvertSuccess) { LOG_LUA("initiate_warp: Failed to convert parameter 4"); return 0; } - - extern void initiate_warp(s16 destLevel, s16 destArea, s16 destWarpNode, s32 arg3); - initiate_warp(destLevel, destArea, destWarpNode, arg3); - - return 1; -} - int smlua_func_reset_level(lua_State* L) { if (network_player_connected_count() >= 2) { LOG_LUA_LINE("reset_level() can only be used in singleplayer"); @@ -1007,36 +989,6 @@ int smlua_func_gfx_set_command(lua_State* L) { return 1; } -int smlua_func_gfx_get_from_name(lua_State *L) { - if (!smlua_functions_valid_param_count(L, 1)) { return 0; } - - const char *name = smlua_to_string(L, 1); - if (!gSmLuaConvertSuccess) { LOG_LUA("gfx_get_from_name: Failed to convert parameter 1"); return 0; } - - u32 length = 0; - Gfx *gfx = dynos_gfx_get(name, &length); - - smlua_push_object(L, LOT_GFX, gfx, NULL); - lua_pushinteger(L, length); - - return 2; -} - -int smlua_func_vtx_get_from_name(lua_State *L) { - if (!smlua_functions_valid_param_count(L, 1)) { return 0; } - - const char *name = smlua_to_string(L, 1); - if (!gSmLuaConvertSuccess) { LOG_LUA("vtx_get_from_name: Failed to convert parameter 1"); return 0; } - - u32 count = 0; - Vtx *vtx = dynos_vtx_get(name, &count); - - smlua_push_object(L, LOT_VTX, vtx, NULL); - lua_pushinteger(L, count); - - return 2; -} - ////////// // bind // ////////// @@ -1048,7 +1000,6 @@ void smlua_bind_functions(void) { smlua_bind_function(L, "table_copy", smlua_func_table_copy); smlua_bind_function(L, "table_deepcopy", smlua_func_table_deepcopy); smlua_bind_function(L, "init_mario_after_warp", smlua_func_init_mario_after_warp); - smlua_bind_function(L, "initiate_warp", smlua_func_initiate_warp); smlua_bind_function(L, "network_init_object", smlua_func_network_init_object); smlua_bind_function(L, "network_send_object", smlua_func_network_send_object); smlua_bind_function(L, "reset_level", smlua_func_reset_level); @@ -1069,6 +1020,4 @@ void smlua_bind_functions(void) { smlua_bind_function(L, "cast_graph_node", smlua_func_cast_graph_node); smlua_bind_function(L, "get_uncolored_string", smlua_func_get_uncolored_string); smlua_bind_function(L, "gfx_set_command", smlua_func_gfx_set_command); - smlua_bind_function(L, "gfx_get_from_name", smlua_func_gfx_get_from_name); - smlua_bind_function(L, "vtx_get_from_name", smlua_func_vtx_get_from_name); } diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 8c88e94d6..60ced0477 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -778,12 +778,15 @@ int smlua_func_update_angle_from_move_flags(lua_State* L) { return 0; } - s32 * angle = (s32 *)smlua_to_cpointer(L, 1, LVT_S32_P); + s32 angle = smlua_to_integer(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "update_angle_from_move_flags"); return 0; } - lua_pushinteger(L, update_angle_from_move_flags(angle)); - return 1; + lua_pushinteger(L, update_angle_from_move_flags(&angle)); + + lua_pushinteger(L, angle); + + return 2; } int smlua_func_cur_obj_spawn_strong_wind_particles(lua_State* L) { @@ -10720,16 +10723,19 @@ int smlua_func_set_or_approach_f32_asymptotic(lua_State* L) { return 0; } - f32 * dst = (f32 *)smlua_to_cpointer(L, 1, LVT_F32_P); + f32 dst = smlua_to_number(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "set_or_approach_f32_asymptotic"); return 0; } f32 goal = smlua_to_number(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "set_or_approach_f32_asymptotic"); return 0; } f32 scale = smlua_to_number(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "set_or_approach_f32_asymptotic"); return 0; } - lua_pushinteger(L, set_or_approach_f32_asymptotic(dst, goal, scale)); - return 1; + lua_pushinteger(L, set_or_approach_f32_asymptotic(&dst, goal, scale)); + + lua_pushnumber(L, dst); + + return 2; } int smlua_func_approach_f32_asymptotic_bool(lua_State* L) { @@ -10741,16 +10747,19 @@ int smlua_func_approach_f32_asymptotic_bool(lua_State* L) { return 0; } - f32 * current = (f32 *)smlua_to_cpointer(L, 1, LVT_F32_P); + f32 current = smlua_to_number(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "approach_f32_asymptotic_bool"); return 0; } f32 target = smlua_to_number(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "approach_f32_asymptotic_bool"); return 0; } f32 multiplier = smlua_to_number(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "approach_f32_asymptotic_bool"); return 0; } - lua_pushinteger(L, approach_f32_asymptotic_bool(current, target, multiplier)); - return 1; + lua_pushinteger(L, approach_f32_asymptotic_bool(¤t, target, multiplier)); + + lua_pushnumber(L, current); + + return 2; } int smlua_func_approach_f32_asymptotic(lua_State* L) { @@ -10783,16 +10792,19 @@ int smlua_func_approach_s16_asymptotic_bool(lua_State* L) { return 0; } - s16 * current = (s16 *)smlua_to_cpointer(L, 1, LVT_S16_P); + s16 current = smlua_to_integer(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "approach_s16_asymptotic_bool"); return 0; } s16 target = smlua_to_integer(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "approach_s16_asymptotic_bool"); return 0; } s16 divisor = smlua_to_integer(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "approach_s16_asymptotic_bool"); return 0; } - lua_pushinteger(L, approach_s16_asymptotic_bool(current, target, divisor)); - return 1; + lua_pushinteger(L, approach_s16_asymptotic_bool(¤t, target, divisor)); + + lua_pushinteger(L, current); + + return 2; } int smlua_func_approach_s16_asymptotic(lua_State* L) { @@ -10887,16 +10899,19 @@ int smlua_func_camera_approach_s16_symmetric_bool(lua_State* L) { return 0; } - s16 * current = (s16 *)smlua_to_cpointer(L, 1, LVT_S16_P); + s16 current = smlua_to_integer(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "camera_approach_s16_symmetric_bool"); return 0; } s16 target = smlua_to_integer(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "camera_approach_s16_symmetric_bool"); return 0; } s16 increment = smlua_to_integer(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "camera_approach_s16_symmetric_bool"); return 0; } - lua_pushinteger(L, camera_approach_s16_symmetric_bool(current, target, increment)); - return 1; + lua_pushinteger(L, camera_approach_s16_symmetric_bool(¤t, target, increment)); + + lua_pushinteger(L, current); + + return 2; } int smlua_func_set_or_approach_s16_symmetric(lua_State* L) { @@ -10908,16 +10923,19 @@ int smlua_func_set_or_approach_s16_symmetric(lua_State* L) { return 0; } - s16 * current = (s16 *)smlua_to_cpointer(L, 1, LVT_S16_P); + s16 current = smlua_to_integer(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "set_or_approach_s16_symmetric"); return 0; } s16 target = smlua_to_integer(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "set_or_approach_s16_symmetric"); return 0; } s16 increment = smlua_to_integer(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "set_or_approach_s16_symmetric"); return 0; } - lua_pushinteger(L, set_or_approach_s16_symmetric(current, target, increment)); - return 1; + lua_pushinteger(L, set_or_approach_s16_symmetric(¤t, target, increment)); + + lua_pushinteger(L, current); + + return 2; } int smlua_func_camera_approach_f32_symmetric_bool(lua_State* L) { @@ -10929,16 +10947,19 @@ int smlua_func_camera_approach_f32_symmetric_bool(lua_State* L) { return 0; } - f32 * current = (f32 *)smlua_to_cpointer(L, 1, LVT_F32_P); + f32 current = smlua_to_number(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "camera_approach_f32_symmetric_bool"); return 0; } f32 target = smlua_to_number(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "camera_approach_f32_symmetric_bool"); return 0; } f32 increment = smlua_to_number(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "camera_approach_f32_symmetric_bool"); return 0; } - lua_pushinteger(L, camera_approach_f32_symmetric_bool(current, target, increment)); - return 1; + lua_pushinteger(L, camera_approach_f32_symmetric_bool(¤t, target, increment)); + + lua_pushnumber(L, current); + + return 2; } int smlua_func_camera_approach_f32_symmetric(lua_State* L) { @@ -11132,8 +11153,8 @@ int smlua_func_calculate_angles(lua_State* L) { if (L == NULL) { return 0; } int top = lua_gettop(L); - if (top != 4) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "calculate_angles", 4, top); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "calculate_angles", 2, top); return 0; } @@ -11145,14 +11166,16 @@ int smlua_func_calculate_angles(lua_State* L) { Vec3f to; smlua_get_vec3f(to, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "calculate_angles"); return 0; } - s16 * pitch = (s16 *)smlua_to_cpointer(L, 3, LVT_S16_P); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "calculate_angles"); return 0; } - s16 * yaw = (s16 *)smlua_to_cpointer(L, 4, LVT_S16_P); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "calculate_angles"); return 0; } - calculate_angles(from, to, pitch, yaw); + s16 pitch; + s16 yaw; - return 1; + calculate_angles(from, to, &pitch, &yaw); + + lua_pushinteger(L, pitch); + lua_pushinteger(L, yaw); + + return 2; } int smlua_func_calc_abs_dist(lua_State* L) { @@ -11406,10 +11429,13 @@ int smlua_func_shake_camera_roll(lua_State* L) { return 0; } - s16 * roll = (s16 *)smlua_to_cpointer(L, 1, LVT_S16_P); + s16 roll = smlua_to_integer(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "shake_camera_roll"); return 0; } - shake_camera_roll(roll); + + shake_camera_roll(&roll); + + lua_pushinteger(L, roll); return 1; } @@ -11851,14 +11877,17 @@ int smlua_func_rotate_camera_around_walls(lua_State* L) { Vec3f cPos; smlua_get_vec3f(cPos, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "rotate_camera_around_walls"); return 0; } - s16 * avoidYaw = (s16 *)smlua_to_cpointer(L, 3, LVT_S16_P); + s16 avoidYaw = smlua_to_integer(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "rotate_camera_around_walls"); return 0; } s16 yawRange = smlua_to_integer(L, 4); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "rotate_camera_around_walls"); return 0; } - lua_pushinteger(L, rotate_camera_around_walls(c, cPos, avoidYaw, yawRange)); - return 1; + lua_pushinteger(L, rotate_camera_around_walls(c, cPos, &avoidYaw, yawRange)); + + lua_pushinteger(L, avoidYaw); + + return 2; } /* @@ -15587,6 +15616,29 @@ int smlua_func_warp_special(lua_State* L) { return 1; } +int smlua_func_initiate_warp(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 4) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "initiate_warp", 4, top); + return 0; + } + + s16 destLevel = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "initiate_warp"); return 0; } + s16 destArea = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "initiate_warp"); return 0; } + s16 destWarpNode = smlua_to_integer(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "initiate_warp"); return 0; } + s32 arg = smlua_to_integer(L, 4); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "initiate_warp"); return 0; } + + initiate_warp(destLevel, destArea, destWarpNode, arg); + + return 1; +} + int smlua_func_lvl_set_current_level(lua_State* L) { if (L == NULL) { return 0; } @@ -16661,13 +16713,12 @@ int smlua_func_resolve_and_return_wall_collisions_data(lua_State* L) { return 1; } -/* int smlua_func_vec3f_find_ceil(lua_State* L) { if (L == NULL) { return 0; } int top = lua_gettop(L); - if (top != 3) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vec3f_find_ceil", 3, top); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vec3f_find_ceil", 2, top); return 0; } @@ -16677,22 +16728,22 @@ int smlua_func_vec3f_find_ceil(lua_State* L) { if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vec3f_find_ceil"); return 0; } f32 height = smlua_to_number(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "vec3f_find_ceil"); return 0; } -// struct Surface** ceil = (struct Surface**)smlua_to_cobject(L, 3, LOT_???); <--- UNIMPLEMENTED - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "vec3f_find_ceil"); return 0; } - lua_pushnumber(L, vec3f_find_ceil(pos, height, ceil)); + struct Surface* ceil; - return 1; + lua_pushnumber(L, vec3f_find_ceil(pos, height, &ceil)); + + smlua_push_object(L, LOT_SURFACE, ceil, NULL); + + return 2; } -*/ -/* int smlua_func_vec3f_mario_ceil(lua_State* L) { if (L == NULL) { return 0; } int top = lua_gettop(L); - if (top != 3) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vec3f_mario_ceil", 3, top); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vec3f_mario_ceil", 2, top); return 0; } @@ -16702,14 +16753,15 @@ int smlua_func_vec3f_mario_ceil(lua_State* L) { if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vec3f_mario_ceil"); return 0; } f32 height = smlua_to_number(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "vec3f_mario_ceil"); return 0; } -// struct Surface** ceil = (struct Surface**)smlua_to_cobject(L, 3, LOT_???); <--- UNIMPLEMENTED - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "vec3f_mario_ceil"); return 0; } - lua_pushnumber(L, vec3f_mario_ceil(pos, height, ceil)); + struct Surface* ceil; - return 1; + lua_pushnumber(L, vec3f_mario_ceil(pos, height, &ceil)); + + smlua_push_object(L, LOT_SURFACE, ceil, NULL); + + return 2; } -*/ int smlua_func_mario_facing_downhill(lua_State* L) { if (L == NULL) { return 0; } @@ -17623,7 +17675,7 @@ int smlua_func_perform_hanging_step(lua_State* L) { smlua_get_vec3f(nextPos, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "perform_hanging_step"); return 0; } - extern s32 perform_hanging_step(struct MarioState *m, OUT Vec3f nextPos); + extern s32 perform_hanging_step(struct MarioState *m, VEC_OUT Vec3f nextPos); lua_pushinteger(L, perform_hanging_step(m, nextPos)); smlua_push_vec3f(nextPos, 2); @@ -19121,7 +19173,7 @@ int smlua_func_perform_water_full_step(lua_State* L) { smlua_get_vec3f(nextPos, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "perform_water_full_step"); return 0; } - extern u32 perform_water_full_step(struct MarioState *m, OUT Vec3f nextPos); + extern u32 perform_water_full_step(struct MarioState *m, VEC_OUT Vec3f nextPos); lua_pushinteger(L, perform_water_full_step(m, nextPos)); smlua_push_vec3f(nextPos, 2); @@ -19145,7 +19197,7 @@ int smlua_func_apply_water_current(lua_State* L) { smlua_get_vec3f(step, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "apply_water_current"); return 0; } - extern void apply_water_current(struct MarioState *m, OUT Vec3f step); + extern void apply_water_current(struct MarioState *m, VEC_OUT Vec3f step); apply_water_current(m, step); smlua_push_vec3f(step, 2); @@ -19852,8 +19904,8 @@ int smlua_func_vec3f_get_dist_and_angle(lua_State* L) { if (L == NULL) { return 0; } int top = lua_gettop(L); - if (top != 5) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vec3f_get_dist_and_angle", 5, top); + if (top != 2) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vec3f_get_dist_and_angle", 2, top); return 0; } @@ -19865,16 +19917,18 @@ int smlua_func_vec3f_get_dist_and_angle(lua_State* L) { Vec3f to; smlua_get_vec3f(to, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "vec3f_get_dist_and_angle"); return 0; } - f32 * dist = (f32 *)smlua_to_cpointer(L, 3, LVT_F32_P); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "vec3f_get_dist_and_angle"); return 0; } - s16 * pitch = (s16 *)smlua_to_cpointer(L, 4, LVT_S16_P); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "vec3f_get_dist_and_angle"); return 0; } - s16 * yaw = (s16 *)smlua_to_cpointer(L, 5, LVT_S16_P); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 5, "vec3f_get_dist_and_angle"); return 0; } - vec3f_get_dist_and_angle(from, to, dist, pitch, yaw); + f32 dist; + s16 pitch; + s16 yaw; - return 1; + vec3f_get_dist_and_angle(from, to, &dist, &pitch, &yaw); + + lua_pushnumber(L, dist); + lua_pushinteger(L, pitch); + lua_pushinteger(L, yaw); + + return 3; } int smlua_func_vec3f_set_dist_and_angle(lua_State* L) { @@ -23790,18 +23844,20 @@ int smlua_func_calc_obj_friction(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", "calc_obj_friction", 2, top); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "calc_obj_friction", 1, top); return 0; } - f32 * objFriction = (f32 *)smlua_to_cpointer(L, 1, LVT_F32_P); + f32 floor_nY = smlua_to_number(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "calc_obj_friction"); return 0; } - f32 floor_nY = smlua_to_number(L, 2); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "calc_obj_friction"); return 0; } - extern void calc_obj_friction(f32 *objFriction, f32 floor_nY); - calc_obj_friction(objFriction, floor_nY); + f32 objFriction; + + extern void calc_obj_friction(RET f32 *objFriction, f32 floor_nY); + calc_obj_friction(&objFriction, floor_nY); + + lua_pushnumber(L, objFriction); return 1; } @@ -24314,7 +24370,7 @@ int smlua_func_obj_find_wall_displacement(lua_State* L) { f32 radius = smlua_to_number(L, 5); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 5, "obj_find_wall_displacement"); return 0; } - extern s8 obj_find_wall_displacement(OUT Vec3f dist, f32 x, f32 y, f32 z, f32 radius); + extern s8 obj_find_wall_displacement(VEC_OUT Vec3f dist, f32 x, f32 y, f32 z, f32 radius); lua_pushinteger(L, obj_find_wall_displacement(dist, x, y, z, radius)); smlua_push_vec3f(dist, 1); @@ -24743,17 +24799,20 @@ int smlua_func_approach_f32_ptr(lua_State* L) { return 0; } - f32 * px = (f32 *)smlua_to_cpointer(L, 1, LVT_F32_P); + f32 px = smlua_to_number(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "approach_f32_ptr"); return 0; } f32 target = smlua_to_number(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "approach_f32_ptr"); return 0; } f32 delta = smlua_to_number(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "approach_f32_ptr"); return 0; } - extern s32 approach_f32_ptr(f32 *px, f32 target, f32 delta); - lua_pushinteger(L, approach_f32_ptr(px, target, delta)); - return 1; + extern s32 approach_f32_ptr(INOUT f32 *px, f32 target, f32 delta); + lua_pushinteger(L, approach_f32_ptr(&px, target, delta)); + + lua_pushnumber(L, px); + + return 2; } int smlua_func_obj_forward_vel_approach(lua_State* L) { @@ -24885,9 +24944,9 @@ int smlua_func_obj_smooth_turn(lua_State* L) { return 0; } - s16 * angleVel = (s16 *)smlua_to_cpointer(L, 1, LVT_S16_P); + s16 angleVel = smlua_to_integer(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_smooth_turn"); return 0; } - s32 * angle = (s32 *)smlua_to_cpointer(L, 2, LVT_S32_P); + s32 angle = smlua_to_integer(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_smooth_turn"); return 0; } s16 targetAngle = smlua_to_integer(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "obj_smooth_turn"); return 0; } @@ -24900,10 +24959,14 @@ int smlua_func_obj_smooth_turn(lua_State* L) { s16 maxSpeed = smlua_to_integer(L, 7); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 7, "obj_smooth_turn"); return 0; } - extern s32 obj_smooth_turn(s16 *angleVel, s32 *angle, s16 targetAngle, f32 targetSpeedProportion, s16 accel, s16 minSpeed, s16 maxSpeed); - lua_pushinteger(L, obj_smooth_turn(angleVel, angle, targetAngle, targetSpeedProportion, accel, minSpeed, maxSpeed)); - return 1; + extern s32 obj_smooth_turn(INOUT s16 *angleVel, INOUT s32 *angle, s16 targetAngle, f32 targetSpeedProportion, s16 accel, s16 minSpeed, s16 maxSpeed); + lua_pushinteger(L, obj_smooth_turn(&angleVel, &angle, targetAngle, targetSpeedProportion, accel, minSpeed, maxSpeed)); + + lua_pushinteger(L, angleVel); + lua_pushinteger(L, angle); + + return 3; } int smlua_func_obj_roll_to_match_yaw_turn(lua_State* L) { @@ -24997,17 +25060,20 @@ int smlua_func_obj_grow_then_shrink(lua_State* L) { return 0; } - f32 * scaleVel = (f32 *)smlua_to_cpointer(L, 1, LVT_F32_P); + f32 scaleVel = smlua_to_number(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_grow_then_shrink"); return 0; } f32 shootFireScale = smlua_to_number(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_grow_then_shrink"); return 0; } f32 endScale = smlua_to_number(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "obj_grow_then_shrink"); return 0; } - extern s32 obj_grow_then_shrink(f32 *scaleVel, f32 shootFireScale, f32 endScale); - lua_pushinteger(L, obj_grow_then_shrink(scaleVel, shootFireScale, endScale)); - return 1; + extern s32 obj_grow_then_shrink(INOUT f32 *scaleVel, f32 shootFireScale, f32 endScale); + lua_pushinteger(L, obj_grow_then_shrink(&scaleVel, shootFireScale, endScale)); + + lua_pushnumber(L, scaleVel); + + return 2; } int smlua_func_oscillate_toward(lua_State* L) { @@ -25019,9 +25085,9 @@ int smlua_func_oscillate_toward(lua_State* L) { return 0; } - s32 * value = (s32 *)smlua_to_cpointer(L, 1, LVT_S32_P); + s32 value = smlua_to_integer(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "oscillate_toward"); return 0; } - f32 * vel = (f32 *)smlua_to_cpointer(L, 2, LVT_F32_P); + f32 vel = smlua_to_number(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "oscillate_toward"); return 0; } s32 target = smlua_to_integer(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "oscillate_toward"); return 0; } @@ -25032,10 +25098,14 @@ int smlua_func_oscillate_toward(lua_State* L) { f32 slowdown = smlua_to_number(L, 6); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 6, "oscillate_toward"); return 0; } - extern s32 oscillate_toward(s32 *value, f32 *vel, s32 target, f32 velCloseToZero, f32 accel, f32 slowdown); - lua_pushinteger(L, oscillate_toward(value, vel, target, velCloseToZero, accel, slowdown)); - return 1; + extern s32 oscillate_toward(INOUT s32 *value, INOUT f32 *vel, s32 target, f32 velCloseToZero, f32 accel, f32 slowdown); + lua_pushinteger(L, oscillate_toward(&value, &vel, target, velCloseToZero, accel, slowdown)); + + lua_pushinteger(L, value); + lua_pushnumber(L, vel); + + return 3; } int smlua_func_obj_update_blinking(lua_State* L) { @@ -25047,7 +25117,7 @@ int smlua_func_obj_update_blinking(lua_State* L) { return 0; } - s32 * blinkTimer = (s32 *)smlua_to_cpointer(L, 1, LVT_S32_P); + s32 blinkTimer = smlua_to_integer(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_update_blinking"); return 0; } s16 baseCycleLength = smlua_to_integer(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_update_blinking"); return 0; } @@ -25056,8 +25126,11 @@ int smlua_func_obj_update_blinking(lua_State* L) { s16 blinkLength = smlua_to_integer(L, 4); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "obj_update_blinking"); return 0; } - extern void obj_update_blinking(s32 *blinkTimer, s16 baseCycleLength, s16 cycleLengthRange, s16 blinkLength); - obj_update_blinking(blinkTimer, baseCycleLength, cycleLengthRange, blinkLength); + + extern void obj_update_blinking(INOUT s32 *blinkTimer, s16 baseCycleLength, s16 cycleLengthRange, s16 blinkLength); + obj_update_blinking(&blinkTimer, baseCycleLength, cycleLengthRange, blinkLength); + + lua_pushinteger(L, blinkTimer); return 1; } @@ -25066,36 +25139,40 @@ int smlua_func_obj_resolve_object_collisions(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", "obj_resolve_object_collisions", 1, top); + if (top != 0) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_resolve_object_collisions", 0, top); return 0; } - s32 * targetYaw = (s32 *)smlua_to_cpointer(L, 1, LVT_S32_P); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_resolve_object_collisions"); return 0; } - extern s32 obj_resolve_object_collisions(s32 *targetYaw); - lua_pushinteger(L, obj_resolve_object_collisions(targetYaw)); + s32 targetYaw; - return 1; + extern s32 obj_resolve_object_collisions(RET s32 *targetYaw); + lua_pushinteger(L, obj_resolve_object_collisions(&targetYaw)); + + lua_pushinteger(L, targetYaw); + + return 2; } int smlua_func_obj_bounce_off_walls_edges_objects(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", "obj_bounce_off_walls_edges_objects", 1, top); + if (top != 0) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_bounce_off_walls_edges_objects", 0, top); return 0; } - s32 * targetYaw = (s32 *)smlua_to_cpointer(L, 1, LVT_S32_P); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "obj_bounce_off_walls_edges_objects"); return 0; } - extern s32 obj_bounce_off_walls_edges_objects(s32 *targetYaw); - lua_pushinteger(L, obj_bounce_off_walls_edges_objects(targetYaw)); + s32 targetYaw; - return 1; + extern s32 obj_bounce_off_walls_edges_objects(RET s32 *targetYaw); + lua_pushinteger(L, obj_bounce_off_walls_edges_objects(&targetYaw)); + + lua_pushinteger(L, targetYaw); + + return 2; } int smlua_func_obj_resolve_collisions_and_turn(lua_State* L) { @@ -25318,22 +25395,24 @@ int smlua_func_treat_far_home_as_mario(lua_State* L) { if (L == NULL) { return 0; } int top = lua_gettop(L); - if (top != 3) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "treat_far_home_as_mario", 3, top); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "treat_far_home_as_mario", 1, top); return 0; } f32 threshold = smlua_to_number(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "treat_far_home_as_mario"); return 0; } - s32* distanceToPlayer = (s32*)smlua_to_cpointer(L, 2, LVT_S32_P); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "treat_far_home_as_mario"); return 0; } - s32* angleToPlayer = (s32*)smlua_to_cpointer(L, 3, LVT_S32_P); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "treat_far_home_as_mario"); return 0; } - extern void treat_far_home_as_mario(f32 threshold, s32* distanceToPlayer, s32* angleToPlayer); - treat_far_home_as_mario(threshold, distanceToPlayer, angleToPlayer); + s32 distanceToPlayer; + s32 angleToPlayer; - return 1; + extern void treat_far_home_as_mario(f32 threshold, RET s32* distanceToPlayer, RET s32* angleToPlayer); + treat_far_home_as_mario(threshold, &distanceToPlayer, &angleToPlayer); + + lua_pushinteger(L, distanceToPlayer); + lua_pushinteger(L, angleToPlayer); + + return 2; } int smlua_func_obj_spit_fire(lua_State* L) { @@ -25381,15 +25460,18 @@ int smlua_func_clear_move_flag(lua_State* L) { return 0; } - u32 * bitSet = (u32 *)smlua_to_cpointer(L, 1, LVT_U32_P); + u32 bitSet = smlua_to_integer(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "clear_move_flag"); return 0; } s32 flag = smlua_to_integer(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "clear_move_flag"); return 0; } - extern s32 clear_move_flag(u32 *bitSet, s32 flag); - lua_pushinteger(L, clear_move_flag(bitSet, flag)); - return 1; + extern s32 clear_move_flag(INOUT u32 *bitSet, s32 flag); + lua_pushinteger(L, clear_move_flag(&bitSet, flag)); + + lua_pushinteger(L, bitSet); + + return 2; } /* @@ -25572,7 +25654,7 @@ int smlua_func_obj_apply_scale_to_matrix(lua_State* L) { smlua_get_mat4(src, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "obj_apply_scale_to_matrix"); return 0; } - extern void obj_apply_scale_to_matrix(struct Object *obj, OUT Mat4 dst, Mat4 src); + extern void obj_apply_scale_to_matrix(struct Object *obj, VEC_OUT Mat4 dst, Mat4 src); obj_apply_scale_to_matrix(obj, dst, src); smlua_push_mat4(dst, 2); @@ -25602,7 +25684,7 @@ int smlua_func_create_transformation_from_matrices(lua_State* L) { smlua_get_mat4(a2, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "create_transformation_from_matrices"); return 0; } - extern void create_transformation_from_matrices(OUT Mat4 a0, Mat4 a1, Mat4 a2); + extern void create_transformation_from_matrices(VEC_OUT Mat4 a0, Mat4 a1, Mat4 a2); create_transformation_from_matrices(a0, a1, a2); smlua_push_mat4(a0, 1); @@ -25723,17 +25805,20 @@ int smlua_func_approach_f32_signed(lua_State* L) { return 0; } - f32 * value = (f32 *)smlua_to_cpointer(L, 1, LVT_F32_P); + f32 value = smlua_to_number(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "approach_f32_signed"); return 0; } f32 target = smlua_to_number(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "approach_f32_signed"); return 0; } f32 increment = smlua_to_number(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "approach_f32_signed"); return 0; } - extern s32 approach_f32_signed(f32 *value, f32 target, f32 increment); - lua_pushinteger(L, approach_f32_signed(value, target, increment)); - return 1; + extern s32 approach_f32_signed(INOUT f32 *value, f32 target, f32 increment); + lua_pushinteger(L, approach_f32_signed(&value, target, increment)); + + lua_pushnumber(L, value); + + return 2; } int smlua_func_approach_f32_symmetric(lua_State* L) { @@ -26272,7 +26357,7 @@ int smlua_func_linear_mtxf_mul_vec3f(lua_State* L) { smlua_get_vec3f(v, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "linear_mtxf_mul_vec3f"); return 0; } - extern void linear_mtxf_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v); + extern void linear_mtxf_mul_vec3f(Mat4 m, VEC_OUT Vec3f dst, Vec3f v); linear_mtxf_mul_vec3f(m, dst, v); smlua_push_vec3f(dst, 2); @@ -26302,7 +26387,7 @@ int smlua_func_linear_mtxf_transpose_mul_vec3f(lua_State* L) { smlua_get_vec3f(v, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "linear_mtxf_transpose_mul_vec3f"); return 0; } - extern void linear_mtxf_transpose_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v); + extern void linear_mtxf_transpose_mul_vec3f(Mat4 m, VEC_OUT Vec3f dst, Vec3f v); linear_mtxf_transpose_mul_vec3f(m, dst, v); smlua_push_vec3f(dst, 2); @@ -26782,20 +26867,22 @@ int smlua_func_cur_obj_find_nearest_object_with_behavior(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", "cur_obj_find_nearest_object_with_behavior", 2, top); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "cur_obj_find_nearest_object_with_behavior", 1, top); return 0; } BehaviorScript * behavior = (BehaviorScript *)smlua_to_cpointer(L, 1, LVT_BEHAVIORSCRIPT_P); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "cur_obj_find_nearest_object_with_behavior"); return 0; } - f32 * dist = (f32 *)smlua_to_cpointer(L, 2, LVT_F32_P); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "cur_obj_find_nearest_object_with_behavior"); return 0; } - extern struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, f32 *dist); - smlua_push_object(L, LOT_OBJECT, cur_obj_find_nearest_object_with_behavior(behavior, dist), NULL); + f32 dist; - return 1; + extern struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, RET f32 *dist); + smlua_push_object(L, LOT_OBJECT, cur_obj_find_nearest_object_with_behavior(behavior, &dist), NULL); + + lua_pushnumber(L, dist); + + return 2; } int smlua_func_cur_obj_count_objects_with_behavior(lua_State* L) { @@ -27377,13 +27464,16 @@ int smlua_func_apply_drag_to_value(lua_State* L) { return 0; } - f32 * value = (f32 *)smlua_to_cpointer(L, 1, LVT_F32_P); + f32 value = smlua_to_number(L, 1); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "apply_drag_to_value"); return 0; } f32 dragStrength = smlua_to_number(L, 2); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "apply_drag_to_value"); return 0; } - extern void apply_drag_to_value(f32 *value, f32 dragStrength); - apply_drag_to_value(value, dragStrength); + + extern void apply_drag_to_value(INOUT f32 *value, f32 dragStrength); + apply_drag_to_value(&value, dragStrength); + + lua_pushnumber(L, value); return 1; } @@ -31154,19 +31244,19 @@ int smlua_func_camera_romhack_allow_dpad_usage(lua_State* L) { return 1; } -int smlua_func_rom_hack_cam_set_collisions(lua_State* L) { +int smlua_func_camera_romhack_set_collisions(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", "rom_hack_cam_set_collisions", 1, top); + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "camera_romhack_set_collisions", 1, top); return 0; } u8 enable = smlua_to_integer(L, 1); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "rom_hack_cam_set_collisions"); return 0; } + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "camera_romhack_set_collisions"); return 0; } - rom_hack_cam_set_collisions(enable); + camera_romhack_set_collisions(enable); return 1; } @@ -32603,6 +32693,27 @@ int smlua_func_gfx_get_texture(lua_State* L) { return 1; } +int smlua_func_gfx_get_from_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_from_name", 1, top); + return 0; + } + + const char* name = smlua_to_string(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_from_name"); return 0; } + + u32 length; + + smlua_push_object(L, LOT_GFX, gfx_get_from_name(name, &length), NULL); + + lua_pushinteger(L, length); + + return 2; +} + int smlua_func_gfx_get_name(lua_State* L) { if (L == NULL) { return 0; } @@ -32764,6 +32875,27 @@ int smlua_func_gfx_delete_all(UNUSED lua_State* L) { return 1; } +int smlua_func_vtx_get_from_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_from_name", 1, top); + return 0; + } + + const char* name = smlua_to_string(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vtx_get_from_name"); return 0; } + + u32 count; + + smlua_push_object(L, LOT_VTX, vtx_get_from_name(name, &count), NULL); + + lua_pushinteger(L, count); + + return 2; +} + int smlua_func_vtx_get_name(lua_State* L) { if (L == NULL) { return 0; } @@ -33995,6 +34127,31 @@ int smlua_func_get_mario_anim_part_pos(lua_State* L) { return 1; } +int smlua_func_get_mario_anim_part_rot(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_mario_anim_part_rot", 3, top); + return 0; + } + + struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_mario_anim_part_rot"); return 0; } + u32 animPart = smlua_to_integer(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "get_mario_anim_part_rot"); return 0; } + + Vec3s rot; + smlua_get_vec3s(rot, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "get_mario_anim_part_rot"); return 0; } + + lua_pushboolean(L, get_mario_anim_part_rot(m, animPart, rot)); + + smlua_push_vec3s(rot, 3); + + return 1; +} + int smlua_func_get_current_save_file_num(UNUSED lua_State* L) { if (L == NULL) { return 0; } @@ -36449,13 +36606,12 @@ int smlua_func_find_wall_collisions(lua_State* L) { return 1; } -/* int smlua_func_find_ceil(lua_State* L) { if (L == NULL) { return 0; } int top = lua_gettop(L); - if (top != 4) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "find_ceil", 4, top); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "find_ceil", 3, top); return 0; } @@ -36465,14 +36621,15 @@ int smlua_func_find_ceil(lua_State* L) { if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "find_ceil"); return 0; } f32 posZ = smlua_to_number(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "find_ceil"); return 0; } -// struct Surface** pceil = (struct Surface**)smlua_to_cobject(L, 4, LOT_???); <--- UNIMPLEMENTED - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "find_ceil"); return 0; } - lua_pushnumber(L, find_ceil(posX, posY, posZ, pceil)); + struct Surface* pceil; - return 1; + lua_pushnumber(L, find_ceil(posX, posY, posZ, &pceil)); + + smlua_push_object(L, LOT_SURFACE, pceil, NULL); + + return 2; } -*/ int smlua_func_find_ceil_height(lua_State* L) { if (L == NULL) { return 0; } @@ -36541,13 +36698,12 @@ int smlua_func_find_floor_height(lua_State* L) { return 1; } -/* int smlua_func_find_floor(lua_State* L) { if (L == NULL) { return 0; } int top = lua_gettop(L); - if (top != 4) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "find_floor", 4, top); + if (top != 3) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "find_floor", 3, top); return 0; } @@ -36557,14 +36713,15 @@ int smlua_func_find_floor(lua_State* L) { if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "find_floor"); return 0; } f32 zPos = smlua_to_number(L, 3); if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 3, "find_floor"); return 0; } -// struct Surface** pfloor = (struct Surface**)smlua_to_cobject(L, 4, LOT_???); <--- UNIMPLEMENTED - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 4, "find_floor"); return 0; } - lua_pushnumber(L, find_floor(xPos, yPos, zPos, pfloor)); + struct Surface* pfloor; - return 1; + lua_pushnumber(L, find_floor(xPos, yPos, zPos, &pfloor)); + + smlua_push_object(L, LOT_SURFACE, pfloor, NULL); + + return 2; } -*/ int smlua_func_find_water_level(lua_State* L) { if (L == NULL) { return 0; } @@ -37768,6 +37925,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "initiate_painting_warp", smlua_func_initiate_painting_warp); smlua_bind_function(L, "level_trigger_warp", smlua_func_level_trigger_warp); smlua_bind_function(L, "warp_special", smlua_func_warp_special); + smlua_bind_function(L, "initiate_warp", smlua_func_initiate_warp); smlua_bind_function(L, "lvl_set_current_level", smlua_func_lvl_set_current_level); // lighting_engine.h @@ -37826,8 +37984,8 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "mario_get_terrain_sound_addend", smlua_func_mario_get_terrain_sound_addend); smlua_bind_function(L, "resolve_and_return_wall_collisions", smlua_func_resolve_and_return_wall_collisions); smlua_bind_function(L, "resolve_and_return_wall_collisions_data", smlua_func_resolve_and_return_wall_collisions_data); - //smlua_bind_function(L, "vec3f_find_ceil", smlua_func_vec3f_find_ceil); <--- UNIMPLEMENTED - //smlua_bind_function(L, "vec3f_mario_ceil", smlua_func_vec3f_mario_ceil); <--- UNIMPLEMENTED + smlua_bind_function(L, "vec3f_find_ceil", smlua_func_vec3f_find_ceil); + smlua_bind_function(L, "vec3f_mario_ceil", smlua_func_vec3f_mario_ceil); smlua_bind_function(L, "mario_facing_downhill", smlua_func_mario_facing_downhill); smlua_bind_function(L, "mario_floor_is_slippery", smlua_func_mario_floor_is_slippery); smlua_bind_function(L, "mario_floor_is_slope", smlua_func_mario_floor_is_slope); @@ -38606,7 +38764,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "camera_romhack_allow_centering", smlua_func_camera_romhack_allow_centering); smlua_bind_function(L, "camera_allow_toxic_gas_camera", smlua_func_camera_allow_toxic_gas_camera); smlua_bind_function(L, "camera_romhack_allow_dpad_usage", smlua_func_camera_romhack_allow_dpad_usage); - smlua_bind_function(L, "rom_hack_cam_set_collisions", smlua_func_rom_hack_cam_set_collisions); + smlua_bind_function(L, "camera_romhack_set_collisions", smlua_func_camera_romhack_set_collisions); smlua_bind_function(L, "camera_romhack_set_zoomed_in_dist", smlua_func_camera_romhack_set_zoomed_in_dist); smlua_bind_function(L, "camera_romhack_set_zoomed_out_dist", smlua_func_camera_romhack_set_zoomed_out_dist); smlua_bind_function(L, "camera_romhack_set_zoomed_in_height", smlua_func_camera_romhack_set_zoomed_in_height); @@ -38697,6 +38855,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_from_name", smlua_func_gfx_get_from_name); 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); @@ -38706,6 +38865,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_from_name", smlua_func_vtx_get_from_name); 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); @@ -38781,6 +38941,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "get_hand_foot_pos_y", smlua_func_get_hand_foot_pos_y); smlua_bind_function(L, "get_hand_foot_pos_z", smlua_func_get_hand_foot_pos_z); smlua_bind_function(L, "get_mario_anim_part_pos", smlua_func_get_mario_anim_part_pos); + smlua_bind_function(L, "get_mario_anim_part_rot", smlua_func_get_mario_anim_part_rot); smlua_bind_function(L, "get_current_save_file_num", smlua_func_get_current_save_file_num); smlua_bind_function(L, "save_file_get_using_backup_slot", smlua_func_save_file_get_using_backup_slot); smlua_bind_function(L, "save_file_set_using_backup_slot", smlua_func_save_file_set_using_backup_slot); @@ -38931,11 +39092,11 @@ void smlua_bind_functions_autogen(void) { // surface_collision.h smlua_bind_function(L, "find_wall_collisions", smlua_func_find_wall_collisions); - //smlua_bind_function(L, "find_ceil", smlua_func_find_ceil); <--- UNIMPLEMENTED + smlua_bind_function(L, "find_ceil", smlua_func_find_ceil); smlua_bind_function(L, "find_ceil_height", smlua_func_find_ceil_height); //smlua_bind_function(L, "find_floor_height_and_data", smlua_func_find_floor_height_and_data); <--- UNIMPLEMENTED smlua_bind_function(L, "find_floor_height", smlua_func_find_floor_height); - //smlua_bind_function(L, "find_floor", smlua_func_find_floor); <--- UNIMPLEMENTED + smlua_bind_function(L, "find_floor", smlua_func_find_floor); smlua_bind_function(L, "find_water_level", smlua_func_find_water_level); smlua_bind_function(L, "find_poison_gas_level", smlua_func_find_poison_gas_level); //smlua_bind_function(L, "find_surface_on_ray", smlua_func_find_surface_on_ray); <--- UNIMPLEMENTED diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index 6ec341c05..d487aa2ac 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -324,7 +324,7 @@ int smlua_hook_mario_action(lua_State* L) { return 1; } -bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* m, s32* returnValue) { +bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* m, s32* cancel) { lua_State* L = gLuaState; if (L == NULL) { return false; } @@ -343,18 +343,39 @@ bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* // call the callback if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod, hook->modFile)) { - LOG_LUA("Failed to call the action callback: %u", m->action); + LOG_LUA("Failed to call the action callback: '%08X'", m->action); continue; } // output the return value - *returnValue = false; - if (lua_type(L, -1) == LUA_TBOOLEAN || lua_type(L, -1) == LUA_TNUMBER) { - *returnValue = smlua_to_integer(L, -1); + // special return values: + // - returning -1 allows to continue the execution, useful when overriding vanilla actions + bool stopActionHook = true; + *cancel = FALSE; + + switch (lua_type(L, -1)) { + case LUA_TBOOLEAN: { + *cancel = smlua_to_boolean(L, -1) ? TRUE : FALSE; + } break; + + case LUA_TNUMBER: { + s32 returnValue = (s32) smlua_to_integer(L, -1); + if (returnValue > 0) { + *cancel = TRUE; + } else if (returnValue == 0) { + *cancel = FALSE; + } else if (returnValue == ACTION_HOOK_CONTINUE_EXECUTION) { + stopActionHook = false; + } else { + LOG_LUA("Invalid return value when calling the action callback: '%08X' returned %d", m->action, returnValue); + } + } break; } lua_pop(L, 1); - return true; + if (stopActionHook) { + return true; + } } } diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index 12a8af6dc..edfcc975f 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -95,6 +95,8 @@ static const char* LuaActionHookTypeArgName[] = { "max (dummy)", }; +#define ACTION_HOOK_CONTINUE_EXECUTION -1 + #define MAX_HOOKED_MOD_MENU_ELEMENTS 256 enum LuaModMenuElementType { @@ -143,7 +145,7 @@ const char* smlua_get_name_from_hooked_behavior_id(enum BehaviorId id); bool smlua_call_behavior_hook(const BehaviorScript** behavior, struct Object* object, bool before); int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod, struct ModFile* activeModFile); -bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* m, s32* returnValue); +bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* m, s32* cancel); u32 smlua_get_action_interaction_type(struct MarioState* m); bool smlua_call_chat_command_hook(char* command); diff --git a/src/pc/lua/smlua_require.c b/src/pc/lua/smlua_require.c index 5852ac54a..c331a0570 100644 --- a/src/pc/lua/smlua_require.c +++ b/src/pc/lua/smlua_require.c @@ -68,6 +68,7 @@ void smlua_cache_module_result(lua_State* L, struct Mod* mod, struct ModFile* fi static struct ModFile* smlua_find_mod_file(const char* moduleName) { char basePath[SYS_MAX_PATH] = ""; char absolutePath[SYS_MAX_PATH] = ""; + char normalizedRelative[SYS_MAX_PATH] = ""; if (!gLuaActiveMod) { return NULL; @@ -100,8 +101,10 @@ static struct ModFile* smlua_find_mod_file(const char* moduleName) { continue; } - // check for match - if (!strcmp(file->relativePath, luaName) || !strcmp(file->relativePath, luacName)) { + // check for match, normalizing to system separators + strcpy(normalizedRelative, file->relativePath); + normalize_path(normalizedRelative); + if (!strcmp(normalizedRelative, luaName) || !strcmp(normalizedRelative, luacName)) { return file; } } diff --git a/src/pc/lua/smlua_utils.c b/src/pc/lua/smlua_utils.c index c6bd63a20..a680fe2b0 100644 --- a/src/pc/lua/smlua_utils.c +++ b/src/pc/lua/smlua_utils.c @@ -221,7 +221,7 @@ void* smlua_to_cpointer(lua_State* L, int index, u16 lvt) { CPointer *cpointer = luaL_checkudata(L, index, "CPointer"); if (lvt != cpointer->lvt) { - LOG_LUA_LINE("smlua_to_cpointer received improper LOT. Expected '%s', received '%s'", smlua_get_lvt_name(lvt), smlua_get_lvt_name(cpointer->lvt)); + LOG_LUA_LINE("smlua_to_cpointer received improper LVT. Expected '%s', received '%s'", smlua_get_lvt_name(lvt), smlua_get_lvt_name(cpointer->lvt)); gSmLuaConvertSuccess = false; return NULL; } diff --git a/src/pc/lua/utils/smlua_camera_utils.c b/src/pc/lua/utils/smlua_camera_utils.c index 2a2b6c94f..00f49c521 100644 --- a/src/pc/lua/utils/smlua_camera_utils.c +++ b/src/pc/lua/utils/smlua_camera_utils.c @@ -69,7 +69,7 @@ void camera_romhack_allow_dpad_usage(u8 allow) { gRomhackCameraSettings.dpad = allow; } -void rom_hack_cam_set_collisions(u8 enable) { +void camera_romhack_set_collisions(u8 enable) { gRomhackCameraSettings.collisions = enable; } diff --git a/src/pc/lua/utils/smlua_camera_utils.h b/src/pc/lua/utils/smlua_camera_utils.h index b9090568b..717f850a5 100644 --- a/src/pc/lua/utils/smlua_camera_utils.h +++ b/src/pc/lua/utils/smlua_camera_utils.h @@ -27,7 +27,7 @@ void camera_romhack_allow_dpad_usage(u8 allow); Toggles collision settings for the ROM hack camera. This enables or disables specific collision behaviors in modded levels |descriptionEnd| */ -void rom_hack_cam_set_collisions(u8 enable); +void camera_romhack_set_collisions(u8 enable); /* |description|Sets the romhack camera's zoomed in distance (Default: 900)|descriptionEnd| */ void camera_romhack_set_zoomed_in_dist(u32 val); diff --git a/src/pc/lua/utils/smlua_deprecated.c b/src/pc/lua/utils/smlua_deprecated.c index fdd998e18..5c9178f55 100644 --- a/src/pc/lua/utils/smlua_deprecated.c +++ b/src/pc/lua/utils/smlua_deprecated.c @@ -34,7 +34,7 @@ void network_player_color_to_palette(struct NetworkPlayer *np, enum PlayerPart p np->overridePalette = np->palette; } -void network_player_palette_to_color(struct NetworkPlayer *np, enum PlayerPart part, OUT Color out) { +void network_player_palette_to_color(struct NetworkPlayer *np, enum PlayerPart part, VEC_OUT Color out) { LOG_LUA_LINE_WARNING("[LUA] network_player_palette_to_color() is deprecated! Use network_player_get_palette_color() or network_player_get_override_palette_color() instead."); if (np == NULL || !(part < PLAYER_PART_MAX && part >= 0)) { if (np == NULL) { // output config palette instead if np is NULL diff --git a/src/pc/lua/utils/smlua_deprecated.h b/src/pc/lua/utils/smlua_deprecated.h index 82314f7d6..a4c305be5 100644 --- a/src/pc/lua/utils/smlua_deprecated.h +++ b/src/pc/lua/utils/smlua_deprecated.h @@ -13,4 +13,4 @@ void audio_stream_set_speed(struct ModAudio* audio, f32 initial_freq, f32 speed, /* |description|[DEPRECATED: Use `network_player_set_override_palette_color` instead]|descriptionEnd| */ void network_player_color_to_palette(struct NetworkPlayer *np, enum PlayerPart part, Color color); /* |description|[DEPRECATED: Use `network_player_get_palette_color` or `network_player_get_override_palette_color` instead]|descriptionEnd| */ -void network_player_palette_to_color(struct NetworkPlayer *np, enum PlayerPart part, OUT Color out); +void network_player_palette_to_color(struct NetworkPlayer *np, enum PlayerPart part, VEC_OUT Color out); diff --git a/src/pc/lua/utils/smlua_gfx_utils.c b/src/pc/lua/utils/smlua_gfx_utils.c index 821b42696..78a3679b1 100644 --- a/src/pc/lua/utils/smlua_gfx_utils.c +++ b/src/pc/lua/utils/smlua_gfx_utils.c @@ -247,6 +247,11 @@ Texture *gfx_get_texture(Gfx *cmd) { return (Texture *) cmd->words.w1; } +Gfx *gfx_get_from_name(const char *name, RET u32 *length) { + *length = 0; + return dynos_gfx_get(name, length); +} + const char *gfx_get_name(Gfx *gfx) { if (!gfx) { return NULL; } @@ -355,6 +360,11 @@ void gfx_delete_all() { dynos_gfx_delete_all(); } +Vtx *vtx_get_from_name(const char *name, RET u32 *count) { + *count = 0; + return dynos_vtx_get(name, count); +} + const char *vtx_get_name(Vtx *vtx) { if (!vtx) { return NULL; } diff --git a/src/pc/lua/utils/smlua_gfx_utils.h b/src/pc/lua/utils/smlua_gfx_utils.h index 4175188b3..d49ebed34 100644 --- a/src/pc/lua/utils/smlua_gfx_utils.h +++ b/src/pc/lua/utils/smlua_gfx_utils.h @@ -69,6 +69,11 @@ u16 gfx_get_vertex_count(Gfx *cmd); /* |description|Gets the texture from a display list command if it has an image related op|descriptionEnd| */ Texture *gfx_get_texture(Gfx *cmd); +/* |description| +Gets a display list of the current mod from its name. +Returns a pointer to the display list and its length +|descriptionEnd| */ +Gfx *gfx_get_from_name(const char *name, RET u32 *length); /* |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| */ @@ -88,6 +93,12 @@ void gfx_delete(Gfx *gfx); /* |description|Deletes all display lists created by `gfx_create`|descriptionEnd| */ void gfx_delete_all(); + +/* |description| +Gets a vertex buffer of the current mod from its name. +Returns a pointer to the vertex buffering and its vertex count +|descriptionEnd| */ +Vtx *vtx_get_from_name(const char *name, RET u32 *count); /* |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| */ diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c index 37ab42d83..bff36cbbf 100644 --- a/src/pc/lua/utils/smlua_misc_utils.c +++ b/src/pc/lua/utils/smlua_misc_utils.c @@ -130,7 +130,6 @@ bool djui_is_playerlist_ping_visible(void) { /// -extern s8 gDialogBoxState; s8 get_dialog_box_state(void) { return gDialogBoxState; } @@ -295,12 +294,10 @@ void hud_set_flash(s8 value) { /// -extern s16 gMenuMode; bool is_game_paused(void) { return gMenuMode != -1; } -extern bool gPauseMenuHidden; bool is_pause_menu_hidden(void) { return gPauseMenuHidden; } @@ -309,7 +306,6 @@ void set_pause_menu_hidden(bool hidden) { gPauseMenuHidden = hidden; } -extern void set_play_mode(s16); void game_pause(void) { if (gMenuMode != -1) { return; } @@ -319,8 +315,6 @@ void game_pause(void) { set_play_mode(PLAY_MODE_PAUSED); } -extern s8 gDialogBoxState; -extern s16 gPauseScreenMode; void game_unpause(void) { if (gMenuMode == -1) { return; } @@ -375,13 +369,20 @@ f32 get_hand_foot_pos_z(struct MarioState* m, u8 index) { return m->marioBodyState->animPartsPos[sHandFootToAnimParts[index]][2]; } -bool get_mario_anim_part_pos(struct MarioState *m, u32 animPart, OUT Vec3f pos) { +bool get_mario_anim_part_pos(struct MarioState *m, u32 animPart, VEC_OUT Vec3f pos) { if (!m) { return false; } if (animPart >= MARIO_ANIM_PART_MAX) { return false; } vec3f_copy(pos, m->marioBodyState->animPartsPos[animPart]); return true; } +bool get_mario_anim_part_rot(struct MarioState *m, u32 animPart, VEC_OUT Vec3s rot) { + if (!m) { return false; } + if (animPart >= MARIO_ANIM_PART_MAX) { return false; } + vec3s_copy(rot, m->marioBodyState->animPartsRot[animPart]); + return true; +} + /// s16 get_current_save_file_num(void) { @@ -576,6 +577,7 @@ bool mod_file_exists(const char* filename) { if (gLuaActiveMod == NULL) { return false; } char normPath[SYS_MAX_PATH] = { 0 }; + char normRelative[SYS_MAX_PATH] = { 0 }; if (snprintf(normPath, sizeof(normPath), "%s", filename) < 0) { LOG_ERROR("Failed to copy filename for normalization: %s", filename); @@ -585,7 +587,9 @@ bool mod_file_exists(const char* filename) { for (s32 i = 0; i < gLuaActiveMod->fileCount; i++) { struct ModFile* file = &gLuaActiveMod->files[i]; - if (!strcmp(file->relativePath, normPath)) { + strcpy(normRelative, file->relativePath); + normalize_path(normRelative); + if (!strcmp(normRelative, normPath)) { return true; } } diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h index b9413649a..5171af3ee 100644 --- a/src/pc/lua/utils/smlua_misc_utils.h +++ b/src/pc/lua/utils/smlua_misc_utils.h @@ -168,7 +168,11 @@ f32 get_hand_foot_pos_z(struct MarioState* m, u8 index); /* |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 |descriptionEnd| */ -bool get_mario_anim_part_pos(struct MarioState *m, u32 animPart, OUT Vec3f pos); +bool get_mario_anim_part_pos(struct MarioState *m, u32 animPart, VEC_OUT Vec3f pos); +/* |description| +Retrieves the animated part rotation associated to `animPart` from the MarioState `m` and stores it into `rot`. Returns `true` on success or `false` on failure +|descriptionEnd| */ +bool get_mario_anim_part_rot(struct MarioState *m, u32 animPart, VEC_OUT Vec3s rot); /* |description|Gets the current save file number (1-indexed)|descriptionEnd| */ s16 get_current_save_file_num(void); diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 320f5d62c..d267d7cb8 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -140,6 +140,8 @@ bool network_init(enum NetworkType inNetworkType, bool reconnecting) { gNametagsSettings.showHealth = false; gNametagsSettings.showSelfTag = false; + gPauseMenuHidden = false; + // initialize the network system gNetworkSentJoin = false; int rc = gNetworkSystem->initialize(inNetworkType, reconnecting); diff --git a/src/pc/network/packets/packet_chat.c b/src/pc/network/packets/packet_chat.c index fc6e97423..78123c865 100644 --- a/src/pc/network/packets/packet_chat.c +++ b/src/pc/network/packets/packet_chat.c @@ -78,12 +78,12 @@ void network_send_chat(char* message, u8 globalIndex) { void network_receive_chat(struct Packet* p) { u16 remoteMessageLength = 0; - char remoteMessage[256] = { 0 }; + char remoteMessage[MAX_CHAT_MSG_LENGTH] = { 0 }; u8 globalIndex; packet_read(p, &globalIndex, sizeof(u8)); packet_read(p, &remoteMessageLength, sizeof(u16)); - if (remoteMessageLength >= 255) { remoteMessageLength = 255; } + if (remoteMessageLength >= MAX_CHAT_MSG_LENGTH - 1) { remoteMessageLength = MAX_CHAT_MSG_LENGTH - 1; } packet_read(p, &remoteMessage, remoteMessageLength * sizeof(u8)); // anti spoof diff --git a/src/pc/network/packets/packet_network_players.c b/src/pc/network/packets/packet_network_players.c index 49f3d6beb..c9e57e298 100644 --- a/src/pc/network/packets/packet_network_players.c +++ b/src/pc/network/packets/packet_network_players.c @@ -82,6 +82,10 @@ void network_receive_network_players(struct Packet *p) { LOG_ERROR("received list of clients as a non-client"); return; } + if (network_player_any_connected() && gNetworkPlayers[p->localIndex].type != NPT_SERVER) { + LOG_ERROR("list of clients came from non-server... refuse!"); + return; + } u8 connectedCount = 0; packet_read(p, &connectedCount, sizeof(u8)); for (s16 i = 0; i < connectedCount; i++) { diff --git a/src/pc/network/version.h b/src/pc/network/version.h index 6f23a13f7..473e8fec5 100644 --- a/src/pc/network/version.h +++ b/src/pc/network/version.h @@ -1,12 +1,12 @@ #ifndef VERSION_H #define VERSION_H -#define SM64COOPDX_VERSION "v1.4" +#define SM64COOPDX_VERSION "v1.4.1" // internal version #define VERSION_TEXT "v" #define VERSION_NUMBER 41 -#define MINOR_VERSION_NUMBER 0 +#define MINOR_VERSION_NUMBER 1 #if defined(VERSION_JP) #define VERSION_REGION "JP" diff --git a/src/pc/utils/misc.c b/src/pc/utils/misc.c index 26320867d..34e70241a 100644 --- a/src/pc/utils/misc.c +++ b/src/pc/utils/misc.c @@ -155,14 +155,14 @@ s32 delta_interpolate_s32(s32 a, s32 b, f32 delta) { return a * (1.0f - delta) + b * delta; } -void delta_interpolate_vec3f(OUT Vec3f res, Vec3f a, Vec3f b, f32 delta) { +void delta_interpolate_vec3f(VEC_OUT Vec3f res, Vec3f a, Vec3f b, f32 delta) { f32 antiDelta = 1.0f - delta; res[0] = ((a[0] * antiDelta) + (b[0] * delta)); res[1] = ((a[1] * antiDelta) + (b[1] * delta)); res[2] = ((a[2] * antiDelta) + (b[2] * delta)); } -void delta_interpolate_vec3s(OUT Vec3s res, Vec3s a, Vec3s b, f32 delta) { +void delta_interpolate_vec3s(VEC_OUT Vec3s res, Vec3s a, Vec3s b, f32 delta) { f32 antiDelta = 1.0f - delta; res[0] = ((a[0] * antiDelta) + (b[0] * delta)); res[1] = ((a[1] * antiDelta) + (b[1] * delta)); diff --git a/src/pc/utils/misc.h b/src/pc/utils/misc.h index a5b9d69af..0efabc869 100644 --- a/src/pc/utils/misc.h +++ b/src/pc/utils/misc.h @@ -28,9 +28,9 @@ f32 delta_interpolate_f32(f32 a, f32 b, f32 delta); /* |description|Linearly interpolates between `a` and `b` with `delta`|descriptionEnd| */ s32 delta_interpolate_s32(s32 a, s32 b, f32 delta); /* |description|Linearly interpolates `res` between `a` and `b` with `delta`|descriptionEnd| */ -void delta_interpolate_vec3f(OUT Vec3f res, Vec3f a, Vec3f b, f32 delta); +void delta_interpolate_vec3f(VEC_OUT Vec3f res, Vec3f a, Vec3f b, f32 delta); /* |description|Linearly interpolates `res` between `a` and `b` with `delta`|descriptionEnd| */ -void delta_interpolate_vec3s(OUT Vec3s res, Vec3s a, Vec3s b, f32 delta); +void delta_interpolate_vec3s(VEC_OUT Vec3s res, Vec3s a, Vec3s b, f32 delta); void delta_interpolate_normal(s8* res, s8* a, s8* b, f32 delta); void delta_interpolate_rgba(u8* res, u8* a, u8* b, f32 delta); void delta_interpolate_mtx(Mtx* out, Mtx* a, Mtx* b, f32 delta);