Merge branch 'develop-zhora' of https://github.com/HarbourMasters/Shipwright into custom-messages

This commit is contained in:
Christopher Leggett 2022-08-08 19:46:09 -04:00
commit 59baf24dc6
No known key found for this signature in database
GPG key ID: 7093AE5FF7037D79
190 changed files with 7592 additions and 10422 deletions

65
soh/CMake/Default.cmake Normal file
View file

@ -0,0 +1,65 @@
################################################################################
# Command for variable_watch. This command issues error message, if a variable
# is changed. If variable PROPERTY_READER_GUARD_DISABLED is TRUE nothing happens
# variable_watch(<variable> property_reader_guard)
################################################################################
function(property_reader_guard VARIABLE ACCESS VALUE CURRENT_LIST_FILE STACK)
if("${PROPERTY_READER_GUARD_DISABLED}")
return()
endif()
if("${ACCESS}" STREQUAL "MODIFIED_ACCESS")
message(FATAL_ERROR
" Variable ${VARIABLE} is not supposed to be changed.\n"
" It is used only for reading target property ${VARIABLE}.\n"
" Use\n"
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}\" \"<value>\")\n"
" or\n"
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}_<CONFIG>\" \"<value>\")\n"
" instead.\n")
endif()
endfunction()
################################################################################
# Create variable <name> with generator expression that expands to value of
# target property <name>_<CONFIG>. If property is empty or not set then property
# <name> is used instead. Variable <name> has watcher property_reader_guard that
# doesn't allow to edit it.
# create_property_reader(<name>)
# Input:
# name - Name of watched property and output variable
################################################################################
function(create_property_reader NAME)
set(PROPERTY_READER_GUARD_DISABLED TRUE)
set(CONFIG_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}_$<UPPER_CASE:$<CONFIG>>>>")
set(IS_CONFIG_VALUE_EMPTY "$<STREQUAL:${CONFIG_VALUE},>")
set(GENERAL_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}>>")
set("${NAME}" "$<IF:${IS_CONFIG_VALUE_EMPTY},${GENERAL_VALUE},${CONFIG_VALUE}>" PARENT_SCOPE)
variable_watch("${NAME}" property_reader_guard)
endfunction()
################################################################################
# Set property $<name>_${PROPS_CONFIG_U} of ${PROPS_TARGET} to <value>
# set_config_specific_property(<name> <value>)
# Input:
# name - Prefix of property name
# value - New value
################################################################################
function(set_config_specific_property NAME VALUE)
set_target_properties("${PROPS_TARGET}" PROPERTIES "${NAME}_${PROPS_CONFIG_U}" "${VALUE}")
endfunction()
################################################################################
create_property_reader("TARGET_NAME")
create_property_reader("OUTPUT_DIRECTORY")
set_config_specific_property("TARGET_NAME" "${PROPS_TARGET}")
set_config_specific_property("OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("ARCHIVE_OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("LIBRARY_OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("RUNTIME_OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("ARCHIVE_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
set_config_specific_property("LIBRARY_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
set_config_specific_property("RUNTIME_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")

View file

@ -0,0 +1,12 @@
include("${CMAKE_CURRENT_LIST_DIR}/Default.cmake")
set_config_specific_property("OUTPUT_DIRECTORY" "${CMAKE_SOURCE_DIR}$<$<NOT:$<STREQUAL:${CMAKE_VS_PLATFORM_NAME},Win32>>:/${CMAKE_VS_PLATFORM_NAME}>/${PROPS_CONFIG}")
if(MSVC)
create_property_reader("DEFAULT_CXX_EXCEPTION_HANDLING")
create_property_reader("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT")
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi")
endif()

View file

@ -0,0 +1,15 @@
# which compilers to use for C and C++
set(CMAKE_C_COMPILER gcc)
set(CMAKE_C_FLAGS "-m32")
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_CXX_FLAGS -m32)
# here is the target environment located
#set(CMAKE_FIND_ROOT_PATH /lib/i386-linux-gnu )
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)

233
soh/CMake/Utils.cmake Normal file
View file

@ -0,0 +1,233 @@
# utils file for projects came from visual studio solution with cmake-converter.
################################################################################
# Wrap each token of the command with condition
################################################################################
cmake_policy(PUSH)
cmake_policy(SET CMP0054 NEW)
macro(prepare_commands)
unset(TOKEN_ROLE)
unset(COMMANDS)
foreach(TOKEN ${ARG_COMMANDS})
if("${TOKEN}" STREQUAL "COMMAND")
set(TOKEN_ROLE "KEYWORD")
elseif("${TOKEN_ROLE}" STREQUAL "KEYWORD")
set(TOKEN_ROLE "CONDITION")
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
set(TOKEN_ROLE "COMMAND")
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
set(TOKEN_ROLE "ARG")
endif()
if("${TOKEN_ROLE}" STREQUAL "KEYWORD")
list(APPEND COMMANDS "${TOKEN}")
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
set(CONDITION ${TOKEN})
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
list(APPEND COMMANDS "$<$<NOT:${CONDITION}>:${DUMMY}>$<${CONDITION}:${TOKEN}>")
elseif("${TOKEN_ROLE}" STREQUAL "ARG")
list(APPEND COMMANDS "$<${CONDITION}:${TOKEN}>")
endif()
endforeach()
endmacro()
cmake_policy(POP)
################################################################################
# Transform all the tokens to absolute paths
################################################################################
macro(prepare_output)
unset(OUTPUT)
foreach(TOKEN ${ARG_OUTPUT})
if(IS_ABSOLUTE ${TOKEN})
list(APPEND OUTPUT "${TOKEN}")
else()
list(APPEND OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${TOKEN}")
endif()
endforeach()
endmacro()
################################################################################
# Parse add_custom_command_if args.
#
# Input:
# PRE_BUILD - Pre build event option
# PRE_LINK - Pre link event option
# POST_BUILD - Post build event option
# TARGET - Target
# OUTPUT - List of output files
# DEPENDS - List of files on which the command depends
# COMMANDS - List of commands(COMMAND condition1 commannd1 args1 COMMAND
# condition2 commannd2 args2 ...)
# Output:
# OUTPUT - Output files
# DEPENDS - Files on which the command depends
# COMMENT - Comment
# PRE_BUILD - TRUE/FALSE
# PRE_LINK - TRUE/FALSE
# POST_BUILD - TRUE/FALSE
# TARGET - Target name
# COMMANDS - Prepared commands(every token is wrapped in CONDITION)
# NAME - Unique name for custom target
# STEP - PRE_BUILD/PRE_LINK/POST_BUILD
################################################################################
function(add_custom_command_if_parse_arguments)
cmake_parse_arguments("ARG" "PRE_BUILD;PRE_LINK;POST_BUILD" "TARGET;COMMENT" "DEPENDS;OUTPUT;COMMANDS" ${ARGN})
if(WIN32)
set(DUMMY "cd.")
elseif(UNIX)
set(DUMMY "true")
endif()
prepare_commands()
prepare_output()
set(DEPENDS "${ARG_DEPENDS}")
set(COMMENT "${ARG_COMMENT}")
set(PRE_BUILD "${ARG_PRE_BUILD}")
set(PRE_LINK "${ARG_PRE_LINK}")
set(POST_BUILD "${ARG_POST_BUILD}")
set(TARGET "${ARG_TARGET}")
if(PRE_BUILD)
set(STEP "PRE_BUILD")
elseif(PRE_LINK)
set(STEP "PRE_LINK")
elseif(POST_BUILD)
set(STEP "POST_BUILD")
endif()
set(NAME "${TARGET}_${STEP}")
set(OUTPUT "${OUTPUT}" PARENT_SCOPE)
set(DEPENDS "${DEPENDS}" PARENT_SCOPE)
set(COMMENT "${COMMENT}" PARENT_SCOPE)
set(PRE_BUILD "${PRE_BUILD}" PARENT_SCOPE)
set(PRE_LINK "${PRE_LINK}" PARENT_SCOPE)
set(POST_BUILD "${POST_BUILD}" PARENT_SCOPE)
set(TARGET "${TARGET}" PARENT_SCOPE)
set(COMMANDS "${COMMANDS}" PARENT_SCOPE)
set(STEP "${STEP}" PARENT_SCOPE)
set(NAME "${NAME}" PARENT_SCOPE)
endfunction()
################################################################################
# Add conditional custom command
#
# Generating Files
# The first signature is for adding a custom command to produce an output:
# add_custom_command_if(
# <OUTPUT output1 [output2 ...]>
# <COMMANDS>
# <COMMAND condition command1 [args1...]>
# [COMMAND condition command2 [args2...]]
# [DEPENDS [depends...]]
# [COMMENT comment]
#
# Build Events
# add_custom_command_if(
# <TARGET target>
# <PRE_BUILD | PRE_LINK | POST_BUILD>
# <COMMAND condition command1 [args1...]>
# [COMMAND condition command2 [args2...]]
# [COMMENT comment]
#
# Input:
# output - Output files the command is expected to produce
# condition - Generator expression for wrapping the command
# command - Command-line(s) to execute at build time.
# args - Command`s args
# depends - Files on which the command depends
# comment - Display the given message before the commands are executed at
# build time.
# PRE_BUILD - Run before any other rules are executed within the target
# PRE_LINK - Run after sources have been compiled but before linking the
# binary
# POST_BUILD - Run after all other rules within the target have been
# executed
################################################################################
function(add_custom_command_if)
add_custom_command_if_parse_arguments(${ARGN})
if(OUTPUT AND TARGET)
message(FATAL_ERROR "Wrong syntax. A TARGET and OUTPUT can not both be specified.")
endif()
if(OUTPUT)
add_custom_command(OUTPUT ${OUTPUT}
${COMMANDS}
DEPENDS ${DEPENDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT ${COMMENT})
elseif(TARGET)
if(PRE_BUILD AND NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio")
add_custom_target(
${NAME}
${COMMANDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT ${COMMENT})
add_dependencies(${TARGET} ${NAME})
else()
add_custom_command(
TARGET ${TARGET}
${STEP}
${COMMANDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT ${COMMENT})
endif()
else()
message(FATAL_ERROR "Wrong syntax. A TARGET or OUTPUT must be specified.")
endif()
endfunction()
################################################################################
# Use props file for a target and configs
# use_props(<target> <configs...> <props_file>)
# Inside <props_file> there are following variables:
# PROPS_TARGET - <target>
# PROPS_CONFIG - One of <configs...>
# PROPS_CONFIG_U - Uppercase PROPS_CONFIG
# Input:
# target - Target to apply props file
# configs - Build configurations to apply props file
# props_file - CMake script
################################################################################
macro(use_props TARGET CONFIGS PROPS_FILE)
set(PROPS_TARGET "${TARGET}")
foreach(PROPS_CONFIG ${CONFIGS})
string(TOUPPER "${PROPS_CONFIG}" PROPS_CONFIG_U)
get_filename_component(ABSOLUTE_PROPS_FILE "${PROPS_FILE}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
if(EXISTS "${ABSOLUTE_PROPS_FILE}")
include("${ABSOLUTE_PROPS_FILE}")
else()
message(WARNING "Corresponding cmake file from props \"${ABSOLUTE_PROPS_FILE}\" doesn't exist")
endif()
endforeach()
endmacro()
################################################################################
# Add compile options to source file
# source_file_compile_options(<source_file> [compile_options...])
# Input:
# source_file - Source file
# compile_options - Options to add to COMPILE_FLAGS property
################################################################################
function(source_file_compile_options SOURCE_FILE)
if("${ARGC}" LESS_EQUAL "1")
return()
endif()
get_source_file_property(COMPILE_OPTIONS "${SOURCE_FILE}" COMPILE_OPTIONS)
if(COMPILE_OPTIONS)
list(APPEND COMPILE_OPTIONS ${ARGN})
else()
set(COMPILE_OPTIONS "${ARGN}")
endif()
set_source_files_properties("${SOURCE_FILE}" PROPERTIES COMPILE_OPTIONS "${COMPILE_OPTIONS}")
endfunction()
################################################################################
# Default properties of visual studio projects
################################################################################
set(DEFAULT_CXX_PROPS "${CMAKE_CURRENT_LIST_DIR}/DefaultCXX.cmake")

1994
soh/CMakeLists.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,235 +0,0 @@
CXX ?= g++
CC ?= gcc
LD := lld
AR := ar
FORMAT := clang-format-11
ZAPD := ../ZAPDTR/ZAPD.out
UNAME := $(shell uname)
UNAMEM := $(shell uname -m)
LIBULTRASHIP := ../libultraship/libultraship.a
ZAPDUTILS := ../ZAPDTR/ZAPDUtils/ZAPDUtils.a
LIBSTORM := ../StormLib/build/libstorm.a
ASAN ?= 0
DEBUG ?= 1
OPTFLAGS ?= -O0
LTO ?= 0
# flag to save whether the compiler being used is clang or gcc by checking CXX --version
CXX_IS_CLANG ?= $(shell $(CXX) --version | grep -c clang)
WARN := \
-Wno-return-type \
-funsigned-char \
-fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-strict-aliasing -fno-inline-functions -fno-inline-small-functions -ffreestanding -fwrapv \
ifeq ($(CXX_IS_CLANG),1)
WARN += -Wno-c++11-narrowing
endif
CXXFLAGS := $(WARN) -std=c++20 -D_GNU_SOURCE -fpermissive -nostdlib $(shell pkg-config --cflags glew) $(shell sdl2-config --cflags)
CFLAGS := $(WARN) -std=c99 -Wno-implicit-function-declaration -D_GNU_SOURCE -nostdlib $(shell pkg-config --cflags glew) $(shell sdl2-config --cflags)
LDFLAGS :=
ifneq ($(CXX_IS_CLANG),1)
CXXFLAGS += -no-pie
CFLAGS += -no-pie
endif
ifeq ($(UNAME), Linux)
ifeq ($(UNAMEM), x86_64)
CXXFLAGS += -msse2 -mfpmath=sse -mhard-float
CFLAGS += -msse2 -mfpmath=sse -mhard-float
endif
CXXFLAGS += $(shell pkg-config --cflags libpulse)
CFLAGS += $(shell pkg-config --cflags libpulse)
endif
CPPFLAGS := -MMD
ifneq ($(DEBUG),0)
CXXFLAGS += -g
CFLAGS += -g
endif
ifneq ($(ASAN),0)
CXXFLAGS += -fsanitize=address
CFLAGS += -fsanitize=address
LDFLAGS += -fsanitize=address
endif
ifneq ($(LTO),0)
CXXFLAGS += -flto
CFLAGS += -flto
LDFLAGS += -flto
endif
ifeq ($(UNAME), Linux)
TARGET := soh.elf
endif
ifeq ($(UNAME), Darwin)
TARGET := soh-$(UNAMEM)
endif
INC_DIRS := $(addprefix -I, \
. \
assets \
build \
include \
src \
../ZAPDTR/ZAPDUtils \
../libultraship/libultraship \
../libultraship/libultraship/Lib/spdlog/include \
../libultraship/libultraship/Lib/Fast3D/U64 \
../libultraship/libultraship/Lib/Fast3D/U64/PR \
)
LDDIRS := $(addprefix -L, \
../libultraship/ \
)
LDLIBS := \
$(ZAPDUTILS) \
$(LIBSTORM) \
$(shell sdl2-config --libs) \
$(shell pkg-config --libs glew) \
$(addprefix -l, \
dl \
bz2 \
z \
pthread \
ultraship \
)
ifeq ($(UNAME), Linux)
LDLIBS += $(shell pkg-config --libs x11 libpulse)
endif
ifeq ($(UNAME), Darwin)
LDLIBS += \
$(addprefix -framework , \
OpenGL \
Foundation \
)
endif
ASSET_BIN_DIRS := $(shell find assets/* -type d -not -path "assets/xml*")
ASSET_FILES_XML := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.xml))
ASSET_FILES_BIN := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.bin))
ASSET_FILES_OUT := $(foreach f,$(ASSET_FILES_XML:.xml=.c),$f) \
$(foreach f,$(ASSET_FILES_BIN:.bin=.bin.inc.c),build/$f)
TEXTURE_FILES_PNG := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.png))
TEXTURE_FILES_JPG := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.jpg))
TEXTURE_FILES_OUT := $(foreach f,$(TEXTURE_FILES_PNG:.png=.inc.c),build/$f) \
$(foreach f,$(TEXTURE_FILES_JPG:.jpg=.jpg.inc.c),build/$f) \
CXX_FILES := \
$(shell find soh -type f -name "*.cpp")
C_FILES := \
$(shell find soh -type f -name "*.c") \
$(shell find src/boot -type f -name "*.c") \
$(shell find src/buffers -type f -name "*.c") \
$(shell find src/code -type f -name "*.c") \
$(shell find src/overlays -type f -name "*.c") \
src/libultra/gu/coss.c \
src/libultra/gu/guLookAt.c \
src/libultra/gu/guLookAtHilite.c \
src/libultra/gu/guPerspectiveF.c \
src/libultra/gu/guPosition.c \
src/libultra/gu/guS2DInitBg.c \
src/libultra/gu/ortho.c \
src/libultra/gu/rotate.c \
src/libultra/gu/sins.c \
src/libultra/gu/sintable.c \
src/libultra/libc/sprintf.c
O_FILES := \
$(C_FILES:%.c=build/%.o) \
$(CXX_FILES:%.cpp=build/%.o)
D_FILES := $(O_FILES:%.o=%.d)
# Apple App Bundle
APPNAME=soh
APPBUNDLE=$(APPNAME).app
APPBUNDLECONTENTS=$(APPBUNDLE)/Contents
APPBUNDLEEXE=$(APPBUNDLECONTENTS)/MacOS
APPBUNDLERESOURCES=$(APPBUNDLECONTENTS)/Resources
APPBUNDLEICON=$(APPBUNDLECONTENTS)/Resources
# create build directory
SRC_DIRS := $(shell find . -type d -a -not -path "*build*")
$(shell mkdir -p $(SRC_DIRS:%=build/%))
all:
$(MAKE) -C ../libultraship
$(MAKE) $(TARGET)
setup:
cd ../OTRExporter
$(MAKE) mpq
mpq:
$(MAKE) -C ../libultraship
$(MAKE) -C ../OTRExporter/OTRExporter
$(MAKE) -C ../ZAPDTR
rm -rf ../OTRExporter/oot.otr
cd ../OTRExporter && python3 extract_assets.py
cp ../OTRExporter/oot.otr .
distclean: clean
$(RM) -r baserom/
$(MAKE) clean -C ../libultraship
$(MAKE) clean -C ../OTRExporter/OTRExporter
$(MAKE) clean -C ../ZAPDTR
clean:
rm -rf build $(TARGET)
.PHONY: all clean distclean setup mpq
build/%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) $< -o $@
build/%.o: %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) $< -o $@
# make soh depend on libultraship
$(TARGET): $(LIBULTRASHIP)
$(TARGET): $(O_FILES)
$(CXX) $^ -o $@ $(LDFLAGS) $(LDDIRS) $(LDLIBS)
-include $(D_FILES)
appbundle: macosx/$(APPNAME).icns
rm -rf $(APPBUNDLE)
mkdir $(APPBUNDLE)
mkdir $(APPBUNDLE)/Contents
mkdir $(APPBUNDLE)/Contents/MacOS
mkdir $(APPBUNDLE)/Contents/Resources
cp macosx/Info.plist $(APPBUNDLECONTENTS)/
cp macosx/PkgInfo $(APPBUNDLECONTENTS)/
cp macosx/$(APPNAME).icns $(APPBUNDLEICON)/
cp $(TARGET) $(APPBUNDLEEXE)/soh
otool -l $(TARGET) | grep -A 2 LC_RPATH | tail -n 1 | awk '{print $2}' | dylibbundler -od -b -x $(APPBUNDLEEXE)/soh -d $(APPBUNDLECONTENTS)/libs
macosx/$(APPNAME).icns: macosx/$(APPNAME)Icon.png
rm -rf macosx/$(APPNAME).iconset
mkdir macosx/$(APPNAME).iconset
sips -z 16 16 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_16x16.png
sips -z 32 32 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_16x16@2x.png
sips -z 32 32 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_32x32.png
sips -z 64 64 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_32x32@2x.png
sips -z 128 128 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_128x128.png
sips -z 256 256 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_128x128@2x.png
sips -z 256 256 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_256x256.png
sips -z 512 512 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_256x256@2x.png
sips -z 512 512 macosx/$(APPNAME)Icon.png --out macosx/$(APPNAME).iconset/icon_512x512.png
cp macosx/$(APPNAME)Icon.png macosx/$(APPNAME).iconset/icon_512x512@2x.png
iconutil -c icns -o macosx/$(APPNAME).icns macosx/$(APPNAME).iconset
rm -r macosx/$(APPNAME).iconset

View file

@ -1,280 +0,0 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
endif
TOPDIR ?= $(CURDIR)
include $(DEVKITPRO)/libnx/switch_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
#
# NO_ICON: if set to anything, do not use icon.
# NO_NACP: if set to anything, no .nacp file is generated.
# APP_TITLE is the name of the app stored in the .nacp file (Optional)
# APP_AUTHOR is the author of the app stored in the .nacp file (Optional)
# APP_VERSION is the version of the app stored in the .nacp file (Optional)
# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional)
# ICON is the filename of the icon (.jpg), relative to the project folder.
# If not set, it attempts to use one of the following (in this order):
# - <Project name>.jpg
# - icon.jpg
# - <libnx folder>/default_icon.jpg
#
# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder.
# If not set, it attempts to use one of the following (in this order):
# - <Project name>.json
# - config.json
# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
# NACP building is skipped as well.
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := switch
DATA :=
INCLUDES := \
. \
assets \
build \
include \
src \
../ZAPDTR/ZAPDUtils \
../libultraship/libultraship \
../libultraship/libultraship/Lib/spdlog/include \
../libultraship/libultraship/Lib/Fast3D/U64 \
../libultraship/libultraship/Lib/Fast3D/U64/PR
#-------------------------------------------------------------------------------
# source files
#-------------------------------------------------------------------------------
SOURCEFILES_C := \
$(shell find soh -type f -name "*.c") \
$(shell find src/boot -type f -name "*.c") \
$(shell find src/buffers -type f -name "*.c") \
$(shell find src/code -type f -name "*.c") \
$(shell find src/overlays -type f -name "*.c") \
src/libultra/gu/coss.c \
src/libultra/gu/guLookAt.c \
src/libultra/gu/guLookAtHilite.c \
src/libultra/gu/guPerspectiveF.c \
src/libultra/gu/guPosition.c \
src/libultra/gu/guS2DInitBg.c \
src/libultra/gu/ortho.c \
src/libultra/gu/rotate.c \
src/libultra/gu/sins.c \
src/libultra/gu/sintable.c \
src/libultra/libc/sprintf.c
SOURCEFILES_CPP := \
$(shell find soh -type f -name "*.cpp")
#---------------------------------------------------------------------------------
# app info
#---------------------------------------------------------------------------------
APP_TITLE := Ship of Harkinian
APP_AUTHOR := Harbour Masters
APP_VERSION := Rachael-Alfa
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE -ffast-math -O3
CFLAGS := -ffunction-sections \
$(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) -D__SWITCH__ \
-DSPDLOG_NO_THREAD_ID \
-DSTBI_NO_THREAD_LOCALS \
`sdl2-config --cflags`
CXXFLAGS := $(CFLAGS) -std=gnu++20 -fpermissive
CFLAGS += -std=gnu11
# disable some warnings
CFLAGS += -Wno-incompatible-pointer-types -Wno-int-conversion \
-Wno-builtin-declaration-mismatch -Wno-implicit-function-declaration \
-Wno-stringop-overflow -Wno-discarded-qualifiers -Wno-switch-unreachable
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
STATIC_LIBS := $(SOH_TOP_DIR)/libultraship/lib/libultraship.a \
$(SOH_TOP_DIR)/ZAPDTR/ZAPDUtils/lib/libZAPDUtils.a \
$(SOH_TOP_DIR)/ZAPDTR/ZAPDUtils/lib/libZAPDUtils.a \
$(SOH_TOP_DIR)/StormLib/nxbuild/libstorm.a \
LIBS := -L$(SOH_TOP_DIR)/StormLib/nxbuild/ -lultraship -lZAPDUtils -lstorm -lz -lbz2 -lnx -lglad -lglapi -ldrm_nouveau -lm `sdl2-config --libs`
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(LIBNX) $(SOH_TOP_DIR)/StormLib/nxbuild $(SOH_TOP_DIR)/libultraship $(SOH_TOP_DIR)/ZAPDTR/ZAPDUtils
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
$(foreach sf,$(SOURCEFILES_C),$(CURDIR)/$(dir $(sf))) \
$(foreach sf,$(SOURCEFILES_CPP),$(CURDIR)/$(dir $(sf)))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) \
$(foreach f,$(SOURCEFILES_C),$(notdir $(f)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) \
$(foreach f,$(SOURCEFILES_CPP),$(notdir $(f)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
ifeq ($(strip $(CONFIG_JSON)),)
jsons := $(wildcard *.json)
ifneq (,$(findstring $(TARGET).json,$(jsons)))
export APP_JSON := $(TOPDIR)/$(TARGET).json
else
ifneq (,$(findstring config.json,$(jsons)))
export APP_JSON := $(TOPDIR)/config.json
endif
endif
else
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
endif
ifeq ($(strip $(ICON)),)
icons := $(wildcard *.jpg)
ifneq (,$(findstring $(TARGET).jpg,$(icons)))
export APP_ICON := $(TOPDIR)/$(TARGET).jpg
else
ifneq (,$(findstring icon.jpg,$(icons)))
export APP_ICON := $(TOPDIR)/icon.jpg
endif
endif
else
export APP_ICON := $(TOPDIR)/$(ICON)
endif
ifeq ($(strip $(NO_ICON)),)
export NROFLAGS += --icon=$(APP_ICON)
endif
ifeq ($(strip $(NO_NACP)),)
export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp
endif
ifneq ($(APP_TITLEID),)
export NACPFLAGS += --titleid=$(APP_TITLEID)
endif
ifneq ($(ROMFS),)
export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS)
endif
.PHONY: $(BUILD) clean all
#---------------------------------------------------------------------------------
all: $(BUILD)
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.switch
#---------------------------------------------------------------------------------
clean:
@echo clean ...
ifeq ($(strip $(APP_JSON)),)
@rm -fr $(BUILD) $(TARGET).nro $(TARGET).nacp $(TARGET).elf
else
@rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf
endif
#---------------------------------------------------------------------------------
else
.PHONY: all
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
ifeq ($(strip $(APP_JSON)),)
all : $(OUTPUT).nro
ifeq ($(strip $(NO_NACP)),)
$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp
else
$(OUTPUT).nro : $(OUTPUT).elf
endif
else
all : $(OUTPUT).nsp
$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm
$(OUTPUT).nso : $(OUTPUT).elf
endif
$(OUTPUT).elf : $(OFILES) \
$(STATIC_LIBS)
$(OFILES_SRC) : $(HFILES_BIN)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View file

@ -63,6 +63,9 @@ u32 Locale_IsRegionNative(void);
#if !defined(__APPLE__) && !defined(__SWITCH__)
void __assert(const char* exp, const char* file, s32 line);
#endif
#if defined(__APPLE__) && defined(NDEBUG)
void __assert(const char* exp, const char* file, s32 line);
#endif
void isPrintfInit(void);
void osSyncPrintfUnused(const char* fmt, ...);
//void osSyncPrintf(const char* fmt, ...);
@ -1528,6 +1531,7 @@ s32 func_800C0CB8(GlobalContext* globalCtx);
s32 FrameAdvance_IsEnabled(GlobalContext* globalCtx);
s32 func_800C0D34(GlobalContext* globalCtx, Actor* actor, s16* yaw);
s32 func_800C0DB4(GlobalContext* globalCtx, Vec3f* pos);
void Gameplay_PerformSave(GlobalContext* globalCtx);
void PreRender_SetValuesSave(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf, void* cvg);
void PreRender_Init(PreRender* this);
void PreRender_SetValues(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf);

View file

@ -25,7 +25,8 @@ typedef struct {
/* 0x0C */ Vec3f position;
/* 0x18 */ Vec3s unkVelocity;
/* 0x1E */ Vec3s unkPosition;
} EffectSparkElement; // size = 0x24
/* 0x24 */ s32 epoch;
} EffectSparkElement; // size = 0x28
typedef struct {
/* 0x000 */ Vec3s position;
@ -117,7 +118,8 @@ typedef struct {
/* 0x10 */ f32 startX;
/* 0x14 */ s16 yaw;
/* 0x16 */ s16 pitch;
} EffectShieldParticleElement; // size = 0x18
/* 0x18 */ s32 epoch;
} EffectShieldParticleElement; // size = 0x1C
typedef struct {
/* 0x00 */ u8 numElements;

8
soh/macosx/soh-macos.sh Executable file
View file

@ -0,0 +1,8 @@
#!/bin/sh
BUNDLE="`echo "$0" | sed -e 's/\/Contents\/MacOS\/.*//'`"
RESOURCES="$BUNDLE/Contents/Resources"
export DYLD_FRAMEWORK_PATH=$RESOURCES/Frameworks
export DYLD_LIBRARY_PATH=$RESOURCES/bin
exec "$RESOURCES/soh-macos"

View file

@ -1,66 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31112.23
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soh", "soh.vcxproj", "{31348AA7-8DC5-4FA7-955F-E80855CADE9E}"
ProjectSection(ProjectDependencies) = postProject
{78424708-1F6E-4D4B-920C-FB6D26847055} = {78424708-1F6E-4D4B-920C-FB6D26847055}
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8} = {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}
{A2E01C3E-D647-45D1-9788-043DEBC1A908} = {A2E01C3E-D647-45D1-9788-043DEBC1A908}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libultraship", "..\libultraship\libultraship\libultraship.vcxproj", "{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPDUtils", "..\ZAPDTR\ZAPDUtils\ZAPDUtils.vcxproj", "{A2E01C3E-D647-45D1-9788-043DEBC1A908}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "..\StormLib\StormLib_vs19.vcxproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{31348AA7-8DC5-4FA7-955F-E80855CADE9E}.Debug|x64.ActiveCfg = Debug|x64
{31348AA7-8DC5-4FA7-955F-E80855CADE9E}.Debug|x64.Build.0 = Debug|x64
{31348AA7-8DC5-4FA7-955F-E80855CADE9E}.Debug|x86.ActiveCfg = Debug|Win32
{31348AA7-8DC5-4FA7-955F-E80855CADE9E}.Debug|x86.Build.0 = Debug|Win32
{31348AA7-8DC5-4FA7-955F-E80855CADE9E}.Release|x64.ActiveCfg = Release|x64
{31348AA7-8DC5-4FA7-955F-E80855CADE9E}.Release|x64.Build.0 = Release|x64
{31348AA7-8DC5-4FA7-955F-E80855CADE9E}.Release|x86.ActiveCfg = Release|Win32
{31348AA7-8DC5-4FA7-955F-E80855CADE9E}.Release|x86.Build.0 = Release|Win32
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x64.ActiveCfg = Debug|x64
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x64.Build.0 = Debug|x64
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x86.ActiveCfg = Debug|Win32
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x86.Build.0 = Debug|Win32
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x64.ActiveCfg = Release|x64
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x64.Build.0 = Release|x64
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x86.ActiveCfg = Release|Win32
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x86.Build.0 = Release|Win32
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x64.ActiveCfg = Debug|x64
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x64.Build.0 = Debug|x64
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x86.ActiveCfg = Debug|Win32
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x86.Build.0 = Debug|Win32
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.ActiveCfg = Release|x64
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.Build.0 = Release|x64
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.ActiveCfg = Release|Win32
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.Build.0 = Release|Win32
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.ActiveCfg = DebugUS|x64
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.Build.0 = DebugUS|x64
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x86.ActiveCfg = DebugUS|Win32
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x86.Build.0 = DebugUS|Win32
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.ActiveCfg = ReleaseUS|x64
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.Build.0 = ReleaseUS|x64
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x86.ActiveCfg = ReleaseUS|Win32
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x86.Build.0 = ReleaseUS|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7659B687-4D92-4865-A037-045115E1C783}
EndGlobalSection
EndGlobal

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup>
<ShowAllFiles>false</ShowAllFiles>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

View file

@ -1,11 +1,6 @@
#include "CosmeticsEditor.h"
#include "../../util.h"
#include "../libultraship/ImGuiImpl.h"
#include "GameSettings.h"
#include <array>
#include <bit>
#include <map>
#include <string>
#include <Cvar.h>
#include <PR/ultra64/types.h>

View file

@ -14,7 +14,6 @@
#define Path _Path
#define PATH_HACK
#include <Utils/StringHelper.h>
#include <Utils/File.h>
#include "Window.h"
#include "Lib/ImGui/imgui_internal.h"
@ -426,7 +425,7 @@ static bool SetCVarHandler(const std::vector<std::string>& args) {
else
CVar_SetS32(args[1].c_str(), std::stoi(args[2]));
DebugConsole_SaveCVars();
CVar_Save();
//INFO("[SOH] Updated player position to [ %.2f, %.2f, %.2f ]", pos.x, pos.y, pos.z);
return CMD_SUCCESS;
@ -463,168 +462,49 @@ void DebugConsole_Init(void) {
CMD_REGISTER("kill", { KillPlayerHandler, "Commit suicide." });
CMD_REGISTER("map", { LoadSceneHandler, "Load up kak?" });
CMD_REGISTER("rupee", { RuppeHandler, "Set your rupee counter.", {
{"amount", ArgumentType::NUMBER }
{"amount", Ship::ArgumentType::NUMBER }
}});
CMD_REGISTER("bItem", { BHandler, "Set an item to the B button.", { { "Item ID", ArgumentType::NUMBER } } });
CMD_REGISTER("health", { SetPlayerHealthHandler, "Set the health of the player.", {
{"health", ArgumentType::NUMBER }
CMD_REGISTER("bItem", { BHandler, "Set an item to the B button.", { { "Item ID", Ship::ArgumentType::NUMBER } } });
CMD_REGISTER("health", { SetPlayerHealthHandler, "Set the health of the player.", { { "health", Ship::ArgumentType::NUMBER }
}});
CMD_REGISTER("spawn", { ActorSpawnHandler, "Spawn an actor.", {
{ "actor_id", ArgumentType::NUMBER },
{ "data", ArgumentType::NUMBER },
{ "x", ArgumentType::PLAYER_POS, true },
{ "y", ArgumentType::PLAYER_POS, true },
{ "z", ArgumentType::PLAYER_POS, true },
{ "rx", ArgumentType::PLAYER_ROT, true },
{ "ry", ArgumentType::PLAYER_ROT, true },
{ "rz", ArgumentType::PLAYER_ROT, true }
CMD_REGISTER("spawn", { ActorSpawnHandler, "Spawn an actor.", { { "actor_id", Ship::ArgumentType::NUMBER },
{ "data", Ship::ArgumentType::NUMBER },
{ "x", Ship::ArgumentType::PLAYER_POS, true },
{ "y", Ship::ArgumentType::PLAYER_POS, true },
{ "z", Ship::ArgumentType::PLAYER_POS, true },
{ "rx", Ship::ArgumentType::PLAYER_ROT, true },
{ "ry", Ship::ArgumentType::PLAYER_ROT, true },
{ "rz", Ship::ArgumentType::PLAYER_ROT, true }
}});
CMD_REGISTER("pos", { SetPosHandler, "Sets the position of the player.", {
{ "x", ArgumentType::PLAYER_POS, true },
{ "y", ArgumentType::PLAYER_POS, true },
{ "z", ArgumentType::PLAYER_POS, true }
CMD_REGISTER("pos", { SetPosHandler, "Sets the position of the player.", { { "x", Ship::ArgumentType::PLAYER_POS, true },
{ "y", Ship::ArgumentType::PLAYER_POS, true },
{ "z", Ship::ArgumentType::PLAYER_POS, true }
}});
CMD_REGISTER("set", { SetCVarHandler,
"Sets a console variable.",
{ { "varName", ArgumentType::TEXT }, { "varValue", ArgumentType::TEXT } } });
CMD_REGISTER("get", { GetCVarHandler, "Gets a console variable.", { { "varName", ArgumentType::TEXT } } });
{ { "varName", Ship::ArgumentType::TEXT }, { "varValue", Ship::ArgumentType::TEXT } } });
CMD_REGISTER("get", { GetCVarHandler, "Gets a console variable.", { { "varName", Ship::ArgumentType::TEXT } } });
CMD_REGISTER("reset", { ResetHandler, "Resets the game." });
CMD_REGISTER("ammo", { AmmoHandler, "Changes ammo of an item.",
{ { "item", ArgumentType::TEXT },
{ "count", ArgumentType::NUMBER } } });
{ { "item", Ship::ArgumentType::TEXT }, { "count", Ship::ArgumentType::NUMBER } } });
CMD_REGISTER("bottle", { BottleHandler,
"Changes item in a bottle slot.",
{ { "item", ArgumentType::TEXT }, { "slot", ArgumentType::NUMBER } } });
{ { "item", Ship::ArgumentType::TEXT }, { "slot", Ship::ArgumentType::NUMBER } } });
CMD_REGISTER("item", { ItemHandler,
"Sets item ID in arg 1 into slot arg 2. No boundary checks. Use with caution.",
{ { "slot", ArgumentType::NUMBER }, { "item id", ArgumentType::NUMBER } } });
CMD_REGISTER("entrance",
{ EntranceHandler, "Sends player to the entered entrance (hex)", { { "entrance", ArgumentType::NUMBER } } });
{ { "slot", Ship::ArgumentType::NUMBER }, { "item id", Ship::ArgumentType::NUMBER } } });
CMD_REGISTER("entrance", { EntranceHandler,
"Sends player to the entered entrance (hex)",
{ { "entrance", Ship::ArgumentType::NUMBER } } });
CMD_REGISTER("save_state", { SaveStateHandler, "Save a state." });
CMD_REGISTER("load_state", { LoadStateHandler, "Load a state." });
CMD_REGISTER("set_slot", { StateSlotSelectHandler, "Selects a SaveState slot", {
{ "Slot number", ArgumentType::NUMBER, }
CMD_REGISTER("set_slot", { StateSlotSelectHandler, "Selects a SaveState slot", { {
"Slot number",
Ship::ArgumentType::NUMBER,
}
} });
DebugConsole_LoadCVars();
}
template <typename Numeric> bool is_number(const std::string& s) {
Numeric n;
return ((std::istringstream(s) >> n >> std::ws).eof());
}
void DebugConsole_LoadLegacyCVars() {
auto cvarsConfig = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("cvars.cfg");
if (File::Exists(cvarsConfig)) {
const auto lines = File::ReadAllLines(cvarsConfig);
for (const std::string& line : lines) {
std::vector<std::string> cfg = StringHelper::Split(line, " = ");
if (line.empty()) continue;
if (cfg.size() < 2) continue;
if (cfg[1].find("\"") == std::string::npos && (cfg[1].find("#") != std::string::npos))
{
std::string value(cfg[1]);
value.erase(std::remove_if(value.begin(), value.end(), [](char c) { return c == '#'; }), value.end());
auto splitTest = StringHelper::Split(value, "\r")[0];
uint32_t val = std::stoul(splitTest, nullptr, 16);
Color_RGBA8 clr;
clr.r = val >> 24;
clr.g = val >> 16;
clr.b = val >> 8;
clr.a = val & 0xFF;
CVar_SetRGBA(cfg[0].c_str(), clr);
}
if (cfg[1].find("\"") != std::string::npos) {
std::string value(cfg[1]);
value.erase(std::remove(value.begin(), value.end(), '\"'), value.end());
CVar_SetString(cfg[0].c_str(), ImStrdup(value.c_str()));
}
if (is_number<float>(cfg[1])) {
CVar_SetFloat(cfg[0].c_str(), std::stof(cfg[1]));
}
if (is_number<int>(cfg[1])) {
CVar_SetS32(cfg[0].c_str(), std::stoi(cfg[1]));
}
}
fs::remove(cvarsConfig);
}
}
void DebugConsole_LoadCVars() {
std::shared_ptr<Mercury> pConf = Ship::GlobalCtx2::GetInstance()->GetConfig();
pConf->reload();
for (const auto& item : pConf->rjson["CVars"].items()) {
auto value = item.value();
switch (value.type()) {
case nlohmann::detail::value_t::array:
break;
case nlohmann::detail::value_t::object:
if (value["Type"].get<std::string>() == mercuryRGBAObjectType) {
Color_RGBA8 clr;
clr.r = value["R"].get<uint8_t>();
clr.g = value["G"].get<uint8_t>();
clr.b = value["B"].get<uint8_t>();
clr.a = value["A"].get<uint8_t>();
}
break;
case nlohmann::detail::value_t::string:
CVar_SetString(item.key().c_str(), value.get<std::string>().c_str());
break;
case nlohmann::detail::value_t::boolean:
CVar_SetS32(item.key().c_str(), value.get<bool>());
break;
case nlohmann::detail::value_t::number_unsigned:
case nlohmann::detail::value_t::number_integer:
CVar_SetS32(item.key().c_str(), value.get<int>());
break;
case nlohmann::detail::value_t::number_float:
CVar_SetFloat(item.key().c_str(), value.get<float>());
break;
default: ;
}
if (item.key() == "gOpenMenuBar") {
int bp = 0;
}
}
DebugConsole_LoadLegacyCVars();
}
void DebugConsole_SaveCVars()
{
std::shared_ptr<Mercury> pConf = Ship::GlobalCtx2::GetInstance()->GetConfig();
for (const auto &cvar : cvars) {
const std::string key = StringHelper::Sprintf("CVars.%s", cvar.first.c_str());
if (cvar.second->type == CVarType::String && cvar.second->value.valueStr != nullptr)
pConf->setString(key, std::string(cvar.second->value.valueStr));
else if (cvar.second->type == CVarType::S32)
pConf->setInt(key, cvar.second->value.valueS32);
else if (cvar.second->type == CVarType::Float)
pConf->setFloat(key, cvar.second->value.valueFloat);
else if (cvar.second->type == CVarType::RGBA)
{
auto keyStr = key.c_str();
Color_RGBA8 clr = cvar.second->value.valueRGBA;
pConf->setUInt(StringHelper::Sprintf("%s.R", keyStr), clr.r);
pConf->setUInt(StringHelper::Sprintf("%s.G", keyStr), clr.r);
pConf->setUInt(StringHelper::Sprintf("%s.B", keyStr), clr.r);
pConf->setUInt(StringHelper::Sprintf("%s.A", keyStr), clr.r);
pConf->setString(StringHelper::Sprintf("%s.Type", keyStr), mercuryRGBAObjectType);
}
}
pConf->save();
CVar_Load();
}

View file

@ -1,5 +1,3 @@
#pragma once
void DebugConsole_Init(void);
void DebugConsole_LoadCVars();
void DebugConsole_SaveCVars();

View file

@ -6,7 +6,6 @@
#include "rando_main.hpp"
// #include <soh/Enhancements/randomizer.h>
#include <Cvar.h>
#include <GameSettings.h>
#define NOGDI
#define WIN32_LEAN_AND_MEAN
#include <GlobalCtx2.h>
@ -25,7 +24,7 @@ void RandoMain::GenerateRando(std::unordered_map<RandomizerSettingKey, u8> cvarS
std::string fileName = Ship::GlobalCtx2::GetPathRelativeToAppDirectory(GenerateRandomizer(cvarSettings).c_str());
CVar_SetString("gSpoilerLog", fileName.c_str());
Game::SaveSettings();
Game::LoadSettings();
CVar_Save();
CVar_Load();
CVar_SetS32("gNewSeedGenerated", 1);
}

View file

@ -8,7 +8,6 @@
#include <Cvar.h>
#include <textures/icon_item_static/icon_item_static.h>
#include <textures/icon_item_24_static/icon_item_24_static.h>
#include <GameSettings.h>
#include "../libultraship/ImGuiImpl.h"
#include <thread>
#include "3drando/rando_main.hpp"
@ -3168,7 +3167,7 @@ std::thread randoThread;
void GenerateRandomizerImgui() {
CVar_SetS32("gRandoGenerating", 1);
Game::SaveSettings();
CVar_Save();
std::unordered_map<RandomizerSettingKey, u8> cvarSettings;
cvarSettings[RSK_FOREST] = CVar_GetS32("gRandomizeForest", 1);
@ -3234,9 +3233,8 @@ void GenerateRandomizerImgui() {
RandoMain::GenerateRando(cvarSettings);
CVar_SetS32("gRandoGenerating", 0);
Game::SaveSettings();
Game::LoadSettings();
CVar_Save();
CVar_Load();
generated = 1;
}

View file

@ -1,8 +1,9 @@
#pragma once
static struct {
std::thread thread;
std::condition_variable cv_to_thread, cv_from_thread;
std::mutex mutex;
bool initialized;
bool running;
bool processing;
} audio;

View file

@ -4,9 +4,7 @@
#include <algorithm>
#include <filesystem>
#include <locale>
#include <codecvt>
#include "GlobalCtx2.h"
#include "GameSettings.h"
#include "ResourceMgr.h"
#include "DisplayList.h"
#include "PlayerAnimation.h"
@ -22,11 +20,9 @@
#else
#include <time.h>
#endif
#include <Vertex.h>
#include <CollisionHeader.h>
#include <Array.h>
#include <Cutscene.h>
#include <Texture.h>
#include "Lib/stb/stb_image.h"
#define DRMP3_IMPLEMENTATION
#include "Lib/dr_libs/mp3.h"
@ -39,10 +35,10 @@
#include <soh/Enhancements/randomizer/randomizer_item_tracker.h>
#include "Enhancements/n64_weird_frame_data.inc"
#include "soh/frame_interpolation.h"
#include "Utils/BitConverter.h"
#include "variables.h"
#include "macros.h"
#include <Utils/StringHelper.h>
#include "Hooks.h"
#include <soh/Enhancements/custom_message/CustomMessageManager.h>
#ifdef __APPLE__
@ -90,11 +86,73 @@ extern "C" void ResourceMgr_CacheDirectory(const char* resName);
extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path);
std::unordered_map<std::string, ExtensionEntry> ExtensionCache;
void OTRAudio_Thread() {
while (audio.running) {
{
std::unique_lock<std::mutex> Lock(audio.mutex);
while (!audio.processing && audio.running) {
audio.cv_to_thread.wait(Lock);
}
if (!audio.running) {
break;
}
}
std::unique_lock<std::mutex> Lock(audio.mutex);
//AudioMgr_ThreadEntry(&gAudioMgr);
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
//#define SAMPLES_HIGH 560
//#define SAMPLES_LOW 528
// PAL values
//#define SAMPLES_HIGH 656
//#define SAMPLES_LOW 624
// 44KHZ values
#define SAMPLES_HIGH 752
#define SAMPLES_LOW 720
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
#define NUM_AUDIO_CHANNELS 2
int samples_left = AudioPlayer_Buffered();
u32 num_audio_samples = samples_left < AudioPlayer_GetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
// 3 is the maximum authentic frame divisor.
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
AudioMgr_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples);
}
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
audio.processing = false;
audio.cv_from_thread.notify_one();
}
}
// C->C++ Bridge
extern "C" void OTRAudio_Init()
{
// Precache all our samples, sequences, etc...
ResourceMgr_CacheDirectory("audio");
if (!audio.running) {
audio.running = true;
audio.thread = std::thread(OTRAudio_Thread);
}
}
extern "C" void OTRAudio_Exit() {
// Tell the audio thread to stop
{
std::unique_lock<std::mutex> Lock(audio.mutex);
audio.running = false;
}
audio.cv_to_thread.notify_all();
// Wait until the audio thread quit
audio.thread.join();
}
extern "C" void OTRExtScanner() {
@ -136,6 +194,10 @@ extern "C" void InitOTR() {
OTRExtScanner();
}
extern "C" void DeinitOTR() {
OTRAudio_Exit();
}
#ifdef _WIN32
extern "C" uint64_t GetFrequency() {
LARGE_INTEGER nFreq;
@ -235,56 +297,10 @@ extern "C" void Graph_StartFrame() {
// C->C++ Bridge
extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
#ifndef __SWITCH__
if (!audio.initialized) {
audio.initialized = true;
std::thread([]() {
for (;;) {
{
std::unique_lock<std::mutex> Lock(audio.mutex);
while (!audio.processing) {
audio.cv_to_thread.wait(Lock);
}
}
std::unique_lock<std::mutex> Lock(audio.mutex);
//AudioMgr_ThreadEntry(&gAudioMgr);
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
//#define SAMPLES_HIGH 560
//#define SAMPLES_LOW 528
// PAL values
//#define SAMPLES_HIGH 656
//#define SAMPLES_LOW 624
// 44KHZ values
#define SAMPLES_HIGH 752
#define SAMPLES_LOW 720
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
#define NUM_AUDIO_CHANNELS 2
int samples_left = AudioPlayer_Buffered();
u32 num_audio_samples = samples_left < AudioPlayer_GetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
// 3 is the maximum authentic frame divisor.
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
AudioMgr_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples);
}
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
audio.processing = false;
audio.cv_from_thread.notify_one();
}
}).detach();
}
{
std::unique_lock<std::mutex> Lock(audio.mutex);
audio.processing = true;
}
#endif
audio.cv_to_thread.notify_one();
std::vector<std::unordered_map<Mtx*, MtxF>> mtx_replacements;
@ -327,14 +343,12 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
last_fps = fps;
last_update_rate = R_UPDATE_RATE;
#ifndef __SWITCH__
{
std::unique_lock<std::mutex> Lock(audio.mutex);
while (audio.processing) {
audio.cv_from_thread.wait(Lock);
}
}
#endif
// OTRTODO: FIGURE OUT END FRAME POINT
/* if (OTRGlobals::Instance->context->GetWindow()->lastScancode != -1)
@ -1310,10 +1324,11 @@ extern "C" uint32_t OTRGetCurrentHeight() {
}
extern "C" void OTRControllerCallback(ControllerCallback* controller) {
const auto controllers = Ship::Window::ControllerApi->virtualDevices;
auto controlDeck = Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
for (int i = 0; i < controllers.size(); ++i) {
Ship::Window::ControllerApi->physicalDevices[controllers[i]]->WriteToSource(i, controller);
for (int i = 0; i < controlDeck->GetNumVirtualDevices(); ++i) {
auto physicalDevice = controlDeck->GetPhysicalDeviceFromVirtualSlot(i);
physicalDevice->WriteToSource(i, controller);
}
}
@ -1367,11 +1382,11 @@ extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len) {
}
extern "C" int Controller_ShouldRumble(size_t i) {
auto controlDeck = Ship::GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck();
const auto controllers = Ship::Window::ControllerApi->virtualDevices;
for (const auto virtual_entry : controllers) {
if (Ship::Window::ControllerApi->physicalDevices[virtual_entry]->CanRumble()) {
for (int i = 0; i < controlDeck->GetNumVirtualDevices(); ++i) {
auto physicalDevice = controlDeck->GetPhysicalDeviceFromVirtualSlot(i);
if (physicalDevice->CanRumble()) {
return 1;
}
}
@ -1379,6 +1394,10 @@ extern "C" int Controller_ShouldRumble(size_t i) {
return 0;
}
extern "C" void Hooks_ExecuteAudioInit() {
Ship::ExecuteHooks<Ship::AudioInit>();
}
extern "C" void* getN64WeirdFrame(s32 i) {
char* weirdFrameBytes = reinterpret_cast<char*>(n64WeirdFrames);
return &weirdFrameBytes[i + sizeof(n64WeirdFrames)];
@ -1459,6 +1478,11 @@ extern "C" s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerChec
return OTRGlobals::Instance->gRandomizer->GetRandomizedItemIdFromKnownCheck(randomizerCheck, ogId);
}
extern "C" bool Randomizer_ObtainedFreestandingIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId, Actor* actor) {
return gSaveContext.n64ddFlag && (actor->parent != NULL) &&
Randomizer_GetItemIdFromKnownCheck(randomizerCheck, ogId) == GI_ICE_TRAP;
}
extern "C" bool Randomizer_ItemIsIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId) {
return gSaveContext.n64ddFlag && Randomizer_GetItemIdFromKnownCheck(randomizerCheck, ogId) == GI_ICE_TRAP;
}

View file

@ -87,6 +87,7 @@ int AudioPlayer_GetDesiredBuffered(void);
void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples);
int Controller_ShouldRumble(size_t i);
void Hooks_ExecuteAudioInit();
void* getN64WeirdFrame(s32 i);
Sprite* GetSeedTexture(uint8_t index);
void Randomizer_LoadSettings(const char* spoilerFileName);
@ -98,6 +99,7 @@ s16 Randomizer_GetItemModelFromId(s16 itemId);
s32 Randomizer_GetItemIDFromGetItemID(s32 getItemId);
s32 Randomizer_GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum);
s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
bool Randomizer_ObtainedFreestandingIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId, Actor* actor);
bool Randomizer_ItemIsIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId);
int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx);
#endif

View file

@ -1,4 +1,4 @@
const char gBuildVersion[] = "RACHAEL ALFA (3.0.0)";
const char gBuildVersion[] = "ZHORA ALFA (3.1.0)";
const char gBuildTeam[] = "github.com/harbourmasters";
const char gBuildDate[] = __DATE__ " " __TIME__;
const char gBuildMakeOption[] = "";

View file

@ -1,6 +1,6 @@
#include "global.h"
#include "Hooks.h"
#include <string.h>
#include "soh/OTRGlobals.h"
void func_800C3C80(AudioMgr* audioMgr) {
AudioTask* task;
@ -108,7 +108,7 @@ void AudioMgr_Init(AudioMgr* audioMgr, void* stack, OSPri pri, OSId id, SchedCon
AudioLoad_SetDmaHandler(DmaMgr_DmaHandler);
Audio_InitSound();
osSendMesgPtr(&audioMgr->unk_C8, NULL, OS_MESG_BLOCK);
ModInternal_ExecuteAudioInitHooks();
Hooks_ExecuteAudioInit();
// Removed due to crash
//IrqMgr_AddClient(audioMgr->irqMgr, &irqClient, &audioMgr->unk_74);
hasInitialized = true;

View file

@ -481,22 +481,6 @@ static void RunFrame()
uint64_t ticksA, ticksB;
ticksA = GetPerfCounter();
#ifdef __SWITCH__
#define SAMPLES_HIGH 752
#define SAMPLES_LOW 720
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
#define NUM_AUDIO_CHANNELS 2
int samples_left = AudioPlayer_Buffered();
u32 num_audio_samples = samples_left < AudioPlayer_GetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
AudioMgr_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples);
}
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
#endif
Graph_StartFrame();
// TODO: Workaround for rumble being too long. Implement os thread functions.

View file

@ -36,12 +36,14 @@ void Main_LogSystemHeap(void) {
osSyncPrintf(VT_RST);
}
void main(int argc, char** argv)
int main(int argc, char** argv)
{
GameConsole_Init();
InitOTR();
BootCommands_Init();
Main(0);
DeinitOTR();
return 0;
}
void Main(void* arg) {

View file

@ -55,13 +55,13 @@ void SpeedMeter_DrawTimeEntries(SpeedMeter* this, GraphicsContext* gfxCtx) {
uly = this->y;
lry = this->y + 2;
OPEN_DISPS(gfxCtx);
/*! @bug if gIrqMgrRetraceTime is 0, CLOSE_DISPS will never be reached */
if (gIrqMgrRetraceTime == 0) {
return;
}
OPEN_DISPS(gfxCtx);
sSpeedMeterTimeEntryPtr = &sSpeedMeterTimeEntryArray[0];
for (i = 0; i < ARRAY_COUNT(sSpeedMeterTimeEntryArray); i++) {
temp = ((f64) * (sSpeedMeterTimeEntryPtr->time) / gIrqMgrRetraceTime) * 64.0;

View file

@ -3957,6 +3957,8 @@ void Actor_DrawDoorLock(GlobalContext* globalCtx, s32 frame, s32 type) {
f32 chainsTranslateX;
f32 chainsTranslateY;
f32 rotZStep;
static s32 epoch = 0;
epoch++;
entry = &sDoorLocksInfo[type];
chainRotZ = entry->chainsRotZInit;
@ -3970,6 +3972,7 @@ void Actor_DrawDoorLock(GlobalContext* globalCtx, s32 frame, s32 type) {
chainsTranslateY = cosf(entry->chainAngle - chainRotZ) * (10 - frame) * 0.1f * entry->chainLength;
for (i = 0; i < 4; i++) {
FrameInterpolation_RecordOpenChild(entry, epoch + i * 25);
Matrix_Put(&baseMtxF);
Matrix_RotateZ(chainRotZ, MTXMODE_APPLY);
Matrix_Translate(chainsTranslateX, chainsTranslateY, 0.0f, MTXMODE_APPLY);
@ -3989,6 +3992,7 @@ void Actor_DrawDoorLock(GlobalContext* globalCtx, s32 frame, s32 type) {
}
chainRotZ += rotZStep;
FrameInterpolation_RecordCloseChild();
}
Matrix_Put(&baseMtxF);

View file

@ -47,6 +47,7 @@ void EffectShieldParticle_Init(void* thisx, void* initParamsx) {
elem->endXChange = elem->initialSpeed;
elem->yaw = Rand_ZeroOne() * 65534.0f;
elem->pitch = Rand_ZeroOne() * 65534.0f;
elem->epoch++;
}
this->lightDecay = initParams->lightDecay;
@ -156,7 +157,6 @@ void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) {
Color_RGBA8 primColor;
Color_RGBA8 envColor;
FrameInterpolation_RecordOpenChild(this, 0);
OPEN_DISPS(gfxCtx);
if (this != NULL) {
@ -182,6 +182,8 @@ void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) {
gDPPipeSync(POLY_XLU_DISP++);
for (elem = &this->elements[0]; elem < &this->elements[this->numElements]; elem++) {
FrameInterpolation_RecordOpenChild(elem, elem->epoch);
Mtx* mtx;
MtxF sp104;
MtxF spC4;
@ -212,9 +214,10 @@ void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) {
gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPVertex(POLY_XLU_DISP++, sVertices, 4, 0);
gSP2Triangles(POLY_XLU_DISP++, 0, 1, 2, 0, 0, 3, 1, 0);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(gfxCtx);
FrameInterpolation_RecordCloseChild();
}

View file

@ -89,6 +89,7 @@ void EffectSpark_Init(void* thisx, void* initParamsx) {
elem->unkPosition.x = Rand_ZeroOne() * 65534.0f;
elem->unkPosition.y = Rand_ZeroOne() * 65534.0f;
elem->unkPosition.z = Rand_ZeroOne() * 65534.0f;
elem->epoch++;
}
this->timer = 0;
@ -210,6 +211,8 @@ void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) {
Mtx* mtx;
f32 temp;
FrameInterpolation_RecordOpenChild(elem, elem->epoch);
SkinMatrix_SetTranslate(&spEC, elem->position.x, elem->position.y, elem->position.z);
temp = ((Rand_ZeroOne() * 2.5f) + 1.5f) / 64.0f;
SkinMatrix_SetScale(&spAC, temp, temp, 1.0f);
@ -264,6 +267,7 @@ void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) {
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &sp12C);
if (mtx == NULL) {
FrameInterpolation_RecordCloseChild();
goto end;
}
@ -273,6 +277,8 @@ void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) {
}
gDPPipeSync(POLY_XLU_DISP++);
FrameInterpolation_RecordCloseChild();
}
end:

View file

@ -3,6 +3,7 @@
#include "vt.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/gameplay_field_keep/gameplay_field_keep.h"
#include "soh/frame_interpolation.h"
typedef enum {
/* 0 */ LENS_FLARE_CIRCLE0,
@ -950,7 +951,6 @@ void Environment_Update(GlobalContext* globalCtx, EnvironmentContext* envCtx, Li
Gfx* prevDisplayList;
OPEN_DISPS(globalCtx->state.gfxCtx);
prevDisplayList = POLY_OPA_DISP;
displayList = Graph_GfxPlusOne(POLY_OPA_DISP);
gSPDisplayList(OVERLAY_DISP++, displayList);
@ -1459,6 +1459,8 @@ void Environment_DrawLensFlare(GlobalContext* globalCtx, EnvironmentContext* env
LENS_FLARE_RING, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1,
LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1,
};
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -1502,9 +1504,7 @@ void Environment_DrawLensFlare(GlobalContext* globalCtx, EnvironmentContext* env
unk88Target = cosAngle;
}
if (cosAngle < 0.0f) {
} else {
if (!(cosAngle < 0.0f)) {
if (arg9) {
u32 shrink = ShrinkWindow_GetCurrentVal();
func_800C016C(globalCtx, &pos, &screenPos);
@ -1517,6 +1517,8 @@ void Environment_DrawLensFlare(GlobalContext* globalCtx, EnvironmentContext* env
}
for (i = 0; i < ARRAY_COUNT(lensFlareTypes); i++) {
FrameInterpolation_RecordOpenChild("Lens Flare", epoch + i * 25);
Matrix_Translate(pos.x, pos.y, pos.z, MTXMODE_NEW);
if (arg9) {
@ -1573,6 +1575,8 @@ void Environment_DrawLensFlare(GlobalContext* globalCtx, EnvironmentContext* env
gSPDisplayList(POLY_XLU_DISP++, gLensFlareRingDL);
break;
}
FrameInterpolation_RecordCloseChild();
}
alphaScale = cosAngle - (1.5f - cosAngle);
@ -1638,6 +1642,8 @@ void Environment_DrawRain(GlobalContext* globalCtx, View* view, GraphicsContext*
Vec3f unused = { 0.0f, 0.0f, 0.0f };
Vec3f windDirection = { 0.0f, 0.0f, 0.0f };
Player* player = GET_PLAYER(globalCtx);
static s32 epoch = 0;
epoch++;
if (!(globalCtx->cameraPtrs[0]->unk_14C & 0x100) && (globalCtx->envCtx.unk_EE[2] == 0)) {
OPEN_DISPS(gfxCtx);
@ -1667,6 +1673,8 @@ void Environment_DrawRain(GlobalContext* globalCtx, View* view, GraphicsContext*
// draw rain drops
for (i = 0; i < globalCtx->envCtx.unk_EE[1]; i++) {
FrameInterpolation_RecordOpenChild("Rain Drop", epoch + i * 25);
temp2 = Rand_ZeroOne();
temp1 = Rand_ZeroOne();
temp3 = Rand_ZeroOne();
@ -1692,6 +1700,8 @@ void Environment_DrawRain(GlobalContext* globalCtx, View* view, GraphicsContext*
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gRaindropDL);
FrameInterpolation_RecordCloseChild();
}
// draw droplet rings on the ground
@ -1699,6 +1709,8 @@ void Environment_DrawRain(GlobalContext* globalCtx, View* view, GraphicsContext*
u8 firstDone = false;
for (i = 0; i < globalCtx->envCtx.unk_EE[1]; i++) {
FrameInterpolation_RecordOpenChild("Droplet Ring", epoch + i * 25);
if (!firstDone) {
func_80093D84(gfxCtx);
gDPSetEnvColor(POLY_XLU_DISP++, 155, 155, 155, 0);
@ -1719,6 +1731,8 @@ void Environment_DrawRain(GlobalContext* globalCtx, View* view, GraphicsContext*
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffShockwaveDL);
FrameInterpolation_RecordCloseChild();
}
}
@ -1911,10 +1925,14 @@ void Environment_DrawLightning(GlobalContext* globalCtx, s32 unused) {
s32 pad[2];
Vec3f unused1 = { 0.0f, 0.0f, 0.0f };
Vec3f unused2 = { 0.0f, 0.0f, 0.0f };
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
for (i = 0; i < ARRAY_COUNT(sLightningBolts); i++) {
FrameInterpolation_RecordOpenChild("Lightning Bolt", epoch + i * 25);
switch (sLightningBolts[i].state) {
case LIGHTNING_BOLT_START:
dx = globalCtx->view.lookAt.x - globalCtx->view.eye.x;
@ -1969,6 +1987,8 @@ void Environment_DrawLightning(GlobalContext* globalCtx, s32 unused) {
gSPMatrix(POLY_XLU_DISP++, SEG_ADDR(1, 0), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffLightningDL);
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View file

@ -1,5 +1,6 @@
#include "global.h"
#include "textures/parameter_static/parameter_static.h"
#include "soh/frame_interpolation.h"
s16 Top_LM_Margin = 0;
s16 Left_LM_Margin = 0;
@ -412,6 +413,8 @@ void HealthMeter_Draw(GlobalContext* globalCtx) {
s32 curCombineModeSet = 0;
u8* curBgImgLoaded = NULL;
s32 ddHeartCountMinusOne = gSaveContext.inventory.defenseHearts - 1;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -449,6 +452,8 @@ void HealthMeter_Draw(GlobalContext* globalCtx) {
}
for (i = 0; i < totalHeartCount; i++) {
FrameInterpolation_RecordOpenChild("HealthMeter Heart", epoch + i * 25);
if ((ddHeartCountMinusOne < 0) || (i > ddHeartCountMinusOne)) {
if (i < fullHeartCount) {
if (curColorSet != 0) {
@ -624,6 +629,8 @@ void HealthMeter_Draw(GlobalContext* globalCtx) {
offsetX = PosX_original;
}
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(gfxCtx);

View file

@ -2675,7 +2675,7 @@ void Message_DrawMain(GlobalContext* globalCtx, Gfx** p) {
if (msgCtx->lastPlayedSong < OCARINA_SONG_SARIAS &&
(msgCtx->ocarinaAction < OCARINA_ACTION_PLAYBACK_MINUET ||
msgCtx->ocarinaAction >= OCARINA_ACTION_PLAYBACK_SARIA)) {
if (msgCtx->disableWarpSongs || interfaceCtx->restrictions.warpSongs == 3) {
if (msgCtx->disableWarpSongs || (interfaceCtx->restrictions.warpSongs == 3 && !gSaveContext.n64ddFlag)) {
Message_StartTextbox(globalCtx, 0x88C, NULL); // "You can't warp here!"
globalCtx->msgCtx.ocarinaMode = OCARINA_MODE_04;
} else if ((gSaveContext.eventInf[0] & 0xF) != 1) {

View file

@ -1384,6 +1384,12 @@ void Inventory_SwapAgeEquipment(void) {
u16 temp;
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
// When becoming adult, remove swordless flag since we'll get master sword
// Only in rando to keep swordless link bugs in vanilla
if (gSaveContext.n64ddFlag) {
gSaveContext.infTable[29] &= ~1;
}
for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
if (i != 0) {
gSaveContext.childEquips.buttonItems[i] = gSaveContext.equips.buttonItems[i];
@ -1444,6 +1450,12 @@ void Inventory_SwapAgeEquipment(void) {
gSaveContext.equips.equipment = gSaveContext.adultEquips.equipment;
}
} else {
// When becoming child, set swordless flag if player doesn't have kokiri sword
// Only in rando to keep swordless link bugs in vanilla
if (gSaveContext.n64ddFlag && (1 << 0 & gSaveContext.inventory.equipment) == 0) {
gSaveContext.infTable[29] |= 1;
}
for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
gSaveContext.adultEquips.buttonItems[i] = gSaveContext.equips.buttonItems[i];
@ -2176,6 +2188,52 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, temp);
INV_CONTENT(item) = item;
// Autosave after getting items by default (cvars are not shown in the UI)
if (CVar_GetS32("gAutosave", 0)) {
if (CVar_GetS32("gAutosaveAllItems", 1)) {
Gameplay_PerformSave(globalCtx);
}
else if (CVar_GetS32("gAutosaveMajorItems", 1)) {
switch (item) {
case ITEM_STICK:
case ITEM_NUT:
case ITEM_BOMB:
case ITEM_BOW:
case ITEM_SEEDS:
case ITEM_FISHING_POLE:
case ITEM_MAGIC_SMALL:
case ITEM_MAGIC_LARGE:
case ITEM_INVALID_4:
case ITEM_INVALID_5:
case ITEM_INVALID_6:
case ITEM_INVALID_7:
case ITEM_HEART:
case ITEM_RUPEE_GREEN:
case ITEM_RUPEE_BLUE:
case ITEM_RUPEE_RED:
case ITEM_RUPEE_PURPLE:
case ITEM_RUPEE_GOLD:
case ITEM_INVALID_8:
case ITEM_STICKS_5:
case ITEM_STICKS_10:
case ITEM_NUTS_5:
case ITEM_NUTS_10:
case ITEM_BOMBS_5:
case ITEM_BOMBS_10:
case ITEM_BOMBS_20:
case ITEM_BOMBS_30:
case ITEM_ARROWS_SMALL:
case ITEM_ARROWS_MEDIUM:
case ITEM_ARROWS_LARGE:
case ITEM_SEEDS_30:
break;
default:
Gameplay_PerformSave(globalCtx);
break;
}
}
}
return temp;
}
@ -3352,8 +3410,8 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
const s16 C_Right_BTN_Pos_ori[] = { C_RIGHT_BUTTON_X+X_Margins_CR, C_RIGHT_BUTTON_Y+Y_Margins_CR };
const s16 C_Up_BTN_Pos_ori[] = { C_UP_BUTTON_X+X_Margins_CU, C_UP_BUTTON_Y+Y_Margins_CU };
const s16 C_Down_BTN_Pos_ori[] = { C_DOWN_BUTTON_X+X_Margins_CD, C_DOWN_BUTTON_Y+Y_Margins_CD };
s16 LabelX_Navi=8;
s16 LabelY_Navi=4 - !!CVar_GetS32("gNaviTextFix", 0);
s16 LabelX_Navi=7 + !!CVar_GetS32("gNaviTextFix", 0);
s16 LabelY_Navi=4;
s16 C_Left_BTN_Pos[2]; //(X,Y)
s16 C_Right_BTN_Pos[2];
s16 C_Up_BTN_Pos[2];

View file

@ -7,6 +7,8 @@
#include "../libultraship/ImGuiImpl.h"
#include "soh/frame_interpolation.h"
#include <time.h>
void* D_8012D1F0 = NULL;
//UNK_TYPE D_8012D1F4 = 0; // unused
Input* D_8012D1F8 = NULL;
@ -201,7 +203,8 @@ void GivePlayerRandoRewardSongOfTime(GlobalContext* globalCtx, RandomizerCheck c
!Flags_GetTreasure(globalCtx, 0x1F) && gSaveContext.nextTransition == 0xFF) {
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_SONG_OF_TIME);
GiveItemWithoutActor(globalCtx, getItemId);
Flags_SetTreasure(globalCtx, 0x1F);
player->pendingFlag.flagID = 0x1F;
player->pendingFlag.flagType = FLAG_SCENE_TREASURE;
}
}
@ -695,6 +698,11 @@ void Gameplay_Update(GlobalContext* globalCtx) {
gTrnsnUnkState = 0;
R_UPDATE_RATE = 3;
}
// Don't autosave in grottos or cutscenes
if (CVar_GetS32("gAutosave", 0) && (globalCtx->sceneNum != SCENE_YOUSEI_IZUMI_TATE) && (globalCtx->sceneNum != SCENE_KAKUSIANA) && (gSaveContext.cutsceneIndex == 0)) {
Gameplay_PerformSave(globalCtx);
}
}
globalCtx->sceneLoadFlag = 0;
} else {
@ -1444,6 +1452,18 @@ void Gameplay_Draw(GlobalContext* globalCtx) {
CLOSE_DISPS(gfxCtx);
}
time_t Gameplay_GetRealTime() {
time_t t1, t2;
struct tm* tms;
time(&t1);
tms = localtime(&t1);
tms->tm_hour = 0;
tms->tm_min = 0;
tms->tm_sec = 0;
t2 = mktime(tms);
return t1 - t2;
}
void Gameplay_Main(GameState* thisx) {
GlobalContext* globalCtx = (GlobalContext*)thisx;
@ -1487,6 +1507,20 @@ void Gameplay_Main(GameState* thisx) {
if (1 && HREG(63)) {
LOG_NUM("1", 1);
}
if (CVar_GetS32("gTimeSync", 0)) {
const int maxRealDaySeconds = 86400;
const int maxInGameDayTicks = 65536;
int secs = (int)Gameplay_GetRealTime();
float percent = (float)secs / (float)maxRealDaySeconds;
int newIngameTime = maxInGameDayTicks * percent;
gSaveContext.dayTime = newIngameTime;
}
}
// original name: "Game_play_demo_mode_check"
@ -1943,3 +1977,19 @@ s32 func_800C0DB4(GlobalContext* globalCtx, Vec3f* pos) {
return false;
}
}
void Gameplay_PerformSave(GlobalContext* globalCtx) {
Gameplay_SaveSceneFlags(globalCtx);
gSaveContext.savedSceneNum = globalCtx->sceneNum;
if (gSaveContext.temporaryWeapon) {
gSaveContext.equips.buttonItems[0] = ITEM_NONE;
GET_PLAYER(globalCtx)->currentSwordItem = ITEM_NONE;
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_NONE);
Save_SaveFile();
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI;
GET_PLAYER(globalCtx)->currentSwordItem = ITEM_SWORD_KOKIRI;
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_KOKIRI);
} else {
Save_SaveFile();
}
}

View file

@ -442,62 +442,65 @@ void Sram_OpenSave() {
Save_LoadFile();
switch (gSaveContext.savedSceneNum) {
case SCENE_YDAN:
case SCENE_DDAN:
case SCENE_BDAN:
case SCENE_BMORI1:
case SCENE_HIDAN:
case SCENE_MIZUSIN:
case SCENE_JYASINZOU:
case SCENE_HAKADAN:
case SCENE_HAKADANCH:
case SCENE_ICE_DOUKUTO:
case SCENE_GANON:
case SCENE_MEN:
case SCENE_GERUDOWAY:
case SCENE_GANONTIKA:
gSaveContext.entranceIndex = dungeonEntrances[gSaveContext.savedSceneNum];
break;
case SCENE_YDAN_BOSS:
gSaveContext.entranceIndex = 0;
break;
case SCENE_DDAN_BOSS:
gSaveContext.entranceIndex = 4;
break;
case SCENE_BDAN_BOSS:
gSaveContext.entranceIndex = 0x28;
break;
case SCENE_MORIBOSSROOM:
gSaveContext.entranceIndex = 0x169;
break;
case SCENE_FIRE_BS:
gSaveContext.entranceIndex = 0x165;
break;
case SCENE_MIZUSIN_BS:
gSaveContext.entranceIndex = 0x10;
break;
case SCENE_JYASINBOSS:
gSaveContext.entranceIndex = 0x82;
break;
case SCENE_HAKADAN_BS:
gSaveContext.entranceIndex = 0x37;
break;
case SCENE_GANON_SONOGO:
case SCENE_GANONTIKA_SONOGO:
case SCENE_GANON_BOSS:
case SCENE_GANON_FINAL:
case SCENE_GANON_DEMO:
gSaveContext.entranceIndex = 0x41B;
break;
if (!CVar_GetS32("gRememberSaveLocation", 0) || gSaveContext.savedSceneNum == SCENE_YOUSEI_IZUMI_TATE ||
gSaveContext.savedSceneNum == SCENE_KAKUSIANA) {
switch (gSaveContext.savedSceneNum) {
case SCENE_YDAN:
case SCENE_DDAN:
case SCENE_BDAN:
case SCENE_BMORI1:
case SCENE_HIDAN:
case SCENE_MIZUSIN:
case SCENE_JYASINZOU:
case SCENE_HAKADAN:
case SCENE_HAKADANCH:
case SCENE_ICE_DOUKUTO:
case SCENE_GANON:
case SCENE_MEN:
case SCENE_GERUDOWAY:
case SCENE_GANONTIKA:
gSaveContext.entranceIndex = dungeonEntrances[gSaveContext.savedSceneNum];
break;
case SCENE_YDAN_BOSS:
gSaveContext.entranceIndex = 0;
break;
case SCENE_DDAN_BOSS:
gSaveContext.entranceIndex = 4;
break;
case SCENE_BDAN_BOSS:
gSaveContext.entranceIndex = 0x28;
break;
case SCENE_MORIBOSSROOM:
gSaveContext.entranceIndex = 0x169;
break;
case SCENE_FIRE_BS:
gSaveContext.entranceIndex = 0x165;
break;
case SCENE_MIZUSIN_BS:
gSaveContext.entranceIndex = 0x10;
break;
case SCENE_JYASINBOSS:
gSaveContext.entranceIndex = 0x82;
break;
case SCENE_HAKADAN_BS:
gSaveContext.entranceIndex = 0x37;
break;
case SCENE_GANON_SONOGO:
case SCENE_GANONTIKA_SONOGO:
case SCENE_GANON_BOSS:
case SCENE_GANON_FINAL:
case SCENE_GANON_DEMO:
gSaveContext.entranceIndex = 0x41B;
break;
default:
if (gSaveContext.savedSceneNum != SCENE_LINK_HOME) {
gSaveContext.entranceIndex = (LINK_AGE_IN_YEARS == YEARS_CHILD) ? 0xBB : 0x5F4;
} else {
gSaveContext.entranceIndex = 0xBB;
}
break;
default:
if (gSaveContext.savedSceneNum != SCENE_LINK_HOME) {
gSaveContext.entranceIndex = (LINK_AGE_IN_YEARS == YEARS_CHILD) ? 0xBB : 0x5F4;
} else {
gSaveContext.entranceIndex = 0xBB;
}
break;
}
}
osSyncPrintf("scene_no = %d\n", gSaveContext.entranceIndex);

View file

@ -10,6 +10,7 @@
#include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h"
#include "scenes/indoors/yousei_izumi_yoko/yousei_izumi_yoko_scene.h"
#include "scenes/indoors/daiyousei_izumi/daiyousei_izumi_scene.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5 | ACTOR_FLAG_25)
@ -960,6 +961,7 @@ void BgDyYoseizo_ParticleInit(BgDyYoseizo* this, Vec3f* initPos, Vec3f* initVelo
particle->pitch = 0.0f;
particle->yaw = Rand_CenteredFloat(30000.0f);
particle->roll = 0.0f;
particle->epoch++;
return;
}
}
@ -1039,6 +1041,8 @@ void BgDyYoseizo_ParticleDraw(BgDyYoseizo* this, GlobalContext* globalCtx) {
func_80093D84(globalCtx->state.gfxCtx);
for (i = 0; i < 200; i++, particle++) {
FrameInterpolation_RecordOpenChild(particle, particle->epoch);
if (particle->alive == 1) {
if (phi_s3 == 0) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gGreatFairyParticleAppearDL));
@ -1060,6 +1064,8 @@ void BgDyYoseizo_ParticleDraw(BgDyYoseizo* this, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gGreatFairyParticleAliveDL));
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(gfxCtx);

View file

@ -24,7 +24,8 @@ typedef struct {
/* 0x36 */ f32 pitch;
/* 0x36 */ f32 yaw;
/* 0x40 */ f32 roll;
} BgDyYoseizoParticle; // size = 0x44
/* 0x44 */ s32 epoch;
} BgDyYoseizoParticle; // size = 0x48
typedef struct BgDyYoseizo {
/* 0x0000 */ Actor actor;

View file

@ -1,6 +1,7 @@
#include "z_bg_jya_megami.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
#include "objects/object_jya_obj/object_jya_obj.h"
#include "soh/frame_interpolation.h"
#define FLAGS 0
@ -217,6 +218,7 @@ void BgJyaMegami_SetupExplode(BgJyaMegami* this) {
for (i = 0; i < ARRAY_COUNT(this->pieces); i++) {
Math_Vec3f_Copy(&this->pieces[i].pos, &this->dyna.actor.world.pos);
this->pieces[i].vel.x = sPiecesInit[i].velX;
this->pieces[i].epoch++;
}
this->explosionTimer = 0;
}
@ -326,6 +328,9 @@ void BgJyaMegami_DrawExplode(BgJyaMegami* this, GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(this->pieces); i++) {
piece = &this->pieces[i];
FrameInterpolation_RecordOpenChild(piece, piece->epoch);
Matrix_Translate(piece->pos.x + sPiecesInit[i].unk_00.x, piece->pos.y + sPiecesInit[i].unk_00.y,
piece->pos.z + sPiecesInit[i].unk_00.z, MTXMODE_NEW);
Matrix_RotateY(piece->rotVelY * (M_PI / 0x8000), MTXMODE_APPLY);
@ -337,6 +342,8 @@ void BgJyaMegami_DrawExplode(BgJyaMegami* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, sDLists[i]);
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View file

@ -13,7 +13,8 @@ typedef struct {
/* 0x0C */ Vec3f vel;
/* 0x18 */ s16 rotVelX;
/* 0x1A */ s16 rotVelY;
} BgJyaMegamiPiece; // size = 0x1C
/* 0x1C */ s32 epoch;
} BgJyaMegamiPiece; // size = 0x20
typedef struct BgJyaMegami {
/* 0x0000 */ DynaPolyActor dyna;

View file

@ -7,6 +7,7 @@
#include "z_bg_spot00_hanebasi.h"
#include "objects/object_spot00_objects/object_spot00_objects.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "soh/frame_interpolation.h"
#define FLAGS ACTOR_FLAG_4
@ -260,6 +261,8 @@ void BgSpot00Hanebasi_DrawTorches(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = globalCtx2;
f32 angle;
s32 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -276,6 +279,8 @@ void BgSpot00Hanebasi_DrawTorches(Actor* thisx, GlobalContext* globalCtx2) {
gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0);
for (i = 0; i < 2; i++) {
FrameInterpolation_RecordOpenChild("Hanebasi Torch", epoch + i * 25);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0,
((globalCtx->gameplayFrames + i) * -20) & 0x1FF, 32, 128));
@ -287,6 +292,8 @@ void BgSpot00Hanebasi_DrawTorches(Actor* thisx, GlobalContext* globalCtx2) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffFire1DL);
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View file

@ -2,6 +2,7 @@
#include "objects/object_kingdodongo/object_kingdodongo.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "scenes/dungeons/ddan_boss/ddan_boss_room_1.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -150,6 +151,7 @@ void func_808C17C8(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* ar
for (i = 0; i < arg5; i++, eff++) {
if (eff->unk_24 == 0) {
eff->epoch++;
eff->unk_24 = 1;
eff->unk_00 = *arg1;
eff->unk_0C = *arg2;
@ -1703,6 +1705,7 @@ void BossDodongo_DrawEffects(GlobalContext* globalCtx) {
#endif
for (i = 0; i < 80; i++, eff++) {
FrameInterpolation_RecordOpenChild(eff, eff->epoch);
if (eff->unk_24 == 1) {
gDPPipeSync(POLY_XLU_DISP++);
@ -1719,6 +1722,7 @@ void BossDodongo_DrawEffects(GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, object_kingdodongo_DL_009DD0);
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(gfxCtx);

View file

@ -17,7 +17,8 @@ typedef struct {
/* 0x26 */ Color_RGB8 color;
/* 0x2A */ s16 alpha;
/* 0x2C */ f32 unk_2C;
} BossDodongoEffect; // Size = 0x30
/* 0x30 */ s32 epoch;
} BossDodongoEffect; // Size = 0x34
typedef struct BossDodongo {
/* 0x0000 */ Actor actor;

View file

@ -1835,6 +1835,8 @@ void BossFd_DrawBody(GlobalContext* globalCtx, BossFd* this) {
s16 i;
f32 temp_float;
Mtx* tempMat = Graph_Alloc(globalCtx->state.gfxCtx, 18 * sizeof(Mtx));
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
if (this->skinSegments != 0) {
@ -1876,6 +1878,8 @@ void BossFd_DrawBody(GlobalContext* globalCtx, BossFd* this) {
Matrix_Push();
for (i = 0; i < 18; i++, tempMat++) {
FrameInterpolation_RecordOpenChild(tempMat, epoch + i * 25);
segIndex = (this->work[BFD_LEAD_BODY_SEG] + sBodyIndex[i + 1]) % 100;
Matrix_Translate(this->bodySegsPos[segIndex].x, this->bodySegsPos[segIndex].y, this->bodySegsPos[segIndex].z,
MTXMODE_NEW);
@ -1938,6 +1942,8 @@ void BossFd_DrawBody(GlobalContext* globalCtx, BossFd* this) {
if (i > 0) {
Collider_UpdateSpheres(i + 1, &this->collider);
}
FrameInterpolation_RecordCloseChild();
}
Matrix_Pop();
osSyncPrintf("BH\n");

View file

@ -9,6 +9,7 @@
#include "overlays/actors/ovl_Boss_Fd/z_boss_fd.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "vt.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -1146,6 +1147,8 @@ void BossFd2_UpdateMane(BossFd2* this, GlobalContext* globalCtx, Vec3f* head, Ve
}
for (i = 0; i < 9; i++) {
FrameInterpolation_RecordOpenChild(this, this->epoch + i * 25);
Matrix_Translate((pos + i)->x, (pos + i)->y, (pos + i)->z, MTXMODE_NEW);
Matrix_RotateY((rot + i)->y, MTXMODE_APPLY);
Matrix_RotateX((rot + i)->x, MTXMODE_APPLY);
@ -1155,6 +1158,8 @@ void BossFd2_UpdateMane(BossFd2* this, GlobalContext* globalCtx, Vec3f* head, Ve
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gHoleVolvagiaManeModelDL);
FrameInterpolation_RecordCloseChild();
}
Matrix_Pop();
CLOSE_DISPS(globalCtx->state.gfxCtx);

View file

@ -87,6 +87,7 @@ typedef struct BossFd2 {
/* 0x1394 */ BossFd2Cam camData;
/* 0x141C */ ColliderJntSph collider;
/* 0x143C */ ColliderJntSphElement elements[9];
} BossFd2; // size = 0x167C
/* 0x167C */ s32 epoch;
} BossFd2; // size = 0x1680
#endif

View file

@ -3356,6 +3356,8 @@ void BossGanon_DrawShock(BossGanon* this, GlobalContext* globalCtx) {
s32 pad;
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -3369,6 +3371,8 @@ void BossGanon_DrawShock(BossGanon* this, GlobalContext* globalCtx) {
Player* player = GET_PLAYER(globalCtx);
for (i = 0; i < ARRAY_COUNT(player->bodyPartsPos); i++) {
FrameInterpolation_RecordOpenChild("Ganondorf Shock 0", epoch + i * 25);
Matrix_Translate(player->bodyPartsPos[i].x, player->bodyPartsPos[i].y, player->bodyPartsPos[i].z,
MTXMODE_NEW);
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);
@ -3377,9 +3381,13 @@ void BossGanon_DrawShock(BossGanon* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gDorfSquareDL);
FrameInterpolation_RecordCloseChild();
}
} else {
for (i = 1; i < 15; i++) {
FrameInterpolation_RecordOpenChild("Ganondorf Shock 1", epoch + i * 25);
Matrix_Translate(this->unk_2EC[i].x, this->unk_2EC[i].y, this->unk_2EC[i].z, MTXMODE_NEW);
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);
Matrix_Scale(this->unk_49C[i], this->unk_49C[i], this->unk_49C[i], MTXMODE_APPLY);
@ -3401,6 +3409,8 @@ void BossGanon_DrawShock(BossGanon* this, GlobalContext* globalCtx) {
} else {
gSPDisplayList(POLY_XLU_DISP++, gDorfSquareDL);
}
FrameInterpolation_RecordCloseChild();
}
}
}
@ -3443,9 +3453,9 @@ void BossGanon_DrawHandLightBall(BossGanon* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gDorfLightCoreDL);
CLOSE_DISPS(gfxCtx);
}
CLOSE_DISPS(gfxCtx);
}
void BossGanon_DrawBigMagicCharge(BossGanon* this, GlobalContext* globalCtx) {
@ -3453,6 +3463,8 @@ void BossGanon_DrawBigMagicCharge(BossGanon* this, GlobalContext* globalCtx) {
f32 yRot;
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -3513,6 +3525,8 @@ void BossGanon_DrawBigMagicCharge(BossGanon* this, GlobalContext* globalCtx) {
yRot = BINANG_TO_RAD(this->actor.yawTowardsPlayer);
for (i = 0; i < this->unk_1AC; i++) {
FrameInterpolation_RecordOpenChild("Ganondorf Big Magic", epoch + i * 25);
f32 xzRot = (BossGanon_RandZeroOne() - 0.5f) * M_PI * 1.5f;
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)this->unk_294[i]);
@ -3527,10 +3541,12 @@ void BossGanon_DrawBigMagicCharge(BossGanon* this, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, gDorfLightRayTriDL);
Matrix_Pop();
}
CLOSE_DISPS(gfxCtx);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(gfxCtx);
}
void BossGanon_DrawTriforce(BossGanon* this, GlobalContext* globalCtx) {
@ -4142,6 +4158,8 @@ void BossGanon_LightBall_Draw(Actor* thisx, GlobalContext* globalCtx) {
s16 i;
f32 alpha;
s32 pad;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -4166,6 +4184,8 @@ void BossGanon_LightBall_Draw(Actor* thisx, GlobalContext* globalCtx) {
if (this->unk_1A8 == 1) {
for (i = 0; i < 8; i++) {
FrameInterpolation_RecordOpenChild("Ganondorf Light Ball 0", epoch + i * 25);
Matrix_Push();
Matrix_RotateY(i * (M_PI / 8), MTXMODE_APPLY);
Matrix_RotateZ(this->fwork[GDF_FWORK_0], MTXMODE_APPLY);
@ -4174,6 +4194,8 @@ void BossGanon_LightBall_Draw(Actor* thisx, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, gDorfSquareDL);
Matrix_Pop();
FrameInterpolation_RecordCloseChild();
}
} else if (this->unk_1A8 == 0) {
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);

View file

@ -5,6 +5,7 @@
#include "objects/object_ganon2/object_ganon2.h"
#include "objects/object_ganon_anime3/object_ganon_anime3.h"
#include "objects/object_geff/object_geff.h"
#include "soh/frame_interpolation.h"
#include <string.h>
@ -2463,6 +2464,8 @@ void func_80904340(BossGanon2* this, GlobalContext* globalCtx) {
f32 angle;
f32 sin;
f32 cos;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
Matrix_Push();
@ -2485,6 +2488,7 @@ void func_80904340(BossGanon2* this, GlobalContext* globalCtx) {
rand = BossGanon2_RandZeroOne();
for (i = 0; i < 5; i++) {
FrameInterpolation_RecordOpenChild("Ganon 80904340", epoch + i * 25);
angle = (i * (2 * M_PI / 5)) + (rand * M_PI);
sin = 5000.0f * sinf(angle);
cos = 5000.0f * cosf(angle);
@ -2500,6 +2504,7 @@ void func_80904340(BossGanon2* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_DL_00D798));
FrameInterpolation_RecordCloseChild();
}
}
@ -2632,6 +2637,8 @@ void BossGanon2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLis
void func_80904D88(BossGanon2* this, GlobalContext* globalCtx) {
s32 pad;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -2647,6 +2654,8 @@ void func_80904D88(BossGanon2* this, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00B308);
for (i = 0; i < 15; i++) {
FrameInterpolation_RecordOpenChild("Ganon 80904D88", epoch + i * 25);
Matrix_Translate(this->unk_234[i].x, this->unk_234[i].y, this->unk_234[i].z, MTXMODE_NEW);
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);
Matrix_Scale(this->unk_30C, this->unk_30C, this->unk_30C, MTXMODE_APPLY);
@ -2654,6 +2663,8 @@ void func_80904D88(BossGanon2* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00B378);
FrameInterpolation_RecordCloseChild();
}
}
@ -2690,6 +2701,8 @@ void func_80904FC8(BossGanon2* this, GlobalContext* globalCtx) {
void func_8090523C(BossGanon2* this, GlobalContext* globalCtx) {
Player* player;
f32 phi_f20;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -2703,6 +2716,8 @@ void func_8090523C(BossGanon2* this, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00B308);
for (i = 0; i < 11; i++) {
FrameInterpolation_RecordOpenChild("Ganon 8090523C", epoch + i * 25);
Matrix_Mult(&player->mf_9E0, MTXMODE_NEW);
Matrix_Translate((i * 250.0f) + 900.0f, 350.0f, 0.0f, MTXMODE_APPLY);
@ -2718,6 +2733,8 @@ void func_8090523C(BossGanon2* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(ovl_Boss_Ganon2_DL_00B378));
FrameInterpolation_RecordCloseChild();
}
}
@ -2916,6 +2933,8 @@ void func_809060E8(GlobalContext* globalCtx) {
BossGanon2Effect* effect;
s16 i;
BossGanon2Effect* effects;
static s32 epoch = 0;
epoch++;
effects = effect = globalCtx->specialEffects;
@ -2925,6 +2944,8 @@ void func_809060E8(GlobalContext* globalCtx) {
for (i = 0; i < 1; i++) {
if (effect->type == 1) {
FrameInterpolation_RecordOpenChild("Ganon 809060E8 0", epoch + i * 25);
Vec3f spA0;
f32 temp_f0;
f32 angle;
@ -2958,6 +2979,8 @@ void func_809060E8(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, ovl_Boss_Ganon2_DL_00F188);
FrameInterpolation_RecordCloseChild();
}
}
@ -2965,6 +2988,8 @@ void func_809060E8(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sBossGanon2Particles); i++, effect++) {
if (effect->type == 2) {
FrameInterpolation_RecordOpenChild("Ganon 809060E8 1", epoch + i * 25);
if (!usingObjectGEff) {
BossGanon2_SetObjectSegment(NULL, globalCtx, OBJECT_GEFF, true);
usingObjectGEff++;
@ -2977,6 +3002,8 @@ void func_809060E8(GlobalContext* globalCtx) {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gGanonRubbleDL);
FrameInterpolation_RecordCloseChild();
}
}

View file

@ -348,6 +348,7 @@ void BossMo_Init(Actor* thisx, GlobalContext* globalCtx2) {
globalCtx->specialEffects = sEffects;
for (i = 0; i < ARRAY_COUNT(sEffects); i++) {
sEffects[i].type = MO_FX_NONE;
sEffects[i].epoch++;
}
this->actor.world.pos.x = 200.0f;
this->actor.world.pos.y = MO_WATER_LEVEL(globalCtx) + 50.0f;
@ -2442,6 +2443,8 @@ void BossMo_DrawTentacle(BossMo* this, GlobalContext* globalCtx) {
f32 phi_f20;
f32 phi_f22;
Vec3f sp110;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -2462,6 +2465,8 @@ void BossMo_DrawTentacle(BossMo* this, GlobalContext* globalCtx) {
BossMo_InitRand(1, 29100, 9786);
for (i = 0; i < 41; i++, matrix++) {
FrameInterpolation_RecordOpenChild("Morpha Tentacle", epoch + i * 25);
s32 pad;
s32 pad2;
@ -2559,6 +2564,8 @@ void BossMo_DrawTentacle(BossMo* this, GlobalContext* globalCtx) {
if ((i < 38) && ((i & 1) == 1)) {
BossMo_UpdateTentColliders(this, i / 2, &this->tentCollider, &this->tentPos[i]);
}
FrameInterpolation_RecordCloseChild();
}
Matrix_Pop();

View file

@ -9,6 +9,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_5 | ACTOR_FLAG_10)
@ -2705,6 +2706,8 @@ s32 BossSst_OverrideHandTrailDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx**
void BossSst_DrawHand(Actor* thisx, GlobalContext* globalCtx) {
BossSst* this = (BossSst*)thisx;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -2738,6 +2741,8 @@ void BossSst_DrawHand(Actor* thisx, GlobalContext* globalCtx) {
for (i = 0; i < end; i++) {
if (Math3D_Vec3fDistSq(&trail2->world.pos, &trail->world.pos) > 900.0f) {
FrameInterpolation_RecordOpenChild(trail, 0);
Matrix_SetTranslateRotateYXZ(trail->world.pos.x, trail->world.pos.y, trail->world.pos.z,
&trail->world.rot);
Matrix_Scale(0.02f, 0.02f, 0.02f, MTXMODE_APPLY);
@ -2749,6 +2754,8 @@ void BossSst_DrawHand(Actor* thisx, GlobalContext* globalCtx) {
POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
this->skelAnime.dListCount, BossSst_OverrideHandTrailDraw, NULL,
trail, POLY_XLU_DISP);
FrameInterpolation_RecordCloseChild();
}
idx = (idx + 5) % 7;
trail2 = trail;
@ -2955,6 +2962,8 @@ void BossSst_SpawnHeadShadow(BossSst* this) {
shadow->scale = 1450;
shadow->alpha = 254;
shadow->status = 65;
shadow->epoch++;
}
this->effects[3].status = -1;
@ -2968,6 +2977,7 @@ void BossSst_SpawnHandShadow(BossSst* this) {
this->effects[0].scale = 2300;
this->effects[0].alpha = 254;
this->effects[0].status = 5;
this->effects[0].epoch++;
this->effects[1].status = -1;
}
@ -2981,6 +2991,7 @@ void BossSst_SpawnShockwave(BossSst* this) {
for (i = 0; i < 3; i++) {
BossSstEffect* shockwave = &this->effects[i];
shockwave->epoch++;
Math_Vec3f_Copy(&shockwave->pos, &this->actor.world.pos);
shockwave->move = (i + 9) * 2;
@ -3035,6 +3046,8 @@ void BossSst_SpawnIceCrystal(BossSst* this, s32 index) {
if ((index % 2) == 0) {
Audio_PlayActorSound2(&this->actor, NA_SE_PL_FREEZE_S);
}
ice->epoch++;
}
void BossSst_SpawnIceShard(BossSst* this) {
@ -3050,6 +3063,7 @@ void BossSst_SpawnIceShard(BossSst* this) {
for (i = 0; i < 18; i++) {
BossSstEffect* ice = &this->effects[i];
ice->epoch++;
Math_Vec3f_Copy(&ice->pos, &spawnPos);
ice->status = 1;
@ -3165,6 +3179,8 @@ void BossSst_DrawEffect(Actor* thisx, GlobalContext* globalCtx) {
for (i = 0; i < 18; i++) {
effect = &this->effects[i];
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
if (effect->move) {
func_8003435C(&effect->pos, globalCtx);
if (this->effects[0].status != 0) {
@ -3182,6 +3198,8 @@ void BossSst_DrawEffect(Actor* thisx, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gBongoIceShardDL);
}
FrameInterpolation_RecordCloseChild();
}
} else if (this->effectMode == BONGO_SHOCKWAVE) {
f32 scaleY = 0.005f;
@ -3193,6 +3211,7 @@ void BossSst_DrawEffect(Actor* thisx, GlobalContext* globalCtx) {
for (i = 0; i < 3; i++, scaleY -= 0.001f) {
effect = &this->effects[i];
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
if (effect->move != 0) {
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
@ -3205,6 +3224,8 @@ void BossSst_DrawEffect(Actor* thisx, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffFireCircleDL);
}
FrameInterpolation_RecordCloseChild();
}
} else if (this->effectMode == BONGO_SHADOW) {
gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x80, 10, 10, 80, 0);
@ -3212,12 +3233,16 @@ void BossSst_DrawEffect(Actor* thisx, GlobalContext* globalCtx) {
effect = &this->effects[0];
while (effect->status != -1) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_Scale(effect->scale * 0.001f, 1.0f, effect->scale * 0.001f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, sShadowDList);
FrameInterpolation_RecordCloseChild();
effect++;
}
}

View file

@ -17,7 +17,8 @@ typedef struct {
/* 0x0020 */ s16 move;
/* 0x0022 */ s16 status;
/* 0x0024 */ u8 alpha;
} BossSstEffect; // size = 0x28
/* 0x0028 */ s32 epoch;
} BossSstEffect; // size = 0x2C
typedef struct {
/* 0x0000 */ PosRot world;

View file

@ -2,6 +2,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_tw/object_tw.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "soh/frame_interpolation.h"
#include <string.h>
@ -467,6 +468,7 @@ void BossTw_Init(Actor* thisx, GlobalContext* globalCtx2) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
sTwEffects[i].type = TWEFF_NONE;
sTwEffects[i].epoch++;
}
}
@ -3327,6 +3329,8 @@ void func_80942180(BossTw* this, GlobalContext* globalCtx) {
void func_809426F0(BossTw* this, GlobalContext* globalCtx) {
s32 pad;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -3360,6 +3364,8 @@ void func_809426F0(BossTw* this, GlobalContext* globalCtx) {
}
for (i = 0; i < 8; i++) {
FrameInterpolation_RecordOpenChild("Twinrova 809426F0", epoch + i * 25);
Matrix_Push();
Matrix_Translate(0.0f, 0.0f, 5000.0f, MTXMODE_APPLY);
Matrix_RotateZ(((i * M_PI) * 2.0f * 0.125f) + this->flameRotation, MTXMODE_APPLY);
@ -3373,6 +3379,8 @@ void func_809426F0(BossTw* this, GlobalContext* globalCtx) {
G_MTX_LOAD | G_MTX_MODELVIEW | G_MTX_NOPUSH);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A430));
Matrix_Pop();
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
@ -4410,6 +4418,8 @@ void BossTw_BlastDraw(Actor* thisx, GlobalContext* globalCtx2) {
f32 scaleFactor;
s16 tailIdx;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -4420,6 +4430,8 @@ void BossTw_BlastDraw(Actor* thisx, GlobalContext* globalCtx2) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 200, 20, 0, (s8)this->workf[TAIL_ALPHA]);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 215, 255, 128);
for (i = 9; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Twinrova Fire Blast", epoch + i * 25);
gSPSegment(POLY_XLU_DISP++, 8,
Gfx_TwoTexScroll(
globalCtx->state.gfxCtx, 0, ((this->work[CS_TIMER_1] * 3) + (i * 10)) & 0x7F,
@ -4434,6 +4446,8 @@ void BossTw_BlastDraw(Actor* thisx, GlobalContext* globalCtx2) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A430));
FrameInterpolation_RecordCloseChild();
}
break;
@ -4444,6 +4458,8 @@ void BossTw_BlastDraw(Actor* thisx, GlobalContext* globalCtx2) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, (s8)this->workf[TAIL_ALPHA]);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A998));
for (i = 9; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Twinrova Ice Blast", epoch + i * 25);
gSPSegment(POLY_XLU_DISP++, 8,
Gfx_TwoTexScroll(
globalCtx->state.gfxCtx, 0, ((this->work[CS_TIMER_1] * 3) + (i * 0xA)) & 0x7F,
@ -4458,6 +4474,8 @@ void BossTw_BlastDraw(Actor* thisx, GlobalContext* globalCtx2) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01AB00));
FrameInterpolation_RecordCloseChild();
}
break;
@ -4474,6 +4492,8 @@ void BossTw_DrawDeathBall(Actor* thisx, GlobalContext* globalCtx2) {
f32 scaleFactor;
s16 tailIdx;
s16 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -4484,6 +4504,8 @@ void BossTw_DrawDeathBall(Actor* thisx, GlobalContext* globalCtx2) {
gDPSetEnvColor(POLY_XLU_DISP++, 255, 215, 255, 128);
for (i = 9; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Twinrova Death Ball 0", epoch + i * 25);
gSPSegment(POLY_XLU_DISP++, 8,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (((this->work[CS_TIMER_1] * 3) + (i * 0xA))) & 0x7F,
(u8)((-this->work[CS_TIMER_1] * 0xF) + (i * 50)), 0x20, 0x40, 1, 0, 0, 0x20,
@ -4498,12 +4520,16 @@ void BossTw_DrawDeathBall(Actor* thisx, GlobalContext* globalCtx2) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A430));
FrameInterpolation_RecordCloseChild();
}
} else {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, (s8)this->workf[TAIL_ALPHA]);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A998));
for (i = 9; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Twinrova Death Ball 1", epoch + i * 25);
gSPSegment(POLY_XLU_DISP++, 8,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (((this->work[CS_TIMER_1] * 3) + (i * 0xA))) & 0x7F,
(u8)((-this->work[CS_TIMER_1] * 0xF) + (i * 50)), 0x20, 0x40, 1, 0, 0, 0x20,
@ -4518,6 +4544,8 @@ void BossTw_DrawDeathBall(Actor* thisx, GlobalContext* globalCtx2) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01AB00));
FrameInterpolation_RecordCloseChild();
}
}
@ -4883,6 +4911,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
if (currentEffect->type == 1) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (sp18F == 0) {
gSPDisplayList(POLY_XLU_DISP++, object_tw_DL_01A528);
sp18F++;
@ -4896,8 +4926,9 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, object_tw_DL_01A5A8);
}
FrameInterpolation_RecordCloseChild();
}
currentEffect++;
}
@ -4906,6 +4937,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
if (currentEffect->type == 3) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (sp18F == 0) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A998));
sp18F++;
@ -4921,6 +4954,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01AB00));
FrameInterpolation_RecordCloseChild();
}
currentEffect++;
}
@ -4930,6 +4965,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
if (currentEffect->type == 2) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (sp18F == 0) {
gDPPipeSync(POLY_XLU_DISP++);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 215, 255, 128);
@ -4946,6 +4983,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A430));
FrameInterpolation_RecordCloseChild();
}
currentEffect++;
@ -4956,6 +4995,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
if (currentEffect->type == 4) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (sp18F == 0) {
sp18F++;
}
@ -4991,6 +5032,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
gDPSetRenderMode(POLY_XLU_DISP++, G_RM_PASS, G_RM_AA_ZB_XLU_SURF2);
gSPClearGeometryMode(POLY_XLU_DISP++, G_CULL_BACK | G_FOG);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A790));
FrameInterpolation_RecordCloseChild();
}
currentEffect++;
@ -5004,6 +5047,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
Vec3f off;
if (currentEffect->type == TWEFF_PLYR_FRZ) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (sp18F == 0) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01AA50));
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, 255);
@ -5037,6 +5082,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01AB00));
}
FrameInterpolation_RecordCloseChild();
}
currentEffect++;
@ -5047,6 +5094,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(sTwEffects); i++) {
if (currentEffect->type >= 6) {
FrameInterpolation_RecordOpenChild(currentEffect, currentEffect->epoch);
if (currentEffect->work[EFF_ARGS] == 0) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, currentEffect->alpha);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A998));
@ -5070,6 +5119,8 @@ void BossTw_DrawEffects(GlobalContext* globalCtx) {
} else {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(object_tw_DL_01A430));
}
FrameInterpolation_RecordCloseChild();
}
currentEffect++;

View file

@ -43,6 +43,7 @@ typedef struct {
/* 0x002E */ s16 work[EFF_WORK_MAX];
/* 0x0034 */ f32 workf[EFF_FWORK_MAX];
/* 0x0044 */ Actor* target;
s32 epoch;
} BossTwEffect;
typedef enum {

View file

@ -4006,6 +4006,8 @@ void BossVa_DrawDoor(GlobalContext* globalCtx, s16 scale) {
f32 yScale;
f32 segAngle = 0.0f;
s32 i;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -4023,6 +4025,8 @@ void BossVa_DrawDoor(GlobalContext* globalCtx, s16 scale) {
Matrix_Get(&doorMtx);
for (i = 0; i < 8; i++, segAngle -= M_PI / 4) {
FrameInterpolation_RecordOpenChild("Barinade Door", epoch + i * 25);
Matrix_Put(&doorMtx);
Matrix_RotateZ(segAngle, MTXMODE_APPLY);
Matrix_Translate(0.0f, doorPieceLength[i] * yScale, 0.0f, MTXMODE_APPLY);
@ -4030,6 +4034,8 @@ void BossVa_DrawDoor(GlobalContext* globalCtx, s16 scale) {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, doorPieceDispList[i]);
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View file

@ -10,6 +10,7 @@
#include "objects/object_demo_6k/object_demo_6k.h"
#include "objects/object_gnd_magic/object_gnd_magic.h"
#include "overlays/actors/ovl_Eff_Dust/z_eff_dust.h"
#include "soh/frame_interpolation.h"
#define FLAGS ACTOR_FLAG_4
@ -563,9 +564,10 @@ void func_80967FFC(Actor* thisx, GlobalContext* globalCtx) {
Demo6K* this = (Demo6K*)thisx;
s32 pad;
u16 timer1 = this->timer1;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
func_80093D84(globalCtx->state.gfxCtx);
Matrix_RotateX(-M_PI / 2, MTXMODE_APPLY);
gSPSegment(POLY_XLU_DISP++, 0x08,
@ -584,6 +586,8 @@ void func_80967FFC(Actor* thisx, GlobalContext* globalCtx) {
Matrix_RotateZ(-M_PI / 2, MTXMODE_APPLY);
for (i = 0; i < 6; i++) {
FrameInterpolation_RecordOpenChild("Demo6K 80967FFC", epoch + i * 25);
Matrix_RotateZ(M_PI / 3, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
@ -591,6 +595,8 @@ void func_80967FFC(Actor* thisx, GlobalContext* globalCtx) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, colors[i][0].r, colors[i][0].g, colors[i][0].b, 255);
gDPSetEnvColor(POLY_XLU_DISP++, colors[i][1].r, colors[i][1].g, colors[i][1].b, 255);
gSPDisplayList(POLY_XLU_DISP++, object_demo_6k_DL_0022B0);
FrameInterpolation_RecordCloseChild();
}
// required to avoid optimizing out i
@ -689,6 +695,8 @@ void func_809688C4(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = globalCtx2;
u32 frames = globalCtx->state.frames;
s32 i;
static s32 epoch = 0;
epoch++;
if ((i = (globalCtx->csCtx.state != CS_STATE_IDLE) && (globalCtx->csCtx.npcActions[1] != NULL)) &&
(globalCtx->csCtx.npcActions[1]->action != 1)) {
@ -699,6 +707,8 @@ void func_809688C4(Actor* thisx, GlobalContext* globalCtx2) {
Matrix_RotateY((s16)(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) + 0x8000) * (M_PI / 0x8000), MTXMODE_APPLY);
for (i = 0; i < 16; i++) {
FrameInterpolation_RecordOpenChild("Demo6K 809688C4", epoch + i * 25);
gDPPipeSync(POLY_XLU_DISP++);
gDPSetEnvColor(POLY_XLU_DISP++, sEnvColors[this->unk_274[i]].r, sEnvColors[this->unk_274[i]].g,
sEnvColors[this->unk_274[i]].b, 255);
@ -712,6 +722,8 @@ void func_809688C4(Actor* thisx, GlobalContext* globalCtx2) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffFlash1DL);
Matrix_Pop();
FrameInterpolation_RecordCloseChild();
}
gSPDisplayList(POLY_XLU_DISP++, gEffFlash1DL);

View file

@ -3,6 +3,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_efc_star_field/object_efc_star_field.h"
#include "objects/object_toki_objects/object_toki_objects.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -521,6 +522,8 @@ void DemoKankyo_DrawRain(Actor* thisx, GlobalContext* globalCtx) {
f32 translateY;
f32 translateZ;
s16 j;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -594,6 +597,8 @@ void DemoKankyo_DrawRain(Actor* thisx, GlobalContext* globalCtx) {
Matrix_Scale(sRainScale * 0.001f, sRainScale * 0.001f, sRainScale * 0.001f, MTXMODE_APPLY);
for (j = 0; j < 5; j++) {
FrameInterpolation_RecordOpenChild("Kankyo Rain", epoch + i * j * 25);
s32 pad1;
if (globalCtx->sceneNum != SCENE_TOKINOMA) {
@ -623,6 +628,8 @@ void DemoKankyo_DrawRain(Actor* thisx, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x14);
gSPDisplayList(POLY_XLU_DISP++, object_efc_star_field_DL_000080);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
@ -656,10 +663,14 @@ void DemoKankyo_DrawClouds(Actor* thisx, GlobalContext* globalCtx) {
f32 dx;
f32 dy;
f32 dz;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
for (i = 0; i < 30; i++) {
FrameInterpolation_RecordOpenChild("Kankyo Clouds", epoch + i * 25);
dx = -(Math_SinS(this->unk_150[i].unk_20 - 0x8000) * 120.0f) * (30.0f + (i / 30.0f) * 10.0f);
dy = Math_CosS(this->unk_150[i].unk_20 - 0x8000) * 5.0f + 1200.0f;
dz = (Math_CosS(this->unk_150[i].unk_20 - 0x8000) * 120.0f) * (30.0f + (i / 30.0f) * 10.0f);
@ -681,6 +692,8 @@ void DemoKankyo_DrawClouds(Actor* thisx, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, SEG_ADDR(1, 0), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffDustDL);
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
@ -771,6 +784,8 @@ void DemoKankyo_DrawWarpSparkles(Actor* thisx, GlobalContext* globalCtx) {
f32 translateZ;
PosRot posRot;
u8 linkAge = gSaveContext.linkAge;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -778,6 +793,8 @@ void DemoKankyo_DrawWarpSparkles(Actor* thisx, GlobalContext* globalCtx) {
this->sparkleCounter += 2;
}
for (i = this->sparkleCounter - 1; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Kankyo Warp Sparkles", epoch + i * 25);
temp_f22 = 1.0f - (i / (f32)this->sparkleCounter);
switch (this->unk_150[i].unk_22) {
@ -891,6 +908,8 @@ void DemoKankyo_DrawWarpSparkles(Actor* thisx, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, disp);
this->unk_150[i].unk_24 += 0x190;
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
@ -914,6 +933,8 @@ void DemoKankyo_DrawSparkles(Actor* thisx, GlobalContext* globalCtx) {
f32 scale;
s16 i;
PosRot posRot;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -922,6 +943,8 @@ void DemoKankyo_DrawSparkles(Actor* thisx, GlobalContext* globalCtx) {
}
for (i = this->sparkleCounter - 1; i >= 0; i--) {
FrameInterpolation_RecordOpenChild("Kankyo Sparkles", epoch + i * 25);
temp_f20 = 1.0f - (i / (f32)this->sparkleCounter);
switch (this->unk_150[i].unk_22) {
@ -993,6 +1016,8 @@ void DemoKankyo_DrawSparkles(Actor* thisx, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, gEffFlash1DL);
this->unk_150[i].unk_24 += 0x190;
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View file

@ -1,5 +1,6 @@
#include "z_efc_erupc.h"
#include "objects/object_efc_erupc/object_efc_erupc.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -167,6 +168,8 @@ void EfcErupc_DrawParticles(EfcErupcParticles* particles, GlobalContext* globalC
OPEN_DISPS(gfxCtx);
for (i = 0; i < EFC_ERUPC_NUM_PARTICLES; i++, particles++) {
FrameInterpolation_RecordOpenChild(particles, particles->epoch);
if (particles->isActive) {
func_80093D84(globalCtx->state.gfxCtx);
gSPDisplayList(POLY_XLU_DISP++, object_efc_erupc_DL_002760);
@ -181,7 +184,10 @@ void EfcErupc_DrawParticles(EfcErupcParticles* particles, GlobalContext* globalC
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, object_efc_erupc_DL_0027D8);
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(gfxCtx);
}
@ -249,5 +255,6 @@ void EfcErupc_InitParticles(EfcErupcParticles* particles) {
for (i = 0; i < EFC_ERUPC_NUM_PARTICLES; i++, particles++) {
particles->isActive = false;
particles->epoch++;
}
}

View file

@ -19,7 +19,8 @@ typedef struct {
/* 0x30 */ char unk_2C[4];
/* 0x34 */ f32 scale;
/* 0x38 */ char unk_34[8];
} EfcErupcParticles; // size 0x3C
/* 0x3C */ s32 epoch;
} EfcErupcParticles; // size 0x40
#define EFC_ERUPC_NUM_PARTICLES 100

View file

@ -6,6 +6,7 @@
#include "z_eff_dust.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -268,6 +269,8 @@ void EffDust_DrawFunc_8099E4F4(Actor* thisx, GlobalContext* globalCtx2) {
f32* distanceTraveled;
s32 i;
f32 aux;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -283,6 +286,8 @@ void EffDust_DrawFunc_8099E4F4(Actor* thisx, GlobalContext* globalCtx2) {
gSPSegment(POLY_XLU_DISP++, 0x08, sEmptyDL);
for (i = 0; i < 64; i++) {
FrameInterpolation_RecordOpenChild("Dust 8099E4F4", epoch + i * 25);
if (*distanceTraveled < 1.0f) {
aux = 1.0f - (*distanceTraveled * *distanceTraveled);
Matrix_Translate(this->actor.world.pos.x + (initialPositions->x * ((this->dx * aux) + (1.0f - this->dx))),
@ -298,6 +303,8 @@ void EffDust_DrawFunc_8099E4F4(Actor* thisx, GlobalContext* globalCtx2) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gEffSparklesDL));
}
FrameInterpolation_RecordCloseChild();
initialPositions++;
distanceTraveled++;
}
@ -314,6 +321,8 @@ void EffDust_DrawFunc_8099E784(Actor* thisx, GlobalContext* globalCtx2) {
s32 i;
f32 aux;
Player* player = GET_PLAYER(globalCtx);
static s32 epoch = 0;
epoch++;
OPEN_DISPS(gfxCtx);
@ -333,6 +342,8 @@ void EffDust_DrawFunc_8099E784(Actor* thisx, GlobalContext* globalCtx2) {
gSPSegment(POLY_XLU_DISP++, 0x08, sEmptyDL);
for (i = 0; i < 64; i++) {
FrameInterpolation_RecordOpenChild("Dust 8099E784", epoch + i * 25);
if (*distanceTraveled < 1.0f) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, *distanceTraveled * 255);
@ -357,6 +368,8 @@ void EffDust_DrawFunc_8099E784(Actor* thisx, GlobalContext* globalCtx2) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gEffSparklesDL));
}
FrameInterpolation_RecordCloseChild();
initialPositions++;
distanceTraveled++;
}

View file

@ -7,6 +7,7 @@
#include "z_en_anubice_fire.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_anubice/object_anubice.h"
#include "soh/frame_interpolation.h"
#define FLAGS ACTOR_FLAG_4
@ -62,6 +63,7 @@ void EnAnubiceFire_Init(Actor* thisx, GlobalContext* globalCtx) {
this->unk_15A = 30;
this->unk_154 = 2.0f;
this->scale = 0.0f;
this->epoch++;
for (i = 0; i < 6; i++) {
this->unk_160[i] = this->actor.world.pos;
@ -230,6 +232,8 @@ void EnAnubiceFire_Draw(Actor* thisx, GlobalContext* globalCtx) {
Matrix_Push();
for (i = this->unk_15E; i < 6; ++i) {
FrameInterpolation_RecordOpenChild(this, this->epoch + i * 25);
f32 scale = this->actor.scale.x - (i * 0.2f);
if (scale < 0.0f) {
@ -248,6 +252,8 @@ void EnAnubiceFire_Draw(Actor* thisx, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, gAnubiceFireAttackDL);
}
FrameInterpolation_RecordCloseChild();
if (this->scale < 0.1f) {
break;
}

View file

@ -19,6 +19,7 @@ typedef struct EnAnubiceFire {
/* 0x015E */ s16 unk_15E;
/* 0x0178 */ Vec3f unk_160[6];
/* 0x01A8 */ ColliderCylinder cylinder;
} EnAnubiceFire; // size = 0x01F4
/* 0x01F4 */ s32 epoch;
} EnAnubiceFire; // size = 0x01F8
#endif

View file

@ -6,6 +6,7 @@
#include "z_en_ba.h"
#include "objects/object_bxa/object_bxa.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4)
@ -107,6 +108,7 @@ void EnBa_Init(Actor* thisx, GlobalContext* globalCtx) {
this->actor.targetMode = 4;
this->upperParams = (thisx->params >> 8) & 0xFF;
thisx->params &= 0xFF;
this->epoch++;
if (this->actor.params < EN_BA_DEAD_BLOB) {
if (Flags_GetSwitch(globalCtx, this->upperParams)) {
@ -489,6 +491,8 @@ void EnBa_Draw(Actor* thisx, GlobalContext* globalCtx) {
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 16, 16, 1, 0,
(globalCtx->gameplayFrames * -10) % 128, 32, 32));
for (i = 0; i < 14; i++, mtx++) {
FrameInterpolation_RecordOpenChild(this, this->epoch + i * 25);
Matrix_Translate(this->unk158[i].x, this->unk158[i].y, this->unk158[i].z, MTXMODE_NEW);
Matrix_RotateZYX(this->unk2A8[i].x, this->unk2A8[i].y, this->unk2A8[i].z, MTXMODE_APPLY);
Matrix_Scale(this->unk200[i].x, this->unk200[i].y, this->unk200[i].z, MTXMODE_APPLY);
@ -504,6 +508,8 @@ void EnBa_Draw(Actor* thisx, GlobalContext* globalCtx) {
}
}
MATRIX_TOMTX(mtx);
FrameInterpolation_RecordCloseChild();
}
Matrix_Pop();
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),

View file

@ -32,6 +32,7 @@ typedef struct EnBa {
/* 0x031C */ s16 unk31C;
/* 0x0320 */ ColliderJntSph collider;
/* 0x0340 */ ColliderJntSphElement colliderItems[2];
} EnBa; // size = 0x03C0
/* 0x03C0 */ s32 epoch;
} EnBa; // size = 0x03C4
#endif

View file

@ -6,6 +6,7 @@
#include "z_en_bx.h"
#include "objects/object_bxa/object_bxa.h"
#include "soh/frame_interpolation.h"
#define FLAGS ACTOR_FLAG_4
@ -103,6 +104,7 @@ void EnBx_Init(Actor* thisx, GlobalContext* globalCtx) {
Actor_Kill(&this->actor);
}
thisx->params &= 0xFF;
this->epoch++;
}
void EnBx_Destroy(Actor* thisx, GlobalContext* globalCtx) {
@ -235,10 +237,14 @@ void EnBx_Draw(Actor* thisx, GlobalContext* globalCtx) {
}
for (i = 0; i < 4; i++, mtx++) {
FrameInterpolation_RecordOpenChild(this, this->epoch + i * 25);
Matrix_Translate(this->unk_154[i].x, this->unk_154[i].y, this->unk_154[i].z, MTXMODE_NEW);
Matrix_RotateZYX(this->unk_1B4[i].x, this->unk_1B4[i].y, this->unk_1B4[i].z, MTXMODE_APPLY);
Matrix_Scale(this->unk_184[i].x, this->unk_184[i].y, this->unk_184[i].z, MTXMODE_APPLY);
MATRIX_TOMTX(mtx);
FrameInterpolation_RecordCloseChild();
}
gSPDisplayList(POLY_OPA_DISP++, object_bxa_DL_0022F0);

View file

@ -16,6 +16,7 @@ typedef struct EnBx {
/* 0x01B4 */ Vec3s unk_1B4[4];
/* 0x01CC */ ColliderCylinder collider;
/* 0x0218 */ ColliderQuad colliderQuad;
} EnBx; // size = 0x0298
/* 0x0298 */ s32 epoch;
} EnBx; // size = 0x029C
#endif

View file

@ -2,6 +2,8 @@
#include <string.h>
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx);
@ -278,6 +280,7 @@ void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx) {
globalCtx->specialEffects = &sClearTagEffects[0];
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++) {
sClearTagEffects[i].type = CLEAR_TAG_EFFECT_AVAILABLE;
sClearTagEffects[i].epoch++;
}
this->drawMode = CLEAR_TAG_DRAW_MODE_ALL;
}
@ -902,6 +905,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
// Draw all Debris effects.
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++, effect++) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
if (effect->type == CLEAR_TAG_EFFECT_DEBRIS) {
// Apply the debris effect material if it has not already been applied.
if (!isMaterialApplied) {
@ -918,6 +923,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gArwingDebrisEffectDL);
}
FrameInterpolation_RecordCloseChild();
}
// Draw all ground flash effects.
@ -925,6 +932,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
isMaterialApplied = false;
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++, effect++) {
if (effect->type == CLEAR_TAG_EFFECT_FLASH) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
// Apply the flash ground effect material if it has not already been applied.
if (!isMaterialApplied) {
gDPPipeSync(POLY_XLU_DISP++);
@ -941,6 +950,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gArwingFlashEffectGroundDL);
FrameInterpolation_RecordCloseChild();
}
}
@ -949,6 +960,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
isMaterialApplied = false;
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++, effect++) {
if (effect->type == CLEAR_TAG_EFFECT_SMOKE) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
// Apply the smoke effect material if it has not already been applied.
if (!isMaterialApplied) {
gSPDisplayList(POLY_XLU_DISP++, gArwingFireEffectMaterialDL);
@ -970,6 +983,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gArwingFireEffectDL);
FrameInterpolation_RecordCloseChild();
}
}
@ -978,6 +993,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
isMaterialApplied = false;
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++, effect++) {
if (effect->type == CLEAR_TAG_EFFECT_FIRE) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
// Apply the fire effect material if it has not already been applied.
if (!isMaterialApplied) {
gSPDisplayList(POLY_XLU_DISP++, gArwingFireEffectMaterialDL);
@ -996,6 +1013,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gArwingFireEffectDL);
FrameInterpolation_RecordCloseChild();
}
}
@ -1004,6 +1023,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
isMaterialApplied = false;
for (i = 0; i < CLEAR_TAG_EFFECT_MAX_COUNT; i++, effect++) {
if (effect->type == CLEAR_TAG_EFFECT_FLASH) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
// Apply the flash billboard effect material if it has not already been applied.
if (!isMaterialApplied) {
gDPPipeSync(POLY_XLU_DISP++);
@ -1019,6 +1040,8 @@ void EnClearTag_DrawEffects(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gArwingFlashEffectDL);
FrameInterpolation_RecordCloseChild();
}
}

View file

@ -88,7 +88,8 @@ typedef struct EnClearTagEffect {
/* 0x0058 */ f32 rotationX;
/* 0x005C */ f32 floorHeight;
/* 0x0060 */ Vec3f floorTangent;
} EnClearTagEffect; // size = 0x6C
/* 0x006C */ s32 epoch;
} EnClearTagEffect; // size = 0x70
#define CLEAR_TAG_EFFECT_MAX_COUNT 100

View file

@ -2,6 +2,7 @@
#include "overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.h"
#include "vt.h"
#include "objects/object_efc_star_field/object_efc_star_field.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -303,6 +304,7 @@ void EnEncount2_ParticleInit(EnEncount2* this, Vec3f* particlePos, f32 scale) {
particle->moveDirection.y = -20.0f;
particle->moveDirection.z = Rand_CenteredFloat(20.0f);
particle->isAlive = 1;
particle->epoch++;
break;
}
}
@ -354,6 +356,8 @@ void EnEncount2_ParticleDraw(Actor* thisx, GlobalContext* globalCtx) {
gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[objBankIndex].segment);
for (i = 0; i < ARRAY_COUNT(this->particles); particle++, i++) {
FrameInterpolation_RecordOpenChild(particle, particle->epoch);
if (particle->isAlive) {
Matrix_Translate(particle->pos.x, particle->pos.y, particle->pos.z, MTXMODE_NEW);
Matrix_RotateX(particle->rot.x * (M_PI / 180.0f), MTXMODE_APPLY);
@ -366,6 +370,8 @@ void EnEncount2_ParticleDraw(Actor* thisx, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, object_efc_star_field_DL_000DE0);
}
FrameInterpolation_RecordCloseChild();
}
}

View file

@ -14,7 +14,8 @@ typedef struct {
/* 0x0010 */ u8 isAlive;
/* 0x0014 */ Vec3f moveDirection;
/* 0x0020 */ Vec3f rot;
} EnEncount2Particle; // size = 0x2C
/* 0x002C */ s32 epoch;
} EnEncount2Particle; // size = 0x30
typedef struct EnEncount2 {
/* 0x0000 */ Actor actor;

View file

@ -7,6 +7,7 @@
#include "z_en_fd.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_fw/object_fw.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_9)
@ -812,6 +813,7 @@ void EnFd_AddEffect(EnFd* this, u8 type, Vec3f* pos, Vec3f* velocity, Vec3f* acc
eff->color.a = 255;
eff->timer = (s16)(Rand_ZeroOne() * 10.0f);
}
eff->epoch++;
return;
}
}
@ -886,6 +888,8 @@ void EnFd_DrawFlames(EnFd* this, GlobalContext* globalCtx) {
func_80093D84(globalCtx->state.gfxCtx);
for (i = 0; i < ARRAY_COUNT(this->effects); i++, eff++) {
if (eff->type == FD_EFFECT_FLAME) {
FrameInterpolation_RecordOpenChild(eff, eff->epoch);
if (!firstDone) {
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerDL_7928);
@ -902,8 +906,11 @@ void EnFd_DrawFlames(EnFd* this, GlobalContext* globalCtx) {
idx = eff->timer * (8.0f / eff->initialTimer);
gSPSegment(POLY_XLU_DISP++, 0x8, SEGMENTED_TO_VIRTUAL(dustTextures[idx]));
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerSquareParticleDL);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
@ -919,6 +926,8 @@ void EnFd_DrawDots(EnFd* this, GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(this->effects); i++, eff++) {
if (eff->type == FD_EFFECT_DOT) {
FrameInterpolation_RecordOpenChild(eff, eff->epoch);
if (!firstDone) {
func_80093D84(globalCtx->state.gfxCtx);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerDL_79F8);
@ -933,6 +942,8 @@ void EnFd_DrawDots(EnFd* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerTriangleParticleDL);
FrameInterpolation_RecordCloseChild();
}
}

View file

@ -25,6 +25,7 @@ typedef struct {
/* 0x0014 */ Vec3f pos;
/* 0x0020 */ Vec3f velocity;
/* 0x002C */ Vec3f accel;
s32 epoch;
} EnFdEffect; // size = 0x38
typedef struct EnFd {

View file

@ -8,6 +8,7 @@
#include "objects/object_fw/object_fw.h"
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_9)
@ -421,6 +422,7 @@ void EnFw_AddDust(EnFw* this, Vec3f* initialPos, Vec3f* initialSpeed, Vec3f* acc
eff->pos = *initialPos;
eff->accel = *accel;
eff->velocity = *initialSpeed;
eff->epoch++;
return;
}
}
@ -464,6 +466,8 @@ void EnFw_DrawDust(EnFw* this, GlobalContext* globalCtx) {
func_80093D84(globalCtx->state.gfxCtx);
for (i = 0; i < ARRAY_COUNT(this->effects); i++, eff++) {
FrameInterpolation_RecordOpenChild(eff, eff->epoch);
if (eff->type != 0) {
if (!firstDone) {
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0U);
@ -484,6 +488,8 @@ void EnFw_DrawDust(EnFw* this, GlobalContext* globalCtx) {
gSPSegment(POLY_XLU_DISP++, 0x8, SEGMENTED_TO_VIRTUAL(dustTextures[idx]));
gSPDisplayList(POLY_XLU_DISP++, gFlareDancerSquareParticleDL);
}
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View file

@ -19,6 +19,7 @@ typedef struct {
/* 0x0014 */ Vec3f pos;
/* 0x0020 */ Vec3f velocity;
/* 0x002C */ Vec3f accel;
s32 epoch;
} EnFwEffect;
typedef struct EnFw {

View file

@ -1,5 +1,6 @@
#include "z_en_fz.h"
#include "objects/object_fz/object_fz.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_10)
@ -756,6 +757,7 @@ void EnFz_SpawnIceSmokeNoFreeze(EnFz* this, Vec3f* pos, Vec3f* velocity, Vec3f*
iceSmoke->xyScale = xyScale / 1000.0f;
iceSmoke->primAlpha = 0;
iceSmoke->timer = 0;
iceSmoke->epoch++;
break;
}
@ -780,6 +782,7 @@ void EnFz_SpawnIceSmokeFreeze(EnFz* this, Vec3f* pos, Vec3f* velocity, Vec3f* ac
iceSmoke->primAlpha = primAlpha;
iceSmoke->timer = 0;
iceSmoke->isTimerMod8 = isTimerMod8;
iceSmoke->epoch++;
break;
}
@ -864,6 +867,8 @@ void EnFz_DrawIceSmoke(EnFz* this, GlobalContext* globalCtx) {
func_80093D84(globalCtx->state.gfxCtx);
for (i = 0; i < ARRAY_COUNT(this->iceSmoke); i++) {
FrameInterpolation_RecordOpenChild(iceSmoke, iceSmoke->epoch);
if (iceSmoke->type > 0) {
gDPPipeSync(POLY_XLU_DISP++);
@ -884,6 +889,8 @@ void EnFz_DrawIceSmoke(EnFz* this, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gFreezardSteamDL));
}
FrameInterpolation_RecordCloseChild();
iceSmoke++;
}

View file

@ -21,6 +21,7 @@ typedef struct {
/* 0x0030 */ f32 xyScale; //
/* 0x0034 */ f32 xyScaleTarget;
/* 0x0038 */ u8 isTimerMod8; // conditional, used to run CollisionCheck_SetAT
s32 epoch;
} EnFzEffectSsIceSmoke; // size = 0x3C
typedef struct EnFz {

View file

@ -12,6 +12,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_tsubo/object_tsubo.h"
#include "objects/object_gi_rupy/object_gi_rupy.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -533,6 +534,7 @@ void EnGSwitch_SpawnEffects(EnGSwitch* this, Vec3f* pos, s16 scale, s16 colorIdx
f32 pitch;
f32 yaw;
effect->epoch++;
effect->pos = *pos;
effect->scale = scale;
effect->colorIdx = colorIdx;
@ -590,6 +592,7 @@ void EnGSwitch_DrawEffects(EnGSwitch* this, GlobalContext* globalCtx) {
func_80093D18(globalCtx->state.gfxCtx);
for (i = 0; i < this->numEffects; i++, effect++) {
if (effect->flag) {
FrameInterpolation_RecordOpenChild(effect, effect->epoch);
scale = effect->scale / 10000.0f;
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
@ -600,6 +603,7 @@ void EnGSwitch_DrawEffects(EnGSwitch* this, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sRupeeTextures[effect->colorIdx]));
gSPDisplayList(POLY_OPA_DISP++, gRupeeDL);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(gfxCtx);

View file

@ -32,6 +32,7 @@ typedef struct {
/* 0x12 */ u8 flag;
/* 0x14 */ Vec3f velocity;
/* 0x20 */ Vec3f rot;
s32 epoch;
} EnGSwitchEffect; // size = 0x2C
typedef struct EnGSwitch {

View file

@ -6,6 +6,7 @@
#include "z_en_gb.h"
#include "objects/object_ps/object_ps.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3)
@ -184,6 +185,7 @@ void EnGb_Init(Actor* thisx, GlobalContext* globalCtx) {
this->actionTimer = (s16)Rand_ZeroFloat(100.0f) + 100;
for (i = 0; i < ARRAY_COUNT(sCagedSoulPositions); i++) {
this->cagedSouls[i].epoch++;
this->cagedSouls[i].infoIdx = (s32)Rand_ZeroFloat(30.0f) % 3;
this->cagedSouls[i].unk_14.x = this->cagedSouls[i].translation.x =
sCagedSoulPositions[i].x + this->dyna.actor.world.pos.x;
@ -524,6 +526,7 @@ void EnGb_DrawCagedSouls(EnGb* this, GlobalContext* globalCtx) {
for (i = 0; i < 4; i++) {
s32 idx = this->cagedSouls[i].infoIdx;
FrameInterpolation_RecordOpenChild(&this->cagedSouls[i], this->cagedSouls[i].epoch);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0,
(u32)(sCagedSoulInfo[idx].timerMultiplier * this->frameTimer) % 512, 32, 128));
@ -548,6 +551,7 @@ void EnGb_DrawCagedSouls(EnGb* this, GlobalContext* globalCtx) {
gSPDisplayList(POLY_XLU_DISP++, gPoeSellerCagedSoulDL);
Matrix_Pop();
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View file

@ -27,6 +27,7 @@ typedef struct {
/* 0x20 */ f32 unk_20;
/* 0x24 */ f32 unk_24;
/* 0x28 */ f32 unk_28;
s32 epoch;
} EnGbCagedSoul; // size = 0x2C
typedef struct EnGb {

View file

@ -2,6 +2,7 @@
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_oF1d_map/object_oF1d_map.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -1133,11 +1134,9 @@ void EnGo_Draw(Actor* thisx, GlobalContext* globalCtx) {
if (this->actionFunc == EnGo_CurledUp) {
EnGo_DrawCurledUp(this, globalCtx);
return; // needed for match?
} else if (this->actionFunc == EnGo_GoronLinkRolling || this->actionFunc == func_80A3FEB4 ||
this->actionFunc == EnGo_StopRolling || this->actionFunc == func_80A3FEB4) {
EnGo_DrawRolling(this, globalCtx);
return; // needed for match?
} else {
func_800943C8(globalCtx->state.gfxCtx);
@ -1146,9 +1145,9 @@ void EnGo_Draw(Actor* thisx, GlobalContext* globalCtx) {
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
this->skelAnime.dListCount, EnGo_OverrideLimbDraw, EnGo_PostLimbDraw, &this->actor);
CLOSE_DISPS(globalCtx->state.gfxCtx);
EnGo_DrawDust(this, globalCtx);
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
void EnGo_AddDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, f32 scaleStep) {
@ -1158,6 +1157,7 @@ void EnGo_AddDust(EnGo* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 init
for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) {
if (dustEffect->type != 1) {
dustEffect->epoch++;
dustEffect->scale = scale;
dustEffect->scaleStep = scaleStep;
timer = initialTimer;
@ -1218,6 +1218,7 @@ void EnGo_DrawDust(EnGo* this, GlobalContext* globalCtx) {
firstDone = true;
}
FrameInterpolation_RecordOpenChild(dustEffect, dustEffect->epoch);
alpha = dustEffect->timer * (255.0f / dustEffect->initialTimer);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 170, 130, 90, alpha);
gDPPipeSync(POLY_XLU_DISP++);
@ -1230,6 +1231,7 @@ void EnGo_DrawDust(EnGo* this, GlobalContext* globalCtx) {
index = dustEffect->timer * (8.0f / dustEffect->initialTimer);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(dustTex[index]));
gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD50);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View file

@ -34,6 +34,7 @@ typedef struct {
/* 0x0014 */ Vec3f pos;
/* 0x0020 */ Vec3f velocity;
/* 0x002C */ Vec3f accel;
s32 epoch;
} EnGoEffect; // size = 0x38
typedef struct EnGo {

View file

@ -2,6 +2,7 @@
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_oF1d_map/object_oF1d_map.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -140,8 +141,6 @@ typedef enum {
/* 10 */ ENGO2_ANIM_10,
/* 11 */ ENGO2_ANIM_11,
/* 12 */ ENGO2_ANIM_12,
/* 13 */ ENGO2_ANIM_13, // Fixed Goron Wakeup Animation
/* 14 */ ENGO2_ANIM_14 // Fixed Biggoron Wakeup Animation
} EnGo2Animation;
static AnimationInfo sAnimationInfo[] = {
@ -151,8 +150,7 @@ static AnimationInfo sAnimationInfo[] = {
{ &gGoronAnim_002D80, 1.0f, 0.0f, -1.0f, 0x02, -8.0f }, { &gGoronAnim_00161C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
{ &gGoronAnim_001A00, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_0021D0, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
{ &gGoronAnim_004930, 0.0f, 0.0f, -1.0f, 0x01, -8.0f }, { &gGoronAnim_000750, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
{ &gGoronAnim_000D5C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_004930, 0.0f, 0.0f, -1.0f, 0x00, 0.0f },
{ &gGoronAnim_004930, 0.0f, 1.0f, -1.0f, 0x01, 0.0f },
{ &gGoronAnim_000D5C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
};
static EnGo2DustEffectData sDustEffectData[2][4] = {
@ -179,6 +177,7 @@ void EnGo2_AddDust(EnGo2* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 in
for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) {
if (dustEffect->type != 1) {
dustEffect->epoch++;
dustEffect->scale = scale;
dustEffect->scaleStep = scaleStep;
timer = initialTimer;
@ -239,6 +238,7 @@ void EnGo2_DrawDust(EnGo2* this, GlobalContext* globalCtx) {
firstDone = true;
}
FrameInterpolation_RecordOpenChild(dustEffect, dustEffect->epoch);
alpha = dustEffect->timer * (255.0f / dustEffect->initialTimer);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 170, 130, 90, alpha);
gDPPipeSync(POLY_XLU_DISP++);
@ -250,6 +250,7 @@ void EnGo2_DrawDust(EnGo2* this, GlobalContext* globalCtx) {
index = dustEffect->timer * (8.0f / dustEffect->initialTimer);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sDustTex[index]));
gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD50);
FrameInterpolation_RecordCloseChild();
}
}
@ -1344,10 +1345,10 @@ void EnGo2_WakeUp(EnGo2* this, GlobalContext* globalCtx) {
}
if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) {
OnePointCutscene_Init(globalCtx, 4200, -99, &this->actor, MAIN_CAM);
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ((CVar_GetS32("gGoronSpeen", 0) == 1) ? ENGO2_ANIM_10 : ENGO2_ANIM_14));
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_10);
this->skelAnime.playSpeed = 0.5f;
} else {
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ((CVar_GetS32("gGoronSpeen", 0) == 1) ? ENGO2_ANIM_1 : ENGO2_ANIM_13));
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1);
this->skelAnime.playSpeed = 1.0f;
}
this->actionFunc = func_80A46B40;

View file

@ -8,6 +8,7 @@
#include "objects/object_niw/object_niw.h"
#include "overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h"
#include "vt.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_23)
@ -1145,6 +1146,7 @@ void EnNiw_FeatherSpawn(EnNiw* this, Vec3f* pos, Vec3f* vel, Vec3f* accel, f32 s
for (i = 0; i < ARRAY_COUNT(this->feathers); i++, feather++) {
if (feather->type == 0) {
feather->epoch++;
feather->type = 1;
feather->pos = *pos;
feather->vel = *vel;
@ -1202,6 +1204,7 @@ void EnNiw_FeatherDraw(EnNiw* this, GlobalContext* globalCtx) {
for (i = 0; i < ARRAY_COUNT(this->feathers); i++, feather++) {
if (feather->type == 1) {
FrameInterpolation_RecordOpenChild(feather, feather->epoch);
if (!flag) {
gSPDisplayList(POLY_XLU_DISP++, gCuccoParticleAppearDL);
flag++;
@ -1214,6 +1217,7 @@ void EnNiw_FeatherDraw(EnNiw* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gCuccoParticleAliveDL);
FrameInterpolation_RecordCloseChild();
}
}

View file

@ -18,6 +18,7 @@ typedef struct {
/* 0x002C */ f32 scale;
/* 0x0030 */ f32 unk_30;
/* 0x0034 */ u8 timer;
s32 epoch;
} EnNiwFeather; // size = 0x0038
typedef struct EnNiw {

View file

@ -6,6 +6,7 @@
#include "z_en_nwc.h"
#include "objects/object_nwc/object_nwc.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -170,6 +171,7 @@ void EnNwc_DrawChicks(EnNwc* this, GlobalContext* globalCtx) {
if (chick->type != CHICK_NONE) {
Mtx* mtx;
FrameInterpolation_RecordOpenChild(chick, chick->epoch);
Matrix_SetTranslateRotateYXZ(chick->pos.x, chick->pos.y + chick->height, chick->pos.z, &chick->rot);
Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY);
mtx = MATRIX_NEWMTX(globalCtx->state.gfxCtx);
@ -180,6 +182,7 @@ void EnNwc_DrawChicks(EnNwc* this, GlobalContext* globalCtx) {
gSPDisplayList(dList2++, gCuccoChickEyesDL);
gSPMatrix(dList3++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(dList3++, gCuccoChickBeakDL);
FrameInterpolation_RecordCloseChild();
}
}
@ -190,6 +193,7 @@ void EnNwc_DrawChicks(EnNwc* this, GlobalContext* globalCtx) {
for (i = 0; i < this->count; i++, chick++) {
if ((chick->type != CHICK_NONE) && (chick->floorPoly != NULL)) {
FrameInterpolation_RecordOpenChild(chick, chick->epoch * 25);
func_80038A28(chick->floorPoly, chick->pos.x, chick->floorY, chick->pos.z, &floorMat);
Matrix_Put(&floorMat);
Matrix_RotateY(chick->rot.y * (M_PI / 0x8000), MTXMODE_APPLY);
@ -197,6 +201,7 @@ void EnNwc_DrawChicks(EnNwc* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gCuccoChickShadowDL);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
@ -220,6 +225,7 @@ void EnNwc_Init(Actor* thisx, GlobalContext* globalCtx) {
this->count = 16;
chick = this->chicks;
for (i = 0; i < this->count; i++, chick++) {
chick->epoch++;
chick->type = CHICK_NORMAL;
chick->pos.x = thisx->world.pos.x + ((Rand_ZeroOne() * 100.0f) - 50.0f);
chick->pos.y = thisx->world.pos.y + 20.0f;

View file

@ -23,6 +23,7 @@ typedef struct EnNwcChick {
/* 0x36 */ u16 height;
/* 0x38 */ CollisionPoly* floorPoly;
/* 0x44 */ char unk_3C[0x20];
s32 epoch;
} EnNwcChick; // size = 0x5C
typedef struct EnNwc {

View file

@ -1,5 +1,6 @@
#include "z_en_ny.h"
#include "objects/object_ny/object_ny.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2)
@ -107,6 +108,7 @@ static InitChainEntry sInitChain[] = {
void EnNy_Init(Actor* thisx, GlobalContext* globalCtx) {
EnNy* this = (EnNy*)thisx;
this->epoch++;
Actor_ProcessInitChain(&this->actor, sInitChain);
this->actor.colChkInfo.damageTable = &sDamageTable;
this->actor.colChkInfo.health = 2;
@ -577,6 +579,7 @@ void EnNy_DrawDeathEffect(Actor* thisx, GlobalContext* globalCtx) {
gDPPipeSync(POLY_OPA_DISP++);
for (i = 0; i < 8; i++) {
if (this->timer < (i + 22)) {
FrameInterpolation_RecordOpenChild(this, this->epoch + i * 25);
temp = &this->unk_1F8[i];
Matrix_Translate(temp->x, temp->y, temp->z, MTXMODE_NEW);
scale = this->actor.scale.x * 0.4f * (1.0f + (i * 0.04f));
@ -584,6 +587,7 @@ void EnNy_DrawDeathEffect(Actor* thisx, GlobalContext* globalCtx) {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gEnNyRockBodyDL);
FrameInterpolation_RecordCloseChild();
}
}
CLOSE_DISPS(globalCtx->state.gfxCtx);

View file

@ -30,6 +30,7 @@ typedef struct EnNy {
/* 0x01F0 */ f32 unk_1F0;
/* 0x01F4 */ f32 unk_1F4;
/* 0x01F8 */ Vec3f unk_1F8[16];
s32 epoch;
} EnNy; // size = 0x02B8
#endif

View file

@ -7,6 +7,7 @@
#include "z_en_po_sisters.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_po_sisters/object_po_sisters.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_2 | ACTOR_FLAG_4 | ACTOR_FLAG_9 | ACTOR_FLAG_12 | ACTOR_FLAG_14)
@ -179,6 +180,8 @@ void EnPoSisters_Init(Actor* thisx, GlobalContext* globalCtx) {
EnPoSisters* this = (EnPoSisters*)thisx;
s32 pad;
this->epoch++;
// Skip Poe Intro Cutscene
if (gSaveContext.n64ddFlag && thisx->params == 4124) {
Flags_SetSwitch(globalCtx, 0x1B);
@ -1186,7 +1189,7 @@ void EnPoSisters_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnPoSisters* this = (EnPoSisters*)thisx;
s16 temp;
if (this->collider.base.atFlags & AT_HIT) {
this->collider.base.atFlags &= ~AT_HIT;
func_80AD9568(this);
@ -1413,6 +1416,7 @@ void EnPoSisters_Draw(Actor* thisx, GlobalContext* globalCtx) {
this->actionFunc != func_80ADBEE8) {
phi_s5 = -i * 31 + 248;
}
FrameInterpolation_RecordOpenChild(this, this->epoch + i * 25);
gDPPipeSync(POLY_XLU_DISP++);
gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, temp_s7->r, temp_s7->g, temp_s7->b, phi_s5);
Matrix_Translate(this->unk_234[i].x, this->unk_234[i].y, this->unk_234[i].z, MTXMODE_NEW);
@ -1425,6 +1429,7 @@ void EnPoSisters_Draw(Actor* thisx, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffFire1DL);
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
}

View file

@ -29,6 +29,7 @@ typedef struct EnPoSisters {
/* 0x029C */ LightInfo lightInfo;
/* 0x02AC */ ColliderCylinder collider;
/* 0x02F8 */ MtxF unk_2F8;
s32 epoch;
} EnPoSisters; // size = 0x0338
#endif

View file

@ -7,6 +7,7 @@
#include "z_en_syateki_niw.h"
#include "objects/object_niw/object_niw.h"
#include "vt.h"
#include "soh/frame_interpolation.h"
#define FLAGS ACTOR_FLAG_4
@ -713,6 +714,7 @@ void func_80B131B8(EnSyatekiNiw* this, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f3
for (i = 0; i < 5; i++, ptr++) {
if (ptr->unk_00 == 0) {
ptr->epoch++;
ptr->unk_00 = 1;
ptr->unk_04 = *arg1;
ptr->unk_10 = *arg2;
@ -773,6 +775,7 @@ void func_80B13464(EnSyatekiNiw* this, GlobalContext* globalCtx) {
flag++;
}
FrameInterpolation_RecordOpenChild(ptr, ptr->epoch);
Matrix_Translate(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);
Matrix_Scale(ptr->unk_2C, ptr->unk_2C, 1.0f, MTXMODE_APPLY);
@ -782,6 +785,7 @@ void func_80B13464(EnSyatekiNiw* this, GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gCuccoParticleAliveDL);
FrameInterpolation_RecordCloseChild();
}
}

View file

@ -18,6 +18,7 @@ typedef struct {
/* 0x2C */ f32 unk_2C;
/* 0x30 */ f32 unk_30;
/* 0x34 */ u8 unk_34;
s32 epoch;
} EnSyatekiNiw_1; // size = 0x38
typedef struct EnSyatekiNiw {

View file

@ -7,6 +7,7 @@
#include "z_en_tk.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_tk/object_tk.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3)
#define COLLECTFLAG_GRAVEDIGGING_HEART_PIECE 0x19
@ -43,6 +44,7 @@ void EnTkEff_Create(EnTk* this, Vec3f* pos, Vec3f* speed, Vec3f* accel, u8 durat
for (i = 0; i < ARRAY_COUNT(this->eff); i++) {
if (eff->active != 1) {
eff->epoch++;
eff->size = size;
eff->growth = growth;
eff->timeTotal = eff->timeLeft = duration;
@ -107,6 +109,7 @@ void EnTkEff_Draw(EnTk* this, GlobalContext* globalCtx) {
gfxSetup = 1;
}
FrameInterpolation_RecordOpenChild(eff, eff->epoch);
alpha = eff->timeLeft * (255.0f / eff->timeTotal);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 170, 130, 90, alpha);
@ -121,6 +124,7 @@ void EnTkEff_Draw(EnTk* this, GlobalContext* globalCtx) {
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(dustTextures[imageIdx]));
gSPDisplayList(POLY_XLU_DISP++, gDampeEff2DL);
FrameInterpolation_RecordCloseChild();
}
eff++;
}

View file

@ -17,6 +17,7 @@ typedef struct EnTkEff {
/* 0x0014 */ Vec3f pos;
/* 0x0020 */ Vec3f speed;
/* 0x002C */ Vec3f accel;
s32 epoch;
} EnTkEff; // size = 0x0038
struct EnTk;

View file

@ -14,6 +14,7 @@
#include "objects/object_gndd/object_gndd.h"
#include "objects/object_ganon/object_ganon.h"
#include "objects/object_opening_demo1/object_opening_demo1.h"
#include "soh/frame_interpolation.h"
#define FLAGS ACTOR_FLAG_4
@ -793,6 +794,7 @@ void EnViewer_InitFireEffect(EnViewer* this, GlobalContext* globalCtx, s16 i) {
eff->endPos.y = -420.0f;
eff->endPos.z = -400.0f;
eff->scale = (Rand_ZeroOne() * 5.0f + 12.0f) * 0.001f;
eff->epoch++;
} else {
eff = &this->fireEffects[i];
eff->startPos.x = -100.0f;
@ -802,6 +804,7 @@ void EnViewer_InitFireEffect(EnViewer* this, GlobalContext* globalCtx, s16 i) {
eff->endPos.y = -420.0f;
eff->endPos.z = -400.0f;
eff->scale = (Rand_ZeroOne() * 5.0f + 12.0f) * 0.001f;
eff->epoch++;
}
if (this) {}
}
@ -843,6 +846,7 @@ void EnViewer_DrawFireEffects(EnViewer* this2, GlobalContext* globalCtx) {
break;
}
FrameInterpolation_RecordOpenChild(&this->fireEffects[i], this->fireEffects[i].epoch);
func_80093D84(globalCtx->state.gfxCtx);
Matrix_Translate(this->fireEffects[i].pos.x, this->fireEffects[i].pos.y, this->fireEffects[i].pos.z,
MTXMODE_NEW);
@ -856,6 +860,7 @@ void EnViewer_DrawFireEffects(EnViewer* this2, GlobalContext* globalCtx) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPMatrix(POLY_XLU_DISP++, SEG_ADDR(1, 0), G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gEffFire1DL);
FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
}

View file

@ -56,6 +56,7 @@ typedef struct {
/* 0x28 */ f32 scale;
/* 0x2C */ f32 lerpFactor;
/* 0x30 */ u8 state;
s32 epoch;
} EnViewerFireEffect; // size = 0x34
typedef struct EnViewer {

View file

@ -90,6 +90,7 @@ typedef struct {
/* 0x32 */ s16 timer;
/* 0x34 */ u8 shouldDraw;
/* 0x38 */ f32 drawDistance;
s32 epoch;
} FishingProp; // size = 0x3C
typedef enum {
@ -115,6 +116,7 @@ typedef struct {
/* 0x40 */ s16 unk_40;
/* 0x42 */ s16 unk_42;
/* 0x44 */ u8 shouldDraw;
s32 epoch;
} FishingGroupFish; // size = 0x48
#define LINE_SEG_COUNT 200
@ -764,6 +766,7 @@ void Fishing_InitPondProps(Fishing* this, GlobalContext* globalCtx) {
break;
}
prop->epoch++;
prop->type = sPondPropInits[i].type;
prop->pos.x = sPondPropInits[i].pos.x;
prop->pos.y = sPondPropInits[i].pos.y;
@ -929,6 +932,8 @@ void Fishing_Init(Actor* thisx, GlobalContext* globalCtx2) {
for (i = 0; i < GROUP_FISH_COUNT; i++) {
FishingGroupFish* fish = &sGroupFishes[i];
fish->epoch++;
fish->type = FS_GROUP_FISH_NORMAL;
if (i <= 20) {
@ -1761,6 +1766,8 @@ static f32 sSinkingLureSizes[] = {
void Fishing_DrawSinkingLure(GlobalContext* globalCtx) {
s16 i;
f32 scale;
static s32 epoch = 0;
epoch++;
OPEN_DISPS(globalCtx->state.gfxCtx);
@ -1773,6 +1780,7 @@ void Fishing_DrawSinkingLure(GlobalContext* globalCtx) {
for (i = SINKING_LURE_SEG_COUNT - 1; i >= 0; i--) {
if ((i + D_80B7FEA0) < SINKING_LURE_SEG_COUNT) {
FrameInterpolation_RecordOpenChild("Fishing Lures 1", epoch + i * 25);
Matrix_Translate(sSinkingLurePos[i].x, sSinkingLurePos[i].y, sSinkingLurePos[i].z, MTXMODE_NEW);
scale = sSinkingLureSizes[i + D_80B7FEA0] * 0.04f;
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
@ -1781,6 +1789,7 @@ void Fishing_DrawSinkingLure(GlobalContext* globalCtx) {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gFishingSinkingLureSegmentModelDL);
FrameInterpolation_RecordCloseChild();
}
}
} else {
@ -1790,6 +1799,7 @@ void Fishing_DrawSinkingLure(GlobalContext* globalCtx) {
for (i = SINKING_LURE_SEG_COUNT - 1; i >= 0; i--) {
if ((i + D_80B7FEA0) < SINKING_LURE_SEG_COUNT) {
FrameInterpolation_RecordOpenChild("Fishing Lures 2", epoch + i * 25);
Matrix_Translate(sSinkingLurePos[i].x, sSinkingLurePos[i].y, sSinkingLurePos[i].z, MTXMODE_NEW);
scale = sSinkingLureSizes[i + D_80B7FEA0] * 0.04f;
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
@ -1798,6 +1808,7 @@ void Fishing_DrawSinkingLure(GlobalContext* globalCtx) {
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gFishingSinkingLureSegmentModelDL);
FrameInterpolation_RecordCloseChild();
}
}
}
@ -4451,7 +4462,7 @@ void Fishing_DrawPondProps(GlobalContext* globalCtx) {
}
if (prop->shouldDraw) {
FrameInterpolation_RecordOpenChild(prop, 0);
FrameInterpolation_RecordOpenChild(prop, prop->epoch);
Matrix_Translate(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW);
Matrix_Scale(prop->scale, prop->scale, prop->scale, MTXMODE_APPLY);
Matrix_RotateY(prop->rotY, MTXMODE_APPLY);
@ -4478,7 +4489,7 @@ void Fishing_DrawPondProps(GlobalContext* globalCtx) {
}
if (prop->shouldDraw) {
FrameInterpolation_RecordOpenChild(prop, 0);
FrameInterpolation_RecordOpenChild(prop, prop->epoch);
Matrix_Translate(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW);
Matrix_Scale(prop->scale, prop->scale, prop->scale, MTXMODE_APPLY);
@ -4502,7 +4513,7 @@ void Fishing_DrawPondProps(GlobalContext* globalCtx) {
}
if (prop->shouldDraw) {
FrameInterpolation_RecordOpenChild(prop, 0);
FrameInterpolation_RecordOpenChild(prop, prop->epoch);
Matrix_Translate(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW);
Matrix_Scale(prop->scale, 1.0f, prop->scale, MTXMODE_APPLY);
Matrix_RotateY(prop->lilyPadAngle * (M_PI / 32768), MTXMODE_APPLY);
@ -4529,7 +4540,7 @@ void Fishing_DrawPondProps(GlobalContext* globalCtx) {
}
if (prop->shouldDraw) {
FrameInterpolation_RecordOpenChild(prop, 0);
FrameInterpolation_RecordOpenChild(prop, prop->epoch);
Matrix_Translate(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW);
Matrix_Scale(prop->scale, prop->scale, prop->scale, MTXMODE_APPLY);
Matrix_RotateY(prop->rotY, MTXMODE_APPLY);
@ -4759,6 +4770,7 @@ void Fishing_DrawGroupFishes(GlobalContext* globalCtx) {
}
if (fish->shouldDraw) {
FrameInterpolation_RecordOpenChild(fish, fish->epoch);
Matrix_Translate(fish->pos.x, fish->pos.y, fish->pos.z, MTXMODE_NEW);
Matrix_RotateY(((f32)fish->unk_3E * M_PI) / 32768.0f, MTXMODE_APPLY);
Matrix_RotateX((-(f32)fish->unk_3C * M_PI) / 32768.0f, MTXMODE_APPLY);
@ -4767,6 +4779,7 @@ void Fishing_DrawGroupFishes(GlobalContext* globalCtx) {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gFishingGroupFishModelDL);
FrameInterpolation_RecordCloseChild();
}
}
fish++;

View file

@ -168,7 +168,8 @@ void ItemOcarina_DoNothing(ItemOcarina* this, GlobalContext* globalCtx) {
}
void ItemOcarina_StartSoTCutscene(ItemOcarina* this, GlobalContext* globalCtx) {
if (Actor_TextboxIsClosing(&this->actor, globalCtx)) {
if (Actor_TextboxIsClosing(&this->actor, globalCtx) ||
Randomizer_ObtainedFreestandingIceTrap(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT, &this->actor)) {
if (!gSaveContext.n64ddFlag) {
globalCtx->csCtx.segment = SEGMENTED_TO_VIRTUAL(gHyruleFieldZeldaSongOfTimeCs);
gSaveContext.cutsceneTrigger = 1;

View file

@ -6,6 +6,7 @@
#include "z_mir_ray.h"
#include "objects/object_mir_ray/object_mir_ray.h"
#include "soh/frame_interpolation.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
@ -481,6 +482,8 @@ void MirRay_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 i;
MirRayShieldReflection reflection[6];
s32 temp;
static s32 epoch = 0;
epoch++;
this->reflectIntensity = 0.0f;
if ((D_80B8E670 == 0) && !this->unLit && Player_HasMirrorShieldSetToDraw(globalCtx)) {
@ -511,6 +514,7 @@ void MirRay_Draw(Actor* thisx, GlobalContext* globalCtx) {
}
for (i = 0; i < 6; i++) {
if (reflection[i].reflectionPoly != NULL) {
FrameInterpolation_RecordOpenChild(&reflection[i], epoch + i * 25);
Matrix_Translate(reflection[i].pos.x, reflection[i].pos.y, reflection[i].pos.z, MTXMODE_NEW);
Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY);
Matrix_Mult(&reflection[i].mtx, MTXMODE_APPLY);
@ -519,6 +523,7 @@ void MirRay_Draw(Actor* thisx, GlobalContext* globalCtx) {
gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_DECAL2);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 150, reflection[0].opacity);
gSPDisplayList(POLY_XLU_DISP++, gShieldBeamImageDL);
FrameInterpolation_RecordCloseChild();
}
}

View file

@ -924,6 +924,7 @@ void ObjectKankyo_DrawBeams(ObjectKankyo* this2, GlobalContext* globalCtx2) {
if (this->requiredObjectLoaded) {
for (i = 0; i < 6; i++) {
if (this->effects[i].size > 0.001f) {
FrameInterpolation_RecordOpenChild(&this->effects[i], this->effects[i].epoch);
Matrix_Translate(beamX[i], beamY[i], beamZ[i], MTXMODE_NEW);
Matrix_RotateY(DEG_TO_RAD(beamYaw[i]), MTXMODE_APPLY);
Matrix_RotateX(DEG_TO_RAD(beamPitch[i]), MTXMODE_APPLY);
@ -940,6 +941,7 @@ void ObjectKankyo_DrawBeams(ObjectKankyo* this2, GlobalContext* globalCtx2) {
globalCtx->state.frames * 10, 32, 64, 1, globalCtx->state.frames * 5,
globalCtx->state.frames * 10, 32, 64));
gSPDisplayList(POLY_XLU_DISP++, gDemoKekkaiDL_005FF0);
FrameInterpolation_RecordCloseChild();
}
}
}

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