Merge remote-tracking branch 'origin/dev' into char-selector

This commit is contained in:
EmeraldLockdown 2026-05-15 22:38:06 -05:00
commit 5dee55b063
106 changed files with 2676 additions and 784 deletions

1
.gitignore vendored
View file

@ -22,6 +22,7 @@
# Executables
*.exe
!updater/*/*.exe
*.out
*.app
*.hex

View file

@ -46,6 +46,8 @@ ENHANCE_LEVEL_TEXTURES ?= 1
DISCORD_SDK ?= 1
# Enable CoopNet SDK (used for CoopNet server hosting)
COOPNET ?= 1
# Enable Updater (used for automatic updates)
UPDATER ?= 1
# Enable docker build workarounds
DOCKERBUILD ?= 0
# Sets your optimization level for building.
@ -924,6 +926,22 @@ else
endif
endif
# Updater
UPDATER_EXEC :=
ifeq ($(UPDATER),1)
ifeq ($(WINDOWS_BUILD),1)
UPDATER_EXEC += ./updater/win64/coopdx_updater.exe
else ifeq ($(OSX_BUILD),1)
ifeq ($(shell uname -m),arm64)
UPDATER_EXEC += ./updater/mac_arm/coopdx_updater
else
UPDATER_EXEC += ./updater/mac_intel/coopdx_updater
endif
else ifeq ($(TARGET_RPI),0)
UPDATER_EXEC += ./updater/linux/coopdx_updater
endif
endif
IS_DEV_OR_DEBUG := $(or $(filter 1,$(DEVELOPMENT)),$(filter 1,$(DEBUG)),0)
ifeq ($(IS_DEV_OR_DEBUG),0)
CFLAGS += -fno-ident -fno-common -ffile-prefix-map="$(PWD)"=. -D__DATE__="\"\"" -D__TIME__="\"\"" -Wno-builtin-macro-redefined
@ -1126,6 +1144,9 @@ $(BUILD_DIR)/$(DISCORD_SDK_LIBS):
$(BUILD_DIR)/$(COOPNET_LIBS):
@$(CP) -f $(COOPNET_LIBS) $(BUILD_DIR)
$(BUILD_DIR)/$(UPDATER_EXEC):
@$(CP) -f $(UPDATER_EXEC) $(BUILD_DIR)
$(BUILD_DIR)/$(LANG_DIR):
@$(CP) -f -r $(LANG_DIR) $(BUILD_DIR)
@ -1474,7 +1495,7 @@ ifeq ($(TARGET_N64),1)
$(BUILD_DIR)/$(TARGET).objdump: $(ELF)
$(OBJDUMP) -D $< > $@
else
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) $(BUILD_DIR)/$(COOPNET_LIBS) $(BUILD_DIR)/$(LANG_DIR) $(BUILD_DIR)/$(MOD_DIR) $(BUILD_DIR)/$(PALETTES_DIR)
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) $(BUILD_DIR)/$(COOPNET_LIBS) $(BUILD_DIR)/$(UPDATER_EXEC) $(BUILD_DIR)/$(LANG_DIR) $(BUILD_DIR)/$(MOD_DIR) $(BUILD_DIR)/$(PALETTES_DIR)
@$(PRINT) "$(GREEN)Linking executable: $(BLUE)$@ $(NO_COL)\n"
$(V)$(LD) $(PROF_FLAGS) -L $(BUILD_DIR) -o $@ $(O_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS)
endif
@ -1512,6 +1533,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/coopdx_updater $(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)/lib/libSDL2-2.0.0.dylib @executable_path/libSDL2.dylib $(APP_MACOS_DIR)/sm64coopdx > /dev/null 2>&1; \

View file

@ -56,7 +56,7 @@ const Gfx dl_power_meter_base[] = {
gsDPSetRenderMode(G_RM_TEX_EDGE, G_RM_TEX_EDGE2),
gsDPSetTextureFilter(G_TF_POINT),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsSPVertex(vertex_power_meter_base, 8, 0),
gsSPVertexNonGlobal(vertex_power_meter_base, 8, 0),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),
gsDPTileSync(),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 6, G_TX_NOLOD, G_TX_CLAMP, 5, G_TX_NOLOD),
@ -78,7 +78,7 @@ ROM_ASSET_LOAD_VTX(vertex_power_meter_health_segments, 0x00201410, 96653, 0x0002
// 0x03029570 - 0x030295A0
const Gfx dl_power_meter_health_segments_begin[] = {
gsDPPipeSync(),
gsSPVertex(vertex_power_meter_health_segments, 4, 0),
gsSPVertexNonGlobal(vertex_power_meter_health_segments, 4, 0),
gsDPTileSync(),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 5, G_TX_NOLOD, G_TX_CLAMP, 5, G_TX_NOLOD),
gsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (32 - 1) << G_TEXTURE_IMAGE_FRAC),

View file

@ -22,18 +22,20 @@ ROM_ASSET_LOAD_TEXTURE(sparkles_animation_seg4_texture_04034A88, "actors/sparkle
// 0x04035288 - 0x04035300
const Gfx sparkles_animation_seg4_dl_04035288[] = {
gsSPClearGeometryMode(G_LIGHTING),
gsDPSetCombineMode(G_CC_MODULATEIA, G_CC_MODULATEIA),
gsDPSetCombineMode(G_CC_FADEA, G_CC_FADEA),
gsDPSetEnvColor(255, 255, 100, 255),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_CLAMP, 5, G_TX_NOLOD, G_TX_CLAMP, 5, G_TX_NOLOD),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 5, G_TX_NOLOD, G_TX_CLAMP, 5, G_TX_NOLOD),
gsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (32 - 1) << G_TEXTURE_IMAGE_FRAC),
gsSPVertexNonGlobal(sparkles_animation_seg4_vertex_04032A48, 4, 0),
gsSPVertex(sparkles_animation_seg4_vertex_04032A48, 4, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
gsSPSetGeometryMode(G_LIGHTING),
gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
gsDPSetEnvColor(255, 255, 255, 255),
gsSPEndDisplayList(),
};

View file

@ -55,6 +55,7 @@ in_files = [
"src/engine/lighting_engine.h",
"include/PR/gbi.h",
"include/PR/gbi_extension.h",
"src/pc/gfx/gfx_pc.h",
"src/engine/surface_load.h",
"src/pc/lua/utils/smlua_audio_utils.h",
]

View file

@ -145,7 +145,7 @@ override_disallowed_functions = {
"src/engine/behavior_script.h": [ "stub_behavior_script_2", "cur_obj_update" ],
"src/pc/mods/mod_storage.h": [ "mod_storage_shutdown" ],
"src/pc/mods/mod_fs.h": [ "mod_fs_read_file_from_uri", "mod_fs_shutdown" ],
"src/pc/utils/misc.h": [ "str_.*", "file_get_line", "delta_interpolate_(normal|rgba|mtx)", "detect_and_skip_mtx_interpolation", "precise_delay_f64" ],
"src/pc/utils/misc.h": [ "str_.*", "file_get_line", "delta_interpolate_(normal|rgba|mtx)", "detect_and_skip_mtx_interpolation", "precise_delay_f64", "can_update_game", "update_game" ],
"src/engine/lighting_engine.h": [ "le_calculate_vertex_lighting", "le_clear", "le_shutdown" ],
}
@ -1079,7 +1079,7 @@ def build_function(function, do_extern):
else:
global total_functions
total_functions += 1
if function['description'] != "":
if function['description'][0] != "":
global total_doc_functions
total_doc_functions += 1
elif verbose:
@ -1215,7 +1215,7 @@ def process_functions(fname, file_str, extracted_descriptions):
rejects += line + '\n'
continue
line = line.strip()
description = extracted_descriptions.get(line, "")
description = extracted_descriptions.get(line, [""])
fn = process_function(fname, line, description)
if fn == None:
continue
@ -1357,14 +1357,15 @@ def doc_function(fname, function):
fid = function['identifier']
s = '\n## [%s](#%s)\n' % (fid, fid)
description = function.get('description', "")
description = function.get('description', [""])
rtype, rlink = translate_type_to_lua(function['type'])
param_str = ', '.join([x['identifier'] for x in function['params'] if 'RET' not in x])
if description != "":
if description[0] != "":
s += '\n### Description\n'
s += f'{description}\n'
for line in description:
s += f'{line}\n'
s += "\n### Lua Example\n"
rvalues = []
@ -1513,7 +1514,7 @@ def def_function(fname, function):
rid = param['identifier']
rtypes.append((rtype, rid))
if function['description'].startswith("[DEPRECATED"):
if function['description'][0].startswith("[DEPRECATED"):
s += "--- @deprecated\n"
for param in fparams:
@ -1535,8 +1536,9 @@ def def_function(fname, function):
if rtype != "nil":
s += ('--- @return %s' % rtype) + (' %s' % rid if rid else '') + '\n'
if function['description'] != "":
s += "--- %s\n" % (function['description'])
if function['description'][0] != "":
for n, line in enumerate(function['description']):
s += "--- %s%s\n" % (line, "<br>" if n != len(function['description']) - 1 else "")
s += "function %s(%s)\n -- ...\nend\n\n" % (fid, param_str)
return s

View file

@ -144,12 +144,13 @@ def extract_functions(filename):
description_lines.insert(0, raw_lines[k].strip())
if found_description_start and description_lines:
# Combine all lines, remove trailing |descriptionEnd| and normalize whitespace
combined_description = ' '.join(description_lines)
combined_description = re.sub(r'\|\s*descriptionEnd\s*\|.*', '', combined_description).strip()
# Normalize whitespace
combined_description = re.sub(r'\s+', ' ', combined_description).strip()
descriptions[re.sub(r'\)\s*\{', ');', line)] = combined_description
# Remove trailing |descriptionEnd|
if description_lines[0] == '': description_lines.pop(0)
description_lines[-1] = re.sub(r'\|\s*descriptionEnd\s*\|.*', '', description_lines[-1]).strip()
if description_lines[-1] == '': description_lines.pop(-1)
if len(description_lines) > 0:
descriptions[re.sub(r'\)\s*\{', ');', line)] = description_lines
break
# normalize function ending

View file

@ -3070,6 +3070,27 @@ BACKGROUND_CUSTOM = 10 --- @type SkyBackgroundParams
--- | `BACKGROUND_PURPLE_SKY`
--- | `BACKGROUND_CUSTOM`
SHADER_FLAG_HUE = 0 --- @type ShaderFlag
SHADER_FLAG_SATURATION = 1 --- @type ShaderFlag
SHADER_FLAG_BRIGHTNESS = 2 --- @type ShaderFlag
SHADER_FLAG_CONTRAST = 3 --- @type ShaderFlag
SHADER_FLAG_EXPOSURE = 4 --- @type ShaderFlag
SHADER_FLAG_DITHERING = 5 --- @type ShaderFlag
SHADER_FLAG_POSTERIZATION = 6 --- @type ShaderFlag
SHADER_FLAG_SCANLINES = 7 --- @type ShaderFlag
SHADER_FLAG_MAX = 8 --- @type ShaderFlag
--- @alias ShaderFlag
--- | `SHADER_FLAG_HUE`
--- | `SHADER_FLAG_SATURATION`
--- | `SHADER_FLAG_BRIGHTNESS`
--- | `SHADER_FLAG_CONTRAST`
--- | `SHADER_FLAG_EXPOSURE`
--- | `SHADER_FLAG_DITHERING`
--- | `SHADER_FLAG_POSTERIZATION`
--- | `SHADER_FLAG_SCANLINES`
--- | `SHADER_FLAG_MAX`
--- @type integer
GRAPH_RENDER_ACTIVE = (1 << 0)

File diff suppressed because it is too large Load diff

View file

@ -556,6 +556,7 @@
--- @class DjuiInteractableTheme
--- @field public textColor DjuiColor
--- @field public disabledTextColor DjuiColor
--- @field public defaultRectColor DjuiColor
--- @field public cursorDownRectColor DjuiColor
--- @field public hoveredRectColor DjuiColor

View file

@ -2351,7 +2351,7 @@ const Gfx dl_transition_draw_filled_region[] = {
const Gfx dl_skybox_begin[] = {
gsDPPipeSync(),
gsSPClearGeometryMode(G_LIGHTING),
gsDPSetCombineMode(G_CC_MODULATERGB, G_CC_MODULATERGB),
gsDPSetCombineMode(G_CC_FADEA, G_CC_FADEA),
gsSPPerspNormalize(0xFFFF),
gsSPMatrix(&matrix_identity, G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH),
gsSPEndDisplayList(),

View file

@ -29,6 +29,8 @@
- [gbi_extension.h](#gbi_extensionh)
- [geo_commands.h](#geo_commandsh)
- [enum SkyBackgroundParams](#enum-SkyBackgroundParams)
- [gfx_pc.h](#gfx_pch)
- [enum ShaderFlag](#enum-ShaderFlag)
- [graph_node.h](#graph_nodeh)
- [interaction.c](#interactionc)
- [interaction.h](#interactionh)
@ -1347,6 +1349,25 @@
<br />
## [gfx_pc.h](#gfx_pc.h)
### [enum ShaderFlag](#ShaderFlag)
| Identifier | Value |
| :--------- | :---- |
| SHADER_FLAG_HUE | 0 |
| SHADER_FLAG_SATURATION | 1 |
| SHADER_FLAG_BRIGHTNESS | 2 |
| SHADER_FLAG_CONTRAST | 3 |
| SHADER_FLAG_EXPOSURE | 4 |
| SHADER_FLAG_DITHERING | 5 |
| SHADER_FLAG_POSTERIZATION | 6 |
| SHADER_FLAG_SCANLINES | 7 |
| SHADER_FLAG_MAX | 8 |
[:arrow_up_small:](#)
<br />
## [graph_node.h](#graph_node.h)
- GRAPH_RENDER_ACTIVE
- GRAPH_RENDER_CHILDREN_FIRST

View file

@ -4197,7 +4197,8 @@ Behavior loop function for Tox Box
## [mario_moving_fast_enough_to_make_piranha_plant_bite](#mario_moving_fast_enough_to_make_piranha_plant_bite)
### Description
Checks if Mario is moving fast enough to make Piranha Plant bite. This one is a mouthful
Checks if Mario is moving fast enough to make Piranha Plant bite.
This one is a mouthful
### Lua Example
`local integerValue = mario_moving_fast_enough_to_make_piranha_plant_bite()`

File diff suppressed because it is too large Load diff

View file

@ -880,7 +880,8 @@ Overrides the soundbank, set to -1 to reset
## [is_anim_at_end](#is_anim_at_end)
### Description
Checks if Mario's current animation has reached its final frame (i.e., the last valid frame in the animation). Useful for deciding when to transition out of an animation-driven action
Checks if Mario's current animation has reached its final frame (i.e., the last valid frame in the animation).
Useful for deciding when to transition out of an animation-driven action
### Lua Example
`local integerValue = is_anim_at_end(m)`
@ -903,7 +904,8 @@ Checks if Mario's current animation has reached its final frame (i.e., the last
## [is_anim_past_end](#is_anim_past_end)
### Description
Checks if Mario's current animation has passed the second-to-last valid frame (i.e., effectively at or beyond its final frames). Useful for advanced checks where slightly early transitions or timing are needed before the final frame
Checks if Mario's current animation has passed the second-to-last valid frame (i.e., effectively at or beyond its final frames).
Useful for advanced checks where slightly early transitions or timing are needed before the final frame
### Lua Example
`local integerValue = is_anim_past_end(m)`
@ -950,7 +952,8 @@ Sets Mario's current animation to `targetAnimID` at a default acceleration (no s
## [set_mario_anim_with_accel](#set_mario_anim_with_accel)
### Description
Sets Mario's current animation to `targetAnimID` with a custom `accel` value to speed up or slow down the animation. Useful for controlling animation timing, e.g., slow-motion or fast-forward effects
Sets Mario's current animation to `targetAnimID` with a custom `accel` value to speed up or slow down the animation.
Useful for controlling animation timing, e.g., slow-motion or fast-forward effects
### Lua Example
`local integerValue = set_mario_anim_with_accel(m, targetAnimID, accel)`
@ -999,7 +1002,8 @@ Sets the character-specific animation at its default rate (no acceleration)
## [set_character_anim_with_accel](#set_character_anim_with_accel)
### Description
Sets a character-specific animation where the animation speed is adjusted by `accel`. Useful for varying animation speeds based on context or dynamic conditions (e.g., slow-motion)
Sets a character-specific animation where the animation speed is adjusted by `accel`.
Useful for varying animation speeds based on context or dynamic conditions (e.g., slow-motion)
### Lua Example
`local integerValue = set_character_anim_with_accel(m, targetAnimID, accel)`
@ -1048,7 +1052,8 @@ Sets the current animation frame to a specific `animFrame`
## [is_anim_past_frame](#is_anim_past_frame)
### Description
Checks if Mario's current animation is past a specified `animFrame`. Useful for conditional logic where an action can branch after reaching a specific point in the animation
Checks if Mario's current animation is past a specified `animFrame`.
Useful for conditional logic where an action can branch after reaching a specific point in the animation
### Lua Example
`local integerValue = is_anim_past_frame(m, animFrame)`
@ -1072,7 +1077,8 @@ Checks if Mario's current animation is past a specified `animFrame`. Useful for
## [find_mario_anim_flags_and_translation](#find_mario_anim_flags_and_translation)
### Description
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
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
### Lua Example
`local integerValue = find_mario_anim_flags_and_translation(o, yaw, translation)`
@ -1120,7 +1126,8 @@ Applies the translation from Mario's current animation to his world position. Co
## [return_mario_anim_y_translation](#return_mario_anim_y_translation)
### Description
Determines the vertical translation from Mario's animation (how much the animation moves Mario up or down). Returns the y-component of the animation's translation. Useful for adjusting Mario's vertical position based on an ongoing animation (e.g., a bounce or jump)
Determines the vertical translation from Mario's animation (how much the animation moves Mario up or down). Returns the y-component of the animation's translation.
Useful for adjusting Mario's vertical position based on an ongoing animation (e.g., a bounce or jump)
### Lua Example
`local integerValue = return_mario_anim_y_translation(m)`
@ -1191,7 +1198,8 @@ Plays Mario's jump sound if it hasn't been played yet since the last action chan
## [adjust_sound_for_speed](#adjust_sound_for_speed)
### Description
Adjusts the pitch/volume of Mario's movement-based sounds according to his forward velocity (`m.forwardVel`). Useful for adding dynamic audio feedback based on Mario's running or walking speed
Adjusts the pitch/volume of Mario's movement-based sounds according to his forward velocity (`m.forwardVel`).
Useful for adding dynamic audio feedback based on Mario's running or walking speed
### Lua Example
`adjust_sound_for_speed(m)`
@ -1312,7 +1320,8 @@ A variant of `play_mario_landing_sound` that ensures the sound is only played on
## [play_mario_heavy_landing_sound](#play_mario_heavy_landing_sound)
### Description
Plays a heavier, more forceful landing sound, possibly for ground pounds or large impacts. Takes into account whether Mario has a metal cap equipped. Useful for making big impact landings stand out aurally
Plays a heavier, more forceful landing sound, possibly for ground pounds or large impacts. Takes into account whether Mario has a metal cap equipped.
Useful for making big impact landings stand out aurally
### Lua Example
`play_mario_heavy_landing_sound(m, soundBits)`
@ -1336,7 +1345,8 @@ Plays a heavier, more forceful landing sound, possibly for ground pounds or larg
## [play_mario_heavy_landing_sound_once](#play_mario_heavy_landing_sound_once)
### Description
A variant of `play_mario_heavy_landing_sound` that ensures the sound is only played once per action (using `play_mario_action_sound` internally). Useful for consistent heavy landing effects without repetition
A variant of `play_mario_heavy_landing_sound` that ensures the sound is only played once per action (using `play_mario_action_sound` internally).
Useful for consistent heavy landing effects without repetition
### Lua Example
`play_mario_heavy_landing_sound_once(m, soundBits)`
@ -1477,7 +1487,8 @@ Transitions Mario into a bubbled state (if available in multiplayer), decrementi
## [mario_set_forward_vel](#mario_set_forward_vel)
### Description
Sets Mario's forward velocity (`m.forwardVel`) and updates `slideVelX/Z` and `m.vel` accordingly, based on `m.faceAngle.y`. Useful for controlling Mario's speed and direction in various actions (jumping, walking, sliding, etc.)
Sets Mario's forward velocity (`m.forwardVel`) and updates `slideVelX/Z` and `m.vel` accordingly, based on `m.faceAngle.y`.
Useful for controlling Mario's speed and direction in various actions (jumping, walking, sliding, etc.)
### Lua Example
`mario_set_forward_vel(m, speed)`
@ -1501,7 +1512,8 @@ Sets Mario's forward velocity (`m.forwardVel`) and updates `slideVelX/Z` and `m.
## [mario_get_floor_class](#mario_get_floor_class)
### Description
Retrieves the slipperiness class of Mario's current floor, ranging from not slippery to very slippery. Considers terrain types and special surfaces. Useful for controlling friction, movement speed adjustments, and whether Mario slips or walks
Retrieves the slipperiness class of Mario's current floor, ranging from not slippery to very slippery. Considers terrain types and special surfaces.
Useful for controlling friction, movement speed adjustments, and whether Mario slips or walks
### Lua Example
`local integerValue = mario_get_floor_class(m)`
@ -1524,7 +1536,8 @@ Retrieves the slipperiness class of Mario's current floor, ranging from not slip
## [mario_get_terrain_sound_addend](#mario_get_terrain_sound_addend)
### Description
Computes a value added to terrain sounds, depending on the floor's type (sand, snow, water, etc.) and slipperiness. This returns a sound 'addend' used with sound effects. Useful for playing context-specific footstep or movement sounds
Computes a value added to terrain sounds, depending on the floor's type (sand, snow, water, etc.) and slipperiness. This returns a sound 'addend' used with sound effects.
Useful for playing context-specific footstep or movement sounds
### Lua Example
`local integerValue = mario_get_terrain_sound_addend(m)`
@ -1547,7 +1560,8 @@ Computes a value added to terrain sounds, depending on the floor's type (sand, s
## [resolve_and_return_wall_collisions](#resolve_and_return_wall_collisions)
### Description
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
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)`
@ -1598,7 +1612,8 @@ Similar to `resolve_and_return_wall_collisions` but also returns detailed collis
## [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
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)`
@ -1623,7 +1638,9 @@ Finds the ceiling from a vec3f horizontally and a height (with 80 vertical buffe
## [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
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)`
@ -1648,7 +1665,8 @@ Finds the ceiling from a vec3f horizontally and a height (with 80 vertical buffe
## [mario_facing_downhill](#mario_facing_downhill)
### 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. Useful for deciding if Mario will walk or slide on sloped floors
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.
Useful for deciding if Mario will walk or slide on sloped floors
### Lua Example
`local integerValue = mario_facing_downhill(m, turnYaw)`
@ -1672,7 +1690,8 @@ Determines if Mario is facing downhill relative to his floor angle, optionally a
## [mario_floor_is_slippery](#mario_floor_is_slippery)
### Description
Checks whether Mario's current floor is slippery based on both the floor's surface class and Mario's environment (e.g., special slides). Useful for deciding if Mario should transition to sliding or maintain normal traction
Checks whether Mario's current floor is slippery based on both the floor's surface class and Mario's environment (e.g., special slides).
Useful for deciding if Mario should transition to sliding or maintain normal traction
### Lua Example
`local integerValue = mario_floor_is_slippery(m)`
@ -1718,7 +1737,8 @@ Checks whether Mario's floor is a slope, i.e., not flat but not necessarily stee
## [mario_floor_is_steep](#mario_floor_is_steep)
### Description
Checks whether Mario's floor is steep enough to cause special behavior, such as forcing slides or preventing certain actions. Returns true if the slope is too steep. Useful for restricting normal movement on surfaces with extreme angles
Checks whether Mario's floor is steep enough to cause special behavior, such as forcing slides or preventing certain actions. Returns true if the slope is too steep.
Useful for restricting normal movement on surfaces with extreme angles
### Lua Example
`local integerValue = mario_floor_is_steep(m)`
@ -1741,7 +1761,8 @@ Checks whether Mario's floor is steep enough to cause special behavior, such as
## [find_floor_height_relative_polar](#find_floor_height_relative_polar)
### Description
Finds the floor height relative to Mario's current position given a polar displacement (`angleFromMario`, `distFromMario`). Useful for determining height differentials ahead or behind Mario, e.g. for slope checks or collision logic
Finds the floor height relative to Mario's current position given a polar displacement (`angleFromMario`, `distFromMario`).
Useful for determining height differentials ahead or behind Mario, e.g. for slope checks or collision logic
### Lua Example
`local numberValue = find_floor_height_relative_polar(m, angleFromMario, distFromMario)`
@ -1766,7 +1787,8 @@ Finds the floor height relative to Mario's current position given a polar displa
## [find_floor_slope](#find_floor_slope)
### Description
Returns a slope angle based on comparing the floor heights slightly in front and behind Mario. It essentially calculates how steep the ground is in a specific yaw direction. Useful for slope-based calculations such as setting walking or sliding behaviors
Returns a slope angle based on comparing the floor heights slightly in front and behind Mario. It essentially calculates how steep the ground is in a specific yaw direction.
Useful for slope-based calculations such as setting walking or sliding behaviors
### Lua Example
`local integerValue = find_floor_slope(m, yawOffset)`
@ -1790,7 +1812,8 @@ Returns a slope angle based on comparing the floor heights slightly in front and
## [update_mario_sound_and_camera](#update_mario_sound_and_camera)
### Description
Updates the background noise and camera modes based on Mario's action. Especially relevant for actions like first-person view or sleeping. Useful for synchronizing camera behavior and ambient sounds with Mario's state changes
Updates the background noise and camera modes based on Mario's action. Especially relevant for actions like first-person view or sleeping.
Useful for synchronizing camera behavior and ambient sounds with Mario's state changes
### Lua Example
`update_mario_sound_and_camera(m)`
@ -1813,7 +1836,8 @@ Updates the background noise and camera modes based on Mario's action. Especiall
## [set_steep_jump_action](#set_steep_jump_action)
### Description
Transitions Mario into ACT_STEEP_JUMP if the floor is too steep, adjusting his forward velocity and orientation accordingly. Useful for forcing special jump states on surfaces exceeding normal slope limits
Transitions Mario into ACT_STEEP_JUMP if the floor is too steep, adjusting his forward velocity and orientation accordingly.
Useful for forcing special jump states on surfaces exceeding normal slope limits
### Lua Example
`set_steep_jump_action(m)`
@ -1985,7 +2009,8 @@ Increments Mario's `hurtCounter` and immediately sets a new action. Often used w
## [check_common_action_exits](#check_common_action_exits)
### Description
Checks for inputs that cause common action transitions (jump, freefall, walking, sliding). Useful for quickly exiting certain stationary actions when Mario begins moving or leaves the floor
Checks for inputs that cause common action transitions (jump, freefall, walking, sliding).
Useful for quickly exiting certain stationary actions when Mario begins moving or leaves the floor
### Lua Example
`local integerValue = check_common_action_exits(m)`
@ -2031,7 +2056,8 @@ Checks for inputs that cause common hold-action transitions (hold jump, hold fre
## [transition_submerged_to_walking](#transition_submerged_to_walking)
### Description
Transitions Mario from being underwater to a walking state. Resets camera to the default mode and can handle object-holding states. Useful for restoring standard ground movement when emerging from water
Transitions Mario from being underwater to a walking state. Resets camera to the default mode and can handle object-holding states.
Useful for restoring standard ground movement when emerging from water
### Lua Example
`local integerValue = transition_submerged_to_walking(m)`
@ -2100,7 +2126,8 @@ Main driver for Mario's behavior. Executes the current action group (stationary,
## [force_idle_state](#force_idle_state)
### Description
Forces Mario into an idle state, either `ACT_IDLE` or `ACT_WATER_IDLE` depending on whether he is submerged. Useful for quickly resetting Mario's state to an idle pose under special conditions (e.g., cutscene triggers)
Forces Mario into an idle state, either `ACT_IDLE` or `ACT_WATER_IDLE` depending on whether he is submerged.
Useful for quickly resetting Mario's state to an idle pose under special conditions (e.g., cutscene triggers)
### Lua Example
`local integerValue = force_idle_state(m)`
@ -2224,7 +2251,8 @@ Gets the MarioState corresponding to the provided object if the object is a Mari
## [play_flip_sounds](#play_flip_sounds)
### Description
Plays a spinning sound at specific animation frames for flips (usually side flips or certain jump flips). If the current animation frame matches any of the specified frames, it triggers `SOUND_ACTION_SPIN`
Plays a spinning sound at specific animation frames for flips (usually side flips or certain jump flips).
If the current animation frame matches any of the specified frames, it triggers `SOUND_ACTION_SPIN`
### Lua Example
`play_flip_sounds(m, frame1, frame2, frame3)`
@ -2250,7 +2278,8 @@ Plays a spinning sound at specific animation frames for flips (usually side flip
## [play_far_fall_sound](#play_far_fall_sound)
### Description
Plays a unique sound when Mario has fallen a significant distance without being invulnerable, twirling, or flying. If the fall exceeds a threshold, triggers a "long fall" exclamation. Also sets a flag to prevent repeated triggering
Plays a unique sound when Mario has fallen a significant distance without being invulnerable, twirling, or flying.
If the fall exceeds a threshold, triggers a "long fall" exclamation. Also sets a flag to prevent repeated triggering
### Lua Example
`play_far_fall_sound(m)`
@ -2273,7 +2302,8 @@ Plays a unique sound when Mario has fallen a significant distance without being
## [play_knockback_sound](#play_knockback_sound)
### Description
Plays a knockback sound effect if Mario is hit or knocked back with significant velocity. The specific sound differs depending on whether Mario's forward velocity is high enough to be considered a strong knockback
Plays a knockback sound effect if Mario is hit or knocked back with significant velocity. The specific sound differs
depending on whether Mario's forward velocity is high enough to be considered a strong knockback
### Lua Example
`play_knockback_sound(m)`
@ -2296,7 +2326,9 @@ Plays a knockback sound effect if Mario is hit or knocked back with significant
## [lava_boost_on_wall](#lava_boost_on_wall)
### Description
Allows Mario to 'lava boost' off a lava wall, reorienting him to face away from the wall and adjusting forward velocity. Increases Mario's hurt counter if he's not metal, plays a burning sound, and transitions his action to `ACT_LAVA_BOOST`. Useful for handling collisions with lava walls, giving Mario a strong upward/forward boost at the cost of health
Allows Mario to 'lava boost' off a lava wall, reorienting him to face away from the wall and adjusting forward velocity.
Increases Mario's hurt counter if he's not metal, plays a burning sound, and transitions his action to `ACT_LAVA_BOOST`.
Useful for handling collisions with lava walls, giving Mario a strong upward/forward boost at the cost of health
### Lua Example
`local integerValue = lava_boost_on_wall(m)`
@ -2319,7 +2351,10 @@ Allows Mario to 'lava boost' off a lava wall, reorienting him to face away from
## [check_fall_damage](#check_fall_damage)
### Description
Evaluates whether Mario should take fall damage based on the height difference between his peak and current position. If the fall is large enough and does not occur over burning surfaces or while twirling, Mario may get hurt or enter a hard fall action. If the fall is significant but not extreme, minimal damage and a squish effect may be applied. Useful for determining if Mario's fall warrants a health penalty or a special landing action
Evaluates whether Mario should take fall damage based on the height difference between his peak and current position.
If the fall is large enough and does not occur over burning surfaces or while twirling, Mario may get hurt or enter
a hard fall action. If the fall is significant but not extreme, minimal damage and a squish effect may be applied.
Useful for determining if Mario's fall warrants a health penalty or a special landing action
### Lua Example
`local integerValue = check_fall_damage(m, hardFallAction)`
@ -2343,7 +2378,8 @@ Evaluates whether Mario should take fall damage based on the height difference b
## [check_kick_or_dive_in_air](#check_kick_or_dive_in_air)
### Description
Checks if Mario should perform a kick or a dive while in mid-air, depending on his current forward velocity. Pressing the B button in the air can trigger a jump kick (at lower speeds) or a dive (at higher speeds)
Checks if Mario should perform a kick or a dive while in mid-air, depending on his current forward velocity.
Pressing the B button in the air can trigger a jump kick (at lower speeds) or a dive (at higher speeds)
### Lua Example
`local integerValue = check_kick_or_dive_in_air(m)`
@ -2366,7 +2402,9 @@ Checks if Mario should perform a kick or a dive while in mid-air, depending on h
## [should_get_stuck_in_ground](#should_get_stuck_in_ground)
### Description
Determines whether Mario should become stuck in the ground after landing, specifically for soft terrain such as snow or sand, provided certain conditions are met (height of the fall, normal of the floor, etc.). Returns true if Mario should be stuck, false otherwise
Determines whether Mario should become stuck in the ground after landing, specifically for soft terrain such as snow
or sand, provided certain conditions are met (height of the fall, normal of the floor, etc.).
Returns true if Mario should be stuck, false otherwise
### Lua Example
`local integerValue = should_get_stuck_in_ground(m)`
@ -2389,7 +2427,9 @@ Determines whether Mario should become stuck in the ground after landing, specif
## [check_fall_damage_or_get_stuck](#check_fall_damage_or_get_stuck)
### Description
Checks if Mario should get stuck in the ground after a large fall onto soft terrain (like snow or sand) or if he should just proceed with regular fall damage calculations. If the terrain and height conditions are met, Mario's action changes to being stuck in the ground. Otherwise, normal fall damage logic applies
Checks if Mario should get stuck in the ground after a large fall onto soft terrain (like snow or sand) or if he
should just proceed with regular fall damage calculations. If the terrain and height conditions are met, Mario's
action changes to being stuck in the ground. Otherwise, normal fall damage logic applies
### Lua Example
`local integerValue = check_fall_damage_or_get_stuck(m, hardFallAction)`
@ -2413,7 +2453,8 @@ Checks if Mario should get stuck in the ground after a large fall onto soft terr
## [check_horizontal_wind](#check_horizontal_wind)
### Description
Checks for the presence of a horizontal wind surface under Mario. If found, applies a push force to Mario's horizontal velocity. Caps speed at certain thresholds, updates Mario's forward velocity and yaw for sliding/wind movement
Checks for the presence of a horizontal wind surface under Mario. If found, applies a push force to Mario's horizontal
velocity. Caps speed at certain thresholds, updates Mario's forward velocity and yaw for sliding/wind movement
### Lua Example
`local integerValue = check_horizontal_wind(m)`
@ -2436,7 +2477,8 @@ Checks for the presence of a horizontal wind surface under Mario. If found, appl
## [update_air_with_turn](#update_air_with_turn)
### Description
Updates Mario's air movement while allowing him to turn. Checks horizontal wind and applies a moderate amount of drag, approaches the forward velocity toward zero if no input is pressed, and modifies forward velocity/angle based on stick input
Updates Mario's air movement while allowing him to turn. Checks horizontal wind and applies a moderate amount of drag,
approaches the forward velocity toward zero if no input is pressed, and modifies forward velocity/angle based on stick input
### Lua Example
`update_air_with_turn(m)`
@ -2459,7 +2501,8 @@ Updates Mario's air movement while allowing him to turn. Checks horizontal wind
## [update_air_without_turn](#update_air_without_turn)
### Description
Updates Mario's air movement without directly turning his facing angle to match his intended yaw. Instead, Mario can move sideways relative to his current facing direction. Also checks horizontal wind and applies drag
Updates Mario's air movement without directly turning his facing angle to match his intended yaw. Instead, Mario can
move sideways relative to his current facing direction. Also checks horizontal wind and applies drag
### Lua Example
`update_air_without_turn(m)`
@ -2482,7 +2525,8 @@ Updates Mario's air movement without directly turning his facing angle to match
## [update_lava_boost_or_twirling](#update_lava_boost_or_twirling)
### Description
Updates Mario's movement when in actions like lava boost or twirling in mid-air. Applies player input to adjust forward velocity and facing angle, but in a more restricted manner compared to standard jump movement. Used by `ACT_LAVA_BOOST` and `ACT_TWIRLING`
Updates Mario's movement when in actions like lava boost or twirling in mid-air. Applies player input to adjust forward velocity
and facing angle, but in a more restricted manner compared to standard jump movement. Used by `ACT_LAVA_BOOST` and `ACT_TWIRLING`
### Lua Example
`update_lava_boost_or_twirling(m)`
@ -2505,7 +2549,8 @@ Updates Mario's movement when in actions like lava boost or twirling in mid-air.
## [update_flying_yaw](#update_flying_yaw)
### Description
Calculates and applies a change in Mario's yaw while flying, based on horizontal stick input. Approaches a target yaw velocity and sets Mario's roll angle to simulate banking turns. This results in a more natural, curved flight path
Calculates and applies a change in Mario's yaw while flying, based on horizontal stick input. Approaches a target yaw velocity
and sets Mario's roll angle to simulate banking turns. This results in a more natural, curved flight path
### Lua Example
`update_flying_yaw(m)`
@ -2528,7 +2573,8 @@ Calculates and applies a change in Mario's yaw while flying, based on horizontal
## [update_flying_pitch](#update_flying_pitch)
### Description
Calculates and applies a change in Mario's pitch while flying, based on vertical stick input. Approaches a target pitch velocity and clamps the final pitch angle to a certain range, simulating a smooth flight control
Calculates and applies a change in Mario's pitch while flying, based on vertical stick input. Approaches a target pitch velocity
and clamps the final pitch angle to a certain range, simulating a smooth flight control
### Lua Example
`update_flying_pitch(m)`
@ -2551,7 +2597,8 @@ Calculates and applies a change in Mario's pitch while flying, based on vertical
## [update_flying](#update_flying)
### Description
Handles the complete flying logic for Mario (usually with the wing cap). Continuously updates pitch and yaw based on controller input, applies drag, and adjusts forward velocity. Also updates Mario's model angles for flight animations
Handles the complete flying logic for Mario (usually with the wing cap). Continuously updates pitch and yaw based on controller input,
applies drag, and adjusts forward velocity. Also updates Mario's model angles for flight animations
### Lua Example
`update_flying(m)`
@ -2574,7 +2621,9 @@ Handles the complete flying logic for Mario (usually with the wing cap). Continu
## [common_air_action_step](#common_air_action_step)
### Description
Performs a standard step update for air actions without knockback, typically used for jumps or freefalls. Updates Mario's velocity (and possibly checks horizontal wind), then calls `perform_air_step` with given `stepArg`. Handles how Mario lands, hits walls, grabs ledges, or grabs ceilings. Optionally sets an animation
Performs a standard step update for air actions without knockback, typically used for jumps or freefalls.
Updates Mario's velocity (and possibly checks horizontal wind), then calls `perform_air_step` with given `stepArg`.
Handles how Mario lands, hits walls, grabs ledges, or grabs ceilings. Optionally sets an animation
### Lua Example
`local integerValue = common_air_action_step(m, landAction, animation, stepArg)`
@ -2600,7 +2649,8 @@ Performs a standard step update for air actions without knockback, typically use
## [common_air_knockback_step](#common_air_knockback_step)
### Description
A shared step update used for airborne knockback states (both forward and backward). Updates velocity, calls `perform_air_step`, and handles wall collisions or landing transitions to appropriate ground knockback actions. Also sets animation and speed
A shared step update used for airborne knockback states (both forward and backward). Updates velocity, calls `perform_air_step`,
and handles wall collisions or landing transitions to appropriate ground knockback actions. Also sets animation and speed
### Lua Example
`local integerValue = common_air_knockback_step(m, landAction, hardFallAction, animation, speed)`
@ -2627,7 +2677,8 @@ A shared step update used for airborne knockback states (both forward and backwa
## [check_wall_kick](#check_wall_kick)
### Description
Checks if Mario should wall kick after performing an air hit against a wall. If the input conditions (e.g., pressing A) and the `wallKickTimer` allow, Mario transitions to `ACT_WALL_KICK_AIR`
Checks if Mario should wall kick after performing an air hit against a wall. If the input conditions (e.g., pressing A)
and the `wallKickTimer` allow, Mario transitions to `ACT_WALL_KICK_AIR`
### Lua Example
`local integerValue = check_wall_kick(m)`
@ -2650,7 +2701,9 @@ Checks if Mario should wall kick after performing an air hit against a wall. If
## [check_common_airborne_cancels](#check_common_airborne_cancels)
### Description
Checks for and handles common conditions that would cancel Mario's current air action. This includes transitioning to a water plunge if below the water level, becoming squished if appropriate, or switching to vertical wind action if on certain wind surfaces. Also resets `m.quicksandDepth`
Checks for and handles common conditions that would cancel Mario's current air action. This includes transitioning
to a water plunge if below the water level, becoming squished if appropriate, or switching to vertical wind action
if on certain wind surfaces. Also resets `m.quicksandDepth`
### Lua Example
`local integerValue = check_common_airborne_cancels(m)`
@ -2673,7 +2726,8 @@ Checks for and handles common conditions that would cancel Mario's current air a
## [mario_execute_airborne_action](#mario_execute_airborne_action)
### Description
Executes Mario's current airborne action by first checking common airborne cancels, then playing a far-fall sound if needed. Dispatches to the appropriate action function, such as jump, double jump, freefall, etc
Executes Mario's current airborne action by first checking common airborne cancels, then playing a far-fall sound if needed.
Dispatches to the appropriate action function, such as jump, double jump, freefall, etc
### Lua Example
`local integerValue = mario_execute_airborne_action(m)`
@ -2702,7 +2756,8 @@ Executes Mario's current airborne action by first checking common airborne cance
## [add_tree_leaf_particles](#add_tree_leaf_particles)
### Description
Spawns leaf particles when Mario climbs a tree, if he is sufficiently high above the floor. In Shifting Sand Land, the leaf effect spawns higher due to the taller palm trees
Spawns leaf particles when Mario climbs a tree, if he is sufficiently high above the floor.
In Shifting Sand Land, the leaf effect spawns higher due to the taller palm trees
### Lua Example
`add_tree_leaf_particles(m)`
@ -2749,7 +2804,8 @@ Plays the appropriate climbing sound effect depending on whether Mario is on a t
## [set_pole_position](#set_pole_position)
### Description
Sets Mario's position and alignment while he is on a climbable pole or tree. This function checks collisions with floors and ceilings, and updates Mario's action if he leaves the pole or touches the floor. Useful for ensuring Mario's correct placement and transitions when climbing poles or trees
Sets Mario's position and alignment while he is on a climbable pole or tree. This function checks collisions with floors and ceilings, and updates Mario's action if he leaves the pole or touches the floor.
Useful for ensuring Mario's correct placement and transitions when climbing poles or trees
### Lua Example
`local integerValue = set_pole_position(m, offsetY)`
@ -2983,7 +3039,8 @@ Checks if Mario should cancel his current automatic action, primarily by detecti
## [mario_execute_automatic_action](#mario_execute_automatic_action)
### Description
Executes Mario's current automatic action (e.g., climbing a pole, hanging, ledge-grabbing) by calling the corresponding function. It also checks for common cancellations, like falling into water. Returns true if the action was canceled and a new action was set, or false otherwise
Executes Mario's current automatic action (e.g., climbing a pole, hanging, ledge-grabbing) by calling the corresponding function. It also checks for common cancellations, like falling into water.
Returns true if the action was canceled and a new action was set, or false otherwise
### Lua Example
`local integerValue = mario_execute_automatic_action(m)`
@ -3374,7 +3431,8 @@ Executes Mario's current cutscene action based on his `action` field. Includes v
## [tilt_body_running](#tilt_body_running)
### Description
Tilts Mario's body according to his running speed and slope angle. Calculates a pitch offset used while running to simulate leaning forward at higher speeds or on slopes
Tilts Mario's body according to his running speed and slope angle.
Calculates a pitch offset used while running to simulate leaning forward at higher speeds or on slopes
### Lua Example
`local integerValue = tilt_body_running(m)`
@ -3397,7 +3455,8 @@ Tilts Mario's body according to his running speed and slope angle. Calculates a
## [play_step_sound](#play_step_sound)
### Description
Checks the current animation frame against two specified frames to trigger footstep sounds. Also chooses specific sounds if Mario is wearing Metal Cap or is in quicksand
Checks the current animation frame against two specified frames to trigger footstep sounds.
Also chooses specific sounds if Mario is wearing Metal Cap or is in quicksand
### Lua Example
`play_step_sound(m, frame1, frame2)`
@ -3471,7 +3530,8 @@ Sets Mario's facing yaw to his intended yaw, applies a specified forward velocit
## [check_ledge_climb_down](#check_ledge_climb_down)
### Description
Checks if Mario is near an edge while moving slowly and the floor below that edge is significantly lower. If the conditions are met, transitions Mario into a ledge-climb-down action and positions him accordingly on the edge
Checks if Mario is near an edge while moving slowly and the floor below that edge is significantly lower.
If the conditions are met, transitions Mario into a ledge-climb-down action and positions him accordingly on the edge
### Lua Example
`check_ledge_climb_down(m)`
@ -3544,7 +3604,9 @@ Determines the proper triple jump action based on Mario's forward velocity and t
## [update_sliding_angle](#update_sliding_angle)
### Description
Adjusts Mario's slide velocity and facing angle when on a slope. Calculates slope direction and steepness, then modifies velocity accordingly (speed up downhill, slow uphill). Handles facing-direction changes and maximum speed limits
Adjusts Mario's slide velocity and facing angle when on a slope.
Calculates slope direction and steepness, then modifies velocity accordingly (speed up downhill, slow uphill).
Handles facing-direction changes and maximum speed limits
### Lua Example
`update_sliding_angle(m, accel, lossFactor)`
@ -3569,7 +3631,9 @@ Adjusts Mario's slide velocity and facing angle when on a slope. Calculates slop
## [update_sliding](#update_sliding)
### Description
Updates Mario's sliding state each frame, applying additional friction or acceleration based on the surface's slipperiness. Also checks if speed has slowed below a threshold to end the slide. Returns `true` if sliding has stopped
Updates Mario's sliding state each frame, applying additional friction or acceleration based on the surface's slipperiness.
Also checks if speed has slowed below a threshold to end the slide.
Returns `true` if sliding has stopped
### Lua Example
`local integerValue = update_sliding(m, stopSpeed)`
@ -3593,7 +3657,8 @@ Updates Mario's sliding state each frame, applying additional friction or accele
## [apply_slope_accel](#apply_slope_accel)
### Description
Applies acceleration or deceleration based on the slope of the floor. On downward slopes, Mario gains speed, while on upward slopes, Mario loses speed
Applies acceleration or deceleration based on the slope of the floor.
On downward slopes, Mario gains speed, while on upward slopes, Mario loses speed
### Lua Example
`apply_slope_accel(m)`
@ -3616,7 +3681,8 @@ Applies acceleration or deceleration based on the slope of the floor. On downwar
## [apply_landing_accel](#apply_landing_accel)
### Description
Applies friction-like deceleration if the floor is flat, or slope-based acceleration if the floor is sloped. Capped in such a way that Mario eventually stops or stabilizes on flatter ground
Applies friction-like deceleration if the floor is flat, or slope-based acceleration if the floor is sloped.
Capped in such a way that Mario eventually stops or stabilizes on flatter ground
### Lua Example
`local integerValue = apply_landing_accel(m, frictionFactor)`
@ -3663,7 +3729,8 @@ Controls Mario's speed when riding a Koopa Shell on the ground.
## [apply_slope_decel](#apply_slope_decel)
### Description
Approaches Mario's forward velocity toward zero at a rate dependent on the floor's slipperiness. This function can completely stop Mario if the slope is gentle enough or if friction is high
Approaches Mario's forward velocity toward zero at a rate dependent on the floor's slipperiness.
This function can completely stop Mario if the slope is gentle enough or if friction is high
### Lua Example
`local integerValue = apply_slope_decel(m, decelCoef)`
@ -3687,7 +3754,8 @@ Approaches Mario's forward velocity toward zero at a rate dependent on the floor
## [update_decelerating_speed](#update_decelerating_speed)
### Description
Gradually reduces Mario's forward speed to zero over time on level ground, unless otherwise influenced by slope or friction. Returns true if Mario's speed reaches zero, meaning he has stopped
Gradually reduces Mario's forward speed to zero over time on level ground, unless otherwise influenced by slope or friction.
Returns true if Mario's speed reaches zero, meaning he has stopped
### Lua Example
`local integerValue = update_decelerating_speed(m)`
@ -3710,7 +3778,8 @@ Gradually reduces Mario's forward speed to zero over time on level ground, unles
## [update_walking_speed](#update_walking_speed)
### Description
Updates Mario's walking speed based on player input and floor conditions (e.g., a slow floor or quicksand). Caps speed at a certain value and may reduce it slightly on steep slopes
Updates Mario's walking speed based on player input and floor conditions (e.g., a slow floor or quicksand).
Caps speed at a certain value and may reduce it slightly on steep slopes
### Lua Example
`update_walking_speed(m)`
@ -3733,7 +3802,8 @@ Updates Mario's walking speed based on player input and floor conditions (e.g.,
## [should_begin_sliding](#should_begin_sliding)
### Description
Checks if Mario should begin sliding, based on player input (facing downhill, pressing the analog stick backward, or on a slide terrain), and current floor steepness. Returns true if conditions to slide are met.
Checks if Mario should begin sliding, based on player input (facing downhill, pressing the analog stick backward, or on a slide terrain), and current floor steepness.
Returns true if conditions to slide are met.
### Lua Example
`local integerValue = should_begin_sliding(m)`
@ -3756,7 +3826,8 @@ Checks if Mario should begin sliding, based on player input (facing downhill, pr
## [analog_stick_held_back](#analog_stick_held_back)
### Description
Checks if the analog stick is held significantly behind Mario's current facing angle. Returns true if the stick is far enough in the opposite direction, indicating Mario wants to move backward
Checks if the analog stick is held significantly behind Mario's current facing angle.
Returns true if the stick is far enough in the opposite direction, indicating Mario wants to move backward
### Lua Example
`local integerValue = analog_stick_held_back(m)`
@ -3779,7 +3850,8 @@ Checks if the analog stick is held significantly behind Mario's current facing a
## [check_ground_dive_or_punch](#check_ground_dive_or_punch)
### Description
Checks if the B button was pressed to either initiate a dive (if moving fast enough) or a punch (if moving slowly). Returns `true` if the action was changed to either a dive or a punching attack
Checks if the B button was pressed to either initiate a dive (if moving fast enough) or a punch (if moving slowly).
Returns `true` if the action was changed to either a dive or a punching attack
### Lua Example
`local integerValue = check_ground_dive_or_punch(m)`
@ -3802,7 +3874,8 @@ Checks if the B button was pressed to either initiate a dive (if moving fast eno
## [begin_braking_action](#begin_braking_action)
### Description
Begins a braking action if Mario's forward velocity is high enough or transitions to a decelerating action otherwise. Also handles the scenario where Mario is up against a wall, transitioning to a standing state
Begins a braking action if Mario's forward velocity is high enough or transitions to a decelerating action otherwise.
Also handles the scenario where Mario is up against a wall, transitioning to a standing state
### Lua Example
`local integerValue = begin_braking_action(m)`
@ -3825,7 +3898,8 @@ Begins a braking action if Mario's forward velocity is high enough or transition
## [anim_and_audio_for_walk](#anim_and_audio_for_walk)
### Description
Handles the animation and audio (footstep sounds) for normal walking or running. The specific animation used (tiptoe, walk, or run) depends on Mario's current speed
Handles the animation and audio (footstep sounds) for normal walking or running.
The specific animation used (tiptoe, walk, or run) depends on Mario's current speed
### Lua Example
`anim_and_audio_for_walk(m)`
@ -3848,7 +3922,8 @@ Handles the animation and audio (footstep sounds) for normal walking or running.
## [anim_and_audio_for_hold_walk](#anim_and_audio_for_hold_walk)
### Description
Plays the appropriate animation and footstep sounds for walking while carrying a lighter object (like a small box). Adjusts the animation speed dynamically based on Mario's velocity
Plays the appropriate animation and footstep sounds for walking while carrying a lighter object (like a small box).
Adjusts the animation speed dynamically based on Mario's velocity
### Lua Example
`anim_and_audio_for_hold_walk(m)`
@ -3871,7 +3946,8 @@ Plays the appropriate animation and footstep sounds for walking while carrying a
## [anim_and_audio_for_heavy_walk](#anim_and_audio_for_heavy_walk)
### Description
Plays the appropriate animation and footstep sounds for walking while carrying a heavy object. Sets the character animation speed based on Mario's intended movement speed
Plays the appropriate animation and footstep sounds for walking while carrying a heavy object.
Sets the character animation speed based on Mario's intended movement speed
### Lua Example
`anim_and_audio_for_heavy_walk(m)`
@ -3918,7 +3994,8 @@ When Mario hits a wall during movement, decides whether he's pushing against the
## [tilt_body_walking](#tilt_body_walking)
### Description
Applies a left/right tilt to Mario's torso (and some pitch if running fast) while walking or running. The tilt is based on his change in yaw and current speed, giving a leaning appearance when turning
Applies a left/right tilt to Mario's torso (and some pitch if running fast) while walking or running.
The tilt is based on his change in yaw and current speed, giving a leaning appearance when turning
### Lua Example
`tilt_body_walking(m, startYaw)`
@ -3942,7 +4019,8 @@ Applies a left/right tilt to Mario's torso (and some pitch if running fast) whil
## [tilt_body_ground_shell](#tilt_body_ground_shell)
### Description
Tilts Mario's torso and head while riding a shell on the ground to reflect turning. Similar to other tilt functions but tuned for shell-riding speeds and angles
Tilts Mario's torso and head while riding a shell on the ground to reflect turning.
Similar to other tilt functions but tuned for shell-riding speeds and angles
### Lua Example
`tilt_body_ground_shell(m, startYaw)`
@ -3966,7 +4044,8 @@ Tilts Mario's torso and head while riding a shell on the ground to reflect turni
## [tilt_body_butt_slide](#tilt_body_butt_slide)
### Description
Tilts Mario's torso while butt sliding based on analog input direction and magnitude. Gives the appearance that Mario is balancing or leaning into a turn
Tilts Mario's torso while butt sliding based on analog input direction and magnitude.
Gives the appearance that Mario is balancing or leaning into a turn
### Lua Example
`tilt_body_butt_slide(m)`
@ -4015,7 +4094,8 @@ Applies shared logic for sliding-related actions while playing sliding sounds, m
## [common_slide_action_with_jump](#common_slide_action_with_jump)
### Description
Builds on `common_slide_action` by also allowing Mario to jump out of a slide if A is pressed after a short delay. If the sliding slows enough, Mario transitions to a specified stopping action
Builds on `common_slide_action` by also allowing Mario to jump out of a slide if A is pressed after a short delay.
If the sliding slows enough, Mario transitions to a specified stopping action
### Lua Example
`local integerValue = common_slide_action_with_jump(m, stopAction, jumpAction, airAction, animation)`
@ -4042,7 +4122,8 @@ Builds on `common_slide_action` by also allowing Mario to jump out of a slide if
## [stomach_slide_action](#stomach_slide_action)
### Description
Updates Mario's sliding state where he is on his stomach. Similar to other slide actions but has a chance to roll out if A or B is pressed. Uses `common_slide_action` for the core movement logic
Updates Mario's sliding state where he is on his stomach. Similar to other slide actions but has a chance to roll out if A or B is pressed.
Uses `common_slide_action` for the core movement logic
### Lua Example
`local integerValue = stomach_slide_action(m, stopAction, airAction, animation)`
@ -4120,7 +4201,8 @@ Applies movement upon landing from a jump or fall. Adjusts velocity based on slo
## [quicksand_jump_land_action](#quicksand_jump_land_action)
### Description
Handles a special landing in quicksand after a jump. Over several frames, Mario emerges from the quicksand. First part of the animation reduces his quicksand depth. Ends with a normal landing action or transitions back to air if he leaves the ground
Handles a special landing in quicksand after a jump. Over several frames, Mario emerges from the quicksand.
First part of the animation reduces his quicksand depth. Ends with a normal landing action or transitions back to air if he leaves the ground
### Lua Example
`local integerValue = quicksand_jump_land_action(m, animation1, animation2, endAction, airAction)`
@ -4247,7 +4329,9 @@ Updates Mario's punching state
## [check_common_object_cancels](#check_common_object_cancels)
### Description
Checks for and handles common conditions that would cancel Mario's current object action. This includes transitioning to a water plunge if below the water level, becoming squished if appropriate, or switching to standing death action if Mario is dead
Checks for and handles common conditions that would cancel Mario's current object action. This includes transitioning
to a water plunge if below the water level, becoming squished if appropriate, or switching to standing death action
if Mario is dead
### Lua Example
`local integerValue = check_common_object_cancels(m)`
@ -4270,7 +4354,8 @@ Checks for and handles common conditions that would cancel Mario's current objec
## [mario_execute_object_action](#mario_execute_object_action)
### Description
Executes Mario's current object action by first checking common object cancels, then updating quicksand state. Dispatches to the appropriate action function, such as punching, throwing, picking up Bowser, etc
Executes Mario's current object action by first checking common object cancels, then updating quicksand state.
Dispatches to the appropriate action function, such as punching, throwing, picking up Bowser, etc
### Lua Example
`local integerValue = mario_execute_object_action(m)`
@ -4489,7 +4574,8 @@ Checks for and handles common conditions that would cancel Mario's current stati
## [mario_execute_stationary_action](#mario_execute_stationary_action)
### Description
Executes Mario's current object action by first checking common stationary cancels, then updating quicksand state. Dispatches to the appropriate action function, such as idle, sleeping, crouching, ect
Executes Mario's current object action by first checking common stationary cancels, then updating quicksand state.
Dispatches to the appropriate action function, such as idle, sleeping, crouching, ect
### Lua Example
`local integerValue = mario_execute_stationary_action(m)`
@ -4636,7 +4722,8 @@ Controls the bobbing that happens when you swim near the water surface
## [mario_execute_submerged_action](#mario_execute_submerged_action)
### Description
Executes Mario's current submerged action by first checking common submerged cancels, then setting quicksand depth and head angles to 0. Dispatches to the appropriate action function, such as breaststroke, flutterkick, water punch, ect
Executes Mario's current submerged action by first checking common submerged cancels, then setting quicksand depth and head angles to 0.
Dispatches to the appropriate action function, such as breaststroke, flutterkick, water punch, ect
### Lua Example
`local integerValue = mario_execute_submerged_action(m)`
@ -5914,7 +6001,8 @@ Converts an angle from degrees to SM64 format
## [mtxf_zero](#mtxf_zero)
### Description
Sets the 4x4 floating-point matrix `mtx` to all zeros. Unless you really need this-It's reccomended to use mtxf_identity instead.
Sets the 4x4 floating-point matrix `mtx` to all zeros.
Unless you really need this-It's reccomended to use mtxf_identity instead.
### Lua Example
`mtxf_zero(mtx)`

View file

@ -1952,7 +1952,11 @@ Writes a line to a text modfs `file`. Returns true on success
## [mod_fs_file_seek](#mod_fs_file_seek)
### Description
Sets the current position of a modfs `file`. If `origin` is `FILE_SEEK_SET`, file position is set to `offset`. If `origin` is `FILE_SEEK_CUR`, `offset` is added to file current position. If `origin` is `FILE_SEEK_END`, file position is set to `end of file + offset`. Returns true on success
Sets the current position of a modfs `file`.
If `origin` is `FILE_SEEK_SET`, file position is set to `offset`.
If `origin` is `FILE_SEEK_CUR`, `offset` is added to file current position.
If `origin` is `FILE_SEEK_END`, file position is set to `end of file + offset`.
Returns true on success
### Lua Example
`local booleanValue = mod_fs_file_seek(file, offset, origin)`
@ -1977,7 +1981,8 @@ Sets the current position of a modfs `file`. If `origin` is `FILE_SEEK_SET`, fil
## [mod_fs_file_rewind](#mod_fs_file_rewind)
### Description
Sets the current position of a modfs `file` to its beginning. Returns true on success
Sets the current position of a modfs `file` to its beginning.
Returns true on success
### Lua Example
`local booleanValue = mod_fs_file_rewind(file)`
@ -3126,7 +3131,8 @@ Generates splashes if at surface of water, entering water, or bubbles if underwa
## [object_step](#object_step)
### Description
Generic object move function. Handles walls, water, floors, and gravity. Returns flags for certain interactions
Generic object move function. Handles walls, water, floors, and gravity.
Returns flags for certain interactions
### Lua Example
`local integerValue = object_step()`
@ -3147,7 +3153,8 @@ Generic object move function. Handles walls, water, floors, and gravity. Returns
## [object_step_without_floor_orient](#object_step_without_floor_orient)
### Description
Takes an object step but does not orient with the object's floor. Used for boulders, falling pillars, and the rolling snowman body
Takes an object step but does not orient with the object's floor.
Used for boulders, falling pillars, and the rolling snowman body
### Lua Example
`local integerValue = object_step_without_floor_orient()`
@ -3168,7 +3175,8 @@ Takes an object step but does not orient with the object's floor. Used for bould
## [obj_move_xyz_using_fvel_and_yaw](#obj_move_xyz_using_fvel_and_yaw)
### Description
Don't use this function outside of of a context where the current object and `obj` are the same. Moves `obj` based on a seemingly random mix of using either the current obj or `obj`'s fields
Don't use this function outside of of a context where the current object and `obj` are the same.
Moves `obj` based on a seemingly random mix of using either the current obj or `obj`'s fields
### Lua Example
`obj_move_xyz_using_fvel_and_yaw(obj)`
@ -3578,7 +3586,8 @@ Randomly displaces an objects home if RNG says to, and turns the object towards
## [obj_check_if_facing_toward_angle](#obj_check_if_facing_toward_angle)
### Description
A series of checks using sin and cos to see if a given angle is facing in the same direction of a given angle, within a certain range
A series of checks using sin and cos to see if a given angle is facing in the same direction
of a given angle, within a certain range
### Lua Example
`local integerValue = obj_check_if_facing_toward_angle(base, goal, range)`
@ -3701,7 +3710,8 @@ Checks if a given room is Mario's current room, even if on an object
## [obj_check_floor_death](#obj_check_floor_death)
### Description
Checks if `floor`'s type is burning or death plane and if so change the current object's action accordingly
Checks if `floor`'s type is burning or death plane and if so change the
current object's action accordingly
### Lua Example
`obj_check_floor_death(collisionFlags, floor)`
@ -3725,7 +3735,8 @@ Checks if `floor`'s type is burning or death plane and if so change the current
## [obj_lava_death](#obj_lava_death)
### Description
Controls an object dying in lava by creating smoke, sinking the object, playing audio, and eventually despawning it. Returns TRUE when the obj is dead
Controls an object dying in lava by creating smoke, sinking the object, playing
audio, and eventually despawning it. Returns TRUE when the obj is dead
### Lua Example
`local integerValue = obj_lava_death()`
@ -4426,7 +4437,10 @@ 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, scaleVel = obj_grow_then_shrink(scaleVel, shootFireScale, endScale)`

View file

@ -777,7 +777,12 @@ Overrides the current room Mario is in. Set to -1 to reset override
## [linear_mtxf_mul_vec3f](#linear_mtxf_mul_vec3f)
### Description
Multiplies a vector by a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ? ? 0 |` `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space
Multiplies a vector by a matrix of the form:
`| ? ? ? 0 |`
`| ? ? ? 0 |`
`| ? ? ? 0 |`
`| 0 0 0 1 |`
i.e. a matrix representing a linear transformation over 3 space
### Lua Example
`linear_mtxf_mul_vec3f(m, dst, v)`
@ -802,7 +807,12 @@ Multiplies a vector by a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ?
## [linear_mtxf_transpose_mul_vec3f](#linear_mtxf_transpose_mul_vec3f)
### Description
Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ? ? 0 |` `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space
Multiplies a vector by the transpose of a matrix of the form:
`| ? ? ? 0 |`
`| ? ? ? 0 |`
`| ? ? ? 0 |`
`| 0 0 0 1 |`
i.e. a matrix representing a linear transformation over 3 space
### Lua Example
`linear_mtxf_transpose_mul_vec3f(m, dst, v)`
@ -4615,7 +4625,9 @@ Apply one frame of platform rotation to the object using the given platform
## [preset_palette_allocate](#preset_palette_allocate)
### Description
Allocates a preset palette that can be shown in the player customization screen. This returns a `PresetPalette` that can be used to customize the palette. Customization functions include `preset_palette_set_name` and `preset_palette_set_color_of_part`.
Allocates a preset palette that can be shown in the player customization screen.
This returns a `PresetPalette` that can be used to customize the palette.
Customization functions include `preset_palette_set_name` and `preset_palette_set_color_of_part`.
### Lua Example
`local presetPaletteValue = preset_palette_allocate(name)`
@ -4868,7 +4880,8 @@ Gets the level number's corresponding course number
## [touch_coin_score_age](#touch_coin_score_age)
### Description
Marks the coin score for a specific course as the newest among all save files. Adjusts the age of other scores to reflect the update. Useful for leaderboard tracking or displaying recent progress
Marks the coin score for a specific course as the newest among all save files. Adjusts the age of other scores to reflect the update.
Useful for leaderboard tracking or displaying recent progress
### Lua Example
`touch_coin_score_age(fileIndex, courseIndex)`
@ -4892,7 +4905,8 @@ Marks the coin score for a specific course as the newest among all save files. A
## [save_file_do_save](#save_file_do_save)
### Description
Saves the current state of the game into a specified save file. Includes data verification and backup management. Useful for maintaining game progress during play or when saving manually
Saves the current state of the game into a specified save file. Includes data verification and backup management.
Useful for maintaining game progress during play or when saving manually
### Lua Example
`save_file_do_save(fileIndex, forceSave)`
@ -4916,7 +4930,8 @@ Saves the current state of the game into a specified save file. Includes data ve
## [save_file_erase](#save_file_erase)
### Description
Erases all data in a specified save file, including backup slots. Marks the save file as modified and performs a save to apply the changes. Useful for resetting a save file to its default state
Erases all data in a specified save file, including backup slots. Marks the save file as modified and performs a save to apply the changes.
Useful for resetting a save file to its default state
### Lua Example
`save_file_erase(fileIndex)`
@ -4960,7 +4975,8 @@ Erases the backup data for the current save file without affecting the primary s
## [save_file_reload](#save_file_reload)
### Description
Reloads the save file data into memory, optionally resetting all save files. Marks the save file as modified. Useful for reloading state after data corruption or during development debugging
Reloads the save file data into memory, optionally resetting all save files. Marks the save file as modified.
Useful for reloading state after data corruption or during development debugging
### Lua Example
`save_file_reload(load_all)`
@ -4983,7 +4999,8 @@ Reloads the save file data into memory, optionally resetting all save files. Mar
## [save_file_get_max_coin_score](#save_file_get_max_coin_score)
### Description
Determines the maximum coin score for a course across all save files. Returns the score along with the file index of the save containing it. Useful for leaderboard-style comparisons and overall progress tracking
Determines the maximum coin score for a course across all save files. Returns the score along with the file index of the save containing it.
Useful for leaderboard-style comparisons and overall progress tracking
### Lua Example
`local integerValue = save_file_get_max_coin_score(courseIndex)`
@ -5006,7 +5023,8 @@ Determines the maximum coin score for a course across all save files. Returns th
## [save_file_get_course_star_count](#save_file_get_course_star_count)
### Description
Calculates the total number of stars collected in a specific course for a given save file. Useful for determining completion status of individual levels
Calculates the total number of stars collected in a specific course for a given save file.
Useful for determining completion status of individual levels
### Lua Example
`local integerValue = save_file_get_course_star_count(fileIndex, courseIndex)`
@ -5030,7 +5048,8 @@ Calculates the total number of stars collected in a specific course for a given
## [save_file_get_total_star_count](#save_file_get_total_star_count)
### Description
Calculates the total number of stars collected across multiple courses within a specified range. Useful for determining the overall progress toward game completion
Calculates the total number of stars collected across multiple courses within a specified range.
Useful for determining the overall progress toward game completion
### Lua Example
`local integerValue = save_file_get_total_star_count(fileIndex, minCourse, maxCourse)`
@ -5055,7 +5074,8 @@ Calculates the total number of stars collected across multiple courses within a
## [save_file_set_flags](#save_file_set_flags)
### Description
Adds new flags to the save file's flag bitmask. Useful for updating progress or triggering new gameplay features
Adds new flags to the save file's flag bitmask.
Useful for updating progress or triggering new gameplay features
### Lua Example
`save_file_set_flags(flags)`
@ -5078,7 +5098,8 @@ Adds new flags to the save file's flag bitmask. Useful for updating progress or
## [save_file_clear_flags](#save_file_clear_flags)
### Description
Clears specific flags in the current save file. The flags are specified as a bitmask in the `flags` parameter. Ensures that the save file remains valid after clearing. Useful for removing specific game states, such as collected items or completed objectives, without resetting the entire save
Clears specific flags in the current save file. The flags are specified as a bitmask in the `flags` parameter. Ensures that the save file remains valid after clearing.
Useful for removing specific game states, such as collected items or completed objectives, without resetting the entire save
### Lua Example
`save_file_clear_flags(flags)`
@ -5101,7 +5122,8 @@ Clears specific flags in the current save file. The flags are specified as a bit
## [save_file_get_flags](#save_file_get_flags)
### Description
Retrieves the bitmask of flags representing the current state of the save file. Flags indicate collected items, completed objectives, and other game states. Useful for checking specific game progress details
Retrieves the bitmask of flags representing the current state of the save file. Flags indicate collected items, completed objectives, and other game states.
Useful for checking specific game progress details
### Lua Example
`local integerValue = save_file_get_flags()`
@ -5122,7 +5144,8 @@ Retrieves the bitmask of flags representing the current state of the save file.
## [save_file_get_star_flags](#save_file_get_star_flags)
### Description
Retrieves the bitmask of stars collected in a specific course or castle secret stars (-1). Useful for evaluating level progress and completion
Retrieves the bitmask of stars collected in a specific course or castle secret stars (-1).
Useful for evaluating level progress and completion
### Lua Example
`local integerValue = save_file_get_star_flags(fileIndex, courseIndex)`
@ -5146,7 +5169,8 @@ Retrieves the bitmask of stars collected in a specific course or castle secret s
## [save_file_set_star_flags](#save_file_set_star_flags)
### Description
Adds specific star flags to the save file, indicating collected stars for a course or castle secret stars. Updates the save file flags as necessary. Useful for recording progress after star collection
Adds specific star flags to the save file, indicating collected stars for a course or castle secret stars. Updates the save file flags as necessary.
Useful for recording progress after star collection
### Lua Example
`save_file_set_star_flags(fileIndex, courseIndex, starFlags)`
@ -5171,7 +5195,8 @@ Adds specific star flags to the save file, indicating collected stars for a cour
## [save_file_remove_star_flags](#save_file_remove_star_flags)
### Description
Removes specific star flags from the save file. This modifies the bitmask representing collected stars for a course or castle secret stars. Useful for undoing progress or debugging collected stars
Removes specific star flags from the save file. This modifies the bitmask representing collected stars for a course or castle secret stars.
Useful for undoing progress or debugging collected stars
### Lua Example
`save_file_remove_star_flags(fileIndex, courseIndex, starFlagsToRemove)`
@ -5196,7 +5221,8 @@ Removes specific star flags from the save file. This modifies the bitmask repres
## [save_file_get_course_coin_score](#save_file_get_course_coin_score)
### Description
Returns the highest coin score for a specified course in the save file. Performs checks to ensure the coin score is valid. Useful for tracking player achievements and high scores
Returns the highest coin score for a specified course in the save file. Performs checks to ensure the coin score is valid.
Useful for tracking player achievements and high scores
### Lua Example
`local integerValue = save_file_get_course_coin_score(fileIndex, courseIndex)`
@ -5220,7 +5246,8 @@ Returns the highest coin score for a specified course in the save file. Performs
## [save_file_set_course_coin_score](#save_file_set_course_coin_score)
### Description
Updates the coin score for a specific course in the save file. The new score is provided in the `coinScore` parameter. Useful for manually setting achievements such as high coin counts in individual levels
Updates the coin score for a specific course in the save file. The new score is provided in the `coinScore` parameter.
Useful for manually setting achievements such as high coin counts in individual levels
### Lua Example
`save_file_set_course_coin_score(fileIndex, courseIndex, coinScore)`
@ -5245,7 +5272,8 @@ Updates the coin score for a specific course in the save file. The new score is
## [save_file_is_cannon_unlocked](#save_file_is_cannon_unlocked)
### Description
Checks whether the cannon in the specified course is unlocked. Returns true if the cannon is unlocked, otherwise false. Useful for tracking course-specific progress and enabling shortcuts
Checks whether the cannon in the specified course is unlocked. Returns true if the cannon is unlocked, otherwise false.
Useful for tracking course-specific progress and enabling shortcuts
### Lua Example
`local integerValue = save_file_is_cannon_unlocked(fileIndex, courseIndex)`
@ -5290,7 +5318,8 @@ Unlocks the cannon in the current course
## [save_file_get_cap_pos](#save_file_get_cap_pos)
### Description
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
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
### Lua Example
`local integerValue = save_file_get_cap_pos(capPos)`
@ -5313,7 +5342,8 @@ Retrieves the current position of Mario's cap, if it is on the ground in the cur
## [save_file_get_sound_mode](#save_file_get_sound_mode)
### Description
Returns the current sound mode (e.g., stereo, mono) stored in the save file. Useful for checking the audio output preferences when loading a save
Returns the current sound mode (e.g., stereo, mono) stored in the save file.
Useful for checking the audio output preferences when loading a save
### Lua Example
`local integerValue = save_file_get_sound_mode()`
@ -6516,7 +6546,8 @@ Sets if the romhack camera should allow D-Pad movement
## [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
Toggles collision settings for the ROM hack camera.
This enables or disables specific collision behaviors in modded levels
### Lua Example
`camera_romhack_set_collisions(enable)`
@ -7649,7 +7680,9 @@ Gets a table of the surface types from `data`
## [smlua_collision_add_surface](#smlua_collision_add_surface)
### Description
Allocates a new collision surface with the given vertices, computes the surface normal and other fields, and inserts it into the spatial partition. Returns the new surface, or `nil` if the triangle is degenerate (zero area). Set `dynamic` to `true` for surfaces that are cleared each frame, or `false` for persistent static surfaces
Allocates a new collision surface with the given vertices, computes the surface normal and other fields, and inserts it into the spatial partition.
Returns the new surface, or `nil` if the triangle is degenerate (zero area).
Set `dynamic` to `true` for surfaces that are cleared each frame, or `false` for persistent static surfaces
### Lua Example
`local surfaceValue = smlua_collision_add_surface(dynamic, surfaceType, vertex1, vertex2, vertex3)`
@ -7676,7 +7709,9 @@ Allocates a new collision surface with the given vertices, computes the surface
## [smlua_collision_move_surface](#smlua_collision_move_surface)
### Description
Moves an existing collision surface to new vertex positions. Recalculates the surface normal, origin offset, and Y bounds, removes the surface from its old spatial partition cells, and re-adds it to the correct cells. The previous vertices are preserved for interpolation
Moves an existing collision surface to new vertex positions.
Recalculates the surface normal, origin offset, and Y bounds, removes the surface from its old spatial partition cells, and re-adds it to the correct cells.
The previous vertices are preserved for interpolation
### Lua Example
`smlua_collision_move_surface(surface, vertex1, vertex2, vertex3)`

View file

@ -11,6 +11,165 @@
<br />
## [get_shader_flag_enabled](#get_shader_flag_enabled)
### Description
Gets if a custom shader flag (`SHADER_FLAG_*`) is enabled or not
### Lua Example
`local booleanValue = get_shader_flag_enabled(flag)`
### Parameters
| Field | Type |
| ----- | ---- |
| flag | [enum ShaderFlag](constants.md#enum-ShaderFlag) |
### Returns
- `boolean`
### C Prototype
`bool get_shader_flag_enabled(enum ShaderFlag flag);`
[:arrow_up_small:](#)
<br />
## [set_shader_flag_enabled](#set_shader_flag_enabled)
### Description
Enables a custom shader flag (`SHADER_FLAG_*`) for the renderer
### Lua Example
`set_shader_flag_enabled(flag, enabled)`
### Parameters
| Field | Type |
| ----- | ---- |
| flag | [enum ShaderFlag](constants.md#enum-ShaderFlag) |
| enabled | `boolean` |
### Returns
- None
### C Prototype
`void set_shader_flag_enabled(enum ShaderFlag flag, bool enabled);`
[:arrow_up_small:](#)
<br />
## [get_shader_flag_value](#get_shader_flag_value)
### Description
Gets a value for one of the custom shader flags (`SHADER_FLAG_*`)
### Lua Example
`local numberValue = get_shader_flag_value(flag)`
### Parameters
| Field | Type |
| ----- | ---- |
| flag | [enum ShaderFlag](constants.md#enum-ShaderFlag) |
### Returns
- `number`
### C Prototype
`f32 get_shader_flag_value(enum ShaderFlag flag);`
[:arrow_up_small:](#)
<br />
## [set_shader_flag_value](#set_shader_flag_value)
### Description
Sets a value for one of the custom shader flags (`SHADER_FLAG_*`) for the renderer
### Lua Example
`set_shader_flag_value(flag, value)`
### Parameters
| Field | Type |
| ----- | ---- |
| flag | [enum ShaderFlag](constants.md#enum-ShaderFlag) |
| value | `number` |
### Returns
- None
### C Prototype
`void set_shader_flag_value(enum ShaderFlag flag, f32 value);`
[:arrow_up_small:](#)
<br />
## [get_global_shader_flags_enabled](#get_global_shader_flags_enabled)
### Description
Gets if custom shader flags are enabled globally
### Lua Example
`local booleanValue = get_global_shader_flags_enabled()`
### Parameters
- None
### Returns
- `boolean`
### C Prototype
`bool get_global_shader_flags_enabled(void);`
[:arrow_up_small:](#)
<br />
## [set_global_shader_flags_enabled](#set_global_shader_flags_enabled)
### Description
Enables custom shader flags as a global toggle, useful for disabling without manually going through every effect
### Lua Example
`set_global_shader_flags_enabled(enabled)`
### Parameters
| Field | Type |
| ----- | ---- |
| enabled | `boolean` |
### Returns
- None
### C Prototype
`void set_global_shader_flags_enabled(bool enabled);`
[:arrow_up_small:](#)
<br />
## [clear_all_shader_flags](#clear_all_shader_flags)
### Description
Clears all custom shader flags (`SHADER_FLAG_*`) for the renderer
### Lua Example
`clear_all_shader_flags()`
### Parameters
- None
### Returns
- None
### C Prototype
`void clear_all_shader_flags(void);`
[:arrow_up_small:](#)
<br />
## [set_override_fov](#set_override_fov)
### Description
@ -592,7 +751,8 @@ 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
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)`
@ -826,7 +986,8 @@ 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
Gets a vertex buffer of the current mod from its name.
Returns a pointer to the vertex buffer and its vertex count
### Lua Example
`local pointerValue, count = vtx_get_from_name(name)`
@ -2374,7 +2535,8 @@ Allocates an action ID with bitwise flags
## [get_hand_foot_pos_x](#get_hand_foot_pos_x)
### Description
Gets the X coordinate of Mario's hand (0-1) or foot (2-3) but it is important to note that the positions are not updated off-screen
Gets the X coordinate of Mario's hand (0-1) or foot (2-3)
but it is important to note that the positions are not updated off-screen
### Lua Example
`local numberValue = get_hand_foot_pos_x(m, index)`
@ -2398,7 +2560,8 @@ Gets the X coordinate of Mario's hand (0-1) or foot (2-3) but it is important to
## [get_hand_foot_pos_y](#get_hand_foot_pos_y)
### Description
Gets the Y coordinate of Mario's hand (0-1) or foot (2-3) but It is important to note that the positions are not updated off-screen
Gets the Y coordinate of Mario's hand (0-1) or foot (2-3)
but It is important to note that the positions are not updated off-screen
### Lua Example
`local numberValue = get_hand_foot_pos_y(m, index)`
@ -2422,7 +2585,8 @@ Gets the Y coordinate of Mario's hand (0-1) or foot (2-3) but It is important to
## [get_hand_foot_pos_z](#get_hand_foot_pos_z)
### Description
Gets the Z coordinate of Mario's hand (0-1) or foot (2-3) but it is important to note that the positions are not updated off-screen
Gets the Z coordinate of Mario's hand (0-1) or foot (2-3)
but it is important to note that the positions are not updated off-screen
### Lua Example
`local numberValue = get_hand_foot_pos_z(m, index)`
@ -3461,7 +3625,8 @@ Gets the extended model ID for the `name` of a `GeoLayout`
## [spawn_sync_object](#spawn_sync_object)
### Description
Spawns a synchronized object at `x`, `y`, and `z` as a child object of the local Mario with his rotation. You can change the fields of the object in `objSetupFunction`
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)`
@ -3489,7 +3654,8 @@ Spawns a synchronized object at `x`, `y`, and `z` as a child object of the local
## [spawn_non_sync_object](#spawn_non_sync_object)
### Description
Spawns a non-synchronized object at `x`, `y`, and `z` as a child object of the local Mario with his rotation. You can change the fields of the object in `objSetupFunction`
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)`
@ -3832,7 +3998,8 @@ Gets the first object loaded with `behaviorId`
## [obj_get_first_with_behavior_id_and_field_s32](#obj_get_first_with_behavior_id_and_field_s32)
### Description
Gets the first object loaded with `behaviorId` and object signed 32-bit integer field (look in `object_fields.h` to get the index of a field)
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)`
@ -3857,7 +4024,8 @@ Gets the first object loaded with `behaviorId` and object signed 32-bit integer
## [obj_get_first_with_behavior_id_and_field_f32](#obj_get_first_with_behavior_id_and_field_f32)
### Description
Gets the first object loaded with `behaviorId` and object float field (look in `object_fields.h` to get the index of a field)
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)`
@ -3928,7 +4096,8 @@ Gets the next object loaded with the same behavior ID
## [obj_get_next_with_same_behavior_id_and_field_s32](#obj_get_next_with_same_behavior_id_and_field_s32)
### Description
Gets the next object loaded with the same behavior ID and object signed 32-bit integer field (look in `object_fields.h` to get the index of a field)
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)`
@ -3953,7 +4122,8 @@ Gets the next object loaded with the same behavior ID and object signed 32-bit i
## [obj_get_next_with_same_behavior_id_and_field_f32](#obj_get_next_with_same_behavior_id_and_field_f32)
### Description
Gets the next object loaded with the same behavior ID and object float field (look in `object_fields.h` to get the index of a field)
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)`
@ -5723,7 +5893,8 @@ Plays a sound if the current object is visible and queues rumble for specific so
## [create_sound_spawner](#create_sound_spawner)
### Description
Create a sound spawner for objects that need a sound play once. (Breakable walls, King Bobomb exploding, etc)
Create a sound spawner for objects that need a sound play once.
(Breakable walls, King Bobomb exploding, etc)
### Lua Example
`create_sound_spawner(soundMagic)`
@ -5746,7 +5917,9 @@ Create a sound spawner for objects that need a sound play once. (Breakable walls
## [calc_dist_to_volume_range_1](#calc_dist_to_volume_range_1)
### Description
Unused vanilla function, calculates a volume based on `distance`. If `distance` is less than 500 then 127, if `distance` is greater than 1500 then 0, if `distance` is between 500 and 1500 then it ranges linearly from 60 to 124. What an even more strange and confusing function
Unused vanilla function, calculates a volume based on `distance`.
If `distance` is less than 500 then 127, if `distance` is greater than 1500 then 0, if `distance` is between 500 and 1500 then it ranges linearly from 60 to 124.
What an even more strange and confusing function
### Lua Example
`local integerValue = calc_dist_to_volume_range_1(distance)`
@ -5769,7 +5942,9 @@ Unused vanilla function, calculates a volume based on `distance`. If `distance`
## [calc_dist_to_volume_range_2](#calc_dist_to_volume_range_2)
### Description
Unused vanilla function, calculates a volume based on `distance`. If `distance` is less than 1300 then 127, if `distance` is greater than 2300 then 0, if `distance` is between 1300 and 2300 then it ranges linearly from 60 to 127. What a strange and confusing function
Unused vanilla function, calculates a volume based on `distance`.
If `distance` is less than 1300 then 127, if `distance` is greater than 2300 then 0, if `distance` is between 1300 and 2300 then it ranges linearly from 60 to 127.
What a strange and confusing function
### Lua Example
`local integerValue = calc_dist_to_volume_range_2(distance)`
@ -5798,7 +5973,8 @@ Unused vanilla function, calculates a volume based on `distance`. If `distance`
## [find_wall_collisions](#find_wall_collisions)
### Description
Detects wall collisions at a given position and adjusts the position based on the walls found. Returns the number of wall collisions detected
Detects wall collisions at a given position and adjusts the position based on the walls found.
Returns the number of wall collisions detected
### Lua Example
`local integerValue = find_wall_collisions(colData)`
@ -5821,7 +5997,8 @@ 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)
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)`
@ -5847,7 +6024,8 @@ Finds the height of the highest ceiling above a given position (x, y, z) and ret
## [find_ceil_height](#find_ceil_height)
### Description
Finds the height of the highest ceiling above a given position (x, y, z). If no ceiling is found, returns the default height limit of `gLevelValues.cellHeightLimit`(20000 by default)
Finds the height of the highest ceiling above a given position (x, y, z).
If no ceiling is found, returns the default height limit of `gLevelValues.cellHeightLimit`(20000 by default)
### Lua Example
`local numberValue = find_ceil_height(x, y, z)`
@ -5872,7 +6050,8 @@ Finds the height of the highest ceiling above a given position (x, y, z). If no
## [find_floor_height](#find_floor_height)
### Description
Finds the height of the highest floor below a given position (x, y, z). If no floor is found, returns the default floor height of `gLevelValues.floorLowerLimit`(-11000 by default)
Finds the height of the highest floor below a given position (x, y, z).
If no floor is found, returns the default floor height of `gLevelValues.floorLowerLimit`(-11000 by default)
### Lua Example
`local numberValue = find_floor_height(x, y, z)`
@ -5897,7 +6076,8 @@ 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)
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)`
@ -5923,7 +6103,8 @@ Finds the height of the highest floor below a given position (x, y, z) and retur
## [find_water_level](#find_water_level)
### Description
Finds the height of water at a given position (x, z), if the position is within a water region. If no water is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default)
Finds the height of water at a given position (x, z), if the position is within a water region.
If no water is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default)
### Lua Example
`local numberValue = find_water_level(x, z)`
@ -5947,7 +6128,8 @@ Finds the height of water at a given position (x, z), if the position is within
## [find_poison_gas_level](#find_poison_gas_level)
### Description
Finds the height of the poison gas at a given position (x, z), if the position is within a gas region. If no gas is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default)
Finds the height of the poison gas at a given position (x, z), if the position is within a gas region.
If no gas is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default)
### Lua Example
`local numberValue = find_poison_gas_level(x, z)`
@ -6027,7 +6209,8 @@ Gets the closest point of the triangle to `src` and returns it in `out`.
## [load_object_collision_model](#load_object_collision_model)
### Description
Loads the object's collision data into dynamic collision. You must run this every frame in your object's behavior loop for it to have collision
Loads the object's collision data into dynamic collision.
You must run this every frame in your object's behavior loop for it to have collision
### Lua Example
`load_object_collision_model()`
@ -6048,7 +6231,8 @@ Loads the object's collision data into dynamic collision. You must run this ever
## [load_static_object_collision](#load_static_object_collision)
### Description
Loads the object's collision data into static collision. You may run this only once to capture the object's collision at that frame.
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()`

View file

@ -623,6 +623,7 @@
- [obj_update_gfx_pos_and_angle](functions-3.md#obj_update_gfx_pos_and_angle)
- [position_based_random_u16](functions-3.md#position_based_random_u16)
- [position_based_random_float_position](functions-3.md#position_based_random_float_position)
- [draw_distance_scalar_is_infinite](functions-3.md#draw_distance_scalar_is_infinite)
- [draw_distance_scalar](functions-3.md#draw_distance_scalar)
<br />
@ -1966,6 +1967,13 @@
<br />
- smlua_gfx_utils.h
- [get_shader_flag_enabled](functions-7.md#get_shader_flag_enabled)
- [set_shader_flag_enabled](functions-7.md#set_shader_flag_enabled)
- [get_shader_flag_value](functions-7.md#get_shader_flag_value)
- [set_shader_flag_value](functions-7.md#set_shader_flag_value)
- [get_global_shader_flags_enabled](functions-7.md#get_global_shader_flags_enabled)
- [set_global_shader_flags_enabled](functions-7.md#set_global_shader_flags_enabled)
- [clear_all_shader_flags](functions-7.md#clear_all_shader_flags)
- [set_override_fov](functions-7.md#set_override_fov)
- [set_override_near](functions-7.md#set_override_near)
- [set_override_far](functions-7.md#set_override_far)
@ -2858,7 +2866,8 @@ Derives a `MARIO_SPAWN_*` constant from `o`
## [area_get_warp_node](#area_get_warp_node)
### Description
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
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)`
@ -2902,7 +2911,8 @@ Gets the first warp node found in the area, otherwise returns nil
## [area_get_warp_node_from_params](#area_get_warp_node_from_params)
### Description
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
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)`

View file

@ -780,6 +780,7 @@
| Field | Type | Access |
| ----- | ---- | ------ |
| textColor | [DjuiColor](structs.md#DjuiColor) | read-only |
| disabledTextColor | [DjuiColor](structs.md#DjuiColor) | read-only |
| defaultRectColor | [DjuiColor](structs.md#DjuiColor) | read-only |
| cursorDownRectColor | [DjuiColor](structs.md#DjuiColor) | read-only |
| hoveredRectColor | [DjuiColor](structs.md#DjuiColor) | read-only |

View file

@ -64,6 +64,7 @@ BACK = "Zpět"
CANCEL = "Zrušit"
NO = "Ne"
YES = "Ano"
SEARCH = "Hledat..."
[CAMERA]
CAMERA = "KAMERA"
@ -167,6 +168,7 @@ D1P5X = "1.5x"
D3X = "3x"
D10X = "10x"
D100X = "100x"
INFINITE = "Nekonečno"
DRAW_DISTANCE = "Vzdálenost vykreslování"
DYNOS_PACKS = "DynOS packy"
ANTIALIASING = "Anti-aliasing"
@ -415,6 +417,10 @@ SFX_VOLUME = "Hlasitost zvuků"
ENV_VOLUME = "Hlasitost prostředí"
FADEOUT = "Ztišit daleké zvuky"
MUTE_FOCUS_LOSS = "Ztlumit, když je okno na pozadí"
SOUND_OUTPUT = "Výstup zvuku"
STEREO = "Stereo"
MONO = "Mono"
HEADSET = "Sluchátka"
[LANGUAGE]
LANGUAGE = "JAZYK"
@ -440,3 +446,7 @@ NO_LOBBIES_FOUND = "Nebyly nalezeny žádné hry."
[CHANGELOG]
CHANGELOG_TITLE = "ZÁZNAM ZMĚN"
[UPDATE]
UPDATE_TITLE = "AKTUALIZACE"
UPDATE_AVAILABLE = "Je k dispozici aktualizace. Chcete ji nainstalovat?"

View file

@ -64,6 +64,7 @@ BACK = "Terug"
CANCEL = "Stop"
NO = "Nee"
YES = "Ja"
SEARCH = "Zoek..."
[CAMERA]
CAMERA = "CAMERA"
@ -167,6 +168,7 @@ D1P5X = "1.5x"
D3X = "3x"
D10X = "10x"
D100X = "100x"
INFINITE = "Oneindig"
DRAW_DISTANCE = "Teken afstand"
DYNOS_PACKS = "DynOS Packs"
ANTIALIASING = "Anti-aliasing"
@ -415,6 +417,10 @@ SFX_VOLUME = "Sfx Geluid"
ENV_VOLUME = "Env Geluid"
FADEOUT = "Vervaagd Geluid in de Verte"
MUTE_FOCUS_LOSS = "Dempen wanneer venster niet meer scherp is"
SOUND_OUTPUT = "Geluidsuitvoer"
STEREO = "Stereo"
MONO = "Mono"
HEADSET = "Hoofdtelefoon"
[LANGUAGE]
LANGUAGE = "TAAL"
@ -440,3 +446,7 @@ NO_LOBBIES_FOUND = "Er zijn geen lobby's gevonden."
[CHANGELOG]
CHANGELOG_TITLE = "WIJZIGINGENLOGBOEK"
[UPDATE]
UPDATE_TITLE = "UPDATE"
UPDATE_AVAILABLE = "Een update is beschikbaar. Wilt u deze installeren?"

View file

@ -64,6 +64,7 @@ BACK = "Back"
CANCEL = "Cancel"
NO = "No"
YES = "Yes"
SEARCH = "Search..."
[CAMERA]
CAMERA = "CAMERA"
@ -167,6 +168,7 @@ D1P5X = "1.5x"
D3X = "3x"
D10X = "10x"
D100X = "100x"
INFINITE = "Infinite"
DRAW_DISTANCE = "Draw Distance"
DYNOS_PACKS = "DynOS Packs"
ANTIALIASING = "Anti-aliasing"
@ -415,6 +417,10 @@ SFX_VOLUME = "Sound Effects Volume"
ENV_VOLUME = "Environment Volume"
FADEOUT = "Fade Out Distant Sounds"
MUTE_FOCUS_LOSS = "Mute When Window Unfocused"
SOUND_OUTPUT = "Sound Output"
STEREO = "Stereo"
MONO = "Mono"
HEADSET = "Headset"
[LANGUAGE]
LANGUAGE = "LANGUAGE"
@ -440,3 +446,7 @@ NO_LOBBIES_FOUND = "No lobbies were found."
[CHANGELOG]
CHANGELOG_TITLE = "CHANGELOG"
[UPDATE]
UPDATE_TITLE = "UPDATE"
UPDATE_AVAILABLE = "An update is available. Would you like to install it?"

View file

@ -64,6 +64,7 @@ BACK = "Retour"
CANCEL = "Annuler"
NO = "Non"
YES = "Oui"
SEARCH = "Rechercher..."
[CAMERA]
CAMERA = "CAMÉRA"
@ -167,6 +168,7 @@ D1P5X = "x1.5"
D3X = "x3"
D10X = "x10"
D100X = "x100"
INFINITE = "Infini"
DRAW_DISTANCE = "Distance d'affichage"
DYNOS_PACKS = "Packs DynOS"
ANTIALIASING = "Anti-aliasing"
@ -415,6 +417,10 @@ SFX_VOLUME = "Volume des effets sonores"
ENV_VOLUME = "Volume de l'environnement"
FADEOUT = "Disparition des sons distants"
MUTE_FOCUS_LOSS = "Muet en arrière plan"
SOUND_OUTPUT = "Sortie audio"
STEREO = "Stéréo"
MONO = "Mono"
HEADSET = "Casque"
[LANGUAGE]
LANGUAGE = "LANGUE"
@ -440,3 +446,7 @@ NO_LOBBIES_FOUND = "Aucune partie n'a été trouvée."
[CHANGELOG]
CHANGELOG_TITLE = "MODIFICATIONS"
[UPDATE]
UPDATE_TITLE = "MISE À JOUR"
UPDATE_AVAILABLE = "Une mise à jour est disponible. Voulez-vous l'installer ?"

View file

@ -64,6 +64,7 @@ BACK = "Zurück"
CANCEL = "Abbrechen"
NO = "Nein"
YES = "Ja"
SEARCH = "Suche..."
[CAMERA]
CAMERA = "KAMERA"
@ -167,6 +168,7 @@ D1P5X = "1.5x"
D3X = "3x"
D10X = "10x"
D100X = "100x"
INFINITE = "Unendlich"
DRAW_DISTANCE = "Sichtweite"
DYNOS_PACKS = "DynOS-Pakete"
ANTIALIASING = "Kantenglättung"
@ -415,6 +417,10 @@ SFX_VOLUME = "Effektlautstärke"
ENV_VOLUME = "Umgebungslautstärke"
FADEOUT = "Ausblenden"
MUTE_FOCUS_LOSS = "Audio bei Fokusverlust stummschalten"
SOUND_OUTPUT = "Audioausgabe"
STEREO = "Stereo"
MONO = "Mono"
HEADSET = "Kopfhörer"
[LANGUAGE]
LANGUAGE = "SPRACHE"
@ -440,3 +446,7 @@ NO_LOBBIES_FOUND = "Keine Lobbys gefunden."
[CHANGELOG]
CHANGELOG_TITLE = "ÄNDERUNGSPROTOKOLL"
[UPDATE]
UPDATE_TITLE = "AKTUALISIERUNG"
UPDATE_AVAILABLE = "Eine Aktualisierung ist verfügbar. Möchten Sie sie installieren?"

View file

@ -64,6 +64,7 @@ BACK = "Indietro"
CANCEL = "Annulla"
NO = "No"
YES = "Si"
SEARCH = "Cerca..."
[CAMERA]
CAMERA = "TELECAMERA"
@ -165,6 +166,7 @@ D1P5X = "1.5x"
D3X = "3x"
D10X = "10x"
D100X = "100x"
INFINITE = "Infinito"
DRAW_DISTANCE = "Distanza di Simulazione"
DYNOS_PACKS = "Pacchetti DynOS"
ANTIALIASING = "Anti-aliasing"
@ -413,6 +415,10 @@ SFX_VOLUME = "Effetti sonori"
ENV_VOLUME = "Ambientazione"
FADEOUT = "Suoni lontani in dissolvenza"
MUTE_FOCUS_LOSS = "Disattiva l'audio quando la finestra non è attiva"
SOUND_OUTPUT = "Uscita audio"
STEREO = "Stereo"
MONO = "Mono"
HEADSET = "Cuffie"
[LANGUAGE]
LANGUAGE = "LINGUA"
@ -438,3 +444,7 @@ NO_LOBBIES_FOUND = "Non è stata trovata alcuna stanza."
[CHANGELOG]
CHANGELOG_TITLE = "REGISTRO DELLE MODIFICHE"
[UPDATE]
UPDATE_TITLE = "AGGIORNAMENTO"
UPDATE_AVAILABLE = "Un aggiornamento è disponibile. Vuoi installarlo?"

View file

@ -64,6 +64,7 @@ BACK = "戻る"
CANCEL = "キャンセル"
NO = "いいえ"
YES = "はい"
SEARCH = "検索…"
[CAMERA]
CAMERA = "CAMERA"
@ -167,6 +168,7 @@ D1P5X = "1.5x"
D3X = "3x"
D10X = "10x"
D100X = "100x"
INFINITE = "無限"
DRAW_DISTANCE = "描画距離"
DYNOS_PACKS = "DynOSパック"
ANTIALIASING = "アンチエイリアス"
@ -415,6 +417,10 @@ SFX_VOLUME = "SE音量"
ENV_VOLUME = "環境音量"
FADEOUT = "音の距離減衰"
MUTE_FOCUS_LOSS = "非フォーカス時に音をミュート"
SOUND_OUTPUT = "音声出力"
STEREO = "ステレオ"
MONO = "モノラル"
HEADSET = "ヘッドセット"
[LANGUAGE]
LANGUAGE = "LANGUAGE"
@ -441,3 +447,7 @@ NO_LOBBIES_FOUND = "ルームが見つかりませんでした。"
[CHANGELOG]
CHANGELOG_TITLE = "CHANGELOG"
[UPDATE]
UPDATE_TITLE = "最新情報"
UPDATE_AVAILABLE = "アップデートが利用可能です。インストールしますか?"

View file

@ -64,6 +64,7 @@ BACK = "Wróć"
CANCEL = "Anuluj"
NO = "Nie"
YES = "Tak"
SEARCH = "Szukaj..."
[CAMERA]
CAMERA = "KAMERA"
@ -167,6 +168,7 @@ D1P5X = "1,5x"
D3X = "3x"
D10X = "10x"
D100X = "100x"
INFINITE = "Nieskończony"
DRAW_DISTANCE = "Odległość Renderowania"
DYNOS_PACKS = "Paczki DynOS"
ANTIALIASING = "Anti-aliasing"
@ -415,6 +417,10 @@ SFX_VOLUME = "Głośność Efektów"
ENV_VOLUME = "Głośność Środowiska"
FADEOUT = "Zanikanie Odległych Dźwięków"
MUTE_FOCUS_LOSS = "Wycisz dźwięk, gdy okno traci fokus"
SOUND_OUTPUT = "Wyjście dźwięku"
STEREO = "Stereo"
MONO = "Mono"
HEADSET = "Słuchawki"
[LANGUAGE]
LANGUAGE = "JĘZYK"
@ -440,3 +446,7 @@ NO_LOBBIES_FOUND = "Nie znaleziono żadnego lobby."
[CHANGELOG]
CHANGELOG_TITLE = "REJESTR ZMIAN"
[UPDATE]
UPDATE_TITLE = "AKTUALIZACJA"
UPDATE_AVAILABLE = "Dostępna jest aktualizacja. Czy chcesz ją zainstalować?"

View file

@ -64,6 +64,7 @@ BACK = "Voltar"
CANCEL = "Cancelar"
NO = "Não"
YES = "Sim"
SEARCH = "Pesquisar..."
[CAMERA]
CAMERA = "CÂMERA"
@ -167,6 +168,7 @@ D1P5X = "1.5x"
D3X = "3x"
D10X = "10x"
D100X = "100x"
INFINITE = "Infinito"
DRAW_DISTANCE = "Distância de renderização"
DYNOS_PACKS = "Pacotes DynOS"
ANTIALIASING = "Antisserrilhamento"
@ -415,6 +417,10 @@ SFX_VOLUME = "Volume dos efeitos sonoros"
ENV_VOLUME = "Volume do ambiente"
FADEOUT = "Desvanecer sons distantes"
MUTE_FOCUS_LOSS = "Silenciar quando a janela estiver desfocada"
SOUND_OUTPUT = "Saída de som"
STEREO = "Estéreo"
MONO = "Mono"
HEADSET = "Fone de ouvido"
[LANGUAGE]
LANGUAGE = "IDIOMA"
@ -440,3 +446,7 @@ NO_LOBBIES_FOUND = "Nenhuma sala encontrada."
[CHANGELOG]
CHANGELOG_TITLE = "ALTERAÇÕES"
[UPDATE]
UPDATE_TITLE = "ATUALIZAÇÃO"
UPDATE_AVAILABLE = "Uma atualização está disponível. Deseja instalá-la?"

View file

@ -64,6 +64,7 @@ BACK = "Назад"
CANCEL = "Отмена"
NO = "Нет"
YES = "Да"
SEARCH = "Поиск..."
[CAMERA]
CAMERA = "CAMERA"
@ -166,6 +167,7 @@ D1P5X = "1.5x"
D3X = "3x"
D10X = "10x"
D100X = "100x"
INFINITE = "Бесконечный"
DRAW_DISTANCE = "Дальность прорисовки"
DYNOS_PACKS = "Пакеты DynOS"
ANTIALIASING = "Анизотропная фильтрация"
@ -414,6 +416,10 @@ SFX_VOLUME = "Громкость звуков"
ENV_VOLUME = "Объёмное звучание"
FADEOUT = "Затухание звуков на расстоянии"
MUTE_FOCUS_LOSS = "Выключить звук когда окно не выбрано"
SOUND_OUTPUT = "Выход звука"
STEREO = "Стерео"
MONO = "Моно"
HEADSET = "Наушники"
[LANGUAGE]
LANGUAGE = "LANGUAGE"
@ -439,3 +445,7 @@ NO_LOBBIES_FOUND = "Группы не найдены."
[CHANGELOG]
CHANGELOG_TITLE = "ЖУРНАЛ ИЗМЕНЕНИЙ"
[UPDATE]
UPDATE_TITLE = "ОБНОВЛЕНИЕ"
UPDATE_AVAILABLE = "Доступно обновление. Хотите его установить?"

View file

@ -64,6 +64,7 @@ BACK = "Volver"
CANCEL = "Cancelar"
NO = "No"
YES = "Sí"
SEARCH = "Buscar..."
[CAMERA]
CAMERA = "CÁMARA"
@ -167,6 +168,7 @@ D1P5X = "1.5x"
D3X = "3x"
D10X = "10x"
D100X = "100x"
INFINITE = "Infinito"
DRAW_DISTANCE = "Distancia de dibujado"
DYNOS_PACKS = "Packs DynOS"
ANTIALIASING = "Anti-aliasing"
@ -415,6 +417,10 @@ SFX_VOLUME = "Volumen de los sonidos"
ENV_VOLUME = "Volumen del entorno"
FADEOUT = "Silenciar sonidos lejanos"
MUTE_FOCUS_LOSS = "Silenciar sonido cuando la ventana esté desenfocada"
SOUND_OUTPUT = "Salida de sonido"
STEREO = "Estéreo"
MONO = "Mono"
HEADSET = "Auriculares"
[LANGUAGE]
LANGUAGE = "IDIOMA"
@ -440,3 +446,7 @@ NO_LOBBIES_FOUND = "No se han encontrado partidas."
[CHANGELOG]
CHANGELOG_TITLE = "REGISTRO DE CAMBIOS"
[UPDATE]
UPDATE_TITLE = "ACTUALIZACIÓN"
UPDATE_AVAILABLE = "Hay una actualización disponible. ¿Quieres instalarla?"

View file

@ -19,26 +19,26 @@ static const Gfx bbh_seg7_dl_0700B8A8[] = {
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, spooky_09006800),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_0700B488, 15, 0),
gsSPVertex(bbh_seg7_vertex_0700B488, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 3, 1, 0x0),
gsSP2Triangles( 4, 5, 6, 0x0, 7, 8, 9, 0x0),
gsSP2Triangles( 5, 10, 11, 0x0, 5, 1, 10, 0x0),
gsSP1Triangle(12, 13, 14, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_0700B578, 16, 0),
gsSPVertex(bbh_seg7_vertex_0700B578, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 3, 6, 4, 0x0, 7, 8, 9, 0x0),
gsSP2Triangles( 7, 4, 8, 0x0, 10, 11, 12, 0x0),
gsSP2Triangles(10, 13, 11, 0x0, 14, 13, 15, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_0700B678, 15, 0),
gsSPVertex(bbh_seg7_vertex_0700B678, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 6, 7, 8, 0x0, 9, 10, 11, 0x0),
gsSP1Triangle(12, 13, 14, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_0700B768, 14, 0),
gsSPVertex(bbh_seg7_vertex_0700B768, 14, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 3, 1, 0x0),
gsSP2Triangles( 4, 1, 5, 0x0, 4, 5, 6, 0x0),
gsSP2Triangles( 7, 8, 9, 0x0, 7, 10, 8, 0x0),
gsSP2Triangles(11, 10, 12, 0x0, 11, 13, 10, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_0700B848, 6, 0),
gsSPVertex(bbh_seg7_vertex_0700B848, 6, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSPEndDisplayList(),
};
@ -46,7 +46,7 @@ static const Gfx bbh_seg7_dl_0700B8A8[] = {
// 0x0700B9E0 - 0x0700BA50
const Gfx bbh_seg7_dl_0700B9E0[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_MODULATERGB, G_CC_MODULATERGB),
gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA),
gsSPClearGeometryMode(G_LIGHTING),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),

View file

@ -7,7 +7,7 @@ static const Gfx bbh_seg7_dl_0700BB50[] = {
gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, spooky_0900B000),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_0700BA50, 16, 0),
gsSPVertex(bbh_seg7_vertex_0700BA50, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 3, 5, 6, 0x0, 7, 4, 3, 0x0),
gsSP2Triangles( 7, 8, 4, 0x0, 6, 5, 9, 0x0),

View file

@ -10,14 +10,14 @@ static const Gfx bbh_seg7_dl_0700D6F0[] = {
gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, spooky_0900B000),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_0700D500, 16, 0),
gsSPVertex(bbh_seg7_vertex_0700D500, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 3, 6, 4, 0x0, 7, 6, 3, 0x0),
gsSP2Triangles( 7, 8, 6, 0x0, 5, 4, 9, 0x0),
gsSP2Triangles( 5, 9, 10, 0x0, 10, 9, 8, 0x0),
gsSP2Triangles(10, 8, 7, 0x0, 11, 1, 0, 0x0),
gsSP2Triangles( 0, 2, 12, 0x0, 13, 14, 15, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_0700D600, 15, 0),
gsSPVertex(bbh_seg7_vertex_0700D600, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 3, 5, 6, 0x0, 6, 5, 1, 0x0),
gsSP2Triangles( 6, 1, 0, 0x0, 7, 8, 9, 0x0),

View file

@ -7,7 +7,7 @@ static const Gfx bbh_seg7_dl_07012680[] = {
gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, spooky_0900B000),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_07012580, 16, 0),
gsSPVertex(bbh_seg7_vertex_07012580, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 3, 5, 6, 0x0, 7, 8, 9, 0x0),
gsSP2Triangles( 7, 9, 10, 0x0, 11, 12, 13, 0x0),

View file

@ -10,14 +10,14 @@ static const Gfx bbh_seg7_dl_07015930[] = {
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, spooky_09006800),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_07015750, 15, 0),
gsSPVertex(bbh_seg7_vertex_07015750, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 1, 3, 2, 0x0),
gsSP2Triangles( 3, 4, 2, 0x0, 4, 0, 2, 0x0),
gsSP2Triangles( 5, 6, 7, 0x0, 8, 5, 7, 0x0),
gsSP2Triangles( 6, 9, 7, 0x0, 9, 8, 7, 0x0),
gsSP2Triangles(10, 11, 12, 0x0, 11, 13, 12, 0x0),
gsSP2Triangles(13, 14, 12, 0x0, 14, 10, 12, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07015840, 15, 0),
gsSPVertex(bbh_seg7_vertex_07015840, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 1, 3, 2, 0x0),
gsSP2Triangles( 3, 4, 2, 0x0, 4, 0, 2, 0x0),
gsSP2Triangles( 5, 6, 7, 0x0, 8, 5, 7, 0x0),
@ -30,7 +30,7 @@ static const Gfx bbh_seg7_dl_07015930[] = {
// 0x07015A20 - 0x07015A90
const Gfx bbh_seg7_dl_07015A20[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_MODULATERGB, G_CC_MODULATERGB),
gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA),
gsSPClearGeometryMode(G_LIGHTING),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),

View file

@ -7,7 +7,7 @@ static const Gfx bbh_seg7_dl_070176E0[] = {
gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, spooky_0900B000),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_070175E0, 16, 0),
gsSPVertex(bbh_seg7_vertex_070175E0, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 3, 5, 6, 0x0, 7, 4, 3, 0x0),
gsSP2Triangles( 7, 8, 4, 0x0, 6, 5, 9, 0x0),

View file

@ -21,7 +21,7 @@ static const Gfx bbh_seg7_dl_0701EE90[] = {
gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, spooky_0900B800),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 64 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_0701EE08, 4, 0),
gsSPVertex(bbh_seg7_vertex_0701EE08, 4, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0),
gsSPEndDisplayList(),
};

View file

@ -7,7 +7,7 @@ static const Gfx bbh_seg7_dl_0701F018[] = {
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, spooky_09006800),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_0701EF58, 12, 0),
gsSPVertex(bbh_seg7_vertex_0701EF58, 12, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 3, 1, 0x0),
gsSP2Triangles( 4, 3, 5, 0x0, 4, 6, 3, 0x0),
gsSP2Triangles( 7, 8, 9, 0x0, 10, 5, 11, 0x0),
@ -17,7 +17,7 @@ static const Gfx bbh_seg7_dl_0701F018[] = {
// 0x0701F070 - 0x0701F0E0
const Gfx bbh_seg7_dl_0701F070[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_MODULATERGB, G_CC_MODULATERGB),
gsDPSetCombineMode(G_CC_DECALRGB, G_CC_DECALRGB),
gsSPClearGeometryMode(G_LIGHTING),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),

View file

@ -13,17 +13,17 @@ static const Gfx bbh_seg7_dl_07007EE8[] = {
gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, spooky_0900B800),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 64 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_07007C08, 15, 0),
gsSPVertex(bbh_seg7_vertex_07007C08, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 3, 6, 4, 0x0, 7, 8, 9, 0x0),
gsSP2Triangles( 7, 10, 8, 0x0, 11, 12, 13, 0x0),
gsSP1Triangle(11, 13, 14, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07007CF8, 15, 0),
gsSPVertex(bbh_seg7_vertex_07007CF8, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 6, 7, 8, 0x0, 6, 9, 7, 0x0),
gsSP2Triangles(10, 11, 12, 0x0, 10, 13, 11, 0x0),
gsSP1Triangle( 0, 2, 14, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07007DE8, 16, 0),
gsSPVertex(bbh_seg7_vertex_07007DE8, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 3, 6, 4, 0x0, 7, 8, 9, 0x0),
gsSP2Triangles( 7, 9, 10, 0x0, 11, 12, 13, 0x0),

View file

@ -31,45 +31,45 @@ static const Gfx bbh_seg7_dl_070088E0[] = {
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, spooky_09006800),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_07008040, 16, 0),
gsSPVertex(bbh_seg7_vertex_07008040, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0),
gsSP2Triangles( 4, 5, 6, 0x0, 7, 0, 8, 0x0),
gsSP2Triangles( 9, 1, 10, 0x0, 9, 11, 1, 0x0),
gsSP2Triangles(12, 13, 14, 0x0, 12, 15, 13, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07008140, 16, 0),
gsSPVertex(bbh_seg7_vertex_07008140, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 1, 6, 7, 0x0, 1, 7, 8, 0x0),
gsSP2Triangles( 9, 10, 11, 0x0, 9, 11, 12, 0x0),
gsSP2Triangles(13, 14, 10, 0x0, 13, 10, 15, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07008240, 15, 0),
gsSPVertex(bbh_seg7_vertex_07008240, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 6, 7, 8, 0x0, 6, 8, 9, 0x0),
gsSP2Triangles(10, 11, 12, 0x0, 13, 6, 14, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07008330, 16, 0),
gsSPVertex(bbh_seg7_vertex_07008330, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 3, 1, 0x0),
gsSP2Triangles( 4, 5, 6, 0x0, 7, 8, 9, 0x0),
gsSP2Triangles( 5, 10, 11, 0x0, 5, 11, 12, 0x0),
gsSP2Triangles(13, 14, 10, 0x0, 13, 10, 15, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07008430, 16, 0),
gsSPVertex(bbh_seg7_vertex_07008430, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0),
gsSP2Triangles( 4, 5, 6, 0x0, 7, 8, 9, 0x0),
gsSP2Triangles( 5, 2, 10, 0x0, 5, 10, 11, 0x0),
gsSP2Triangles(12, 13, 14, 0x0, 12, 14, 15, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07008530, 15, 0),
gsSPVertex(bbh_seg7_vertex_07008530, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0),
gsSP2Triangles( 4, 5, 6, 0x0, 7, 0, 8, 0x0),
gsSP2Triangles( 9, 10, 11, 0x0, 12, 13, 14, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07008620, 16, 0),
gsSPVertex(bbh_seg7_vertex_07008620, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0),
gsSP2Triangles( 4, 2, 5, 0x0, 4, 5, 6, 0x0),
gsSP2Triangles( 7, 8, 9, 0x0, 7, 9, 10, 0x0),
gsSP2Triangles(11, 12, 13, 0x0, 14, 10, 15, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07008720, 16, 0),
gsSPVertex(bbh_seg7_vertex_07008720, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0),
gsSP2Triangles( 4, 5, 6, 0x0, 7, 8, 9, 0x0),
gsSP2Triangles(10, 11, 5, 0x0, 10, 12, 11, 0x0),
gsSP2Triangles(13, 14, 15, 0x0, 13, 11, 14, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07008820, 12, 0),
gsSPVertex(bbh_seg7_vertex_07008820, 12, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0),
gsSP2Triangles( 4, 5, 6, 0x0, 7, 3, 8, 0x0),
gsSP2Triangles( 9, 2, 10, 0x0, 9, 10, 11, 0x0),
@ -79,7 +79,7 @@ static const Gfx bbh_seg7_dl_070088E0[] = {
// 0x07008B58 - 0x07008BC8
const Gfx bbh_seg7_dl_07008B58[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_MODULATERGB, G_CC_MODULATERGB),
gsDPSetCombineMode(G_CC_DECALRGB, G_CC_DECALRGB),
gsSPClearGeometryMode(G_LIGHTING),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),

View file

@ -10,14 +10,14 @@ static const Gfx bbh_seg7_dl_07008DB8[] = {
gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, spooky_0900B000),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_07008BC8, 16, 0),
gsSPVertex(bbh_seg7_vertex_07008BC8, 16, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 3, 6, 4, 0x0, 7, 6, 3, 0x0),
gsSP2Triangles( 7, 8, 6, 0x0, 5, 4, 9, 0x0),
gsSP2Triangles( 5, 9, 10, 0x0, 10, 9, 8, 0x0),
gsSP2Triangles(10, 8, 7, 0x0, 11, 1, 0, 0x0),
gsSP2Triangles( 0, 2, 12, 0x0, 13, 14, 15, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_07008CC8, 15, 0),
gsSPVertex(bbh_seg7_vertex_07008CC8, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 3, 5, 6, 0x0, 6, 5, 1, 0x0),
gsSP2Triangles( 6, 1, 0, 0x0, 7, 8, 9, 0x0),

View file

@ -10,12 +10,12 @@ static const Gfx bbh_seg7_dl_0700B398[] = {
gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, spooky_0900B800),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 64 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPVertexNonGlobal(bbh_seg7_vertex_0700B238, 15, 0),
gsSPVertex(bbh_seg7_vertex_0700B238, 15, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP2Triangles( 3, 5, 6, 0x0, 7, 8, 9, 0x0),
gsSP2Triangles( 7, 9, 10, 0x0, 11, 12, 13, 0x0),
gsSP1Triangle(11, 14, 12, 0x0),
gsSPVertexNonGlobal(bbh_seg7_vertex_0700B328, 7, 0),
gsSPVertex(bbh_seg7_vertex_0700B328, 7, 0),
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
gsSP1Triangle( 0, 6, 1, 0x0),
gsSPEndDisplayList(),

View file

@ -14,8 +14,8 @@
#define SEQUENCE_ARGS(priority, seqId) ((priority << 8) | seqId)
#define SOUND_MODE_STEREO 0
#define SOUND_MODE_MONO 3
#define SOUND_MODE_HEADSET 1
#define SOUND_MODE_MONO 1
#define SOUND_MODE_HEADSET 2
#define SEQ_PLAYER_LEVEL 0 // Level background music
#define SEQ_PLAYER_ENV 1 // Misc music like the puzzle jingle

View file

@ -228,6 +228,13 @@ void discard_bank(s32 bankId) {
note->parentLayer->finished = TRUE;
}
note_disable(note);
// Reset sample state
note->sound = NULL;
note->samplePosInt = 0;
note->samplePosFrac = 0;
note->sampleDmaIndex = 0;
audio_list_remove(&note->listItem);
audio_list_push_back(&gNoteFreeLists.disabled, &note->listItem);
}

View file

@ -1591,7 +1591,15 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) {
if (smlua_audio_utils_override(seqId, &bankId, &sequenceData)) {
sequence_player_disable(seqPlayer);
seqPlayer->defaultBank[0] = bankId;
if (!bank_load_immediate(bankId, 0)) { return; }
// Check if the bank is already loaded in the temporary cache
if (get_bank_or_seq(&gBankLoadedPool, 0, bankId) == NULL) {
if (!bank_load_immediate(bankId, 0)) { return; }
} else if (gBankLoadStatus[bankId] == SOUND_LOAD_STATUS_DISCARDABLE) {
// This bank is still available, so just mark it as loaded again
gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_COMPLETE;
}
seqPlayer->seqId = seqId;
gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE;
init_sequence_player(player);

View file

@ -1438,7 +1438,9 @@ cur_obj_update_begin:;
} else if ((objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) && gCurrentObject->collisionData == NULL) {
if (!(objFlags & OBJ_FLAG_ACTIVE_FROM_AFAR)) {
// If the object has a render distance, check if it should be shown.
if (distanceFromMario > gCurrentObject->oDrawingDistance * draw_distance_scalar()) {
if (!draw_distance_scalar_is_infinite() &&
distanceFromMario > gCurrentObject->oDrawingDistance * draw_distance_scalar()
) {
// Out of render distance, hide the object.
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
@ -1486,6 +1488,13 @@ f32 position_based_random_float_position(void) {
return rnd / (double)0x10000;
}
bool draw_distance_scalar_is_infinite(void) {
if (!gBehaviorValues.InfiniteRenderDistance) {
return false;
}
return configDrawDistance == 6; // Expecting this to be "Infinite"
}
f32 draw_distance_scalar(void) {
if (!gBehaviorValues.InfiniteRenderDistance) { return 1.0f; }

View file

@ -37,6 +37,8 @@ void obj_update_gfx_pos_and_angle(struct Object *obj);
u16 position_based_random_u16(void);
/* |description|Sets the current object's position to random floats between 0.0 and 1.0|descriptionEnd| */
f32 position_based_random_float_position(void);
/* |description|Checks if the draw distance scalar is infinite|descriptionEnd| */
bool draw_distance_scalar_is_infinite(void);
/* |description|Gets the draw distance scalar|descriptionEnd| */
f32 draw_distance_scalar(void);

View file

@ -1045,7 +1045,9 @@ static void load_object_collision_model_internal(bool isSOC) {
if (!isSOC) {
f32 marioDist = dist_between_objects(gCurrentObject, gMarioStates[0].marioObj);
if (marioDist < gCurrentObject->oDrawingDistance * draw_distance_scalar()) {
if (draw_distance_scalar_is_infinite() ||
marioDist < gCurrentObject->oDrawingDistance * draw_distance_scalar()
) {
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
} else {
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;

View file

@ -230,7 +230,7 @@ void king_bobomb_act_7(void) {
void king_bobomb_act_8(void) {
if (!(o->header.gfx.node.flags & GRAPH_RENDER_INVISIBLE)) {
struct Object *star = NULL;
create_sound_spawner(SOUND_OBJ_KING_WHOMP_DEATH);
cur_obj_hide();
cur_obj_become_intangible();
@ -367,6 +367,10 @@ void king_bobomb_move(void) {
cur_obj_move_using_fvel_and_gravity();
CUR_OBJ_CALL_ACTION_FUNCTION(sKingBobombActions);
exec_anim_sound_state(sKingBobombSoundStates, sizeof(sKingBobombSoundStates) / sizeof(struct SoundState));
if (draw_distance_scalar_is_infinite()) {
cur_obj_enable_rendering();
return;
}
s32 distanceToPlayer = dist_between_objects(o, gMarioStates[0].marioObj);
if (distanceToPlayer < 5000.0f * draw_distance_scalar())
cur_obj_enable_rendering();

View file

@ -375,12 +375,16 @@ void bhv_piranha_plant_loop(void) {
CUR_OBJ_CALL_ACTION_FUNCTION(TablePiranhaPlantActions);
// In WF, hide all Piranha Plants once high enough up.
if (gCurrLevelNum == LEVEL_WF) {
struct Object* player = gMarioStates[0].marioObj;
f32 scalar = max(draw_distance_scalar(), 1.0f);
if (player->oPosY > 3400.0f * scalar)
cur_obj_hide();
else
if (draw_distance_scalar_is_infinite()) {
cur_obj_unhide();
} else {
struct Object* player = gMarioStates[0].marioObj;
f32 scalar = max(draw_distance_scalar(), 1.0f);
if (player->oPosY > 3400.0f * scalar)
cur_obj_hide();
else
cur_obj_unhide();
}
}
o->oInteractStatus = 0;
}

View file

@ -44,11 +44,15 @@ void bhv_whirlpool_loop(void) {
o->oWhirlpoolTimeout = 30;
}
f32 marioDist = dist_between_objects(o, gMarioStates[0].marioObj);
if (marioDist < 5000.0f * draw_distance_scalar()) {
if (draw_distance_scalar_is_infinite()) {
o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
} else {
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
f32 marioDist = dist_between_objects(o, gMarioStates[0].marioObj);
if (marioDist < 5000.0f * draw_distance_scalar()) {
o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
} else {
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
}
}
// not sure if actually an array

View file

@ -325,7 +325,7 @@ void render_hud_icon(Vtx *vtx, const Texture *texture, u32 fmt, u32 siz, s32 tex
case G_IM_SIZ_16b: gDPLoadTextureBlock(gDisplayListHead++, texture, fmt, G_IM_SIZ_16b, texW, texH, 0, G_TX_CLAMP, G_TX_CLAMP, 0, 0, 0, 0); break;
case G_IM_SIZ_32b: gDPLoadTextureBlock(gDisplayListHead++, texture, fmt, G_IM_SIZ_32b, texW, texH, 0, G_TX_CLAMP, G_TX_CLAMP, 0, 0, 0, 0); break;
}
gSPVertex(gDisplayListHead++, vtx, 4, 0);
gSPVertexNonGlobal(gDisplayListHead++, vtx, 4, 0);
gSP2Triangles(gDisplayListHead++, 0, 1, 2, 0x0, 0, 2, 3, 0x0);
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF);
gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE);

View file

@ -701,6 +701,10 @@ s8 is_point_close_to_object(struct Object *obj, f32 x, f32 y, f32 z, s32 dist) {
/* |description|Sets an object as visible if within a certain distance of Mario's graphical position|descriptionEnd| */
void set_object_visibility(struct Object *obj, s32 dist) {
if (!obj) { return; }
if (draw_distance_scalar_is_infinite()) {
obj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
return;
}
s32 distanceToPlayer = dist_between_objects(obj, gMarioStates[0].marioObj);
if (distanceToPlayer < dist * draw_distance_scalar()) {
obj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;

View file

@ -3010,7 +3010,9 @@ void cur_obj_if_hit_wall_bounce_away(void) {
s32 cur_obj_hide_if_mario_far_away_y(f32 distY) {
if (!o) { return 0; }
if (!gMarioStates[0].marioObj) { return FALSE; }
if (absf(o->oPosY - gMarioStates[0].marioObj->oPosY) < distY * draw_distance_scalar()) {
if (draw_distance_scalar_is_infinite() ||
absf(o->oPosY - gMarioStates[0].marioObj->oPosY) < distY * draw_distance_scalar()
) {
cur_obj_unhide();
return FALSE;
}

View file

@ -50,6 +50,8 @@
#define DISPLAY_LIST_HEAP_SIZE 32000
#define MAX_FAR_PLANE_DIST 1000000.f
f32 gProjectionMaxNearValue = 5;
s16 gProjectionVanillaNearValue = 100;
s16 gProjectionVanillaFarValue = 1000;
@ -310,6 +312,10 @@ void patch_mtx_interpolated(f32 delta) {
f32 fovInterpolated = delta_interpolate_f32(sPerspectiveNode->prevFov, sPerspectiveNode->fov, delta);
f32 near = get_first_person_enabled() ? 1.f : replace_value_if_not_zero(MIN(sPerspectiveNode->near, gProjectionMaxNearValue), gOverrideNear);
f32 far = replace_value_if_not_zero(sPerspectiveNode->far, gOverrideFar);
// "infinite" draw distance
if (gOverrideFar == 0 && configDrawDistance == 6) { far = max(far, MAX_FAR_PLANE_DIST); }
guPerspective(sPerspectiveMtx, &perspNorm, fovInterpolated, sPerspectiveAspect, near, far, 1.0f);
gSPMatrix(sPerspectivePos, VIRTUAL_TO_PHYSICAL(sPerspectiveNode), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
}
@ -650,6 +656,10 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
gProjectionVanillaFarValue = node->far;
f32 near = get_first_person_enabled() ? 1.f : replace_value_if_not_zero(MIN(node->near, gProjectionMaxNearValue), gOverrideNear);
f32 far = replace_value_if_not_zero(node->far, gOverrideFar);
// "infinite" draw distance
if (gOverrideFar == 0 && configDrawDistance == 6) { far = max(far, MAX_FAR_PLANE_DIST); }
guPerspective(mtx, &perspNorm, node->prevFov, aspect, near, far, 1.0f);
sPerspectiveNode = node;
@ -1139,7 +1149,7 @@ static void anim_process(Vec3f translation, Vec3s rotation, Vec3f scale, u8 *ani
scale[2] *= ((f32) scaleZ) / 256.0f;
}
}
if (gCurAnim->flags & ANIM_FLAG_BONE_TRANS) {
*animType = ANIM_TYPE_TRANSLATION;
}
@ -1459,7 +1469,7 @@ static s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
// makes PU travel safe when the camera is locked on the main map.
// If Mario were rendered with a depth over 65536 it would cause overflow
// when converting the transformation matrix to a fixed point matrix.
if (matrix[3][2] < -20000.0f - cullingRadius) {
if (configDrawDistance != 6 && matrix[3][2] < -20000.0f - cullingRadius) {
return FALSE;
}

View file

@ -15,6 +15,8 @@
#include "pc/network/network.h"
#include "pc/lua/utils/smlua_level_utils.h"
#include "pc/utils/misc.h"
#include "pc/configfile.h"
#include "audio/external.h"
#ifndef bcopy
#define bcopy(b1,b2,len) (memmove((b2), (b1), (len)), (void) 0)
@ -814,7 +816,8 @@ void save_file_set_sound_mode(u16 mode) {
}
u16 save_file_get_sound_mode(void) {
return gSaveBuffer.menuData[0].soundMode;
if (configSoundOutput > SOUND_MODE_HEADSET) { return SOUND_MODE_STEREO; }
return configSoundOutput;
}
void save_file_move_cap_to_default_location(void) {

View file

@ -191,7 +191,7 @@ f32 calculate_skybox_scaled_y(s8 player, UNUSED f32 fov) {
* into an x and y by modulus and division by SKYBOX_COLS. x and y are then scaled by
* SKYBOX_TILE_WIDTH to get a point in world space.
*/
Vtx *make_skybox_rect(s32 tileRow, s32 tileCol, s8 colorIndex, s32 row, s32 col) {
Vtx *make_skybox_rect(s32 tileRow, s32 tileCol, s32 row, s32 col) {
u16 index = row * sSkyboxTileNumX + col;
Vtx *verts;
if (gRenderingInterpolated) {
@ -205,14 +205,10 @@ Vtx *make_skybox_rect(s32 tileRow, s32 tileCol, s8 colorIndex, s32 row, s32 col)
f32 y = SKYBOX_HEIGHT - tileRow / SKYBOX_COLS * SKYBOX_TILE_HEIGHT;
if (verts != NULL) {
f32 r = gSkyboxColor[0] / 255.0f;
f32 g = gSkyboxColor[1] / 255.0f;
f32 b = gSkyboxColor[2] / 255.0f;
u8 *colors = sSkyboxColors[colorIndex];
make_vertex(verts, 0, x, y, -1, 0, 0, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 1, x, y - SKYBOX_TILE_HEIGHT, -1, 0, 31 << 5, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 2, x + SKYBOX_TILE_WIDTH, y - SKYBOX_TILE_HEIGHT, -1, 31 << 5, 31 << 5, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 3, x + SKYBOX_TILE_WIDTH, y, -1, 31 << 5, 0, colors[0] * r, colors[1] * g, colors[2] * b, 255);
make_vertex(verts, 0, x, y, -1, 0, 0, 255, 255, 255, 255);
make_vertex(verts, 1, x, y - SKYBOX_TILE_HEIGHT, -1, 0, 31 << 5, 255, 255, 255, 255);
make_vertex(verts, 2, x + SKYBOX_TILE_WIDTH, y - SKYBOX_TILE_HEIGHT, -1, 31 << 5, 31 << 5, 255, 255, 255, 255);
make_vertex(verts, 3, x + SKYBOX_TILE_WIDTH, y, -1, 31 << 5, 0, 255, 255, 255, 255);
}
return verts;
}
@ -246,10 +242,16 @@ void draw_skybox_tile_grid(Gfx **dlist, s8 background, s8 player, s8 colorIndex)
texture = (*(SkyboxTexture *) segmented_to_virtual(sSkyboxTextures[background]))[tileIndex];
}
Vtx *vertices = make_skybox_rect(tileRow, tileColTmp, colorIndex, row, col);
f32 r = gSkyboxColor[0] / 255.0f;
f32 g = gSkyboxColor[1] / 255.0f;
f32 b = gSkyboxColor[2] / 255.0f;
u8 *color = sSkyboxColors[colorIndex];
gDPSetEnvColor((*dlist)++, color[0] * r, color[1] * g, color[2] * b, 255);
Vtx *vertices = make_skybox_rect(tileRow, tileColTmp, row, col);
gLoadBlockTexture((*dlist)++, 32, 32, G_IM_FMT_RGBA, texture);
gSPVertexNonGlobal((*dlist)++, VIRTUAL_TO_PHYSICAL(vertices), 4, 0);
gSPVertex((*dlist)++, VIRTUAL_TO_PHYSICAL(vertices), 4, 0);
gSPDisplayList((*dlist)++, dl_draw_quad_verts_0123);
}
}
@ -284,7 +286,7 @@ void *create_skybox_ortho_matrix(s8 player) {
Gfx *init_skybox_display_list(s8 player, s8 background, s8 colorIndex) {
extern Gfx* gBackgroundSkyboxGfx;
s32 dlCommandCount = 5 + (sSkyboxTileNumY * sSkyboxTileNumX) * 7; // 5 for the start and end, plus the amount of skybox tiles
s32 dlCommandCount = 5 + (sSkyboxTileNumY * sSkyboxTileNumX) * 8; // 5 for the start and end, plus the amount of skybox tiles
void *skybox;
if (gRenderingInterpolated) {

View file

@ -89,7 +89,7 @@ bool configShowPing = false;
enum RefreshRateMode configFramerateMode = RRM_AUTO;
unsigned int configFrameLimit = 60;
unsigned int configInterpolationMode = 1;
unsigned int configDrawDistance = 4;
unsigned int configDrawDistance = 6;
// sound settings
unsigned int configMasterVolume = 80; // 0 - MAX_VOLUME
unsigned int configMusicVolume = MAX_VOLUME;
@ -97,6 +97,7 @@ unsigned int configSfxVolume = MAX_VOLUME;
unsigned int configEnvVolume = MAX_VOLUME;
bool configFadeoutDistantSounds = false;
bool configMuteFocusLoss = false;
unsigned int configSoundOutput = 0; // 0 = Stereo, 1 = Mono, 2 = Headset
// control binds
unsigned int configKeyA[MAX_BINDS] = { 0x0026, 0x1000, 0x1103 };
unsigned int configKeyB[MAX_BINDS] = { 0x0033, 0x1001, 0x1101 };
@ -243,6 +244,7 @@ static const struct ConfigOption options[] = {
{.name = "env_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configEnvVolume},
{.name = "fade_distant_sounds", .type = CONFIG_TYPE_BOOL, .boolValue = &configFadeoutDistantSounds},
{.name = "mute_focus_loss", .type = CONFIG_TYPE_BOOL, .boolValue = &configMuteFocusLoss},
{.name = "sound_output", .type = CONFIG_TYPE_UINT, .uintValue = &configSoundOutput},
// control binds
{.name = "key_a", .type = CONFIG_TYPE_BIND, .uintValue = configKeyA},
{.name = "key_b", .type = CONFIG_TYPE_BIND, .uintValue = configKeyB},

View file

@ -71,6 +71,7 @@ extern unsigned int configSfxVolume;
extern unsigned int configEnvVolume;
extern bool configFadeoutDistantSounds;
extern bool configMuteFocusLoss;
extern unsigned int configSoundOutput;
// control binds
extern unsigned int configKeyA[MAX_BINDS];
extern unsigned int configKeyB[MAX_BINDS];

View file

@ -75,9 +75,19 @@ void controller_mouse_read_window(void) {
GetFocus() == game_window);
POINT p;
if (GetCursorPos(&p) && ScreenToClient(game_window, &p)) {
mouse_window_x = p.x - gfx_current_dimensions.x_adjust_4by3;
mouse_window_y = p.y;
if (GetCursorPos(&p)) {
HWND hwnd_under = WindowFromPoint(p);
if (hwnd_under == game_window || IsChild(game_window, hwnd_under)) {
if (ScreenToClient(game_window, &p)) {
mouse_window_x = p.x - gfx_current_dimensions.x_adjust_4by3;
mouse_window_y = p.y;
}
} else {
// invalidate the mouse position
// so the ui isn't interacted with
mouse_window_x = -1000;
mouse_window_y = -1000;
}
}
} else {
mouse_window_buttons = SDL_GetMouseState(&mouse_window_x, &mouse_window_y);

View file

@ -5,6 +5,7 @@
#include "djui_panel_pause.h"
#include "djui_panel_join.h"
#include "djui_panel_join_message.h"
#include "djui_panel_confirm.h"
#include "djui_ctx_display.h"
#include "djui_fps_display.h"
#include "djui_lua_profiler.h"
@ -152,6 +153,17 @@ void djui_connect_menu_open(void) {
djui_panel_join_message_create(NULL);
}
static void djui_update_game(UNUSED struct DjuiBase *caller) {
update_game();
}
void djui_open_update_panel(void) {
djui_panel_shutdown();
gDjuiInMainMenu = true;
djui_panel_main_create(NULL);
djui_panel_confirm_create(NULL, DLANG(UPDATE, UPDATE_TITLE), DLANG(UPDATE, UPDATE_AVAILABLE), djui_update_game);
}
void djui_lua_error(char* text, struct DjuiColor color) {
if (!sDjuiLuaError) { return; }
djui_base_set_color(&sDjuiLuaError->base, color.r, color.g, color.b, color.a);

View file

@ -28,6 +28,7 @@
#include "djui_progress_bar.h"
#include "djui_checkbox.h"
#include "djui_flow_layout.h"
#include "djui_searchbox.h"
#include "djui_selectionbox.h"
#include "djui_bind.h"
#include "djui_popup.h"
@ -46,6 +47,7 @@ extern bool gDjuiDisabled;
void djui_init(void);
void djui_init_late(void);
void djui_connect_menu_open(void);
void djui_open_update_panel(void);
void djui_lua_error(char* text, struct DjuiColor color);
void djui_lua_error_clear(void);
void djui_render(void);

View file

@ -417,7 +417,7 @@ static bool djui_chat_box_input_on_key_down(UNUSED struct DjuiBase* base, int sc
sent_history_init(&sentHistory);
if (gDjuiChatBox == NULL) { return false; }
f32 pageAmount = gDjuiChatBox->chatContainer->base.elem.height * 3.0f / 4.0f;
char previousText[MAX_CHAT_MSG_LENGTH];
@ -547,7 +547,7 @@ struct DjuiChatBox* djui_chat_box_create(void) {
struct DjuiBase* cfBase = &chatFlow->base;
djui_base_set_location(cfBase, 0, 0);
djui_base_set_size_type(cfBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(cfBase, 1.0f, 2);
djui_base_set_size(cfBase, 1.0f, 0);
djui_base_set_color(cfBase, 0, 0, 0, 128);
djui_base_set_padding(cfBase, 2, 2, 2, 2);
djui_flow_layout_set_margin(chatFlow, 2);

View file

@ -96,6 +96,9 @@ void djui_chat_message_create(const char* message) {
chatText->base.comp.width = maxTextWidth;
f32 messageHeight = djui_text_count_lines(chatText, 10) * (chatText->font->lineHeight * chatText->font->defaultFontScale) + 8;
djui_base_set_size(base, 1.0f, messageHeight);
if (gDjuiChatBox->chatFlow->base.height.value == 0) {
gDjuiChatBox->chatFlow->base.height.value = 2;
}
gDjuiChatBox->chatFlow->base.height.value += messageHeight + gDjuiChatBox->chatFlow->margin.value;
if (!gDjuiChatBox->scrolling) {
gDjuiChatBox->chatFlow->base.y.value = gDjuiChatBox->chatContainer->base.elem.height - gDjuiChatBox->chatFlow->base.height.value;

View file

@ -20,15 +20,27 @@ static u8 sCursorBlink = 0;
static void djui_inputbox_update_style(struct DjuiBase* base) {
struct DjuiInputbox* inputbox = (struct DjuiInputbox*)base;
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
if (!inputbox->base.enabled) {
djui_base_set_border_color(base, 90, 90, 90, 255);
djui_base_set_color(&inputbox->base, 140, 140, 140, 255);
struct DjuiColor bc = djui_theme_shade_color(theme->interactables.defaultBorderColor, 0.6f);
struct DjuiColor rc = djui_theme_shade_color(theme->interactables.defaultRectColor, 0.6f);
djui_base_set_border_color(base, bc.r, bc.g, bc.b, bc.a);
djui_base_set_color(&inputbox->base, rc.r, rc.g, rc.b, rc.a);
} else if (gDjuiCursorDownOn == base) {
struct DjuiColor bc = theme->interactables.cursorDownBorderColor;
struct DjuiColor rc = theme->interactables.cursorDownRectColor;
djui_base_set_border_color(base, bc.r, bc.g, bc.b, bc.a);
djui_base_set_color(&inputbox->base, rc.r, rc.g, rc.b, rc.a);
} else if (gDjuiHovered == base) {
djui_base_set_border_color(base, 0, 120, 215, 255);
djui_base_set_color(&inputbox->base, 255, 255, 255, 255);
struct DjuiColor bc = theme->interactables.hoveredBorderColor;
struct DjuiColor rc = theme->interactables.hoveredRectColor;
djui_base_set_border_color(base, bc.r, bc.g, bc.b, bc.a);
djui_base_set_color(&inputbox->base, rc.r, rc.g, rc.b, rc.a);
} else {
djui_base_set_border_color(base, 150, 150, 150, 255);
djui_base_set_color(&inputbox->base, 240, 240, 240, 255);
struct DjuiColor bc = theme->interactables.defaultBorderColor;
struct DjuiColor rc = theme->interactables.defaultRectColor;
djui_base_set_border_color(base, bc.r, bc.g, bc.b, bc.a);
djui_base_set_color(&inputbox->base, rc.r, rc.g, rc.b, rc.a);
}
}
@ -397,7 +409,7 @@ void djui_inputbox_on_text_input(struct DjuiBase *base, char* text) {
inputbox->selection[1] = inputbox->selection[0];
sCursorBlink = 0;
djui_inputbox_on_change(inputbox);
inputbox->imePos = 0;
if (inputbox->imeBuffer != NULL) {
free(inputbox->imeBuffer);
@ -408,9 +420,9 @@ void djui_inputbox_on_text_input(struct DjuiBase *base, char* text) {
void djui_inputbox_on_text_editing(struct DjuiBase *base, char* text, int cursorPos) {
struct DjuiInputbox *inputbox = (struct DjuiInputbox *) base;
inputbox->imePos = (u16)cursorPos;
if (inputbox->imeBuffer != NULL) free(inputbox->imeBuffer);
if (*text == '\0') {
inputbox->imeBuffer = NULL;
}
@ -420,7 +432,7 @@ void djui_inputbox_on_text_editing(struct DjuiBase *base, char* text, int cursor
strcpy(copy,text);
inputbox->imeBuffer = copy;
}
djui_inputbox_on_change(inputbox);
}
@ -469,9 +481,9 @@ static void djui_inputbox_render_selection(struct DjuiInputbox* inputbox) {
}
sCursorBlink = (sCursorBlink + 1) % DJUI_INPUTBOX_MAX_BLINK;
f32 renderX = x;
u16 imePos = inputbox->imePos;
if (imePos != 0) {
char* ime = inputbox->imeBuffer;
@ -480,13 +492,14 @@ static void djui_inputbox_render_selection(struct DjuiInputbox* inputbox) {
ime = djui_unicode_next_char(ime);
}
}
// render only cursor when there is no selection width
if (selection[0] == selection[1]) {
if (sCursorBlink < DJUI_INPUTBOX_MID_BLINK && djui_interactable_is_input_focus(&inputbox->base)) {
create_dl_translation_matrix(DJUI_MTX_PUSH, renderX - DJUI_INPUTBOX_CURSOR_WIDTH / 2.0f, -0.1f, 0);
create_dl_scale_matrix(DJUI_MTX_NOPUSH, DJUI_INPUTBOX_CURSOR_WIDTH, 0.8f, 1.0f);
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255);
struct DjuiColor *textColor = &inputbox->textColor;
gDPSetEnvColor(gDisplayListHead++, textColor->r, textColor->g, textColor->b, textColor->a);
gSPDisplayList(gDisplayListHead++, dl_djui_simple_rect);
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
}
@ -559,7 +572,7 @@ static bool djui_inputbox_render(struct DjuiBase* base) {
// translate position
f32 translatedX = comp->x + inputbox->viewX;
f32 translatedY = comp->y + DJUI_INPUTBOX_YOFF;
f32 translatedY = comp->y + inputbox->yOffset;
djui_gfx_position_translate(&translatedX, &translatedY);
create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0);
@ -584,7 +597,7 @@ static bool djui_inputbox_render(struct DjuiBase* base) {
u16 selection[2] = { 0 };
selection[0] = fmin(inputbox->selection[0], inputbox->selection[1]);
selection[1] = fmax(inputbox->selection[0], inputbox->selection[1]);
// render text
char* c = inputbox->buffer;
f32 drawX = inputbox->viewX;
@ -593,7 +606,7 @@ static bool djui_inputbox_render(struct DjuiBase* base) {
font->render_begin();
for (u16 i = 0; i < inputbox->bufferSize; i++) {
//render composition text
if (selection[0] == i && inputbox->imeBuffer != NULL) {
char *ime = inputbox->imeBuffer;
@ -602,7 +615,7 @@ static bool djui_inputbox_render(struct DjuiBase* base) {
ime = djui_unicode_next_char(ime);
}
}
if (*c == '\0') { break; }
// deal with seleciton color
@ -636,14 +649,16 @@ static void djui_inputbox_destroy(struct DjuiBase* base) {
struct DjuiInputbox* djui_inputbox_create(struct DjuiBase* parent, u16 bufferSize) {
struct DjuiInputbox* inputbox = calloc(1, sizeof(struct DjuiInputbox));
struct DjuiBase* base = &inputbox->base;
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
struct DjuiColor* textColor = &theme->interactables.textColor;
inputbox->bufferSize = bufferSize;
inputbox->buffer = calloc(bufferSize, sizeof(char));
inputbox->yOffset = DJUI_INPUTBOX_YOFF;
djui_base_init(parent, base, djui_inputbox_render, djui_inputbox_destroy);
djui_base_set_size(base, 200, 32);
djui_base_set_border_width(base, 2);
djui_base_set_gradient(base, false);
djui_inputbox_set_text_color(inputbox, 0, 0, 0, 255);
djui_inputbox_set_text_color(inputbox, textColor->r, textColor->g, textColor->b, textColor->a);
djui_interactable_create(base, djui_inputbox_update_style);
djui_interactable_hook_cursor_down(base, djui_inputbox_on_cursor_down_begin, djui_inputbox_on_cursor_down, NULL);
djui_interactable_hook_key(base, djui_inputbox_on_key_down, djui_inputbox_on_key_up);

View file

@ -8,6 +8,7 @@ struct DjuiInputbox {
u16 bufferSize;
u16 selection[2];
f32 viewX;
f32 yOffset;
struct DjuiColor textColor;
void (*on_enter_press)(struct DjuiInputbox*);
void (*on_escape_press)(struct DjuiInputbox*);

View file

@ -26,9 +26,11 @@ static void djui_panel_display_framerate_mode_change(UNUSED struct DjuiBase* cal
static void djui_panel_display_frame_limit_text_change(struct DjuiBase* caller) {
struct DjuiInputbox* inputbox1 = (struct DjuiInputbox*)caller;
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
struct DjuiColor* textColor = &theme->interactables.textColor;
s32 frameLimit = atoi(inputbox1->buffer);
if (frameLimit >= 30 && frameLimit <= 3000) {
djui_inputbox_set_text_color(inputbox1, 0, 0, 0, 255);
djui_inputbox_set_text_color(inputbox1, textColor->r, textColor->g, textColor->b, textColor->a);
configFrameLimit = frameLimit;
} else {
djui_inputbox_set_text_color(inputbox1, 255, 0, 0, 255);
@ -129,8 +131,16 @@ void djui_panel_display_create(struct DjuiBase* caller) {
djui_selectionbox_create(body, DLANG(DISPLAY, ANTIALIASING), msaaChoices, choiceCount, &sMsaaSelection, djui_panel_display_msaa_change);
}
char* drawDistanceChoices[6] = { DLANG(DISPLAY, D0P5X), DLANG(DISPLAY, D1X), DLANG(DISPLAY, D1P5X), DLANG(DISPLAY, D3X), DLANG(DISPLAY, D10X), DLANG(DISPLAY, D100X) };
djui_selectionbox_create(body, DLANG(DISPLAY, DRAW_DISTANCE), drawDistanceChoices, 6, &configDrawDistance, NULL);
char* drawDistanceChoices[] = {
DLANG(DISPLAY, D0P5X),
DLANG(DISPLAY, D1X),
DLANG(DISPLAY, D1P5X),
DLANG(DISPLAY, D3X),
DLANG(DISPLAY, D10X),
DLANG(DISPLAY, D100X),
DLANG(DISPLAY, INFINITE),
};
djui_selectionbox_create(body, DLANG(DISPLAY, DRAW_DISTANCE), drawDistanceChoices, ARRAY_COUNT(drawDistanceChoices), &configDrawDistance, NULL);
djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_menu_back);

View file

@ -10,6 +10,10 @@
#include "game/level_update.h"
#include "pc/lua/smlua_hooks.h"
static struct DjuiFlowLayout* sDynosLayout = NULL;
static struct DjuiPaginated* sDynosPaginated = NULL;
static struct DjuiInputbox* sSearchInputbox = NULL;
void djui_panel_dynos_create(struct DjuiBase* caller);
static void djui_panel_dynos_apply(struct DjuiBase* caller) {
@ -37,27 +41,47 @@ static void djui_panel_dynos_destroy(UNUSED struct DjuiBase* caller) {
gDjuiInPlayerMenu = false;
}
static void djui_panel_dynos_add_packs(struct DjuiBase* base) {
int packCount = dynos_pack_get_count();
for (int i = 0; i < packCount; i++) {
if (!dynos_pack_get_exists(i)) { continue; }
bool tmp = dynos_pack_get_enabled(i);
const char* pack = dynos_pack_get_name(i);
// filter results
if (sSearchInputbox != NULL &&
sSearchInputbox->buffer != NULL &&
!strcasestr(djui_text_get_uncolored_string(NULL, strlen(pack) + 1, pack), sSearchInputbox->buffer)
) {
continue;
}
struct DjuiCheckbox* checkbox1 = djui_checkbox_create(base, pack, &tmp, djui_panel_dynos_apply);
checkbox1->base.tag = i;
checkbox1->base.bTag = tmp;
checkbox1->value = &checkbox1->base.bTag;
}
}
static void djui_panel_dynos_rebuild_list(UNUSED struct DjuiBase* caller) {
djui_base_destroy_children(&sDynosLayout->base);
djui_panel_dynos_add_packs(&sDynosLayout->base);
djui_paginated_calculate_height(sDynosPaginated);
}
void djui_panel_dynos_create(struct DjuiBase* caller) {
gDjuiInPlayerMenu = true;
int packCount = dynos_pack_get_count();
struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(DYNOS, DYNOS), true);
struct DjuiBase* body = djui_three_panel_get_body(panel);
{
struct DjuiSearchbox* searchbox = djui_searchbox_create(body, djui_panel_dynos_rebuild_list);
sSearchInputbox = searchbox->inputbox;
struct DjuiPaginated* paginated = djui_paginated_create(body, 8);
struct DjuiBase* layoutBase = &paginated->layout->base;
for (int i = 0; i < packCount; i++) {
if (dynos_pack_get_exists(i)) {
bool tmp = dynos_pack_get_enabled(i);
const char* pack = dynos_pack_get_name(i);
struct DjuiCheckbox* checkbox1 = djui_checkbox_create(layoutBase, pack, &tmp, djui_panel_dynos_apply);
checkbox1->base.tag = i;
checkbox1->base.bTag = tmp;
checkbox1->value = &checkbox1->base.bTag;
}
}
sDynosLayout = paginated->layout;
djui_panel_dynos_add_packs(layoutBase);
djui_paginated_calculate_height(paginated);
sDynosPaginated = paginated;
struct DjuiRect* space = djui_rect_create(body);
djui_base_set_size_type(&space->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);

View file

@ -45,8 +45,10 @@ static bool djui_panel_host_port_valid(void) {
static void djui_panel_host_port_text_change(struct DjuiBase* caller) {
struct DjuiInputbox* sInputboxPort = (struct DjuiInputbox*)caller;
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
struct DjuiColor* textColor = &theme->interactables.textColor;
if (djui_panel_host_port_valid()) {
djui_inputbox_set_text_color(sInputboxPort, 0, 0, 0, 255);
djui_inputbox_set_text_color(sInputboxPort, textColor->r, textColor->g, textColor->b, textColor->a);
} else {
djui_inputbox_set_text_color(sInputboxPort, 255, 0, 0, 255);
}

View file

@ -25,6 +25,7 @@ static struct DjuiText* sTooltip = NULL;
static struct DjuiPaginated* sModPaginated = NULL;
static struct DjuiButton* sBackButton = NULL;
static struct DjuiButton* sRefreshButton = NULL;
static struct DjuiInputbox* sSearchInputbox = NULL;
static unsigned int sSelectedCategory = MOD_CATEGORY_ALL;
static bool sWarned = false;
@ -174,6 +175,13 @@ void djui_panel_host_mods_add_mods(struct DjuiBase* layoutBase) {
break;
}
}
// filter results
if (sSearchInputbox != NULL &&
sSearchInputbox->buffer != NULL &&
!strcasestr(djui_text_get_uncolored_string(NULL, strlen(mod->name) + 1, mod->name), sSearchInputbox->buffer)
) {
continue;
}
struct DjuiCheckbox* checkbox = djui_checkbox_create(layoutBase, mod->name, &mod->enabled, djui_mod_checkbox_on_value_change);
checkbox->base.tag = i;
djui_base_set_enabled(&checkbox->base, mod->selectable);
@ -189,7 +197,7 @@ void djui_panel_host_mods_add_mods(struct DjuiBase* layoutBase) {
}
}
static void djui_panel_on_categories_change(UNUSED struct DjuiBase* caller) {
static void djui_panel_rebuild_mods_list(UNUSED struct DjuiBase* caller) {
if (gModRefreshThread.state == RUNNING) { return; }
djui_base_destroy_children(&sModLayout->base);
djui_panel_host_mods_add_mods(&sModLayout->base);
@ -234,14 +242,15 @@ void djui_panel_host_mods_create(struct DjuiBase* caller) {
struct DjuiBase* body = djui_three_panel_get_body(panel);
{
// copy category choices from sCategories
char* categoryChoices[sizeof(sCategories)];
struct DjuiSearchbox* searchbox = djui_searchbox_create(body, djui_panel_rebuild_mods_list);
sSearchInputbox = searchbox->inputbox;
// loop thru all categories names, and add those to the categoryChoices string array
char* categoryChoices[sizeof(sCategories)];
for (int i = 0; i < numCategories; i++) {
categoryChoices[i] = djui_language_get("HOST_MOD_CATEGORIES", sCategories[i].langKey);
}
djui_selectionbox_create(body, DLANG(HOST_MODS, CATEGORIES), categoryChoices, numCategories, &sSelectedCategory, djui_panel_on_categories_change);
djui_selectionbox_create(body, DLANG(HOST_MODS, CATEGORIES), categoryChoices, numCategories, &sSelectedCategory, djui_panel_rebuild_mods_list);
struct DjuiPaginated* paginated = djui_paginated_create(body, 8);
paginated->showMaxCount = true;
sModLayout = paginated->layout;
@ -259,7 +268,7 @@ void djui_panel_host_mods_create(struct DjuiBase* caller) {
djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_menu_back);
}
panel->bodySize.value = paginated->base.height.value + 64 + 64;
panel->bodySize.value = paginated->base.height.value + 64 + 64 + 64;
}
panel->base.destroy = djui_panel_host_mods_destroy;

View file

@ -34,8 +34,10 @@ static bool djui_panel_host_limit_valid(void) {
static void djui_panel_host_player_text_change(struct DjuiBase* caller) {
struct DjuiInputbox* inputbox1 = (struct DjuiInputbox*)caller;
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
struct DjuiColor* textColor = &theme->interactables.textColor;
if (djui_panel_host_limit_valid()) {
djui_inputbox_set_text_color(inputbox1, 0, 0, 0, 255);
djui_inputbox_set_text_color(inputbox1, textColor->r, textColor->g, textColor->b, textColor->a);
} else {
djui_inputbox_set_text_color(inputbox1, 255, 0, 0, 255);
return;

View file

@ -86,8 +86,10 @@ UNUSED static bool djui_panel_join_direct_ip_valid(char* buffer) {
static void djui_panel_join_direct_ip_text_change(struct DjuiBase* caller) {
struct DjuiInputbox* inputbox1 = (struct DjuiInputbox*)caller;
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
struct DjuiColor* textColor = &theme->interactables.textColor;
if (strlen(inputbox1->buffer) > 2) {
djui_inputbox_set_text_color(inputbox1, 0, 0, 0, 255);
djui_inputbox_set_text_color(inputbox1, textColor->r, textColor->g, textColor->b, textColor->a);
} else {
djui_inputbox_set_text_color(inputbox1, 255, 0, 0, 255);
}

View file

@ -160,8 +160,10 @@ static char* djui_panel_player_edit_palette_preset_name_get_text(void) {
static void djui_panel_player_edit_palette_preset_name_text_change(struct DjuiBase* caller) {
struct DjuiInputbox* inputbox1 = (struct DjuiInputbox*)caller;
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
struct DjuiColor* textColor = &theme->interactables.textColor;
if (djui_panel_player_edit_palette_preset_name_valid(inputbox1->buffer)) {
djui_inputbox_set_text_color(inputbox1, 0, 0, 0, 255);
djui_inputbox_set_text_color(inputbox1, textColor->r, textColor->g, textColor->b, textColor->a);
} else {
djui_inputbox_set_text_color(inputbox1, 255, 0, 0, 255);
}
@ -169,10 +171,12 @@ static void djui_panel_player_edit_palette_preset_name_text_change(struct DjuiBa
static void djui_panel_player_edit_palette_preset_name_on_focus_end(struct DjuiBase* caller) {
struct DjuiInputbox* inputbox1 = (struct DjuiInputbox*)caller;
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
struct DjuiColor* textColor = &theme->interactables.textColor;
if (!djui_panel_player_edit_palette_preset_name_valid(inputbox1->buffer)) {
djui_inputbox_set_text(inputbox1, djui_panel_player_edit_palette_preset_name_get_text());
}
djui_inputbox_set_text_color(inputbox1, 0, 0, 0, 255);
djui_inputbox_set_text_color(inputbox1, textColor->r, textColor->g, textColor->b, textColor->a);
djui_inputbox_on_focus_end(&inputbox1->base);
}
@ -403,8 +407,10 @@ static char *djui_panel_player_name_default_get(void) {
static void djui_panel_player_name_text_change(struct DjuiBase* caller) {
struct DjuiInputbox* inputbox1 = (struct DjuiInputbox*)caller;
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
struct DjuiColor* textColor = &theme->interactables.textColor;
if (network_player_name_valid(inputbox1->buffer)) {
djui_inputbox_set_text_color(inputbox1, 0, 0, 0, 255);
djui_inputbox_set_text_color(inputbox1, textColor->r, textColor->g, textColor->b, textColor->a);
} else {
djui_inputbox_set_text_color(inputbox1, 255, 0, 0, 255);
}
@ -412,11 +418,13 @@ static void djui_panel_player_name_text_change(struct DjuiBase* caller) {
static void djui_panel_player_name_on_focus_end(struct DjuiBase* caller) {
struct DjuiInputbox* inputbox1 = (struct DjuiInputbox*)caller;
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
struct DjuiColor* textColor = &theme->interactables.textColor;
if (!network_player_name_valid(inputbox1->buffer)) {
djui_inputbox_set_text(inputbox1, djui_panel_player_name_default_get());
}
snprintf(configPlayerName, MAX_CONFIG_STRING, "%s", inputbox1->buffer);
djui_inputbox_set_text_color(inputbox1, 0, 0, 0, 255);
djui_inputbox_set_text_color(inputbox1, textColor->r, textColor->g, textColor->b, textColor->a);
if (gNetworkType != NT_NONE) {
network_send_player_settings();

View file

@ -4,21 +4,31 @@
#include "pc/utils/misc.h"
#include "pc/configfile.h"
#include "pc/lua/utils/smlua_audio_utils.h"
#include "game/sound_init.h"
static void djui_panel_sound_value_change(UNUSED struct DjuiBase* caller) {
audio_custom_update_volume();
}
static void djui_panel_sound_output_change(UNUSED struct DjuiBase* caller) {
set_sound_mode(configSoundOutput);
}
void djui_panel_sound_create(struct DjuiBase* caller) {
struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(SOUND, SOUND), false);
struct DjuiBase* body = djui_three_panel_get_body(panel);
{
char* outputChoices[3] = { DLANG(SOUND, STEREO), DLANG(SOUND, MONO), DLANG(SOUND, HEADSET) };
djui_selectionbox_create(body, DLANG(SOUND, SOUND_OUTPUT), outputChoices, 3, &configSoundOutput, djui_panel_sound_output_change);
djui_slider_create(body, DLANG(SOUND, MASTER_VOLUME), &configMasterVolume, 0, 127, djui_panel_sound_value_change);
djui_slider_create(body, DLANG(SOUND, MUSIC_VOLUME), &configMusicVolume, 0, 127, djui_panel_sound_value_change);
djui_slider_create(body, DLANG(SOUND, SFX_VOLUME), &configSfxVolume, 0, 127, djui_panel_sound_value_change);
djui_slider_create(body, DLANG(SOUND, ENV_VOLUME), &configEnvVolume, 0, 127, djui_panel_sound_value_change);
djui_checkbox_create(body, DLANG(SOUND, FADEOUT), &configFadeoutDistantSounds, NULL);
djui_checkbox_create(body, DLANG(SOUND, MUTE_FOCUS_LOSS), &configMuteFocusLoss, NULL);
djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_menu_back);
}

View file

@ -0,0 +1,63 @@
#include <stdio.h>
#include <string.h>
#include "djui.h"
static void djui_searchbox_destroy(struct DjuiBase* base) {
struct DjuiSearchbox* searchbox = (struct DjuiSearchbox*)base;
free(searchbox);
}
static void djui_searchbox_on_value_change(struct DjuiBase* base) {
struct DjuiInputbox* input = (struct DjuiInputbox*)base;
struct DjuiSearchbox* searchbox = (struct DjuiSearchbox*)input->base.parent->parent;
if (input->buffer[0] != '\0') {
djui_base_set_visible(&searchbox->text->base, false);
} else {
djui_base_set_visible(&searchbox->text->base, true);
}
if (searchbox->on_value_change) {
searchbox->on_value_change(base);
}
}
struct DjuiSearchbox* djui_searchbox_create(struct DjuiBase* parent, void (*on_value_change)(struct DjuiBase*)) {
struct DjuiSearchbox* searchbox = calloc(1, sizeof(struct DjuiSearchbox));
struct DjuiBase* base = &searchbox->base;
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
struct DjuiColor disabledTextColor = theme->interactables.disabledTextColor;
djui_base_init(parent, base, NULL, djui_searchbox_destroy);
djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(base, 1.0f, 35.0f);
struct DjuiFlowLayout* searchFlow = djui_flow_layout_create(base);
djui_base_set_color(&searchFlow->base, 0, 0, 0, 0);
djui_base_set_size_type(&searchFlow->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&searchFlow->base, 1.0f, 35.0f);
djui_flow_layout_set_margin(searchFlow, 0);
djui_flow_layout_set_flow_direction(searchFlow, DJUI_FLOW_DIR_RIGHT);
struct DjuiInputbox* searchInputBox = djui_inputbox_create(&searchFlow->base, 64);
djui_base_set_alignment(&searchInputBox->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_CENTER);
djui_base_set_size_type(&searchInputBox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&searchInputBox->base, 1.0f, 35.0f);
djui_interactable_hook_value_change(&searchInputBox->base, djui_searchbox_on_value_change);
searchInputBox->yOffset = 0;
searchbox->inputbox = searchInputBox;
struct DjuiText* text = djui_text_create(&searchInputBox->base, DLANG(MENU, SEARCH));
djui_base_set_color(&text->base, disabledTextColor.r, disabledTextColor.g, disabledTextColor.b, disabledTextColor.a);
djui_base_set_alignment(&text->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_CENTER);
djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE);
djui_base_set_size(&text->base, 1.0f, 1.0f);
djui_text_set_alignment(text, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
djui_text_set_drop_shadow(text, 64, 64, 64, 100);
searchbox->text = text;
searchbox->on_value_change = on_value_change;
return searchbox;
}

View file

@ -0,0 +1,12 @@
#pragma once
#include "djui.h"
struct DjuiSearchbox {
struct DjuiBase base;
struct DjuiText* text;
struct DjuiImage* image;
struct DjuiInputbox* inputbox;
void (*on_value_change)(struct DjuiBase*);
};
struct DjuiSearchbox* djui_searchbox_create(struct DjuiBase* base, void (*on_value_change)(struct DjuiBase*));

View file

@ -7,6 +7,9 @@ static struct DjuiTheme sDjuiThemeLight = {
.textColor = {
11, 11, 11, 255
},
.disabledTextColor = {
60, 60, 60, 255
},
.defaultRectColor = {
222, 222, 222, 255
@ -48,6 +51,9 @@ static struct DjuiTheme sDjuiThemeDark = {
.textColor = {
220, 220, 220, 255
},
.disabledTextColor = {
140, 140, 140, 255
},
.defaultRectColor = {
22, 22, 22, 255
@ -89,6 +95,9 @@ static struct DjuiTheme sDjuiThemeFileSelect = {
.textColor = {
11, 11, 11, 255
},
.disabledTextColor = {
60, 60, 60, 255
},
.defaultRectColor = {
200, 215, 197, 255
@ -130,6 +139,9 @@ static struct DjuiTheme sDjuiThemeMario = {
.textColor = {
11, 11, 11, 255
},
.disabledTextColor = {
60, 60, 60, 255
},
.defaultRectColor = {
255, 227, 0, 255
@ -171,6 +183,9 @@ static struct DjuiTheme sDjuiThemeOdyssey = {
.textColor = {
11, 11, 11, 255
},
.disabledTextColor = {
60, 60, 60, 255
},
.defaultRectColor = {
255, 255, 255, 255

View file

@ -15,6 +15,7 @@ enum DjuiThemeType {
struct DjuiInteractableTheme {
struct DjuiColor textColor;
struct DjuiColor disabledTextColor;
struct DjuiColor defaultRectColor;
struct DjuiColor cursorDownRectColor;

View file

@ -46,6 +46,7 @@ struct GfxVertex {
struct RGBA color;
uint8_t fog_z;
uint8_t clip_rej;
uint8_t world_geometry;
};
struct GfxDimensions {

View file

@ -72,12 +72,13 @@ struct CombineMode {
};
union {
struct {
uint8_t use_alpha : 1;
uint8_t use_fog : 1;
uint8_t texture_edge : 1;
uint8_t use_dither : 1;
uint8_t use_2cycle : 1;
uint8_t light_map : 1;
uint8_t use_alpha : 1;
uint8_t use_fog : 1;
uint8_t texture_edge : 1;
uint8_t use_dither : 1;
uint8_t use_2cycle : 1;
uint8_t light_map : 1;
uint8_t world_geometry : 1;
};
uint32_t flags;
};

View file

@ -17,6 +17,9 @@
#endif
#include <PR/gbi.h>
#include "types.h"
#include "pc/configfile.h"
#include "gfx_cc.h"
#include "gfx_window_manager_api.h"
#include "gfx_rendering_api.h"
@ -24,6 +27,7 @@
extern "C" {
#include "pc/controller/controller_bind_mapping.h"
extern Color gVertexColor;
}
#define DECLARE_GFX_DXGI_FUNCTIONS
@ -31,7 +35,6 @@ extern "C" {
#include "gfx_screen_config.h"
#define THREE_POINT_FILTERING 0
#define DEBUG_D3D 0
using namespace Microsoft::WRL; // For ComPtr
@ -52,6 +55,13 @@ struct PerDrawCB {
uint32_t linear_filtering;
uint32_t padding;
} textures[2];
uint32_t filter;
uint32_t padding[3];
};
struct LightmapCB {
float color[3];
float padding;
};
struct TextureData {
@ -72,6 +82,7 @@ struct ShaderProgramD3D11 {
uint8_t num_inputs;
uint8_t num_floats;
bool used_textures[2];
bool used_lightmap;
};
static struct {
@ -93,6 +104,7 @@ static struct {
ComPtr<ID3D11Buffer> vertex_buffer;
ComPtr<ID3D11Buffer> per_frame_cb;
ComPtr<ID3D11Buffer> per_draw_cb;
ComPtr<ID3D11Buffer> lightmap_cb;
#if DEBUG_D3D
ComPtr<ID3D11Debug> debug;
@ -102,6 +114,7 @@ static struct {
PerFrameCB per_frame_cb_data;
PerDrawCB per_draw_cb_data;
LightmapCB lightmap_cb_data;
struct ShaderProgramD3D11 shader_program_pool[CC_MAX_SHADERS];
uint8_t shader_program_pool_size;
@ -309,6 +322,19 @@ static void gfx_d3d11_init(void) {
d3d.context->PSSetConstantBuffers(1, 1, d3d.per_draw_cb.GetAddressOf());
// Create lightmap constant buffer
constant_buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
constant_buffer_desc.ByteWidth = (sizeof(LightmapCB) + 15) / 16 * 16;
constant_buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constant_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
constant_buffer_desc.MiscFlags = 0;
ThrowIfFailed(d3d.device->CreateBuffer(&constant_buffer_desc, nullptr, d3d.lightmap_cb.GetAddressOf()),
gfx_dxgi_get_h_wnd(), "Failed to create lightmap constant buffer.");
d3d.context->PSSetConstantBuffers(2, 1, d3d.lightmap_cb.GetAddressOf());
controller_bind_init();
}
@ -331,7 +357,7 @@ static struct ShaderProgram *gfx_d3d11_create_and_load_new_shader(struct ColorCo
char buf[4096];
size_t len, num_floats;
gfx_direct3d_common_build_shader(buf, len, num_floats, *cc, cc_features, false, THREE_POINT_FILTERING);
gfx_direct3d_common_build_shader(buf, len, num_floats, *cc, cc_features, false);
ComPtr<ID3DBlob> vs, ps;
ComPtr<ID3DBlob> error_blob;
@ -414,6 +440,7 @@ static struct ShaderProgram *gfx_d3d11_create_and_load_new_shader(struct ColorCo
prg->num_floats = num_floats;
prg->used_textures[0] = cc_features.used_textures[0];
prg->used_textures[1] = cc_features.used_textures[1];
prg->used_lightmap = cc->cm.light_map;
return (struct ShaderProgram *)(d3d.shader_program = prg);
}
@ -504,11 +531,7 @@ static void gfx_d3d11_set_sampler_parameters(int tile, bool linear_filter, uint3
D3D11_SAMPLER_DESC sampler_desc;
ZeroMemory(&sampler_desc, sizeof(D3D11_SAMPLER_DESC));
#if THREE_POINT_FILTERING
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
#else
sampler_desc.Filter = linear_filter ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT;
#endif
sampler_desc.AddressU = gfx_cm_to_d3d11(cms);
sampler_desc.AddressV = gfx_cm_to_d3d11(cmt);
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
@ -611,28 +634,37 @@ static void gfx_d3d11_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t
for (int32_t i = 0; i < 2; i++) {
if (d3d.shader_program->used_textures[i]) {
if (d3d.last_resource_views[i].Get() != d3d.textures[d3d.current_texture_ids[i]].resource_view.Get()) {
d3d.last_resource_views[i] = d3d.textures[d3d.current_texture_ids[i]].resource_view.Get();
d3d.context->PSSetShaderResources(i, 1, d3d.textures[d3d.current_texture_ids[i]].resource_view.GetAddressOf());
TextureData &texture_data = d3d.textures[d3d.current_texture_ids[i]];
bool resource_changed = d3d.last_resource_views[i].Get() != texture_data.resource_view.Get();
bool sampler_changed = d3d.last_sampler_states[i].Get() != texture_data.sampler_state.Get();
#if THREE_POINT_FILTERING
d3d.per_draw_cb_data.textures[i].width = d3d.textures[d3d.current_texture_ids[i]].width;
d3d.per_draw_cb_data.textures[i].height = d3d.textures[d3d.current_texture_ids[i]].height;
d3d.per_draw_cb_data.textures[i].linear_filtering = d3d.textures[d3d.current_texture_ids[i]].linear_filtering;
if (resource_changed) {
d3d.last_resource_views[i] = texture_data.resource_view.Get();
d3d.context->PSSetShaderResources(i, 1, texture_data.resource_view.GetAddressOf());
}
if (sampler_changed) {
d3d.last_sampler_states[i] = texture_data.sampler_state.Get();
d3d.context->PSSetSamplers(i, 1, texture_data.sampler_state.GetAddressOf());
}
if (resource_changed || sampler_changed) {
d3d.per_draw_cb_data.textures[i].width = texture_data.width;
d3d.per_draw_cb_data.textures[i].height = texture_data.height;
d3d.per_draw_cb_data.textures[i].linear_filtering = texture_data.linear_filtering;
textures_changed = true;
#endif
if (d3d.last_sampler_states[i].Get() != d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get()) {
d3d.last_sampler_states[i] = d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get();
d3d.context->PSSetSamplers(i, 1, d3d.textures[d3d.current_texture_ids[i]].sampler_state.GetAddressOf());
}
}
}
}
// Set per-draw constant buffer
if (textures_changed) {
bool per_draw_cb_dirty = textures_changed;
if (d3d.per_draw_cb_data.filter != configFiltering) {
d3d.per_draw_cb_data.filter = configFiltering;
per_draw_cb_dirty = true;
}
if (per_draw_cb_dirty) {
D3D11_MAPPED_SUBRESOURCE ms;
ZeroMemory(&ms, sizeof(D3D11_MAPPED_SUBRESOURCE));
d3d.context->Map(d3d.per_draw_cb.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &ms);
@ -640,6 +672,20 @@ static void gfx_d3d11_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t
d3d.context->Unmap(d3d.per_draw_cb.Get(), 0);
}
// Set lightmap constant buffer
if (d3d.shader_program->used_lightmap) {
d3d.lightmap_cb_data.color[0] = gVertexColor[0] / 255.0f;
d3d.lightmap_cb_data.color[1] = gVertexColor[1] / 255.0f;
d3d.lightmap_cb_data.color[2] = gVertexColor[2] / 255.0f;
D3D11_MAPPED_SUBRESOURCE ms;
ZeroMemory(&ms, sizeof(D3D11_MAPPED_SUBRESOURCE));
d3d.context->Map(d3d.lightmap_cb.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &ms);
memcpy(ms.pData, &d3d.lightmap_cb_data, sizeof(LightmapCB));
d3d.context->Unmap(d3d.lightmap_cb.Get(), 0);
}
// Set vertex buffer data
D3D11_MAPPED_SUBRESOURCE ms;

View file

@ -122,7 +122,7 @@ static void append_formula(char *buf, size_t *len, const uint8_t* c, bool do_sin
}
}
void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_floats, struct ColorCombiner& cc, const CCFeatures& ccf, bool include_root_signature, bool three_point_filtering) {
void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_floats, struct ColorCombiner& cc, const CCFeatures& ccf, bool include_root_signature) {
len = 0;
num_floats = 4;
@ -194,17 +194,26 @@ void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_f
append_line(buf, &len, "}");
}
if (cc.cm.light_map) {
append_line(buf, &len, "cbuffer LightmapCB : register(b2) {");
append_line(buf, &len, " float3 lightmap_color;");
append_line(buf, &len, "}");
}
// 3 point texture filtering
// Original author: ArthurCarvalho
// Based on GLSL implementation by twinaphex, mupen64plus-libretro project.
if (three_point_filtering && (ccf.used_textures[0] || ccf.used_textures[1])) {
if (ccf.used_textures[0] || ccf.used_textures[1]) {
append_line(buf, &len, "cbuffer PerDrawCB : register(b1) {");
append_line(buf, &len, " struct {");
append_line(buf, &len, " uint width;");
append_line(buf, &len, " uint height;");
append_line(buf, &len, " bool linear_filtering;");
append_line(buf, &len, " bool padding;");
append_line(buf, &len, " } textures[2];");
append_line(buf, &len, " uint filter;");
append_line(buf, &len, " uint padding[3];");
append_line(buf, &len, "}");
append_line(buf, &len, "#define TEX_OFFSET(tex, tSampler, texCoord, off, texSize) tex.Sample(tSampler, texCoord - off / texSize)");
append_line(buf, &len, "float4 tex2D3PointFilter(in Texture2D tex, in SamplerState tSampler, in float2 texCoord, in float2 texSize) {");
@ -269,38 +278,27 @@ void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_f
}
if (ccf.used_textures[0]) {
if (three_point_filtering) {
append_line(buf, &len, " float4 texVal0;");
append_line(buf, &len, " if (textures[0].linear_filtering)");
append_line(buf, &len, " texVal0 = tex2D3PointFilter(g_texture0, g_sampler0, input.uv0, float2(textures[0].width, textures[0].height));");
append_line(buf, &len, " else");
append_line(buf, &len, " texVal0 = g_texture0.Sample(g_sampler0, input.uv0);");
} else {
append_line(buf, &len, " float4 texVal0 = g_texture0.Sample(g_sampler0, input.uv0);");
}
append_line(buf, &len, " float4 texVal0;");
append_line(buf, &len, " if (textures[0].linear_filtering && filter == 2)");
append_line(buf, &len, " texVal0 = tex2D3PointFilter(g_texture0, g_sampler0, input.uv0, float2(textures[0].width, textures[0].height));");
append_line(buf, &len, " else");
append_line(buf, &len, " texVal0 = g_texture0.Sample(g_sampler0, input.uv0);");
}
if (ccf.used_textures[1]) {
if (cc.cm.light_map) {
if (three_point_filtering) {
append_line(buf, &len, " float4 texVal1;");
append_line(buf, &len, " if (textures[1].linear_filtering)");
append_line(buf, &len, " texVal1 = tex2D3PointFilter(g_texture1, g_sampler1, input.lightmap, float2(textures[1].width, textures[1].height));");
append_line(buf, &len, " else");
append_line(buf, &len, " texVal1 = g_texture1.Sample(g_sampler1, input.lightmap);");
} else {
append_line(buf, &len, " float4 texVal1 = g_texture1.Sample(g_sampler1, input.lightmap);");
}
append_line(buf, &len, " float4 texVal1;");
append_line(buf, &len, " if (textures[1].linear_filtering && filter == 2)");
append_line(buf, &len, " texVal1 = tex2D3PointFilter(g_texture1, g_sampler1, input.lightmap, float2(textures[1].width, textures[1].height));");
append_line(buf, &len, " else");
append_line(buf, &len, " texVal1 = g_texture1.Sample(g_sampler1, input.lightmap);");
append_line(buf, &len, " texVal1.rgb = texVal1.rgb * texVal1.rgb + texVal1.rgb;");
append_line(buf, &len, " texVal0.rgb *= lightmap_color;");
} else {
if (three_point_filtering) {
append_line(buf, &len, " float4 texVal1;");
append_line(buf, &len, " if (textures[1].linear_filtering)");
append_line(buf, &len, " texVal1 = tex2D3PointFilter(g_texture1, g_sampler1, input.uv1, float2(textures[1].width, textures[1].height));");
append_line(buf, &len, " else");
append_line(buf, &len, " texVal1 = g_texture1.Sample(g_sampler1, input.uv1);");
} else {
append_line(buf, &len, " float4 texVal1 = g_texture1.Sample(g_sampler1, input.uv1);");
}
append_line(buf, &len, " float4 texVal1;");
append_line(buf, &len, " if (textures[1].linear_filtering && filter == 2)");
append_line(buf, &len, " texVal1 = tex2D3PointFilter(g_texture1, g_sampler1, input.uv1, float2(textures[1].width, textures[1].height));");
append_line(buf, &len, " else");
append_line(buf, &len, " texVal1 = g_texture1.Sample(g_sampler1, input.uv1);");
}
}

View file

@ -7,7 +7,7 @@
#include "gfx_cc.h"
void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_floats, struct ColorCombiner& cc, const CCFeatures& cc_features, bool include_root_signature, bool three_point_filtering);
void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_floats, struct ColorCombiner& cc, const CCFeatures& cc_features, bool include_root_signature);
#endif

View file

@ -394,12 +394,13 @@ static void gfx_dxgi_init(const char *window_title) {
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = nullptr;
wcex.hIcon = nullptr;
HINSTANCE hInstance = GetModuleHandle(NULL);
wcex.hIcon = LoadIconW(hInstance, L"id");
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = WINCLASS_NAME;
wcex.hIconSm = nullptr;
wcex.hIconSm = (HICON)LoadImageW(hInstance, L"id", IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
ATOM winclass = RegisterClassExW(&wcex);
@ -411,6 +412,14 @@ static void gfx_dxgi_init(const char *window_title) {
dxgi.h_wnd = CreateWindowW(WINCLASS_NAME, w_title, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, wr.right - wr.left, wr.bottom - wr.top, nullptr, nullptr, nullptr, nullptr);
// Set the window icons
if (wcex.hIcon) {
SendMessage(dxgi.h_wnd, WM_SETICON, ICON_BIG, (LPARAM)wcex.hIcon);
}
if (wcex.hIconSm) {
SendMessage(dxgi.h_wnd, WM_SETICON, ICON_SMALL, (LPARAM)wcex.hIconSm);
}
});
load_dxgi_library();

View file

@ -41,11 +41,12 @@ struct ShaderProgram {
bool used_textures[2];
uint8_t num_floats;
GLint attrib_locations[7];
GLint uniform_locations[7];
GLint uniform_locations[9];
uint8_t attrib_sizes[7];
uint8_t num_attribs;
bool used_noise;
bool used_lightmap;
bool world_geometry;
};
struct GLTexture {
@ -88,7 +89,12 @@ static void gfx_opengl_vertex_array_set_attribs(struct ShaderProgram *prg) {
static inline void gfx_opengl_set_shader_uniforms(struct ShaderProgram *prg) {
if (prg->used_noise) { glUniform1f(prg->uniform_locations[4], (float)frame_count); }
if (prg->used_lightmap) { glUniform3f(prg->uniform_locations[5], gVertexColor[0] / 255.0f, gVertexColor[1] / 255.0f, gVertexColor[2] / 255.0f); }
glUniform1i(prg->uniform_locations[6], configFiltering);
if (prg->world_geometry) {
glUniform1iv(prg->uniform_locations[6], SHADER_FLAG_MAX, gShaderFlags);
glUniform1fv(prg->uniform_locations[7], SHADER_FLAG_MAX, gShaderFlagValues);
}
glUniform1i(prg->uniform_locations[8], configFiltering);
}
static inline void gfx_opengl_set_texture_uniforms(struct ShaderProgram *prg, const int tile) {
@ -245,6 +251,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
bool opt_texture_edge = cc->cm.texture_edge;
bool opt_2cycle = cc->cm.use_2cycle;
bool opt_light_map = cc->cm.light_map;
bool world_geometry = cc->cm.world_geometry;
#ifdef USE_GLES
bool opt_dither = false;
@ -252,8 +259,8 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
bool opt_dither = cc->cm.use_dither;
#endif
char vs_buf[1024];
char fs_buf[2048];
char vs_buf[8192];
char fs_buf[8192];
size_t vs_len = 0;
size_t fs_len = 0;
size_t num_floats = 4;
@ -357,6 +364,56 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
append_line(fs_buf, &fs_len, "}");
}
if (world_geometry) {
append_line(fs_buf, &fs_len, "float dither4x4(vec2 position, float brightness) {");
append_line(fs_buf, &fs_len, " int x = int(mod(position.x, 4.0));");
append_line(fs_buf, &fs_len, " int y = int(mod(position.y, 4.0));");
append_line(fs_buf, &fs_len, " int index = x + y * 4;");
append_line(fs_buf, &fs_len, " float limit = 0.0;");
append_line(fs_buf, &fs_len, " if (x < 8) {");
append_line(fs_buf, &fs_len, " if (index == 0) limit = 0.0625;");
append_line(fs_buf, &fs_len, " if (index == 1) limit = 0.5625;");
append_line(fs_buf, &fs_len, " if (index == 2) limit = 0.1875;");
append_line(fs_buf, &fs_len, " if (index == 3) limit = 0.6875;");
append_line(fs_buf, &fs_len, " if (index == 4) limit = 0.8125;");
append_line(fs_buf, &fs_len, " if (index == 5) limit = 0.3125;");
append_line(fs_buf, &fs_len, " if (index == 6) limit = 0.9375;");
append_line(fs_buf, &fs_len, " if (index == 7) limit = 0.4375;");
append_line(fs_buf, &fs_len, " if (index == 8) limit = 0.25;");
append_line(fs_buf, &fs_len, " if (index == 9) limit = 0.75;");
append_line(fs_buf, &fs_len, " if (index == 10) limit = 0.125;");
append_line(fs_buf, &fs_len, " if (index == 11) limit = 0.625;");
append_line(fs_buf, &fs_len, " if (index == 12) limit = 1.0;");
append_line(fs_buf, &fs_len, " if (index == 13) limit = 0.5;");
append_line(fs_buf, &fs_len, " if (index == 14) limit = 0.875;");
append_line(fs_buf, &fs_len, " if (index == 15) limit = 0.375;");
append_line(fs_buf, &fs_len, " }");
append_line(fs_buf, &fs_len, " return brightness < limit ? 0.0 : 1.0;");
append_line(fs_buf, &fs_len, "}");
append_line(fs_buf, &fs_len, "vec3 rgb2hsv(vec3 c) {");
append_line(fs_buf, &fs_len, " vec4 K = vec4(0.0, -1.0/3.0, 2.0/3.0, -1.0);");
append_line(fs_buf, &fs_len, " vec4 p = mix(vec4(c.bg, K.wz),");
append_line(fs_buf, &fs_len, " vec4(c.gb, K.xy),");
append_line(fs_buf, &fs_len, " step(c.b, c.g));");
append_line(fs_buf, &fs_len, " vec4 q = mix(vec4(p.xyw, c.r),");
append_line(fs_buf, &fs_len, " vec4(c.r, p.yzx),");
append_line(fs_buf, &fs_len, " step(p.x, c.r));");
append_line(fs_buf, &fs_len, " float d = q.x - min(q.w, q.y);");
append_line(fs_buf, &fs_len, " float e = 1.0e-10;");
append_line(fs_buf, &fs_len, " return vec3(");
append_line(fs_buf, &fs_len, " abs(q.z + (q.w - q.y) / (6.0 * d + e)), // hue");
append_line(fs_buf, &fs_len, " d / (q.x + e), // saturation");
append_line(fs_buf, &fs_len, " q.x // value");
append_line(fs_buf, &fs_len, " );");
append_line(fs_buf, &fs_len, "}");
append_line(fs_buf, &fs_len, "");
append_line(fs_buf, &fs_len, "vec3 hsv2rgb(vec3 c) {");
append_line(fs_buf, &fs_len, " vec3 p = abs(fract(c.xxx + vec3(0.0, 2.0/3.0, 1.0/3.0)) * 6.0 - 3.0);");
append_line(fs_buf, &fs_len, " return c.z * mix(vec3(1.0), clamp(p - 1.0, 0.0, 1.0), c.y);");
append_line(fs_buf, &fs_len, "}");
}
if ((opt_alpha && opt_dither) || ccf.do_noise) {
append_line(fs_buf, &fs_len, "uniform float uFrameCount;");
@ -370,6 +427,11 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
append_line(fs_buf, &fs_len, "uniform vec3 uLightmapColor;");
}
if (world_geometry) {
fs_len += sprintf(fs_buf + fs_len, "uniform int uShaderFlags[%d];\n", SHADER_FLAG_MAX);
fs_len += sprintf(fs_buf + fs_len, "uniform float uShaderFlagValues[%d];\n", SHADER_FLAG_MAX);
}
append_line(fs_buf, &fs_len, "uniform int uFilter;");
append_line(fs_buf, &fs_len, "void main() {");
@ -416,6 +478,55 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
// TODO discard if alpha is 0?
if (world_geometry) {
// hue
append_line(fs_buf, &fs_len, "if (uShaderFlags[0] == 1) {");
append_line(fs_buf, &fs_len, "vec3 hsv = rgb2hsv(texel.rgb);");
append_line(fs_buf, &fs_len, "hsv.x = fract(hsv.x + uShaderFlagValues[0]);");
append_line(fs_buf, &fs_len, "vec3 finalColor = hsv2rgb(hsv);");
append_line(fs_buf, &fs_len, "texel.rgb = finalColor;");
append_line(fs_buf, &fs_len, "}");
// saturation
append_line(fs_buf, &fs_len, "if (uShaderFlags[1] == 1) {");
append_line(fs_buf, &fs_len, "const vec3 w = vec3(0.2125, 0.7154, 0.0721);");
append_line(fs_buf, &fs_len, "vec3 intensity = vec3(dot(texel.rgb, w));");
append_line(fs_buf, &fs_len, "texel.rgb = mix(intensity, texel.rgb, uShaderFlagValues[1]);");
append_line(fs_buf, &fs_len, "}");
// brightness
append_line(fs_buf, &fs_len, "if (uShaderFlags[2] == 1) {");
append_line(fs_buf, &fs_len, "texel.rgb *= uShaderFlagValues[2];");
append_line(fs_buf, &fs_len, "}");
// contrast
append_line(fs_buf, &fs_len, "if (uShaderFlags[3] == 1) {");
append_line(fs_buf, &fs_len, "texel.rgb = 0.5 + uShaderFlagValues[3] * (texel.rgb - 0.5);");
append_line(fs_buf, &fs_len, "}");
// exposure
append_line(fs_buf, &fs_len, "if (uShaderFlags[4] == 1) {");
append_line(fs_buf, &fs_len, "texel.rgb = texel.rgb + (uShaderFlagValues[4] - 2) * texel.rgb + texel.rgb;");
append_line(fs_buf, &fs_len, "}");
// dithering
append_line(fs_buf, &fs_len, "if (uShaderFlags[5] == 1) {");
append_line(fs_buf, &fs_len, "texel.rgb *= dither4x4(gl_FragCoord.xy, dot(texel.rgb, vec3(0.299, 0.587, 0.114)));");
append_line(fs_buf, &fs_len, "}");
// posterization
append_line(fs_buf, &fs_len, "if (uShaderFlags[6] == 1) {");
append_line(fs_buf, &fs_len, "int levels = int(max(1.0, uShaderFlagValues[6]));");
append_line(fs_buf, &fs_len, "texel.rgb = floor(texel.rgb * levels) / levels;");
append_line(fs_buf, &fs_len, "}");
// scan lines
append_line(fs_buf, &fs_len, "if (uShaderFlags[7] == 1) {");
append_line(fs_buf, &fs_len, "float scan = sin(gl_FragCoord.y * 1.5) * 0.04;");
append_line(fs_buf, &fs_len, "texel.rgb -= scan * uShaderFlagValues[7];");
append_line(fs_buf, &fs_len, "}");
}
if (opt_fog) {
if (opt_alpha) {
append_line(fs_buf, &fs_len, "texel = vec4(mix(texel.rgb, vFog.rgb, vFog.a), texel.a);");
@ -558,7 +669,15 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
prg->used_lightmap = false;
}
prg->uniform_locations[6] = glGetUniformLocation(shader_program, "uFilter");
if (world_geometry) {
prg->uniform_locations[6] = glGetUniformLocation(shader_program, "uShaderFlags");
prg->uniform_locations[7] = glGetUniformLocation(shader_program, "uShaderFlagValues");
prg->world_geometry = true;
} else {
prg->world_geometry = false;
}
prg->uniform_locations[8] = glGetUniformLocation(shader_program, "uFilter");
return prg;
}
@ -717,6 +836,18 @@ static void gfx_opengl_init(void) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
bool gfx_opengl_check_compatibility(void) {
// check GL version
int vmajor = 0;
int vminor = 0;
bool is_es = false;
gl_get_version(&vmajor, &vminor, &is_es);
if (vmajor < 2 && vminor < 1 && !is_es)
return false;
return true;
}
static void gfx_opengl_on_resize(void) {
}

View file

@ -5,4 +5,6 @@
extern struct GfxRenderingAPI gfx_opengl_api;
bool gfx_opengl_check_compatibility(void);
#endif

View file

@ -129,6 +129,20 @@ Color gVertexColor = { 0xFF, 0xFF, 0xFF };
Color gFogColor = { 0xFF, 0xFF, 0xFF };
f32 gFogIntensity = 1;
int gShaderFlags[SHADER_FLAG_MAX] = { 0 };
f32 gDefaultShaderFlagValues[SHADER_FLAG_MAX] = {
[SHADER_FLAG_HUE] = 0.0f,
[SHADER_FLAG_SATURATION] = 1.0f,
[SHADER_FLAG_BRIGHTNESS] = 1.0f,
[SHADER_FLAG_CONTRAST] = 1.0f,
[SHADER_FLAG_EXPOSURE] = 1.0f,
[SHADER_FLAG_DITHERING] = 0.0f,
[SHADER_FLAG_POSTERIZATION] = 8.0f,
[SHADER_FLAG_SCANLINES] = 1.0f
};
f32 gShaderFlagValues[SHADER_FLAG_MAX] = { 0 };
bool gShaderFlagsEnabled = true;
// need inverse camera matrix to compute world space for lighting engine
static Mat4 sInverseCameraMatrix;
static bool sHasInverseCameraMatrix = false;
@ -1015,6 +1029,8 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
if (!(rsp.geometry_mode & G_FRESNEL_ALPHA_EXT)) {
d->color.a = v->cn[3];
}
d->world_geometry = luaVertexColor;
}
}
@ -1103,12 +1119,13 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t
struct CombineMode* cm = &rdp.combine_mode;
cm->use_alpha = (rdp.other_mode_l & (G_BL_A_MEM << 18)) == 0;
cm->texture_edge = (rdp.other_mode_l & CVG_X_ALPHA) == CVG_X_ALPHA;
cm->use_dither = (rdp.other_mode_l & G_AC_DITHER) == G_AC_DITHER;
cm->use_2cycle = (rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)) == G_CYC_2CYCLE;
cm->use_fog = (rdp.other_mode_l >> 30) == G_BL_CLR_FOG;
cm->light_map = (rsp.geometry_mode & G_LIGHT_MAP_EXT) == G_LIGHT_MAP_EXT;
cm->use_alpha = (rdp.other_mode_l & (G_BL_A_MEM << 18)) == 0;
cm->texture_edge = (rdp.other_mode_l & CVG_X_ALPHA) == CVG_X_ALPHA;
cm->use_dither = (rdp.other_mode_l & G_AC_DITHER) == G_AC_DITHER;
cm->use_2cycle = (rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)) == G_CYC_2CYCLE;
cm->use_fog = (rdp.other_mode_l >> 30) == G_BL_CLR_FOG;
cm->light_map = (rsp.geometry_mode & G_LIGHT_MAP_EXT) == G_LIGHT_MAP_EXT;
cm->world_geometry = gShaderFlagsEnabled && (v1->world_geometry && v2->world_geometry && v3->world_geometry);
if (cm->texture_edge) {
cm->use_alpha = true;

View file

@ -4,6 +4,18 @@
#include "types.h"
#include "pc/gfx/gfx.h"
enum ShaderFlag {
SHADER_FLAG_HUE,
SHADER_FLAG_SATURATION,
SHADER_FLAG_BRIGHTNESS,
SHADER_FLAG_CONTRAST,
SHADER_FLAG_EXPOSURE,
SHADER_FLAG_DITHERING,
SHADER_FLAG_POSTERIZATION,
SHADER_FLAG_SCANLINES,
SHADER_FLAG_MAX
};
struct GfxRenderingAPI;
struct GfxWindowManagerAPI;
@ -13,6 +25,11 @@ extern Color gVertexColor;
extern Color gFogColor;
extern f32 gFogIntensity;
extern int gShaderFlags[SHADER_FLAG_MAX];
extern f32 gDefaultShaderFlagValues[SHADER_FLAG_MAX];
extern f32 gShaderFlagValues[SHADER_FLAG_MAX];
extern bool gShaderFlagsEnabled;
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -155,6 +155,39 @@ static void gfx_sdl_init(const char *window_title) {
controller_bind_init();
}
bool gfx_sdl_check_opengl_compatibility(void) {
if (!(SDL_WasInit(SDL_INIT_VIDEO) & SDL_INIT_VIDEO)) {
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
return false;
}
}
// hidden window
SDL_Window* window = SDL_CreateWindow(
"",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1,
SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN
);
if (!window) {
return false;
}
SDL_GLContext ctx = SDL_GL_CreateContext(window);
if (!ctx) {
SDL_DestroyWindow(window);
return false;
}
bool validVersion = gfx_opengl_check_compatibility();
SDL_GL_DeleteContext(ctx);
SDL_DestroyWindow(window);
return validVersion;
}
static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) {
run_one_game_iter();
}

View file

@ -5,4 +5,6 @@
extern struct GfxWindowManagerAPI gfx_sdl;
bool gfx_sdl_check_opengl_compatibility(void);
#endif

View file

@ -753,12 +753,13 @@ static struct LuaObjectField sDjuiColorFields[LUA_DJUI_COLOR_FIELD_COUNT] = {
{ "r", LVT_U8, offsetof(struct DjuiColor, r), false, LOT_NONE },
};
#define LUA_DJUI_INTERACTABLE_THEME_FIELD_COUNT 7
#define LUA_DJUI_INTERACTABLE_THEME_FIELD_COUNT 8
static struct LuaObjectField sDjuiInteractableThemeFields[LUA_DJUI_INTERACTABLE_THEME_FIELD_COUNT] = {
{ "cursorDownBorderColor", LVT_COBJECT, offsetof(struct DjuiInteractableTheme, cursorDownBorderColor), true, LOT_DJUICOLOR },
{ "cursorDownRectColor", LVT_COBJECT, offsetof(struct DjuiInteractableTheme, cursorDownRectColor), true, LOT_DJUICOLOR },
{ "defaultBorderColor", LVT_COBJECT, offsetof(struct DjuiInteractableTheme, defaultBorderColor), true, LOT_DJUICOLOR },
{ "defaultRectColor", LVT_COBJECT, offsetof(struct DjuiInteractableTheme, defaultRectColor), true, LOT_DJUICOLOR },
{ "disabledTextColor", LVT_COBJECT, offsetof(struct DjuiInteractableTheme, disabledTextColor), true, LOT_DJUICOLOR },
{ "hoveredBorderColor", LVT_COBJECT, offsetof(struct DjuiInteractableTheme, hoveredBorderColor), true, LOT_DJUICOLOR },
{ "hoveredRectColor", LVT_COBJECT, offsetof(struct DjuiInteractableTheme, hoveredRectColor), true, LOT_DJUICOLOR },
{ "textColor", LVT_COBJECT, offsetof(struct DjuiInteractableTheme, textColor), true, LOT_DJUICOLOR },

View file

@ -1604,6 +1604,15 @@ char gSmluaConstants[] = ""
"BACKGROUND_ABOVE_CLOUDS=8\n"
"BACKGROUND_PURPLE_SKY=9\n"
"BACKGROUND_CUSTOM=10\n"
"SHADER_FLAG_HUE=0\n"
"SHADER_FLAG_SATURATION=1\n"
"SHADER_FLAG_BRIGHTNESS=2\n"
"SHADER_FLAG_CONTRAST=3\n"
"SHADER_FLAG_EXPOSURE=4\n"
"SHADER_FLAG_DITHERING=5\n"
"SHADER_FLAG_POSTERIZATION=6\n"
"SHADER_FLAG_SCANLINES=7\n"
"SHADER_FLAG_MAX=8\n"
"GRAPH_RENDER_ACTIVE=(1 << 0)\n"
"GRAPH_RENDER_CHILDREN_FIRST=(1 << 1)\n"
"GRAPH_RENDER_BILLBOARD=(1 << 2)\n"

View file

@ -900,6 +900,7 @@ static GraphNodeLot graphNodeLots[] = {
{ GRAPH_NODE_TYPE_ROOT, LOT_GRAPHNODE },
{ GRAPH_NODE_TYPE_ROTATION, LOT_GRAPHNODEROTATION },
{ GRAPH_NODE_TYPE_SCALE, LOT_GRAPHNODESCALE },
{ GRAPH_NODE_TYPE_SCALE_XYZ, LOT_GRAPHNODESCALEXYZ },
{ GRAPH_NODE_TYPE_SHADOW, LOT_GRAPHNODESHADOW },
{ GRAPH_NODE_TYPE_START, LOT_GRAPHNODESTART },
{ GRAPH_NODE_TYPE_SWITCH_CASE, LOT_GRAPHNODESWITCHCASE },

View file

@ -9890,6 +9890,21 @@ int smlua_func_position_based_random_float_position(UNUSED lua_State* L) {
return 1;
}
int smlua_func_draw_distance_scalar_is_infinite(UNUSED lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 0) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "draw_distance_scalar_is_infinite", 0, top);
return 0;
}
lua_pushboolean(L, draw_distance_scalar_is_infinite());
return 1;
}
int smlua_func_draw_distance_scalar(UNUSED lua_State* L) {
if (L == NULL) { return 0; }
@ -32586,6 +32601,125 @@ int smlua_func_network_player_palette_to_color(lua_State* L) {
// smlua_gfx_utils.h //
///////////////////////
int smlua_func_get_shader_flag_enabled(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 1) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_shader_flag_enabled", 1, top);
return 0;
}
int flag = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_shader_flag_enabled"); return 0; }
lua_pushboolean(L, get_shader_flag_enabled(flag));
return 1;
}
int smlua_func_set_shader_flag_enabled(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", "set_shader_flag_enabled", 2, top);
return 0;
}
int flag = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "set_shader_flag_enabled"); return 0; }
bool enabled = smlua_to_boolean(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "set_shader_flag_enabled"); return 0; }
set_shader_flag_enabled(flag, enabled);
return 1;
}
int smlua_func_get_shader_flag_value(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 1) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_shader_flag_value", 1, top);
return 0;
}
int flag = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_shader_flag_value"); return 0; }
lua_pushnumber(L, get_shader_flag_value(flag));
return 1;
}
int smlua_func_set_shader_flag_value(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", "set_shader_flag_value", 2, top);
return 0;
}
int flag = smlua_to_integer(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "set_shader_flag_value"); return 0; }
f32 value = smlua_to_number(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "set_shader_flag_value"); return 0; }
set_shader_flag_value(flag, value);
return 1;
}
int smlua_func_get_global_shader_flags_enabled(UNUSED lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 0) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_global_shader_flags_enabled", 0, top);
return 0;
}
lua_pushboolean(L, get_global_shader_flags_enabled());
return 1;
}
int smlua_func_set_global_shader_flags_enabled(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", "set_global_shader_flags_enabled", 1, top);
return 0;
}
bool enabled = smlua_to_boolean(L, 1);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "set_global_shader_flags_enabled"); return 0; }
set_global_shader_flags_enabled(enabled);
return 1;
}
int smlua_func_clear_all_shader_flags(UNUSED lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 0) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "clear_all_shader_flags", 0, top);
return 0;
}
clear_all_shader_flags();
return 1;
}
int smlua_func_set_override_fov(lua_State* L) {
if (L == NULL) { return 0; }
@ -38038,6 +38172,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "obj_update_gfx_pos_and_angle", smlua_func_obj_update_gfx_pos_and_angle);
smlua_bind_function(L, "position_based_random_u16", smlua_func_position_based_random_u16);
smlua_bind_function(L, "position_based_random_float_position", smlua_func_position_based_random_float_position);
smlua_bind_function(L, "draw_distance_scalar_is_infinite", smlua_func_draw_distance_scalar_is_infinite);
smlua_bind_function(L, "draw_distance_scalar", smlua_func_draw_distance_scalar);
// behavior_table.h
@ -39291,6 +39426,13 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "network_player_palette_to_color", smlua_func_network_player_palette_to_color);
// smlua_gfx_utils.h
smlua_bind_function(L, "get_shader_flag_enabled", smlua_func_get_shader_flag_enabled);
smlua_bind_function(L, "set_shader_flag_enabled", smlua_func_set_shader_flag_enabled);
smlua_bind_function(L, "get_shader_flag_value", smlua_func_get_shader_flag_value);
smlua_bind_function(L, "set_shader_flag_value", smlua_func_set_shader_flag_value);
smlua_bind_function(L, "get_global_shader_flags_enabled", smlua_func_get_global_shader_flags_enabled);
smlua_bind_function(L, "set_global_shader_flags_enabled", smlua_func_set_global_shader_flags_enabled);
smlua_bind_function(L, "clear_all_shader_flags", smlua_func_clear_all_shader_flags);
smlua_bind_function(L, "set_override_fov", smlua_func_set_override_fov);
smlua_bind_function(L, "set_override_near", smlua_func_set_override_near);
smlua_bind_function(L, "set_override_far", smlua_func_set_override_far);

View file

@ -638,18 +638,20 @@ void audio_sample_play(struct ModAudio* audio, Vec3f position, f32 volume) {
}
f32 dist = 0;
f32 pan = 0.5f;
f32 pan = 0;
if (gCamera) {
f32 dX = position[0] - gCamera->pos[0];
f32 dY = position[1] - gCamera->pos[1];
f32 dZ = position[2] - gCamera->pos[2];
dist = sqrtf(dX * dX + dY * dY + dZ * dZ);
Mat4 mtx;
mtxf_translate(mtx, position);
mtxf_mul(mtx, mtx, gCamera->mtx);
f32 factor = 10;
pan = (get_sound_pan(mtx[3][0] * factor, mtx[3][2] * factor) - 0.5f) * 2.0f;
if (configSoundOutput != SOUND_MODE_MONO) {
Mat4 mtx;
mtxf_translate(mtx, position);
mtxf_mul(mtx, mtx, gCamera->mtx);
f32 factor = 10;
pan = (get_sound_pan(mtx[3][0] * factor, mtx[3][2] * factor) - 0.5f) * 2.0f;
}
}
if (configMuteFocusLoss && !gWindowApi->has_focus()) {

View file

@ -1,9 +1,45 @@
#include "smlua_gfx_utils.h"
#include "pc/gfx/gfx_pc.h"
#include "pc/pc_main.h"
#include "game/rendering_graph_node.h"
#include "game/skybox.h"
#include "geo_commands.h"
bool get_shader_flag_enabled(enum ShaderFlag flag) {
if (flag < 0 || flag >= SHADER_FLAG_MAX) { return false; }
return gShaderFlags[flag];
}
void set_shader_flag_enabled(enum ShaderFlag flag, bool enabled) {
if (flag < 0 || flag >= SHADER_FLAG_MAX) { return; }
gShaderFlags[flag] = enabled ? 1 : 0;
}
f32 get_shader_flag_value(enum ShaderFlag flag) {
if (flag < 0 || flag >= SHADER_FLAG_MAX) { return 0.0f; }
return gShaderFlagValues[flag];
}
void set_shader_flag_value(enum ShaderFlag flag, f32 value) {
if (flag < 0 || flag >= SHADER_FLAG_MAX) { return; }
gShaderFlagValues[flag] = value;
}
bool get_global_shader_flags_enabled(void) {
return gShaderFlagsEnabled;
}
void set_global_shader_flags_enabled(bool enabled) {
gShaderFlagsEnabled = enabled;
}
AT_STARTUP void clear_all_shader_flags(void) {
gShaderFlagsEnabled = true;
memset(gShaderFlags, 0, sizeof(s32) * SHADER_FLAG_MAX);
memcpy(gShaderFlagValues, gDefaultShaderFlagValues, sizeof(f32) * SHADER_FLAG_MAX);
}
///
void set_override_fov(f32 fov) {
gOverrideFOV = fov;
}

View file

@ -1,6 +1,7 @@
#ifndef SMLUA_GFX_UTILS_H
#define SMLUA_GFX_UTILS_H
#include "pc/gfx/gfx_pc.h"
#include "pc/lua/smlua.h"
#include "types.h"
#include "geo_commands.h"
@ -12,6 +13,21 @@ Gfx *gfx_allocate_internal(Gfx *gfx, u32 length);
Vtx *vtx_allocate_internal(Vtx *vtx, u32 count);
u32 gfx_get_length_no_sentinel(const Gfx *gfx);
/* |description|Gets if a custom shader flag (`SHADER_FLAG_*`) is enabled or not|descriptionEnd| */
bool get_shader_flag_enabled(enum ShaderFlag flag);
/* |description|Enables a custom shader flag (`SHADER_FLAG_*`) for the renderer|descriptionEnd| */
void set_shader_flag_enabled(enum ShaderFlag flag, bool enabled);
/* |description|Gets a value for one of the custom shader flags (`SHADER_FLAG_*`)|descriptionEnd| */
f32 get_shader_flag_value(enum ShaderFlag flag);
/* |description|Sets a value for one of the custom shader flags (`SHADER_FLAG_*`) for the renderer|descriptionEnd| */
void set_shader_flag_value(enum ShaderFlag flag, f32 value);
/* |description|Gets if custom shader flags are enabled globally|descriptionEnd| */
bool get_global_shader_flags_enabled(void);
/* |description|Enables custom shader flags as a global toggle, useful for disabling without manually going through every effect|descriptionEnd| */
void set_global_shader_flags_enabled(bool enabled);
/* |description|Clears all custom shader flags (`SHADER_FLAG_*`) for the renderer|descriptionEnd| */
void clear_all_shader_flags(void);
/* |description|Sets the override FOV|descriptionEnd| */
void set_override_fov(f32 fov);
/* |description|Sets the override near plane|descriptionEnd| */
@ -96,7 +112,7 @@ 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
Returns a pointer to the vertex buffer 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| */

View file

@ -16,6 +16,7 @@
#include "pc/lua/utils/smlua_model_utils.h"
#include "pc/lua/utils/smlua_misc_utils.h"
#include "pc/lua/utils/smlua_camera_utils.h"
#include "pc/lua/utils/smlua_gfx_utils.h"
#include "pc/mods/mods.h"
#include "pc/crash_handler.h"
#include "pc/debuglog.h"
@ -36,7 +37,7 @@
#include "game/mario.h"
#include "engine/math_util.h"
#include "engine/lighting_engine.h"
#include "src/audio/load.h"
#include "audio/load.h"
#ifdef DISCORD_SDK
#include "pc/discord/discord.h"
@ -723,6 +724,7 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect
color_set(gSkyboxColor, 0xFF, 0xFF, 0xFF);
color_set(gFogColor, 0xFF, 0xFF, 0xFF);
gFogIntensity = 1.0f;
clear_all_shader_flags();
gOverrideBackground = -1;
gOverrideEnvFx = ENVFX_MODE_NO_OVERRIDE;
gRomhackCameraSettings.centering = FALSE;

View file

@ -221,6 +221,11 @@ static void select_graphics_backend(void) {
return;
}
#if defined(_WIN32)
if (configGraphicsBackend == GAPI_GL && !gfx_sdl_check_opengl_compatibility()) {
configGraphicsBackend = GAPI_D3D11;
}
#endif
int backend = configGraphicsBackend;
#if defined(_WIN32)
if (gCLIOpts.backend != -1) { backend = gCLIOpts.backend; }
@ -578,6 +583,10 @@ int main(int argc, char *argv[]) {
show_update_popup();
if (can_update_game()) {
djui_open_update_panel();
}
// initialize network
if (gCLIOpts.network == NT_CLIENT) {
network_set_system(NS_SOCKET);

Some files were not shown because too many files have changed in this diff Show more