diff --git a/Makefile b/Makefile index 330ecf086..9d6784dd0 100644 --- a/Makefile +++ b/Makefile @@ -30,9 +30,6 @@ TARGET_N64 = 0 # Build and optimize for Raspberry Pi(s) TARGET_RPI ?= 0 -# Build for Emscripten/WebGL -TARGET_WEB ?= 0 - # Makeflag to enable OSX fixes OSX_BUILD ?= 0 @@ -132,10 +129,8 @@ else endif endif -ifeq ($(TARGET_WEB),0) - ifeq ($(HOST_OS),Windows) - WINDOWS_BUILD := 1 - endif +ifeq ($(HOST_OS),Windows) + WINDOWS_BUILD := 1 endif # MXE overrides @@ -228,7 +223,7 @@ else ifeq ($(DEBUG_INFO_LEVEL),1) else ifeq ($(DEBUG_INFO_LEVEL),0) # If we're compiling with -0g. I don't believe this will do anything worthwhile. OPT_FLAGS += -g0 -else +else # This is our default AND level 2. OPT_FLAGS += -g endif @@ -239,10 +234,6 @@ else PROF_FLAGS := endif -ifeq ($(TARGET_WEB),1) - OPT_FLAGS := -O2 -g4 --source-map-base http://localhost:8080/ -endif - ifeq ($(TARGET_RPI),1) machine = $(shell sh -c 'uname -m 2>/dev/null || echo unknown') @@ -321,10 +312,6 @@ ifeq ($(OSX_BUILD),1) # Modify GFX & SDL2 for OSX GL DEFINES += OSX_BUILD=1 endif -ifeq ($(TARGET_WEB),1) - DEFINES := $(DEFINES) -DTARGET_WEB -DUSE_GLES -endif - # Check backends ifneq (,$(filter $(RENDER_API),D3D11 D3D12)) @@ -357,7 +344,7 @@ ifeq ($(HEADLESS),1) RENDER_API := DUMMY WINDOW_API := DUMMY AUDIO_API := DUMMY - CONTROLLER_API := + CONTROLLER_API := endif ifeq ($(TARGET_RPI),1) @@ -490,23 +477,15 @@ _ := $(shell $(PYTHON) $(TOOLS_DIR)/copy_mario_sounds.py) BUILD_DIR_BASE := build # BUILD_DIR is the location where all build artifacts are placed -ifeq ($(TARGET_WEB),1) - BUILD_DIR := $(BUILD_DIR_BASE)/$(VERSION)_web -else - BUILD_DIR := $(BUILD_DIR_BASE)/$(VERSION)_pc -endif +BUILD_DIR := $(BUILD_DIR_BASE)/$(VERSION)_pc -ifeq ($(TARGET_WEB),1) - EXE := $(BUILD_DIR)/$(TARGET_STRING).html -else - ifeq ($(WINDOWS_BUILD),1) - EXE := $(BUILD_DIR)/$(TARGET_STRING).exe - else # Linux builds/binary namer - ifeq ($(TARGET_RPI),1) - EXE := $(BUILD_DIR)/$(TARGET_STRING).arm - else - EXE := $(BUILD_DIR)/$(TARGET_STRING) - endif +ifeq ($(WINDOWS_BUILD),1) + EXE := $(BUILD_DIR)/$(TARGET_STRING).exe +else # Linux builds/binary namer + ifeq ($(TARGET_RPI),1) + EXE := $(BUILD_DIR)/$(TARGET_STRING).arm + else + EXE := $(BUILD_DIR)/$(TARGET_STRING) endif endif @@ -606,7 +585,7 @@ RPC_LIBS := #ifeq ($(DISCORDRPC),1) # ifeq ($(WINDOWS_BUILD),1) # RPC_LIBS := lib/discord/libdiscord-rpc.dll -# else ifeq ($(OSX_BUILD),1) +# else ifeq ($(OSX_BUILD),1) # # needs testing # RPC_LIBS := lib/discord/libdiscord-rpc.dylib # else @@ -701,9 +680,6 @@ else ifeq ($(COMPILER),clang) CXX := clang++ CPP := clang++ EXTRA_CFLAGS += -Wno-unused-function -Wno-unused-variable -Wno-unknown-warning-option -Wno-self-assign -Wno-unknown-pragmas -Wno-unused-result -else ifeq ($(TARGET_WEB),1) # As in, web PC port - CC := emcc - CXX := emcc else ifeq ($(USE_QEMU_IRIX),1) IRIX_ROOT := $(TOOLS_DIR)/ido5.3_compiler @@ -827,7 +803,7 @@ ifeq ($(SDL1_USED)$(SDL2_USED),11) endif # SDL can be used by different systems, so we consolidate all of that shit into this - + ifeq ($(SDL2_USED),1) SDLCONFIG := $(CROSS)sdl2-config BACKEND_CFLAGS += -DHAVE_SDL2=1 @@ -844,7 +820,7 @@ ifneq ($(SDL1_USED)$(SDL2_USED),00) else BACKEND_CFLAGS += `$(SDLCONFIG) --cflags` endif - + ifeq ($(WINDOWS_BUILD),1) BACKEND_LDFLAGS += `$(SDLCONFIG) --static-libs` -lsetupapi -luser32 -limm32 -lole32 -loleaut32 -lshell32 -lwinmm -lversion else @@ -865,9 +841,6 @@ ifeq ($(WINDOWS_BUILD),1) ifeq ($(TARGET_BITS), 32) BACKEND_LDFLAGS += -ldbghelp endif -else ifeq ($(TARGET_WEB),1) - CC_CHECK_CFLAGS := -fsyntax-only -fsigned-char $(BACKEND_CFLAGS) $(DEF_INC_CFLAGS) -Wall -Wextra -Wno-format-security $(TARGET_CFLAGS) -s USE_SDL=2 - CFLAGS := $(OPT_FLAGS) $(DEF_INC_CFLAGS) $(BACKEND_CFLAGS) $(TARGET_CFLAGS) -fno-strict-aliasing -fwrapv -s USE_SDL=2 else ifeq ($(TARGET_N64),0) # Linux / Other builds below CC_CHECK_CFLAGS := -fsyntax-only -fsigned-char $(BACKEND_CFLAGS) $(DEF_INC_CFLAGS) -Wall -Wextra $(TARGET_CFLAGS) CFLAGS := $(OPT_FLAGS) $(DEF_INC_CFLAGS) $(BACKEND_CFLAGS) $(TARGET_CFLAGS) -fno-strict-aliasing -fwrapv @@ -886,7 +859,7 @@ ifeq ($(TARGET_N64),1) RSPASMFLAGS := $(foreach d,$(DEFINES),-definelabel $(subst =, ,$(d))) else ASFLAGS := $(foreach i,$(INCLUDE_DIRS),-I$(i)) $(foreach d,$(DEFINES),--defsym $(d)) - RSPASMFLAGS := + RSPASMFLAGS := endif # C preprocessor flags @@ -902,9 +875,7 @@ ifeq ($(TARGET_N64),1) endif endif -ifeq ($(TARGET_WEB),1) - LDFLAGS := -lm -lGL -lSDL2 -no-pie -s TOTAL_MEMORY=20MB -g4 --source-map-base http://localhost:8080/ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']" -else ifeq ($(WINDOWS_BUILD),1) +ifeq ($(WINDOWS_BUILD),1) LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -Llib -lpthread $(BACKEND_LDFLAGS) -static ifeq ($(CROSS),) LDFLAGS += -no-pie @@ -1207,9 +1178,9 @@ clean: cleantools: $(MAKE) -s -C $(TOOLS_DIR) clean -distclean: clean +distclean: clean cleantools $(PYTHON) extract_assets.py --clean - + test: $(ROM) $(EMULATOR) $(EMU_FLAGS) $< @@ -1220,7 +1191,7 @@ libultra: $(BUILD_DIR)/libultra.a $(BUILD_DIR)/$(RPC_LIBS): @$(CP) -f $(RPC_LIBS) $(BUILD_DIR) - + $(BUILD_DIR)/$(DISCORD_SDK_LIBS): @$(CP) -f $(DISCORD_SDK_LIBS) $(BUILD_DIR) @@ -1301,7 +1272,7 @@ else $(BUILD_DIR)/%: %.png $(call print,Converting:,$<,$@) $(V)$(N64GRAPHICS) -s raw -i $@ -g $< -f $(lastword $(subst ., ,$@)) - + $(BUILD_DIR)/%.inc.c: %.png $(call print,Converting:,$<,$@) $(V)$(N64GRAPHICS) -s $(TEXTURE_ENCODING) -i $@ -g $< -f $(lastword ,$(subst ., ,$(basename $<))) @@ -1355,7 +1326,7 @@ $(BUILD_DIR)/%.mio0: $(BUILD_DIR)/%.bin $(BUILD_DIR)/%.mio0.o: $(BUILD_DIR)/%.mio0 $(call print,Converting MIO0 to ELF:,$<,$@) $(V)printf ".section .data\n\n.incbin \"$<\"\n" | $(AS) $(ASFLAGS) -o $@ - + endif @@ -1556,7 +1527,7 @@ endif $(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT) $(call print,Preprocessing linker script:,$<,$@) $(V)$(CPP) $(PROF_FLAGS) $(CPPFLAGS) -DBUILD_DIR=$(BUILD_DIR) -MMD -MP -MT $@ -MF $@.d -o $@ $< - + # Assemble assembly code $(BUILD_DIR)/%.o: %.s $(call print,Assembling:,$<,$@) @@ -1567,7 +1538,7 @@ ifeq ($(TARGET_N64),1) $(BUILD_DIR)/rsp/%.bin $(BUILD_DIR)/rsp/%_data.bin: rsp/%.s $(call print,Assembling:,$<,$@) $(V)$(RSPASM) -sym $@.sym $(RSPASMFLAGS) -strequ CODE_FILE $(BUILD_DIR)/rsp/$*.bin -strequ DATA_FILE $(BUILD_DIR)/rsp/$*_data.bin $< - + # Link libultra $(BUILD_DIR)/libultra.a: $(ULTRA_O_FILES) @$(PRINT) "$(GREEN)Linking libultra: $(BLUE)$@ $(NO_COL)\n" @@ -1578,7 +1549,7 @@ ifeq ($(TARGET_N64),1) $(BUILD_DIR)/libgoddard.a: $(GODDARD_O_FILES) @$(PRINT) "$(GREEN)Linking libgoddard: $(BLUE)$@ $(NO_COL)\n" $(V)$(AR) rcs -o $@ $(GODDARD_O_FILES) - + # Link SM64 ELF file $(ELF): $(O_FILES) $(MIO0_OBJ_FILES) $(SEG_FILES) $(BUILD_DIR)/$(LD_SCRIPT) undefined_syms.txt $(BUILD_DIR)/libultra.a $(BUILD_DIR)/libgoddard.a @$(PRINT) "$(GREEN)Linking ELF file: $(BLUE)$@ $(NO_COL)\n" @@ -1589,7 +1560,7 @@ ifeq ($(TARGET_N64),1) $(call print,Building ROM:,$<,$@) $(V)$(OBJCOPY) --pad-to=0x800000 --gap-fill=0xFF $< $(@:.z64=.bin) -O binary $(V)$(N64CKSUM) $(@:.z64=.bin) $@ - + $(BUILD_DIR)/$(TARGET).objdump: $(ELF) $(OBJDUMP) -D $< > $@ else diff --git a/README_es_ES.md b/README_es_ES.md index 44a34a1c5..17d4c556c 100644 --- a/README_es_ES.md +++ b/README_es_ES.md @@ -164,8 +164,6 @@ make VERSION=jp -j6 # Compila la versión (J) usando 6 make VERSION=us MARCH=i686 TARGET_BITS=32 # Compila un ejecutable de la versión (U) de 32 bits make TARGET_RPI=1 # Compila un ejecutable para Raspberry Pi ``` -## Compilar para la web -Puedes compilar el juego para navegadores que admitan WebGL usando [Emscripten](https://github.com/emscripten-core). Para hacerlo, instala [emsdk](https://github.com/emscripten-core/emsdk) y ejecuta `make TARGET_WEB=1`. ## Script para compilar para Raspberry Pi @@ -185,19 +183,13 @@ El script está incluído en la rama master, pero también puede descargarse [aq * La versión EU tiene bugs en los textos y no tiene audio. * El movimiento analógico horizontal de la cámara vuelve al estilo antiguo en el nivel Bowser in the Dark World (#72) * La cámara con el ratón falla cuando disparas a Mario hacia un árbol o un tubo. (#71) - * "make: Nothing to be done for 'default'" al compilar para web. (#67) ### Estos problemas están marcados como solucionados. Por favor, contacta si sigues teniendo estos problemas. * El juego se llena de flags aleatorias en las builds de 64 bits para Windows * Hazy Maze Cave se cuelga en pantalla completa (#57) * La pantalla de título no tiene el cursor para manipular a Mario en pantalla completa. (#28) -## Parches -En la carpeta `./enhancements` hay varios archivos `patch`, que pueden aplicarse de la siguiente manera: -``` - git apply fps.patch --ignore-whitespace --reject -``` Si ocurre un rechazo, puedes buscarlo con el comando `find | grep .rej`. Intenta resolver los rechazos a través de [wiggle](https://github.com/neilbrown/wiggle). ``` diff --git a/actors/toad_player/custom_toad_cap.rgba16.png b/actors/toad_player/custom_toad_cap.rgba16.png index c5893dfd3..e2f5f14eb 100644 Binary files a/actors/toad_player/custom_toad_cap.rgba16.png and b/actors/toad_player/custom_toad_cap.rgba16.png differ diff --git a/actors/toad_player/custom_toad_hair.rgba16.png b/actors/toad_player/custom_toad_hair.rgba16.png index 7bfc50f54..8e555e708 100644 Binary files a/actors/toad_player/custom_toad_hair.rgba16.png and b/actors/toad_player/custom_toad_hair.rgba16.png differ diff --git a/actors/waluigi/custom_waluigi_cap.rgba16.png b/actors/waluigi/custom_waluigi_cap.rgba16.png index 411a27ef1..ba33abd33 100644 Binary files a/actors/waluigi/custom_waluigi_cap.rgba16.png and b/actors/waluigi/custom_waluigi_cap.rgba16.png differ diff --git a/actors/waluigi/custom_waluigi_eyes0.rgba16.png b/actors/waluigi/custom_waluigi_eyes0.rgba16.png index c8d9c52c4..9f5dfc037 100644 Binary files a/actors/waluigi/custom_waluigi_eyes0.rgba16.png and b/actors/waluigi/custom_waluigi_eyes0.rgba16.png differ diff --git a/actors/waluigi/custom_waluigi_eyes1.rgba16.png b/actors/waluigi/custom_waluigi_eyes1.rgba16.png index e5b17698b..fd6f5abe8 100644 Binary files a/actors/waluigi/custom_waluigi_eyes1.rgba16.png and b/actors/waluigi/custom_waluigi_eyes1.rgba16.png differ diff --git a/actors/waluigi/custom_waluigi_eyes2.rgba16.png b/actors/waluigi/custom_waluigi_eyes2.rgba16.png index eba4f312e..f9afdb543 100644 Binary files a/actors/waluigi/custom_waluigi_eyes2.rgba16.png and b/actors/waluigi/custom_waluigi_eyes2.rgba16.png differ diff --git a/actors/waluigi/custom_waluigi_eyes3.rgba16.png b/actors/waluigi/custom_waluigi_eyes3.rgba16.png index 31db3c560..776a64b6f 100644 Binary files a/actors/waluigi/custom_waluigi_eyes3.rgba16.png and b/actors/waluigi/custom_waluigi_eyes3.rgba16.png differ diff --git a/actors/waluigi/custom_waluigi_glove.rgba16.png b/actors/waluigi/custom_waluigi_glove.rgba16.png index d18c64c1a..0f5387372 100644 Binary files a/actors/waluigi/custom_waluigi_glove.rgba16.png and b/actors/waluigi/custom_waluigi_glove.rgba16.png differ diff --git a/actors/waluigi/custom_waluigi_mouth.rgba16.png b/actors/waluigi/custom_waluigi_mouth.rgba16.png index e8316be7a..65afbdcdd 100644 Binary files a/actors/waluigi/custom_waluigi_mouth.rgba16.png and b/actors/waluigi/custom_waluigi_mouth.rgba16.png differ diff --git a/actors/wario/custom_wario_mouth.rgba16.png b/actors/wario/custom_wario_mouth.rgba16.png index da16dbd82..09fd7fe1b 100644 Binary files a/actors/wario/custom_wario_mouth.rgba16.png and b/actors/wario/custom_wario_mouth.rgba16.png differ diff --git a/actors/wario/custom_wario_overalls_button.rgba16.png b/actors/wario/custom_wario_overalls_button.rgba16.png index 8ae4efb76..df018f56b 100644 Binary files a/actors/wario/custom_wario_overalls_button.rgba16.png and b/actors/wario/custom_wario_overalls_button.rgba16.png differ diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index 5d4847405..cf98b7486 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -55,7 +55,7 @@ in_files = [ ] override_allowed_functions = { - "src/audio/external.h": [ " play_", "fade", "current_background" ], + "src/audio/external.h": [ " play_", "fade", "current_background", "stop_" ], "src/game/rumble_init.c": [ "queue_rumble_", "reset_rumble_timers" ], "src/pc/djui/djui_popup.h" : [ "create" ], "src/game/save_file.h": [ "save_file_get_", "save_file_set_flags", "save_file_clear_flags", "save_file_erase", "save_file_reload", "save_file_set_star_flags" ], diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index e5019fb4d..3fbca7d65 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -1983,7 +1983,13 @@ id_bhvYellowCoin = 533 id_bhvYoshi = 534 --- @type BehaviorId -id_bhv_max_count = 535 +id_RM_Scroll_Texture = 535 + +--- @type BehaviorId +id_editor_Scroll_Texture = 536 + +--- @type BehaviorId +id_bhv_max_count = 537 --- @type integer CAMERA_MODE_8_DIRECTIONS = 0x0E diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 5f264a9ad..4d01779f5 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -2852,6 +2852,11 @@ function update_angle_from_move_flags(angle) -- ... end +--- @return nil +function uv_update_scroll() + -- ... +end + --- @param dest Vec3f --- @param src Vec3f --- @return nil @@ -3257,6 +3262,12 @@ function resolve_geometry_collisions(pos, lastGood) -- ... end +--- @param enable integer +--- @return nil +function rom_hack_cam_set_collisions(enable) + -- ... +end + --- @param c Camera --- @param cPos Vec3f --- @param avoidYaw Pointer_integer @@ -3809,6 +3820,30 @@ function seq_player_unlower_volume(player, fadeDuration) -- ... end +--- @param seqId integer +--- @return nil +function stop_background_music(seqId) + -- ... +end + +--- @param soundBits integer +--- @param pos Vec3f +--- @return nil +function stop_sound(soundBits, pos) + -- ... +end + +--- @param pos Vec3f +--- @return nil +function stop_sounds_from_source(pos) + -- ... +end + +--- @return nil +function stop_sounds_in_continuous_banks() + -- ... +end + --- @param m MarioState --- @return integer function does_mario_have_normal_cap_on_head(m) @@ -7497,6 +7532,18 @@ function warp_to_level(aLevel, aArea, aAct) -- ... end +--- @param index integer +--- @param name string +--- @param offset integer +--- @param size integer +--- @return nil +function add_scroll_target(index, name, offset, size) + +--- @return boolean +function warp_to_start_level() + -- ... +end + --- @param actFlags integer --- @return integer function allocate_mario_action(actFlags) @@ -7634,6 +7681,11 @@ function get_current_save_file_num() -- ... end +--- @return integer +function get_dialog_id() + -- ... +end + --- @param index integer --- @return number function get_environment_region(index) @@ -7705,11 +7757,21 @@ function hud_show() -- ... end +--- @return nil +function init_scroll_targets() + -- ... +end + --- @return boolean function is_game_paused() -- ... end +--- @return boolean +function is_transition_playing() + -- ... +end + --- @param name string --- @param level integer --- @param area integer diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index e8be7bea0..dd3c52268 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -528,8 +528,13 @@ --- @field public camera TextureInfo --- @field public coin TextureInfo --- @field public lakitu TextureInfo +--- @field public luigi_head TextureInfo +--- @field public mario_head TextureInfo --- @field public no_camera TextureInfo --- @field public star TextureInfo +--- @field public toad_head TextureInfo +--- @field public waluigi_head TextureInfo +--- @field public wario_head TextureInfo --- @class GraphNode --- @field public children GraphNode @@ -558,6 +563,7 @@ --- @field public prevTimestamp integer --- @field public scale Vec3f --- @field public sharedChild GraphNode +--- @field public skipInViewCheck boolean --- @field public skipInterpolationTimestamp integer --- @field public unk4C SpawnInfo diff --git a/data/behavior_data.c b/data/behavior_data.c index 6b899cb4a..9cea0cab3 100644 --- a/data/behavior_data.c +++ b/data/behavior_data.c @@ -6379,3 +6379,19 @@ const BehaviorScript bhvIntroScene[] = { CALL_NATIVE(bhv_intro_scene_loop), END_LOOP(), }; + +const BehaviorScript RM_Scroll_Texture[] = { + BEGIN(OBJ_LIST_GENACTOR), + ID(id_RM_Scroll_Texture), + BEGIN_LOOP(), + CALL_NATIVE(uv_update_scroll), + END_LOOP(), +}; + +const BehaviorScript editor_Scroll_Texture[] = { + BEGIN(OBJ_LIST_GENACTOR), + ID(id_editor_Scroll_Texture), + BEGIN_LOOP(), + CALL_NATIVE(uv_update_scroll), + END_LOOP(), +}; diff --git a/data/behavior_table.c b/data/behavior_table.c index 7b4d0c627..f325f581d 100644 --- a/data/behavior_table.c +++ b/data/behavior_table.c @@ -546,6 +546,8 @@ const struct BehaviorTableEntry gBehaviorTable[id_bhv_max_count] = { BHV_ENTRY(bhvYellowBall), BHV_ENTRY(bhvYellowCoin), BHV_ENTRY(bhvYoshi), + BHV_ENTRY(RM_Scroll_Texture), + BHV_ENTRY(editor_Scroll_Texture) }; enum BehaviorId get_id_from_behavior(const BehaviorScript* behavior) { diff --git a/data/dynos.c.h b/data/dynos.c.h index fb415c05a..d3fa1225b 100644 --- a/data/dynos.c.h +++ b/data/dynos.c.h @@ -20,6 +20,7 @@ void dynos_gfx_swap_animations(void *ptr); LevelScript* dynos_get_level_script(char* scriptEntryName); bool dynos_warp_to_level(s32 aLevel, s32 aArea, s32 aAct); bool dynos_warp_restart_level(void); +bool dynos_warp_to_start_level(void); bool dynos_warp_exit_level(s32 aDelay); bool dynos_warp_to_castle(s32 aLevel); @@ -64,6 +65,8 @@ void dynos_behavior_hook_all_custom_behaviors(void); // -- other -- // void dynos_mod_shutdown(void); +void dynos_add_scroll_target(u32 index, const char *name, u32 offset, u32 size); +void dynos_init_scroll_targets(void); #endif #endif diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h index e21353334..7b5d0bc22 100644 --- a/data/dynos.cpp.h +++ b/data/dynos.cpp.h @@ -1064,5 +1064,8 @@ bool DynOS_Bin_IsCompressed(const SysPath &aFilename); bool DynOS_Bin_Compress(const SysPath &aFilename); BinFile *DynOS_Bin_Decompress(const SysPath &aFilename); +void DynOS_Add_Scroll_Target(u32 index, const char *name, u32 offset, u32 size); +void DynOS_Init_Scroll_Targets(void); + #endif #endif diff --git a/data/dynos_bin_behavior.cpp b/data/dynos_bin_behavior.cpp index d141e2fdf..0d8b84544 100644 --- a/data/dynos_bin_behavior.cpp +++ b/data/dynos_bin_behavior.cpp @@ -771,6 +771,8 @@ s64 DynOS_Bhv_ParseBehaviorScriptConstants(const String &_Arg, bool *found) { bhv_constant(id_bhvYellowBall); bhv_constant(id_bhvYellowCoin); bhv_constant(id_bhvYoshi); + bhv_constant(id_RM_Scroll_Texture); + bhv_constant(id_editor_Scroll_Texture); // Define a special type for new ids that don't override. if (_Arg == "id_bhvNewId") { return (BehaviorScript) (0xFFFF); } @@ -2673,4 +2675,4 @@ void DynOS_Bhv_GeneratePack(const SysPath &aPackFolder) { DynOS_Bhv_Generate(aPackFolder, _BehaviorsFolders, _GfxData); DynOS_Gfx_Free(_GfxData); -} \ No newline at end of file +} diff --git a/data/dynos_bin_common.cpp b/data/dynos_bin_common.cpp index 8de35f713..abdf94641 100644 --- a/data/dynos_bin_common.cpp +++ b/data/dynos_bin_common.cpp @@ -547,6 +547,8 @@ s64 DynOS_Common_ParseBhvConstants(const String &_Arg, bool *found) { common_constant(bhvEndBirds2); common_constant(bhvIntroScene); common_constant(bhvUnusedFakeStar); + common_constant(RM_Scroll_Texture); + common_constant(editor_Scroll_Texture); // Legacy behavior names common_legacy_constant(bhvFish2, bhvManyBlueFishSpawner); diff --git a/data/dynos_bin_gfx.cpp b/data/dynos_bin_gfx.cpp index 33a2e9146..5807f48fb 100644 --- a/data/dynos_bin_gfx.cpp +++ b/data/dynos_bin_gfx.cpp @@ -732,6 +732,7 @@ static void ParseGfxSymbol(GfxData* aGfxData, DataNode* aNode, Gfx*& aHead, gfx_symbol_4(gsDPSetFogColor); gfx_symbol_2(gsSPFogPosition, false); gfx_symbol_1(gsDPSetAlphaCompare, false); + gfx_symbol_1(gsDPSetTextureFilter, false); gfx_symbol_2(gsSPCopyLightEXT, false); gfx_symbol_2(gsSPFogFactor, false); diff --git a/data/dynos_c.cpp b/data/dynos_c.cpp index e8e27f5cc..3adc2df6b 100644 --- a/data/dynos_c.cpp +++ b/data/dynos_c.cpp @@ -1,6 +1,7 @@ #include "dynos.cpp.h" extern "C" { #include "src/game/moving_texture.h" +#include "game/hardcoded.h" void *dynos_swap_cmd(void *cmd) { return DynOS_SwapCmd(cmd); @@ -38,6 +39,16 @@ bool dynos_warp_to_level(s32 aLevel, s32 aArea, s32 aAct) { return DynOS_Warp_ToLevel(aLevel, aArea, aAct); } +bool dynos_warp_to_start_level(void) { + + // change the level to the start level + extern s16 gChangeLevel; + gChangeLevel = gLevelValues.entryLevel; + + // always return true since it will always suceed + return true; +} + bool dynos_warp_restart_level(void) { return DynOS_Warp_RestartLevel(); } @@ -187,4 +198,12 @@ void dynos_mod_shutdown(void) { DynOS_Mod_Shutdown(); } -} \ No newline at end of file +void dynos_add_scroll_target(u32 index, const char *name, u32 offset, u32 size) { + DynOS_Add_Scroll_Target(index, name, offset, size); +} + +void dynos_init_scroll_targets(void) { + DynOS_Init_Scroll_Targets(); +} + +} diff --git a/data/dynos_misc.cpp b/data/dynos_misc.cpp index c34fa0a9e..3c99d6a42 100644 --- a/data/dynos_misc.cpp +++ b/data/dynos_misc.cpp @@ -16,6 +16,7 @@ extern "C" { #include "game/behavior_actions.h" #include "game/rendering_graph_node.h" #include "game/skybox.h" +#include "game/scroll_targets.h" } // @@ -174,3 +175,21 @@ void *DynOS_Geo_GetGraphNode(const void *aGeoLayout, bool aKeepInMemory) { free(_Pool); return NULL; } + +// +// Scroll Targets +// + +void DynOS_Add_Scroll_Target(u32 index, const char* name, u32 offset, u32 size) { + for (auto& lvlPair : DynOS_Lvl_GetArray()) { + for (auto& node : lvlPair.second->mVertices) { + if (node->mName.Find(name) >= 0) { + add_vtx_scroll_target(index, &node->mData[offset], size); + } + } + } +} + +void DynOS_Init_Scroll_Targets(void) { + init_vtx_scroll_targets(); +} diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 760541f8c..7ac323fa4 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -619,7 +619,9 @@ | id_bhvYellowBall | 532 | | id_bhvYellowCoin | 533 | | id_bhvYoshi | 534 | -| id_bhv_max_count | 535 | +| id_RM_Scroll_Texture | 535 | +| id_editor_Scroll_Texture | 536 | +| id_bhv_max_count | 537 | [:arrow_up_small:](#) diff --git a/docs/lua/functions-2.md b/docs/lua/functions-2.md index cd17218c3..ea85d7882 100644 --- a/docs/lua/functions-2.md +++ b/docs/lua/functions-2.md @@ -10184,6 +10184,24 @@
+## [uv_update_scroll](#uv_update_scroll) + +### Lua Example +`uv_update_scroll()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void uv_update_scroll(void);` + +[:arrow_up_small:](#) + +
+ ## [vec3f_copy_2](#vec3f_copy_2) ### Lua Example diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md index 29b418cb8..8c1d1861a 100644 --- a/docs/lua/functions-3.md +++ b/docs/lua/functions-3.md @@ -1084,6 +1084,26 @@
+## [rom_hack_cam_set_collisions](#rom_hack_cam_set_collisions) + +### Lua Example +`rom_hack_cam_set_collisions(enable)` + +### Parameters +| Field | Type | +| ----- | ---- | +| enable | `integer` | + +### Returns +- None + +### C Prototype +`void rom_hack_cam_set_collisions(u8 enable);` + +[:arrow_up_small:](#) + +
+ ## [rotate_camera_around_walls](#rotate_camera_around_walls) ### Lua Example @@ -2768,6 +2788,85 @@
+## [stop_background_music](#stop_background_music) + +### Lua Example +`stop_background_music(seqId)` + +### Parameters +| Field | Type | +| ----- | ---- | +| seqId | `integer` | + +### Returns +- None + +### C Prototype +`void stop_background_music(u16 seqId);` + +[:arrow_up_small:](#) + +
+ +## [stop_sound](#stop_sound) + +### Lua Example +`stop_sound(soundBits, pos)` + +### Parameters +| Field | Type | +| ----- | ---- | +| soundBits | `integer` | +| pos | [Vec3f](structs.md#Vec3f) | + +### Returns +- None + +### C Prototype +`void stop_sound(u32 soundBits, f32 *pos);` + +[:arrow_up_small:](#) + +
+ +## [stop_sounds_from_source](#stop_sounds_from_source) + +### Lua Example +`stop_sounds_from_source(pos)` + +### Parameters +| Field | Type | +| ----- | ---- | +| pos | [Vec3f](structs.md#Vec3f) | + +### Returns +- None + +### C Prototype +`void stop_sounds_from_source(f32 *pos);` + +[:arrow_up_small:](#) + +
+ +## [stop_sounds_in_continuous_banks](#stop_sounds_in_continuous_banks) + +### Lua Example +`stop_sounds_in_continuous_banks()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void stop_sounds_in_continuous_banks(void);` + +[:arrow_up_small:](#) + +
+ --- # functions from interaction.h diff --git a/docs/lua/functions-4.md b/docs/lua/functions-4.md index db18a1cf7..61d8eb8a1 100644 --- a/docs/lua/functions-4.md +++ b/docs/lua/functions-4.md @@ -6286,12 +6286,53 @@
+## [warp_to_start_level](#warp_to_start_level) + +### Lua Example +`local booleanValue = warp_to_start_level()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool warp_to_start_level(void);` + +[:arrow_up_small:](#) + +
+ --- # functions from smlua_misc_utils.h
+## [add_scroll_target](#add_scroll_target) + +### Lua Example +`add_scroll_target(index, name, offset, size)` + +### Parameters +| Field | Type | +| ----- | ---- | +| index | `integer` | +| name | `string` | +| offset | `integer` | +| size | `integer` | + +### Returns +- None + +### C Prototype +`void add_scroll_target(u32 index, const char* name, u32 offset, u32 size);` + +[:arrow_up_small:](#) + +
+ ## [allocate_mario_action](#allocate_mario_action) ### Lua Example @@ -6766,6 +6807,24 @@
+## [get_dialog_id](#get_dialog_id) + +### Lua Example +`local integerValue = get_dialog_id()` + +### Parameters +- None + +### Returns +- `integer` + +### C Prototype +`s16 get_dialog_id(void);` + +[:arrow_up_small:](#) + +
+ ## [get_environment_region](#get_environment_region) ### Lua Example @@ -6988,6 +7047,24 @@
+## [init_scroll_targets](#init_scroll_targets) + +### Lua Example +`init_scroll_targets()` + +### Parameters +- None + +### Returns +- None + +### C Prototype +`void init_scroll_targets(void);` + +[:arrow_up_small:](#) + +
+ ## [is_game_paused](#is_game_paused) ### Lua Example @@ -7006,6 +7083,24 @@
+## [is_transition_playing](#is_transition_playing) + +### Lua Example +`local booleanValue = is_transition_playing()` + +### Parameters +- None + +### Returns +- `boolean` + +### C Prototype +`bool is_transition_playing(void);` + +[:arrow_up_small:](#) + +
+ ## [movtexqc_register](#movtexqc_register) ### Lua Example diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 8b9b1ebb7..d8d9cb142 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -583,6 +583,7 @@ - [spawn_wind_particles](functions-2.md#spawn_wind_particles) - [tox_box_move](functions-2.md#tox_box_move) - [update_angle_from_move_flags](functions-2.md#update_angle_from_move_flags) + - [uv_update_scroll](functions-2.md#uv_update_scroll) - [vec3f_copy_2](functions-2.md#vec3f_copy_2)
@@ -648,6 +649,7 @@ - [random_vec3s](functions-3.md#random_vec3s) - [reset_camera](functions-3.md#reset_camera) - [resolve_geometry_collisions](functions-3.md#resolve_geometry_collisions) + - [rom_hack_cam_set_collisions](functions-3.md#rom_hack_cam_set_collisions) - [rotate_camera_around_walls](functions-3.md#rotate_camera_around_walls) - [rotate_in_xz](functions-3.md#rotate_in_xz) - [rotate_in_yz](functions-3.md#rotate_in_yz) @@ -748,6 +750,10 @@ - [seq_player_fade_out](functions-3.md#seq_player_fade_out) - [seq_player_lower_volume](functions-3.md#seq_player_lower_volume) - [seq_player_unlower_volume](functions-3.md#seq_player_unlower_volume) + - [stop_background_music](functions-3.md#stop_background_music) + - [stop_sound](functions-3.md#stop_sound) + - [stop_sounds_from_source](functions-3.md#stop_sounds_from_source) + - [stop_sounds_in_continuous_banks](functions-3.md#stop_sounds_in_continuous_banks)
@@ -1395,10 +1401,12 @@ - [warp_restart_level](functions-4.md#warp_restart_level) - [warp_to_castle](functions-4.md#warp_to_castle) - [warp_to_level](functions-4.md#warp_to_level) + - [warp_to_start_level](functions-4.md#warp_to_start_level)
- smlua_misc_utils.h + - [add_scroll_target](functions-4.md#add_scroll_target) - [allocate_mario_action](functions-4.md#allocate_mario_action) - [camera_config_enable_analog_cam](functions-4.md#camera_config_enable_analog_cam) - [camera_config_enable_free_cam](functions-4.md#camera_config_enable_free_cam) @@ -1424,6 +1432,7 @@ - [camera_unfreeze](functions-4.md#camera_unfreeze) - [deref_s32_pointer](functions-4.md#deref_s32_pointer) - [get_current_save_file_num](functions-4.md#get_current_save_file_num) + - [get_dialog_id](functions-4.md#get_dialog_id) - [get_environment_region](functions-4.md#get_environment_region) - [get_hand_foot_pos_x](functions-4.md#get_hand_foot_pos_x) - [get_hand_foot_pos_y](functions-4.md#get_hand_foot_pos_y) @@ -1435,7 +1444,9 @@ - [hud_render_power_meter](functions-4.md#hud_render_power_meter) - [hud_set_value](functions-4.md#hud_set_value) - [hud_show](functions-4.md#hud_show) + - [init_scroll_targets](functions-4.md#init_scroll_targets) - [is_game_paused](functions-4.md#is_game_paused) + - [is_transition_playing](functions-4.md#is_transition_playing) - [movtexqc_register](functions-4.md#movtexqc_register) - [play_transition](functions-4.md#play_transition) - [save_file_set_using_backup_slot](functions-4.md#save_file_set_using_backup_slot) diff --git a/docs/lua/structs.md b/docs/lua/structs.md index dc591b855..6b4de48dc 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -761,8 +761,13 @@ | camera | [TextureInfo](structs.md#TextureInfo) | read-only | | coin | [TextureInfo](structs.md#TextureInfo) | read-only | | lakitu | [TextureInfo](structs.md#TextureInfo) | read-only | +| luigi_head | [TextureInfo](structs.md#TextureInfo) | read-only | +| mario_head | [TextureInfo](structs.md#TextureInfo) | read-only | | no_camera | [TextureInfo](structs.md#TextureInfo) | read-only | | star | [TextureInfo](structs.md#TextureInfo) | read-only | +| toad_head | [TextureInfo](structs.md#TextureInfo) | read-only | +| waluigi_head | [TextureInfo](structs.md#TextureInfo) | read-only | +| wario_head | [TextureInfo](structs.md#TextureInfo) | read-only | [:arrow_up_small:](#) @@ -805,6 +810,7 @@ | prevTimestamp | `integer` | | | scale | [Vec3f](structs.md#Vec3f) | read-only | | sharedChild | [GraphNode](structs.md#GraphNode) | | +| skipInViewCheck | `boolean` | | | skipInterpolationTimestamp | `integer` | | | unk4C | [SpawnInfo](structs.md#SpawnInfo) | | diff --git a/include/behavior_data.h b/include/behavior_data.h index 4eb2c0d0e..58cb9ffc8 100644 --- a/include/behavior_data.h +++ b/include/behavior_data.h @@ -539,5 +539,7 @@ extern const BehaviorScript bhvEndBirds1[]; extern const BehaviorScript bhvEndBirds2[]; extern const BehaviorScript bhvIntroScene[]; extern const BehaviorScript bhvUnusedFakeStar[]; +extern const BehaviorScript RM_Scroll_Texture[]; +extern const BehaviorScript editor_Scroll_Texture[]; #endif // BEHAVIOR_DATA_H diff --git a/include/behavior_table.h b/include/behavior_table.h index c595b282d..a18b67105 100644 --- a/include/behavior_table.h +++ b/include/behavior_table.h @@ -539,6 +539,8 @@ enum BehaviorId { id_bhvYellowBall, id_bhvYellowCoin, id_bhvYoshi, + id_RM_Scroll_Texture, + id_editor_Scroll_Texture, id_bhv_max_count // must be the last in the list }; diff --git a/include/types.h b/include/types.h index 932396b0d..c07d6f326 100644 --- a/include/types.h +++ b/include/types.h @@ -7,6 +7,7 @@ #include #include "macros.h" #include "pc/network/version.h" +#include "src/pc/platform.h" // Certain functions are marked as having return values, but do not // actually return a value. This causes undefined behavior, which we'd rather @@ -155,6 +156,7 @@ struct GraphNodeObject Mat4 *throwMatrixPrev; /*0x54*/ Vec3f cameraToObject; u32 skipInterpolationTimestamp; + bool skipInViewCheck; }; struct ObjectNode diff --git a/mods/character-movesets.lua b/mods/character-movesets.lua index b7d1ea207..ed11e8d50 100644 --- a/mods/character-movesets.lua +++ b/mods/character-movesets.lua @@ -36,8 +36,8 @@ end -- luigi -- ----------- -ACT_SPIN_POUND_LAND = allocate_mario_action(ACT_GROUP_STATIONARY | ACT_FLAG_STATIONARY | ACT_FLAG_ATTACKING) -ACT_SPIN_POUND = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ATTACKING) +ACT_SPIN_POUND_LAND = allocate_mario_action(ACT_FLAG_STATIONARY | ACT_FLAG_ATTACKING) +ACT_SPIN_POUND = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ATTACKING) function act_spin_pound(m) local e = gStateExtras[m.playerIndex] @@ -139,6 +139,8 @@ function luigi_before_phys_step(m) local floorClass = mario_get_floor_class(m) local hScale = 1.0 local vScale = 1.0 + + if gPlayerSyncTable[0].modelId ~= nil then return end -- faster swimming if (m.action & ACT_FLAG_SWIMMING) ~= 0 then @@ -191,6 +193,8 @@ end function luigi_on_set_action(m) local e = gStateExtras[m.playerIndex] + + if gPlayerSyncTable[0].modelId ~= nil then return end -- extra height to the backflip if m.action == ACT_BACKFLIP then @@ -216,6 +220,8 @@ end function luigi_update(m) local e = gStateExtras[m.playerIndex] + + if gPlayerSyncTable[0].modelId ~= nil then return end -- increase player damage if (m.hurtCounter > e.lastHurtCounter) then @@ -225,14 +231,18 @@ function luigi_update(m) -- air scuttle e.scuttle = 0 - local shouldScuttle = (m.action == ACT_JUMP or m.action == ACT_DOUBLE_JUMP) and ((m.controller.buttonDown & A_BUTTON) ~= 0 and m.vel.y < -5) + local shouldScuttle = (m.action == ACT_JUMP or m.action == ACT_DOUBLE_JUMP or m.action == ACT_HOLD_JUMP) and ((m.controller.buttonDown & A_BUTTON) ~= 0 and m.vel.y < -5) if shouldScuttle then -- prevent wing flutter from glitching out while scuttling if m.marioBodyState.wingFlutter == 1 then m.vel.y = m.vel.y + 1 else m.vel.y = m.vel.y + 3 - set_mario_animation(m, MARIO_ANIM_RUNNING_UNUSED) + if m.action == ACT_HOLD_JUMP then + set_mario_animation(m, MARIO_ANIM_RUN_WITH_LIGHT_OBJ) + else + set_mario_animation(m, MARIO_ANIM_RUNNING_UNUSED) + end set_anim_to_frame(m, e.animFrame) e.animFrame = e.animFrame + 13 if e.animFrame >= m.marioObj.header.gfx.animInfo.curAnim.loopEnd then @@ -360,7 +370,7 @@ gEventTable[CT_TOAD] = { -- waluigi -- ------------- -ACT_WALL_SLIDE = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_MOVING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) +ACT_WALL_SLIDE = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_MOVING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) function act_wall_slide(m) if (m.input & INPUT_A_PRESSED) ~= 0 then @@ -481,11 +491,12 @@ gEventTable[CT_WALUIGI] = { ----------- -- wario -- ----------- - -ACT_WARIO_DASH = allocate_mario_action(ACT_GROUP_MOVING | ACT_FLAG_MOVING | ACT_FLAG_ATTACKING) -ACT_WARIO_AIR_DASH = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ATTACKING) -ACT_CORKSCREW_CONK = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_AIR | ACT_FLAG_ATTACKING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) -ACT_WARIO_SPINNING_OBJ = allocate_mario_action(ACT_GROUP_OBJECT | ACT_FLAG_STATIONARY) +ACT_WARIO_DASH = allocate_mario_action(ACT_FLAG_MOVING | ACT_FLAG_ATTACKING) +ACT_WARIO_AIR_DASH = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ATTACKING) +ACT_WARIO_HOLD_JUMP = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) +ACT_CORKSCREW_CONK = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ATTACKING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) +ACT_PILEDRIVER = allocate_mario_action(ACT_FLAG_AIR | ACT_FLAG_ATTACKING | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION) +ACT_WARIO_SPINNING_OBJ = allocate_mario_action(ACT_FLAG_STATIONARY) function act_corkscrew_conk(m) local e = gStateExtras[m.playerIndex] @@ -533,7 +544,7 @@ function act_wario_dash(m) -- make sound if m.actionTimer == 0 then m.actionState = m.actionArg - play_character_sound(m, CHAR_SOUND_YAHOO) + play_character_sound(m, CHAR_SOUND_WAH2) end -- walk once dash is up @@ -562,6 +573,8 @@ function act_wario_dash(m) if (m.input & INPUT_Z_PRESSED) ~= 0 then return set_mario_action(m, ACT_SLIDE_KICK, 0) end + + m.faceAngle.y = m.intendedYaw - approach_s32(convert_s16(m.intendedYaw - m.faceAngle.y), 0, 0x400, 0x400) m.actionTimer = m.actionTimer + 1 return 0 @@ -609,6 +622,8 @@ function act_wario_air_dash(m) if (m.input & INPUT_Z_PRESSED) ~= 0 then return set_mario_action(m, ACT_SLIDE_KICK, 0) end + + m.faceAngle.y = m.intendedYaw - approach_s32(convert_s16(m.intendedYaw - m.faceAngle.y), 0, 0x400, 0x400) m.actionTimer = m.actionTimer + 1 return 0 @@ -619,7 +634,7 @@ function act_wario_spinning_obj(m) -- throw object if m.playerIndex == 0 and (m.input & INPUT_B_PRESSED) ~= 0 then - play_character_sound_if_no_flag(m, CHAR_SOUND_WAH2, MARIO_MARIO_SOUND_PLAYED) + play_character_sound_if_no_flag(m, CHAR_SOUND_SO_LONGA_BOWSER, MARIO_MARIO_SOUND_PLAYED) play_sound_if_no_flag(m, SOUND_ACTION_THROW, MARIO_ACTION_SOUND_PLAYED) return set_mario_action(m, ACT_RELEASING_BOWSER, 0) end @@ -773,6 +788,59 @@ function wario_update_spin_input(m) e.lastIntendedMag = m.intendedMag end +function act_wario_hold_jump(m) + if (m.marioObj.oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) ~= 0 then + return drop_and_set_mario_action(m, ACT_FREEFALL, 0) + end + + if (m.input & INPUT_B_PRESSED) ~= 0 and (m.heldObj ~= nil and (m.heldObj.oInteractionSubtype & INT_SUBTYPE_HOLDABLE_NPC) ~= nil) then + return set_mario_action(m, ACT_AIR_THROW, 0) + end + + if (m.input & INPUT_Z_PRESSED) ~= 0 then + return set_mario_action(m, ACT_PILEDRIVER, 0) + end + + play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0) + common_air_action_step(m, ACT_HOLD_JUMP_LAND, MARIO_ANIM_JUMP_WITH_LIGHT_OBJ, + AIR_STEP_CHECK_LEDGE_GRAB) + return false +end + +function act_piledriver(m) + local e = gStateExtras[m.playerIndex] + if m.actionTimer == 0 then + play_sound(SOUND_ACTION_SPIN, m.marioObj.header.gfx.cameraToObject) + play_character_sound(m, CHAR_SOUND_SO_LONGA_BOWSER) + end + set_mario_animation(m, MARIO_ANIM_HOLDING_BOWSER) + local stepResult = perform_air_step(m, 0) + if stepResult == AIR_STEP_LANDED then + if should_get_stuck_in_ground(m) ~= 0 then + queue_rumble_data_mario(m, 5, 80) + play_sound(SOUND_MARIO_OOOF2, m.marioObj.header.gfx.cameraToObject) + m.particleFlags = m.particleFlags | PARTICLE_MIST_CIRCLE + set_mario_action(m, ACT_BUTT_STUCK_IN_GROUND, 0) + else + play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_HEAVY_LANDING) + if check_fall_damage(m, ACT_HARD_BACKWARD_GROUND_KB) == 0 then + m.particleFlags = m.particleFlags | PARTICLE_MIST_CIRCLE | PARTICLE_HORIZONTAL_STAR + -- set facing direction + -- not part of original Extended Moveset + local yawDiff = m.faceAngle.y - m.intendedYaw + e.rotAngle = e.rotAngle + yawDiff + m.faceAngle.y = m.intendedYaw + return set_mario_action(m, ACT_RELEASING_BOWSER, 0) + end + end + end + m.vel.y = -32 + mario_set_forward_vel(m, 0) + m.faceAngle.y = m.faceAngle.y + 0x3000 + m.actionTimer = m.actionTimer + 1 + return 0 +end + function wario_before_phys_step(m) local hScale = 1.0 @@ -883,6 +951,11 @@ function wario_on_set_action(m) m.pos.y = m.pos.y + 10 end end + + if m.action == ACT_HOLD_JUMP then + return set_mario_action(m, ACT_WARIO_HOLD_JUMP, 0) + end + e.lastAction = action end @@ -922,6 +995,7 @@ function wario_update(m) -- shake camera if m.action == ACT_GROUND_POUND_LAND then set_camera_shake_from_point(SHAKE_POS_MEDIUM, m.pos.x, m.pos.y, m.pos.z) + m.squishTimer = 5 end -- faster ground pound @@ -1001,6 +1075,18 @@ function mario_update(m) gEventTable[m.character.type].update(m) end +function convert_s16(num) + local min = -32768 + local max = 32767 + while (num < min) do + num = max + (num - min) + end + while (num > max) do + num = min + (num - max) + end + return num +end + ----------- -- hooks -- ----------- @@ -1009,10 +1095,12 @@ hook_event(HOOK_MARIO_UPDATE, mario_update) hook_event(HOOK_ON_SET_MARIO_ACTION, mario_on_set_action) hook_event(HOOK_BEFORE_PHYS_STEP, mario_before_phys_step) -hook_mario_action(ACT_WALL_SLIDE, { every_frame = act_wall_slide }) -hook_mario_action(ACT_SPIN_POUND, { every_frame = act_spin_pound }, INT_GROUND_POUND_OR_TWIRL) -hook_mario_action(ACT_SPIN_POUND_LAND, { every_frame = act_spin_pound_land }, INT_GROUND_POUND_OR_TWIRL) -hook_mario_action(ACT_WARIO_DASH, { every_frame = act_wario_dash }, INT_PUNCH) -hook_mario_action(ACT_WARIO_AIR_DASH, { every_frame = act_wario_air_dash }, INT_PUNCH) -hook_mario_action(ACT_CORKSCREW_CONK, { every_frame = act_corkscrew_conk }, INT_FAST_ATTACK_OR_SHELL) -hook_mario_action(ACT_WARIO_SPINNING_OBJ, { every_frame = act_wario_spinning_obj }) +hook_mario_action(ACT_WALL_SLIDE, act_wall_slide) +hook_mario_action(ACT_SPIN_POUND, act_spin_pound, INT_GROUND_POUND_OR_TWIRL) +hook_mario_action(ACT_SPIN_POUND_LAND, act_spin_pound_land, INT_GROUND_POUND_OR_TWIRL) +hook_mario_action(ACT_WARIO_DASH, act_wario_dash, INT_KICK) +hook_mario_action(ACT_WARIO_AIR_DASH, act_wario_air_dash, INT_KICK) +hook_mario_action(ACT_CORKSCREW_CONK, act_corkscrew_conk, INT_FAST_ATTACK_OR_SHELL) +hook_mario_action(ACT_WARIO_SPINNING_OBJ, act_wario_spinning_obj) +hook_mario_action(ACT_PILEDRIVER, act_piledriver) +hook_mario_action(ACT_WARIO_HOLD_JUMP, act_wario_hold_jump) diff --git a/mods/extended-moveset.lua b/mods/extended-moveset.lua index 0cbd6ec41..357f12d04 100644 --- a/mods/extended-moveset.lua +++ b/mods/extended-moveset.lua @@ -563,7 +563,6 @@ function act_spin_pound_land(m) end if (m.input & INPUT_A_PRESSED) ~= 0 then - m.vel.y = 65.0 return set_jumping_action(m, ACT_GROUND_POUND_JUMP, 0) end @@ -1002,7 +1001,9 @@ function act_dive_slide(m) if (m.input & INPUT_B_PRESSED) ~= 0 then -- dive hop m.vel.y = 21.0 - return set_mario_action(m, ACT_DIVE, 1) + set_mario_action(m, ACT_DIVE, 1) + set_mario_animation(m, MARIO_ANIM_DIVE) + set_anim_to_frame(m, 15) end end @@ -1338,7 +1339,9 @@ function mario_on_set_action(m) end end - if m.action == ACT_WATER_PLUNGE and m.prevAction == ACT_GROUND_POUND then + if m.action == ACT_GROUND_POUND_JUMP then + m.vel.y = 65.0 + elseif m.action == ACT_WATER_PLUNGE and m.prevAction == ACT_GROUND_POUND then return set_mario_action(m, ACT_WATER_GROUND_POUND, 1) elseif m.action == ACT_WALL_SLIDE then m.vel.y = 0.0 diff --git a/mods/hide-and-seek.lua b/mods/hide-and-seek.lua index b1740d1b6..e5e8bbbef 100644 --- a/mods/hide-and-seek.lua +++ b/mods/hide-and-seek.lua @@ -37,6 +37,10 @@ sDistanceTimeout = 10 * 30 -- ten seconds -- flashing 'keep moving' index sFlashingIndex = 0 +-- pu prevention +local puX = 0 +local puZ = 0 + function server_update(m) -- increment timer sRoundTimer = sRoundTimer + 1 @@ -197,40 +201,43 @@ function mario_update(m) s.seeking = true end + -- remove caps if m.playerIndex == 0 or gGlobalSyncTable.roundState ~= ROUND_STATE_ACTIVE then if gGlobalSyncTable.seekerCaps and gPlayerSyncTable[m.playerIndex].seeking then - m.flags = m.flags & ~MARIO_WING_CAP --Remove wing cap if seeking - m.flags = m.flags & ~MARIO_METAL_CAP --Remove metal cap if seeking + m.flags = m.flags & ~MARIO_WING_CAP -- remove wing cap if seeking + m.flags = m.flags & ~MARIO_METAL_CAP -- remove metal cap if seeking stop_cap_music() m.capTimer = 0 elseif gGlobalSyncTable.hiderCaps and not gPlayerSyncTable[m.playerIndex].seeking then - m.flags = m.flags & ~MARIO_WING_CAP --Remove wing cap if hiding - m.flags = m.flags & ~MARIO_METAL_CAP --Remove metal cap if hiding + m.flags = m.flags & ~MARIO_WING_CAP -- remove wing cap if hiding + m.flags = m.flags & ~MARIO_METAL_CAP -- remove metal cap if hiding stop_cap_music() m.capTimer = 0 end end - if gNetworkPlayers[m.playerIndex].currLevelNum == LEVEL_RR and m.playerIndex == 0 then - warp_to_castle(LEVEL_RR) - end + -- warp players out of banned levels + if m.playerIndex == 0 then + if gNetworkPlayers[m.playerIndex].currLevelNum == LEVEL_RR then + warp_to_castle(LEVEL_RR) + end - if gNetworkPlayers[m.playerIndex].currLevelNum == LEVEL_BOWSER_1 and m.playerIndex == 0 then - warp_to_castle(LEVEL_BITDW) - end + if gNetworkPlayers[m.playerIndex].currLevelNum == LEVEL_BOWSER_1 then + warp_to_castle(LEVEL_BITDW) + end - if gNetworkPlayers[m.playerIndex].currLevelNum == LEVEL_BOWSER_2 and m.playerIndex == 0 then - warp_to_castle(LEVEL_BITFS) - end + if gNetworkPlayers[m.playerIndex].currLevelNum == LEVEL_BOWSER_2 then + warp_to_castle(LEVEL_BITFS) + end - if gNetworkPlayers[m.playerIndex].currLevelNum == LEVEL_BOWSER_3 and m.playerIndex == 0 then - warp_to_castle(LEVEL_BITS) - end + if gNetworkPlayers[m.playerIndex].currLevelNum == LEVEL_BOWSER_3 then + warp_to_castle(LEVEL_BITS) + end - -- this doesn't work properly, it automatically ends the round again - --if m.playerIndex == 0 and gPlayerSyncTable[m.playerIndex].seeking and gGlobalSyncTable.displayTimer == 0 and gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then - -- warp_to_level(LEVEL_CASTLE_GROUNDS, 1, 0) - --end + if gPlayerSyncTable[m.playerIndex].seeking and gGlobalSyncTable.displayTimer == 0 and gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then + warp_to_level(gLevelValues.entryLevel, 1, 0) + end + end -- display all seekers as metal if s.seeking then @@ -238,6 +245,23 @@ function mario_update(m) m.health = 0x880 end + + -- pu prevention + if m.pos.x >= 0 then + puX = math.floor((8192 + m.pos.x) / 65536) + else + puX = math.ceil((-8192 + m.pos.x) / 65536) + end + + if m.pos.z >= 0 then + puZ = math.floor((8192 + m.pos.z) / 65536) + else + puZ = math.ceil((-8192 + m.pos.z) / 65536) + end + + if (puX ~= 0) or (puZ ~= 0) then + s.seeking = true + end end function mario_before_phys_step(m) @@ -565,8 +589,6 @@ function on_seeking_changed(tag, oldVal, newVal) sLastSeekerIndex = m.playerIndex end sRoundTimer = 32 - - end if newVal then diff --git a/mods/shell-rush/level-data.lua b/mods/shell-rush/level-data.lua index 3eef859ea..8546039ca 100644 --- a/mods/shell-rush/level-data.lua +++ b/mods/shell-rush/level-data.lua @@ -7,6 +7,53 @@ gLevelDataTable = { platforms = { }, }, + [LEVEL_CASTLE_GROUNDS] = { + waypoints = { + { x = -3122, y = 260, z = 4191 }, + { x = -3616, y = 415, z = 365 }, + { x = -5348, y = 492, z = -3201 }, + { x = -6273, y = 497, z = -2918 }, + { x = -6288, y = 336, z = -605 }, + { x = -3708, y = 412, z = 165 }, + { x = -331, y = 806, z = 511 }, + { x = 5171, y = 385, z = -1250 }, + { x = 4673, y = 544, z = -4888 }, + { x = 3930, y = -511, z = -2185 }, + { x = -265, y = -511, z = -1126 }, + { x = -3904, y = -511, z = -1674 }, + { x = -308, y = -511, z = -1189 }, + { x = 3891, y = -511, z = -1034 }, + { x = 4336, y = -800, z = 2988 }, + { x = 297, y = 632, z = 2089 }, + }, + powerups = { + { pos = { x = -3801, y = 399, z = 709 }, obj = nil }, + { pos = { x = -3604, y = 415, z = 363 }, obj = nil }, + { pos = { x = -3378, y = 431, z = -4 }, obj = nil }, + { pos = { x = -3302, y = 431, z = 599 }, obj = nil }, + { pos = { x = -3949, y = 396, z = 120 }, obj = nil }, + { pos = { x = -292, y = -511, z = -1156 }, obj = nil }, + { pos = { x = -292, y = -511, z = -1571 }, obj = nil }, + { pos = { x = -292, y = -511, z = -741 }, obj = nil }, + }, + spawn = { + { + a = { x = -2365, y = 260, z = 4673 }, + b = { x = -940, y = 260, z = 5294 }, + }, + { + a = { x = -2134, y = 260, z = 4143 }, + b = { x = -348, y = 260, z = 4922 }, + }, + }, + erase = { + [id_bhvDoorWarp] = true, + }, + platforms = { + { pos = { x = -3369, y = -540, z = -2025 }, rot = { x = 0, y = 0, z = 0 }, scale = { x = 1, y = 1, z = 1 } }, + }, + }, + [LEVEL_BOB] = { waypoints = { { x = -1953, y = 0, z = 1418 }, @@ -98,50 +145,98 @@ gLevelDataTable = { }, }, - [LEVEL_CASTLE_GROUNDS] = { + [LEVEL_TTM] = { waypoints = { - { x = -3122, y = 260, z = 4191 }, - { x = -3616, y = 415, z = 365 }, - { x = -5348, y = 492, z = -3201 }, - { x = -6273, y = 497, z = -2918 }, - { x = -6288, y = 336, z = -605 }, - { x = -3708, y = 412, z = 165 }, - { x = -331, y = 806, z = 511 }, - { x = 5171, y = 385, z = -1250 }, - { x = 4673, y = 544, z = -4888 }, - { x = 3930, y = -511, z = -2185 }, - { x = -265, y = -511, z = -1126 }, - { x = -3904, y = -511, z = -1674 }, - { x = -308, y = -511, z = -1189 }, - { x = 3891, y = -511, z = -1034 }, - { x = 4336, y = -800, z = 2988 }, - { x = 297, y = 632, z = 2089 }, + { x = 1802, y = -4231, z = 5331 }, + { x = 4415, y = -3520, z = 2452 }, + { x = 4468, y = -3287, z = 20 }, + { x = 4933, y = -3075, z = -2634 }, + { x = -696, y = -2671, z = -4768 }, + { x = -3440, y = -2552, z = -2028 }, + { x = -1758, y = -2048, z = 3317 }, + { x = 2759, y = -1548, z = 4366 }, + { x = 3851, y = -1234, z = 666 }, + { x = 3571, y = -1013, z = -1833 }, + { x = -349, y = -27, z = -2919 }, + { x = -1952, y = 0, z = 713 }, + { x = 1388, y = 606, z = 2048 }, + { x = 3308, y = 375, z = 1101 }, + { x = 3392, y = 768, z = -1496 }, + { x = 99, y = 1242, z = -1963 }, + { x = -1176, y = 1536, z = 173 }, + { x = 1312, y = 1587, z = 1879 }, + { x = 2549, y = 1457, z = 1903 }, + { x = 2927, y = 1536, z = 254 }, + { x = 1970, y = 1920, z = -548 }, + { x = 1124, y = 2309, z = 374 }, }, powerups = { - { pos = { x = -3801, y = 399, z = 709 }, obj = nil }, - { pos = { x = -3604, y = 415, z = 363 }, obj = nil }, - { pos = { x = -3378, y = 431, z = -4 }, obj = nil }, - { pos = { x = -3302, y = 431, z = 599 }, obj = nil }, - { pos = { x = -3949, y = 396, z = 120 }, obj = nil }, - { pos = { x = -292, y = -511, z = -1156 }, obj = nil }, - { pos = { x = -292, y = -511, z = -1571 }, obj = nil }, - { pos = { x = -292, y = -511, z = -741 }, obj = nil }, + { pos = { x = 4301, y = -3284, z = -4 }, obj = nil }, + { pos = { x = 4501, y = -3284, z = -4 }, obj = nil }, + { pos = { x = 4701, y = -3284, z = -4 }, obj = nil }, + { pos = { x = 357, y = -2047, z = 3510 }, obj = nil }, + { pos = { x = 357, y = -2047, z = 3810 }, obj = nil }, + { pos = { x = 357, y = -2047, z = 4048 }, obj = nil }, + { pos = { x = 2786, y = 313, z = 1171 }, obj = nil }, + { pos = { x = 2977, y = 313, z = 1481 }, obj = nil }, + { pos = { x = 3159, y = 313, z = 1931 }, obj = nil }, }, spawn = { { - a = { x = -2365, y = 260, z = 4673 }, - b = { x = -940, y = 260, z = 5294 }, + a = { x = 349, y = -4332, z = 5410 }, + b = { x = -1774, y = -4354, z = 5374 }, }, { - a = { x = -2134, y = 260, z = 4143 }, - b = { x = -348, y = 260, z = 4922 }, + a = { x = 47, y = -4332, z = 5968 }, + b = { x = -1942, y = -4459, z = 5840 }, }, }, erase = { - [id_bhvDoorWarp] = true, + [id_bhvChuckya] = true, }, platforms = { - { pos = { x = -3369, y = -540, z = -2025 }, rot = { x = 0, y = 0, z = 0 }, scale = { x = 1, y = 1, z = 1 } }, + { pos = { x = 3122, y = 1000, z = -1044 }, rot = { x = 0, y = 0, z = 0x4000 }, scale = { x = 2, y = 2, z = 2 } }, + }, + }, + + [LEVEL_CCM] = { + waypoints = { + { x = -513, y = 2560, z = -2567 }, + { x = 3524, y = 2253, z = -2367 }, + { x = 1981, y = 1480, z = 2361 }, + { x = -3132, y = 1095, z = 1302 }, + { x = -4232, y = 819, z = -979 }, + { x = -2972, y = 757, z = -2704 }, + { x = 3109, y = -411, z = -2739 }, + { x = -2066, y = -1182, z = -3710 }, + { x = -4748, y = -1349, z = -1054 }, + { x = -3354, y = -1535, z = 3948 }, + { x = 755, y = -1536, z = 5171 }, + { x = 2669, y = -2303, z = 3379 }, + { x = 4163, y = -3071, z = 685 }, + { x = 2775, y = -4351, z = 3636 }, + { x = 4067, y = -4607, z = 1758 }, + { x = 3349, y = -4694, z = -183 }, + }, + powerups = { + { pos = { x = 4301, y = -3284, z = -4 }, obj = nil }, + }, + spawn = { + { + a = { x = -1002, y = 2560, z = -2680 }, + b = { x = -2129, y = 2560, z = -2554 }, + }, + { + a = { x = -594, y = 2560, z = -2142 }, + b = { x = -2408, y = 2560, z = -2127 }, + }, + }, + erase = { + [id_bhvRedCoin] = true, + [id_bhvSpindrift] = true, + }, + platforms = { + { pos = { x = -27, y = 3090, z = -1331 }, rot = { x = 0, y = 0, z = 0 }, scale = { x = 1.25, y = 1, z = 2 } }, }, }, } diff --git a/mods/shell-rush/race.lua b/mods/shell-rush/race.lua index da084a677..6de6b1026 100644 --- a/mods/shell-rush/race.lua +++ b/mods/shell-rush/race.lua @@ -176,10 +176,14 @@ function race_update() -- race is finished, start a new one if gLevelData == gLevelDataTable[LEVEL_CASTLE_GROUNDS] then race_start(LEVEL_BOB) - elseif gLevelData == gLevelDataTable[LEVEL_SL] then - race_start(LEVEL_CASTLE_GROUNDS) elseif gLevelData == gLevelDataTable[LEVEL_BOB] then race_start(LEVEL_SL) + elseif gLevelData == gLevelDataTable[LEVEL_SL] then + race_start(LEVEL_TTM) + elseif gLevelData == gLevelDataTable[LEVEL_TTM] then + race_start(LEVEL_CCM) + elseif gLevelData == gLevelDataTable[LEVEL_CCM] then + race_start(LEVEL_CASTLE_GROUNDS) end end end @@ -191,6 +195,10 @@ function on_race_command(msg) djui_chat_message_create('Only the server can change this setting!') return true end + if msg == 'CG' then + race_start(LEVEL_CASTLE_GROUNDS) + return true + end if msg == 'BOB' then race_start(LEVEL_BOB) return true @@ -199,10 +207,13 @@ function on_race_command(msg) race_start(LEVEL_SL) return true end - if msg == 'CG' then - race_start(LEVEL_CASTLE_GROUNDS) + if msg == 'TTM' then + race_start(LEVEL_TTM) return true end + if msg == 'CCM' then + race_start(LEVEL_CCM) + end return false end @@ -228,7 +239,7 @@ function on_game_state_changed(tag, oldVal, newVal) end if network_is_server() then - hook_chat_command('race', "[CG|SL|BOB]", on_race_command) + hook_chat_command('race', "[CG|BOB|SL|TTM|CCM]", on_race_command) hook_chat_command('laps', "[number]", on_laps_command) end hook_on_sync_table_change(gGlobalSyncTable, 'gameState', i, on_game_state_changed) diff --git a/src/engine/level_script.c b/src/engine/level_script.c index 3d69bfed4..26680daea 100644 --- a/src/engine/level_script.c +++ b/src/engine/level_script.c @@ -27,6 +27,7 @@ #include "level_table.h" #include "src/pc/lua/utils/smlua_model_utils.h" #include "src/pc/lua/smlua.h" +#include "src/pc/djui/djui.h" #define CMD_GET(type, offset) (*(type *) (CMD_PROCESS_OFFSET(offset) + (u8 *) sCurrentCmd)) @@ -763,7 +764,7 @@ static void level_cmd_nop(void) { } static void level_cmd_show_dialog(void) { - if (sCurrAreaIndex != -1) { + if (sCurrAreaIndex != -1 && !gDjuiInMainMenu) { if (CMD_GET(u8, 2) < 2) { gAreas[sCurrAreaIndex].dialog[CMD_GET(u8, 2)] = CMD_GET(u8, 3); } diff --git a/src/game/behavior_actions.c b/src/game/behavior_actions.c index 4e3596cdf..4aac79222 100644 --- a/src/game/behavior_actions.c +++ b/src/game/behavior_actions.c @@ -284,3 +284,4 @@ s32 set_obj_anim_with_accel_and_sound(s16 a0, s16 a1, s32 a2) { #include "behaviors/strong_wind_particle.inc.c" #include "behaviors/sl_snowman_wind.inc.c" #include "behaviors/sl_walking_penguin.inc.c" +#include "behaviors/texscroll.inc.c" diff --git a/src/game/behavior_actions.h b/src/game/behavior_actions.h index 95f1899e9..506bece52 100644 --- a/src/game/behavior_actions.h +++ b/src/game/behavior_actions.h @@ -565,6 +565,7 @@ void bhv_intro_scene_loop(void); void bhv_dust_smoke_loop(void); void bhv_yoshi_loop(void); void bhv_volcano_trap_loop(void); +void uv_update_scroll(void); Gfx *geo_move_mario_part_from_parent(s32 run, UNUSED struct GraphNode *node, Mat4 mtx); diff --git a/src/game/behaviors/texscroll.inc.c b/src/game/behaviors/texscroll.inc.c new file mode 100644 index 000000000..b135469c0 --- /dev/null +++ b/src/game/behaviors/texscroll.inc.c @@ -0,0 +1,138 @@ +/* + * All credit goes to https://github.com/jesusyoshi54 + * also known as scuttlebugraiser, the creator of RM2C + * Created for the project https://github.com/jesusyoshi54/sm64ex-alo for RM2C support + * https://github.com/jesusyoshi54/sm64ex-alo/blob/master/src/game/behaviors/texscroll.inc.c + */ + +#include +#include "engine/math_util.h" +#include "src/game/scroll_targets.h" +#include "pc/pc_main.h" +#include "pc/utils/misc.h" + +/* SCROLLING BHVS */ +#define SCROLL_X 0 +#define SCROLL_Y 1 +#define SCROLL_Z 2 +#define SCROLL_UV_X 4 +#define SCROLL_UV_Y 5 + +/* SCROLLING TYPES */ +#define MODE_SCROLL_UV 0 +#define MODE_SCROLL_SINE 182 // 1 +#define MODE_SCROLL_JUMP 108 // 2 + +// typedef struct { + // float ob[3]; /* x, y, z */ + // unsigned short flag; + // short tc[2]; /* texture coord */ + // signed char n[3]; /* normal */ + // unsigned char a; /* alpha */ +// } Vtx_tn; + +// typedef union { + // Vtx_t v; /* Use this one for colors */ + // Vtx_tn n; /* Use this one for normals */ + // long long int force_structure_alignment; +// } Vtx; +extern Vtx *gScrollTargets[]; +extern f32 gRenderingDelta; + +static void shift_UV_JUMP(s32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 cycle) { + Vtx* *verts = get_scroll_targets(vtxIndex); + u16 i; + + if (verts[0]->n.flag++ <= cycle) { + return; + } + + verts[0]->n.flag = 0; + + if (bhv < SCROLL_UV_X) { + for (i = 0; i < vertcount; i++) { + verts[i]->n.ob[bhv] += speed; + } + } else { + for (i = 0; i < vertcount; i++) { + verts[i]->n.tc[bhv-SCROLL_UV_X] += speed; + } + } +} + +static void shift_UV_NORMAL(u32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 cycle) { + u16 overflownum = 0x1000; + Vtx* *verts = get_scroll_targets(vtxIndex); + u16 correction = 0; + u16 i; + + if (bhv < SCROLL_UV_X) { + if (verts[0]->n.flag >= cycle) { + correction = verts[0]->n.flag * speed; + verts[0]->n.flag = 0; + } + + for (i = 0; i < vertcount; i++) { + if (correction == 0) { + verts[i]->n.ob[bhv] += speed; + } else { + verts[i]->n.ob[bhv] -= correction; + } + } + } else { + if (verts[0]->n.flag * absi(speed) > overflownum) { + correction = overflownum * signum_positive(speed); + verts[0]->n.flag = 0; + } + + for (i = 0; i < vertcount; i++) { + if (correction == 0) { + verts[i]->n.tc[bhv-SCROLL_UV_X] += speed; + } else { + verts[i]->n.tc[bhv-SCROLL_UV_X] -= correction; + } + } + } + + if (correction == 0) { + verts[0]->n.flag++; + } +} + +static void shift_UV_SINE(u32 vtxIndex, u16 vertcount, s16 speed, u16 bhv, u16 cycle) { + Vtx* *verts = get_scroll_targets(vtxIndex); + u32 i; + + if (bhv < SCROLL_UV_X) { + for (i = 0; i < vertcount; i++) { + verts[i]->n.ob[bhv] += sins(verts[0]->n.flag) * speed; + } + } else { + for (i = 0; i < vertcount; i++) { + verts[i]->n.tc[bhv-SCROLL_UV_X] += (u16) (sins(verts[0]->n.flag) * speed); + } + } + verts[0]->n.flag += cycle * 0x23; +} + +// format I will use is x=spd, y=bhv, z=vert amount, rx=offset, ry=scrollType, rz=cycle, bparam=addr +void uv_update_scroll(void) { + s16 speed = (s16) o->oPosX; + u16 bhv = (u16) o->oPosY; + u16 vertCount = (u16) o->oPosZ; + u8 scrollType = (u8) o->oFaceAngleYaw; + u16 cycle = (u16) o->oFaceAngleRoll * 180 / 0x8000; + u32 vtxIndex = (u32) o->oBehParams; + + switch (scrollType) { + case MODE_SCROLL_UV: + shift_UV_NORMAL(vtxIndex, vertCount, speed, bhv, cycle); + break; + case MODE_SCROLL_SINE: + shift_UV_SINE(vtxIndex, vertCount, speed, bhv, cycle); + break; + case MODE_SCROLL_JUMP: + shift_UV_JUMP(vtxIndex, vertCount, speed, bhv, cycle); + break; + } +} diff --git a/src/game/camera.c b/src/game/camera.c index 52a5f715a..0cd32df7b 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -11749,10 +11749,19 @@ static u8 sRomHackZoom = 1; static s8 sRomHackIsUpdate = 0; static f32 sRomHackWaterFocus = 0; static f32 sRomHackWaterPitchOffset = 0; +u8 gRomHackCamSetCollisions = TRUE; + +void rom_hack_cam_set_collisions(u8 enable) { + gRomHackCamSetCollisions = enable; +} static u8 rom_hack_cam_can_see_mario(Vec3f desiredPos) { // do collision checking struct Surface *surf = NULL; + if (!gRomHackCamSetCollisions) { + return true; + } + f32 floorHeight = find_floor(desiredPos[0], desiredPos[1], desiredPos[2], &surf); if (surf == NULL || floorHeight <= -11000) { return false; diff --git a/src/game/camera.h b/src/game/camera.h index 9177920b7..c54720318 100644 --- a/src/game/camera.h +++ b/src/game/camera.h @@ -784,5 +784,6 @@ Gfx *geo_camera_fov(s32 callContext, struct GraphNode *g, UNUSED void *context); s32 set_camera_mode_fixed(struct Camera* c, s16 x, s16 y, s16 z); void camera_set_use_course_specific_settings(u8 enable); +void rom_hack_cam_set_collisions(u8 enable); #endif // CAMERA_H diff --git a/src/game/interaction.c b/src/game/interaction.c index 999416cb1..87b5fdc90 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -29,6 +29,7 @@ #include "pc/configfile.h" #include "pc/network/network.h" #include "pc/lua/smlua_hooks.h" +#include "pc/cheats.h" enum InteractionFlag { INT_GROUND_POUND_OR_TWIRL = (1 << 0), // 0x01 @@ -2249,7 +2250,7 @@ void check_death_barrier(struct MarioState *m) { } void check_lava_boost(struct MarioState *m) { - if (m->action == ACT_BUBBLED) { return; } + if (m->action == ACT_BUBBLED || (Cheats.enabled && Cheats.godMode)) { return; } if (!(m->action & ACT_FLAG_RIDING_SHELL) && m->pos[1] < m->floorHeight + 10.0f) { if (!(m->flags & MARIO_METAL_CAP)) { m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 12 : 18; diff --git a/src/game/level_update.c b/src/game/level_update.c index 35812c57f..d9af72be9 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -20,7 +20,7 @@ #include "object_list_processor.h" #include "ingame_menu.h" #include "obj_behaviors.h" -#include "game/object_helpers.h" +#include "object_helpers.h" #include "save_file.h" #include "hardcoded.h" #include "debug_course.h" @@ -438,7 +438,7 @@ void init_mario_after_warp(void) { set_mario_initial_action(gMarioState, marioSpawnType, sWarpDest.arg); // remove offset from local mario during warps - if (sWarpDest.type == WARP_TYPE_SAME_AREA) { + if (sWarpDest.type == WARP_TYPE_SAME_AREA && marioSpawnType != MARIO_SPAWN_DOOR_WARP) { gMarioState[0].pos[0] = (s16)spawnNode->object->oPosX; gMarioState[0].pos[1] = (s16)spawnNode->object->oPosY; gMarioState[0].pos[2] = (s16)spawnNode->object->oPosZ; @@ -525,6 +525,10 @@ void init_mario_after_warp(void) { network_player_update_course_level(gNetworkPlayerLocal, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex); } + if (gMarioState->health <= 0x110) { + gMarioState->health = 0x880; + } + smlua_call_event_hooks(HOOK_ON_WARP); } @@ -845,7 +849,8 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) { break; case WARP_OP_DEATH: - if (m->numLives <= 0) { + m->numLives--; + if (m->numLives <= -1) { sDelayedWarpOp = WARP_OP_GAME_OVER; } sDelayedWarpTimer = 48; @@ -863,7 +868,8 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) { case WARP_OP_WARP_FLOOR: sSourceWarpNodeId = WARP_NODE_WARP_FLOOR; if (area_get_warp_node(sSourceWarpNodeId) == NULL) { - if (m->numLives <= 0) { + m->numLives--; + if (m->numLives <= -1) { sDelayedWarpOp = WARP_OP_GAME_OVER; } else { sSourceWarpNodeId = WARP_NODE_DEATH; @@ -961,7 +967,7 @@ void initiate_delayed_warp(void) { switch (sDelayedWarpOp) { case WARP_OP_GAME_OVER: gChangeLevel = gLevelValues.entryLevel; - gMarioStates[0].numLives = 3; + gMarioStates[0].numLives = 4; gMarioStates[0].health = 0x880; break; @@ -1331,7 +1337,7 @@ void update_menu_level(void) { default: curLevel = LEVEL_CASTLE_GROUNDS; break; } - // warp to level + // warp to level, this feels buggy if (gCurrLevelNum != curLevel) { if (curLevel == LEVEL_JRB) { dynos_warp_to_level(curLevel, 1, 2); @@ -1342,135 +1348,108 @@ void update_menu_level(void) { } } - // set mario/camera pos - if (gCurrLevelNum == LEVEL_CASTLE_GROUNDS) { - if (!sFirstCastleGroundsMenu) { - gMarioState->pos[0] = -1328; - gMarioState->pos[1] = 260; - gMarioState->pos[2] = 4664; - gMarioState->faceAngle[1] = 0x0; - gLakituState.curPos[1] = 390; - gLakituState.curPos[0] = -1328; - gLakituState.curPos[2] = 6064; - } - } else if (gCurrLevelNum == LEVEL_BOB) { - gMarioState->pos[0] = 7008; - gMarioState->pos[1] = 864; - gMarioState->pos[2] = 1943; - gLakituState.curPos[1] = 1064; - gLakituState.curPos[2] = 2843; - gLakituState.curPos[0] = 7908; - gMarioState->faceAngle[1] = 0x2000; - - // delete all goombas as they interfere with the main menu - - struct Object *o; - - o = find_object_with_behavior(bhvGoomba); - - if (o != NULL) { - if (obj_has_behavior(o, bhvGoomba)) { - obj_mark_for_deletion(o); - } - } - - } else if (gCurrLevelNum == LEVEL_WF) { - gLakituState.curPos[1] = 2760; - gLakituState.curPos[2] = -777; - gLakituState.curPos[0] = -4504; - gMarioState->pos[1] = 2560; - gMarioState->pos[2] = -327; - gMarioState->pos[0] = -2904; - gMarioState->faceAngle[1] = -31072 / 2; - } else if (gCurrLevelNum == LEVEL_WMOTR) { - gLakituState.curPos[1] = -2438; - gLakituState.curPos[2] = 6063; - gLakituState.curPos[0] = 3548; - gMarioState->pos[1] = -2738; - gMarioState->pos[2] = 4663; - gMarioState->pos[0] = 3548; - gMarioState->faceAngle[1] = 0; - } else if (gCurrLevelNum == LEVEL_JRB) { - gLakituState.curPos[1] = 1736; - gLakituState.curPos[2] = 6402; - gLakituState.curPos[0] = 5039; - gMarioState->pos[1] = 1536; - gMarioState->pos[2] = 6202; - gMarioState->pos[0] = 3639; - } else if (gCurrLevelNum == LEVEL_SSL) { - gLakituState.curPos[1] = 356; - gLakituState.curPos[2] = 2461; - gLakituState.curPos[0] = -2048; - gMarioState->pos[1] = 256; - gMarioState->pos[2] = 961; - gMarioState->pos[0] = -2048; - gMarioState->faceAngle[1] = 0; - } else if (gCurrLevelNum == LEVEL_TTM) { - gLakituState.curPos[1] = 1763; - gLakituState.curPos[2] = 3411; - gLakituState.curPos[0] = 3488; - gMarioState->pos[1] = 1460; - gMarioState->pos[2] = 2011; - gMarioState->pos[0] = 2488; - gMarioState->faceAngle[1] = 0x1000; - } else if (gCurrLevelNum == LEVEL_SL) { - gLakituState.curPos[1] = 1124; - gLakituState.curPos[2] = 443; - gLakituState.curPos[0] = 6994; - gMarioState->pos[1] = 1024; - gMarioState->pos[2] = 443; - gMarioState->pos[0] = 5494; - gMarioState->faceAngle[1] = 0x4000; - } else if (gCurrLevelNum == LEVEL_BBH) { - gLakituState.curPos[1] = -204; - gLakituState.curPos[2] = 6803; - gLakituState.curPos[0] = 666; - gMarioState->pos[1] = -204; - gMarioState->pos[2] = 5303; - gMarioState->pos[0] = 666; - gMarioState->faceAngle[1] = 0; - } else if (gCurrLevelNum == LEVEL_LLL) { - gLakituState.curPos[1] = 938; - gLakituState.curPos[2] = 1576; - gLakituState.curPos[0] = -3576; - gMarioState->pos[1] = 638; - gMarioState->pos[2] = 956; - gMarioState->pos[0] = -2376; - gMarioState->faceAngle[1] = -0x2800; - } else if (gCurrLevelNum == LEVEL_THI) { - gLakituState.curPos[1] = 431; - gLakituState.curPos[2] = -324; - gLakituState.curPos[0] = -2246; - gMarioState->pos[1] = 341; - gMarioState->pos[2] = -324; - gMarioState->pos[0] = -1010; - gMarioState->faceAngle[1] = -0x4000; - - // delete all goombas as they interfere with the main menu - - struct Object *o; - - o = find_object_with_behavior(bhvGoomba); - - if (o != NULL) { - if (obj_has_behavior(o, bhvGoomba)) { - obj_mark_for_deletion(o); - } - } + // set sFirstCastleGroundsMenu to false to prevent wall hugging bug + if (curLevel != LEVEL_CASTLE_GROUNDS) { + sFirstCastleGroundsMenu = false; } + struct Object *o; + // set mario/camera pos + switch (gCurrLevelNum) { + case LEVEL_CASTLE_GROUNDS: + if (!sFirstCastleGroundsMenu) { + vec3f_set(gMarioState->pos, -1328, 260, 4664); + vec3f_set(gLakituState.curPos, -1328, 390, 6064); + gMarioState->faceAngle[1] = 0; + gLakituState.nextYaw = gMarioState->faceAngle[1] + 0x8000; + } + break; + case LEVEL_BOB: + vec3f_set(gMarioState->pos, 7008, 864, 1943); + vec3f_set(gLakituState.curPos, 7909, 1064, 2843); + gMarioState->faceAngle[1] = 0x2000; + + // delete all goombas as they interfere with the main menu + o = find_object_with_behavior(bhvGoomba); + if (o != NULL) { + obj_mark_for_deletion(o); + } + break; + case LEVEL_WF: + vec3f_set(gMarioState->pos, -2904, 2560, -327); + vec3f_set(gLakituState.curPos, -4504, 2760, -777); + gMarioState->faceAngle[1] = -15536; + break; + case LEVEL_WMOTR: + vec3f_set(gMarioState->pos, 3548, -2738, 4663); + vec3f_set(gLakituState.curPos, 3548, -2438, 6063); + gMarioState->faceAngle[1] = 0; + break; + case LEVEL_JRB: + vec3f_set(gMarioState->pos, 3639, 1536, 6202); + vec3f_set(gLakituState.curPos, 5039, 1736, 6402); + break; + case LEVEL_SSL: + vec3f_set(gMarioState->pos, -2048, 256, 961); + vec3f_set(gLakituState.curPos, -2048, 356, 2461); + gMarioState->faceAngle[1] = 0; + break; + case LEVEL_TTM: + vec3f_set(gMarioState->pos, 2488, 1460, 2011); + vec3f_set(gLakituState.curPos, 3488, 1763, 3411); + gMarioState->faceAngle[1] = 0x1000; + break; + case LEVEL_SL: + vec3f_set(gMarioState->pos, 5494, 1024, 443); + vec3f_set(gLakituState.curPos, 6994, 1124, 443); + gMarioState->faceAngle[1] = 0x4000; + break; + case LEVEL_BBH: + vec3f_set(gMarioState->pos, 666, -204, 5303); + vec3f_set(gLakituState.curPos, 666, -204, 6803); + gMarioState->faceAngle[1] = 0; + + // delete all scuttlebugs as they interfere with the main menu + o = find_object_with_behavior(bhvScuttlebug); + if (o != NULL) { + obj_mark_for_deletion(o); + } + break; + case LEVEL_LLL: + vec3f_set(gMarioState->pos, -2376, 638, 956); + vec3f_set(gLakituState.curPos, -3576, 938, 1576); + gMarioState->faceAngle[1] = -0x2800; + break; + case LEVEL_THI: + vec3f_set(gMarioState->pos, -1010, 341, -324); + vec3f_set(gLakituState.curPos, -2246, 431, -324); + gMarioState->faceAngle[1] = -0x4000; + + // delete all goombas as they interfere with the main menu + o = find_object_with_behavior(bhvGoomba); + if (o != NULL) { + obj_mark_for_deletion(o); + } + break; + } + + gMarioState->health = 0x880; // reset input gMarioState->input = 0; + gMarioState->controller->rawStickX = 0; + gMarioState->controller->rawStickY = 0; + gMarioState->controller->stickX = 0; + gMarioState->controller->stickY = 0; // figure out music - if (!configMenuSound) { + if (!configMenuSound || curLevel == LEVEL_CASTLE_GROUNDS) { reset_volume(); disable_background_sound(); set_background_music(0, 0x0021, 0); } else { reset_volume(); disable_background_sound(); - + if (get_current_background_music() == 0x0021) { if (curLevel == LEVEL_JRB) { dynos_warp_to_level(curLevel, 1, 2); @@ -1491,7 +1470,7 @@ s32 update_level(void) { } else { sFirstCastleGroundsMenu = false; } - + s32 changeLevel = 0; if (gChangeLevel != -1) { diff --git a/src/game/mario.c b/src/game/mario.c index 128d6f667..057c26226 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1542,12 +1542,11 @@ void update_mario_inputs(struct MarioState *m) { debug_print_speed_action_normal(m); - /* Moonjump cheat */ - while (Cheats.MoonJump == true && Cheats.EnableCheats == true && m->controller->buttonDown & L_TRIG ){ - m->vel[1] = 25; - break; // TODO: Unneeded break? + if (Cheats.enabled && Cheats.moonJump && m->controller->buttonDown & L_TRIG) { + set_mario_action(m, ACT_FREEFALL, 0); + m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800); + m->vel[1] = 30; } - /*End of moonjump cheat */ /* Developer stuff */ #ifdef DEVELOPMENT @@ -1874,7 +1873,7 @@ static void debug_update_mario_cap(u16 button, s32 flags, u16 capTimer, u16 capM } } -void func_sh_8025574C(void) { +void queue_particle_rumble(void) { if (gMarioState->particleFlags & PARTICLE_HORIZONTAL_STAR) { queue_rumble_data_mario(gMarioState, 5, 80); } else if (gMarioState->particleFlags & PARTICLE_VERTICAL_STAR) { @@ -1992,22 +1991,13 @@ s32 execute_mario_action(UNUSED struct Object *o) { } } - /** - * Cheat stuff - */ - if (Cheats.EnableCheats) { - if (Cheats.GodMode) - gMarioState->health = 0x880; + if (Cheats.enabled) { + if (Cheats.godMode) { gMarioState->health = 0x880; } - if (Cheats.InfiniteLives && gMarioState->numLives < 99) - gMarioState->numLives += 1; + if (Cheats.infiniteLives && gMarioState->numLives < 100) { gMarioState->numLives = 100; } - if (Cheats.SuperSpeed && gMarioState->controller->stickMag > 0.5f) - gMarioState->forwardVel += 100; + if (Cheats.superSpeed && gMarioState->controller->stickMag > 0.5f) { gMarioState->forwardVel += 100; } } - /** - * End of cheat stuff - */ if (gMarioState->action) { if (gMarioState->action != ACT_BUBBLED) { @@ -2122,7 +2112,7 @@ s32 execute_mario_action(UNUSED struct Object *o) { play_infinite_stairs_music(); gMarioState->marioObj->oInteractStatus = 0; - func_sh_8025574C(); + queue_particle_rumble(); return gMarioState->particleFlags; } @@ -2267,7 +2257,7 @@ static void init_mario_single_from_save_file(struct MarioState* m, u16 index) { m->numStars = save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1); m->numKeys = 0; - m->numLives = 3; + m->numLives = 4; m->health = 0x880; m->prevNumStarsForDialog = m->numStars; diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index bec7eacdf..98d61a630 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -22,6 +22,7 @@ #include "pc/configfile.h" #include "pc/network/network.h" #include "pc/lua/smlua.h" +#include "pc/cheats.h" void play_flip_sounds(struct MarioState *m, s16 frame1, s16 frame2, s16 frame3) { s32 animFrame = m->marioObj->header.gfx.animInfo.animFrame; @@ -68,6 +69,8 @@ s32 lava_boost_on_wall(struct MarioState *m) { } s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) { + if (Cheats.enabled && Cheats.godMode) { return FALSE; } + f32 fallHeight; f32 damageHeight; diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 9b0466ee6..f3c2d542c 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -1023,7 +1023,7 @@ s32 act_bubbled(struct MarioState* m) { // make invisible on -1 lives if (m->playerIndex == 0) { - if (m->numLives == -1) { + if (m->numLives <= -1) { m->marioObj->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE; level_trigger_warp(m, WARP_OP_DEATH); return set_mario_action(m, ACT_SOFT_BONK, 0); diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 874fc2186..a6a04ec8c 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -682,6 +682,7 @@ void general_star_dance_handler(struct MarioState *m, s32 isInWater) { struct MarioState* marioState = &gMarioStates[i]; if (!is_player_active(marioState)) { continue; } if (marioState->marioObj == NULL) { continue; } + if (marioState->playerIndex != m->playerIndex) { continue; } struct Object* celebStar = spawn_object(marioState->marioObj, MODEL_STAR, bhvCelebrationStar); if (m != marioState && celebStar != NULL) { celebStar->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE; @@ -1360,7 +1361,6 @@ s32 act_death_exit(struct MarioState *m) { play_character_sound(m, CHAR_SOUND_OOOF2); #endif queue_rumble_data_mario(m, 5, 80); - m->numLives--; // restore 7.75 units of health m->healCounter = 31; } @@ -1376,7 +1376,6 @@ s32 act_unused_death_exit(struct MarioState *m) { #else play_character_sound(m, CHAR_SOUND_OOOF2); #endif - m->numLives--; // restore 7.75 units of health m->healCounter = 31; } @@ -1393,7 +1392,6 @@ s32 act_falling_death_exit(struct MarioState *m) { play_character_sound(m, CHAR_SOUND_OOOF2); #endif queue_rumble_data_mario(m, 5, 80); - m->numLives--; // restore 7.75 units of health m->healCounter = 31; } @@ -1438,7 +1436,6 @@ s32 act_special_death_exit(struct MarioState *m) { if (launch_mario_until_land(m, ACT_HARD_BACKWARD_GROUND_KB, MARIO_ANIM_BACKWARD_AIR_KB, -24.0f)) { queue_rumble_data_mario(m, 5, 80); - m->numLives--; m->healCounter = 31; } // show Mario diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index 88154e00e..4a9831f7a 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -467,13 +467,11 @@ void update_walking_speed(struct MarioState *m) { m->forwardVel = 48.0f; } - /* Handles the "Super responsive controls" cheat. The content of the "else" is Mario's original code for turning around.*/ - - if (Cheats.Responsive == true && Cheats.EnableCheats == true ) { + // handles the "Super responsive controls" cheat. The content of the "else" is Mario's original code for turning around. + if (Cheats.enabled && Cheats.responsive) { m->faceAngle[1] = m->intendedYaw; - } - else { - m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800); + } else { + m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800); } apply_slope_accel(m); } diff --git a/src/game/mario_step.c b/src/game/mario_step.c index ba1507b1b..a1e1d921c 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -10,6 +10,7 @@ #include "mario_step.h" #include "pc/lua/smlua.h" #include "game/hardcoded.h" +#include "pc/cheats.h" static s16 sMovingSandSpeeds[] = { 12, 8, 4, 0 }; @@ -108,7 +109,7 @@ void mario_bonk_reflection(struct MarioState *m, u32 negateSpeed) { } u32 mario_update_quicksand(struct MarioState *m, f32 sinkingSpeed) { - if (m->action & ACT_FLAG_RIDING_SHELL) { + if (m->action & ACT_FLAG_RIDING_SHELL || (Cheats.enabled && Cheats.godMode)) { m->quicksandDepth = 0.0f; } else { if (m->quicksandDepth < 1.1f) { diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 2f86903a6..94bf3d770 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -1341,7 +1341,9 @@ void obj_mark_for_deletion(struct Object *obj) { // setting it to 0 could potentially enable unexpected behavior. After an // object is marked for deletion, it still updates on that frame (I think), // so this is worth looking into. - obj->activeFlags = ACTIVE_FLAG_DEACTIVATED; + if (obj != NULL) { + obj->activeFlags = ACTIVE_FLAG_DEACTIVATED; + } } void cur_obj_disable(void) { diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 5ce8d55c4..f3c1cfbb8 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -1119,6 +1119,8 @@ static void geo_process_shadow(struct GraphNodeShadow *node) { static s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) { if (node->node.flags & GRAPH_RENDER_INVISIBLE) { return FALSE; + } else if (node->skipInViewCheck) { + return TRUE; } // ! @bug The aspect ratio is not accounted for. When the fov value is 45, diff --git a/src/game/scroll_targets.c b/src/game/scroll_targets.c new file mode 100644 index 000000000..1e1c023a1 --- /dev/null +++ b/src/game/scroll_targets.c @@ -0,0 +1,27 @@ +#include "scroll_targets.h" + +Vtx *gScrollTargets[1024]; + +static int startIndex[128]; +static int lastIndex = 0; + +Vtx* *get_scroll_targets(u32 id) { + return &gScrollTargets[startIndex[id]]; +} + +void add_vtx_scroll_target(u32 id, Vtx *vtx, u32 size) { + if (startIndex[id] == -1) { + startIndex[id] = lastIndex; + } + + for (u32 i = 0; i < size; ++i) { + gScrollTargets[lastIndex++] = &vtx[i]; + } +} + +void init_vtx_scroll_targets(void) { + for (int i = 0; i < 128; ++i) { + startIndex[i] = -1; + } + lastIndex = 0; +} diff --git a/src/game/scroll_targets.h b/src/game/scroll_targets.h new file mode 100644 index 000000000..ede2b4e70 --- /dev/null +++ b/src/game/scroll_targets.h @@ -0,0 +1,19 @@ +/* + * All credit goes to https://github.com/jesusyoshi54 + * also known as scuttlebugraiser, the creator of RM2C + * Created for the project https://github.com/jesusyoshi54/sm64ex-alo for RM2C support + * https://github.com/jesusyoshi54/sm64ex-alo/blob/master/src/game/ScrollTargets.inc.c + */ + +#include +#include "sm64.h" +#include "types.h" + +//Q. Why does this exist instead of just directly referencing VBs? +//A. Because gcc is dumb and will seg fault if you reference a VB by abstracting it through a bparam +//instead of directly refencing it, causing this horrible shit. +extern Vtx *gScrollTargets[]; + +Vtx* *get_scroll_targets(u32 id); +void add_vtx_scroll_target(u32 id, Vtx *vtx, u32 size); +void init_vtx_scroll_targets(void); diff --git a/src/menu/star_select.c b/src/menu/star_select.c index 34bd1453f..5ffa4359a 100644 --- a/src/menu/star_select.c +++ b/src/menu/star_select.c @@ -402,7 +402,7 @@ void print_act_selector_strings(void) { if (playersInAct > 0) { char message[16] = { 0 }; if (playersInAct == 1) { - if (snprintf(message, 16, "join") < 0) { + if (snprintf(message, 16, " join ") < 0) { // do nothing } } else { diff --git a/src/pc/cheats.h b/src/pc/cheats.h index 531c392fa..0bf1ab429 100644 --- a/src/pc/cheats.h +++ b/src/pc/cheats.h @@ -4,12 +4,12 @@ #include struct CheatList { - bool EnableCheats; - bool MoonJump; - bool GodMode; - bool InfiniteLives; - bool SuperSpeed; - bool Responsive; + bool enabled; + bool moonJump; + bool godMode; + bool infiniteLives; + bool superSpeed; + bool responsive; }; extern struct CheatList Cheats; diff --git a/src/pc/cliopts.c b/src/pc/cliopts.c index 6f0766590..5b337fa71 100644 --- a/src/pc/cliopts.c +++ b/src/pc/cliopts.c @@ -67,7 +67,7 @@ void parse_cli_opts(int argc, char* argv[]) { arg_uint("--client ", argv[++i], &gCLIOpts.NetworkPort); } else if (strcmp(argv[i], "--cheats") == 0) // Enable cheats menu - Cheats.EnableCheats = true; + Cheats.enabled = true; else if (strcmp(argv[i], "--poolsize") == 0) // Main pool size arg_uint("--poolsize", argv[++i], &gCLIOpts.PoolSize); diff --git a/src/pc/controller/controller_emscripten_keyboard.c b/src/pc/controller/controller_emscripten_keyboard.c deleted file mode 100644 index cf78cf62f..000000000 --- a/src/pc/controller/controller_emscripten_keyboard.c +++ /dev/null @@ -1,151 +0,0 @@ -#ifdef TARGET_WEB - -#include -#include -#include "macros.h" -#include "controller_keyboard.h" - -static const struct { - const char *code; - int scancode; -} keymap_browser[] = { - {"Escape", 0x01}, - {"Digit1", 0x02 }, - {"Digit2", 0x03 }, - {"Digit3", 0x04 }, - {"Digit4", 0x05 }, - {"Digit5", 0x06 }, - {"Digit6", 0x07 }, - {"Digit7", 0x08 }, - {"Digit8", 0x09 }, - {"Digit9", 0x0a }, - {"Digit0", 0x0b }, - {"Minus", 0x0c }, - {"Equal", 0x0d }, - {"Backspace", 0x0e }, - {"Tab", 0x0f }, - {"KeyQ", 0x10 }, - {"KeyW", 0x11 }, - {"KeyE", 0x12 }, - {"KeyR", 0x13 }, - {"KeyT", 0x14 }, - {"KeyY", 0x15 }, - {"KeyU", 0x16 }, - {"KeyI", 0x17 }, - {"KeyO", 0x18 }, - {"KeyP", 0x19 }, - {"BracketLeft", 0x1a }, - {"BracketRight", 0x1b }, - {"Enter", 0x1c }, - {"ControlLeft", 0x1d }, - {"KeyA", 0x1e }, - {"KeyS", 0x1f }, - {"KeyD", 0x20 }, - {"KeyF", 0x21 }, - {"KeyG", 0x22 }, - {"KeyH", 0x23 }, - {"KeyJ", 0x24 }, - {"KeyK", 0x25 }, - {"KeyL", 0x26 }, - {"Semicolon", 0x27 }, - {"Quote", 0x28 }, - {"Backquote", 0x29 }, - {"ShiftLeft", 0x2a }, - {"Backslash", 0x2b }, - {"KeyZ", 0x2c }, - {"KeyX", 0x2d }, - {"KeyC", 0x2e }, - {"KeyV", 0x2f }, - {"KeyB", 0x30 }, - {"KeyN", 0x31 }, - {"KeyM", 0x32 }, - {"Comma", 0x33 }, - {"Period", 0x34 }, - {"Slash", 0x35 }, - {"ShiftRight", 0x36 }, - {"NumpadMultiply", 0x37 }, - {"AltLeft", 0x38 }, - {"Space", 0x39 }, - {"CapsLock", 0x3a }, - {"F1", 0x3b }, - {"F2", 0x3c }, - {"F3", 0x3d }, - {"F4", 0x3e }, - {"F5", 0x3f }, - {"F6", 0x40 }, - {"F7", 0x41 }, - {"F8", 0x42 }, - {"F9", 0x43 }, - {"F10", 0x44 }, - {"NumLock", 0x45 }, - {"ScrollLock", 0x46 }, - {"Numpad7", 0x47 }, - {"Numpad8", 0x48 }, - {"Numpad9", 0x49 }, - {"NumpadSubtract", 0x4a }, - {"Numpad4", 0x4b }, - {"Numpad5", 0x4c }, - {"Numpad6", 0x4d }, - {"NumpadAdd", 0x4e }, - {"Numpad1", 0x4f }, - {"Numpad2", 0x50 }, - {"Numpad3", 0x51 }, - {"Numpad0", 0x52 }, - {"NumpadDecimal", 0x53 }, - {"PrintScreen", 0x54 }, - // 0x55 - {"IntlBackslash", 0x56 }, - {"F11", 0x57 }, - {"F12", 0x58 }, - {"IntlRo", 0x59 }, - //{"Katakana", 0 }, - //{"Hiragana", 0 }, - {"NumpadEnter", 0x11c }, - {"ControlRight", 0x11d }, - {"NumpadDivide", 0x135 }, - {"AltRight", 0x138 }, - {"Home", 0x147 }, - {"ArrowUp", 0x148 }, - {"PageUp", 0x149 }, - {"ArrowLeft", 0x14b }, - {"ArrowRight", 0x14d }, - {"End", 0x14f }, - {"ArrowDown", 0x150 }, - {"PageDown", 0x151 }, - {"Insert", 0x152 }, - {"Delete", 0x153 }, - {"Pause", 0x21d }, - {"MetaLeft", 0x15b }, - {"MetaRight", 0x15c }, - {"ContextMenu", 0x15d }, -}; - -static EM_BOOL controller_emscripten_keyboard_handler(int event_type, const EmscriptenKeyboardEvent *key_event, UNUSED void *user_data) { - for (size_t i = 0; i < sizeof(keymap_browser) / sizeof(keymap_browser[0]); i++) { - if (strcmp(key_event->code, keymap_browser[i].code) == 0) { - if (event_type == EMSCRIPTEN_EVENT_KEYDOWN) { - return keyboard_on_key_down(keymap_browser[i].scancode); - } else if (event_type == EMSCRIPTEN_EVENT_KEYUP) { - return keyboard_on_key_up(keymap_browser[i].scancode); - } - break; - } - } - return EM_FALSE; -} - -static EM_BOOL controller_emscripten_keyboard_blur_handler(UNUSED int event_type, UNUSED const EmscriptenFocusEvent *focus_event, UNUSED void *user_data) { - keyboard_on_all_keys_up(); - return EM_TRUE; -} - -void controller_emscripten_keyboard_init(void) { - // Should be #window according to docs, but that crashes - const char *target = EMSCRIPTEN_EVENT_TARGET_WINDOW; - - emscripten_set_keydown_callback(target, NULL, EM_FALSE, controller_emscripten_keyboard_handler); - emscripten_set_keyup_callback(target, NULL, EM_FALSE, controller_emscripten_keyboard_handler); - emscripten_set_blur_callback(target, NULL, EM_FALSE, controller_emscripten_keyboard_blur_handler); -} - -#endif diff --git a/src/pc/controller/controller_emscripten_keyboard.h b/src/pc/controller/controller_emscripten_keyboard.h deleted file mode 100644 index 9b72873bc..000000000 --- a/src/pc/controller/controller_emscripten_keyboard.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef CONTROLLER_KEYBOARD_EMSCRIPTEN_H -#define CONTROLLER_KEYBOARD_EMSCRIPTEN_H - -#ifdef TARGET_WEB -void controller_emscripten_keyboard_init(void); -#endif - -#endif diff --git a/src/pc/controller/controller_keyboard.c b/src/pc/controller/controller_keyboard.c index 9923b5823..4a3665d41 100644 --- a/src/pc/controller/controller_keyboard.c +++ b/src/pc/controller/controller_keyboard.c @@ -5,10 +5,6 @@ #include "pc/configfile.h" #include "controller_api.h" -#ifdef TARGET_WEB -#include "controller_emscripten_keyboard.h" -#endif - #include "../configfile.h" #include "controller_keyboard.h" #include "controller_keyboard_debug.h" @@ -113,10 +109,6 @@ static void keyboard_bindkeys(void) { static void keyboard_init(void) { keyboard_bindkeys(); - -#ifdef TARGET_WEB - controller_emscripten_keyboard_init(); -#endif } static void keyboard_read(OSContPad *pad) { diff --git a/src/pc/controller/controller_keyboard.h b/src/pc/controller/controller_keyboard.h index b7edea01d..e297e0c70 100644 --- a/src/pc/controller/controller_keyboard.h +++ b/src/pc/controller/controller_keyboard.h @@ -9,14 +9,22 @@ #define SCANCODE_ESCAPE 1 #define SCANCODE_BACKSPACE 14 #define SCANCODE_ENTER 28 -#define SCANCODE_CONTROL_LEFT 29 +#ifdef __APPLE__ + #define SCANCODE_CONTROL_LEFT 91 +#else + #define SCANCODE_CONTROL_LEFT 29 +#endif #define SCANCODE_SHIFT_LEFT 42 #define SCANCODE_A 30 #define SCANCODE_X 45 #define SCANCODE_C 46 #define SCANCODE_V 47 #define SCANCODE_SHIFT_RIGHT 54 -#define SCANCODE_CONTROL_RIGHT 285 +#ifdef __APPLE__ + #define SCANCODE_CONTROL_RIGHT 92 +#else + #define SCANCODE_CONTROL_RIGHT 285 +#endif #define SCANCODE_HOME 327 #define SCANCODE_LEFT 331 #define SCANCODE_RIGHT 333 diff --git a/src/pc/controller/controller_sdl1.c b/src/pc/controller/controller_sdl1.c index bbc5a2774..aef341088 100644 --- a/src/pc/controller/controller_sdl1.c +++ b/src/pc/controller/controller_sdl1.c @@ -185,20 +185,6 @@ static void controller_sdl_read(OSContPad *pad) { int16_t ltrig = get_axis(JOY_AXIS_LTRIG); int16_t rtrig = get_axis(JOY_AXIS_RTRIG); -#ifdef TARGET_WEB - // Firefox has a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1606562 - // It sets down y to 32768.0f / 32767.0f, which is greater than the allowed 1.0f, - // which SDL then converts to a int16_t by multiplying by 32767.0f, which overflows into -32768. - // Maximum up will hence never become -32768 with the current version of SDL2, - // so this workaround should be safe in compliant browsers. - if (lefty == -32768) { - lefty = 32767; - } - if (righty == -32768) { - righty = 32767; - } -#endif - for (int i = 0; i < num_joy_buttons; ++i) { const bool new = SDL_JoystickGetButton(sdl_joy, i); update_button(i, new); diff --git a/src/pc/controller/controller_sdl2.c b/src/pc/controller/controller_sdl2.c index f7417c450..dbcd18524 100644 --- a/src/pc/controller/controller_sdl2.c +++ b/src/pc/controller/controller_sdl2.c @@ -246,20 +246,6 @@ static void controller_sdl_read(OSContPad *pad) { int16_t ltrig = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_TRIGGERLEFT); int16_t rtrig = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); -#ifdef TARGET_WEB - // Firefox has a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1606562 - // It sets down y to 32768.0f / 32767.0f, which is greater than the allowed 1.0f, - // which SDL then converts to a int16_t by multiplying by 32767.0f, which overflows into -32768. - // Maximum up will hence never become -32768 with the current version of SDL2, - // so this workaround should be safe in compliant browsers. - if (lefty == -32768) { - lefty = 32767; - } - if (righty == -32768) { - righty = 32767; - } -#endif - for (u32 i = 0; i < SDL_CONTROLLER_BUTTON_MAX; ++i) { const bool new = SDL_GameControllerGetButton(sdl_cntrl, i); update_button(i, new); diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c index 2f9916d82..f599d4db6 100644 --- a/src/pc/djui/djui_hud_utils.c +++ b/src/pc/djui/djui_hud_utils.c @@ -31,15 +31,25 @@ extern ALIGNED8 const u8 texture_hud_char_arrow_up[]; extern ALIGNED8 const u8 texture_hud_char_arrow_down[]; extern ALIGNED8 const u8 texture_hud_char_coin[]; extern ALIGNED8 const u8 texture_hud_char_star[]; +extern ALIGNED8 const u8 texture_hud_char_mario_head[]; +extern ALIGNED8 const u8 texture_hud_char_luigi_head[]; +extern ALIGNED8 const u8 texture_hud_char_toad_head[]; +extern ALIGNED8 const u8 texture_hud_char_waluigi_head[]; +extern ALIGNED8 const u8 texture_hud_char_wario_head[]; struct GlobalTextures gGlobalTextures = { - .camera = { .texture = (u8*)texture_hud_char_camera, .bitSize = 8, .width = 16, .height = 16 }, - .lakitu = { .texture = (u8*)texture_hud_char_lakitu, .bitSize = 8, .width = 16, .height = 16 }, - .no_camera = { .texture = (u8*)texture_hud_char_no_camera, .bitSize = 8, .width = 16, .height = 16 }, - .arrow_up = { .texture = (u8*)texture_hud_char_arrow_up, .bitSize = 8, .width = 8, .height = 8 }, - .arrow_down = { .texture = (u8*)texture_hud_char_arrow_down, .bitSize = 8, .width = 8, .height = 8 }, - .coin = { .texture = (u8*)texture_hud_char_coin, .bitSize = 8, .width = 16, .height = 16 }, - .star = { .texture = (u8*)texture_hud_char_star, .bitSize = 8, .width = 16, .height = 16 }, + .camera = { .texture = (u8*)texture_hud_char_camera, .bitSize = 8, .width = 16, .height = 16 }, + .lakitu = { .texture = (u8*)texture_hud_char_lakitu, .bitSize = 8, .width = 16, .height = 16 }, + .no_camera = { .texture = (u8*)texture_hud_char_no_camera, .bitSize = 8, .width = 16, .height = 16 }, + .arrow_up = { .texture = (u8*)texture_hud_char_arrow_up, .bitSize = 8, .width = 8, .height = 8 }, + .arrow_down = { .texture = (u8*)texture_hud_char_arrow_down, .bitSize = 8, .width = 8, .height = 8 }, + .coin = { .texture = (u8*)texture_hud_char_coin, .bitSize = 8, .width = 16, .height = 16 }, + .star = { .texture = (u8*)texture_hud_char_star, .bitSize = 8, .width = 16, .height = 16 }, + .mario_head = { .texture = (u8*)texture_hud_char_mario_head, .bitSize = 8, .width = 16, .height = 16 }, + .luigi_head = { .texture = (u8*)texture_hud_char_luigi_head, .bitSize = 8, .width = 16, .height = 16 }, + .toad_head = { .texture = (u8*)texture_hud_char_toad_head, .bitSize = 8, .width = 16, .height = 16 }, + .waluigi_head = { .texture = (u8*)texture_hud_char_waluigi_head, .bitSize = 8, .width = 16, .height = 16 }, + .wario_head = { .texture = (u8*)texture_hud_char_wario_head, .bitSize = 8, .width = 16, .height = 16 } }; static void djui_hud_position_translate(f32* x, f32* y) { diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h index 70a547556..a6487777b 100644 --- a/src/pc/djui/djui_hud_utils.h +++ b/src/pc/djui/djui_hud_utils.h @@ -22,6 +22,11 @@ struct GlobalTextures { struct TextureInfo arrow_down; struct TextureInfo coin; struct TextureInfo star; + struct TextureInfo mario_head; + struct TextureInfo luigi_head; + struct TextureInfo toad_head; + struct TextureInfo waluigi_head; + struct TextureInfo wario_head; }; extern struct GlobalTextures gGlobalTextures; diff --git a/src/pc/djui/djui_panel_cheats.c b/src/pc/djui/djui_panel_cheats.c index ee4b2de4a..3d3d0c8d7 100644 --- a/src/pc/djui/djui_panel_cheats.c +++ b/src/pc/djui/djui_panel_cheats.c @@ -10,28 +10,28 @@ void djui_panel_cheats_create(struct DjuiBase* caller) { { { - struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Moon jump", &Cheats.MoonJump); + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Moon jump", &Cheats.moonJump); djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox->base, 1.0f, 32); defaultBase = &checkbox->base; } { - struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "God mode", &Cheats.GodMode); + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "God mode", &Cheats.godMode); djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox->base, 1.0f, 32); } { - struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Infinite lives", &Cheats.InfiniteLives); + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Infinite lives", &Cheats.infiniteLives); djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox->base, 1.0f, 32); } { - struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Super speed", &Cheats.SuperSpeed); + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Super speed", &Cheats.superSpeed); djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox->base, 1.0f, 32); } { - struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Responsive controls", &Cheats.Responsive); + struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, "Responsive controls", &Cheats.responsive); djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox->base, 1.0f, 32); } diff --git a/src/pc/djui/djui_panel_join_message.c b/src/pc/djui/djui_panel_join_message.c index b42a00f54..8436f26e6 100644 --- a/src/pc/djui/djui_panel_join_message.c +++ b/src/pc/djui/djui_panel_join_message.c @@ -16,7 +16,7 @@ void djui_panel_join_message_error(char* message) { } void djui_panel_join_message_cancel(struct DjuiBase* caller) { - network_shutdown(true, false); + network_shutdown(true, false, false); djui_panel_menu_back(caller); } diff --git a/src/pc/djui/djui_panel_pause.c b/src/pc/djui/djui_panel_pause.c index 43b7dfbca..8ae54680d 100644 --- a/src/pc/djui/djui_panel_pause.c +++ b/src/pc/djui/djui_panel_pause.c @@ -1,7 +1,10 @@ #include "djui.h" #include "pc/cheats.h" -#include "src/pc/pc_main.h" -#include "src/pc/network/network.h" +#include "pc/pc_main.h" +#include "pc/network/network.h" +#include "game/object_helpers.h" +#include "behavior_table.h" +#include "sm64.h" bool gDjuiPanelPauseCreated = false; @@ -10,10 +13,12 @@ static void djui_panel_pause_resume(UNUSED struct DjuiBase* caller) { } static void djui_panel_pause_quit_yes(UNUSED struct DjuiBase* caller) { - network_shutdown(true, false); + network_shutdown(true, false, false); } static void djui_panel_pause_quit(struct DjuiBase* caller) { + if (find_object_with_behavior(bhvActSelector) != NULL || gMarioStates[0].action == ACT_PUSHING_DOOR || gMarioStates[0].action == ACT_PULLING_DOOR) { return; } + if (gNetworkType == NT_SERVER) { djui_panel_confirm_create(caller, "\\#ff0800\\Q\\#1be700\\U\\#00b3ff\\I\\#ffef00\\T", @@ -31,7 +36,7 @@ void djui_panel_pause_create(struct DjuiBase* caller) { if (gDjuiChatBoxFocus) { djui_chat_box_toggle(); } f32 bodyHeight = 64 * 5 + 16 * 4; - if (Cheats.EnableCheats) { bodyHeight += 64 + 16; } + if (Cheats.enabled) { bodyHeight += 64 + 16; } struct DjuiBase* defaultBase = NULL; struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\P\\#1be700\\A\\#00b3ff\\U\\#ffef00\\S\\#ff0800\\E"); @@ -61,7 +66,7 @@ void djui_panel_pause_create(struct DjuiBase* caller) { djui_interactable_hook_click(&button1->base, djui_panel_options_create); defaultBase = &button1->base; - if (Cheats.EnableCheats) { + if (Cheats.enabled) { struct DjuiButton* button1 = djui_button_create(&body->base, "Cheats"); djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button1->base, 1.0f, 64); diff --git a/src/pc/djui/djui_panel_player.c b/src/pc/djui/djui_panel_player.c index 0d279b1f8..b0c17fa12 100644 --- a/src/pc/djui/djui_panel_player.c +++ b/src/pc/djui/djui_panel_player.c @@ -72,8 +72,8 @@ static void djui_panel_player_edit_palette_hex_code_changed(struct DjuiBase* cal } for (int i = 0; i < 3; i++) { - configPlayerPalette.parts[sCurrentPlayerPart][i] = (char_to_hex_digit(input->buffer[2*i]) << 4) | - char_to_hex_digit(input->buffer[2*i] + 1); + configPlayerPalette.parts[sCurrentPlayerPart][i] = (char_to_hex_digit(input->buffer[2 * i]) << 4) | + char_to_hex_digit(input->buffer[2 * i + 1]); } djui_panel_player_edit_palette_update_sliders(); diff --git a/src/pc/gfx/gfx_sdl1.c b/src/pc/gfx/gfx_sdl1.c index 23cd3f120..ef9f2ae0b 100644 --- a/src/pc/gfx/gfx_sdl1.c +++ b/src/pc/gfx/gfx_sdl1.c @@ -135,8 +135,6 @@ static void gfx_sdl_handle_events(void) { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { -#ifndef TARGET_WEB - // Scancodes are broken in Emscripten SDL2: https://bugzilla.libsdl.org/show_bug.cgi?id=3259 case SDL_KEYDOWN: gfx_sdl_onkeydown(event.key.keysym.sym); // ALT+F4 in case the OS doesn't do it (SDL1 doesn't seem to do it on my machine) @@ -146,7 +144,6 @@ static void gfx_sdl_handle_events(void) { case SDL_KEYUP: gfx_sdl_onkeyup(event.key.keysym.sym); break; -#endif case SDL_VIDEORESIZE: window_w = configWindow.w = event.resize.w; window_h = configWindow.h = event.resize.h; diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index e63c755af..42eaa64a4 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -167,8 +167,6 @@ static void gfx_sdl_handle_events(void) { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { -#ifndef TARGET_WEB - // Scancodes are broken in Emscripten SDL2: https://bugzilla.libsdl.org/show_bug.cgi?id=3259 case SDL_TEXTINPUT: kb_text_input(event.text.text); break; @@ -178,8 +176,7 @@ static void gfx_sdl_handle_events(void) { case SDL_KEYUP: gfx_sdl_onkeyup(event.key.keysym.scancode); break; -#endif - case SDL_WINDOWEVENT: // TODO: Check if this makes sense to be included in the Web build + case SDL_WINDOWEVENT: if (!IS_FULLSCREEN()) { switch (event.window.event) { case SDL_WINDOWEVENT_MOVED: diff --git a/src/pc/lua/smlua_cobject.c b/src/pc/lua/smlua_cobject.c index 973985fc2..52db23458 100644 --- a/src/pc/lua/smlua_cobject.c +++ b/src/pc/lua/smlua_cobject.c @@ -4,6 +4,7 @@ #include "game/area.h" #include "game/mario.h" #include "game/hardcoded.h" +#include "game/scroll_targets.h" #include "audio/external.h" #include "object_fields.h" #include "pc/djui/djui_hud_utils.h" @@ -590,7 +591,6 @@ void smlua_cobject_init_globals(void) { smlua_push_object(L, LOT_BEHAVIORVALUES, &gBehaviorValues); lua_setglobal(L, "gBehaviorValues"); } - } void smlua_cobject_init_per_file_globals(char* path) { diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index cd44cc1fa..2e5161373 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -604,15 +604,20 @@ static struct LuaObjectField sGlobalObjectCollisionDataFields[LUA_GLOBAL_OBJECT_ { "wooden_signpost_seg3_collision_0302DD80", LVT_COLLISION_P, offsetof(struct GlobalObjectCollisionData, wooden_signpost_seg3_collision_0302DD80), false, LOT_POINTER }, }; -#define LUA_GLOBAL_TEXTURES_FIELD_COUNT 7 +#define LUA_GLOBAL_TEXTURES_FIELD_COUNT 12 static struct LuaObjectField sGlobalTexturesFields[LUA_GLOBAL_TEXTURES_FIELD_COUNT] = { - { "arrow_down", LVT_COBJECT, offsetof(struct GlobalTextures, arrow_down), true, LOT_TEXTUREINFO }, - { "arrow_up", LVT_COBJECT, offsetof(struct GlobalTextures, arrow_up), true, LOT_TEXTUREINFO }, - { "camera", LVT_COBJECT, offsetof(struct GlobalTextures, camera), true, LOT_TEXTUREINFO }, - { "coin", LVT_COBJECT, offsetof(struct GlobalTextures, coin), true, LOT_TEXTUREINFO }, - { "lakitu", LVT_COBJECT, offsetof(struct GlobalTextures, lakitu), true, LOT_TEXTUREINFO }, - { "no_camera", LVT_COBJECT, offsetof(struct GlobalTextures, no_camera), true, LOT_TEXTUREINFO }, - { "star", LVT_COBJECT, offsetof(struct GlobalTextures, star), true, LOT_TEXTUREINFO }, + { "arrow_down", LVT_COBJECT, offsetof(struct GlobalTextures, arrow_down), true, LOT_TEXTUREINFO }, + { "arrow_up", LVT_COBJECT, offsetof(struct GlobalTextures, arrow_up), true, LOT_TEXTUREINFO }, + { "camera", LVT_COBJECT, offsetof(struct GlobalTextures, camera), true, LOT_TEXTUREINFO }, + { "coin", LVT_COBJECT, offsetof(struct GlobalTextures, coin), true, LOT_TEXTUREINFO }, + { "lakitu", LVT_COBJECT, offsetof(struct GlobalTextures, lakitu), true, LOT_TEXTUREINFO }, + { "luigi_head", LVT_COBJECT, offsetof(struct GlobalTextures, luigi_head), true, LOT_TEXTUREINFO }, + { "mario_head", LVT_COBJECT, offsetof(struct GlobalTextures, mario_head), true, LOT_TEXTUREINFO }, + { "no_camera", LVT_COBJECT, offsetof(struct GlobalTextures, no_camera), true, LOT_TEXTUREINFO }, + { "star", LVT_COBJECT, offsetof(struct GlobalTextures, star), true, LOT_TEXTUREINFO }, + { "toad_head", LVT_COBJECT, offsetof(struct GlobalTextures, toad_head), true, LOT_TEXTUREINFO }, + { "waluigi_head", LVT_COBJECT, offsetof(struct GlobalTextures, waluigi_head), true, LOT_TEXTUREINFO }, + { "wario_head", LVT_COBJECT, offsetof(struct GlobalTextures, wario_head), true, LOT_TEXTUREINFO }, }; #define LUA_GRAPH_NODE_FIELD_COUNT 7 @@ -627,7 +632,7 @@ static struct LuaObjectField sGraphNodeFields[LUA_GRAPH_NODE_FIELD_COUNT] = { { "type", LVT_S16, offsetof(struct GraphNode, type), false, LOT_NONE }, }; -#define LUA_GRAPH_NODE_OBJECT_FIELD_COUNT 19 +#define LUA_GRAPH_NODE_OBJECT_FIELD_COUNT 20 static struct LuaObjectField sGraphNodeObjectFields[LUA_GRAPH_NODE_OBJECT_FIELD_COUNT] = { { "activeAreaIndex", LVT_S8, offsetof(struct GraphNodeObject, activeAreaIndex), false, LOT_NONE }, { "angle", LVT_COBJECT, offsetof(struct GraphNodeObject, angle), true, LOT_VEC3S }, @@ -647,6 +652,7 @@ static struct LuaObjectField sGraphNodeObjectFields[LUA_GRAPH_NODE_OBJECT_FIELD_ { "prevTimestamp", LVT_U32, offsetof(struct GraphNodeObject, prevTimestamp), false, LOT_NONE }, { "scale", LVT_COBJECT, offsetof(struct GraphNodeObject, scale), true, LOT_VEC3F }, { "sharedChild", LVT_COBJECT_P, offsetof(struct GraphNodeObject, sharedChild), false, LOT_GRAPHNODE }, + { "skipInViewCheck", LVT_BOOL, offsetof(struct GraphNodeObject, skipInViewCheck), false, LOT_NONE }, { "skipInterpolationTimestamp", LVT_U32, offsetof(struct GraphNodeObject, skipInterpolationTimestamp), false, LOT_NONE }, // { "throwMatrix", LVT_???, offsetof(struct GraphNodeObject, throwMatrix), false, LOT_??? }, <--- UNIMPLEMENTED // { "throwMatrixPrev", LVT_???, offsetof(struct GraphNodeObject, throwMatrixPrev), false, LOT_??? }, <--- UNIMPLEMENTED diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index b69f843e0..edc3c4fd4 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -855,7 +855,9 @@ char gSmluaConstants[] = "" "id_bhvYellowBall = 532\n" "id_bhvYellowCoin = 533\n" "id_bhvYoshi = 534\n" -"id_bhv_max_count = 535\n" +"id_RM_Scroll_Texture = 535\n" +"id_editor_Scroll_Texture = 536\n" +"id_bhv_max_count = 537\n" "CAM_MODE_MARIO_ACTIVE = 0x01\n" "CAM_MODE_LAKITU_WAS_ZOOMED_OUT = 0x02\n" "CAM_MODE_MARIO_SELECTED = 0x04\n" diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index e98743531..7c4071fa8 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -5348,6 +5348,15 @@ int smlua_func_update_angle_from_move_flags(lua_State* L) { return 1; } +int smlua_func_uv_update_scroll(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + uv_update_scroll(); + + return 1; +} + int smlua_func_vec3f_copy_2(lua_State* L) { if(!smlua_functions_valid_param_count(L, 2)) { return 0; } @@ -6450,6 +6459,17 @@ int smlua_func_resolve_geometry_collisions(lua_State* L) { return 1; } +int smlua_func_rom_hack_cam_set_collisions(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 1)) { return 0; } + + u8 enable = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1 for function 'rom_hack_cam_set_collisions'"); return 0; } + + rom_hack_cam_set_collisions(enable); + + return 1; +} + int smlua_func_rotate_camera_around_walls(lua_State* L) { if(!smlua_functions_valid_param_count(L, 4)) { return 0; } @@ -7678,6 +7698,66 @@ int smlua_func_seq_player_unlower_volume(lua_State* L) { return 1; } +int smlua_func_stop_background_music(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 1)) { return 0; } + + u16 seqId = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1 for function 'stop_background_music'"); return 0; } + + stop_background_music(seqId); + + return 1; +} + +int smlua_func_stop_sound(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 2)) { return 0; } + + u32 soundBits = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1 for function 'stop_sound'"); return 0; } + + f32* pos = smlua_get_vec3f_from_buffer(); + pos[0] = smlua_get_number_field(2, "x"); + pos[1] = smlua_get_number_field(2, "y"); + pos[2] = smlua_get_number_field(2, "z"); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2 for function 'stop_sound'"); return 0; } + + stop_sound(soundBits, pos); + + smlua_push_number_field(2, "x", pos[0]); + smlua_push_number_field(2, "y", pos[1]); + smlua_push_number_field(2, "z", pos[2]); + + return 1; +} + +int smlua_func_stop_sounds_from_source(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 1)) { return 0; } + + + f32* pos = smlua_get_vec3f_from_buffer(); + pos[0] = smlua_get_number_field(1, "x"); + pos[1] = smlua_get_number_field(1, "y"); + pos[2] = smlua_get_number_field(1, "z"); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1 for function 'stop_sounds_from_source'"); return 0; } + + stop_sounds_from_source(pos); + + smlua_push_number_field(1, "x", pos[0]); + smlua_push_number_field(1, "y", pos[1]); + smlua_push_number_field(1, "z", pos[2]); + + return 1; +} + +int smlua_func_stop_sounds_in_continuous_banks(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + stop_sounds_in_continuous_banks(); + + return 1; +} + /////////////////// // interaction.h // /////////////////// @@ -16564,10 +16644,36 @@ int smlua_func_warp_to_level(lua_State* L) { return 1; } +int smlua_func_warp_to_start_level(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + lua_pushboolean(L, warp_to_start_level()); + + return 1; +} + //////////////////////// // smlua_misc_utils.h // //////////////////////// +int smlua_func_add_scroll_target(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 4)) { return 0; } + + u32 index = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1 for function 'add_scroll_target'"); return 0; } + const char* name = smlua_to_string(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2 for function 'add_scroll_target'"); return 0; } + u32 offset = smlua_to_integer(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3 for function 'add_scroll_target'"); return 0; } + u32 size = smlua_to_integer(L, 4); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4 for function 'add_scroll_target'"); return 0; } + + add_scroll_target(index, name, offset, size); + + return 1; +} + int smlua_func_allocate_mario_action(lua_State* L) { if(!smlua_functions_valid_param_count(L, 1)) { return 0; } @@ -16817,6 +16923,15 @@ int smlua_func_get_current_save_file_num(UNUSED lua_State* L) { return 1; } +int smlua_func_get_dialog_id(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + lua_pushinteger(L, get_dialog_id()); + + return 1; +} + int smlua_func_get_environment_region(lua_State* L) { if(!smlua_functions_valid_param_count(L, 1)) { return 0; } @@ -16948,6 +17063,15 @@ int smlua_func_hud_show(UNUSED lua_State* L) { return 1; } +int smlua_func_init_scroll_targets(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + init_scroll_targets(); + + return 1; +} + int smlua_func_is_game_paused(UNUSED lua_State* L) { if(!smlua_functions_valid_param_count(L, 0)) { return 0; } @@ -16957,6 +17081,15 @@ int smlua_func_is_game_paused(UNUSED lua_State* L) { return 1; } +int smlua_func_is_transition_playing(UNUSED lua_State* L) { + if(!smlua_functions_valid_param_count(L, 0)) { return 0; } + + + lua_pushboolean(L, is_transition_playing()); + + return 1; +} + int smlua_func_movtexqc_register(lua_State* L) { if(!smlua_functions_valid_param_count(L, 4)) { return 0; } @@ -18534,6 +18667,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "spawn_wind_particles", smlua_func_spawn_wind_particles); smlua_bind_function(L, "tox_box_move", smlua_func_tox_box_move); smlua_bind_function(L, "update_angle_from_move_flags", smlua_func_update_angle_from_move_flags); + smlua_bind_function(L, "uv_update_scroll", smlua_func_uv_update_scroll); smlua_bind_function(L, "vec3f_copy_2", smlua_func_vec3f_copy_2); // behavior_table.h @@ -18598,6 +18732,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "random_vec3s", smlua_func_random_vec3s); smlua_bind_function(L, "reset_camera", smlua_func_reset_camera); smlua_bind_function(L, "resolve_geometry_collisions", smlua_func_resolve_geometry_collisions); + smlua_bind_function(L, "rom_hack_cam_set_collisions", smlua_func_rom_hack_cam_set_collisions); smlua_bind_function(L, "rotate_camera_around_walls", smlua_func_rotate_camera_around_walls); smlua_bind_function(L, "rotate_in_xz", smlua_func_rotate_in_xz); smlua_bind_function(L, "rotate_in_yz", smlua_func_rotate_in_yz); @@ -18688,6 +18823,10 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "seq_player_fade_out", smlua_func_seq_player_fade_out); smlua_bind_function(L, "seq_player_lower_volume", smlua_func_seq_player_lower_volume); smlua_bind_function(L, "seq_player_unlower_volume", smlua_func_seq_player_unlower_volume); + smlua_bind_function(L, "stop_background_music", smlua_func_stop_background_music); + smlua_bind_function(L, "stop_sound", smlua_func_stop_sound); + smlua_bind_function(L, "stop_sounds_from_source", smlua_func_stop_sounds_from_source); + smlua_bind_function(L, "stop_sounds_in_continuous_banks", smlua_func_stop_sounds_in_continuous_banks); // interaction.h smlua_bind_function(L, "does_mario_have_normal_cap_on_head", smlua_func_does_mario_have_normal_cap_on_head); @@ -19341,8 +19480,10 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "warp_restart_level", smlua_func_warp_restart_level); smlua_bind_function(L, "warp_to_castle", smlua_func_warp_to_castle); smlua_bind_function(L, "warp_to_level", smlua_func_warp_to_level); + smlua_bind_function(L, "warp_to_start_level", smlua_func_warp_to_start_level); // smlua_misc_utils.h + smlua_bind_function(L, "add_scroll_target", smlua_func_add_scroll_target); smlua_bind_function(L, "allocate_mario_action", smlua_func_allocate_mario_action); smlua_bind_function(L, "camera_config_enable_analog_cam", smlua_func_camera_config_enable_analog_cam); smlua_bind_function(L, "camera_config_enable_free_cam", smlua_func_camera_config_enable_free_cam); @@ -19368,6 +19509,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "camera_unfreeze", smlua_func_camera_unfreeze); smlua_bind_function(L, "deref_s32_pointer", smlua_func_deref_s32_pointer); smlua_bind_function(L, "get_current_save_file_num", smlua_func_get_current_save_file_num); + smlua_bind_function(L, "get_dialog_id", smlua_func_get_dialog_id); smlua_bind_function(L, "get_environment_region", smlua_func_get_environment_region); smlua_bind_function(L, "get_hand_foot_pos_x", smlua_func_get_hand_foot_pos_x); smlua_bind_function(L, "get_hand_foot_pos_y", smlua_func_get_hand_foot_pos_y); @@ -19379,7 +19521,9 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "hud_render_power_meter", smlua_func_hud_render_power_meter); smlua_bind_function(L, "hud_set_value", smlua_func_hud_set_value); smlua_bind_function(L, "hud_show", smlua_func_hud_show); + smlua_bind_function(L, "init_scroll_targets", smlua_func_init_scroll_targets); smlua_bind_function(L, "is_game_paused", smlua_func_is_game_paused); + smlua_bind_function(L, "is_transition_playing", smlua_func_is_transition_playing); smlua_bind_function(L, "movtexqc_register", smlua_func_movtexqc_register); smlua_bind_function(L, "play_transition", smlua_func_play_transition); smlua_bind_function(L, "save_file_set_using_backup_slot", smlua_func_save_file_set_using_backup_slot); diff --git a/src/pc/lua/utils/smlua_level_utils.c b/src/pc/lua/utils/smlua_level_utils.c index 5310cd8ed..dae54ea87 100644 --- a/src/pc/lua/utils/smlua_level_utils.c +++ b/src/pc/lua/utils/smlua_level_utils.c @@ -130,6 +130,10 @@ bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct) { return dynos_warp_to_level(aLevel, aArea, aAct); } +bool warp_to_start_level(void) { + return dynos_warp_to_start_level(); +} + bool warp_restart_level(void) { return dynos_warp_restart_level(); } diff --git a/src/pc/lua/utils/smlua_level_utils.h b/src/pc/lua/utils/smlua_level_utils.h index c151b3c25..473e2043a 100644 --- a/src/pc/lua/utils/smlua_level_utils.h +++ b/src/pc/lua/utils/smlua_level_utils.h @@ -23,6 +23,7 @@ struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(char* shortNam s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3); bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct); bool warp_restart_level(void); +bool warp_to_start_level(void); bool warp_exit_level(s32 aDelay); bool warp_to_castle(s32 aLevel); diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c index ed6d45cd9..5097140c0 100644 --- a/src/pc/lua/utils/smlua_misc_utils.c +++ b/src/pc/lua/utils/smlua_misc_utils.c @@ -95,6 +95,7 @@ void hud_render_power_meter(s32 health, f32 x, f32 y, f32 width, f32 height) { { (u8*)texture_power_meter_seven_segments, 8, 32, 32 }, { (u8*)texture_power_meter_full, 8, 32, 32 }, }; + djui_hud_set_color(255, 255, 255, 255); djui_hud_render_texture(&sPowerMeterTexturesInfo[0], x, y, width / 64, height / 64); djui_hud_render_texture(&sPowerMeterTexturesInfo[1], x + width / 2, y, width / 64, height / 64); s32 numWedges = MIN(MAX(health >> 8, 0), 8); @@ -272,6 +273,12 @@ bool is_game_paused(void) { /// +bool is_transition_playing(void) { + return sTransitionUpdate != NULL || gWarpTransition.isActive; +} + +/// + u32 allocate_mario_action(u32 actFlags) { actFlags = actFlags & (~((u32)0x3F)); return actFlags | ACT_FLAG_CUSTOM_ACTION | gLuaMarioActionIndex++; @@ -312,6 +319,8 @@ void movtexqc_register(const char* name, s16 level, s16 area, s16 type) { dynos_movtexqc_register(name, level, area, type); } +/// + f32 get_environment_region(u8 index) { if (gEnvironmentRegions != NULL && index <= gEnvironmentRegions[0]) { return gEnvironmentRegions[6 * (int)index]; @@ -319,20 +328,38 @@ f32 get_environment_region(u8 index) { return -11000; } +/// + void set_environment_region(u8 index, s32 value) { if (gEnvironmentRegions != NULL && index <= gEnvironmentRegions[0]) { gEnvironmentRegions[6 * (int)index] = value; } } +/// + void set_override_fov(f32 fov) { gOverrideFOV = fov; } +/// + void set_override_near(f32 near) { gOverrideNear = near; } +/// + void set_override_far(f32 far) { gOverrideFar = far; } + +/// + +void add_scroll_target(u32 index, const char* name, u32 offset, u32 size) { + dynos_add_scroll_target(index, name, offset, size); +} + +void init_scroll_targets(void) { + dynos_init_scroll_targets(); +} diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h index 3ed03f755..e29929bd1 100644 --- a/src/pc/lua/utils/smlua_misc_utils.h +++ b/src/pc/lua/utils/smlua_misc_utils.h @@ -62,6 +62,9 @@ void camera_config_set_pan_level(u32 value); void camera_config_set_deceleration(u32 value); bool is_game_paused(void); +bool is_transition_playing(void); + +s16 get_dialog_id(void); u32 allocate_mario_action(u32 actFlags); @@ -80,6 +83,9 @@ void set_override_fov(f32 fov); void set_override_near(f32 near); void set_override_far(f32 far); +void add_scroll_target(u32 index, const char* name, u32 offset, u32 size); +void init_scroll_targets(void); + void play_transition(s16 transType, s16 time, u8 red, u8 green, u8 blue); #endif diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 4cdaad715..2ab06e819 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -101,7 +101,7 @@ bool network_init(enum NetworkType inNetworkType) { #else gServerSettings.headlessServer = 0; #endif - Cheats.EnableCheats = gServerSettings.enableCheats; + Cheats.enabled = gServerSettings.enableCheats; // initialize the network system gNetworkSentJoin = false; @@ -483,7 +483,7 @@ void network_register_mod(char* modName) { string_linked_list_append(&gRegisteredMods, modName); } -void network_shutdown(bool sendLeaving, bool exiting) { +void network_shutdown(bool sendLeaving, bool exiting, bool popup) { if (gDjuiChatBox != NULL) { djui_base_destroy(&gDjuiChatBox->base); gDjuiChatBox = NULL; @@ -496,7 +496,7 @@ void network_shutdown(bool sendLeaving, bool exiting) { if (gNetworkSystem == NULL) { LOG_ERROR("no network system attached"); return; } if (gNetworkPlayerLocal != NULL && sendLeaving) { network_send_leaving(gNetworkPlayerLocal->globalIndex); } - network_player_shutdown(); + network_player_shutdown(popup); gNetworkSystem->shutdown(); if (gNetworkServerAddr != NULL) { diff --git a/src/pc/network/network.h b/src/pc/network/network.h index b6a5aab9a..8bf1e69ea 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -99,6 +99,6 @@ void network_receive(u8 localIndex, void* addr, u8* data, u16 dataLength); void* network_duplicate_address(u8 localIndex); void network_update(void); void network_register_mod(char* modName); -void network_shutdown(bool sendLeaving, bool exiting); +void network_shutdown(bool sendLeaving, bool exiting, bool popup); #endif diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c index 450190af6..772361729 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -158,7 +158,7 @@ void network_player_update(void) { #ifndef DEVELOPMENT if (elapsed > NETWORK_PLAYER_TIMEOUT * 1.5f) { LOG_INFO("dropping due to no server connectivity"); - network_shutdown(false, false); + network_shutdown(false, false, true); } #endif @@ -284,7 +284,7 @@ u8 network_player_disconnected(u8 globalIndex) { LOG_ERROR("player disconnected, but it's local.. this shouldn't happen!"); return UNKNOWN_GLOBAL_INDEX; } else { - network_shutdown(true, false); + network_shutdown(true, false, true); } } @@ -402,7 +402,7 @@ void network_player_update_course_level(struct NetworkPlayer* np, s16 courseNum, } } -void network_player_shutdown(void) { +void network_player_shutdown(bool popup) { gNetworkPlayerLocal = NULL; gNetworkPlayerServer = NULL; for (s32 i = 0; i < MAX_PLAYERS; i++) { @@ -412,6 +412,6 @@ void network_player_shutdown(void) { gNetworkSystem->clear_id(i); } - djui_popup_create("\\#ffa0a0\\Error:\\#dcdcdc\\ network shutdown", 1); + if (popup) { djui_popup_create("\\#ffa0a0\\Disconnected:\\#dcdcdc\\ server closed", 1); } LOG_INFO("cleared all network players"); } diff --git a/src/pc/network/network_player.h b/src/pc/network/network_player.h index cb444c008..1e4b05cec 100644 --- a/src/pc/network/network_player.h +++ b/src/pc/network/network_player.h @@ -79,6 +79,6 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode u8 network_player_disconnected(u8 globalIndex); void network_player_update_course_level(struct NetworkPlayer* np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex); -void network_player_shutdown(void); +void network_player_shutdown(bool popup); #endif diff --git a/src/pc/network/packets/packet_join.c b/src/pc/network/packets/packet_join.c index 413a9635c..6c896d2e5 100644 --- a/src/pc/network/packets/packet_join.c +++ b/src/pc/network/packets/packet_join.c @@ -153,7 +153,7 @@ void network_receive_join(struct Packet* p) { packet_read(p, &remoteVersion, sizeof(u8) * MAX_VERSION_LENGTH); LOG_INFO("server has version: %s", version); if (memcmp(version, remoteVersion, MAX_VERSION_LENGTH) != 0) { - network_shutdown(true, false); + network_shutdown(true, false, false); LOG_ERROR("version mismatch"); char mismatchMessage[256] = { 0 }; snprintf(mismatchMessage, 256, "\\#ffa0a0\\Error:\\#c8c8c8\\ Version mismatch.\n\nYour version: \\#a0a0ff\\%s\\#c8c8c8\\\nTheir version: \\#a0a0ff\\%s\\#c8c8c8\\\n\nSomeone is out of date!\n", version, remoteVersion); @@ -174,7 +174,7 @@ void network_receive_join(struct Packet* p) { packet_read(p, eeprom, sizeof(u8) * 512); packet_read(p, &modCount, sizeof(u8)); - Cheats.EnableCheats = gServerSettings.enableCheats; + Cheats.enabled = gServerSettings.enableCheats; struct StringLinkedList head = { 0 }; for (s32 i = 0; i < modCount; i++) { @@ -186,7 +186,7 @@ void network_receive_join(struct Packet* p) { } if (string_linked_list_mismatch(&gRegisteredMods, &head)) { - network_shutdown(true, false); + network_shutdown(true, false, false); struct StringBuilder* builder = string_builder_create(512); string_builder_append(builder, "\\#ffa0a0\\Error:\\#c8c8c8\\ mods don't match.\n\n"); diff --git a/src/pc/network/packets/packet_kick.c b/src/pc/network/packets/packet_kick.c index 4a77b020a..0a16c60a3 100644 --- a/src/pc/network/packets/packet_kick.c +++ b/src/pc/network/packets/packet_kick.c @@ -32,5 +32,5 @@ void network_receive_kick(struct Packet* p) { case EKT_BANNED: djui_panel_join_message_error("\\#ffa0a0\\Error:\\#c8c8c8\\ The server banned you."); break; default: djui_panel_join_message_error("\\#ffa0a0\\Error:\\#c8c8c8\\ Host has closed the connection."); break; } - network_shutdown(false, false); + network_shutdown(false, false, false); } diff --git a/src/pc/network/packets/packet_mod_list.c b/src/pc/network/packets/packet_mod_list.c index efd9084f1..4e3ea73eb 100644 --- a/src/pc/network/packets/packet_mod_list.c +++ b/src/pc/network/packets/packet_mod_list.c @@ -121,7 +121,7 @@ void network_receive_mod_list(struct Packet* p) { packet_read(p, &remoteVersion, sizeof(u8) * MAX_VERSION_LENGTH); LOG_INFO("server has version: %s", version); if (memcmp(version, remoteVersion, MAX_VERSION_LENGTH) != 0) { - network_shutdown(true, false); + network_shutdown(true, false, false); LOG_ERROR("version mismatch"); char mismatchMessage[256] = { 0 }; snprintf(mismatchMessage, 256, "\\#ffa0a0\\Error:\\#c8c8c8\\ Version mismatch.\n\nYour version: \\#a0a0ff\\%s\\#c8c8c8\\\nTheir version: \\#a0a0ff\\%s\\#c8c8c8\\\n\nSomeone is out of date!\n", version, remoteVersion); @@ -205,7 +205,7 @@ void network_receive_mod_list_entry(struct Packet* p) { // sanity check mod size if (mod->size >= MAX_MOD_SIZE) { djui_popup_create("Server had too large of a mod.\nQuitting.", 4); - network_shutdown(false, false); + network_shutdown(false, false, false); return; } diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index ea25839bc..351e58386 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -3,11 +3,6 @@ #include #include -#ifdef TARGET_WEB -#include -#include -#endif - #include "sm64.h" #include "pc/lua/smlua.h" @@ -254,7 +249,7 @@ void game_deinit(void) { audio_custom_shutdown(); audio_shutdown(); gfx_shutdown(); - network_shutdown(true, true); + network_shutdown(true, true, false); smlua_shutdown(); mods_shutdown(); inited = false; @@ -263,49 +258,13 @@ void game_deinit(void) { void game_exit(void) { LOG_INFO("exiting cleanly"); game_deinit(); -#ifndef TARGET_WEB exit(0); -#endif } void inthand(UNUSED int signum) { game_exit(); } -#ifdef TARGET_WEB -static void em_main_loop(void) { -} - -static void request_anim_frame(void (*func)(double time)) { - EM_ASM(requestAnimationFrame(function(time) { - dynCall("vd", $0, [time]); - }), func); -} - -static void on_anim_frame(double time) { - static double target_time; - - time *= 0.03; // milliseconds to frame count (33.333 ms -> 1) - - if (time >= target_time + 10.0) { - // We are lagging 10 frames behind, probably due to coming back after inactivity, - // so reset, with a small margin to avoid potential jitter later. - target_time = time - 0.010; - } - - for (s32 i = 0; i < 2; i++) { - // If refresh rate is 15 Hz or something we might need to generate two frames - if (time >= target_time) { - produce_one_frame(); - target_time = target_time + 1.0; - } - } - - if (inited) // only continue if the init flag is still set - request_anim_frame(on_anim_frame); -} -#endif - void main_func(void) { const char *gamedir = gCLIOpts.GameDir[0] ? gCLIOpts.GameDir : FS_BASEDIR; const char *userpath = gCLIOpts.SavePath[0] ? gCLIOpts.SavePath : sys_user_path(); @@ -416,10 +375,6 @@ void main_func(void) { discord_init(); #endif -#ifdef TARGET_WEB - emscripten_set_main_loop(em_main_loop, 0, 0); - request_anim_frame(on_anim_frame); -#else while (true) { wm_api->main_loop(produce_one_frame); #ifdef DISCORDRPC @@ -430,7 +385,6 @@ void main_func(void) { fflush(stderr); #endif } -#endif bassh_deinit(); } diff --git a/src/pc/ultra_reimplementation.c b/src/pc/ultra_reimplementation.c index 6e6d98e68..85651ef77 100644 --- a/src/pc/ultra_reimplementation.c +++ b/src/pc/ultra_reimplementation.c @@ -5,10 +5,6 @@ #include "platform.h" #include "fs/fs.h" -#ifdef TARGET_WEB -#include -#endif - u8* gOverrideEeprom = NULL; extern OSMgrArgs piMgrArgs; @@ -136,27 +132,6 @@ s32 osEepromLongRead(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes) u8 content[512]; s32 ret = -1; -#ifdef TARGET_WEB - if (EM_ASM_INT({ - var s = localStorage.sm64_save_file; - if (s && s.length === 684) { - try { - var binary = atob(s); - if (binary.length === 512) { - for (var i = 0; i < 512; i++) { - HEAPU8[$0 + i] = binary.charCodeAt(i); - } - return 1; - } - } catch (e) { - } - } - return 0; - }, content)) { - memcpy(buffer, content + address * 8, nbytes); - ret = 0; - } -#else fs_file_t *fp = fs_open(SAVE_FILENAME); if (fp == NULL) { return -1; @@ -166,7 +141,7 @@ s32 osEepromLongRead(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes) ret = 0; } fs_close(fp); -#endif + return ret; } @@ -182,22 +157,12 @@ s32 osEepromLongWrite(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes } memcpy(content + address * 8, buffer, nbytes); -#ifdef TARGET_WEB - EM_ASM({ - var str = ""; - for (var i = 0; i < 512; i++) { - str += String.fromCharCode(HEAPU8[$0 + i]); - } - localStorage.sm64_save_file = btoa(str); - }, content); - s32 ret = 0; -#else FILE *fp = fopen(fs_get_write_path(SAVE_FILENAME), "wb"); if (fp == NULL) { return -1; } s32 ret = fwrite(content, 1, 512, fp) == 512 ? 0 : -1; fclose(fp); -#endif + return ret; }