mirror of
https://github.com/HarbourMasters/2ship2harkinian.git
synced 2024-11-22 21:49:54 +00:00
Initial commit for 2S2H
Co-authored-by: Louis <35883445+louist103@users.noreply.github.com> Co-authored-by: Nicholas Estelami <NEstelami@users.noreply.github.com> Co-authored-by: Random06457 <28494085+Random06457@users.noreply.github.com>
This commit is contained in:
parent
ea8c7de686
commit
2332f63f5a
23
.clang-format
Normal file
23
.clang-format
Normal file
@ -0,0 +1,23 @@
|
||||
IndentWidth: 4
|
||||
Language: Cpp
|
||||
UseTab: Never
|
||||
ColumnLimit: 120
|
||||
PointerAlignment: Left
|
||||
BreakBeforeBraces: Attach
|
||||
SpaceAfterCStyleCast: false
|
||||
Cpp11BracedListStyle: false
|
||||
IndentCaseLabels: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignOperands: true
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
AllowShortBlocksOnASingleLine: true
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignTrailingComments: true
|
||||
SortIncludes: false
|
9
.clang-tidy
Normal file
9
.clang-tidy
Normal file
@ -0,0 +1,9 @@
|
||||
Checks: '-*,readability-braces-around-statements,readability-inconsistent-declaration-parameter-name'
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: '(src|include)\/.*\.h$'
|
||||
FormatStyle: 'file'
|
||||
CheckOptions:
|
||||
# Require argument names to match exactly (instead of allowing a name to be a prefix/suffix of another)
|
||||
# Note: 'true' is expected by clang-tidy 12+ but '1' is used for compatibility with older versions
|
||||
- key: readability-inconsistent-declaration-parameter-name.Strict
|
||||
value: 1
|
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
56
.gitignore
vendored
Normal file
56
.gitignore
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
*.otr
|
||||
.vscode
|
||||
*.swp
|
||||
logs
|
||||
*.nix
|
||||
shipofharkinian.json
|
||||
.envrc
|
||||
imgui.ini
|
||||
|
||||
mm/libultraship/extern/Debug/ImGui.lib
|
||||
|
||||
mm/libultraship/extern/Debug/StrHash64.lib
|
||||
|
||||
mm/libultraship/extern/Debug/tinyxml2.lib
|
||||
|
||||
mm/libultraship/extern/ImGui.dir/Debug/ImGui.lib.recipe
|
||||
|
||||
mm/libultraship/extern/ImGui.dir/Debug/ImGui.tlog/CL.command.1.tlog
|
||||
|
||||
mm/libultraship/extern/ImGui.dir/Debug/ImGui.tlog/CL.read.1.tlog
|
||||
|
||||
mm/libultraship/extern/ImGui.dir/Debug/ImGui.tlog/CL.write.1.tlog
|
||||
|
||||
mm/libultraship/extern/ImGui.dir/Debug/ImGui.tlog/CustomBuild.command.1.tlog
|
||||
|
||||
mm/libultraship/extern/ImGui.dir/Debug/ImGui.tlog/CustomBuild.read.1.tlog
|
||||
|
||||
mm/libultraship/extern/ImGui.dir/Debug/ImGui.tlog/CustomBuild.write.1.tlog
|
||||
|
||||
mm/libultraship/extern/ImGui.dir/Debug/ImGui.tlog/ImGui.lastbuildstate
|
||||
|
||||
mm/libultraship/extern/ImGui.dir/Debug/ImGui.tlog/Lib-link.read.1.tlog
|
||||
|
||||
mm/libultraship/extern/StrHash64.dir/Debug/StrHash64.tlog/CL.command.1.tlog
|
||||
|
||||
mm/libultraship/extern/StrHash64.dir/Debug/StrHash64.tlog/CL.read.1.tlog
|
||||
|
||||
mm/libultraship/extern/StrHash64.dir/Debug/StrHash64.tlog/CL.write.1.tlog
|
||||
|
||||
mm/libultraship/extern/StrHash64.dir/Debug/StrHash64.tlog/CustomBuild.command.1.tlog
|
||||
|
||||
mm/libultraship/extern/StrHash64.dir/Debug/StrHash64.tlog/CustomBuild.read.1.tlog
|
||||
|
||||
mm/libultraship/extern/StrHash64.dir/Debug/StrHash64.tlog/CustomBuild.write.1.tlog
|
||||
|
||||
mm/libultraship/extern/StrHash64.dir/Debug/StrHash64.tlog/Lib-link.read.1.tlog
|
||||
|
||||
mm/libultraship/extern/StrHash64.dir/Debug/StrHash64.tlog/Lib-link.write.1.tlog
|
||||
|
||||
mm/libultraship/extern/StrHash64.dir/Debug/StrHash64.tlog/Lib.command.1.tlog
|
||||
/buildmm
|
||||
/Debug/libultraship.lib
|
||||
/Debug
|
||||
/build*
|
||||
/Release
|
||||
.vs/*
|
9
.gitmodules
vendored
Normal file
9
.gitmodules
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
[submodule "libultraship"]
|
||||
path = libultraship
|
||||
url = git@github.com:louist103/libultraship.git
|
||||
[submodule "OTRExporter"]
|
||||
path = OTRExporter
|
||||
url = git@github.com:louist103/OTRExporter.git
|
||||
[submodule "ZAPDTR"]
|
||||
path = ZAPDTR
|
||||
url = git@github.com:louist103/ZAPDTR.git
|
65
CMake/Default.cmake
Normal file
65
CMake/Default.cmake
Normal 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}")
|
12
CMake/DefaultCXX.cmake
Normal file
12
CMake/DefaultCXX.cmake
Normal 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()
|
30
CMake/Packaging-2.cmake
Normal file
30
CMake/Packaging-2.cmake
Normal file
@ -0,0 +1,30 @@
|
||||
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
|
||||
set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY 0)
|
||||
set(CPACK_COMPONENTS_ALL "ship" "extractor" "appimage")
|
||||
|
||||
if (NOT CPACK_GENERATOR STREQUAL "External")
|
||||
list(REMOVE_ITEM CPACK_COMPONENTS_ALL "appimage")
|
||||
endif()
|
||||
|
||||
if (CPACK_GENERATOR MATCHES "DEB|RPM")
|
||||
# https://unix.stackexchange.com/a/11552/254512
|
||||
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/ship/bin")#/${CMAKE_PROJECT_VERSION}")
|
||||
set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY 0)
|
||||
elseif (CPACK_GENERATOR MATCHES "ZIP")
|
||||
set(CPACK_PACKAGING_INSTALL_PREFIX "")
|
||||
endif()
|
||||
|
||||
if (CPACK_GENERATOR MATCHES "External")
|
||||
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
|
||||
SET(CPACK_MONOLITHIC_INSTALL 1)
|
||||
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/bin")
|
||||
endif()
|
||||
|
||||
if (CPACK_GENERATOR MATCHES "Bundle")
|
||||
set(CPACK_BUNDLE_NAME "soh")
|
||||
set(CPACK_BUNDLE_PLIST "macosx/Info.plist")
|
||||
set(CPACK_BUNDLE_ICON "macosx/soh.icns")
|
||||
set(CPACK_BUNDLE_STARTUP_COMMAND "../soh/macosx/soh-macos.sh")
|
||||
set(CPACK_BUNDLE_APPLE_CERT_APP "-")
|
||||
endif()
|
||||
|
90
CMake/Packaging.cmake
Normal file
90
CMake/Packaging.cmake
Normal file
@ -0,0 +1,90 @@
|
||||
# these are cache variables, so they could be overwritten with -D,
|
||||
|
||||
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}"
|
||||
CACHE STRING "The resulting package name"
|
||||
)
|
||||
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple C++ application"
|
||||
CACHE STRING "Package description for the package metadata"
|
||||
)
|
||||
set(CPACK_PACKAGE_VENDOR "Some Company")
|
||||
|
||||
set(CPACK_VERBATIM_VARIABLES YES)
|
||||
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
|
||||
SET(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_SOURCE_DIR}/_packages")
|
||||
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
|
||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
|
||||
set(CPACK_PACKAGE_CONTACT "YOUR@E-MAIL.net")
|
||||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "YOUR NAME")
|
||||
|
||||
#set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||
set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(CPACK_SYSTEM_NAME ${LSB_RELEASE_CODENAME_SHORT})
|
||||
# package name for deb
|
||||
# if set, then instead of some-application-0.9.2-Linux.deb
|
||||
# you'll get some-application_0.9.2_amd64.deb (note the underscores too)
|
||||
#set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
|
||||
execute_process(COMMAND dpkg --print-architecture OUTPUT_VARIABLE ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
set( CPACK_DEBIAN_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}-${ARCHITECTURE}.deb )
|
||||
# if you want every group to have its own package,
|
||||
# although the same happens if this is not sent (so it defaults to ONE_PER_GROUP)
|
||||
# and CPACK_DEB_COMPONENT_INSTALL is set to YES
|
||||
set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE)#ONE_PER_GROUP)
|
||||
# without this you won't be able to pack only specified component
|
||||
set(CPACK_DEB_COMPONENT_INSTALL YES)
|
||||
|
||||
set(CPACK_EXTERNAL_ENABLE_STAGING YES)
|
||||
set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${PROJECT_BINARY_DIR}/appimage-generate.cmake")
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT "${PROJECT_BINARY_DIR}/appimage-generate.cmake"
|
||||
CONTENT [[
|
||||
include(CMakePrintHelpers)
|
||||
cmake_print_variables(CPACK_TEMPORARY_DIRECTORY)
|
||||
cmake_print_variables(CPACK_TOPLEVEL_DIRECTORY)
|
||||
cmake_print_variables(CPACK_PACKAGE_DIRECTORY)
|
||||
cmake_print_variables(CPACK_PACKAGE_FILE_NAME)
|
||||
|
||||
find_program(LINUXDEPLOY_EXECUTABLE
|
||||
NAMES linuxdeploy linuxdeploy-x86_64.AppImage
|
||||
PATHS ${CPACK_PACKAGE_DIRECTORY}/linuxdeploy)
|
||||
|
||||
if (NOT LINUXDEPLOY_EXECUTABLE)
|
||||
message(STATUS "Downloading linuxdeploy")
|
||||
set(LINUXDEPLOY_EXECUTABLE ${CPACK_PACKAGE_DIRECTORY}/linuxdeploy/linuxdeploy)
|
||||
file(DOWNLOAD
|
||||
https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
${LINUXDEPLOY_EXECUTABLE}
|
||||
INACTIVITY_TIMEOUT 10
|
||||
LOG ${CPACK_PACKAGE_DIRECTORY}/linuxdeploy/download.log
|
||||
STATUS LINUXDEPLOY_DOWNLOAD)
|
||||
execute_process(COMMAND chmod +x ${LINUXDEPLOY_EXECUTABLE} COMMAND_ECHO STDOUT)
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E env
|
||||
OUTPUT=${CPACK_PACKAGE_FILE_NAME}.appimage
|
||||
VERSION=$<IF:$<BOOL:${CPACK_PACKAGE_VERSION}>,${CPACK_PACKAGE_VERSION},0.1.0>
|
||||
${LINUXDEPLOY_EXECUTABLE}
|
||||
--appimage-extract-and-run
|
||||
--appdir=${CPACK_TEMPORARY_DIRECTORY}
|
||||
--executable=$<TARGET_FILE:soh>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:soh,APPIMAGE_DESKTOP_FILE>>:--desktop-file=$<TARGET_PROPERTY:soh,APPIMAGE_DESKTOP_FILE>>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:soh,APPIMAGE_ICON_FILE>>:--icon-file=$<TARGET_PROPERTY:soh,APPIMAGE_ICON_FILE>>
|
||||
--output=appimage
|
||||
# --verbosity=2
|
||||
)
|
||||
]])
|
||||
|
||||
endif()
|
||||
|
||||
include(CPack)
|
||||
|
248
CMake/Utils.cmake
Normal file
248
CMake/Utils.cmake
Normal file
@ -0,0 +1,248 @@
|
||||
# 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")
|
||||
|
||||
function(get_linux_lsb_release_information)
|
||||
find_program(LSB_RELEASE_EXEC lsb_release)
|
||||
if(NOT LSB_RELEASE_EXEC)
|
||||
message(FATAL_ERROR "Could not detect lsb_release executable, can not gather required information")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --id OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --release OUTPUT_VARIABLE LSB_RELEASE_VERSION_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --codename OUTPUT_VARIABLE LSB_RELEASE_CODENAME_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
set(LSB_RELEASE_ID_SHORT "${LSB_RELEASE_ID_SHORT}" PARENT_SCOPE)
|
||||
set(LSB_RELEASE_VERSION_SHORT "${LSB_RELEASE_VERSION_SHORT}" PARENT_SCOPE)
|
||||
set(LSB_RELEASE_CODENAME_SHORT "${LSB_RELEASE_CODENAME_SHORT}" PARENT_SCOPE)
|
||||
endfunction()
|
191
CMake/automate-vcpkg.cmake
Normal file
191
CMake/automate-vcpkg.cmake
Normal file
@ -0,0 +1,191 @@
|
||||
#------------------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# Automate-VCPKG by Andre Taulien
|
||||
# ===============================
|
||||
#
|
||||
# Project Repository: https://github.com/REGoth-project/Automate-VCPKG
|
||||
# License ..........: MIT, see end of file.
|
||||
#
|
||||
# Based on: https://github.com/sutambe/cpptruths/blob/vcpkg_cmake_blog/cpp0x/vcpkg_test/CMakeLists.txt
|
||||
#
|
||||
#
|
||||
# While [Vcpkg](https://github.com/microsoft/vcpkg) on it's own is awesome, it does add
|
||||
# a little bit of complexity to getting a project to build. Even more if the one trying
|
||||
# to compile your application is not too fond of the commandline. Additionally, CMake
|
||||
# commands tend to get rather long with the toolchain path.
|
||||
#
|
||||
# To keep things simple for new users who just want to get the project to build, this
|
||||
# script offers a solution.
|
||||
#
|
||||
# Lets assume your main `CMakelists.txt` looks something like this:
|
||||
#
|
||||
# cmake_minimum_required (VERSION 3.12.0)
|
||||
# project (MyProject)
|
||||
#
|
||||
# add_executable(MyExecutable main.c)
|
||||
#
|
||||
# To integrate Vcpkg into that `CMakelists.txt`, simple put the following lines before the
|
||||
# call to `project(MyProject)`:
|
||||
#
|
||||
# include(cmake/automate-vcpkg.cmake)
|
||||
#
|
||||
# vcpkg_bootstrap()
|
||||
# vcpkg_install_packages(libsquish physfs)
|
||||
#
|
||||
# The call to `vcpkg_bootstrap()` will clone the official Vcpkg repository and bootstrap it.
|
||||
# If it detected an existing environment variable defining a valid `VCPKG_ROOT`, it will
|
||||
# update the existing installation of Vcpkg.
|
||||
#
|
||||
# Arguments to `vcpkg_install_packages()` are the packages you want to install using Vcpkg.
|
||||
#
|
||||
# If you want to keep the possibility for users to chose their own copy of Vcpkg, you can
|
||||
# simply not run the code snippet mentioned above, something like this will work:
|
||||
#
|
||||
# option(SKIP_AUTOMATE_VCPKG "When ON, you will need to built the packages
|
||||
# required by MyProject on your own or supply your own vcpkg toolchain.")
|
||||
#
|
||||
# if (NOT SKIP_AUTOMATE_VCPKG)
|
||||
# include(cmake/automate-vcpkg.cmake)
|
||||
#
|
||||
# vcpkg_bootstrap()
|
||||
# vcpkg_install_packages(libsquish physfs)
|
||||
# endif()
|
||||
#
|
||||
# Then, the user has to supply the packages on their own, be it through Vcpkg or manually
|
||||
# specifying their locations.
|
||||
#------------------------------------------------------------------------------------------------------------
|
||||
|
||||
cmake_minimum_required (VERSION 3.12)
|
||||
|
||||
if(WIN32)
|
||||
set(VCPKG_FALLBACK_ROOT ${CMAKE_CURRENT_BINARY_DIR}/vcpkg CACHE STRING "vcpkg configuration directory to use if vcpkg was not installed on the system before")
|
||||
else()
|
||||
set(VCPKG_FALLBACK_ROOT ${CMAKE_CURRENT_BINARY_DIR}/.vcpkg CACHE STRING "vcpkg configuration directory to use if vcpkg was not installed on the system before")
|
||||
endif()
|
||||
|
||||
# On Windows, Vcpkg defaults to x86, even on x64 systems. If we're
|
||||
# doing a 64-bit build, we need to fix that.
|
||||
if (WIN32)
|
||||
|
||||
# Since the compiler checks haven't run yet, we need to figure
|
||||
# out the value of CMAKE_SIZEOF_VOID_P ourselfs
|
||||
|
||||
include(CheckTypeSize)
|
||||
enable_language(C)
|
||||
check_type_size("void*" SIZEOF_VOID_P BUILTIN_TYPES_ONLY)
|
||||
|
||||
if (SIZEOF_VOID_P EQUAL 8)
|
||||
message(STATUS "Using Vcpkg triplet 'x64-windows'")
|
||||
|
||||
set(VCPKG_TRIPLET x64-windows)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED VCPKG_ROOT)
|
||||
if(NOT DEFINED ENV{VCPKG_ROOT})
|
||||
set(VCPKG_ROOT ${VCPKG_FALLBACK_ROOT})
|
||||
else()
|
||||
set(VCPKG_ROOT $ENV{VCPKG_ROOT})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Installs a new copy of Vcpkg or updates an existing one
|
||||
macro(vcpkg_bootstrap)
|
||||
_install_or_update_vcpkg()
|
||||
|
||||
# Find out whether the user supplied their own VCPKG toolchain file
|
||||
if(NOT DEFINED ${CMAKE_TOOLCHAIN_FILE})
|
||||
# We know this wasn't set before so we need point the toolchain file to the newly found VCPKG_ROOT
|
||||
set(CMAKE_TOOLCHAIN_FILE ${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake CACHE STRING "")
|
||||
|
||||
# Just setting vcpkg.cmake as toolchain file does not seem to actually pull in the code
|
||||
include(${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
|
||||
|
||||
set(AUTOMATE_VCPKG_USE_SYSTEM_VCPKG OFF)
|
||||
else()
|
||||
# VCPKG_ROOT has been defined by the toolchain file already
|
||||
set(AUTOMATE_VCPKG_USE_SYSTEM_VCPKG ON)
|
||||
endif()
|
||||
|
||||
message(STATUS "Automate VCPKG status:")
|
||||
message(STATUS " VCPKG_ROOT.....: ${VCPKG_ROOT}")
|
||||
message(STATUS " VCPKG_EXEC.....: ${VCPKG_EXEC}")
|
||||
message(STATUS " VCPKG_BOOTSTRAP: ${VCPKG_BOOTSTRAP}")
|
||||
endmacro()
|
||||
|
||||
macro(_install_or_update_vcpkg)
|
||||
if(NOT EXISTS ${VCPKG_ROOT})
|
||||
message(STATUS "Cloning vcpkg in ${VCPKG_ROOT}")
|
||||
execute_process(COMMAND git clone https://github.com/Microsoft/vcpkg.git ${VCPKG_ROOT} --depth 1)
|
||||
|
||||
# If a reproducible build is desired (and potentially old libraries are # ok), uncomment the
|
||||
# following line and pin the vcpkg repository to a specific githash.
|
||||
# execute_process(COMMAND git checkout 745a0aea597771a580d0b0f4886ea1e3a94dbca6 WORKING_DIRECTORY ${VCPKG_ROOT})
|
||||
else()
|
||||
# The following command has no effect if the vcpkg repository is in a detached head state.
|
||||
message(STATUS "Auto-updating vcpkg in ${VCPKG_ROOT}")
|
||||
execute_process(COMMAND git pull WORKING_DIRECTORY ${VCPKG_ROOT})
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${VCPKG_ROOT}/README.md)
|
||||
message(FATAL_ERROR "***** FATAL ERROR: Could not clone vcpkg *****")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(VCPKG_EXEC ${VCPKG_ROOT}/vcpkg.exe)
|
||||
set(VCPKG_BOOTSTRAP ${VCPKG_ROOT}/bootstrap-vcpkg.bat)
|
||||
else()
|
||||
set(VCPKG_EXEC ${VCPKG_ROOT}/vcpkg)
|
||||
set(VCPKG_BOOTSTRAP ${VCPKG_ROOT}/bootstrap-vcpkg.sh)
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${VCPKG_EXEC})
|
||||
message("Bootstrapping vcpkg in ${VCPKG_ROOT}")
|
||||
execute_process(COMMAND ${VCPKG_BOOTSTRAP} WORKING_DIRECTORY ${VCPKG_ROOT})
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${VCPKG_EXEC})
|
||||
message(FATAL_ERROR "***** FATAL ERROR: Could not bootstrap vcpkg *****")
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
# Installs the list of packages given as parameters using Vcpkg
|
||||
macro(vcpkg_install_packages)
|
||||
|
||||
# Need the given list to be space-separated
|
||||
#string (REPLACE ";" " " PACKAGES_LIST_STR "${ARGN}")
|
||||
|
||||
message(STATUS "Installing/Updating the following vcpkg-packages: ${PACKAGES_LIST_STR}")
|
||||
|
||||
if (VCPKG_TRIPLET)
|
||||
set(ENV{VCPKG_DEFAULT_TRIPLET} "${VCPKG_TRIPLET}")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${VCPKG_EXEC} install ${ARGN}
|
||||
WORKING_DIRECTORY ${VCPKG_ROOT}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2019 REGoth-project
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
225
CMakeLists.txt
Normal file
225
CMakeLists.txt
Normal file
@ -0,0 +1,225 @@
|
||||
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
|
||||
|
||||
set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||
|
||||
project(2s2h VERSION 0.0.1 LANGUAGES C CXX)
|
||||
set(PROJECT_BUILD_NAME "PRE ALPHA" CACHE STRING "")
|
||||
set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "")
|
||||
|
||||
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT mm)
|
||||
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>)
|
||||
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/utf-8>)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows|Linux")
|
||||
if(NOT DEFINED BUILD_CROWD_CONTROL)
|
||||
set(BUILD_CROWD_CONTROL OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
include(CMake/automate-vcpkg.cmake)
|
||||
|
||||
set(VCPKG_TRIPLET x86-windows-static)
|
||||
set(VCPKG_TARGET_TRIPLET x86-windows-static)
|
||||
|
||||
vcpkg_bootstrap()
|
||||
vcpkg_install_packages(zlib bzip2 libpng sdl2 sdl2-net glew glfw3)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Set target arch type if empty. Visual studio solution generator provides it.
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if(NOT CMAKE_VS_PLATFORM_NAME)
|
||||
set(CMAKE_VS_PLATFORM_NAME "x64")
|
||||
endif()
|
||||
message("${CMAKE_VS_PLATFORM_NAME} architecture in use")
|
||||
|
||||
if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64"
|
||||
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"))
|
||||
message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Global configuration types
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-g -ffast-math -DDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -ffast-math -DDEBUG")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3 -ffast-math -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -ffast-math -DNDEBUG")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-fuse-ld=lld")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-g")
|
||||
set(CMAKE_LINKER_FLAGS_DEBUG "-fuse-ld=lld")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
|
||||
set(CMAKE_OBJCXX_FLAGS_RELEASE "-O2 -DNDEBUG")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE )
|
||||
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Common utils
|
||||
################################################################################
|
||||
include(CMake/Utils.cmake)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
get_linux_lsb_release_information()
|
||||
message(STATUS "Linux ${LSB_RELEASE_ID_SHORT} ${LSB_RELEASE_VERSION_SHORT} ${LSB_RELEASE_CODENAME_SHORT}")
|
||||
else()
|
||||
message(STATUS ${CMAKE_SYSTEM_NAME})
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Additional Global Settings(add specific info there)
|
||||
################################################################################
|
||||
include(CMake/GlobalSettingsInclude.cmake OPTIONAL)
|
||||
|
||||
################################################################################
|
||||
# Use solution folders feature
|
||||
################################################################################
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
################################################################################
|
||||
# Sub-projects
|
||||
################################################################################
|
||||
add_subdirectory(libultraship ${CMAKE_BINARY_DIR}/libultraship)
|
||||
add_subdirectory(ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD)
|
||||
add_subdirectory(OTRExporter)
|
||||
add_subdirectory(mm)
|
||||
|
||||
set_property(TARGET mm PROPERTY APPIMAGE_DESKTOP_FILE_TERMINAL YES)
|
||||
set_property(TARGET mm PROPERTY APPIMAGE_DESKTOP_FILE "${CMAKE_SOURCE_DIR}/scripts/linux/appimage/soh.desktop")
|
||||
set_property(TARGET mm PROPERTY APPIMAGE_ICON_FILE "${CMAKE_BINARY_DIR}/sohIcon.png")
|
||||
|
||||
#if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
#install(PROGRAMS "${CMAKE_SOURCE_DIR}/scripts/linux/appimage/soh.sh" DESTINATION . COMPONENT appimage)
|
||||
#install(FILES "${CMAKE_SOURCE_DIR}/soh.otr" DESTINATION . COMPONENT ship)
|
||||
#install(TARGETS ZAPD DESTINATION ./assets/extractor COMPONENT extractor)
|
||||
#install(DIRECTORY "${CMAKE_SOURCE_DIR}/soh/assets/extractor/" DESTINATION ./assets/extractor COMPONENT extractor)
|
||||
#install(DIRECTORY "${CMAKE_SOURCE_DIR}/soh/assets/xml/" DESTINATION ./assets/extractor/xmls COMPONENT extractor)
|
||||
#install(DIRECTORY "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/filelists/" DESTINATION ./assets/extractor/filelists COMPONENT extractor)
|
||||
#install(FILES "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ActorList_OoTMqDbg.txt" DESTINATION ./assets/extractor/symbols COMPONENT extractor)
|
||||
#install(FILES "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ObjectList_OoTMqDbg.txt" DESTINATION ./assets/extractor/symbols COMPONENT extractor)
|
||||
#install(FILES "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/SymbolMap_OoTMqDbg.txt" DESTINATION ./assets/extractor/symbols COMPONENT extractor)
|
||||
#endif()
|
||||
|
||||
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
|
||||
install(DIRECTORY "${CMAKE_SOURCE_DIR}/mm/assets/extractor/" DESTINATION ./assets/extractor COMPONENT 2s2h)
|
||||
install(DIRECTORY "${CMAKE_SOURCE_DIR}/mm/assets/xml/" DESTINATION ./assets/extractor/xmls COMPONENT 2s2h)
|
||||
install(DIRECTORY "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/filelists/" DESTINATION ./assets/extractor/filelists COMPONENT 2s2h)
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ActorList_OoTMqDbg.txt" DESTINATION ./assets/extractor/symbols COMPONENT 2s2h)
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ObjectList_OoTMqDbg.txt" DESTINATION ./assets/extractor/symbols COMPONENT 2s2h)
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/SymbolMap_OoTMqDbg.txt" DESTINATION ./assets/extractor/symbols COMPONENT 2s2h)
|
||||
endif()
|
||||
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
|
||||
# Target to generate OTRs
|
||||
add_custom_target(
|
||||
ExtractAssets
|
||||
# CMake versions prior to 3.17 do not have the rm command, use remove instead for older versions
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<VERSION_LESS:${CMAKE_VERSION},3.17>,remove,rm> -f oot.otr oot-mq.otr soh.otr
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$<TARGET_FILE:ZAPD>" --non-interactive
|
||||
COMMAND ${CMAKE_COMMAND} -DSYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DTARGET_DIR="$<TARGET_FILE_DIR:ZAPD>" -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DBINARY_DIR=${CMAKE_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/copy-existing-otrs.cmake
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter
|
||||
COMMENT "Running asset extraction..."
|
||||
DEPENDS ZAPD
|
||||
BYPRODUCTS mm.otr ${CMAKE_SOURCE_DIR}/mm.otr ${CMAKE_SOURCE_DIR}/soh.otr
|
||||
)
|
||||
|
||||
# Target to generate headers
|
||||
add_custom_target(
|
||||
ExtractAssetHeaders
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$<TARGET_FILE:ZAPD>" --non-interactive --gen-headers
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter
|
||||
COMMENT "Generating asset headers..."
|
||||
DEPENDS ZAPD
|
||||
)
|
||||
|
||||
# Target to generate only soh.otr
|
||||
add_custom_target(
|
||||
GenerateSohOtr
|
||||
# CMake versions prior to 3.17 do not have the rm command, use remove instead for older versions
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<VERSION_LESS:${CMAKE_VERSION},3.17>,remove,rm> -f soh.otr
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$<TARGET_FILE:ZAPD>" --norom
|
||||
COMMAND ${CMAKE_COMMAND} -DSYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DTARGET_DIR="$<TARGET_FILE_DIR:ZAPD>" -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DBINARY_DIR=${CMAKE_BINARY_DIR} -DONLYSOHOTR=On -P ${CMAKE_CURRENT_SOURCE_DIR}/copy-existing-otrs.cmake
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter
|
||||
COMMENT "Generating soh.otr..."
|
||||
DEPENDS ZAPD
|
||||
)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
find_package(ImageMagick COMPONENTS convert)
|
||||
if (ImageMagick_FOUND)
|
||||
execute_process (
|
||||
COMMAND ${ImageMagick_convert_EXECUTABLE} mm/macosx/sohIcon.png -resize 512x512 ${CMAKE_BINARY_DIR}/sohIcon.png
|
||||
OUTPUT_VARIABLE outVar
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
#add_custom_target(CreateOSXIcons
|
||||
# COMMAND mkdir -p ${CMAKE_BINARY_DIR}/macosx/soh.iconset
|
||||
# COMMAND sips -z 16 16 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_16x16.png
|
||||
# COMMAND sips -z 32 32 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_16x16@2x.png
|
||||
# COMMAND sips -z 32 32 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_32x32.png
|
||||
# COMMAND sips -z 64 64 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_32x32@2x.png
|
||||
# COMMAND sips -z 128 128 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_128x128.png
|
||||
# COMMAND sips -z 256 256 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_128x128@2x.png
|
||||
# COMMAND sips -z 256 256 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_256x256.png
|
||||
# COMMAND sips -z 512 512 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_256x256@2x.png
|
||||
# COMMAND sips -z 512 512 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_512x512.png
|
||||
# COMMAND cp soh/macosx/sohIcon.png ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_512x512@2x.png
|
||||
# COMMAND iconutil -c icns -o ${CMAKE_BINARY_DIR}/macosx/soh.icns ${CMAKE_BINARY_DIR}/macosx/soh.iconset
|
||||
# WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
# COMMENT "Creating OSX icons ..."
|
||||
# )
|
||||
#add_dependencies(soh CreateOSXIcons)
|
||||
|
||||
install(TARGETS ZAPD DESTINATION ${CMAKE_BINARY_DIR}/assets/extractor)
|
||||
|
||||
set(PROGRAM_PERMISSIONS_EXECUTE OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ)
|
||||
|
||||
install(DIRECTORY "${CMAKE_SOURCE_DIR}/mm/assets/extractor/" DESTINATION ./assets/extractor)
|
||||
install(DIRECTORY "${CMAKE_SOURCE_DIR}/mm/assets/xml/" DESTINATION ./assets/extractor/xmls)
|
||||
install(DIRECTORY "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/filelists/" DESTINATION ./assets/extractor/filelists)
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ActorList_OoTMqDbg.txt" DESTINATION ./assets/extractor/symbols)
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ObjectList_OoTMqDbg.txt" DESTINATION ./assets/extractor/symbols)
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/OTRExporter/CFG/SymbolMap_OoTMqDbg.txt" DESTINATION ./assets/extractor/symbols)
|
||||
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/assets
|
||||
DESTINATION .
|
||||
PATTERN ZAPD.out
|
||||
PERMISSIONS ${PROGRAM_PERMISSIONS_EXECUTE}
|
||||
)
|
||||
|
||||
#install(CODE "
|
||||
# include(BundleUtilities)
|
||||
# fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/soh-macos\" \"\" \"${dirs}\")
|
||||
# ")
|
||||
|
||||
#endif()
|
||||
|
||||
#if(CMAKE_SYSTEM_NAME MATCHES "Windows|NintendoSwitch|CafeOS")
|
||||
#install(FILES ${CMAKE_SOURCE_DIR}/README.md DESTINATION . COMPONENT 2s2h RENAME readme.txt )
|
||||
#endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(CPACK_GENERATOR "External")
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Windows|NintendoSwitch|CafeOS")
|
||||
set(CPACK_GENERATOR "ZIP")
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
set(CPACK_GENERATOR "Bundle")
|
||||
endif()
|
||||
|
||||
#set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_SOURCE_DIR}/CMake/Packaging-2.cmake)
|
||||
#include(CMake/Packaging.cmake)
|
57
Dockerfile
Normal file
57
Dockerfile
Normal file
@ -0,0 +1,57 @@
|
||||
FROM ubuntu:latest
|
||||
|
||||
ARG MY_XAUTH_COOKIE
|
||||
|
||||
ENV LANG C.UTF-8
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN dpkg --add-architecture i386
|
||||
RUN apt-get update
|
||||
|
||||
RUN apt-get install -y \
|
||||
binutils:i386 \
|
||||
gcc-12:i386 \
|
||||
g++-12:i386 && \
|
||||
ln -sf /usr/bin/python3.10 /usr/bin/python3 && \
|
||||
ln -s /usr/bin/gcc-12 /usr/bin/gcc && \
|
||||
ln -s /usr/bin/gcc-12 /usr/bin/cc && \
|
||||
ln -s /usr/bin/g++-12 /usr/bin/g++ && \
|
||||
ln -s /usr/bin/g++-12 /usr/bin/c++
|
||||
|
||||
RUN apt-get install -y \
|
||||
libsdl2-dev:i386 \
|
||||
zlib1g-dev:i386 \
|
||||
libbz2-dev:i386 \
|
||||
libpng-dev:i386 \
|
||||
libboost-dev:i386 \
|
||||
libgles2-mesa-dev
|
||||
|
||||
RUN apt-get install -y \
|
||||
make \
|
||||
cmake \
|
||||
git \
|
||||
gdb \
|
||||
lld \
|
||||
python3.10 \
|
||||
ninja-build \
|
||||
lsb-release \
|
||||
clang-format
|
||||
|
||||
RUN git clone https://github.com/Perlmint/glew-cmake.git && \
|
||||
cmake -B glew-cmake/builddir -S glew-cmake -GNinja && \
|
||||
cmake --build glew-cmake/builddir && \
|
||||
cmake --install glew-cmake/builddir --prefix /usr && \
|
||||
mv /usr/lib/libglew-shared.so /usr/lib/libglew.so
|
||||
|
||||
RUN git clone https://github.com/libsdl-org/SDL_net.git -b SDL2 && \
|
||||
cmake -B SDL_net/build -S SDL_net -DCMAKE_BUILD_TYPE=Release && \
|
||||
cmake --build SDL_net/build --config Release --parallel && \
|
||||
cmake --install SDL_net/build --config Release
|
||||
|
||||
|
||||
RUN touch /root/.Xauthority && \
|
||||
xauth add $MY_XAUTH_COOKIE
|
||||
|
||||
|
||||
RUN mkdir /2ship
|
||||
WORKDIR /2ship
|
121
LICENSE
Normal file
121
LICENSE
Normal file
@ -0,0 +1,121 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
1
OTRExporter
Submodule
1
OTRExporter
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 6212ebc4407107340a76b3ab052f94170a42a3a6
|
1
ZAPDTR
Submodule
1
ZAPDTR
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 01615a6c4c6f8e95149fd52ab85b1ae970167bc3
|
1
libultraship
Submodule
1
libultraship
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 1dd5f43ffcf4d3d9d322da2408aca76bd41b0bb2
|
2
mm/.gitignore
vendored
2
mm/.gitignore
vendored
@ -7,7 +7,6 @@ __pycache__/
|
||||
.vscode/
|
||||
.vs/
|
||||
.idea/
|
||||
CMakeLists.txt
|
||||
cmake-build-debug
|
||||
venv/
|
||||
tags
|
||||
@ -55,3 +54,4 @@ docs/doxygen/
|
||||
.python-version
|
||||
.make_options
|
||||
.*env
|
||||
*.otr
|
1340
mm/2s2h/BenPort.cpp
Normal file
1340
mm/2s2h/BenPort.cpp
Normal file
File diff suppressed because it is too large
Load Diff
137
mm/2s2h/BenPort.h
Normal file
137
mm/2s2h/BenPort.h
Normal file
@ -0,0 +1,137 @@
|
||||
#ifndef OTR_GLOBALS_H
|
||||
#define OTR_GLOBALS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#define GAME_REGION_NTSC 0
|
||||
#define GAME_REGION_PAL 1
|
||||
|
||||
#define GAME_PLATFORM_N64 0
|
||||
#define GAME_PLATFORM_GC 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <Context.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
const std::string customMessageTableID = "BaseGameOverrides";
|
||||
const std::string appShortName = "soh";
|
||||
|
||||
class OTRGlobals {
|
||||
public:
|
||||
static OTRGlobals* Instance;
|
||||
|
||||
std::shared_ptr<LUS::Context> context;
|
||||
|
||||
OTRGlobals();
|
||||
~OTRGlobals();
|
||||
|
||||
bool HasMasterQuest();
|
||||
bool HasOriginal();
|
||||
uint32_t GetInterpolationFPS();
|
||||
std::shared_ptr<std::vector<std::string>> ListFiles(std::string path);
|
||||
|
||||
private:
|
||||
void CheckSaveFile(size_t sramSize) const;
|
||||
bool hasMasterQuest;
|
||||
bool hasOriginal;
|
||||
};
|
||||
|
||||
uint32_t IsGameMasterQuest();
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
void InitOTR(void);
|
||||
void DeinitOTR(void);
|
||||
void VanillaItemTable_Init();
|
||||
void OTRAudio_Init();
|
||||
void OTRMessage_Init();
|
||||
void InitAudio();
|
||||
void Graph_StartFrame();
|
||||
void Graph_ProcessGfxCommands(Gfx* commands);
|
||||
void Graph_ProcessFrame(void (*run_one_game_iter)(void));
|
||||
void OTRLogString(const char* src);
|
||||
void OTRGfxPrint(const char* str, void* printer, void (*printImpl)(void*, char));
|
||||
void OTRGetPixelDepthPrepare(float x, float y);
|
||||
uint16_t OTRGetPixelDepth(float x, float y);
|
||||
int32_t OTRGetLastScancode();
|
||||
uint32_t ResourceMgr_IsGameMasterQuest();
|
||||
uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum);
|
||||
uint32_t ResourceMgr_GameHasMasterQuest();
|
||||
uint32_t ResourceMgr_GameHasOriginal();
|
||||
uint32_t ResourceMgr_GetNumGameVersions();
|
||||
uint32_t ResourceMgr_GetGameVersion(int index);
|
||||
uint32_t ResourceMgr_GetGamePlatform(int index);
|
||||
uint32_t ResourceMgr_GetGameRegion(int index);
|
||||
void ResourceMgr_LoadDirectory(const char* resName);
|
||||
char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize);
|
||||
uint8_t ResourceMgr_FileExists(const char* resName);
|
||||
char* GetResourceDataByNameHandlingMQ(const char* path);
|
||||
void ResourceMgr_LoadFile(const char* resName);
|
||||
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
|
||||
uint8_t ResourceMgr_ResourceIsBackground(char* texPath);
|
||||
char* ResourceMgr_LoadJPEG(char* data, size_t dataSize);
|
||||
uint16_t ResourceMgr_LoadTexWidthByName(char* texPath);
|
||||
uint16_t ResourceMgr_LoadTexHeightByName(char* texPath);
|
||||
CollisionHeader* ResourceMgr_LoadColByName(const char* path);
|
||||
AnimatedMaterial* ResourceMgr_LoadAnimatedMatByName(const char* path);
|
||||
char* ResourceMgr_LoadTexOrDListByName(const char* filePath);
|
||||
char* ResourceMgr_LoadPlayerAnimByName(const char* animPath);
|
||||
AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path);
|
||||
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc);
|
||||
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc);
|
||||
Gfx* ResourceMgr_LoadGfxByName(const char* path);
|
||||
void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction);
|
||||
void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName);
|
||||
char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path);
|
||||
char* ResourceMgr_LoadArrayByName(const char* path);
|
||||
size_t ResourceMgr_GetArraySizeByName(const char* path);
|
||||
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc);
|
||||
char* ResourceMgr_LoadVtxArrayByName(const char* path);
|
||||
size_t ResourceMgr_GetVtxArraySizeByName(const char* path);
|
||||
Vtx* ResourceMgr_LoadVtxByName(char* path);
|
||||
|
||||
void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size);
|
||||
void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size);
|
||||
|
||||
uint64_t GetPerfCounter();
|
||||
struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path, SkelAnime* skelAnime);
|
||||
void ResourceMgr_UnregisterSkeleton(SkelAnime* skelAnime);
|
||||
void ResourceMgr_ClearSkeletons();
|
||||
s32* ResourceMgr_LoadCSByName(const char* path);
|
||||
int ResourceMgr_OTRSigCheck(char* imgData);
|
||||
uint64_t osGetTime(void);
|
||||
uint32_t osGetCount(void);
|
||||
uint32_t OTRGetCurrentWidth(void);
|
||||
uint32_t OTRGetCurrentHeight(void);
|
||||
float OTRGetAspectRatio(void);
|
||||
float OTRGetDimensionFromLeftEdge(float v);
|
||||
float OTRGetDimensionFromRightEdge(float v);
|
||||
int16_t OTRGetRectDimensionFromLeftEdge(float v);
|
||||
int16_t OTRGetRectDimensionFromRightEdge(float v);
|
||||
int AudioPlayer_Buffered(void);
|
||||
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 slot);
|
||||
void Controller_BlockGameInput();
|
||||
void Controller_UnblockGameInput();
|
||||
void Overlay_DisplayText(float duration, const char* text);
|
||||
void Overlay_DisplayText_Seconds(int seconds, const char* text);
|
||||
|
||||
void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* replacement);
|
||||
void CheckTracker_OnMessageClose();
|
||||
|
||||
int32_t GetGIID(uint32_t itemID);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
uint64_t GetUnixTimestamp();
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
BIN
mm/2s2h/Extractor/EndianCvt.o
Normal file
BIN
mm/2s2h/Extractor/EndianCvt.o
Normal file
Binary file not shown.
603
mm/2s2h/Extractor/Extract.cpp
Normal file
603
mm/2s2h/Extractor/Extract.cpp
Normal file
@ -0,0 +1,603 @@
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#include <winuser.h>
|
||||
#include <shlwapi.h>
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
#endif
|
||||
#include "Extract.h"
|
||||
#include "portable-file-dialogs.h"
|
||||
#include <Utils/BitConverter.h>
|
||||
|
||||
#ifdef unix
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define BSWAP32 _byteswap_ulong
|
||||
#define BSWAP16 _byteswap_ushort
|
||||
#elif __has_include(<byteswap.h>)
|
||||
#include <byteswap.h>
|
||||
#define BSWAP32 bswap_32
|
||||
#define BSWAP16 bswap_16
|
||||
#else
|
||||
#define BSWAP16(value) ((((value)&0xff) << 8) | ((value) >> 8))
|
||||
|
||||
#define BSWAP32(value) \
|
||||
(((uint32_t)BSWAP16((uint16_t)((value)&0xffff)) << 16) | (uint32_t)BSWAP16((uint16_t)((value) >> 16)))
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define UNREACHABLE __assume(0)
|
||||
#elif __llvm__
|
||||
#define UNREACHABLE __builtin_assume(0)
|
||||
#else
|
||||
#define UNREACHABLE __builtin_unreachable();
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <SDL2/SDL_messagebox.h>
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <unordered_map>
|
||||
#include <random>
|
||||
#include <string>
|
||||
|
||||
extern "C" uint32_t CRC32C(unsigned char* data, size_t dataSize);
|
||||
|
||||
static constexpr uint32_t OOT_PAL_GC = 0x09465AC3;
|
||||
static constexpr uint32_t OOT_PAL_MQ = 0x1D4136F3;
|
||||
static constexpr uint32_t OOT_PAL_GC_DBG1 = 0x871E1C92; // 03-21-2002 build
|
||||
static constexpr uint32_t OOT_PAL_GC_DBG2 = 0x87121EFE; // 03-13-2002 build
|
||||
static constexpr uint32_t OOT_PAL_GC_MQ_DBG = 0x917D18F6;
|
||||
static constexpr uint32_t OOT_PAL_10 = 0xB044B569;
|
||||
static constexpr uint32_t OOT_PAL_11 = 0xB2055FBD;
|
||||
static constexpr uint32_t MM_US_10 = 0x5354631C;
|
||||
|
||||
static const std::unordered_map<uint32_t, const char*> verMap = {
|
||||
{ MM_US_10, "U.S 1.0" },
|
||||
//{ OOT_PAL_GC, "PAL Gamecube" },
|
||||
//{ OOT_PAL_MQ, "PAL MQ" },
|
||||
//{ OOT_PAL_GC_DBG1, "PAL Debug 1" },
|
||||
//{ OOT_PAL_GC_DBG2, "PAL Debug 2" },
|
||||
//{ OOT_PAL_GC_MQ_DBG, "PAL MQ Debug" },
|
||||
//{ OOT_PAL_10, "PAL N64 1.0" },
|
||||
//{ OOT_PAL_11, "PAL N64 1.1" },
|
||||
};
|
||||
|
||||
// TODO only check the first 54MB of the rom.
|
||||
static constexpr std::array<const uint32_t, 10> goodCrcs = {
|
||||
|
||||
//0xfa8c0555, // MQ DBG 64MB (Original overdump)
|
||||
//0x8652ac4c, // MQ DBG 64MB
|
||||
//0x5B8A1EB7, // MQ DBG 64MB (Empty overdump)
|
||||
//0x1f731ffe, // MQ DBG 54MB
|
||||
//0x044b3982, // NMQ DBG 54MB
|
||||
//0xEB15D7B9, // NMQ DBG 64MB
|
||||
//0xDA8E61BF, // GC PAL
|
||||
//0x7A2FAE68, // GC MQ PAL
|
||||
//0xFD9913B1, // N64 PAL 1.0
|
||||
//0xE033FBBA, // N64 PAL 1.1
|
||||
};
|
||||
|
||||
enum class ButtonId : int {
|
||||
YES,
|
||||
NO,
|
||||
FIND,
|
||||
};
|
||||
|
||||
|
||||
void Extractor::ShowErrorBox(const char* title, const char* text) {
|
||||
#ifdef _WIN32
|
||||
MessageBoxA(nullptr, text, title, MB_OK | MB_ICONERROR);
|
||||
#else
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, text, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Extractor::ShowSizeErrorBox() const {
|
||||
std::unique_ptr<char[]> boxBuffer = std::make_unique<char[]>(mCurrentRomPath.size() + 100);
|
||||
snprintf(boxBuffer.get(), mCurrentRomPath.size() + 100,
|
||||
"The rom file %s was not a valid size. Was %zu MB, expecting 32, 54, or 64MB.", mCurrentRomPath.c_str(),
|
||||
mCurRomSize / MB_BASE);
|
||||
ShowErrorBox("Invalid Rom Size", boxBuffer.get());
|
||||
}
|
||||
|
||||
void Extractor::ShowCrcErrorBox() const {
|
||||
ShowErrorBox("Rom CRC invalid", "Rom CRC did not match the list of known good roms. Please find another.");
|
||||
}
|
||||
|
||||
int Extractor::ShowRomPickBox(uint32_t verCrc) const {
|
||||
std::unique_ptr<char[]> boxBuffer = std::make_unique<char[]>(mCurrentRomPath.size() + 100);
|
||||
SDL_MessageBoxData boxData = { 0 };
|
||||
SDL_MessageBoxButtonData buttons[3] = { { 0 } };
|
||||
int ret;
|
||||
|
||||
buttons[0].buttonid = 0;
|
||||
buttons[0].text = "Yes";
|
||||
buttons[0].flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
|
||||
buttons[1].buttonid = 1;
|
||||
buttons[1].text = "No";
|
||||
buttons[1].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
|
||||
buttons[2].buttonid = 2;
|
||||
buttons[2].text = "Find ROM";
|
||||
boxData.numbuttons = 3;
|
||||
boxData.flags = SDL_MESSAGEBOX_INFORMATION;
|
||||
boxData.message = boxBuffer.get();
|
||||
boxData.title = "Rom Detected";
|
||||
boxData.window = nullptr;
|
||||
|
||||
boxData.buttons = buttons;
|
||||
snprintf(boxBuffer.get(), mCurrentRomPath.size() + 100,
|
||||
"Rom detected: %s, Header CRC32: %8X. It appears to be: %s. Use this rom?", mCurrentRomPath.c_str(),
|
||||
verCrc, verMap.at(verCrc));
|
||||
|
||||
SDL_ShowMessageBox(&boxData, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Extractor::ShowYesNoBox(const char* title, const char* box) {
|
||||
int ret;
|
||||
#ifdef _WIN32
|
||||
ret = MessageBoxA(nullptr, box, title, MB_YESNO | MB_ICONQUESTION);
|
||||
#else
|
||||
SDL_MessageBoxData boxData = { 0 };
|
||||
SDL_MessageBoxButtonData buttons[2] = { { 0 } };
|
||||
|
||||
buttons[0].buttonid = IDYES;
|
||||
buttons[0].text = "Yes";
|
||||
buttons[0].flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
|
||||
buttons[1].buttonid = IDNO;
|
||||
buttons[1].text = "No";
|
||||
buttons[1].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
|
||||
boxData.numbuttons = 2;
|
||||
boxData.flags = SDL_MESSAGEBOX_INFORMATION;
|
||||
boxData.message = box;
|
||||
boxData.title = title;
|
||||
boxData.buttons = buttons;
|
||||
SDL_ShowMessageBox(&boxData, &ret);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Extractor::SetRomInfo(const std::string& path) {
|
||||
mCurrentRomPath = path;
|
||||
mCurRomSize = GetCurRomSize();
|
||||
}
|
||||
|
||||
void Extractor::FilterRoms(std::vector<std::string>& roms, RomSearchMode searchMode) {
|
||||
std::ifstream inFile;
|
||||
std::vector<std::string>::iterator it = roms.begin();
|
||||
|
||||
while (it != roms.end()) {
|
||||
std::string rom = *it;
|
||||
SetRomInfo(rom);
|
||||
|
||||
// Skip. We will handle rom size errors later on after filtering
|
||||
if (!ValidateRomSize()) {
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
inFile.open(rom, std::ios::in | std::ios::binary);
|
||||
inFile.read((char*)mRomData.get(), mCurRomSize);
|
||||
inFile.clear();
|
||||
inFile.close();
|
||||
|
||||
BitConverter::RomToBigEndian(mRomData.get(), mCurRomSize);
|
||||
|
||||
// Rom doesn't claim to be valid
|
||||
// Game type doesn't match search mode
|
||||
if (!verMap.contains(GetRomVerCrc()) ||
|
||||
(searchMode == RomSearchMode::Vanilla && IsMasterQuest()) ||
|
||||
(searchMode == RomSearchMode::MQ && !IsMasterQuest())) {
|
||||
it = roms.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
void Extractor::GetRoms(std::vector<std::string>& roms) {
|
||||
#ifdef _WIN32
|
||||
WIN32_FIND_DATAA ffd;
|
||||
HANDLE h = FindFirstFileA(".\\*", &ffd);
|
||||
|
||||
do {
|
||||
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
char* ext = PathFindExtensionA(ffd.cFileName);
|
||||
|
||||
// Check for any standard N64 rom file extensions.
|
||||
if ((strcmp(ext, ".z64") == 0) || (strcmp(ext, ".n64") == 0) || (strcmp(ext, ".v64") == 0))
|
||||
roms.push_back(ffd.cFileName);
|
||||
}
|
||||
} while (FindNextFileA(h, &ffd) != 0);
|
||||
// if (h != nullptr) {
|
||||
// CloseHandle(h);
|
||||
//}
|
||||
#elif unix
|
||||
// Open the directory of the app.
|
||||
DIR* d = opendir(".");
|
||||
struct dirent* dir;
|
||||
|
||||
if (d != NULL) {
|
||||
// Go through each file in the directory
|
||||
while ((dir = readdir(d)) != NULL) {
|
||||
struct stat path;
|
||||
|
||||
// Check if current entry is not folder
|
||||
stat(dir->d_name, &path);
|
||||
if (S_ISREG(path.st_mode)) {
|
||||
|
||||
// Get the position of the extension character.
|
||||
char* ext = strrchr(dir->d_name, '.');
|
||||
if (ext != NULL && (strcmp(ext, ".z64") == 0 || strcmp(ext, ".n64") == 0 ||
|
||||
strcmp(ext, ".v64") == 0)) {
|
||||
roms.push_back(dir->d_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
#else
|
||||
for (const auto& file : std::filesystem::directory_iterator("./")) {
|
||||
if (file.is_directory())
|
||||
continue;
|
||||
if ((file.path().extension() == ".n64") || (file.path().extension() == ".z64") ||
|
||||
(file.path().extension() == ".v64")) {
|
||||
roms.push_back((file.path()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Extractor::GetRomPathFromBox() {
|
||||
#ifdef _WIN32
|
||||
OPENFILENAMEA box = { 0 };
|
||||
char nameBuffer[512];
|
||||
nameBuffer[0] = 0;
|
||||
|
||||
box.lStructSize = sizeof(box);
|
||||
box.lpstrFile = nameBuffer;
|
||||
box.nMaxFile = sizeof(nameBuffer) / sizeof(nameBuffer[0]);
|
||||
box.lpstrTitle = "Open Rom";
|
||||
box.Flags = OFN_NOCHANGEDIR | OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
|
||||
box.lpstrFilter = "N64 Roms\0*.z64;*.v64;*.n64\0\0";
|
||||
if (!GetOpenFileNameA(&box)) {
|
||||
DWORD err = CommDlgExtendedError();
|
||||
// GetOpenFileName will return 0 but no error is set if the user just closes the box.
|
||||
if (err != 0) {
|
||||
const char* errStr = nullptr;
|
||||
switch (err) {
|
||||
case FNERR_BUFFERTOOSMALL:
|
||||
errStr = "Path buffer too small. Move file closer to root of your drive";
|
||||
break;
|
||||
case FNERR_INVALIDFILENAME:
|
||||
errStr = "File name for rom provided is invalid.";
|
||||
break;
|
||||
case FNERR_SUBCLASSFAILURE:
|
||||
errStr = "Failed to open a filebox because there is not enough RAM to do so.";
|
||||
break;
|
||||
}
|
||||
MessageBoxA(nullptr, "Box Error", errStr, MB_OK | MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// The box was closed without something being selected.
|
||||
if (nameBuffer[0] == 0) {
|
||||
return false;
|
||||
}
|
||||
mCurrentRomPath = nameBuffer;
|
||||
#else
|
||||
auto selection = pfd::open_file("Select a file", ".", { "N64 Roms", "*.z64 *.n64 *.v64" }).result();
|
||||
|
||||
if (selection.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mCurrentRomPath = selection[0];
|
||||
#endif
|
||||
mCurRomSize = GetCurRomSize();
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t Extractor::GetRomVerCrc() const {
|
||||
return BSWAP32(((uint32_t*)mRomData.get())[4]);
|
||||
}
|
||||
|
||||
size_t Extractor::GetCurRomSize() const {
|
||||
return std::filesystem::file_size(mCurrentRomPath);
|
||||
}
|
||||
|
||||
bool Extractor::ValidateAndFixRom() {
|
||||
// The MQ debug rom sometimes has the header patched to look like a US rom. Change it back
|
||||
if (GetRomVerCrc() == OOT_PAL_GC_MQ_DBG) {
|
||||
mRomData[0x3E] = 'P';
|
||||
}
|
||||
|
||||
const uint32_t actualCrc = CRC32C(mRomData.get(), mCurRomSize);
|
||||
|
||||
for (const uint32_t crc : goodCrcs) {
|
||||
if (actualCrc == crc) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Extractor::ValidateRomSize() const {
|
||||
if (mCurRomSize != MB32 && mCurRomSize != MB54 && mCurRomSize != MB64) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Extractor::ValidateRom(bool skipCrcTextBox) {
|
||||
if (!ValidateRomSize()) {
|
||||
ShowSizeErrorBox();
|
||||
return false;
|
||||
}
|
||||
if (!ValidateAndFixRom()) {
|
||||
if (!skipCrcTextBox) {
|
||||
ShowCrcErrorBox();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Extractor::ManuallySearchForRom() {
|
||||
std::ifstream inFile;
|
||||
|
||||
if (!GetRomPathFromBox()) {
|
||||
ShowErrorBox("No rom selected", "No Rom selected. Exiting");
|
||||
return false;
|
||||
}
|
||||
|
||||
inFile.open(mCurrentRomPath, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!inFile.is_open()) {
|
||||
return false; // TODO Handle error
|
||||
}
|
||||
|
||||
inFile.read((char*)mRomData.get(), mCurRomSize);
|
||||
inFile.close();
|
||||
BitConverter::RomToBigEndian(mRomData.get(), mCurRomSize);
|
||||
|
||||
if (!ValidateRom()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Extractor::ManuallySearchForRomMatchingType(RomSearchMode searchMode) {
|
||||
if (!ManuallySearchForRom()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char msgBuf[150];
|
||||
snprintf(msgBuf, 150, "The selected rom does not match the expected game type\nExpected type: %s.\n\nDo you want to search again?",
|
||||
searchMode == RomSearchMode::MQ ? "Master Quest" : "Vanilla");
|
||||
|
||||
while ((searchMode == RomSearchMode::Vanilla && IsMasterQuest()) ||
|
||||
(searchMode == RomSearchMode::MQ && !IsMasterQuest())) {
|
||||
int ret = ShowYesNoBox("Wrong Game Type", msgBuf);
|
||||
switch (ret) {
|
||||
case IDYES:
|
||||
if (!ManuallySearchForRom()) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
case IDNO:
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Extractor::Run(RomSearchMode searchMode) {
|
||||
std::vector<std::string> roms;
|
||||
std::ifstream inFile;
|
||||
|
||||
GetRoms(roms);
|
||||
FilterRoms(roms, searchMode);
|
||||
|
||||
if (roms.empty()) {
|
||||
int ret = ShowYesNoBox("No roms found", "No roms found. Look for one?");
|
||||
|
||||
switch (ret) {
|
||||
case IDYES:
|
||||
if (!ManuallySearchForRomMatchingType(searchMode)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case IDNO:
|
||||
ShowErrorBox("No rom selected", "No rom selected. Exiting");
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& rom : roms) {
|
||||
SetRomInfo(rom);
|
||||
|
||||
if (!ValidateRomSize()) {
|
||||
ShowSizeErrorBox();
|
||||
continue;
|
||||
}
|
||||
|
||||
inFile.open(rom, std::ios::in | std::ios::binary);
|
||||
inFile.read((char*)mRomData.get(), mCurRomSize);
|
||||
inFile.clear();
|
||||
inFile.close();
|
||||
BitConverter::RomToBigEndian(mRomData.get(), mCurRomSize);
|
||||
|
||||
int option = ShowRomPickBox(GetRomVerCrc());
|
||||
|
||||
if (option == (int)ButtonId::YES) {
|
||||
if (!ValidateRom(true)) {
|
||||
if (rom == roms.back()) {
|
||||
ShowCrcErrorBox();
|
||||
} else {
|
||||
ShowErrorBox("Rom CRC invalid",
|
||||
"Rom CRC did not match the list of known good roms. Trying the next one...");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
} else if (option == (int)ButtonId::FIND) {
|
||||
if (!ManuallySearchForRomMatchingType(searchMode)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
} else if (option == (int)ButtonId::NO) {
|
||||
if (rom == roms.back()) {
|
||||
ShowErrorBox("No rom provided", "No rom provided. Exiting");
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Extractor::IsMasterQuest() const {
|
||||
switch (GetRomVerCrc()) {
|
||||
case OOT_PAL_MQ:
|
||||
case OOT_PAL_GC_MQ_DBG:
|
||||
return true;
|
||||
case OOT_PAL_10:
|
||||
case OOT_PAL_11:
|
||||
case OOT_PAL_GC:
|
||||
case OOT_PAL_GC_DBG1:
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
const char* Extractor::GetZapdVerStr() const {
|
||||
switch (GetRomVerCrc()) {
|
||||
case OOT_PAL_GC:
|
||||
return "GC_NMQ_PAL_F";
|
||||
case OOT_PAL_MQ:
|
||||
return "GC_MQ_PAL_F";
|
||||
case OOT_PAL_GC_DBG1:
|
||||
return "GC_NMQ_D";
|
||||
case OOT_PAL_GC_MQ_DBG:
|
||||
return "GC_MQ_D";
|
||||
case OOT_PAL_10:
|
||||
return "N64_PAL_10";
|
||||
case OOT_PAL_11:
|
||||
return "N64_PAL_11";
|
||||
default:
|
||||
// We should never be in a state where this path happens.
|
||||
UNREACHABLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Extractor::Mkdtemp() {
|
||||
std::string temp_dir = std::filesystem::temp_directory_path().string();
|
||||
|
||||
// create 6 random alphanumeric characters
|
||||
static const char charset[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<> dist(0, sizeof(charset) - 1);
|
||||
|
||||
char randchr[7];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
randchr[i] = charset[dist(gen)];
|
||||
}
|
||||
randchr[6] = '\0';
|
||||
|
||||
std::string tmppath = temp_dir + "/extractor-" + randchr;
|
||||
std::filesystem::create_directory(tmppath);
|
||||
return tmppath;
|
||||
}
|
||||
|
||||
extern "C" int zapd_main(int argc, char** argv);
|
||||
|
||||
bool Extractor::CallZapd(std::string installPath, std::string exportdir) {
|
||||
constexpr int argc = 16;
|
||||
char xmlPath[1024];
|
||||
char confPath[1024];
|
||||
std::array<const char*, argc> argv;
|
||||
const char* version = GetZapdVerStr();
|
||||
const char* otrFile = IsMasterQuest() ? "oot-mq.otr" : "oot.otr";
|
||||
|
||||
std::string romPath = std::filesystem::absolute(mCurrentRomPath).string();
|
||||
installPath = std::filesystem::absolute(installPath).string();
|
||||
exportdir = std::filesystem::absolute(exportdir).string();
|
||||
// Work this out in the temporary folder
|
||||
std::string tempdir = Mkdtemp();
|
||||
std::string curdir = std::filesystem::current_path().string();
|
||||
#ifdef _WIN32
|
||||
std::filesystem::copy(installPath + "/assets", tempdir + "/assets",
|
||||
std::filesystem::copy_options::recursive | std::filesystem::copy_options::update_existing);
|
||||
#else
|
||||
std::filesystem::create_symlink(installPath + "/assets", tempdir + "/assets");
|
||||
#endif
|
||||
|
||||
std::filesystem::current_path(tempdir);
|
||||
|
||||
snprintf(xmlPath, 1024, "assets/extractor/xmls/%s", version);
|
||||
snprintf(confPath, 1024, "assets/extractor/Config_%s.xml", version);
|
||||
|
||||
argv[0] = "ZAPD";
|
||||
argv[1] = "ed";
|
||||
argv[2] = "-i";
|
||||
argv[3] = xmlPath;
|
||||
argv[4] = "-b";
|
||||
argv[5] = romPath.c_str();
|
||||
argv[6] = "-fl";
|
||||
argv[7] = "assets/extractor/filelists";
|
||||
argv[8] = "-gsf";
|
||||
argv[9] = "1";
|
||||
argv[10] = "-rconf";
|
||||
argv[11] = confPath;
|
||||
argv[12] = "-se";
|
||||
argv[13] = "OTR";
|
||||
argv[14] = "--otrfile";
|
||||
argv[15] = otrFile;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Grab a handle to the command window.
|
||||
HWND cmdWindow = GetConsoleWindow();
|
||||
|
||||
// Normally the command window is hidden. We want the window to be shown here so the user can see the progess of the extraction.
|
||||
ShowWindow(cmdWindow, SW_SHOW);
|
||||
SetWindowPos(cmdWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
||||
#endif
|
||||
|
||||
zapd_main(argc, (char**)argv.data());
|
||||
|
||||
#ifdef _WIN32
|
||||
// Hide the command window again.
|
||||
ShowWindow(cmdWindow, SW_HIDE);
|
||||
#endif
|
||||
|
||||
std::filesystem::copy(otrFile, exportdir + "/" + otrFile, std::filesystem::copy_options::overwrite_existing);
|
||||
|
||||
// Go back to where this game was executed from
|
||||
std::filesystem::current_path(curdir);
|
||||
std::filesystem::remove_all(tempdir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
64
mm/2s2h/Extractor/Extract.h
Normal file
64
mm/2s2h/Extractor/Extract.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef EXTRACT_H
|
||||
#define EXTRACT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
// Values come from windows.h
|
||||
#ifndef IDYES
|
||||
#define IDYES 6
|
||||
#endif
|
||||
#ifndef IDNO
|
||||
#define IDNO 7
|
||||
#endif
|
||||
|
||||
static constexpr size_t MB_BASE = 1024 * 1024;
|
||||
static constexpr size_t MB32 = 32 * MB_BASE;
|
||||
static constexpr size_t MB54 = 54 * MB_BASE;
|
||||
static constexpr size_t MB64 = 64 * MB_BASE;
|
||||
|
||||
enum class RomSearchMode {
|
||||
Both = 0,
|
||||
Vanilla = 1,
|
||||
MQ = 2,
|
||||
};
|
||||
|
||||
class Extractor {
|
||||
std::unique_ptr<unsigned char[]> mRomData = std::make_unique<unsigned char[]>(MB64);
|
||||
std::string mCurrentRomPath;
|
||||
size_t mCurRomSize = 0;
|
||||
|
||||
bool GetRomPathFromBox();
|
||||
|
||||
uint32_t GetRomVerCrc() const;
|
||||
size_t GetCurRomSize() const;
|
||||
bool ValidateAndFixRom();
|
||||
bool ValidateRomSize() const;
|
||||
|
||||
bool ValidateRom(bool skipCrcBox = false);
|
||||
const char* GetZapdVerStr() const;
|
||||
|
||||
void SetRomInfo(const std::string& path);
|
||||
|
||||
void FilterRoms(std::vector<std::string>& roms, RomSearchMode searchMode);
|
||||
void GetRoms(std::vector<std::string>& roms);
|
||||
void ShowSizeErrorBox() const;
|
||||
void ShowCrcErrorBox() const;
|
||||
int ShowRomPickBox(uint32_t verCrc) const;
|
||||
bool ManuallySearchForRom();
|
||||
bool ManuallySearchForRomMatchingType(RomSearchMode searchMode);
|
||||
|
||||
public:
|
||||
//TODO create some kind of abstraction for message boxes.
|
||||
static int ShowYesNoBox(const char* title, const char* text);
|
||||
static void ShowErrorBox(const char* title, const char* text);
|
||||
bool IsMasterQuest() const;
|
||||
|
||||
bool Run(RomSearchMode searchMode = RomSearchMode::Both);
|
||||
bool CallZapd(std::string installPath, std::string exportdir);
|
||||
const char* GetZapdStr();
|
||||
std::string Mkdtemp();
|
||||
};
|
||||
#endif
|
144
mm/2s2h/Extractor/FastCrc32C.c
Normal file
144
mm/2s2h/Extractor/FastCrc32C.c
Normal file
@ -0,0 +1,144 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Force the compiler to assume we have support for the CRC32 intrinsic. We will check for our selves later.
|
||||
// Clang will define both __llvm__ and __GNUC__ but GCC will only define __GNUC__. So we need to check for __llvm__ first.
|
||||
#if ((defined(__llvm__) && (defined(__x86_64__) || defined(__i386__))))
|
||||
#pragma clang attribute push(__attribute__((target("crc32"))), apply_to = function)
|
||||
#elif ((defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))))
|
||||
// GCC Only lets you enable all of sse4.2 so we will for just this file and reset it at the end.
|
||||
#pragma GCC push_options
|
||||
#pragma GCC target("sse4.2")
|
||||
#endif
|
||||
|
||||
// Include headers for the CRC32 intrinsic and cpuid instruction on windows. No need to do any other checks because it assumes the target will support CRC32
|
||||
#ifdef _WIN32
|
||||
#include <immintrin.h>
|
||||
#include <intrin.h>
|
||||
// Same as above but these platforms use slightly different headers
|
||||
#elif ((defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))))
|
||||
#include <nmmintrin.h>
|
||||
#include <cpuid.h>
|
||||
#elif defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
|
||||
// Nothing cause its a compiler builtin
|
||||
#else
|
||||
#define NO_CRC_INTRIN
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
|
||||
#define INTRIN_CRC32_64(crc, value) __asm__("crc32cx %w[c], %w[c], %x[v]" : [c] "+r"(crc) : [v] "r"(value))
|
||||
#define INTRIN_CRC32_32(crc, value) __asm__("crc32cw %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
|
||||
#define INTRIN_CRC32_16(crc, value) __asm__("crc32ch %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
|
||||
#define INTRIN_CRC32_8(crc, value) __asm__("crc32cb %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
|
||||
#elif defined(__GNUC__) || defined(_MSC_VER)
|
||||
#define INTRIN_CRC32_64(crc, data) crc = _mm_crc32_u64(crc, data)
|
||||
#define INTRIN_CRC32_32(crc, data) crc = _mm_crc32_u32(crc, data)
|
||||
#define INTRIN_CRC32_16(crc, data) crc = _mm_crc32_u16(crc, data)
|
||||
#define INTRIN_CRC32_8(crc, data) crc = _mm_crc32_u8(crc, data)
|
||||
#endif
|
||||
|
||||
static const uint32_t crc32Table[256] = {
|
||||
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL,
|
||||
0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, 0x105EC76FL, 0xE235446CL,
|
||||
0xF165B798L, 0x030E349BL, 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L,
|
||||
0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
|
||||
0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL,
|
||||
0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL,
|
||||
0x1642AE59L, 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L,
|
||||
0x6EF07595L, 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
|
||||
0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, 0x5125DAD3L,
|
||||
0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL,
|
||||
0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L,
|
||||
0x72966096L, 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
|
||||
0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, 0xB602C312L,
|
||||
0x44694011L, 0x5739B3E5L, 0xA55230E6L, 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, 0xCEB018DEL,
|
||||
0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L,
|
||||
0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
|
||||
0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L,
|
||||
0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, 0xA24BB5A6L, 0x502036A5L,
|
||||
0x4370C551L, 0xB11B4652L, 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL,
|
||||
0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
|
||||
0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L,
|
||||
0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L,
|
||||
0xE52CC12CL, 0x1747422FL, 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L,
|
||||
0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
|
||||
0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL,
|
||||
0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L,
|
||||
0x88D28022L, 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, 0xF36E6F75L, 0x0105EC76L, 0x12551F82L,
|
||||
0xE03E9C81L, 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
|
||||
0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
|
||||
};
|
||||
// On platforms that we know will never support a crc32 instruction (such as the WiiU) we will skip compiling this function in.
|
||||
#ifndef NO_CRC_INTRIN
|
||||
|
||||
static uint32_t CRC32IntrinImpl(unsigned char* data, size_t dataSize) {
|
||||
uint32_t ret = 0xFFFFFFFF;
|
||||
int64_t sizeSigned = dataSize;
|
||||
// Only 64bit platforms support doing a CRC32 operation on a 64bit value
|
||||
#if defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__)
|
||||
while ((sizeSigned -= sizeof(uint64_t)) >= 0) {
|
||||
INTRIN_CRC32_64(ret, *(uint64_t*)data);
|
||||
data += sizeof(uint64_t);
|
||||
}
|
||||
|
||||
if (sizeSigned & sizeof(uint32_t)) {
|
||||
INTRIN_CRC32_32(ret, *(uint32_t*)data);
|
||||
|
||||
data += sizeof(uint32_t);
|
||||
}
|
||||
// On 32 bit we can only do 32bit operations
|
||||
#elif defined(_M_IX86) || defined(__i386__)
|
||||
while ((sizeSigned -= sizeof(uint32_t)) >= 0) {
|
||||
INTRIN_CRC32_32(ret, *(uint32_t*)data);
|
||||
data += sizeof(uint32_t);
|
||||
}
|
||||
#endif
|
||||
if (sizeSigned & sizeof(uint16_t)) {
|
||||
INTRIN_CRC32_16(ret, *(uint16_t*)data);
|
||||
data += sizeof(uint16_t);
|
||||
}
|
||||
|
||||
if (sizeSigned & sizeof(uint8_t)) {
|
||||
INTRIN_CRC32_8(ret, *data);
|
||||
}
|
||||
|
||||
return ~ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t CRC32TableImpl(unsigned char* data, size_t dataSize) {
|
||||
const uint8_t* p = data;
|
||||
uint32_t crc = 0xFFFFFFFF;
|
||||
|
||||
while (dataSize--)
|
||||
crc = crc32Table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
uint32_t CRC32C(unsigned char* data, size_t dataSize) {
|
||||
#ifndef NO_CRC_INTRIN
|
||||
// Test to make sure the CPU supports the CRC32 intrinsic
|
||||
unsigned int cpuidData[4];
|
||||
#ifdef _WIN32
|
||||
__cpuid(cpuidData, 1);
|
||||
#elif __APPLE__ || (defined(__aarch64__) && defined(__ARM_FEATURE_CRC32))
|
||||
// Every Mac that supports SoH should support this instruction. Also check for ARM64 at the same time
|
||||
return CRC32IntrinImpl(data, dataSize);
|
||||
#else
|
||||
__get_cpuid(1, &cpuidData[0], &cpuidData[1], &cpuidData[2], &cpuidData[3]);
|
||||
#endif
|
||||
|
||||
if (cpuidData[2] & (1 << 20)) { // bit_SSE4_2
|
||||
return CRC32IntrinImpl(data, dataSize);
|
||||
}
|
||||
#endif // NO_CRC_INTRIN
|
||||
return CRC32TableImpl(data, dataSize);
|
||||
}
|
||||
|
||||
#if ((defined(__llvm__) && (defined(__x86_64__) || defined(__i386__))))
|
||||
#pragma clang attribute pop
|
||||
#elif ((defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))))
|
||||
#pragma GCC pop_options
|
||||
#else
|
||||
#endif
|
1887
mm/2s2h/Extractor/portable-file-dialogs.h
Normal file
1887
mm/2s2h/Extractor/portable-file-dialogs.h
Normal file
File diff suppressed because it is too large
Load Diff
216
mm/2s2h/SohGui.cpp
Normal file
216
mm/2s2h/SohGui.cpp
Normal file
@ -0,0 +1,216 @@
|
||||
//
|
||||
// SohGui.cpp
|
||||
// soh
|
||||
//
|
||||
// Created by David Chavez on 24.08.22.
|
||||
//
|
||||
|
||||
#include "SohGui.hpp"
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <ImGui/imgui.h>
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include <ImGui/imgui_internal.h>
|
||||
#include <libultraship/libultraship.h>
|
||||
#include <Fast3D/gfx_pc.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "graphic/Fast3D/gfx_metal.h"
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <port/switch/SwitchImpl.h>
|
||||
#endif
|
||||
|
||||
//#include "UIWidgets.hpp"
|
||||
#include "include/global.h"
|
||||
#include "include/z64audio.h"
|
||||
//#include "soh/SaveManager.h"
|
||||
//#include "OTRGlobals.h"
|
||||
//#include "soh/Enhancements/presets.h"
|
||||
//#include "2s2h/resource/type/Skeleton.h"
|
||||
#include "libultraship/libultraship.h"
|
||||
|
||||
//#ifdef ENABLE_CROWD_CONTROL
|
||||
//#include "Enhancements/crowd-control/CrowdControl.h"
|
||||
//#endif
|
||||
|
||||
//#include "Enhancements/game-interactor/GameInteractor.h"
|
||||
//#include "Enhancements/cosmetics/authenticGfxPatches.h"
|
||||
|
||||
bool ShouldClearTextureCacheAtEndOfFrame = false;
|
||||
bool isBetaQuestEnabled = false;
|
||||
|
||||
extern "C" {
|
||||
void enableBetaQuest() { isBetaQuestEnabled = true; }
|
||||
void disableBetaQuest() { isBetaQuestEnabled = false; }
|
||||
}
|
||||
|
||||
|
||||
namespace SohGui {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
static const char* chestSizeAndTextureMatchesContentsOptions[4] = { "Disabled", "Both", "Texture Only", "Size Only" };
|
||||
static const char* bunnyHoodOptions[3] = { "Disabled", "Faster Run & Longer Jump", "Faster Run" };
|
||||
static const char* allPowers[9] = {
|
||||
"Vanilla (1x)",
|
||||
"Double (2x)",
|
||||
"Quadruple (4x)",
|
||||
"Octuple (8x)",
|
||||
"Foolish (16x)",
|
||||
"Ridiculous (32x)",
|
||||
"Merciless (64x)",
|
||||
"Pure Torture (128x)",
|
||||
"OHKO (256x)" };
|
||||
static const char* subPowers[8] = { allPowers[0], allPowers[1], allPowers[2], allPowers[3], allPowers[4], allPowers[5], allPowers[6], allPowers[7] };
|
||||
static const char* subSubPowers[7] = { allPowers[0], allPowers[1], allPowers[2], allPowers[3], allPowers[4], allPowers[5], allPowers[6] };
|
||||
static const char* zFightingOptions[3] = { "Disabled", "Consistent Vanish", "No Vanish" };
|
||||
static const char* autosaveLabels[6] = { "Off", "New Location + Major Item", "New Location + Any Item", "New Location", "Major Item", "Any Item" };
|
||||
static const char* FastFileSelect[5] = { "File N.1", "File N.2", "File N.3", "Zelda Map Select (require OoT Debug Mode)", "File select" };
|
||||
static const char* bonkDamageValues[8] = {
|
||||
"No Damage",
|
||||
"0.25 Heart",
|
||||
"0.5 Heart",
|
||||
"1 Heart",
|
||||
"2 Hearts",
|
||||
"4 Hearts",
|
||||
"8 Hearts",
|
||||
"OHKO"
|
||||
};
|
||||
|
||||
static const inline std::vector<std::pair<const char*, const char*>> audioBackends = {
|
||||
#ifdef _WIN32
|
||||
{ "wasapi", "Windows Audio Session API" },
|
||||
#endif
|
||||
#if defined(__linux)
|
||||
{ "pulse", "PulseAudio" },
|
||||
#endif
|
||||
{ "sdl", "SDL Audio" }
|
||||
};
|
||||
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
std::string GetWindowButtonText(const char* text, bool menuOpen) {
|
||||
char buttonText[100] = "";
|
||||
if (menuOpen) {
|
||||
strcat(buttonText, ICON_FA_CHEVRON_RIGHT " ");
|
||||
}
|
||||
strcat(buttonText, text);
|
||||
if (!menuOpen) { strcat(buttonText, " "); }
|
||||
return buttonText;
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Delegates
|
||||
|
||||
std::shared_ptr<SohMenuBar> mSohMenuBar;
|
||||
|
||||
std::shared_ptr<LUS::GuiWindow> mConsoleWindow;
|
||||
std::shared_ptr<LUS::GuiWindow> mStatsWindow;
|
||||
std::shared_ptr<LUS::GuiWindow> mInputEditorWindow;
|
||||
std::shared_ptr<LUS::GuiWindow> mGfxDebuggerWindow;
|
||||
|
||||
//std::shared_ptr<AudioEditor> mAudioEditorWindow;
|
||||
//std::shared_ptr<GameControlEditor::GameControlEditorWindow> mGameControlEditorWindow;
|
||||
//std::shared_ptr<CosmeticsEditorWindow> mCosmeticsEditorWindow;
|
||||
//std::shared_ptr<ActorViewerWindow> mActorViewerWindow;
|
||||
//std::shared_ptr<ColViewerWindow> mColViewerWindow;
|
||||
//std::shared_ptr<SaveEditorWindow> mSaveEditorWindow;
|
||||
//std::shared_ptr<DLViewerWindow> mDLViewerWindow;
|
||||
//std::shared_ptr<GameplayStatsWindow> mGameplayStatsWindow;
|
||||
//std::shared_ptr<CheckTracker::CheckTrackerSettingsWindow> mCheckTrackerSettingsWindow;
|
||||
//std::shared_ptr<CheckTracker::CheckTrackerWindow> mCheckTrackerWindow;
|
||||
//std::shared_ptr<EntranceTrackerWindow> mEntranceTrackerWindow;
|
||||
//std::shared_ptr<ItemTrackerSettingsWindow> mItemTrackerSettingsWindow;
|
||||
//std::shared_ptr<ItemTrackerWindow> mItemTrackerWindow;
|
||||
//std::shared_ptr<RandomizerSettingsWindow> mRandomizerSettingsWindow;
|
||||
|
||||
void SetupGuiElements() {
|
||||
auto gui = LUS::Context::GetInstance()->GetWindow()->GetGui();
|
||||
|
||||
mSohMenuBar = std::make_shared<SohMenuBar>("gOpenMenuBar", CVarGetInteger("gOpenMenuBar", 0));
|
||||
gui->SetMenuBar(std::reinterpret_pointer_cast<LUS::GuiMenuBar>(mSohMenuBar));
|
||||
|
||||
if (gui->GetMenuBar() && !gui->GetMenuBar()->IsVisible()) {
|
||||
#if defined(__SWITCH__) || defined(__WIIU__)
|
||||
gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Press - to access enhancements menu");
|
||||
#else
|
||||
gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Press F1 to access enhancements menu");
|
||||
#endif
|
||||
}
|
||||
|
||||
mStatsWindow = gui->GetGuiWindow("Stats");
|
||||
if (mStatsWindow == nullptr) {
|
||||
SPDLOG_ERROR("Could not find stats window");
|
||||
}
|
||||
|
||||
mConsoleWindow = gui->GetGuiWindow("Console");
|
||||
if (mConsoleWindow == nullptr) {
|
||||
SPDLOG_ERROR("Could not find console window");
|
||||
}
|
||||
|
||||
mInputEditorWindow = gui->GetGuiWindow("Input Editor");
|
||||
if (mInputEditorWindow == nullptr) {
|
||||
SPDLOG_ERROR("Could not find input editor window");
|
||||
}
|
||||
|
||||
mGfxDebuggerWindow = gui->GetGuiWindow("GfxDebuggerWindow");
|
||||
if (mGfxDebuggerWindow == nullptr) {
|
||||
SPDLOG_ERROR("Could not find input GfxDebuggerWindow");
|
||||
}
|
||||
|
||||
/*
|
||||
mAudioEditorWindow = std::make_shared<AudioEditor>("gAudioEditor.WindowOpen", "Audio Editor");
|
||||
gui->AddGuiWindow(mAudioEditorWindow);
|
||||
mGameControlEditorWindow = std::make_shared<GameControlEditor::GameControlEditorWindow>("gGameControlEditorEnabled", "Game Control Editor");
|
||||
gui->AddGuiWindow(mGameControlEditorWindow);
|
||||
mCosmeticsEditorWindow = std::make_shared<CosmeticsEditorWindow>("gCosmeticsEditorEnabled", "Cosmetics Editor");
|
||||
gui->AddGuiWindow(mCosmeticsEditorWindow);
|
||||
mActorViewerWindow = std::make_shared<ActorViewerWindow>("gActorViewerEnabled", "Actor Viewer");
|
||||
gui->AddGuiWindow(mActorViewerWindow);
|
||||
mColViewerWindow = std::make_shared<ColViewerWindow>("gCollisionViewerEnabled", "Collision Viewer");
|
||||
gui->AddGuiWindow(mColViewerWindow);
|
||||
mSaveEditorWindow = std::make_shared<SaveEditorWindow>("gSaveEditorEnabled", "Save Editor");
|
||||
gui->AddGuiWindow(mSaveEditorWindow);
|
||||
mDLViewerWindow = std::make_shared<DLViewerWindow>("gDLViewerEnabled", "Display List Viewer");
|
||||
gui->AddGuiWindow(mDLViewerWindow);
|
||||
mGameplayStatsWindow = std::make_shared<GameplayStatsWindow>("gGameplayStatsEnabled", "Gameplay Stats");
|
||||
gui->AddGuiWindow(mGameplayStatsWindow);
|
||||
mCheckTrackerWindow = std::make_shared<CheckTracker::CheckTrackerWindow>("gCheckTrackerEnabled", "Check Tracker");
|
||||
gui->AddGuiWindow(mCheckTrackerWindow);
|
||||
mCheckTrackerSettingsWindow = std::make_shared<CheckTracker::CheckTrackerSettingsWindow>("gCheckTrackerSettingsEnabled", "Check Tracker Settings");
|
||||
gui->AddGuiWindow(mCheckTrackerSettingsWindow);
|
||||
mEntranceTrackerWindow = std::make_shared<EntranceTrackerWindow>("gEntranceTrackerEnabled","Entrance Tracker");
|
||||
gui->AddGuiWindow(mEntranceTrackerWindow);
|
||||
mItemTrackerWindow = std::make_shared<ItemTrackerWindow>("gItemTrackerEnabled", "Item Tracker");
|
||||
gui->AddGuiWindow(mItemTrackerWindow);
|
||||
mItemTrackerSettingsWindow = std::make_shared<ItemTrackerSettingsWindow>("gItemTrackerSettingsEnabled", "Item Tracker Settings");
|
||||
gui->AddGuiWindow(mItemTrackerSettingsWindow);
|
||||
mRandomizerSettingsWindow = std::make_shared<RandomizerSettingsWindow>("gRandomizerSettingsEnabled", "Randomizer Settings");
|
||||
gui->AddGuiWindow(mRandomizerSettingsWindow);
|
||||
*/
|
||||
}
|
||||
|
||||
void Destroy() {
|
||||
//mRandomizerSettingsWindow = nullptr;
|
||||
//mItemTrackerWindow = nullptr;
|
||||
//mItemTrackerSettingsWindow = nullptr;
|
||||
//mEntranceTrackerWindow = nullptr;
|
||||
//mCheckTrackerWindow = nullptr;
|
||||
//mCheckTrackerSettingsWindow = nullptr;
|
||||
//mGameplayStatsWindow = nullptr;
|
||||
//mDLViewerWindow = nullptr;
|
||||
//mSaveEditorWindow = nullptr;
|
||||
//mColViewerWindow = nullptr;
|
||||
//mActorViewerWindow = nullptr;
|
||||
//mCosmeticsEditorWindow = nullptr;
|
||||
//mGameControlEditorWindow = nullptr;
|
||||
//mAudioEditorWindow = nullptr;
|
||||
//mInputEditorWindow = nullptr;
|
||||
mStatsWindow = nullptr;
|
||||
mConsoleWindow = nullptr;
|
||||
mSohMenuBar = nullptr;
|
||||
}
|
||||
}
|
42
mm/2s2h/SohGui.hpp
Normal file
42
mm/2s2h/SohGui.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
//
|
||||
// SohGui.hpp
|
||||
// soh
|
||||
//
|
||||
// Created by David Chavez on 24.08.22.
|
||||
//
|
||||
|
||||
#ifndef SohGui_hpp
|
||||
#define SohGui_hpp
|
||||
|
||||
#include <stdio.h>
|
||||
#include "SohMenuBar.h"
|
||||
//#include "Enhancements/audio/AudioEditor.h"
|
||||
//#include "Enhancements/controls/GameControlEditor.h"
|
||||
//#include "Enhancements/cosmetics/CosmeticsEditor.h"
|
||||
//#include "Enhancements/debugger/actorViewer.h"
|
||||
//#include "Enhancements/debugger/colViewer.h"
|
||||
//#include "Enhancements/debugger/debugSaveEditor.h"
|
||||
//#include "Enhancements/debugger/dlViewer.h"
|
||||
//#include "Enhancements/gameplaystatswindow.h"
|
||||
//#include "Enhancements/randomizer/randomizer_check_tracker.h"
|
||||
//#include "Enhancements/randomizer/randomizer_entrance_tracker.h"
|
||||
//#include "Enhancements/randomizer/randomizer_item_tracker.h"
|
||||
//#include "Enhancements/randomizer/randomizer_settings_window.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void enableBetaQuest();
|
||||
void disableBetaQuest();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace SohGui {
|
||||
void SetupHooks();
|
||||
void SetupGuiElements();
|
||||
void Draw();
|
||||
void Destroy();
|
||||
}
|
||||
|
||||
#endif /* SohGui_hpp */
|
574
mm/2s2h/SohMenuBar.cpp
Normal file
574
mm/2s2h/SohMenuBar.cpp
Normal file
@ -0,0 +1,574 @@
|
||||
#include "SohMenuBar.h"
|
||||
#include "ImGui/imgui.h"
|
||||
#include "public/bridge/consolevariablebridge.h"
|
||||
#include <libultraship/libultraship.h>
|
||||
#include "UIWidgets.hpp"
|
||||
//#include "include/z64audio.h"
|
||||
//#include "OTRGlobals.h"
|
||||
#include "z64.h"
|
||||
//#include "Enhancements/game-interactor/GameInteractor.h"
|
||||
//#include "soh/Enhancements/presets.h"
|
||||
//#include "soh/Enhancements/mods.h"
|
||||
//#include "Enhancements/cosmetics/authenticGfxPatches.h"
|
||||
#ifdef ENABLE_CROWD_CONTROL
|
||||
#include "Enhancements/crowd-control/CrowdControl.h"
|
||||
#endif
|
||||
|
||||
|
||||
//#include "Enhancements/audio/AudioEditor.h"
|
||||
//#include "Enhancements/controls/GameControlEditor.h"
|
||||
//#include "Enhancements/cosmetics/CosmeticsEditor.h"
|
||||
//#include "Enhancements/debugger/actorViewer.h"
|
||||
//#include "Enhancements/debugger/colViewer.h"
|
||||
//#include "Enhancements/debugger/debugSaveEditor.h"
|
||||
//#include "Enhancements/debugger/dlViewer.h"
|
||||
//#include "Enhancements/gameplaystatswindow.h"
|
||||
//#include "Enhancements/randomizer/randomizer_check_tracker.h"
|
||||
//#include "Enhancements/randomizer/randomizer_entrance_tracker.h"
|
||||
//#include "Enhancements/randomizer/randomizer_item_tracker.h"
|
||||
//#include "Enhancements/randomizer/randomizer_settings_window.h"
|
||||
|
||||
extern bool ShouldClearTextureCacheAtEndOfFrame;
|
||||
extern bool isBetaQuestEnabled;
|
||||
|
||||
extern "C" PlayState* gPlayState;
|
||||
|
||||
enum SeqPlayers {
|
||||
/* 0 */ SEQ_BGM_MAIN,
|
||||
/* 1 */ SEQ_FANFARE,
|
||||
/* 2 */ SEQ_SFX,
|
||||
/* 3 */ SEQ_BGM_SUB,
|
||||
/* 4 */ SEQ_MAX
|
||||
};
|
||||
|
||||
std::string GetWindowButtonText(const char* text, bool menuOpen) {
|
||||
char buttonText[100] = "";
|
||||
if (menuOpen) {
|
||||
strcat(buttonText, ICON_FA_CHEVRON_RIGHT " ");
|
||||
}
|
||||
strcat(buttonText, text);
|
||||
if (!menuOpen) { strcat(buttonText, " "); }
|
||||
return buttonText;
|
||||
}
|
||||
|
||||
static const char* filters[3] = {
|
||||
#ifdef __WIIU__
|
||||
"",
|
||||
#else
|
||||
"Three-Point",
|
||||
#endif
|
||||
"Linear", "None"
|
||||
};
|
||||
|
||||
static const char* chestStyleMatchesContentsOptions[4] = { "Disabled", "Both", "Texture Only", "Size Only" };
|
||||
static const char* bunnyHoodOptions[3] = { "Disabled", "Faster Run & Longer Jump", "Faster Run" };
|
||||
static const char* mirroredWorldModes[9] = {
|
||||
"Disabled", "Always", "Random", "Random (Seeded)", "Dungeons",
|
||||
"Dungeons (Vanilla)", "Dungeons (MQ)", "Dungeons Random", "Dungeons Random (Seeded)",
|
||||
};
|
||||
static const char* enemyRandomizerModes[3] = { "Disabled", "Random", "Random (Seeded)" };
|
||||
static const char* allPowers[9] = {
|
||||
"Vanilla (1x)",
|
||||
"Double (2x)",
|
||||
"Quadruple (4x)",
|
||||
"Octuple (8x)",
|
||||
"Foolish (16x)",
|
||||
"Ridiculous (32x)",
|
||||
"Merciless (64x)",
|
||||
"Pure Torture (128x)",
|
||||
"OHKO (256x)" };
|
||||
static const char* subPowers[8] = { allPowers[0], allPowers[1], allPowers[2], allPowers[3], allPowers[4], allPowers[5], allPowers[6], allPowers[7] };
|
||||
static const char* subSubPowers[7] = { allPowers[0], allPowers[1], allPowers[2], allPowers[3], allPowers[4], allPowers[5], allPowers[6] };
|
||||
static const char* zFightingOptions[3] = { "Disabled", "Consistent Vanish", "No Vanish" };
|
||||
static const char* autosaveLabels[6] = { "Off", "New Location + Major Item", "New Location + Any Item", "New Location", "Major Item", "Any Item" };
|
||||
static const char* DebugSaveFileModes[3] = { "Off", "Vanilla", "Maxed" };
|
||||
static const char* FastFileSelect[5] = { "File N.1", "File N.2", "File N.3", "Zelda Map Select (require OoT Debug Mode)", "File select" };
|
||||
static const char* DekuStickCheat[3] = { "Normal", "Unbreakable", "Unbreakable + Always on Fire" };
|
||||
static const char* bonkDamageValues[8] = {
|
||||
"No Damage",
|
||||
"0.25 Heart",
|
||||
"0.5 Heart",
|
||||
"1 Heart",
|
||||
"2 Hearts",
|
||||
"4 Hearts",
|
||||
"8 Hearts",
|
||||
"OHKO"
|
||||
};
|
||||
static const char* timeTravelOptions[3] = { "Disabled", "Ocarina of Time", "Any Ocarina" };
|
||||
|
||||
extern "C" SaveContext gSaveContext;
|
||||
|
||||
namespace SohGui {
|
||||
|
||||
void DrawMenuBarIcon() {
|
||||
static bool gameIconLoaded = false;
|
||||
if (!gameIconLoaded) {
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTexture("Game_Icon", "textures/icons/gIcon.png");
|
||||
gameIconLoaded = true;
|
||||
}
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Game_Icon")) {
|
||||
#ifdef __SWITCH__
|
||||
ImVec2 iconSize = ImVec2(20.0f, 20.0f);
|
||||
float posScale = 1.0f;
|
||||
#elif defined(__WIIU__)
|
||||
ImVec2 iconSize = ImVec2(16.0f * 2, 16.0f * 2);
|
||||
float posScale = 2.0f;
|
||||
#else
|
||||
ImVec2 iconSize = ImVec2(16.0f, 16.0f);
|
||||
float posScale = 1.0f;
|
||||
#endif
|
||||
ImGui::SetCursorPos(ImVec2(5, 2.5f) * posScale);
|
||||
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Game_Icon"), iconSize);
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPos(ImVec2(25, 0) * posScale);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawShipMenu() {
|
||||
if (ImGui::BeginMenu("Ship")) {
|
||||
if (ImGui::MenuItem("Hide Menu Bar",
|
||||
#if !defined(__SWITCH__) && !defined(__WIIU__)
|
||||
"F1"
|
||||
#else
|
||||
"[-]"
|
||||
#endif
|
||||
)) {
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->GetMenuBar()->ToggleVisibility();
|
||||
}
|
||||
UIWidgets::Spacer(0);
|
||||
#if !defined(__SWITCH__) && !defined(__WIIU__)
|
||||
if (ImGui::MenuItem("Toggle Fullscreen", "F11")) {
|
||||
LUS::Context::GetInstance()->GetWindow()->ToggleFullscreen();
|
||||
}
|
||||
UIWidgets::Spacer(0);
|
||||
#endif
|
||||
if (ImGui::MenuItem("Reset",
|
||||
#ifdef __APPLE__
|
||||
"Command-R"
|
||||
#elif !defined(__SWITCH__) && !defined(__WIIU__)
|
||||
"Ctrl+R"
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
)) {
|
||||
std::reinterpret_pointer_cast<LUS::ConsoleWindow>(
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))
|
||||
->Dispatch("reset");
|
||||
}
|
||||
#if !defined(__SWITCH__) && !defined(__WIIU__)
|
||||
UIWidgets::Spacer(0);
|
||||
if (ImGui::MenuItem("Open App Files Folder")) {
|
||||
std::string filesPath = LUS::Context::GetInstance()->GetAppDirectoryPath();
|
||||
SDL_OpenURL(std::string("file:///" + std::filesystem::absolute(filesPath).string()).c_str());
|
||||
}
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
if (ImGui::MenuItem("Quit")) {
|
||||
LUS::Context::GetInstance()->GetWindow()->Close();
|
||||
}
|
||||
#endif
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
extern std::shared_ptr<LUS::GuiWindow> mInputEditorWindow;
|
||||
// extern std::shared_ptr<GameControlEditor::GameControlEditorWindow> mGameControlEditorWindow;
|
||||
|
||||
void DrawSettingsMenu() {
|
||||
if (ImGui::BeginMenu("Settings")) {
|
||||
if (ImGui::BeginMenu("Audio")) {
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f,
|
||||
1.0f, "", 1.0f, true, true, false, true);
|
||||
if (UIWidgets::PaddedEnhancementSliderFloat("Main Music Volume: %d %%", "##Main_Music_Vol",
|
||||
"gMainMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false,
|
||||
true)) {
|
||||
// Audio_SetGameVolume(SEQ_BGM_MAIN, CVarGetFloat("gMainMusicVolume", 1.0f));
|
||||
}
|
||||
if (UIWidgets::PaddedEnhancementSliderFloat("Sub Music Volume: %d %%", "##Sub_Music_Vol", "gSubMusicVolume",
|
||||
0.0f, 1.0f, "", 1.0f, true, true, false, true)) {
|
||||
// Audio_SetGameVolume(SEQ_BGM_SUB, CVarGetFloat("gSubMusicVolume", 1.0f));
|
||||
}
|
||||
if (UIWidgets::PaddedEnhancementSliderFloat("Sound Effects Volume: %d %%", "##Sound_Effect_Vol",
|
||||
"gSFXMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false,
|
||||
true)) {
|
||||
// Audio_SetGameVolume(SEQ_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f));
|
||||
}
|
||||
if (UIWidgets::PaddedEnhancementSliderFloat("Fanfare Volume: %d %%", "##Fanfare_Vol", "gFanfareVolume",
|
||||
0.0f, 1.0f, "", 1.0f, true, true, false, true)) {
|
||||
// Audio_SetGameVolume(SEQ_FANFARE, CVarGetFloat("gFanfareVolume", 1.0f));
|
||||
}
|
||||
|
||||
static std::unordered_map<LUS::AudioBackend, const char*> audioBackendNames = {
|
||||
{ LUS::AudioBackend::WASAPI, "Windows Audio Session API" },
|
||||
{ LUS::AudioBackend::PULSE, "PulseAudio" },
|
||||
{ LUS::AudioBackend::SDL, "SDL" },
|
||||
};
|
||||
|
||||
ImGui::Text("Audio API (Needs reload)");
|
||||
auto currentAudioBackend = LUS::Context::GetInstance()->GetAudio()->GetAudioBackend();
|
||||
|
||||
if (LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) {
|
||||
UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
|
||||
}
|
||||
if (ImGui::BeginCombo("##AApi", audioBackendNames[currentAudioBackend])) {
|
||||
for (uint8_t i = 0; i < LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size();
|
||||
i++) {
|
||||
auto backend = LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->data()[i];
|
||||
if (ImGui::Selectable(audioBackendNames[backend], backend == currentAudioBackend)) {
|
||||
LUS::Context::GetInstance()->GetAudio()->SetAudioBackend(backend);
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (LUS::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) {
|
||||
UIWidgets::ReEnableComponent("");
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
if (ImGui::BeginMenu("Controller")) {
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f));
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.0f));
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
//ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f));
|
||||
if (mInputEditorWindow) {
|
||||
if (ImGui::Button(
|
||||
GetWindowButtonText("Controller Mapping", CVarGetInteger("gControllerConfigurationEnabled", 0))
|
||||
.c_str(),
|
||||
ImVec2(-1.0f, 0.0f))) {
|
||||
mInputEditorWindow->ToggleVisibility();
|
||||
}
|
||||
}
|
||||
// if (mGameControlEditorWindow) {
|
||||
// if (ImGui::Button(GetWindowButtonText("Additional Controller Options",
|
||||
// CVarGetInteger("gGameControlEditorEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) {
|
||||
// mGameControlEditorWindow->ToggleVisibility();
|
||||
//}
|
||||
|
||||
ImGui::EndMenu();
|
||||
|
||||
}
|
||||
UIWidgets::PaddedSeparator();
|
||||
//ImGui::PopStyleColor(1);
|
||||
//ImGui::PopStyleVar(3);
|
||||
#ifndef __SWITCH__
|
||||
UIWidgets::EnhancementCheckbox("Menubar Controller Navigation", "gControlNav");
|
||||
UIWidgets::Tooltip("Allows controller navigation of the SOH menu bar (Settings, Enhancements,...)\nCAUTION: "
|
||||
"This will disable game inputs while the menubar is visible.\n\nD-pad to move between "
|
||||
"items, A to select, and X to grab focus on the menu bar");
|
||||
#endif
|
||||
UIWidgets::PaddedEnhancementCheckbox("Show Inputs", "gInputEnabled", true, false);
|
||||
UIWidgets::Tooltip("Shows currently pressed inputs on the bottom right of the screen");
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f,
|
||||
false, true, true, false);
|
||||
UIWidgets::Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting");
|
||||
UIWidgets::PaddedEnhancementSliderInt("Simulated Input Lag: %d frames", "##SimulatedInputLag",
|
||||
"gSimulatedInputLag", 0, 6, "", 0, true, true, false);
|
||||
UIWidgets::Tooltip("Buffers your inputs to be executed a specified amount of frames later");
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
if (ImGui::BeginMenu("Graphics")) {
|
||||
#ifndef __APPLE__
|
||||
if (UIWidgets::EnhancementSliderFloat("Internal Resolution: %d %%", "##IMul", "gInternalResolution", 0.5f, 2.0f,
|
||||
"", 1.0f, true)) {
|
||||
LUS::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(CVarGetFloat("gInternalResolution", 1));
|
||||
};
|
||||
UIWidgets::Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but effective "
|
||||
"form of anti-aliasing");
|
||||
#endif
|
||||
#ifndef __WIIU__
|
||||
if (UIWidgets::PaddedEnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "", 1, true, true,
|
||||
false)) {
|
||||
LUS::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger("gMSAAValue", 1));
|
||||
};
|
||||
UIWidgets::Tooltip("Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel");
|
||||
#endif
|
||||
|
||||
{ // FPS Slider
|
||||
const int minFps = 20;
|
||||
static int maxFps;
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) {
|
||||
maxFps = 360;
|
||||
} else {
|
||||
maxFps = LUS::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
|
||||
}
|
||||
// int currentFps = fmax(fmin(OTRGlobals::Instance->GetInterpolationFPS(), maxFps), minFps);
|
||||
int currentFps = 20;
|
||||
bool matchingRefreshRate =
|
||||
CVarGetInteger("gMatchRefreshRate", 0) &&
|
||||
LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() != LUS::WindowBackend::DX11;
|
||||
UIWidgets::PaddedEnhancementSliderInt((currentFps == 20) ? "FPS: Original (20)" : "FPS: %d",
|
||||
"##FPSInterpolation", "gInterpolationFPS", minFps, maxFps, "", 20,
|
||||
true, true, false, matchingRefreshRate);
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) {
|
||||
UIWidgets::Tooltip(
|
||||
"Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is purely "
|
||||
"visual and does not impact game logic, execution of glitches etc.\n\n"
|
||||
"A higher target FPS than your monitor's refresh rate will waste resources, and might give a worse "
|
||||
"result.");
|
||||
} else {
|
||||
UIWidgets::Tooltip(
|
||||
"Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is purely "
|
||||
"visual and does not impact game logic, execution of glitches etc.");
|
||||
}
|
||||
} // END FPS Slider
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) {
|
||||
UIWidgets::Spacer(0);
|
||||
if (ImGui::Button("Match Refresh Rate")) {
|
||||
int hz = LUS::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
|
||||
if (hz >= 20 && hz <= 360) {
|
||||
CVarSetInteger("gInterpolationFPS", hz);
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Match Refresh Rate", "gMatchRefreshRate", true, false);
|
||||
}
|
||||
UIWidgets::Tooltip("Matches interpolation value to the current game's window refresh rate");
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) {
|
||||
UIWidgets::PaddedEnhancementSliderInt(
|
||||
CVarGetInteger("gExtraLatencyThreshold", 80) == 0 ? "Jitter fix: Off" : "Jitter fix: >= %d FPS",
|
||||
"##ExtraLatencyThreshold", "gExtraLatencyThreshold", 0, 360, "", 80, true, true, false);
|
||||
UIWidgets::Tooltip("When Interpolation FPS setting is at least this threshold, add one frame of input lag "
|
||||
"(e.g. 16.6 ms for 60 FPS) in order to avoid jitter. This setting allows the CPU to "
|
||||
"work on one frame while GPU works on the previous frame.\nThis setting should be used "
|
||||
"when your computer is too slow to do CPU + GPU work in time.");
|
||||
}
|
||||
|
||||
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
|
||||
static std::unordered_map<LUS::WindowBackend, const char*> windowBackendNames = {
|
||||
{ LUS::WindowBackend::DX11, "DirectX" },
|
||||
{ LUS::WindowBackend::SDL_OPENGL, "OpenGL" },
|
||||
{ LUS::WindowBackend::SDL_METAL, "Metal" },
|
||||
{ LUS::WindowBackend::GX2, "GX2" }
|
||||
};
|
||||
|
||||
ImGui::Text("Renderer API (Needs reload)");
|
||||
LUS::WindowBackend runningWindowBackend = LUS::Context::GetInstance()->GetWindow()->GetWindowBackend();
|
||||
LUS::WindowBackend configWindowBackend;
|
||||
int configWindowBackendId = LUS::Context::GetInstance()->GetConfig()->GetInt("Window.Backend.Id", -1);
|
||||
if (configWindowBackendId != -1 &&
|
||||
configWindowBackendId < static_cast<int>(LUS::WindowBackend::BACKEND_COUNT)) {
|
||||
configWindowBackend = static_cast<LUS::WindowBackend>(configWindowBackendId);
|
||||
} else {
|
||||
configWindowBackend = runningWindowBackend;
|
||||
}
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) {
|
||||
UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
|
||||
}
|
||||
if (ImGui::BeginCombo("##RApi", windowBackendNames[configWindowBackend])) {
|
||||
for (size_t i = 0; i < LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size();
|
||||
i++) {
|
||||
auto backend = LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->data()[i];
|
||||
if (ImGui::Selectable(windowBackendNames[backend], backend == configWindowBackend)) {
|
||||
LUS::Context::GetInstance()->GetConfig()->SetInt("Window.Backend.Id", static_cast<int>(backend));
|
||||
LUS::Context::GetInstance()->GetConfig()->SetString("Window.Backend.Name",
|
||||
windowBackendNames[backend]);
|
||||
LUS::Context::GetInstance()->GetConfig()->Save();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) {
|
||||
UIWidgets::ReEnableComponent("");
|
||||
}
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Enable Vsync", "gVsyncEnabled", true, false);
|
||||
}
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->SupportsWindowedFullscreen()) {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Windowed fullscreen", "gSdlWindowedFullscreen", true, false);
|
||||
}
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetGui()->SupportsViewports()) {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Allow multi-windows", "gEnableMultiViewports", true, false, false, "",
|
||||
UIWidgets::CheckboxGraphics::Cross, true);
|
||||
UIWidgets::Tooltip("Allows windows to be able to be dragged off of the main game window. Requires a reload "
|
||||
"to take effect.");
|
||||
}
|
||||
|
||||
// If more filters are added to LUS, make sure to add them to the filters list here
|
||||
ImGui::Text("Texture Filter (Needs reload)");
|
||||
|
||||
UIWidgets::EnhancementCombobox("gTextureFilter", filters, FILTER_THREE_POINT);
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->DrawSettings();
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
if (ImGui::BeginMenu("Languages")) {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Translate Title Screen", "gTitleScreenTranslation");
|
||||
if (UIWidgets::EnhancementRadioButton("English", "gLanguages", LANGUAGE_ENG)) {
|
||||
// GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSetGameLanguage>();
|
||||
}
|
||||
if (UIWidgets::EnhancementRadioButton("German", "gLanguages", LANGUAGE_GER)) {
|
||||
// GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSetGameLanguage>();
|
||||
}
|
||||
// if (UIWidgets::EnhancementRadioButton("French", "gLanguages", LANGUAGE_FRA)) {
|
||||
// GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSetGameLanguage>();
|
||||
//}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
if (ImGui::BeginMenu("Accessibility")) {
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
UIWidgets::PaddedEnhancementCheckbox("Text to Speech", "gA11yTTS");
|
||||
UIWidgets::Tooltip("Enables text to speech for in game dialog");
|
||||
#endif
|
||||
UIWidgets::PaddedEnhancementCheckbox("Disable Idle Camera Re-Centering", "gA11yDisableIdleCam");
|
||||
UIWidgets::Tooltip("Disables the automatic re-centering of the camera when idle.");
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
//ImGui::EndMenu();
|
||||
}
|
||||
|
||||
extern std::shared_ptr<LUS::GuiWindow> mStatsWindow;
|
||||
extern std::shared_ptr<LUS::GuiWindow> mConsoleWindow;
|
||||
extern std::shared_ptr<LUS::GuiWindow> mGfxDebuggerWindow;
|
||||
// extern std::shared_ptr<SaveEditorWindow> mSaveEditorWindow;
|
||||
// extern std::shared_ptr<ColViewerWindow> mColViewerWindow;
|
||||
// extern std::shared_ptr<ActorViewerWindow> mActorViewerWindow;
|
||||
// extern std::shared_ptr<DLViewerWindow> mDLViewerWindow;
|
||||
|
||||
void DrawDeveloperToolsMenu() {
|
||||
if (ImGui::BeginMenu("Developer Tools")) {
|
||||
UIWidgets::EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled");
|
||||
UIWidgets::Tooltip("Enables Debug Mode, allowing you to select maps with L + R + Z, noclip with L + D-pad "
|
||||
"Right, and open the debug menu with L on the pause screen");
|
||||
if (CVarGetInteger("gDebugEnabled", 0)) {
|
||||
ImGui::Text("Debug Save File Mode:");
|
||||
UIWidgets::EnhancementCombobox("gDebugSaveFileMode", DebugSaveFileModes, 1);
|
||||
UIWidgets::Tooltip("Changes the behaviour of debug file select creation (creating a save file on slot 1 "
|
||||
"with debug mode on)\n"
|
||||
"- Off: The debug save file will be a normal savefile\n"
|
||||
"- Vanilla: The debug save file will be the debug save file from the original game\n"
|
||||
"- Maxed: The debug save file will be a save file with all of the items & upgrades");
|
||||
}
|
||||
UIWidgets::PaddedEnhancementCheckbox("OoT Skulltula Debug", "gSkulltulaDebugEnabled", true, false);
|
||||
UIWidgets::Tooltip("Enables Skulltula Debug, when moving the cursor in the menu above various map icons (boss "
|
||||
"key, compass, map screen locations, etc) will set the GS bits in that area.\nUSE WITH "
|
||||
"CAUTION AS IT DOES NOT UPDATE THE GS COUNT.");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Fast File Select", "gSkipLogoTitle", true, false);
|
||||
UIWidgets::Tooltip(
|
||||
"Load the game to the selected menu or file\n\"Zelda Map Select\" require debug mode else you will "
|
||||
"fallback to File choose menu\nUsing a file number that don't have save will create a save file only if "
|
||||
"you toggle on \"Create a new save if none ?\" else it will bring you to the File choose menu");
|
||||
if (CVarGetInteger("gSkipLogoTitle", 0)) {
|
||||
ImGui::Text("Loading:");
|
||||
UIWidgets::EnhancementCombobox("gSaveFileID", FastFileSelect, 0);
|
||||
};
|
||||
UIWidgets::PaddedEnhancementCheckbox("Better Debug Warp Screen", "gBetterDebugWarpScreen", true, false);
|
||||
UIWidgets::Tooltip("Optimized debug warp screen, with the added ability to chose entrances and time of day");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Debug Warp Screen Translation", "gDebugWarpScreenTranslation", true,
|
||||
false, false, "", UIWidgets::CheckboxGraphics::Cross, true);
|
||||
UIWidgets::Tooltip("Translate the Debug Warp Screen based on the game language");
|
||||
UIWidgets::PaddedSeparator();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f));
|
||||
if (mStatsWindow) {
|
||||
if (ImGui::Button(GetWindowButtonText("Stats", CVarGetInteger("gStatsEnabled", 0)).c_str(),
|
||||
ImVec2(-1.0f, 0.0f))) {
|
||||
mStatsWindow->ToggleVisibility();
|
||||
}
|
||||
UIWidgets::Tooltip("Shows the stats window, with your FPS and frametimes, and the OS you're playing on");
|
||||
}
|
||||
UIWidgets::Spacer(0);
|
||||
if (mConsoleWindow) {
|
||||
if (ImGui::Button(GetWindowButtonText("Console", CVarGetInteger("gConsoleEnabled", 0)).c_str(),
|
||||
ImVec2(-1.0f, 0.0f))) {
|
||||
mConsoleWindow->ToggleVisibility();
|
||||
}
|
||||
UIWidgets::Tooltip(
|
||||
"Enables the console window, allowing you to input commands, type help for some examples");
|
||||
}
|
||||
UIWidgets::Spacer(0);
|
||||
if (mGfxDebuggerWindow) {
|
||||
if (ImGui::Button(GetWindowButtonText("Gfx Debugger", CVarGetInteger("gGfxDebuggerEnabled", 0)).c_str(),
|
||||
ImVec2(-1.0f, 0.0f))) {
|
||||
mGfxDebuggerWindow->ToggleVisibility();
|
||||
}
|
||||
UIWidgets::Tooltip(
|
||||
"Enables the Gfx Debugger window, allowing you to input commands, type help for some examples");
|
||||
}
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
// if (mSaveEditorWindow) {
|
||||
// if (ImGui::Button(GetWindowButtonText("Save Editor", CVarGetInteger("gSaveEditorEnabled", 0)).c_str(),
|
||||
// ImVec2(-1.0f, 0.0f))) {
|
||||
// //mSaveEditorWindow->ToggleVisibility();
|
||||
// }
|
||||
// }
|
||||
// UIWidgets::Spacer(0);
|
||||
// if (mColViewerWindow) {
|
||||
// if (ImGui::Button(GetWindowButtonText("Collision Viewer", CVarGetInteger("gCollisionViewerEnabled",
|
||||
// 0)).c_str(), ImVec2(-1.0f, 0.0f))) {
|
||||
// //mColViewerWindow->ToggleVisibility();
|
||||
// }
|
||||
// }
|
||||
// UIWidgets::Spacer(0);
|
||||
// if (mActorViewerWindow) {
|
||||
// if (ImGui::Button(GetWindowButtonText("Actor Viewer", CVarGetInteger("gActorViewerEnabled", 0)).c_str(),
|
||||
// ImVec2(-1.0f, 0.0f))) {
|
||||
// //mActorViewerWindow->ToggleVisibility();
|
||||
// }
|
||||
// }
|
||||
// UIWidgets::Spacer(0);
|
||||
// if (mDLViewerWindow) {
|
||||
// if (ImGui::Button(GetWindowButtonText("Display List Viewer", CVarGetInteger("gDLViewerEnabled",
|
||||
// 0)).c_str(), ImVec2(-1.0f, 0.0f))) {
|
||||
// //mDLViewerWindow->ToggleVisibility();
|
||||
// }
|
||||
// }
|
||||
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void SohMenuBar::DrawElement() {
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
static ImVec2 sWindowPadding(8.0f, 8.0f);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, sWindowPadding);
|
||||
|
||||
ImGui::SetCursorPosY(0.0f);
|
||||
DrawSettingsMenu();
|
||||
|
||||
ImGui::SetCursorPosY(0.0f);
|
||||
|
||||
DrawDeveloperToolsMenu();
|
||||
|
||||
ImGui::SetCursorPosY(0.0f);
|
||||
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
}
|
||||
}
|
||||
// namespace SohGui
|
16
mm/2s2h/SohMenuBar.h
Normal file
16
mm/2s2h/SohMenuBar.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
//#include <libultraship/libultraship.h>
|
||||
#include "window/gui/GuiMenuBar.h"
|
||||
#include "window/gui/GuiElement.h"
|
||||
|
||||
namespace SohGui {
|
||||
class SohMenuBar : public LUS::GuiMenuBar {
|
||||
public:
|
||||
using LUS::GuiMenuBar::GuiMenuBar;
|
||||
protected:
|
||||
void DrawElement() override;
|
||||
void InitElement() override {};
|
||||
void UpdateElement() override {};
|
||||
};
|
||||
} // namespace SohGui
|
716
mm/2s2h/UIWidgets.cpp
Normal file
716
mm/2s2h/UIWidgets.cpp
Normal file
@ -0,0 +1,716 @@
|
||||
//
|
||||
// UIWidgets.cpp
|
||||
// soh
|
||||
//
|
||||
// Created by David Chavez on 25.08.22.
|
||||
//
|
||||
|
||||
#include "UIWidgets.hpp"
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include <ImGui/imgui_internal.h>
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
#include <libultraship/libultra/types.h>
|
||||
//#include "soh/Enhancements/cosmetics/CosmeticsEditor.h"
|
||||
|
||||
namespace UIWidgets {
|
||||
|
||||
// MARK: - Layout Helper
|
||||
|
||||
// Automatically adds newlines to break up text longer than a specified number of characters
|
||||
// Manually included newlines will still be respected and reset the line length
|
||||
// If line is midword when it hits the limit, text should break at the last encountered space
|
||||
char* WrappedText(const char* text, unsigned int charactersPerLine) {
|
||||
std::string newText(text);
|
||||
const size_t tipLength = newText.length();
|
||||
int lastSpace = -1;
|
||||
int currentLineLength = 0;
|
||||
for (unsigned int currentCharacter = 0; currentCharacter < tipLength; currentCharacter++) {
|
||||
if (newText[currentCharacter] == '\n') {
|
||||
currentLineLength = 0;
|
||||
lastSpace = -1;
|
||||
continue;
|
||||
} else if (newText[currentCharacter] == ' ') {
|
||||
lastSpace = currentCharacter;
|
||||
}
|
||||
|
||||
if ((currentLineLength >= charactersPerLine) && (lastSpace >= 0)) {
|
||||
newText[lastSpace] = '\n';
|
||||
currentLineLength = currentCharacter - lastSpace - 1;
|
||||
lastSpace = -1;
|
||||
}
|
||||
currentLineLength++;
|
||||
}
|
||||
|
||||
return strdup(newText.c_str());
|
||||
}
|
||||
|
||||
char* WrappedText(const std::string& text, unsigned int charactersPerLine) {
|
||||
return WrappedText(text.c_str(), charactersPerLine);
|
||||
}
|
||||
|
||||
void SetLastItemHoverText(const std::string& text) {
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("%s", WrappedText(text, 60));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void SetLastItemHoverText(const char* text) {
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("%s", WrappedText(text, 60));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a "?" next to the previous ImGui item with a custom tooltip
|
||||
void InsertHelpHoverText(const std::string& text) {
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "?");
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("%s", WrappedText(text, 60));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void InsertHelpHoverText(const char* text) {
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "?");
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("%s", WrappedText(text, 60));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - UI Elements
|
||||
|
||||
void Tooltip(const char* text) {
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s", WrappedText(text));
|
||||
}
|
||||
}
|
||||
|
||||
void Spacer(float height) {
|
||||
ImGui::Dummy(ImVec2(0.0f, height));
|
||||
}
|
||||
|
||||
void PaddedSeparator(bool padTop, bool padBottom, float extraVerticalTopPadding, float extraVerticalBottomPadding) {
|
||||
if (padTop) {
|
||||
Spacer(extraVerticalTopPadding);
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (padBottom) {
|
||||
Spacer(extraVerticalBottomPadding);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderCross(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz) {
|
||||
float thickness = ImMax(sz / 5.0f, 1.0f);
|
||||
sz -= thickness * 0.5f;
|
||||
pos += ImVec2(thickness * 0.25f, thickness * 0.25f);
|
||||
|
||||
draw_list->PathLineTo(ImVec2(pos.x, pos.y));
|
||||
draw_list->PathLineTo(ImVec2(pos.x + sz, pos.y + sz));
|
||||
draw_list->PathStroke(col, 0, thickness);
|
||||
|
||||
draw_list->PathLineTo(ImVec2(pos.x + sz, pos.y));
|
||||
draw_list->PathLineTo(ImVec2(pos.x, pos.y + sz));
|
||||
draw_list->PathStroke(col, 0, thickness);
|
||||
}
|
||||
|
||||
bool CustomCheckbox(const char* label, bool* v, bool disabled, CheckboxGraphics disabledGraphic) {
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
if (window->SkipItems) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
|
||||
|
||||
const float square_sz = ImGui::GetFrameHeight();
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f));
|
||||
ImGui::ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ImGui::ItemAdd(total_bb, id)) {
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ImGui::ButtonBehavior(total_bb, id, &hovered, &held);
|
||||
if (pressed) {
|
||||
*v = !(*v);
|
||||
ImGui::MarkItemEdited(id);
|
||||
}
|
||||
|
||||
const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz));
|
||||
ImGui::RenderNavHighlight(total_bb, id);
|
||||
ImGui::RenderFrame(check_bb.Min, check_bb.Max, ImGui::GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
|
||||
ImU32 check_col = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||
ImU32 cross_col = ImGui::GetColorU32(ImVec4(0.50f, 0.50f, 0.50f, 1.00f));
|
||||
bool mixed_value = (g.LastItemData.InFlags & ImGuiItemFlags_MixedValue) != 0;
|
||||
if (mixed_value) {
|
||||
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
|
||||
// This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox)
|
||||
ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)));
|
||||
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
|
||||
} else if ((!disabled && *v) || (disabled && disabledGraphic == CheckboxGraphics::Checkmark)) {
|
||||
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f));
|
||||
ImGui::RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f);
|
||||
} else if (disabled && disabledGraphic == CheckboxGraphics::Cross) {
|
||||
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f));
|
||||
RenderCross(window->DrawList, check_bb.Min + ImVec2(pad, pad), cross_col, square_sz - pad * 2.0f);
|
||||
}
|
||||
|
||||
ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y);
|
||||
if (g.LogEnabled) {
|
||||
ImGui::LogRenderedText(&label_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]");
|
||||
}
|
||||
if (label_size.x > 0.0f) {
|
||||
ImGui::RenderText(label_pos, label);
|
||||
}
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
|
||||
return pressed;
|
||||
}
|
||||
|
||||
void ReEnableComponent(const char* disabledTooltipText) {
|
||||
// End of disable region of previous component
|
||||
ImGui::PopStyleVar(1);
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(disabledTooltipText, "") != 0) {
|
||||
ImGui::SetTooltip("%s", disabledTooltipText);
|
||||
}
|
||||
ImGui::PopItemFlag();
|
||||
}
|
||||
|
||||
void DisableComponent(const float alpha) {
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
|
||||
}
|
||||
|
||||
bool EnhancementCheckbox(const char* text, const char* cvarName, bool disabled, const char* disabledTooltipText, CheckboxGraphics disabledGraphic, bool defaultValue) {
|
||||
bool changed = false;
|
||||
if (disabled) {
|
||||
DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
|
||||
}
|
||||
|
||||
bool val = (bool)CVarGetInteger(cvarName, defaultValue);
|
||||
if (CustomCheckbox(text, &val, disabled, disabledGraphic)) {
|
||||
CVarSetInteger(cvarName, val);
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
ReEnableComponent(disabledTooltipText);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop, bool padBottom, bool disabled, const char* disabledTooltipText, CheckboxGraphics disabledGraphic, bool defaultValue) {
|
||||
ImGui::BeginGroup();
|
||||
if (padTop) Spacer(0);
|
||||
|
||||
bool changed = EnhancementCheckbox(text, cvarName, disabled, disabledTooltipText, disabledGraphic, defaultValue);
|
||||
|
||||
if (padBottom) Spacer(0);
|
||||
ImGui::EndGroup();
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool EnhancementCombobox(const char* cvarName, std::span<const char*, std::dynamic_extent> comboArray, uint8_t defaultIndex, bool disabled, const char* disabledTooltipText, uint8_t disabledValue) {
|
||||
bool changed = false;
|
||||
if (defaultIndex <= 0) {
|
||||
defaultIndex = 0;
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
|
||||
}
|
||||
|
||||
uint8_t selected = CVarGetInteger(cvarName, defaultIndex);
|
||||
std::string comboName = std::string("##") + std::string(cvarName);
|
||||
if (ImGui::BeginCombo(comboName.c_str(), comboArray[selected])) {
|
||||
for (uint8_t i = 0; i < comboArray.size(); i++) {
|
||||
if (strlen(comboArray[i]) > 0) {
|
||||
if (ImGui::Selectable(comboArray[i], i == selected)) {
|
||||
CVarSetInteger(cvarName, i);
|
||||
selected = i;
|
||||
changed = true;
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
ReEnableComponent(disabledTooltipText);
|
||||
|
||||
if (disabledValue >= 0 && selected != disabledValue) {
|
||||
CVarSetInteger(cvarName, disabledValue);
|
||||
changed = true;
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool LabeledRightAlignedEnhancementCombobox(const char* label, const char* cvarName, std::span<const char*, std::dynamic_extent> comboArray, uint8_t defaultIndex, bool disabled, const char* disabledTooltipText, uint8_t disabledValue) {
|
||||
ImGui::Text("%s", label);
|
||||
s32 currentValue = CVarGetInteger(cvarName, defaultIndex);
|
||||
|
||||
#ifdef __WIIU__
|
||||
ImGui::SameLine(ImGui::GetContentRegionAvail().x - (ImGui::CalcTextSize(comboArray[currentValue]).x + 40.0f));
|
||||
ImGui::PushItemWidth(ImGui::CalcTextSize(comboArray[currentValue]).x + 60.0f);
|
||||
#else
|
||||
ImGui::SameLine(ImGui::GetContentRegionAvail().x - (ImGui::CalcTextSize(comboArray[currentValue]).x + 20.0f));
|
||||
ImGui::PushItemWidth(ImGui::CalcTextSize(comboArray[currentValue]).x + 30.0f);
|
||||
#endif
|
||||
|
||||
bool changed = EnhancementCombobox(cvarName, comboArray, defaultIndex, disabled, disabledTooltipText, disabledValue);
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
return changed;
|
||||
}
|
||||
|
||||
void PaddedText(const char* text, bool padTop, bool padBottom) {
|
||||
if (padTop) Spacer(0);
|
||||
|
||||
ImGui::Text("%s", text);
|
||||
|
||||
if (padBottom) Spacer(0);
|
||||
}
|
||||
|
||||
bool EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue, bool PlusMinusButton, bool disabled, const char* disabledTooltipText) {
|
||||
bool changed = false;
|
||||
int val = CVarGetInteger(cvarName, defaultValue);
|
||||
|
||||
if (disabled) {
|
||||
DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
|
||||
}
|
||||
|
||||
ImGui::Text(text, val);
|
||||
Spacer(0);
|
||||
|
||||
ImGui::BeginGroup();
|
||||
if (PlusMinusButton) {
|
||||
std::string MinusBTNName = " - ##" + std::string(cvarName);
|
||||
if (ImGui::Button(MinusBTNName.c_str())) {
|
||||
val--;
|
||||
changed = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||
}
|
||||
|
||||
ImGui::PushItemWidth(std::min((ImGui::GetContentRegionAvail().x - (PlusMinusButton ? sliderButtonWidth : 0.0f)), maxSliderWidth));
|
||||
if (ImGui::SliderInt(id, &val, min, max, format, ImGuiSliderFlags_AlwaysClamp))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (PlusMinusButton) {
|
||||
std::string PlusBTNName = " + ##" + std::string(cvarName);
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||
if (ImGui::Button(PlusBTNName.c_str())) {
|
||||
val++;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
if (disabled) {
|
||||
ReEnableComponent(disabledTooltipText);
|
||||
}
|
||||
|
||||
if (val < min) {
|
||||
val = min;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (val > max) {
|
||||
val = max;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
CVarSetInteger(cvarName, val);
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton, bool disabled, const char* disabledTooltipText) {
|
||||
bool changed = false;
|
||||
float val = CVarGetFloat(cvarName, defaultValue);
|
||||
|
||||
if (disabled) {
|
||||
DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
|
||||
}
|
||||
|
||||
if (!isPercentage) {
|
||||
ImGui::Text(text, val);
|
||||
} else {
|
||||
ImGui::Text(text, static_cast<int>(100 * val));
|
||||
}
|
||||
Spacer(0);
|
||||
|
||||
ImGui::BeginGroup();
|
||||
if (PlusMinusButton) {
|
||||
std::string MinusBTNName = " - ##" + std::string(cvarName);
|
||||
if (ImGui::Button(MinusBTNName.c_str())) {
|
||||
if (isPercentage) {
|
||||
val -= 0.01f;
|
||||
} else {
|
||||
val -= 0.1f;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||
}
|
||||
|
||||
ImGui::PushItemWidth(std::min((ImGui::GetContentRegionAvail().x - (PlusMinusButton ? sliderButtonWidth : 0.0f)), maxSliderWidth));
|
||||
if (ImGui::SliderFloat(id, &val, min, max, format, ImGuiSliderFlags_AlwaysClamp)) {
|
||||
if (isPercentage) {
|
||||
val = roundf(val * 100) / 100;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (PlusMinusButton) {
|
||||
std::string PlusBTNName = " + ##" + std::string(cvarName);
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||
if (ImGui::Button(PlusBTNName.c_str())) {
|
||||
if (isPercentage) {
|
||||
val += 0.01f;
|
||||
} else {
|
||||
val += 0.1f;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
if (disabled) {
|
||||
ReEnableComponent(disabledTooltipText);
|
||||
}
|
||||
|
||||
if (val < min) {
|
||||
val = min;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (val > max) {
|
||||
val = max;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
CVarSetFloat(cvarName, val);
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool PaddedEnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue, bool PlusMinusButton, bool padTop, bool padBottom, bool disabled, const char* disabledTooltipText) {
|
||||
bool changed = false;
|
||||
ImGui::BeginGroup();
|
||||
if (padTop) Spacer(0);
|
||||
|
||||
changed = EnhancementSliderInt(text, id, cvarName, min, max, format, defaultValue, PlusMinusButton, disabled, disabledTooltipText);
|
||||
|
||||
if (padBottom) Spacer(0);
|
||||
ImGui::EndGroup();
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool PaddedEnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton, bool padTop, bool padBottom, bool disabled, const char* disabledTooltipText) {
|
||||
bool changed = false;
|
||||
ImGui::BeginGroup();
|
||||
if (padTop) Spacer(0);
|
||||
|
||||
changed = EnhancementSliderFloat(text, id, cvarName, min, max, format, defaultValue, isPercentage, PlusMinusButton, disabled, disabledTooltipText);
|
||||
|
||||
if (padBottom) Spacer(0);
|
||||
ImGui::EndGroup();
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool EnhancementRadioButton(const char* text, const char* cvarName, int id) {
|
||||
/*Usage :
|
||||
EnhancementRadioButton("My Visible Name","gMyCVarName", MyID);
|
||||
First arg is the visible name of the Radio button
|
||||
Second is the cvar name where MyID will be saved.
|
||||
Note: the CVar name should be the same to each Buddies.
|
||||
Example :
|
||||
EnhancementRadioButton("English", "gLanguages", LANGUAGE_ENG);
|
||||
EnhancementRadioButton("German", "gLanguages", LANGUAGE_GER);
|
||||
EnhancementRadioButton("French", "gLanguages", LANGUAGE_FRA);
|
||||
*/
|
||||
std::string make_invisible = "##" + std::string(text) + std::string(cvarName);
|
||||
|
||||
bool ret = false;
|
||||
int val = CVarGetInteger(cvarName, 0);
|
||||
if (ImGui::RadioButton(make_invisible.c_str(), id == val)) {
|
||||
CVarSetInteger(cvarName, id);
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
ret = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", text);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DrawResetColorButton(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha) {
|
||||
bool changed = false;
|
||||
std::string Cvar_RBM = std::string(cvarName) + "RBM";
|
||||
std::string MakeInvisible = "Reset##" + std::string(cvarName) + "Reset";
|
||||
if (ImGui::Button(MakeInvisible.c_str())) {
|
||||
colors->x = defaultcolors.x;
|
||||
colors->y = defaultcolors.y;
|
||||
colors->z = defaultcolors.z;
|
||||
colors->w = has_alpha ? defaultcolors.w : 255.0f;
|
||||
|
||||
Color_RGBA8 colorsRGBA;
|
||||
colorsRGBA.r = defaultcolors.x;
|
||||
colorsRGBA.g = defaultcolors.y;
|
||||
colorsRGBA.b = defaultcolors.z;
|
||||
colorsRGBA.a = has_alpha ? defaultcolors.w : 255.0f;
|
||||
|
||||
CVarSetColor(cvarName, colorsRGBA);
|
||||
CVarSetInteger(Cvar_RBM.c_str(), 0); //On click disable rainbow mode.
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
changed = true;
|
||||
}
|
||||
Tooltip("Revert colors to the game's original colors (GameCube version)\nOverwrites previously chosen color");
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool DrawRandomizeColorButton(const char* cvarName, ImVec4* colors) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DrawLockColorCheckbox(const char* cvarName) {
|
||||
std::string Cvar_Lock = std::string(cvarName) + "Lock";
|
||||
s32 lock = CVarGetInteger(Cvar_Lock.c_str(), 0);
|
||||
std::string FullName = "Lock##" + Cvar_Lock;
|
||||
EnhancementCheckbox(FullName.c_str(), Cvar_Lock.c_str());
|
||||
Tooltip("Prevents this color from being changed upon selecting \"Randomize all\"");
|
||||
}
|
||||
|
||||
void RainbowColor(const char* cvarName, ImVec4* colors) {
|
||||
std::string Cvar_RBM = std::string(cvarName) + "RBM";
|
||||
std::string MakeInvisible = "Rainbow##" + std::string(cvarName) + "Rainbow";
|
||||
|
||||
EnhancementCheckbox(MakeInvisible.c_str(), Cvar_RBM.c_str());
|
||||
Tooltip("Cycles through colors on a timer\nOverwrites previously chosen color");
|
||||
}
|
||||
|
||||
void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha) {
|
||||
Color_RGBA8 defaultColors;
|
||||
defaultColors.r = default_colors.x;
|
||||
defaultColors.g = default_colors.y;
|
||||
defaultColors.b = default_colors.z;
|
||||
defaultColors.a = default_colors.w;
|
||||
|
||||
Color_RGBA8 cvarColor = CVarGetColor(cvarname, defaultColors);
|
||||
|
||||
ColorArray.x = cvarColor.r / 255.0;
|
||||
ColorArray.y = cvarColor.g / 255.0;
|
||||
ColorArray.z = cvarColor.b / 255.0;
|
||||
ColorArray.w = cvarColor.a / 255.0;
|
||||
}
|
||||
|
||||
bool EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow, bool has_alpha, bool TitleSameLine) {
|
||||
bool changed = false;
|
||||
LoadPickersColors(ColorRGBA, cvarName, default_colors, has_alpha);
|
||||
|
||||
ImGuiColorEditFlags flags = ImGuiColorEditFlags_None;
|
||||
|
||||
if (!TitleSameLine) {
|
||||
ImGui::Text("%s", text);
|
||||
flags = ImGuiColorEditFlags_NoLabel;
|
||||
}
|
||||
|
||||
ImGui::PushID(cvarName);
|
||||
|
||||
if (!has_alpha) {
|
||||
if (ImGui::ColorEdit3(text, (float*)&ColorRGBA, flags))
|
||||
{
|
||||
Color_RGBA8 colors;
|
||||
colors.r = ColorRGBA.x * 255.0;
|
||||
colors.g = ColorRGBA.y * 255.0;
|
||||
colors.b = ColorRGBA.z * 255.0;
|
||||
colors.a = 255.0;
|
||||
|
||||
CVarSetColor(cvarName, colors);
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreview;
|
||||
if (ImGui::ColorEdit4(text, (float*)&ColorRGBA, flags))
|
||||
{
|
||||
Color_RGBA8 colors;
|
||||
colors.r = ColorRGBA.x * 255.0;
|
||||
colors.g = ColorRGBA.y * 255.0;
|
||||
colors.b = ColorRGBA.z * 255.0;
|
||||
colors.a = ColorRGBA.w * 255.0;
|
||||
|
||||
CVarSetColor(cvarName, colors);
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
//ImGui::SameLine(); // Removing that one to gain some width spacing on the HUD editor
|
||||
ImGui::PushItemWidth(-FLT_MIN);
|
||||
if (DrawResetColorButton(cvarName, &ColorRGBA, default_colors, has_alpha)) {
|
||||
changed = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (DrawRandomizeColorButton(cvarName, &ColorRGBA)) {
|
||||
changed = true;
|
||||
}
|
||||
if (allow_rainbow) {
|
||||
if (ImGui::GetContentRegionAvail().x > 185) {
|
||||
ImGui::SameLine();
|
||||
}
|
||||
RainbowColor(cvarName, &ColorRGBA);
|
||||
}
|
||||
DrawLockColorCheckbox(cvarName);
|
||||
ImGui::NewLine();
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void DrawFlagArray32(const std::string& name, uint32_t& flags) {
|
||||
ImGui::PushID(name.c_str());
|
||||
for (int32_t flagIndex = 0; flagIndex < 32; flagIndex++) {
|
||||
if ((flagIndex % 8) != 0) {
|
||||
ImGui::SameLine();
|
||||
}
|
||||
ImGui::PushID(flagIndex);
|
||||
uint32_t bitMask = 1 << flagIndex;
|
||||
bool flag = (flags & bitMask) != 0;
|
||||
if (ImGui::Checkbox("##check", &flag)) {
|
||||
if (flag) {
|
||||
flags |= bitMask;
|
||||
} else {
|
||||
flags &= ~bitMask;
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void DrawFlagArray16(const std::string& name, uint16_t& flags) {
|
||||
ImGui::PushID(name.c_str());
|
||||
for (int16_t flagIndex = 0; flagIndex < 16; flagIndex++) {
|
||||
if ((flagIndex % 8) != 0) {
|
||||
ImGui::SameLine();
|
||||
}
|
||||
ImGui::PushID(flagIndex);
|
||||
uint16_t bitMask = 1 << flagIndex;
|
||||
bool flag = (flags & bitMask) != 0;
|
||||
if (ImGui::Checkbox("##check", &flag)) {
|
||||
if (flag) {
|
||||
flags |= bitMask;
|
||||
} else {
|
||||
flags &= ~bitMask;
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void DrawFlagArray8(const std::string& name, uint8_t& flags) {
|
||||
ImGui::PushID(name.c_str());
|
||||
for (int8_t flagIndex = 0; flagIndex < 8; flagIndex++) {
|
||||
if ((flagIndex % 8) != 0) {
|
||||
ImGui::SameLine();
|
||||
}
|
||||
ImGui::PushID(flagIndex);
|
||||
uint8_t bitMask = 1 << flagIndex;
|
||||
bool flag = (flags & bitMask) != 0;
|
||||
if (ImGui::Checkbox("##check", &flag)) {
|
||||
if (flag) {
|
||||
flags |= bitMask;
|
||||
} else {
|
||||
flags &= ~bitMask;
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
bool StateButtonEx(const char* str_id, const char* label, ImVec2 size, ImGuiButtonFlags flags) {
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
|
||||
|
||||
const ImGuiID id = window->GetID(str_id);
|
||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
||||
const float default_size = ImGui::GetFrameHeight();
|
||||
ImGui::ItemSize(size, (size.y >= default_size) ? g.Style.FramePadding.y : -1.0f);
|
||||
if (!ImGui::ItemAdd(bb, id))
|
||||
return false;
|
||||
|
||||
if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat)
|
||||
flags |= ImGuiButtonFlags_Repeat;
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, flags);
|
||||
|
||||
// Render
|
||||
const ImU32 bg_col = ImGui::GetColorU32((held && hovered) ? ImGuiCol_ButtonActive
|
||||
: hovered ? ImGuiCol_ButtonHovered
|
||||
: ImGuiCol_Button);
|
||||
//const ImU32 text_col = ImGui::GetColorU32(ImGuiCol_Text);
|
||||
ImGui::RenderNavHighlight(bb, id);
|
||||
ImGui::RenderFrame(bb.Min, bb.Max, bg_col, true, g.Style.FrameRounding);
|
||||
ImGui::RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, {0.55f, 0.45f}, &bb);
|
||||
/*ImGui::RenderArrow(window->DrawList,
|
||||
bb.Min +
|
||||
ImVec2(ImMax(0.0f, (size.x - g.FontSize) * 0.5f), ImMax(0.0f, (size.y - g.FontSize) * 0.5f)),
|
||||
text_col, dir);*/
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, str_id, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool StateButton(const char* str_id, const char* label) {
|
||||
float sz = ImGui::GetFrameHeight();
|
||||
return StateButtonEx(str_id, label, ImVec2(sz, sz), ImGuiButtonFlags_None);
|
||||
}
|
||||
}
|
101
mm/2s2h/UIWidgets.hpp
Normal file
101
mm/2s2h/UIWidgets.hpp
Normal file
@ -0,0 +1,101 @@
|
||||
//
|
||||
// UIWidgets.hpp
|
||||
// soh
|
||||
//
|
||||
// Created by David Chavez on 25.08.22.
|
||||
//
|
||||
|
||||
#ifndef UIWidgets_hpp
|
||||
#define UIWidgets_hpp
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <stdint.h>
|
||||
#include <ImGui/imgui.h>
|
||||
|
||||
namespace UIWidgets {
|
||||
|
||||
struct TextFilters {
|
||||
static int FilterNumbers(ImGuiInputTextCallbackData* data) {
|
||||
if (data->EventChar < 256 && strchr("1234567890", (char)data->EventChar)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int FilterAlphaNum(ImGuiInputTextCallbackData* data) {
|
||||
const char* alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789";
|
||||
if (data->EventChar < 256 && strchr(alphanum, (char)data->EventChar)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// MARK: - Enums
|
||||
|
||||
enum class CheckboxGraphics {
|
||||
Cross,
|
||||
Checkmark,
|
||||
None
|
||||
};
|
||||
constexpr float maxSliderWidth = 260.0f;
|
||||
#ifdef __SWITCH__
|
||||
constexpr float sliderButtonWidth = 42.0f;
|
||||
#elif defined(__WIIU__)
|
||||
constexpr float sliderButtonWidth = 60.0f;
|
||||
#else
|
||||
constexpr float sliderButtonWidth = 30.0f;
|
||||
#endif
|
||||
|
||||
char* WrappedText(const char* text, unsigned int charactersPerLine = 60);
|
||||
char* WrappedText(const std::string& text, unsigned int charactersPerLine);
|
||||
|
||||
void SetLastItemHoverText(const std::string& text);
|
||||
void SetLastItemHoverText(const char* text);
|
||||
|
||||
void InsertHelpHoverText(const std::string& text);
|
||||
void InsertHelpHoverText(const char* text);
|
||||
|
||||
void Tooltip(const char* text);
|
||||
void Spacer(float height);
|
||||
void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f, float extraVerticalBottomPadding = 0.0f);
|
||||
|
||||
void RenderCross(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz);
|
||||
bool CustomCheckbox(const char* label, bool* v, bool disabled, CheckboxGraphics disabledGraphic);
|
||||
|
||||
void ReEnableComponent(const char* disabledTooltipText);
|
||||
void DisableComponent(const float alpha);
|
||||
|
||||
bool EnhancementCheckbox(const char* text, const char* cvarName, bool disabled = false, const char* disabledTooltipText = "", CheckboxGraphics disabledGraphic = CheckboxGraphics::Cross, bool defaultValue = false);
|
||||
bool PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "", CheckboxGraphics disabledGraphic = CheckboxGraphics::Cross, bool defaultValue = false);
|
||||
|
||||
bool EnhancementCombobox(const char* cvarName, std::span<const char*, std::dynamic_extent> comboArray, uint8_t defaultIndex, bool disabled = false, const char* disabledTooltipText = "", uint8_t disabledValue = -1);
|
||||
bool LabeledRightAlignedEnhancementCombobox(const char* label, const char* cvarName, std::span<const char*, std::dynamic_extent> comboArray, uint8_t defaultIndex, bool disabled = false, const char* disabledTooltipText = "", uint8_t disabledValue = -1);
|
||||
|
||||
void PaddedText(const char* text, bool padTop = true, bool padBottom = true);
|
||||
|
||||
bool EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = true, bool disabled = false, const char* disabledTooltipText = "");
|
||||
bool PaddedEnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = true, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "");
|
||||
bool EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton = true, bool disabled = false, const char* disabledTooltipText = "");
|
||||
bool PaddedEnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton = true, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "");
|
||||
|
||||
bool EnhancementRadioButton(const char* text, const char* cvarName, int id);
|
||||
|
||||
bool DrawResetColorButton(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha);
|
||||
bool DrawRandomizeColorButton(const char* cvarName, ImVec4* colors);
|
||||
void DrawLockColorCheckbox(const char* cvarName);
|
||||
void RainbowColor(const char* cvarName, ImVec4* colors);
|
||||
|
||||
void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha);
|
||||
bool EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow = true, bool has_alpha = false, bool TitleSameLine = false);
|
||||
|
||||
void DrawFlagArray32(const std::string& name, uint32_t& flags);
|
||||
void DrawFlagArray16(const std::string& name, uint16_t& flags);
|
||||
void DrawFlagArray8(const std::string& name, uint8_t& flags);
|
||||
bool StateButton(const char* str_id, const char* label);
|
||||
}
|
||||
|
||||
#endif /* UIWidgets_hpp */
|
88
mm/2s2h/gu_pc.c
Normal file
88
mm/2s2h/gu_pc.c
Normal file
@ -0,0 +1,88 @@
|
||||
#include <math.h>
|
||||
#include "z64.h"
|
||||
|
||||
void guMtxF2L(float mf[4][4], Mtx* m) {
|
||||
unsigned int r, c;
|
||||
s32 tmp1;
|
||||
s32 tmp2;
|
||||
s32* m1 = &m->m[0][0];
|
||||
s32* m2 = &m->m[2][0];
|
||||
for (r = 0; r < 4; r++) {
|
||||
for (c = 0; c < 2; c++) {
|
||||
tmp1 = mf[r][2 * c] * 65536.0f;
|
||||
tmp2 = mf[r][2 * c + 1] * 65536.0f;
|
||||
*m1++ = (tmp1 & 0xffff0000) | ((tmp2 >> 0x10) & 0xffff);
|
||||
*m2++ = ((tmp1 << 0x10) & 0xffff0000) | (tmp2 & 0xffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void guMtxL2F(float mf[4][4], Mtx* m) {
|
||||
unsigned int r, c;
|
||||
u32 tmp1;
|
||||
u32 tmp2;
|
||||
u32* m1;
|
||||
u32* m2;
|
||||
s32 stmp1, stmp2;
|
||||
m1 = (u32*)&m->m[0][0];
|
||||
m2 = (u32*)&m->m[2][0];
|
||||
for (r = 0; r < 4; r++) {
|
||||
for (c = 0; c < 2; c++) {
|
||||
tmp1 = (*m1 & 0xffff0000) | ((*m2 >> 0x10) & 0xffff);
|
||||
tmp2 = ((*m1++ << 0x10) & 0xffff0000) | (*m2++ & 0xffff);
|
||||
stmp1 = *(s32*)&tmp1;
|
||||
stmp2 = *(s32*)&tmp2;
|
||||
mf[r][c * 2 + 0] = stmp1 / 65536.0f;
|
||||
mf[r][c * 2 + 1] = stmp2 / 65536.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void guMtxIdentF(f32 mf[4][4]) {
|
||||
unsigned int r, c;
|
||||
for (r = 0; r < 4; r++) {
|
||||
for (c = 0; c < 4; c++) {
|
||||
if (r == c) {
|
||||
mf[r][c] = 1.0f;
|
||||
} else {
|
||||
mf[r][c] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void guMtxIdent(Mtx* m) {
|
||||
guMtxIdentF(m->m);
|
||||
}
|
||||
|
||||
void guTranslateF(float m[4][4], float x, float y, float z) {
|
||||
guMtxIdentF(m);
|
||||
m[3][0] = x;
|
||||
m[3][1] = y;
|
||||
m[3][2] = z;
|
||||
}
|
||||
void guTranslate(Mtx* m, float x, float y, float z) {
|
||||
float mf[4][4];
|
||||
guTranslateF(mf, x, y, z);
|
||||
guMtxF2L(mf, m);
|
||||
}
|
||||
|
||||
void guScaleF(float mf[4][4], float x, float y, float z) {
|
||||
guMtxIdentF(mf);
|
||||
mf[0][0] = x;
|
||||
mf[1][1] = y;
|
||||
mf[2][2] = z;
|
||||
mf[3][3] = 1.0;
|
||||
}
|
||||
void guScale(Mtx* m, float x, float y, float z) {
|
||||
float mf[4][4];
|
||||
guScaleF(mf, x, y, z);
|
||||
guMtxF2L(mf, m);
|
||||
}
|
||||
|
||||
void guNormalize(f32* x, f32* y, f32* z) {
|
||||
f32 tmp = 1.0f / sqrtf(*x * *x + *y * *y + *z * *z);
|
||||
*x = *x * tmp;
|
||||
*y = *y * tmp;
|
||||
*z = *z * tmp;
|
||||
}
|
108
mm/2s2h/resource/importer/AnimationFactory.cpp
Normal file
108
mm/2s2h/resource/importer/AnimationFactory.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
#include "2s2h/resource/importer/AnimationFactory.h"
|
||||
#include "2s2h/resource/type/Animation.h"
|
||||
#include "2s2h/resource/importer/PlayerAnimationFactory.h"
|
||||
#include <libultraship/libultraship.h>
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
AnimationFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<Animation>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<AnimationFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Animation with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::AnimationFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<Animation> animation = std::static_pointer_cast<Animation>(resource);
|
||||
|
||||
ResourceVersionFactory::ParseFileBinary(reader, animation);
|
||||
|
||||
AnimationType animType = (AnimationType)reader->ReadUInt32();
|
||||
animation->type = animType;
|
||||
|
||||
if (animType == AnimationType::Normal) {
|
||||
// Set frame count
|
||||
animation->animationData.animationHeader.common.frameCount = reader->ReadInt16();
|
||||
|
||||
// Populate frame data
|
||||
uint32_t rotValuesCnt = reader->ReadUInt32();
|
||||
animation->rotationValues.reserve(rotValuesCnt);
|
||||
for (uint32_t i = 0; i < rotValuesCnt; i++) {
|
||||
animation->rotationValues.push_back(reader->ReadUInt16());
|
||||
}
|
||||
animation->animationData.animationHeader.frameData = (int16_t*)animation->rotationValues.data();
|
||||
|
||||
// Populate joint indices
|
||||
uint32_t rotIndCnt = reader->ReadUInt32();
|
||||
animation->rotationIndices.reserve(rotIndCnt);
|
||||
for (size_t i = 0; i < rotIndCnt; i++) {
|
||||
uint16_t x = reader->ReadUInt16();
|
||||
uint16_t y = reader->ReadUInt16();
|
||||
uint16_t z = reader->ReadUInt16();
|
||||
animation->rotationIndices.push_back(RotationIndex(x, y, z));
|
||||
}
|
||||
animation->animationData.animationHeader.jointIndices = (JointIndex*)animation->rotationIndices.data();
|
||||
|
||||
// Set static index max
|
||||
animation->animationData.animationHeader.staticIndexMax = reader->ReadInt16();
|
||||
} else if (animType == AnimationType::Curve) {
|
||||
// Read frame count (unused in this animation type)
|
||||
reader->ReadInt16();
|
||||
|
||||
// Set refIndex
|
||||
uint32_t refArrCnt = reader->ReadUInt32();
|
||||
animation->refIndexArr.reserve(refArrCnt);
|
||||
for (uint32_t i = 0; i < refArrCnt; i++) {
|
||||
animation->refIndexArr.push_back(reader->ReadUByte());
|
||||
}
|
||||
animation->animationData.transformUpdateIndex.refIndex = animation->refIndexArr.data();
|
||||
|
||||
// Populate transform data
|
||||
uint32_t transformDataCnt = reader->ReadUInt32();
|
||||
animation->transformDataArr.reserve(transformDataCnt);
|
||||
for (uint32_t i = 0; i < transformDataCnt; i++) {
|
||||
TransformData data;
|
||||
data.unk_00 = reader->ReadUInt16();
|
||||
data.unk_02 = reader->ReadInt16();
|
||||
data.unk_04 = reader->ReadInt16();
|
||||
data.unk_06 = reader->ReadInt16();
|
||||
data.unk_08 = reader->ReadFloat();
|
||||
|
||||
animation->transformDataArr.push_back(data);
|
||||
}
|
||||
animation->animationData.transformUpdateIndex.transformData = animation->transformDataArr.data();
|
||||
|
||||
// Populate copy values
|
||||
uint32_t copyValuesCnt = reader->ReadUInt32();
|
||||
animation->copyValuesArr.reserve(copyValuesCnt);
|
||||
for (uint32_t i = 0; i < copyValuesCnt; i++) {
|
||||
animation->copyValuesArr.push_back(reader->ReadInt16());
|
||||
}
|
||||
animation->animationData.transformUpdateIndex.copyValues = animation->copyValuesArr.data();
|
||||
} else if (animType == AnimationType::Link) {
|
||||
// Read the frame count
|
||||
animation->animationData.linkAnimationHeader.common.frameCount = reader->ReadInt16();
|
||||
|
||||
// Read the segment pointer (always 32 bit, doesn't adjust for system pointer size)
|
||||
std::string path = reader->ReadString();
|
||||
|
||||
animation->animationData.linkAnimationHeader.segment = ResourceGetDataByName(path.c_str());
|
||||
} else if (animType == AnimationType::Legacy) {
|
||||
SPDLOG_DEBUG("BEYTAH ANIMATION?!");
|
||||
}
|
||||
}
|
||||
} // namespace LUS
|
17
mm/2s2h/resource/importer/AnimationFactory.h
Normal file
17
mm/2s2h/resource/importer/AnimationFactory.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class AnimationFactory : public ResourceFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class AnimationFactoryV0 : public ResourceVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
141
mm/2s2h/resource/importer/AudioSampleFactory.cpp
Normal file
141
mm/2s2h/resource/importer/AudioSampleFactory.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
#include "2s2h/resource/importer/AudioSampleFactory.h"
|
||||
#include "2s2h/resource/type/AudioSample.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
AudioSampleFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<AudioSample>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 2:
|
||||
factory = std::make_shared<AudioSampleFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load AudioSample with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::AudioSampleFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<AudioSample> audioSample = std::static_pointer_cast<AudioSample>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, audioSample);
|
||||
|
||||
audioSample->sample.codec = reader->ReadUByte();
|
||||
audioSample->sample.medium = reader->ReadUByte();
|
||||
audioSample->sample.unk_bit26 = reader->ReadUByte();
|
||||
audioSample->sample.unk_bit25 = reader->ReadUByte();
|
||||
audioSample->sample.size = reader->ReadUInt32();
|
||||
|
||||
audioSample->audioSampleData.reserve(audioSample->sample.size);
|
||||
for (uint32_t i = 0; i < audioSample->sample.size; i++) {
|
||||
audioSample->audioSampleData.push_back(reader->ReadUByte());
|
||||
}
|
||||
audioSample->sample.sampleAddr = audioSample->audioSampleData.data();
|
||||
|
||||
audioSample->loop.start = reader->ReadUInt32();
|
||||
audioSample->loop.end = reader->ReadUInt32();
|
||||
audioSample->loop.count = reader->ReadUInt32();
|
||||
|
||||
audioSample->loopStateCount = reader->ReadUInt32();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
audioSample->loop.state[i] = 0;
|
||||
}
|
||||
for (uint32_t i = 0; i < audioSample->loopStateCount; i++) {
|
||||
audioSample->loop.state[i] = reader->ReadInt16();
|
||||
}
|
||||
audioSample->sample.loop = &audioSample->loop;
|
||||
|
||||
audioSample->book.order = reader->ReadInt32();
|
||||
audioSample->book.npredictors = reader->ReadInt32();
|
||||
audioSample->bookDataCount = reader->ReadUInt32();
|
||||
|
||||
audioSample->bookData.reserve(audioSample->bookDataCount);
|
||||
for (uint32_t i = 0; i < audioSample->bookDataCount; i++) {
|
||||
audioSample->bookData.push_back(reader->ReadInt16());
|
||||
}
|
||||
audioSample->book.book = audioSample->bookData.data();
|
||||
audioSample->sample.book = &audioSample->book;
|
||||
}
|
||||
} // namespace LUS
|
||||
|
||||
|
||||
/*
|
||||
in ResourceMgr_LoadAudioSample we used to have
|
||||
--------------
|
||||
if (cachedCustomSFs.find(path) != cachedCustomSFs.end())
|
||||
return cachedCustomSFs[path];
|
||||
|
||||
SoundFontSample* cSample = ReadCustomSample(path);
|
||||
|
||||
if (cSample != nullptr)
|
||||
return cSample;
|
||||
--------------
|
||||
before the rest of the standard sample reading, this is the ReadCustomSample code we used to have
|
||||
|
||||
extern "C" SoundFontSample* ReadCustomSample(const char* path) {
|
||||
|
||||
if (!ExtensionCache.contains(path))
|
||||
return nullptr;
|
||||
|
||||
ExtensionEntry entry = ExtensionCache[path];
|
||||
|
||||
auto sampleRaw = LUS::Context::GetInstance()->GetResourceManager()->LoadFile(entry.path);
|
||||
uint32_t* strem = (uint32_t*)sampleRaw->Buffer.get();
|
||||
uint8_t* strem2 = (uint8_t*)strem;
|
||||
|
||||
SoundFontSample* sampleC = new SoundFontSample;
|
||||
|
||||
if (entry.ext == "wav") {
|
||||
drwav_uint32 channels;
|
||||
drwav_uint32 sampleRate;
|
||||
drwav_uint64 totalPcm;
|
||||
drmp3_int16* pcmData =
|
||||
drwav_open_memory_and_read_pcm_frames_s16(strem2, sampleRaw->BufferSize, &channels, &sampleRate, &totalPcm, NULL);
|
||||
sampleC->size = totalPcm;
|
||||
sampleC->sampleAddr = (uint8_t*)pcmData;
|
||||
sampleC->codec = CODEC_S16;
|
||||
|
||||
sampleC->loop = new AdpcmLoop;
|
||||
sampleC->loop->start = 0;
|
||||
sampleC->loop->end = sampleC->size - 1;
|
||||
sampleC->loop->count = 0;
|
||||
sampleC->sampleRateMagicValue = 'RIFF';
|
||||
sampleC->sampleRate = sampleRate;
|
||||
|
||||
cachedCustomSFs[path] = sampleC;
|
||||
return sampleC;
|
||||
} else if (entry.ext == "mp3") {
|
||||
drmp3_config mp3Info;
|
||||
drmp3_uint64 totalPcm;
|
||||
drmp3_int16* pcmData =
|
||||
drmp3_open_memory_and_read_pcm_frames_s16(strem2, sampleRaw->BufferSize, &mp3Info, &totalPcm, NULL);
|
||||
|
||||
sampleC->size = totalPcm * mp3Info.channels * sizeof(short);
|
||||
sampleC->sampleAddr = (uint8_t*)pcmData;
|
||||
sampleC->codec = CODEC_S16;
|
||||
|
||||
sampleC->loop = new AdpcmLoop;
|
||||
sampleC->loop->start = 0;
|
||||
sampleC->loop->end = sampleC->size;
|
||||
sampleC->loop->count = 0;
|
||||
sampleC->sampleRateMagicValue = 'RIFF';
|
||||
sampleC->sampleRate = mp3Info.sampleRate;
|
||||
|
||||
cachedCustomSFs[path] = sampleC;
|
||||
return sampleC;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
*/
|
19
mm/2s2h/resource/importer/AudioSampleFactory.h
Normal file
19
mm/2s2h/resource/importer/AudioSampleFactory.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class AudioSampleFactory : public ResourceFactory
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class AudioSampleFactoryV0 : public ResourceVersionFactory
|
||||
{
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
52
mm/2s2h/resource/importer/AudioSequenceFactory.cpp
Normal file
52
mm/2s2h/resource/importer/AudioSequenceFactory.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include "2s2h/resource/importer/AudioSequenceFactory.h"
|
||||
#include "2s2h/resource/type/AudioSequence.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
AudioSequenceFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<AudioSequence>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 2:
|
||||
factory = std::make_shared<AudioSequenceFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr)
|
||||
{
|
||||
SPDLOG_ERROR("Failed to load AudioSequence with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::AudioSequenceFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<AudioSequence> audioSequence = std::static_pointer_cast<AudioSequence>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, audioSequence);
|
||||
|
||||
audioSequence->sequence.seqDataSize = reader->ReadInt32();
|
||||
audioSequence->sequenceData.reserve(audioSequence->sequence.seqDataSize);
|
||||
for (uint32_t i = 0; i < audioSequence->sequence.seqDataSize; i++) {
|
||||
audioSequence->sequenceData.push_back(reader->ReadChar());
|
||||
}
|
||||
audioSequence->sequence.seqData = audioSequence->sequenceData.data();
|
||||
|
||||
audioSequence->sequence.seqNumber = reader->ReadUByte();
|
||||
audioSequence->sequence.medium = reader->ReadUByte();
|
||||
audioSequence->sequence.cachePolicy = reader->ReadUByte();
|
||||
|
||||
audioSequence->sequence.numFonts = reader->ReadUInt32();
|
||||
for (uint32_t i = 0; i < 16; i++) {
|
||||
audioSequence->sequence.fonts[i] = 0;
|
||||
}
|
||||
for (uint32_t i = 0; i < audioSequence->sequence.numFonts; i++) {
|
||||
audioSequence->sequence.fonts[i] = reader->ReadUByte();
|
||||
}
|
||||
}
|
||||
} // namespace LUS
|
19
mm/2s2h/resource/importer/AudioSequenceFactory.h
Normal file
19
mm/2s2h/resource/importer/AudioSequenceFactory.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class AudioSequenceFactory : public ResourceFactory
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class AudioSequenceFactoryV0 : public ResourceVersionFactory
|
||||
{
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
190
mm/2s2h/resource/importer/AudioSoundFontFactory.cpp
Normal file
190
mm/2s2h/resource/importer/AudioSoundFontFactory.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
#include "2s2h/resource/importer/AudioSoundFontFactory.h"
|
||||
#include "2s2h/resource/type/AudioSoundFont.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "libultraship/libultraship.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
AudioSoundFontFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<AudioSoundFont>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 2:
|
||||
factory = std::make_shared<AudioSoundFontFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr)
|
||||
{
|
||||
SPDLOG_ERROR("Failed to load AudioSoundFont with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::AudioSoundFontFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<AudioSoundFont> audioSoundFont = std::static_pointer_cast<AudioSoundFont>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, audioSoundFont);
|
||||
|
||||
audioSoundFont->soundFont.fntIndex = reader->ReadInt32();
|
||||
audioSoundFont->medium = reader->ReadInt8();
|
||||
audioSoundFont->cachePolicy = reader->ReadInt8();
|
||||
|
||||
audioSoundFont->data1 = reader->ReadUInt16();
|
||||
audioSoundFont->soundFont.sampleBankId1 = audioSoundFont->data1 >> 8;
|
||||
audioSoundFont->soundFont.sampleBankId2 = audioSoundFont->data1 & 0xFF;
|
||||
|
||||
audioSoundFont->data2 = reader->ReadUInt16();
|
||||
audioSoundFont->data3 = reader->ReadUInt16();
|
||||
|
||||
uint32_t drumCount = reader->ReadUInt32();
|
||||
audioSoundFont->soundFont.numDrums = drumCount;
|
||||
|
||||
uint32_t instrumentCount = reader->ReadUInt32();
|
||||
audioSoundFont->soundFont.numInstruments = instrumentCount;
|
||||
|
||||
uint32_t soundEffectCount = reader->ReadUInt32();
|
||||
audioSoundFont->soundFont.numSfx = soundEffectCount;
|
||||
|
||||
// 🥁 DRUMS 🥁
|
||||
audioSoundFont->drums.reserve(audioSoundFont->soundFont.numDrums);
|
||||
audioSoundFont->drumAddresses.reserve(audioSoundFont->soundFont.numDrums);
|
||||
for (uint32_t i = 0; i < audioSoundFont->soundFont.numDrums; i++) {
|
||||
Drum drum;
|
||||
drum.releaseRate = reader->ReadUByte();
|
||||
drum.pan = reader->ReadUByte();
|
||||
drum.loaded = reader->ReadUByte();
|
||||
drum.loaded = 0; // this was always getting set to zero in ResourceMgr_LoadAudioSoundFont
|
||||
|
||||
uint32_t envelopeCount = reader->ReadUInt32();
|
||||
audioSoundFont->drumEnvelopeCounts.push_back(envelopeCount);
|
||||
std::vector<AdsrEnvelope> drumEnvelopes;
|
||||
drumEnvelopes.reserve(audioSoundFont->drumEnvelopeCounts[i]);
|
||||
for (uint32_t j = 0; j < audioSoundFont->drumEnvelopeCounts.back(); j++) {
|
||||
AdsrEnvelope env;
|
||||
|
||||
int16_t delay = reader->ReadInt16();
|
||||
int16_t arg = reader->ReadInt16();
|
||||
|
||||
env.delay = BE16SWAP(delay);
|
||||
env.arg = BE16SWAP(arg);
|
||||
|
||||
drumEnvelopes.push_back(env);
|
||||
}
|
||||
audioSoundFont->drumEnvelopeArrays.push_back(drumEnvelopes);
|
||||
drum.envelope = audioSoundFont->drumEnvelopeArrays.back().data();
|
||||
|
||||
bool hasSample = reader->ReadInt8();
|
||||
std::string sampleFileName = reader->ReadString();
|
||||
drum.sound.tuning = reader->ReadFloat();
|
||||
|
||||
if (sampleFileName.empty()) {
|
||||
drum.sound.sample = nullptr;
|
||||
} else {
|
||||
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
drum.sound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
}
|
||||
|
||||
audioSoundFont->drums.push_back(drum);
|
||||
audioSoundFont->drumAddresses.push_back(&audioSoundFont->drums.back());
|
||||
}
|
||||
audioSoundFont->soundFont.drums = audioSoundFont->drumAddresses.data();
|
||||
|
||||
// 🎺🎻🎷🎸🎹 INSTRUMENTS 🎹🎸🎷🎻🎺
|
||||
audioSoundFont->instruments.reserve(audioSoundFont->soundFont.numInstruments);
|
||||
for (uint32_t i = 0; i < audioSoundFont->soundFont.numInstruments; i++) {
|
||||
Instrument instrument;
|
||||
|
||||
uint8_t isValidEntry = reader->ReadUByte();
|
||||
instrument.loaded = reader->ReadUByte();
|
||||
instrument.loaded = 0; // this was always getting set to zero in ResourceMgr_LoadAudioSoundFont
|
||||
|
||||
instrument.normalRangeLo = reader->ReadUByte();
|
||||
instrument.normalRangeHi = reader->ReadUByte();
|
||||
instrument.releaseRate = reader->ReadUByte();
|
||||
|
||||
uint32_t envelopeCount = reader->ReadInt32();
|
||||
audioSoundFont->instrumentEnvelopeCounts.push_back(envelopeCount);
|
||||
std::vector<AdsrEnvelope> instrumentEnvelopes;
|
||||
for (uint32_t j = 0; j < audioSoundFont->instrumentEnvelopeCounts.back(); j++) {
|
||||
AdsrEnvelope env;
|
||||
|
||||
int16_t delay = reader->ReadInt16();
|
||||
int16_t arg = reader->ReadInt16();
|
||||
|
||||
env.delay = BE16SWAP(delay);
|
||||
env.arg = BE16SWAP(arg);
|
||||
|
||||
instrumentEnvelopes.push_back(env);
|
||||
}
|
||||
audioSoundFont->instrumentEnvelopeArrays.push_back(instrumentEnvelopes);
|
||||
instrument.envelope = audioSoundFont->instrumentEnvelopeArrays.back().data();
|
||||
|
||||
bool hasLowNoteSoundFontEntry = reader->ReadInt8();
|
||||
if (hasLowNoteSoundFontEntry) {
|
||||
bool hasSampleRef = reader->ReadInt8();
|
||||
std::string sampleFileName = reader->ReadString();
|
||||
instrument.lowNotesSound.tuning = reader->ReadFloat();
|
||||
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
instrument.lowNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
} else {
|
||||
instrument.lowNotesSound.sample = nullptr;
|
||||
instrument.lowNotesSound.tuning = 0;
|
||||
}
|
||||
|
||||
bool hasNormalNoteSoundFontEntry = reader->ReadInt8();
|
||||
if (hasNormalNoteSoundFontEntry) {
|
||||
bool hasSampleRef = reader->ReadInt8();
|
||||
std::string sampleFileName = reader->ReadString();
|
||||
instrument.normalNotesSound.tuning = reader->ReadFloat();
|
||||
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
instrument.normalNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
} else {
|
||||
instrument.normalNotesSound.sample = nullptr;
|
||||
instrument.normalNotesSound.tuning = 0;
|
||||
}
|
||||
|
||||
bool hasHighNoteSoundFontEntry = reader->ReadInt8();
|
||||
if (hasHighNoteSoundFontEntry) {
|
||||
bool hasSampleRef = reader->ReadInt8();
|
||||
std::string sampleFileName = reader->ReadString();
|
||||
instrument.highNotesSound.tuning = reader->ReadFloat();
|
||||
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
instrument.highNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
} else {
|
||||
instrument.highNotesSound.sample = nullptr;
|
||||
instrument.highNotesSound.tuning = 0;
|
||||
}
|
||||
|
||||
|
||||
audioSoundFont->instruments.push_back(instrument);
|
||||
audioSoundFont->instrumentAddresses.push_back(isValidEntry ?
|
||||
&audioSoundFont->instruments.back() :
|
||||
nullptr);
|
||||
}
|
||||
audioSoundFont->soundFont.instruments = audioSoundFont->instrumentAddresses.data();
|
||||
|
||||
// 🔊 SOUND EFFECTS 🔊
|
||||
audioSoundFont->soundEffects.reserve(audioSoundFont->soundFont.numSfx);
|
||||
for (uint32_t i = 0; i < audioSoundFont->soundFont.numSfx; i++) {
|
||||
SoundFontSound soundEffect;
|
||||
|
||||
bool hasSFEntry = reader->ReadInt8();
|
||||
if (hasSFEntry) {
|
||||
bool hasSampleRef = reader->ReadInt8();
|
||||
std::string sampleFileName = reader->ReadString();
|
||||
soundEffect.tuning = reader->ReadFloat();
|
||||
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
soundEffect.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
}
|
||||
|
||||
audioSoundFont->soundEffects.push_back(soundEffect);
|
||||
}
|
||||
audioSoundFont->soundFont.soundEffects = audioSoundFont->soundEffects.data();
|
||||
}
|
||||
} // namespace LUS
|
19
mm/2s2h/resource/importer/AudioSoundFontFactory.h
Normal file
19
mm/2s2h/resource/importer/AudioSoundFontFactory.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class AudioSoundFontFactory : public ResourceFactory
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class AudioSoundFontFactoryV0 : public ResourceVersionFactory
|
||||
{
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
39
mm/2s2h/resource/importer/BackgroundFactory.cpp
Normal file
39
mm/2s2h/resource/importer/BackgroundFactory.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include "2s2h/resource/importer/BackgroundFactory.h"
|
||||
#include "2s2h/resource/type/Background.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
BackgroundFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<Background>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<BackgroundFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Background with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void BackgroundFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<Background> background = std::static_pointer_cast<Background>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, background);
|
||||
|
||||
uint32_t dataSize = reader->ReadUInt32();
|
||||
|
||||
background->Data.reserve(dataSize);
|
||||
|
||||
for (uint32_t i = 0; i < dataSize; i++) {
|
||||
background->Data.push_back(reader->ReadUByte());
|
||||
}
|
||||
}
|
||||
} // namespace LUS
|
17
mm/2s2h/resource/importer/BackgroundFactory.h
Normal file
17
mm/2s2h/resource/importer/BackgroundFactory.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "resource/Resource.h"
|
||||
#include "resource/ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class BackgroundFactory : public ResourceFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class BackgroundFactoryV0 : public ResourceVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
142
mm/2s2h/resource/importer/CollisionHeaderFactory.cpp
Normal file
142
mm/2s2h/resource/importer/CollisionHeaderFactory.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include "2s2h/resource/importer/CollisionHeaderFactory.h"
|
||||
#include "2s2h/resource/type/CollisionHeader.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
CollisionHeaderFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<CollisionHeader>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<CollisionHeaderFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Collision Header with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::CollisionHeaderFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<CollisionHeader> collisionHeader = std::static_pointer_cast<CollisionHeader>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, collisionHeader);
|
||||
|
||||
collisionHeader->collisionHeaderData.minBounds.x = reader->ReadInt16();
|
||||
collisionHeader->collisionHeaderData.minBounds.y = reader->ReadInt16();
|
||||
collisionHeader->collisionHeaderData.minBounds.z = reader->ReadInt16();
|
||||
|
||||
collisionHeader->collisionHeaderData.maxBounds.x = reader->ReadInt16();
|
||||
collisionHeader->collisionHeaderData.maxBounds.y = reader->ReadInt16();
|
||||
collisionHeader->collisionHeaderData.maxBounds.z = reader->ReadInt16();
|
||||
|
||||
collisionHeader->collisionHeaderData.numVertices = reader->ReadInt32();
|
||||
collisionHeader->vertices.reserve(collisionHeader->collisionHeaderData.numVertices);
|
||||
for (int32_t i = 0; i < collisionHeader->collisionHeaderData.numVertices; i++) {
|
||||
Vec3s vtx;
|
||||
vtx.x = reader->ReadInt16();
|
||||
vtx.y = reader->ReadInt16();
|
||||
vtx.z = reader->ReadInt16();
|
||||
collisionHeader->vertices.push_back(vtx);
|
||||
}
|
||||
collisionHeader->collisionHeaderData.vtxList = collisionHeader->vertices.data();
|
||||
|
||||
collisionHeader->collisionHeaderData.numPolygons = reader->ReadUInt32();
|
||||
collisionHeader->polygons.reserve(collisionHeader->collisionHeaderData.numPolygons);
|
||||
for (uint32_t i = 0; i < collisionHeader->collisionHeaderData.numPolygons; i++) {
|
||||
CollisionPoly polygon;
|
||||
|
||||
polygon.type = reader->ReadUInt16();
|
||||
|
||||
polygon.flags_vIA = reader->ReadUInt16();
|
||||
polygon.flags_vIB = reader->ReadUInt16();
|
||||
polygon.vIC = reader->ReadUInt16();
|
||||
|
||||
polygon.normal.x = reader->ReadUInt16();
|
||||
polygon.normal.y = reader->ReadUInt16();
|
||||
polygon.normal.z = reader->ReadUInt16();
|
||||
|
||||
polygon.dist = reader->ReadUInt16();
|
||||
|
||||
collisionHeader->polygons.push_back(polygon);
|
||||
|
||||
}
|
||||
collisionHeader->collisionHeaderData.polyList = collisionHeader->polygons.data();
|
||||
|
||||
collisionHeader->surfaceTypesCount = reader->ReadUInt32();
|
||||
collisionHeader->surfaceTypes.reserve(collisionHeader->surfaceTypesCount);
|
||||
for (uint32_t i = 0; i < collisionHeader->surfaceTypesCount; i++) {
|
||||
SurfaceType surfaceType;
|
||||
|
||||
surfaceType.data[1] = reader->ReadUInt32();
|
||||
surfaceType.data[0] = reader->ReadUInt32();
|
||||
|
||||
collisionHeader->surfaceTypes.push_back(surfaceType);
|
||||
}
|
||||
collisionHeader->collisionHeaderData.surfaceTypeList = collisionHeader->surfaceTypes.data();
|
||||
|
||||
collisionHeader->camDataCount = reader->ReadUInt32();
|
||||
collisionHeader->camData.reserve(collisionHeader->camDataCount);
|
||||
collisionHeader->camPosDataIndices.reserve(collisionHeader->camDataCount);
|
||||
for (uint32_t i = 0; i < collisionHeader->camDataCount; i++) {
|
||||
CamData camDataEntry;
|
||||
camDataEntry.cameraSType = reader->ReadUInt16();
|
||||
camDataEntry.numCameras = reader->ReadInt16();
|
||||
collisionHeader->camData.push_back(camDataEntry);
|
||||
|
||||
int32_t camPosDataIdx = reader->ReadInt32();
|
||||
collisionHeader->camPosDataIndices.push_back(camPosDataIdx);
|
||||
}
|
||||
|
||||
collisionHeader->camPosCount = reader->ReadInt32();
|
||||
collisionHeader->camPosData.reserve(collisionHeader->camPosCount);
|
||||
for (int32_t i = 0; i < collisionHeader->camPosCount; i++) {
|
||||
Vec3s pos;
|
||||
pos.x = reader->ReadInt16();
|
||||
pos.y = reader->ReadInt16();
|
||||
pos.z = reader->ReadInt16();
|
||||
collisionHeader->camPosData.push_back(pos);
|
||||
}
|
||||
|
||||
Vec3s zero;
|
||||
zero.x = 0;
|
||||
zero.y = 0;
|
||||
zero.z = 0;
|
||||
collisionHeader->camPosDataZero = zero;
|
||||
|
||||
for (size_t i = 0; i < collisionHeader->camDataCount; i++) {
|
||||
int32_t idx = collisionHeader->camPosDataIndices[i];
|
||||
|
||||
if (collisionHeader->camPosCount > 0) {
|
||||
collisionHeader->camData[i].camPosData = &collisionHeader->camPosData[idx];
|
||||
} else {
|
||||
collisionHeader->camData[i].camPosData = &collisionHeader->camPosDataZero;
|
||||
}
|
||||
}
|
||||
collisionHeader->collisionHeaderData.cameraDataList = collisionHeader->camData.data();
|
||||
collisionHeader->collisionHeaderData.cameraDataListLen = collisionHeader->camDataCount;
|
||||
|
||||
collisionHeader->collisionHeaderData.numWaterBoxes = reader->ReadInt32();
|
||||
collisionHeader->waterBoxes.reserve(collisionHeader->collisionHeaderData.numWaterBoxes);
|
||||
for (int32_t i = 0; i < collisionHeader->collisionHeaderData.numWaterBoxes; i++) {
|
||||
WaterBox waterBox;
|
||||
waterBox.xMin = reader->ReadInt16();
|
||||
waterBox.ySurface = reader->ReadInt16();
|
||||
waterBox.zMin = reader->ReadInt16();
|
||||
waterBox.xLength = reader->ReadInt16();
|
||||
waterBox.zLength = reader->ReadInt16();
|
||||
waterBox.properties = reader->ReadInt32();
|
||||
|
||||
collisionHeader->waterBoxes.push_back(waterBox);
|
||||
}
|
||||
collisionHeader->collisionHeaderData.waterBoxes = collisionHeader->waterBoxes.data();
|
||||
}
|
||||
}
|
17
mm/2s2h/resource/importer/CollisionHeaderFactory.h
Normal file
17
mm/2s2h/resource/importer/CollisionHeaderFactory.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class CollisionHeaderFactory : public ResourceFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class CollisionHeaderFactoryV0 : public ResourceVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
917
mm/2s2h/resource/importer/CutsceneFactory.cpp
Normal file
917
mm/2s2h/resource/importer/CutsceneFactory.cpp
Normal file
@ -0,0 +1,917 @@
|
||||
#include "2s2h/resource/importer/CutsceneFactory.h"
|
||||
#include "2s2h/resource/type/Cutscene.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
// TODO headers
|
||||
// extern "C" {
|
||||
//#include "z64cutscene.h"
|
||||
//}
|
||||
typedef enum {
|
||||
/* 0x00A */ CS_CMD_TEXT = 10,
|
||||
/* 0x05A */ CS_CMD_CAMERA_SPLINE = 90,
|
||||
/* 0x064 */ CS_CMD_ACTOR_CUE_100 = 100,
|
||||
/* 0x065 */ CS_CMD_ACTOR_CUE_101,
|
||||
/* 0x066 */ CS_CMD_ACTOR_CUE_102,
|
||||
/* 0x067 */ CS_CMD_ACTOR_CUE_103,
|
||||
/* 0x068 */ CS_CMD_ACTOR_CUE_104,
|
||||
/* 0x069 */ CS_CMD_ACTOR_CUE_105,
|
||||
/* 0x06A */ CS_CMD_ACTOR_CUE_106,
|
||||
/* 0x06B */ CS_CMD_ACTOR_CUE_107,
|
||||
/* 0x06C */ CS_CMD_ACTOR_CUE_108,
|
||||
/* 0x06D */ CS_CMD_ACTOR_CUE_109,
|
||||
/* 0x06E */ CS_CMD_ACTOR_CUE_110,
|
||||
/* 0x06F */ CS_CMD_ACTOR_CUE_111,
|
||||
/* 0x070 */ CS_CMD_ACTOR_CUE_112,
|
||||
/* 0x071 */ CS_CMD_ACTOR_CUE_113,
|
||||
/* 0x072 */ CS_CMD_ACTOR_CUE_114,
|
||||
/* 0x073 */ CS_CMD_ACTOR_CUE_115,
|
||||
/* 0x074 */ CS_CMD_ACTOR_CUE_116,
|
||||
/* 0x075 */ CS_CMD_ACTOR_CUE_117,
|
||||
/* 0x076 */ CS_CMD_ACTOR_CUE_118,
|
||||
/* 0x077 */ CS_CMD_ACTOR_CUE_119,
|
||||
/* 0x078 */ CS_CMD_ACTOR_CUE_120,
|
||||
/* 0x079 */ CS_CMD_ACTOR_CUE_121,
|
||||
/* 0x07A */ CS_CMD_ACTOR_CUE_122,
|
||||
/* 0x07B */ CS_CMD_ACTOR_CUE_123,
|
||||
/* 0x07C */ CS_CMD_ACTOR_CUE_124,
|
||||
/* 0x07D */ CS_CMD_ACTOR_CUE_125,
|
||||
/* 0x07E */ CS_CMD_ACTOR_CUE_126,
|
||||
/* 0x07F */ CS_CMD_ACTOR_CUE_127,
|
||||
/* 0x080 */ CS_CMD_ACTOR_CUE_128,
|
||||
/* 0x081 */ CS_CMD_ACTOR_CUE_129,
|
||||
/* 0x082 */ CS_CMD_ACTOR_CUE_130,
|
||||
/* 0x083 */ CS_CMD_ACTOR_CUE_131,
|
||||
/* 0x084 */ CS_CMD_ACTOR_CUE_132,
|
||||
/* 0x085 */ CS_CMD_ACTOR_CUE_133,
|
||||
/* 0x086 */ CS_CMD_ACTOR_CUE_134,
|
||||
/* 0x087 */ CS_CMD_ACTOR_CUE_135,
|
||||
/* 0x088 */ CS_CMD_ACTOR_CUE_136,
|
||||
/* 0x089 */ CS_CMD_ACTOR_CUE_137,
|
||||
/* 0x08A */ CS_CMD_ACTOR_CUE_138,
|
||||
/* 0x08B */ CS_CMD_ACTOR_CUE_139,
|
||||
/* 0x08C */ CS_CMD_ACTOR_CUE_140,
|
||||
/* 0x08D */ CS_CMD_ACTOR_CUE_141,
|
||||
/* 0x08E */ CS_CMD_ACTOR_CUE_142,
|
||||
/* 0x08F */ CS_CMD_ACTOR_CUE_143,
|
||||
/* 0x090 */ CS_CMD_ACTOR_CUE_144,
|
||||
/* 0x091 */ CS_CMD_ACTOR_CUE_145,
|
||||
/* 0x092 */ CS_CMD_ACTOR_CUE_146,
|
||||
/* 0x093 */ CS_CMD_ACTOR_CUE_147,
|
||||
/* 0x094 */ CS_CMD_ACTOR_CUE_148,
|
||||
/* 0x095 */ CS_CMD_ACTOR_CUE_149,
|
||||
/* 0x096 */ CS_CMD_MISC,
|
||||
/* 0x097 */ CS_CMD_LIGHT_SETTING,
|
||||
/* 0x098 */ CS_CMD_TRANSITION,
|
||||
/* 0x099 */ CS_CMD_MOTION_BLUR,
|
||||
/* 0x09A */ CS_CMD_GIVE_TATL,
|
||||
/* 0x09B */ CS_CMD_TRANSITION_GENERAL,
|
||||
/* 0x09C */ CS_CMD_FADE_OUT_SEQ,
|
||||
/* 0x09D */ CS_CMD_TIME,
|
||||
/* 0x0C8 */ CS_CMD_PLAYER_CUE = 200,
|
||||
/* 0x0C9 */ CS_CMD_ACTOR_CUE_201,
|
||||
/* 0x0FA */ CS_CMD_UNK_DATA_FA = 0xFA,
|
||||
/* 0x0FE */ CS_CMD_UNK_DATA_FE = 0xFE,
|
||||
/* 0x0FF */ CS_CMD_UNK_DATA_FF,
|
||||
/* 0x100 */ CS_CMD_UNK_DATA_100,
|
||||
/* 0x101 */ CS_CMD_UNK_DATA_101,
|
||||
/* 0x102 */ CS_CMD_UNK_DATA_102,
|
||||
/* 0x103 */ CS_CMD_UNK_DATA_103,
|
||||
/* 0x104 */ CS_CMD_UNK_DATA_104,
|
||||
/* 0x105 */ CS_CMD_UNK_DATA_105,
|
||||
/* 0x108 */ CS_CMD_UNK_DATA_108 = 0x108,
|
||||
/* 0x109 */ CS_CMD_UNK_DATA_109,
|
||||
/* 0x12C */ CS_CMD_START_SEQ = 300,
|
||||
/* 0x12D */ CS_CMD_STOP_SEQ,
|
||||
/* 0x12E */ CS_CMD_START_AMBIENCE,
|
||||
/* 0x12F */ CS_CMD_FADE_OUT_AMBIENCE,
|
||||
/* 0x130 */ CS_CMD_SFX_REVERB_INDEX_2,
|
||||
/* 0x131 */ CS_CMD_SFX_REVERB_INDEX_1,
|
||||
/* 0x132 */ CS_CMD_MODIFY_SEQ,
|
||||
/* 0x15E */ CS_CMD_DESTINATION = 350,
|
||||
/* 0x15F */ CS_CMD_CHOOSE_CREDITS_SCENES,
|
||||
/* 0x190 */ CS_CMD_RUMBLE = 400,
|
||||
/* 0x1C2 */ CS_CMD_ACTOR_CUE_450 = 450,
|
||||
/* 0x1C3 */ CS_CMD_ACTOR_CUE_451,
|
||||
/* 0x1C4 */ CS_CMD_ACTOR_CUE_452,
|
||||
/* 0x1C5 */ CS_CMD_ACTOR_CUE_453,
|
||||
/* 0x1C6 */ CS_CMD_ACTOR_CUE_454,
|
||||
/* 0x1C7 */ CS_CMD_ACTOR_CUE_455,
|
||||
/* 0x1C8 */ CS_CMD_ACTOR_CUE_456,
|
||||
/* 0x1C9 */ CS_CMD_ACTOR_CUE_457,
|
||||
/* 0x1CA */ CS_CMD_ACTOR_CUE_458,
|
||||
/* 0x1CB */ CS_CMD_ACTOR_CUE_459,
|
||||
/* 0x1CC */ CS_CMD_ACTOR_CUE_460,
|
||||
/* 0x1CD */ CS_CMD_ACTOR_CUE_461,
|
||||
/* 0x1CE */ CS_CMD_ACTOR_CUE_462,
|
||||
/* 0x1CF */ CS_CMD_ACTOR_CUE_463,
|
||||
/* 0x1D0 */ CS_CMD_ACTOR_CUE_464,
|
||||
/* 0x1D1 */ CS_CMD_ACTOR_CUE_465,
|
||||
/* 0x1D2 */ CS_CMD_ACTOR_CUE_466,
|
||||
/* 0x1D3 */ CS_CMD_ACTOR_CUE_467,
|
||||
/* 0x1D4 */ CS_CMD_ACTOR_CUE_468,
|
||||
/* 0x1D5 */ CS_CMD_ACTOR_CUE_469,
|
||||
/* 0x1D6 */ CS_CMD_ACTOR_CUE_470,
|
||||
/* 0x1D7 */ CS_CMD_ACTOR_CUE_471,
|
||||
/* 0x1D8 */ CS_CMD_ACTOR_CUE_472,
|
||||
/* 0x1D9 */ CS_CMD_ACTOR_CUE_473,
|
||||
/* 0x1DA */ CS_CMD_ACTOR_CUE_474,
|
||||
/* 0x1DB */ CS_CMD_ACTOR_CUE_475,
|
||||
/* 0x1DC */ CS_CMD_ACTOR_CUE_476,
|
||||
/* 0x1DD */ CS_CMD_ACTOR_CUE_477,
|
||||
/* 0x1DE */ CS_CMD_ACTOR_CUE_478,
|
||||
/* 0x1DF */ CS_CMD_ACTOR_CUE_479,
|
||||
/* 0x1E0 */ CS_CMD_ACTOR_CUE_480,
|
||||
/* 0x1E1 */ CS_CMD_ACTOR_CUE_481,
|
||||
/* 0x1E2 */ CS_CMD_ACTOR_CUE_482,
|
||||
/* 0x1E3 */ CS_CMD_ACTOR_CUE_483,
|
||||
/* 0x1E4 */ CS_CMD_ACTOR_CUE_484,
|
||||
/* 0x1E5 */ CS_CMD_ACTOR_CUE_485,
|
||||
/* 0x1E6 */ CS_CMD_ACTOR_CUE_486,
|
||||
/* 0x1E7 */ CS_CMD_ACTOR_CUE_487,
|
||||
/* 0x1E8 */ CS_CMD_ACTOR_CUE_488,
|
||||
/* 0x1E9 */ CS_CMD_ACTOR_CUE_489,
|
||||
/* 0x1EA */ CS_CMD_ACTOR_CUE_490,
|
||||
/* 0x1EB */ CS_CMD_ACTOR_CUE_491,
|
||||
/* 0x1EC */ CS_CMD_ACTOR_CUE_492,
|
||||
/* 0x1ED */ CS_CMD_ACTOR_CUE_493,
|
||||
/* 0x1EE */ CS_CMD_ACTOR_CUE_494,
|
||||
/* 0x1EF */ CS_CMD_ACTOR_CUE_495,
|
||||
/* 0x1F0 */ CS_CMD_ACTOR_CUE_496,
|
||||
/* 0x1F1 */ CS_CMD_ACTOR_CUE_497,
|
||||
/* 0x1F2 */ CS_CMD_ACTOR_CUE_498,
|
||||
/* 0x1F3 */ CS_CMD_ACTOR_CUE_499,
|
||||
/* 0x1F4 */ CS_CMD_ACTOR_CUE_500,
|
||||
/* 0x1F5 */ CS_CMD_ACTOR_CUE_501,
|
||||
/* 0x1F6 */ CS_CMD_ACTOR_CUE_502,
|
||||
/* 0x1F7 */ CS_CMD_ACTOR_CUE_503,
|
||||
/* 0x1F8 */ CS_CMD_ACTOR_CUE_504,
|
||||
/* 0x1F9 */ CS_CMD_ACTOR_CUE_SOTCS, // Song of Time Cutscenes (Double SoT, Three-Day Reset SoT)
|
||||
/* 0x1FA */ CS_CMD_ACTOR_CUE_506,
|
||||
/* 0x1FB */ CS_CMD_ACTOR_CUE_507,
|
||||
/* 0x1FC */ CS_CMD_ACTOR_CUE_508,
|
||||
/* 0x1FD */ CS_CMD_ACTOR_CUE_509,
|
||||
/* 0x1FE */ CS_CMD_ACTOR_CUE_510,
|
||||
/* 0x1FF */ CS_CMD_ACTOR_CUE_511,
|
||||
/* 0x200 */ CS_CMD_ACTOR_CUE_512,
|
||||
/* 0x201 */ CS_CMD_ACTOR_CUE_513,
|
||||
/* 0x202 */ CS_CMD_ACTOR_CUE_514,
|
||||
/* 0x203 */ CS_CMD_ACTOR_CUE_515,
|
||||
/* 0x204 */ CS_CMD_ACTOR_CUE_516,
|
||||
/* 0x205 */ CS_CMD_ACTOR_CUE_517,
|
||||
/* 0x206 */ CS_CMD_ACTOR_CUE_518,
|
||||
/* 0x207 */ CS_CMD_ACTOR_CUE_519,
|
||||
/* 0x208 */ CS_CMD_ACTOR_CUE_520,
|
||||
/* 0x209 */ CS_CMD_ACTOR_CUE_521,
|
||||
/* 0x20A */ CS_CMD_ACTOR_CUE_522,
|
||||
/* 0x20B */ CS_CMD_ACTOR_CUE_523,
|
||||
/* 0x20C */ CS_CMD_ACTOR_CUE_524,
|
||||
/* 0x20D */ CS_CMD_ACTOR_CUE_525,
|
||||
/* 0x20E */ CS_CMD_ACTOR_CUE_526,
|
||||
/* 0x20F */ CS_CMD_ACTOR_CUE_527,
|
||||
/* 0x210 */ CS_CMD_ACTOR_CUE_528,
|
||||
/* 0x211 */ CS_CMD_ACTOR_CUE_529,
|
||||
/* 0x212 */ CS_CMD_ACTOR_CUE_530,
|
||||
/* 0x213 */ CS_CMD_ACTOR_CUE_531,
|
||||
/* 0x214 */ CS_CMD_ACTOR_CUE_532,
|
||||
/* 0x215 */ CS_CMD_ACTOR_CUE_533,
|
||||
/* 0x216 */ CS_CMD_ACTOR_CUE_534,
|
||||
/* 0x217 */ CS_CMD_ACTOR_CUE_535,
|
||||
/* 0x218 */ CS_CMD_ACTOR_CUE_536,
|
||||
/* 0x219 */ CS_CMD_ACTOR_CUE_537,
|
||||
/* 0x21A */ CS_CMD_ACTOR_CUE_538,
|
||||
/* 0x21B */ CS_CMD_ACTOR_CUE_539,
|
||||
/* 0x21C */ CS_CMD_ACTOR_CUE_540,
|
||||
/* 0x21D */ CS_CMD_ACTOR_CUE_541,
|
||||
/* 0x21E */ CS_CMD_ACTOR_CUE_542,
|
||||
/* 0x21F */ CS_CMD_ACTOR_CUE_543,
|
||||
/* 0x220 */ CS_CMD_ACTOR_CUE_544,
|
||||
/* 0x221 */ CS_CMD_ACTOR_CUE_545,
|
||||
/* 0x222 */ CS_CMD_ACTOR_CUE_546,
|
||||
/* 0x223 */ CS_CMD_ACTOR_CUE_547,
|
||||
/* 0x224 */ CS_CMD_ACTOR_CUE_548,
|
||||
/* 0x225 */ CS_CMD_ACTOR_CUE_549,
|
||||
/* 0x226 */ CS_CMD_ACTOR_CUE_550,
|
||||
/* 0x227 */ CS_CMD_ACTOR_CUE_551,
|
||||
/* 0x228 */ CS_CMD_ACTOR_CUE_552,
|
||||
/* 0x229 */ CS_CMD_ACTOR_CUE_553,
|
||||
/* 0x22A */ CS_CMD_ACTOR_CUE_554,
|
||||
/* 0x22B */ CS_CMD_ACTOR_CUE_555,
|
||||
/* 0x22C */ CS_CMD_ACTOR_CUE_556,
|
||||
/* 0x22D */ CS_CMD_ACTOR_CUE_557,
|
||||
/* 0x22E */ CS_CMD_ACTOR_CUE_558,
|
||||
/* 0x22F */ CS_CMD_ACTOR_CUE_559,
|
||||
/* 0x230 */ CS_CMD_ACTOR_CUE_560,
|
||||
/* 0x231 */ CS_CMD_ACTOR_CUE_561,
|
||||
/* 0x232 */ CS_CMD_ACTOR_CUE_562,
|
||||
/* 0x233 */ CS_CMD_ACTOR_CUE_563,
|
||||
/* 0x234 */ CS_CMD_ACTOR_CUE_564,
|
||||
/* 0x235 */ CS_CMD_ACTOR_CUE_565,
|
||||
/* 0x236 */ CS_CMD_ACTOR_CUE_566,
|
||||
/* 0x237 */ CS_CMD_ACTOR_CUE_567,
|
||||
/* 0x238 */ CS_CMD_ACTOR_CUE_568,
|
||||
/* 0x239 */ CS_CMD_ACTOR_CUE_569,
|
||||
/* 0x23A */ CS_CMD_ACTOR_CUE_570,
|
||||
/* 0x23B */ CS_CMD_ACTOR_CUE_571,
|
||||
/* 0x23C */ CS_CMD_ACTOR_CUE_572,
|
||||
/* 0x23D */ CS_CMD_ACTOR_CUE_573,
|
||||
/* 0x23E */ CS_CMD_ACTOR_CUE_574,
|
||||
/* 0x23F */ CS_CMD_ACTOR_CUE_575,
|
||||
/* 0x240 */ CS_CMD_ACTOR_CUE_576,
|
||||
/* 0x241 */ CS_CMD_ACTOR_CUE_577,
|
||||
/* 0x242 */ CS_CMD_ACTOR_CUE_578,
|
||||
/* 0x243 */ CS_CMD_ACTOR_CUE_579,
|
||||
/* 0x244 */ CS_CMD_ACTOR_CUE_580,
|
||||
/* 0x245 */ CS_CMD_ACTOR_CUE_581,
|
||||
/* 0x246 */ CS_CMD_ACTOR_CUE_582,
|
||||
/* 0x247 */ CS_CMD_ACTOR_CUE_583,
|
||||
/* 0x248 */ CS_CMD_ACTOR_CUE_584,
|
||||
/* 0x249 */ CS_CMD_ACTOR_CUE_585,
|
||||
/* 0x24A */ CS_CMD_ACTOR_CUE_586,
|
||||
/* 0x24B */ CS_CMD_ACTOR_CUE_587,
|
||||
/* 0x24C */ CS_CMD_ACTOR_CUE_588,
|
||||
/* 0x24D */ CS_CMD_ACTOR_CUE_589,
|
||||
/* 0x24E */ CS_CMD_ACTOR_CUE_590,
|
||||
/* 0x24F */ CS_CMD_ACTOR_CUE_591,
|
||||
/* 0x250 */ CS_CMD_ACTOR_CUE_592,
|
||||
/* 0x251 */ CS_CMD_ACTOR_CUE_593,
|
||||
/* 0x252 */ CS_CMD_ACTOR_CUE_594,
|
||||
/* 0x253 */ CS_CMD_ACTOR_CUE_595,
|
||||
/* 0x254 */ CS_CMD_ACTOR_CUE_596,
|
||||
/* 0x255 */ CS_CMD_ACTOR_CUE_597,
|
||||
/* 0x256 */ CS_CMD_ACTOR_CUE_598,
|
||||
/* 0x257 */ CS_CMD_ACTOR_CUE_599,
|
||||
/* -2 */ CS_CMD_ACTOR_CUE_POST_PROCESS = 0xFFFFFFFE,
|
||||
/* -1 */ CS_CAM_STOP // OoT Remnant
|
||||
} CutsceneCmd;
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource> CutsceneFactory::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<Cutscene>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<CutsceneFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Cutscene with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
static inline uint32_t read_CMD_BBBB(std::shared_ptr<BinaryReader> reader) {
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline uint32_t read_CMD_BBH(std::shared_ptr<BinaryReader> reader) {
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
// swap the half word to match endianness
|
||||
if (reader->GetEndianness() != LUS::Endianness::Native) {
|
||||
uint8_t* b = (uint8_t*)&v;
|
||||
uint8_t tmp = b[2];
|
||||
b[2] = b[3];
|
||||
b[3] = tmp;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline uint32_t read_CMD_HBB(std::shared_ptr<BinaryReader> reader) {
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
// swap the half word to match endianness
|
||||
if (reader->GetEndianness() != LUS::Endianness::Native) {
|
||||
uint8_t* b = (uint8_t*)&v;
|
||||
uint8_t tmp = b[0];
|
||||
b[0] = b[1];
|
||||
b[1] = tmp;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline uint32_t read_CMD_HH(std::shared_ptr<BinaryReader> reader) {
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
// swap the half words to match endianness
|
||||
if (reader->GetEndianness() != LUS::Endianness::Native) {
|
||||
uint8_t* b = (uint8_t*)&v;
|
||||
uint8_t tmp = b[0];
|
||||
b[0] = b[1];
|
||||
b[1] = tmp;
|
||||
tmp = b[2];
|
||||
b[2] = b[3];
|
||||
b[3] = tmp;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void LUS::CutsceneFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<Cutscene> cutscene = std::static_pointer_cast<Cutscene>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, cutscene);
|
||||
|
||||
uint32_t numEntries = reader->ReadUInt32();
|
||||
cutscene->commands.reserve(numEntries);
|
||||
|
||||
cutscene->numCommands = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(cutscene->numCommands);
|
||||
|
||||
cutscene->endFrame = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(cutscene->endFrame);
|
||||
|
||||
// BENTODO detect the game
|
||||
ParseFileBinaryMM(reader, cutscene);
|
||||
}
|
||||
|
||||
void LUS::CutsceneFactoryV0::ParseFileBinaryOoT(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<Cutscene> cutscene) {
|
||||
while (true) {
|
||||
uint32_t commandId = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(commandId);
|
||||
|
||||
switch (commandId) {
|
||||
case (uint32_t)CutsceneCommands::SetCameraPos: {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true) {
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cutscene->commands.push_back(val);
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case (uint32_t)CutsceneCommands::SetCameraFocus: {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true) {
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cutscene->commands.push_back(val);
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SpecialAction: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetLighting: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetCameraPosLink: {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true) {
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cutscene->commands.push_back(val);
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetCameraFocusLink: {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true) {
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cutscene->commands.push_back(val);
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::Cmd09: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HBB(reader));
|
||||
cutscene->commands.push_back(read_CMD_BBH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x15:
|
||||
case (uint32_t)CutsceneCommands::Unknown: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
} break;
|
||||
case (uint32_t)CutsceneCommands::Textbox: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetActorAction0:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction1:
|
||||
case 17:
|
||||
case 18:
|
||||
case 23:
|
||||
case 34:
|
||||
case 39:
|
||||
case 46:
|
||||
case 76:
|
||||
case 85:
|
||||
case 93:
|
||||
case 105:
|
||||
case 107:
|
||||
case 110:
|
||||
case 119:
|
||||
case 123:
|
||||
case 138:
|
||||
case 139:
|
||||
case 144:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction2:
|
||||
case 16:
|
||||
case 24:
|
||||
case 35:
|
||||
case 40:
|
||||
case 48:
|
||||
case 64:
|
||||
case 68:
|
||||
case 70:
|
||||
case 78:
|
||||
case 80:
|
||||
case 94:
|
||||
case 116:
|
||||
case 118:
|
||||
case 120:
|
||||
case 125:
|
||||
case 131:
|
||||
case 141:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction3:
|
||||
case 36:
|
||||
case 41:
|
||||
case 50:
|
||||
case 67:
|
||||
case 69:
|
||||
case 72:
|
||||
case 74:
|
||||
case 81:
|
||||
case 106:
|
||||
case 117:
|
||||
case 121:
|
||||
case 126:
|
||||
case 132:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction4:
|
||||
case 37:
|
||||
case 42:
|
||||
case 51:
|
||||
case 53:
|
||||
case 63:
|
||||
case 65:
|
||||
case 66:
|
||||
case 75:
|
||||
case 82:
|
||||
case 108:
|
||||
case 127:
|
||||
case 133:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction5:
|
||||
case 38:
|
||||
case 43:
|
||||
case 47:
|
||||
case 54:
|
||||
case 79:
|
||||
case 83:
|
||||
case 128:
|
||||
case 135:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction6:
|
||||
case 55:
|
||||
case 77:
|
||||
case 84:
|
||||
case 90:
|
||||
case 129:
|
||||
case 136:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction7:
|
||||
case 52:
|
||||
case 57:
|
||||
case 58:
|
||||
case 88:
|
||||
case 115:
|
||||
case 130:
|
||||
case 137:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction8:
|
||||
case 60:
|
||||
case 89:
|
||||
case 111:
|
||||
case 114:
|
||||
case 134:
|
||||
case 142:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction9:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction10: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetSceneTransFX: {
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::PlayBGM: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::StopBGM: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::FadeBGM: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetTime: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HBB(reader));
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::Terminator: {
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
break;
|
||||
}
|
||||
case 0xFFFFFFFF: // CS_END
|
||||
{
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
return;
|
||||
}
|
||||
default:
|
||||
SPDLOG_TRACE("CutsceneV0: Unknown command {}\n", commandId);
|
||||
// error?
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LUS::CutsceneFactoryV0::ParseFileBinaryMM(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<Cutscene> cutscene) {
|
||||
while (true) {
|
||||
uint32_t command = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(command);
|
||||
|
||||
if (((command >= CS_CMD_ACTOR_CUE_100) && (command <= CS_CMD_ACTOR_CUE_149)) ||
|
||||
(command == CS_CMD_ACTOR_CUE_201) ||
|
||||
((command >= CS_CMD_ACTOR_CUE_450) && (command <= CS_CMD_ACTOR_CUE_599))) {
|
||||
goto actorCue;
|
||||
}
|
||||
|
||||
switch (command) {
|
||||
case CS_CMD_TEXT: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
// uint8_t type = reader->ReadInt8();
|
||||
cutscene->commands.push_back(size);
|
||||
// BENTODO do we need to read the type?
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_CAMERA_SPLINE: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < (size / 4); i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_MISC: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_LIGHT_SETTING: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_BBH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_TRANSITION: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_MOTION_BLUR: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_GIVE_TATL: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_START_SEQ:
|
||||
case CS_CMD_STOP_SEQ: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_BBH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_SFX_REVERB_INDEX_2:
|
||||
case CS_CMD_SFX_REVERB_INDEX_1:
|
||||
case CS_CMD_MODIFY_SEQ:
|
||||
|
||||
case CS_CMD_START_AMBIENCE:
|
||||
case CS_CMD_FADE_OUT_AMBIENCE:
|
||||
case CS_CMD_DESTINATION:
|
||||
case CS_CMD_CHOOSE_CREDITS_SCENES:
|
||||
|
||||
case CS_CMD_UNK_DATA_FA:
|
||||
case CS_CMD_UNK_DATA_FE:
|
||||
case CS_CMD_UNK_DATA_FF:
|
||||
case CS_CMD_UNK_DATA_100:
|
||||
case CS_CMD_UNK_DATA_101:
|
||||
case CS_CMD_UNK_DATA_102:
|
||||
case CS_CMD_UNK_DATA_103:
|
||||
case CS_CMD_UNK_DATA_104:
|
||||
case CS_CMD_UNK_DATA_105:
|
||||
case CS_CMD_UNK_DATA_108:
|
||||
case CS_CMD_UNK_DATA_109: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_BBH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_TRANSITION_GENERAL: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HBB(reader));
|
||||
cutscene->commands.push_back(read_CMD_BBBB(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_FADE_OUT_SEQ: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_TIME: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HBB(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_PLAYER_CUE: {
|
||||
actorCue:
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CS_CMD_RUMBLE: {
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cutscene->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
cutscene->commands.push_back(read_CMD_HH(reader));
|
||||
cutscene->commands.push_back(read_CMD_HBB(reader));
|
||||
cutscene->commands.push_back(read_CMD_BBBB(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0xFFFFFFFF: {
|
||||
cutscene->commands.push_back(reader->ReadUInt32());
|
||||
return;
|
||||
}
|
||||
default:
|
||||
SPDLOG_TRACE("CutsceneV0: Unknown command {}\n", command);
|
||||
// error?
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
25
mm/2s2h/resource/importer/CutsceneFactory.h
Normal file
25
mm/2s2h/resource/importer/CutsceneFactory.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
|
||||
namespace LUS {
|
||||
class Cutscene;
|
||||
class CutsceneFactory : public ResourceFactory
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class CutsceneFactoryV0 : public ResourceVersionFactory
|
||||
{
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
|
||||
private:
|
||||
void ParseFileBinaryOoT(std::shared_ptr<BinaryReader> reader,std::shared_ptr<Cutscene> cutscene);
|
||||
void ParseFileBinaryMM(std::shared_ptr<BinaryReader> reader, std::shared_ptr<Cutscene> cutscene);
|
||||
};
|
||||
}; // namespace LUS
|
113
mm/2s2h/resource/importer/PathFactory.cpp
Normal file
113
mm/2s2h/resource/importer/PathFactory.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
#include "2s2h/resource/importer/PathFactory.h"
|
||||
#include "2s2h/resource/type/Path.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
PathFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<Path>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<PathFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Path with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::PathFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<Path> path = std::static_pointer_cast<Path>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, path);
|
||||
|
||||
path->numPaths = reader->ReadUInt32();
|
||||
path->paths.reserve(path->numPaths);
|
||||
for (uint32_t k = 0; k < path->numPaths; k++) {
|
||||
std::vector<Vec3s> points;
|
||||
uint32_t pointCount = reader->ReadUInt32();
|
||||
points.reserve(pointCount);
|
||||
for (uint32_t i = 0; i < pointCount; i++) {
|
||||
Vec3s point;
|
||||
point.x = reader->ReadInt16();
|
||||
point.y = reader->ReadInt16();
|
||||
point.z = reader->ReadInt16();
|
||||
|
||||
points.push_back(point);
|
||||
}
|
||||
|
||||
PathData pathDataEntry;
|
||||
pathDataEntry.count = pointCount;
|
||||
|
||||
path->paths.push_back(points);
|
||||
pathDataEntry.points = path->paths.back().data();
|
||||
|
||||
path->pathData.push_back(pathDataEntry);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<IResource> PathFactoryMM::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<Path>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<PathFactoryMMV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Path with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::PathFactoryMMV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<PathMM> path = std::static_pointer_cast<PathMM>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, path);
|
||||
|
||||
path->numPaths = reader->ReadUInt32();
|
||||
path->paths.reserve(path->numPaths);
|
||||
for (uint32_t k = 0; k < path->numPaths; k++) {
|
||||
std::vector<Vec3s> points;
|
||||
uint32_t pointCount = reader->ReadUInt32();
|
||||
|
||||
uint8_t additionalPathIndex = reader->ReadUByte();
|
||||
int16_t customValue = reader->ReadInt16();
|
||||
|
||||
for (uint32_t i = 0; i < pointCount; i++) {
|
||||
Vec3s point;
|
||||
point.x = reader->ReadInt16();
|
||||
point.y = reader->ReadInt16();
|
||||
point.z = reader->ReadInt16();
|
||||
|
||||
points.push_back(point);
|
||||
}
|
||||
|
||||
PathDataMM pathDataEntry;
|
||||
pathDataEntry.count = pointCount;
|
||||
pathDataEntry.additionalPathIndex = additionalPathIndex;
|
||||
pathDataEntry.customValue = customValue;
|
||||
|
||||
path->paths.push_back(points);
|
||||
pathDataEntry.points = path->paths.back().data();
|
||||
|
||||
path->pathData.push_back(pathDataEntry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace LUS
|
31
mm/2s2h/resource/importer/PathFactory.h
Normal file
31
mm/2s2h/resource/importer/PathFactory.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class PathFactory : public ResourceFactory
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class PathFactoryV0 : public ResourceVersionFactory
|
||||
{
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
|
||||
class PathFactoryMM : public ResourceFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource> ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class PathFactoryMMV0 : public ResourceVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
|
||||
}; // namespace LUS
|
41
mm/2s2h/resource/importer/PlayerAnimationFactory.cpp
Normal file
41
mm/2s2h/resource/importer/PlayerAnimationFactory.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include "2s2h/resource/importer/PlayerAnimationFactory.h"
|
||||
#include "2s2h/resource/type/PlayerAnimation.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
PlayerAnimationFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<PlayerAnimation>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<PlayerAnimationFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr)
|
||||
{
|
||||
SPDLOG_ERROR("Failed to load PlayerAnimation with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::PlayerAnimationFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<PlayerAnimation> playerAnimation = std::static_pointer_cast<PlayerAnimation>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, playerAnimation);
|
||||
|
||||
uint32_t numEntries = reader->ReadUInt32();
|
||||
playerAnimation->limbRotData.reserve(numEntries);
|
||||
|
||||
for (uint32_t i = 0; i < numEntries; i++) {
|
||||
playerAnimation->limbRotData.push_back(reader->ReadInt16());
|
||||
}
|
||||
}
|
||||
} // namespace LUS
|
17
mm/2s2h/resource/importer/PlayerAnimationFactory.h
Normal file
17
mm/2s2h/resource/importer/PlayerAnimationFactory.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class PlayerAnimationFactory : public ResourceFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class PlayerAnimationFactoryV0 : public ResourceVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
140
mm/2s2h/resource/importer/SceneFactory.cpp
Normal file
140
mm/2s2h/resource/importer/SceneFactory.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "2s2h/resource/importer/SceneFactory.h"
|
||||
#include "2s2h/resource/type/Scene.h"
|
||||
#include "2s2h/resource/type/scenecommand/SceneCommand.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetLightingSettingsFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetWindSettingsFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetExitListFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetTimeSettingsFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetSkyboxModifierFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetEchoSettingsFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetSoundSettingsFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetSkyboxSettingsFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetRoomBehaviorFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetCsCameraFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetCameraSettingsFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetRoomListFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetCollisionHeaderFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetEntranceListFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetSpecialObjectsFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetObjectListFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetStartPositionListFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetActorListFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetTransitionActorListFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/EndMarkerFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetAlternateHeadersFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetPathwaysFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetCutscenesFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetLightListFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetMeshFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetAnimatedMaterialListFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetMinimapListFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetMinimapChestsFactory.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SetActorCutsceneListFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
|
||||
std::shared_ptr<IResource>
|
||||
SceneFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
if (SceneFactory::sceneCommandFactories.empty()) {
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetLightingSettings] = std::make_shared<SetLightingSettingsFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetWind] = std::make_shared<SetWindSettingsFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetExitList] = std::make_shared<SetExitListFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetTimeSettings] = std::make_shared<SetTimeSettingsFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetSkyboxModifier] = std::make_shared<SetSkyboxModifierFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetEchoSettings] = std::make_shared<SetEchoSettingsFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetSoundSettings] = std::make_shared<SetSoundSettingsFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetSkyboxSettings] = std::make_shared<SetSkyboxSettingsFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetRoomBehavior] = std::make_shared<SetRoomBehaviorMMFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetCsCamera] = std::make_shared<SetCsCameraFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetCameraSettings] = std::make_shared<SetCameraSettingsFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetRoomList] = std::make_shared<SetRoomListFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetCollisionHeader] = std::make_shared<SetCollisionHeaderFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetEntranceList] = std::make_shared<SetEntranceListFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetSpecialObjects] = std::make_shared<SetSpecialObjectsFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetObjectList] = std::make_shared<SetObjectListFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetStartPositionList] = std::make_shared<SetStartPositionListFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetActorList] = std::make_shared<SetActorListFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetTransitionActorList] = std::make_shared<SetTransitionActorListFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::EndMarker] = std::make_shared<EndMarkerFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetAlternateHeaders] = std::make_shared<SetAlternateHeadersFactory>();
|
||||
// TODO should we use a different custom scene command like cutscenes?
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetPathways] = std::make_shared<SetPathwaysMMFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetCutscenes] = std::make_shared<SetCutscenesFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetLightList] = std::make_shared<SetLightListFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetMesh] = std::make_shared<SetMeshFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetCutscenesMM] = std::make_shared<SetCutsceneFactoryMM>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetAnimatedMaterialList] =
|
||||
std::make_shared<SetAnimatedMaterialListFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetMinimapList] =
|
||||
std::make_shared<SetMinimapListFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetMinimapChests] =
|
||||
std::make_shared<SetMinimapChestsFactory>();
|
||||
SceneFactory::sceneCommandFactories[LUS::SceneCommandID::SetActorCutsceneList] =
|
||||
std::make_shared<SetActorCutsceneListFactory>();
|
||||
}
|
||||
|
||||
auto resource = std::make_shared<Scene>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SceneFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Scene with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void SceneFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<Scene> scene = std::static_pointer_cast<Scene>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, scene);
|
||||
|
||||
ParseSceneCommands(scene, reader);
|
||||
}
|
||||
|
||||
void SceneFactoryV0::ParseSceneCommands(std::shared_ptr<Scene> scene, std::shared_ptr<BinaryReader> reader) {
|
||||
uint32_t commandCount = reader->ReadUInt32();
|
||||
scene->commands.reserve(commandCount);
|
||||
|
||||
for (uint32_t i = 0; i < commandCount; i++) {
|
||||
scene->commands.push_back(ParseSceneCommand(scene, reader, i));
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<ISceneCommand> SceneFactoryV0::ParseSceneCommand(std::shared_ptr<Scene> scene,
|
||||
std::shared_ptr<BinaryReader> reader, uint32_t index) {
|
||||
SceneCommandID cmdID = (SceneCommandID)reader->ReadInt32();
|
||||
|
||||
reader->Seek(-sizeof(int32_t), SeekOffsetType::Current);
|
||||
|
||||
std::shared_ptr<ISceneCommand> result = nullptr;
|
||||
std::shared_ptr<SceneCommandFactory> commandFactory = SceneFactory::sceneCommandFactories[cmdID];
|
||||
|
||||
if (commandFactory != nullptr) {
|
||||
auto initData = std::make_shared<ResourceInitData>();
|
||||
initData->Id = scene->GetInitData()->Id;
|
||||
initData->Type = ResourceType::SOH_SceneCommand;
|
||||
initData->Path = scene->GetInitData()->Path + "/SceneCommand" + std::to_string(index);
|
||||
initData->ResourceVersion = scene->GetInitData()->ResourceVersion;
|
||||
result = std::static_pointer_cast<ISceneCommand>(commandFactory->ReadResource(initData, reader));
|
||||
// Cache the resource?
|
||||
}
|
||||
|
||||
if (result == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load scene command of type {} in scene {}", (uint32_t)cmdID, scene->GetInitData()->Path);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace LUS
|
29
mm/2s2h/resource/importer/SceneFactory.h
Normal file
29
mm/2s2h/resource/importer/SceneFactory.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/type/Scene.h"
|
||||
#include "2s2h/resource/type/scenecommand/SceneCommand.h"
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SceneFactory : public ResourceFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
|
||||
// Doing something very similar to what we do on the ResourceLoader.
|
||||
// Eventually, scene commands should be moved up to the ResourceLoader as well.
|
||||
// They can not right now because the exporter does not give them a proper resource type enum value,
|
||||
// and the exporter does not export the commands with a proper OTR header.
|
||||
static inline std::unordered_map<SceneCommandID, std::shared_ptr<SceneCommandFactory>> sceneCommandFactories;
|
||||
};
|
||||
|
||||
class SceneFactoryV0 : public ResourceVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
void ParseSceneCommands(std::shared_ptr<Scene> scene, std::shared_ptr<BinaryReader> reader);
|
||||
protected:
|
||||
std::shared_ptr<ISceneCommand> ParseSceneCommand(std::shared_ptr<Scene> scene, std::shared_ptr<BinaryReader> reader, uint32_t index);
|
||||
};
|
||||
}; // namespace LUS
|
158
mm/2s2h/resource/importer/SkeletonFactory.cpp
Normal file
158
mm/2s2h/resource/importer/SkeletonFactory.cpp
Normal file
@ -0,0 +1,158 @@
|
||||
#include "2s2h/resource/importer/SkeletonFactory.h"
|
||||
#include "2s2h/resource/type/Skeleton.h"
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
SkeletonFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<Skeleton>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SkeletonFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Skeleton with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
std::shared_ptr<IResource>
|
||||
SkeletonFactory::ReadResourceXML(std::shared_ptr<ResourceInitData> initData, tinyxml2::XMLElement *reader) {
|
||||
auto resource = std::make_shared<Skeleton>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SkeletonFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Skeleton with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileXML(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void SkeletonFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<Skeleton> skeleton = std::static_pointer_cast<Skeleton>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, skeleton);
|
||||
|
||||
skeleton->type = (SkeletonType)reader->ReadInt8();
|
||||
skeleton->limbType = (LimbType)reader->ReadInt8();
|
||||
skeleton->limbCount = reader->ReadUInt32();
|
||||
skeleton->dListCount = reader->ReadUInt32();
|
||||
skeleton->limbTableType = (LimbType)reader->ReadInt8();
|
||||
skeleton->limbTableCount = reader->ReadUInt32();
|
||||
|
||||
skeleton->limbTable.reserve(skeleton->limbTableCount);
|
||||
for (uint32_t i = 0; i < skeleton->limbTableCount; i++) {
|
||||
std::string limbPath = reader->ReadString();
|
||||
|
||||
skeleton->limbTable.push_back(limbPath);
|
||||
}
|
||||
|
||||
if (skeleton->type == LUS::SkeletonType::Curve) {
|
||||
skeleton->skeletonData.skelCurveLimbList.limbCount = skeleton->limbCount;
|
||||
skeleton->curveLimbArray.reserve(skeleton->skeletonData.skelCurveLimbList.limbCount);
|
||||
} else if (skeleton->type == LUS::SkeletonType::Flex) {
|
||||
skeleton->skeletonData.flexSkeletonHeader.dListCount = skeleton->dListCount;
|
||||
}
|
||||
|
||||
if (skeleton->type == LUS::SkeletonType::Normal) {
|
||||
skeleton->skeletonData.skeletonHeader.limbCount = skeleton->limbCount;
|
||||
skeleton->standardLimbArray.reserve(skeleton->skeletonData.skeletonHeader.limbCount);
|
||||
} else if (skeleton->type == LUS::SkeletonType::Flex) {
|
||||
skeleton->skeletonData.flexSkeletonHeader.sh.limbCount = skeleton->limbCount;
|
||||
skeleton->standardLimbArray.reserve(skeleton->skeletonData.flexSkeletonHeader.sh.limbCount);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < skeleton->limbTable.size(); i++) {
|
||||
std::string limbStr = skeleton->limbTable[i];
|
||||
auto limb = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(limbStr.c_str());
|
||||
skeleton->skeletonHeaderSegments.push_back(limb ? limb->GetRawPointer() : nullptr);
|
||||
}
|
||||
|
||||
if (skeleton->type == LUS::SkeletonType::Normal) {
|
||||
skeleton->skeletonData.skeletonHeader.segment = (void**)skeleton->skeletonHeaderSegments.data();
|
||||
} else if (skeleton->type == LUS::SkeletonType::Flex) {
|
||||
skeleton->skeletonData.flexSkeletonHeader.sh.segment = (void**)skeleton->skeletonHeaderSegments.data();
|
||||
} else if (skeleton->type == LUS::SkeletonType::Curve) {
|
||||
skeleton->skeletonData.skelCurveLimbList.limbs = (SkelCurveLimb**)skeleton->skeletonHeaderSegments.data();
|
||||
} else {
|
||||
SPDLOG_ERROR("unknown skeleton type {}", (uint32_t)skeleton->type);
|
||||
}
|
||||
|
||||
skeleton->skeletonData.skeletonHeader.skeletonType = (uint8_t)skeleton->type;
|
||||
}
|
||||
void SkeletonFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<Skeleton> skel = std::static_pointer_cast<Skeleton>(resource);
|
||||
|
||||
std::string skeletonType = reader->Attribute("Type");
|
||||
// std::string skeletonLimbType = reader->Attribute("LimbType");
|
||||
int numLimbs = reader->IntAttribute("LimbCount");
|
||||
int numDLs = reader->IntAttribute("DisplayListCount");
|
||||
|
||||
if (skeletonType == "Flex") {
|
||||
skel->type = SkeletonType::Flex;
|
||||
} else if (skeletonType == "Curve") {
|
||||
skel->type = SkeletonType::Curve;
|
||||
} else if (skeletonType == "Normal") {
|
||||
skel->type = SkeletonType::Normal;
|
||||
}
|
||||
|
||||
skel->type = SkeletonType::Flex;
|
||||
skel->limbType = LimbType::LOD;
|
||||
|
||||
// if (skeletonLimbType == "Standard")
|
||||
// skel->limbType = LimbType::Standard;
|
||||
// else if (skeletonLimbType == "LOD")
|
||||
// skel->limbType = LimbType::LOD;
|
||||
// else if (skeletonLimbType == "Curve")
|
||||
// skel->limbType = LimbType::Curve;
|
||||
// else if (skeletonLimbType == "Skin")
|
||||
// skel->limbType = LimbType::Skin;
|
||||
// else if (skeletonLimbType == "Legacy")
|
||||
// Sskel->limbType = LimbType::Legacy;
|
||||
|
||||
auto child = reader->FirstChildElement();
|
||||
|
||||
skel->limbCount = numLimbs;
|
||||
skel->dListCount = numDLs;
|
||||
|
||||
while (child != nullptr) {
|
||||
std::string childName = child->Name();
|
||||
|
||||
if (childName == "SkeletonLimb") {
|
||||
std::string limbName = child->Attribute("Path");
|
||||
skel->limbTable.push_back(limbName);
|
||||
|
||||
auto limb = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(limbName.c_str());
|
||||
skel->skeletonHeaderSegments.push_back(limb ? limb->GetRawPointer() : nullptr);
|
||||
}
|
||||
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
|
||||
skel->skeletonData.flexSkeletonHeader.sh.limbCount = skel->limbCount;
|
||||
skel->skeletonData.flexSkeletonHeader.sh.segment = (void**)skel->skeletonHeaderSegments.data();
|
||||
skel->skeletonData.flexSkeletonHeader.dListCount = skel->dListCount;
|
||||
skel->skeletonData.skeletonHeader.skeletonType = (uint8_t)skel->type;
|
||||
}
|
||||
|
||||
} // namespace LUS
|
23
mm/2s2h/resource/importer/SkeletonFactory.h
Normal file
23
mm/2s2h/resource/importer/SkeletonFactory.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SkeletonFactory : public ResourceFactory
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
std::shared_ptr<IResource>
|
||||
ReadResourceXML(std::shared_ptr<ResourceInitData> initData, tinyxml2::XMLElement *reader) override;
|
||||
};
|
||||
|
||||
class SkeletonFactoryV0 : public ResourceVersionFactory
|
||||
{
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
void ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
||||
|
271
mm/2s2h/resource/importer/SkeletonLimbFactory.cpp
Normal file
271
mm/2s2h/resource/importer/SkeletonLimbFactory.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
#include "2s2h/resource/importer/SkeletonLimbFactory.h"
|
||||
#include "2s2h/resource/type/SkeletonLimb.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "libultraship/libultraship.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
SkeletonLimbFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SkeletonLimb>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SkeletonLimbFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Skeleton Limb with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
std::shared_ptr<IResource>
|
||||
SkeletonLimbFactory::ReadResourceXML(std::shared_ptr<ResourceInitData> initData, tinyxml2::XMLElement *reader) {
|
||||
auto resource = std::make_shared<SkeletonLimb>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SkeletonLimbFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Skeleton Limb with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileXML(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SkeletonLimbFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<SkeletonLimb> skeletonLimb = std::static_pointer_cast<SkeletonLimb>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, skeletonLimb);
|
||||
|
||||
skeletonLimb->limbType = (LimbType)reader->ReadInt8();
|
||||
skeletonLimb->skinSegmentType = (ZLimbSkinType)reader->ReadInt8();
|
||||
skeletonLimb->skinDList = reader->ReadString();
|
||||
|
||||
skeletonLimb->skinVtxCnt = reader->ReadUInt16();
|
||||
|
||||
skeletonLimb->skinLimbModifCount = reader->ReadUInt32();
|
||||
skeletonLimb->skinLimbModifArray.reserve(skeletonLimb->skinLimbModifCount);
|
||||
skeletonLimb->skinLimbModifVertexArrays.reserve(skeletonLimb->skinLimbModifCount);
|
||||
skeletonLimb->skinLimbModifTransformationArrays.reserve(skeletonLimb->skinLimbModifCount);
|
||||
for (size_t i = 0; i < skeletonLimb->skinLimbModifCount; i++) {
|
||||
SkinLimbModif skinLimbModif;
|
||||
skinLimbModif.unk_4 = reader->ReadUInt16();
|
||||
skeletonLimb->skinLimbModifArray.push_back(skinLimbModif);
|
||||
|
||||
std::vector<SkinVertex> skinVertexArray;
|
||||
int32_t skinVertexCount = reader->ReadInt32();
|
||||
skinVertexArray.reserve(skinVertexCount);
|
||||
for (int32_t k = 0; k < skinVertexCount; k++) {
|
||||
SkinVertex skinVertex;
|
||||
|
||||
skinVertex.index = reader->ReadInt16();
|
||||
skinVertex.s = reader->ReadInt16();
|
||||
skinVertex.t = reader->ReadInt16();
|
||||
skinVertex.normX = reader->ReadInt8();
|
||||
skinVertex.normY = reader->ReadInt8();
|
||||
skinVertex.normZ = reader->ReadInt8();
|
||||
skinVertex.alpha = reader->ReadUByte();
|
||||
|
||||
skinVertexArray.push_back(skinVertex);
|
||||
}
|
||||
skeletonLimb->skinLimbModifVertexArrays.push_back(skinVertexArray);
|
||||
|
||||
std::vector<SkinTransformation> skinTransformationArray;
|
||||
int32_t skinTransformationCount = reader->ReadInt32();
|
||||
skinTransformationArray.reserve(skinTransformationCount);
|
||||
for (int32_t k = 0; k < skinTransformationCount; k++) {
|
||||
SkinTransformation skinTransformation;
|
||||
|
||||
skinTransformation.limbIndex = reader->ReadUByte();
|
||||
skinTransformation.x = reader->ReadInt16();
|
||||
skinTransformation.y = reader->ReadInt16();
|
||||
skinTransformation.z = reader->ReadInt16();
|
||||
skinTransformation.scale = reader->ReadUByte();
|
||||
|
||||
skinTransformationArray.push_back(skinTransformation);
|
||||
}
|
||||
skeletonLimb->skinLimbModifTransformationArrays.push_back(skinTransformationArray);
|
||||
}
|
||||
|
||||
skeletonLimb->skinDList2 = reader->ReadString();
|
||||
|
||||
skeletonLimb->legTransX = reader->ReadFloat();
|
||||
skeletonLimb->legTransY = reader->ReadFloat();
|
||||
skeletonLimb->legTransZ = reader->ReadFloat();
|
||||
|
||||
skeletonLimb->rotX = reader->ReadUInt16();
|
||||
skeletonLimb->rotY = reader->ReadUInt16();
|
||||
skeletonLimb->rotZ = reader->ReadUInt16();
|
||||
|
||||
skeletonLimb->childPtr = reader->ReadString();
|
||||
skeletonLimb->siblingPtr = reader->ReadString();
|
||||
skeletonLimb->dListPtr = reader->ReadString();
|
||||
skeletonLimb->dList2Ptr = reader->ReadString();
|
||||
|
||||
skeletonLimb->transX = reader->ReadInt16();
|
||||
skeletonLimb->transY = reader->ReadInt16();
|
||||
skeletonLimb->transZ = reader->ReadInt16();
|
||||
|
||||
skeletonLimb->childIndex = reader->ReadUByte();
|
||||
skeletonLimb->siblingIndex = reader->ReadUByte();
|
||||
|
||||
if (skeletonLimb->limbType == LUS::LimbType::LOD) {
|
||||
skeletonLimb->limbData.lodLimb.jointPos.x = skeletonLimb->transX;
|
||||
skeletonLimb->limbData.lodLimb.jointPos.y = skeletonLimb->transY;
|
||||
skeletonLimb->limbData.lodLimb.jointPos.z = skeletonLimb->transZ;
|
||||
skeletonLimb->limbData.lodLimb.child = skeletonLimb->childIndex;
|
||||
skeletonLimb->limbData.lodLimb.sibling = skeletonLimb->siblingIndex;
|
||||
|
||||
if (skeletonLimb->dListPtr != "") {
|
||||
auto dList = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(skeletonLimb->dListPtr.c_str());
|
||||
skeletonLimb->limbData.lodLimb.dLists[0] = (Gfx*)(dList ? dList->GetRawPointer() : nullptr);
|
||||
} else {
|
||||
skeletonLimb->limbData.lodLimb.dLists[0] = nullptr;
|
||||
}
|
||||
|
||||
if (skeletonLimb->dList2Ptr != "") {
|
||||
auto dList = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(skeletonLimb->dList2Ptr.c_str());
|
||||
skeletonLimb->limbData.lodLimb.dLists[1] = (Gfx*)(dList ? dList->GetRawPointer() : nullptr);
|
||||
} else {
|
||||
skeletonLimb->limbData.lodLimb.dLists[1] = nullptr;
|
||||
}
|
||||
} else if (skeletonLimb->limbType == LUS::LimbType::Standard) {
|
||||
skeletonLimb->limbData.standardLimb.jointPos.x = skeletonLimb->transX;
|
||||
skeletonLimb->limbData.standardLimb.jointPos.y = skeletonLimb->transY;
|
||||
skeletonLimb->limbData.standardLimb.jointPos.z = skeletonLimb->transZ;
|
||||
skeletonLimb->limbData.standardLimb.child = skeletonLimb->childIndex;
|
||||
skeletonLimb->limbData.standardLimb.sibling = skeletonLimb->siblingIndex;
|
||||
skeletonLimb->limbData.standardLimb.dList = nullptr;
|
||||
|
||||
if (!skeletonLimb->dListPtr.empty()) {
|
||||
const auto dList = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(skeletonLimb->dListPtr.c_str());
|
||||
skeletonLimb->limbData.standardLimb.dList = (Gfx*)(dList ? dList->GetRawPointer() : nullptr);
|
||||
}
|
||||
} else if (skeletonLimb->limbType == LUS::LimbType::Curve) {
|
||||
skeletonLimb->limbData.skelCurveLimb.firstChildIdx = skeletonLimb->childIndex;
|
||||
skeletonLimb->limbData.skelCurveLimb.nextLimbIdx = skeletonLimb->siblingIndex;
|
||||
skeletonLimb->limbData.skelCurveLimb.dList[0] = nullptr;
|
||||
skeletonLimb->limbData.skelCurveLimb.dList[1] = nullptr;
|
||||
|
||||
if (!skeletonLimb->dListPtr.empty()) {
|
||||
const auto dList = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(skeletonLimb->dListPtr.c_str());
|
||||
skeletonLimb->limbData.skelCurveLimb.dList[0] = (Gfx*)(dList ? dList->GetRawPointer() : nullptr);
|
||||
}
|
||||
|
||||
if (!skeletonLimb->dList2Ptr.empty()) {
|
||||
const auto dList = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(skeletonLimb->dList2Ptr.c_str());
|
||||
skeletonLimb->limbData.skelCurveLimb.dList[1] = (Gfx*)(dList ? dList->GetRawPointer() : nullptr);
|
||||
}
|
||||
} else if (skeletonLimb->limbType == LUS::LimbType::Skin) {
|
||||
skeletonLimb->limbData.skinLimb.jointPos.x = skeletonLimb->transX;
|
||||
skeletonLimb->limbData.skinLimb.jointPos.y = skeletonLimb->transY;
|
||||
skeletonLimb->limbData.skinLimb.jointPos.z = skeletonLimb->transZ;
|
||||
skeletonLimb->limbData.skinLimb.child = skeletonLimb->childIndex;
|
||||
skeletonLimb->limbData.skinLimb.sibling = skeletonLimb->siblingIndex;
|
||||
|
||||
if (skeletonLimb->skinSegmentType == LUS::ZLimbSkinType::SkinType_DList) {
|
||||
skeletonLimb->limbData.skinLimb.segmentType = static_cast<int32_t>(skeletonLimb->skinSegmentType);
|
||||
} else if (skeletonLimb->skinSegmentType == LUS::ZLimbSkinType::SkinType_4) {
|
||||
skeletonLimb->limbData.skinLimb.segmentType = 4;
|
||||
} else if (skeletonLimb->skinSegmentType == LUS::ZLimbSkinType::SkinType_5) {
|
||||
skeletonLimb->limbData.skinLimb.segmentType = 5;
|
||||
} else {
|
||||
skeletonLimb->limbData.skinLimb.segmentType = 0;
|
||||
}
|
||||
|
||||
if (skeletonLimb->skinSegmentType == LUS::ZLimbSkinType::SkinType_DList) {
|
||||
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(skeletonLimb->skinDList.c_str());
|
||||
skeletonLimb->limbData.skinLimb.segment = res ? res->GetRawPointer() : nullptr;
|
||||
} else if (skeletonLimb->skinSegmentType == LUS::ZLimbSkinType::SkinType_4) {
|
||||
skeletonLimb->skinAnimLimbData.totalVtxCount = skeletonLimb->skinVtxCnt;
|
||||
skeletonLimb->skinAnimLimbData.limbModifCount = skeletonLimb->skinLimbModifCount;
|
||||
skeletonLimb->skinAnimLimbData.limbModifications = skeletonLimb->skinLimbModifArray.data();
|
||||
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(skeletonLimb->skinDList2.c_str());
|
||||
skeletonLimb->skinAnimLimbData.dlist = (Gfx*)(res ? res->GetRawPointer() : nullptr);
|
||||
|
||||
for (size_t i = 0; i < skeletonLimb->skinLimbModifArray.size(); i++) {
|
||||
skeletonLimb->skinAnimLimbData.limbModifications[i].vtxCount = skeletonLimb->skinLimbModifVertexArrays[i].size();
|
||||
skeletonLimb->skinAnimLimbData.limbModifications[i].skinVertices = skeletonLimb->skinLimbModifVertexArrays[i].data();
|
||||
|
||||
skeletonLimb->skinAnimLimbData.limbModifications[i].transformCount = skeletonLimb->skinLimbModifTransformationArrays[i].size();
|
||||
skeletonLimb->skinAnimLimbData.limbModifications[i].limbTransformations = skeletonLimb->skinLimbModifTransformationArrays[i].data();
|
||||
|
||||
skeletonLimb->skinAnimLimbData.limbModifications[i].unk_4 = skeletonLimb->skinLimbModifArray[i].unk_4;
|
||||
}
|
||||
|
||||
skeletonLimb->limbData.skinLimb.segment = &skeletonLimb->skinAnimLimbData;
|
||||
}
|
||||
}
|
||||
}
|
||||
void SkeletonLimbFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<SkeletonLimb> skelLimb = std::static_pointer_cast<SkeletonLimb>(resource);
|
||||
|
||||
std::string limbType = reader->Attribute("Type");
|
||||
|
||||
// OTRTODO
|
||||
skelLimb->limbType = LimbType::LOD;
|
||||
|
||||
// skelLimb->legTransX = reader->FloatAttribute("LegTransX");
|
||||
// skelLimb->legTransY = reader->FloatAttribute("LegTransY");
|
||||
// skelLimb->legTransZ = reader->FloatAttribute("LegTransZ");
|
||||
skelLimb->rotX = reader->IntAttribute("RotX");
|
||||
skelLimb->rotY = reader->IntAttribute("RotY");
|
||||
skelLimb->rotZ = reader->IntAttribute("RotZ");
|
||||
|
||||
// skelLimb->transX = reader->IntAttribute("TransX");
|
||||
// skelLimb->transY = reader->IntAttribute("TransY");
|
||||
// skelLimb->transZ = reader->IntAttribute("TransZ");
|
||||
|
||||
skelLimb->transX = (int)reader->FloatAttribute("LegTransX");
|
||||
skelLimb->transY = (int)reader->FloatAttribute("LegTransY");
|
||||
skelLimb->transZ = (int)reader->FloatAttribute("LegTransZ");
|
||||
|
||||
skelLimb->childIndex = reader->IntAttribute("ChildIndex");
|
||||
skelLimb->siblingIndex = reader->IntAttribute("SiblingIndex");
|
||||
|
||||
// skelLimb->childPtr = reader->Attribute("ChildLimb");
|
||||
// skelLimb->siblingPtr = reader->Attribute("SiblingLimb");
|
||||
skelLimb->dListPtr = reader->Attribute("DisplayList1");
|
||||
|
||||
if (std::string(reader->Attribute("DisplayList1")) == "gEmptyDL") {
|
||||
skelLimb->dListPtr = "";
|
||||
}
|
||||
|
||||
auto& limbData = skelLimb->limbData;
|
||||
|
||||
limbData.lodLimb.jointPos.x = skelLimb->transX;
|
||||
limbData.lodLimb.jointPos.y = skelLimb->transY;
|
||||
limbData.lodLimb.jointPos.z = skelLimb->transZ;
|
||||
|
||||
if (skelLimb->dListPtr != "") {
|
||||
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess((const char*)skelLimb->dListPtr.c_str());
|
||||
limbData.lodLimb.dLists[0] = (Gfx*)(res ? res->GetRawPointer() : nullptr);
|
||||
} else {
|
||||
limbData.lodLimb.dLists[0] = nullptr;
|
||||
}
|
||||
|
||||
limbData.lodLimb.dLists[1] = nullptr;
|
||||
|
||||
limbData.lodLimb.child = skelLimb->childIndex;
|
||||
limbData.lodLimb.sibling = skelLimb->siblingIndex;
|
||||
|
||||
// skelLimb->dList2Ptr = reader->Attribute("DisplayList2");
|
||||
}
|
||||
|
||||
} // namespace LUS
|
23
mm/2s2h/resource/importer/SkeletonLimbFactory.h
Normal file
23
mm/2s2h/resource/importer/SkeletonLimbFactory.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SkeletonLimbFactory : public ResourceFactory
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
std::shared_ptr<IResource>
|
||||
ReadResourceXML(std::shared_ptr<ResourceInitData> initData, tinyxml2::XMLElement *reader) override;
|
||||
};
|
||||
|
||||
class SkeletonLimbFactoryV0 : public ResourceVersionFactory
|
||||
{
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
void ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
||||
|
93
mm/2s2h/resource/importer/TextFactory.cpp
Normal file
93
mm/2s2h/resource/importer/TextFactory.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include "2s2h/resource/importer/TextFactory.h"
|
||||
#include "2s2h/resource/type/Text.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
TextFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<Text>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<TextFactoryV0>();
|
||||
break;
|
||||
default:
|
||||
// VERSION NOT SUPPORTED
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Text with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
std::shared_ptr<IResource>
|
||||
TextFactory::ReadResourceXML(std::shared_ptr<ResourceInitData> initData, tinyxml2::XMLElement *reader) {
|
||||
auto resource = std::make_shared<Text>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<TextFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Text with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileXML(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::TextFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<Text> text = std::static_pointer_cast<Text>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, text);
|
||||
|
||||
uint32_t msgCount = reader->ReadUInt32();
|
||||
text->messages.reserve(msgCount);
|
||||
|
||||
for (uint32_t i = 0; i < msgCount; i++) {
|
||||
MessageEntry entry;
|
||||
entry.id = reader->ReadUInt16();
|
||||
entry.textboxType = reader->ReadUByte();
|
||||
entry.textboxYPos = reader->ReadUByte();
|
||||
entry.msg = reader->ReadString();
|
||||
|
||||
text->messages.push_back(entry);
|
||||
}
|
||||
}
|
||||
void TextFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<Text> txt = std::static_pointer_cast<Text>(resource);
|
||||
|
||||
auto child = reader->FirstChildElement();
|
||||
|
||||
while (child != nullptr) {
|
||||
std::string childName = child->Name();
|
||||
|
||||
if (childName == "TextEntry") {
|
||||
MessageEntry entry;
|
||||
entry.id = child->IntAttribute("ID");
|
||||
entry.textboxType = child->IntAttribute("TextboxType");
|
||||
entry.textboxYPos = child->IntAttribute("TextboxYPos");
|
||||
entry.msg = child->Attribute("Message");
|
||||
entry.msg += "\x2";
|
||||
|
||||
txt->messages.push_back(entry);
|
||||
int bp = 0;
|
||||
}
|
||||
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
23
mm/2s2h/resource/importer/TextFactory.h
Normal file
23
mm/2s2h/resource/importer/TextFactory.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class TextFactory : public ResourceFactory
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
std::shared_ptr<IResource>
|
||||
ReadResourceXML(std::shared_ptr<ResourceInitData> initData, tinyxml2::XMLElement *reader) override;
|
||||
};
|
||||
|
||||
class TextFactoryV0 : public ResourceVersionFactory
|
||||
{
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
void ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
||||
|
100
mm/2s2h/resource/importer/TextMMFactory.cpp
Normal file
100
mm/2s2h/resource/importer/TextMMFactory.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include "2s2h/resource/importer/TextMMFactory.h"
|
||||
#include "2s2h/resource/type/TextMM.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
TextMMFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<TextMM>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<TextMMFactoryV0>();
|
||||
break;
|
||||
default:
|
||||
// VERSION NOT SUPPORTED
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Text with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
std::shared_ptr<IResource> TextMMFactory::ReadResourceXML(std::shared_ptr<ResourceInitData> initData,
|
||||
tinyxml2::XMLElement* reader) {
|
||||
auto resource = std::make_shared<TextMM>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<TextMMFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Text with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileXML(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::TextMMFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<TextMM> text = std::static_pointer_cast<TextMM>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, text);
|
||||
|
||||
uint32_t msgCount = reader->ReadUInt32();
|
||||
text->messages.reserve(msgCount);
|
||||
|
||||
for (uint32_t i = 0; i < msgCount; i++) {
|
||||
MessageEntryMM entry;
|
||||
entry.id = reader->ReadUInt16();
|
||||
entry.textboxType = reader->ReadUByte();
|
||||
entry.textboxYPos = reader->ReadUByte();
|
||||
entry.icon = reader->ReadUByte();
|
||||
entry.nextMessageID = reader->ReadUInt16();
|
||||
entry.firstItemCost = reader->ReadUInt16();
|
||||
entry.secondItemCost = reader->ReadUInt16();
|
||||
entry.msg = reader->ReadString();
|
||||
|
||||
text->messages.push_back(entry);
|
||||
}
|
||||
}
|
||||
void TextMMFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<TextMM> txt = std::static_pointer_cast<TextMM>(resource);
|
||||
|
||||
auto child = reader->FirstChildElement();
|
||||
|
||||
while (child != nullptr) {
|
||||
std::string childName = child->Name();
|
||||
|
||||
if (childName == "TextEntry") {
|
||||
MessageEntryMM entry;
|
||||
entry.id = child->IntAttribute("ID");
|
||||
entry.textboxType = child->IntAttribute("TextboxType");
|
||||
entry.textboxYPos = child->IntAttribute("TextboxYPos");
|
||||
|
||||
// BENTODO: MM Unique Fields
|
||||
|
||||
|
||||
entry.msg = child->Attribute("Message");
|
||||
entry.msg += "\x2";
|
||||
|
||||
txt->messages.push_back(entry);
|
||||
int bp = 0;
|
||||
}
|
||||
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
23
mm/2s2h/resource/importer/TextMMFactory.h
Normal file
23
mm/2s2h/resource/importer/TextMMFactory.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class TextMMFactory : public ResourceFactory
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
std::shared_ptr<IResource>
|
||||
ReadResourceXML(std::shared_ptr<ResourceInitData> initData, tinyxml2::XMLElement *reader) override;
|
||||
};
|
||||
|
||||
class TextMMFactoryV0 : public ResourceVersionFactory
|
||||
{
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
void ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
||||
|
124
mm/2s2h/resource/importer/TextureAnimationFactory.cpp
Normal file
124
mm/2s2h/resource/importer/TextureAnimationFactory.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
#include "2s2h/resource/importer/TextureAnimationFactory.h"
|
||||
#include "2s2h/resource/type/TextureAnimation.h"
|
||||
#include <libultraship/libultraship.h>
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
|
||||
std::shared_ptr<IResource> TextureAnimationFactory::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<TextureAnimation>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<TextureAnimationFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load Texture Animation with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::TextureAnimationFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<TextureAnimation> tAnim = std::static_pointer_cast<TextureAnimation>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, tAnim);
|
||||
|
||||
size_t numEntries = reader->ReadUInt32();
|
||||
|
||||
for (size_t i = 0; i < numEntries; i++) {
|
||||
AnimatedMaterial anim;
|
||||
anim.segment = reader->ReadInt8();
|
||||
anim.type = reader->ReadInt8();
|
||||
|
||||
switch ((TextureAnimationParamsType)anim.type) {
|
||||
case TextureAnimationParamsType::SingleScroll: {
|
||||
auto* e = new AnimatedMatTexScrollParams;
|
||||
e->xStep = reader->ReadInt8();
|
||||
e->yStep = reader->ReadInt8();
|
||||
e->width = reader->ReadUByte();
|
||||
e->height = reader->ReadUByte();
|
||||
anim.params = e;
|
||||
break;
|
||||
}
|
||||
case TextureAnimationParamsType::DualScroll: {
|
||||
auto* e = new AnimatedMatTexScrollParams[2];
|
||||
e[0].xStep = reader->ReadInt8();
|
||||
e[0].yStep = reader->ReadInt8();
|
||||
e[0].width = reader->ReadUByte();
|
||||
e[0].height = reader->ReadUByte();
|
||||
e[1].xStep = reader->ReadInt8();
|
||||
e[1].yStep = reader->ReadInt8();
|
||||
e[1].width = reader->ReadUByte();
|
||||
e[1].height = reader->ReadUByte();
|
||||
anim.params = e;
|
||||
break;
|
||||
}
|
||||
case TextureAnimationParamsType::ColorChange:
|
||||
case TextureAnimationParamsType::ColorChangeLERP:
|
||||
case TextureAnimationParamsType::ColorChangeLagrange: {
|
||||
auto* e = new AnimatedMatColorParams;
|
||||
e->keyFrameLength = reader->ReadUInt16();
|
||||
e->keyFrameCount = reader->ReadUInt16();
|
||||
|
||||
size_t frames = reader->ReadUInt32();
|
||||
|
||||
e->keyFrames = new uint16_t[frames];
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
e->keyFrames[i] = reader->ReadUInt16();
|
||||
}
|
||||
size_t primColorSize = reader->ReadUInt32();
|
||||
e->primColors = new F3DPrimColor[primColorSize];
|
||||
|
||||
for (size_t i = 0; i < primColorSize; i++) {
|
||||
e->primColors[i].r = reader->ReadUByte();
|
||||
e->primColors[i].g = reader->ReadUByte();
|
||||
e->primColors[i].b = reader->ReadUByte();
|
||||
e->primColors[i].a = reader->ReadUByte();
|
||||
e->primColors[i].lodFrac = reader->ReadUByte();
|
||||
}
|
||||
|
||||
size_t envColorSize = reader->ReadUInt16();
|
||||
e->envColors = new F3DEnvColor[envColorSize];
|
||||
for (size_t i = 0; i < envColorSize; i++) {
|
||||
e->envColors[i].r = reader->ReadUByte();
|
||||
e->envColors[i].g = reader->ReadUByte();
|
||||
e->envColors[i].b = reader->ReadUByte();
|
||||
e->envColors[i].a = reader->ReadUByte();
|
||||
}
|
||||
anim.params = e;
|
||||
break;
|
||||
}
|
||||
case TextureAnimationParamsType::TextureCycle: {
|
||||
auto* e = new AnimatedMatTexCycleParams;
|
||||
|
||||
e->keyFrameLength = reader->ReadUInt16();
|
||||
e->textureList = new void*[e->keyFrameLength];
|
||||
e->textureIndexList = new uint8_t[e->keyFrameLength];
|
||||
|
||||
for (size_t i = 0; i < e->keyFrameLength; i++) {
|
||||
e->textureList[i] = ResourceGetDataByName(reader->ReadString().c_str());
|
||||
}
|
||||
for (size_t i = 0; i < e->keyFrameLength; i++) {
|
||||
e->textureIndexList[i] = reader->ReadUByte();
|
||||
}
|
||||
anim.params = e;
|
||||
break;
|
||||
}
|
||||
case TextureAnimationParamsType::Empty: {
|
||||
anim.params = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tAnim->anims.emplace_back(anim);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
18
mm/2s2h/resource/importer/TextureAnimationFactory.h
Normal file
18
mm/2s2h/resource/importer/TextureAnimationFactory.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class TextureAnimationFactory : public ResourceFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource> ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) override;
|
||||
|
||||
};
|
||||
|
||||
class TextureAnimationFactoryV0 : public ResourceVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
38
mm/2s2h/resource/importer/scenecommand/EndMarkerFactory.cpp
Normal file
38
mm/2s2h/resource/importer/scenecommand/EndMarkerFactory.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "2s2h/resource/importer/scenecommand/EndMarkerFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/EndMarker.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
EndMarkerFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<EndMarker>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<EndMarkerFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load EndMarker with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::EndMarkerFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<EndMarker> endMarker = std::static_pointer_cast<EndMarker>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, endMarker);
|
||||
|
||||
ReadCommandId(endMarker, reader);
|
||||
|
||||
// This has no data.
|
||||
}
|
||||
|
||||
} // namespace LUS
|
16
mm/2s2h/resource/importer/scenecommand/EndMarkerFactory.h
Normal file
16
mm/2s2h/resource/importer/scenecommand/EndMarkerFactory.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class EndMarkerFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class EndMarkerFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,10 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SceneCommand.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
void SceneCommandVersionFactory::ReadCommandId(std::shared_ptr<ISceneCommand> command, std::shared_ptr<BinaryReader> reader) {
|
||||
command->cmdId = (SceneCommandID)reader->ReadInt32();
|
||||
}
|
||||
}
|
||||
|
15
mm/2s2h/resource/importer/scenecommand/SceneCommandFactory.h
Normal file
15
mm/2s2h/resource/importer/scenecommand/SceneCommandFactory.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SceneCommand.h"
|
||||
|
||||
namespace LUS {
|
||||
class SceneCommandFactory : public ResourceFactory {};
|
||||
|
||||
class SceneCommandVersionFactory : public ResourceVersionFactory {
|
||||
protected:
|
||||
void ReadCommandId(std::shared_ptr<ISceneCommand> command, std::shared_ptr<BinaryReader> reader);
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,55 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetActorCutsceneListFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetActorCutsceneList.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource> SetActorCutsceneListFactory::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetActorCutsceneList>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetActorCutsceneListFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetActorList with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
|
||||
void SetActorCutsceneListFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<SetActorCutsceneList> setActorCsList = std::static_pointer_cast<SetActorCutsceneList>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setActorCsList);
|
||||
|
||||
ReadCommandId(setActorCsList, reader);
|
||||
|
||||
setActorCsList->numEntries = reader->ReadUInt32();
|
||||
setActorCsList->entries.reserve(setActorCsList->numEntries);
|
||||
|
||||
for (uint32_t i = 0; i < setActorCsList->numEntries; i++) {
|
||||
CutsceneEntry e;
|
||||
e.priority = reader->ReadInt16();
|
||||
e.length = reader->ReadInt16();
|
||||
e.csCamId = reader->ReadInt16();
|
||||
e.scriptIndex = reader->ReadInt16();
|
||||
e.additionalCsId = reader->ReadInt16();
|
||||
e.endSfx = reader->ReadUByte();
|
||||
e.customValue = reader->ReadUByte();
|
||||
e.hudVisibility = reader->ReadInt16();
|
||||
e.endCam = reader->ReadUByte();
|
||||
e.letterboxSize = reader->ReadUByte();
|
||||
setActorCsList->entries.emplace_back(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace LUS
|
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetActorCutsceneListFactory : public SceneCommandFactory {
|
||||
std::shared_ptr<IResource> ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetActorCutsceneListFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetActorListFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetActorList.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
SetActorListFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetActorList>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetActorListFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr)
|
||||
{
|
||||
SPDLOG_ERROR("Failed to load SetActorList with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetActorListFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<SetActorList> setActorList = std::static_pointer_cast<SetActorList>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setActorList);
|
||||
|
||||
ReadCommandId(setActorList, reader);
|
||||
|
||||
setActorList->numActors = reader->ReadUInt32();
|
||||
setActorList->actorList.reserve(setActorList->numActors);
|
||||
for (uint32_t i = 0; i < setActorList->numActors; i++) {
|
||||
ActorEntry entry;
|
||||
|
||||
entry.id = reader->ReadUInt16();
|
||||
entry.pos.x = reader->ReadInt16();
|
||||
entry.pos.y = reader->ReadInt16();
|
||||
entry.pos.z = reader->ReadInt16();
|
||||
entry.rot.x = reader->ReadInt16();
|
||||
entry.rot.y = reader->ReadInt16();
|
||||
entry.rot.z = reader->ReadInt16();
|
||||
entry.params = reader->ReadUInt16();
|
||||
|
||||
setActorList->actorList.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
16
mm/2s2h/resource/importer/scenecommand/SetActorListFactory.h
Normal file
16
mm/2s2h/resource/importer/scenecommand/SetActorListFactory.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetActorListFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetActorListFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,49 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetAlternateHeadersFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetAlternateHeaders.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "libultraship/libultraship.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource> SetAlternateHeadersFactory::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetAlternateHeaders>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetAlternateHeadersFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr)
|
||||
{
|
||||
SPDLOG_ERROR("Failed to load SetAlternateHeaders with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetAlternateHeadersFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<SetAlternateHeaders> setAlternateHeaders = std::static_pointer_cast<SetAlternateHeaders>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setAlternateHeaders);
|
||||
|
||||
ReadCommandId(setAlternateHeaders, reader);
|
||||
|
||||
setAlternateHeaders->numHeaders = reader->ReadUInt32();
|
||||
setAlternateHeaders->headers.reserve(setAlternateHeaders->numHeaders);
|
||||
for (uint32_t i = 0; i < setAlternateHeaders->numHeaders; i++) {
|
||||
auto headerName = reader->ReadString();
|
||||
if (!headerName.empty()) {
|
||||
setAlternateHeaders->headers.push_back(std::static_pointer_cast<LUS::Scene>(LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(headerName.c_str())));
|
||||
} else {
|
||||
setAlternateHeaders->headers.push_back(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetAlternateHeadersFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetAlternateHeadersFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,41 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetAnimatedMaterialListFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetAnimatedMaterialList.h"
|
||||
#include "2s2h/resource/type/TextureAnimation.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
namespace LUS {
|
||||
|
||||
std::shared_ptr<IResource> LUS::SetAnimatedMaterialListFactory::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetAnimatedMaterialList>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetAnimatedMaterialListFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetAnimatedMaterialList with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetAnimatedMaterialListFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<SetAnimatedMaterialList> setAnimatedMat =
|
||||
std::static_pointer_cast<SetAnimatedMaterialList>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setAnimatedMat);
|
||||
|
||||
ReadCommandId(setAnimatedMat, reader);
|
||||
AnimatedMaterialData* res = (AnimatedMaterialData*)ResourceGetDataByName(reader->ReadString().c_str());
|
||||
setAnimatedMat->mat = res;
|
||||
}
|
||||
|
||||
} // namespace LUS
|
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetAnimatedMaterialListFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource> ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetAnimatedMaterialListFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetCameraSettingsFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetCameraSettings.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource> SetCameraSettingsFactory::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetCameraSettings>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetCameraSettingsFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetCameraSettings with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetCameraSettingsFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<SetCameraSettings> setCameraSettings = std::static_pointer_cast<SetCameraSettings>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setCameraSettings);
|
||||
|
||||
ReadCommandId(setCameraSettings, reader);
|
||||
// BENTODO in MM this scene command is only used as a signal to have the scene system mark an area as visted. We should make a new command factory for this but this is fine for now.
|
||||
//setCameraSettings->settings.cameraMovement = reader->ReadInt8();
|
||||
//setCameraSettings->settings.worldMapArea = reader->ReadInt32();
|
||||
}
|
||||
|
||||
} // namespace LUS
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetCameraSettingsFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetCameraSettingsFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,39 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetCollisionHeaderFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetCollisionHeader.h"
|
||||
#include "libultraship/libultraship.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource> SetCollisionHeaderFactory::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetCollisionHeader>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetCollisionHeaderFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetCollisionHeader with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetCollisionHeaderFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<SetCollisionHeader> setCollisionHeader = std::static_pointer_cast<SetCollisionHeader>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setCollisionHeader);
|
||||
|
||||
ReadCommandId(setCollisionHeader, reader);
|
||||
|
||||
setCollisionHeader->fileName = reader->ReadString();
|
||||
setCollisionHeader->collisionHeader = std::static_pointer_cast<CollisionHeader>(LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(setCollisionHeader->fileName.c_str()));
|
||||
}
|
||||
|
||||
} // namespace LUS
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetCollisionHeaderFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetCollisionHeaderFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,55 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetCsCameraFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetCsCamera.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
SetCsCameraFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetCsCamera>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetCsCameraFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetCsCamera with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetCsCameraFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<SetCsCamera> setCsCamera = std::static_pointer_cast<SetCsCamera>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setCsCamera);
|
||||
|
||||
ReadCommandId(setCsCamera, reader);
|
||||
|
||||
size_t camSize = reader->ReadUInt32();
|
||||
|
||||
for (size_t i = 0; i < camSize; i++) {
|
||||
ActorCsCamInfoData data;
|
||||
data.setting = reader->ReadUInt16();
|
||||
data.count = reader->ReadUInt16();
|
||||
if (data.count == 0) {
|
||||
data.actorCsCamFuncData = nullptr;
|
||||
continue;
|
||||
}
|
||||
data.actorCsCamFuncData = new z64Vec3s[data.count];
|
||||
for (size_t j = 0; j < data.count; j++) {
|
||||
data.actorCsCamFuncData[j].x = reader->ReadInt16();
|
||||
data.actorCsCamFuncData[j].y = reader->ReadInt16();
|
||||
data.actorCsCamFuncData[j].z = reader->ReadInt16();
|
||||
}
|
||||
setCsCamera->csCamera.emplace_back(data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace LUS
|
16
mm/2s2h/resource/importer/scenecommand/SetCsCameraFactory.h
Normal file
16
mm/2s2h/resource/importer/scenecommand/SetCsCameraFactory.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetCsCameraFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetCsCameraFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,81 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetCutscenesFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetCutscenes.h"
|
||||
#include <libultraship/libultraship.h>
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
SetCutscenesFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetCutscenes>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetCutscenesFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr)
|
||||
{
|
||||
SPDLOG_ERROR("Failed to load SetCutscenes with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetCutscenesFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<SetCutscenes> setCutscenes = std::static_pointer_cast<SetCutscenes>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setCutscenes);
|
||||
|
||||
ReadCommandId(setCutscenes, reader);
|
||||
|
||||
setCutscenes->fileName = reader->ReadString();
|
||||
setCutscenes->cutscene = std::static_pointer_cast<Cutscene>(LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(setCutscenes->fileName.c_str()));
|
||||
}
|
||||
|
||||
std::shared_ptr<IResource> SetCutsceneFactoryMM::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetCutscenesMM>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetCutscenesFactoryMMV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetCutscenes with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetCutscenesFactoryMMV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<SetCutscenesMM> setCutscenes = std::static_pointer_cast<SetCutscenesMM>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setCutscenes);
|
||||
|
||||
ReadCommandId(setCutscenes, reader);
|
||||
|
||||
size_t numCs = reader->ReadUByte();
|
||||
|
||||
for (size_t i = 0; i < numCs; i++) {
|
||||
CutsceneScriptEntry entry;
|
||||
std::string path = reader->ReadString();
|
||||
entry.exit = reader->ReadUInt16();
|
||||
entry.entrance = reader->ReadUByte();
|
||||
entry.flag = reader->ReadUByte();
|
||||
entry.data = ResourceGetDataByName(path.c_str());
|
||||
setCutscenes->entries.emplace_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
28
mm/2s2h/resource/importer/scenecommand/SetCutscenesFactory.h
Normal file
28
mm/2s2h/resource/importer/scenecommand/SetCutscenesFactory.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetCutscenesFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetCutscenesFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
|
||||
class SetCutsceneFactoryMM : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource> ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetCutscenesFactoryMMV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
|
||||
}; // namespace LUS
|
@ -0,0 +1,38 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetEchoSettingsFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetEchoSettings.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
SetEchoSettingsFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetEchoSettings>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetEchoSettingsFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetEchoSettings with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetEchoSettingsFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<SetEchoSettings> setEchoSettings = std::static_pointer_cast<SetEchoSettings>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setEchoSettings);
|
||||
|
||||
ReadCommandId(setEchoSettings, reader);
|
||||
|
||||
setEchoSettings->settings.echo = reader->ReadInt8();
|
||||
}
|
||||
|
||||
} // namespace LUS
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetEchoSettingsFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetEchoSettingsFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,46 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetEntranceListFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetEntranceList.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
SetEntranceListFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetEntranceList>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetEntranceListFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetEntranceListList with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetEntranceListFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<SetEntranceList> setEntranceList = std::static_pointer_cast<SetEntranceList>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setEntranceList);
|
||||
|
||||
ReadCommandId(setEntranceList, reader);
|
||||
|
||||
setEntranceList->numEntrances = reader->ReadUInt32();
|
||||
setEntranceList->entrances.reserve(setEntranceList->numEntrances);
|
||||
for (uint32_t i = 0; i < setEntranceList->numEntrances; i++) {
|
||||
EntranceEntry entranceEntry;
|
||||
|
||||
entranceEntry.spawn = reader->ReadInt8();
|
||||
entranceEntry.room = reader->ReadInt8();
|
||||
|
||||
setEntranceList->entrances.push_back(entranceEntry);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetEntranceListFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetEntranceListFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,41 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetExitListFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetExitList.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
SetExitListFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetExitList>( initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetExitListFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetExitList with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetExitListFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<SetExitList> setExitList = std::static_pointer_cast<SetExitList>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setExitList);
|
||||
|
||||
ReadCommandId(setExitList, reader);
|
||||
|
||||
setExitList->numExits = reader->ReadUInt32();
|
||||
setExitList->exits.reserve(setExitList->numExits);
|
||||
for (uint32_t i = 0; i < setExitList->numExits; i++) {
|
||||
setExitList->exits.push_back(reader->ReadUInt16());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
16
mm/2s2h/resource/importer/scenecommand/SetExitListFactory.h
Normal file
16
mm/2s2h/resource/importer/scenecommand/SetExitListFactory.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetExitListFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetExitListFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,58 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetLightListFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetLightList.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
SetLightListFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetLightList>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetLightListFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr)
|
||||
{
|
||||
SPDLOG_ERROR("Failed to load SetLightList with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetLightListFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<SetLightList> setLightList = std::static_pointer_cast<SetLightList>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setLightList);
|
||||
|
||||
ReadCommandId(setLightList, reader);
|
||||
|
||||
setLightList->numLights = reader->ReadUInt32();
|
||||
setLightList->lightList.reserve(setLightList->numLights);
|
||||
for (uint32_t i = 0; i < setLightList->numLights; i++) {
|
||||
LightInfo light;
|
||||
|
||||
light.type = reader->ReadUByte();
|
||||
|
||||
light.params.point.x = reader->ReadInt16();
|
||||
light.params.point.y = reader->ReadInt16();
|
||||
light.params.point.z = reader->ReadInt16();
|
||||
|
||||
light.params.point.color[0] = reader->ReadUByte(); // r
|
||||
light.params.point.color[1] = reader->ReadUByte(); // g
|
||||
light.params.point.color[2] = reader->ReadUByte(); // b
|
||||
|
||||
light.params.point.drawGlow = reader->ReadUByte();
|
||||
light.params.point.radius = reader->ReadInt16();
|
||||
|
||||
setLightList->lightList.push_back(light);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
16
mm/2s2h/resource/importer/scenecommand/SetLightListFactory.h
Normal file
16
mm/2s2h/resource/importer/scenecommand/SetLightListFactory.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetLightListFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetLightListFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,70 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetLightingSettingsFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetLightingSettings.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource> SetLightingSettingsFactory::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetLightingSettings>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetLightingSettingsFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetLightingSettings with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetLightingSettingsFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<SetLightingSettings> setLightingSettings = std::static_pointer_cast<SetLightingSettings>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setLightingSettings);
|
||||
|
||||
ReadCommandId(setLightingSettings, reader);
|
||||
|
||||
uint32_t count = reader->ReadInt32();
|
||||
setLightingSettings->settings.reserve(count);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
EnvLightSettings lightSettings;
|
||||
lightSettings.ambientColor[0] = reader->ReadInt8();
|
||||
lightSettings.ambientColor[1] = reader->ReadInt8();
|
||||
lightSettings.ambientColor[2] = reader->ReadInt8();
|
||||
|
||||
lightSettings.light1Dir[0] = reader->ReadInt8();
|
||||
lightSettings.light1Dir[1] = reader->ReadInt8();
|
||||
lightSettings.light1Dir[2] = reader->ReadInt8();
|
||||
|
||||
lightSettings.light1Color[0] = reader->ReadInt8();
|
||||
lightSettings.light1Color[1] = reader->ReadInt8();
|
||||
lightSettings.light1Color[2] = reader->ReadInt8();
|
||||
|
||||
lightSettings.light2Dir[0] = reader->ReadInt8();
|
||||
lightSettings.light2Dir[1] = reader->ReadInt8();
|
||||
lightSettings.light2Dir[2] = reader->ReadInt8();
|
||||
|
||||
lightSettings.light2Color[0] = reader->ReadInt8();
|
||||
lightSettings.light2Color[1] = reader->ReadInt8();
|
||||
lightSettings.light2Color[2] = reader->ReadInt8();
|
||||
|
||||
lightSettings.fogColor[0] = reader->ReadInt8();
|
||||
lightSettings.fogColor[1] = reader->ReadInt8();
|
||||
lightSettings.fogColor[2] = reader->ReadInt8();
|
||||
|
||||
lightSettings.fogNear = reader->ReadInt16();
|
||||
lightSettings.fogFar = reader->ReadUInt16();
|
||||
setLightingSettings->settings.push_back(lightSettings);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetLightingSettingsFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetLightingSettingsFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
169
mm/2s2h/resource/importer/scenecommand/SetMeshFactory.cpp
Normal file
169
mm/2s2h/resource/importer/scenecommand/SetMeshFactory.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetMeshFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetMesh.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "libultraship/libultraship.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
SetMeshFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetMesh>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetMeshFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr)
|
||||
{
|
||||
SPDLOG_ERROR("Failed to load SetMesh with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetMeshFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<SetMesh> setMesh = std::static_pointer_cast<SetMesh>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setMesh);
|
||||
|
||||
ReadCommandId(setMesh, reader);
|
||||
|
||||
setMesh->data = reader->ReadInt8();
|
||||
|
||||
setMesh->meshHeader.base.type = reader->ReadInt8();
|
||||
int32_t polyNum = 1;
|
||||
|
||||
if (setMesh->meshHeader.base.type != 1) {
|
||||
polyNum = reader->ReadInt8();
|
||||
if (setMesh->meshHeader.base.type == 0) {
|
||||
setMesh->meshHeader.polygon0.num = polyNum;
|
||||
} else if (setMesh->meshHeader.base.type == 2) {
|
||||
setMesh->meshHeader.polygon2.num = polyNum;
|
||||
} else {
|
||||
SPDLOG_ERROR("Tried to load mesh in SetMesh scene header with type that doesn't exist: {}", setMesh->meshHeader.base.type);
|
||||
}
|
||||
}
|
||||
|
||||
if (setMesh->meshHeader.base.type == 2) {
|
||||
setMesh->dlists2.reserve(polyNum);
|
||||
} else {
|
||||
setMesh->dlists.reserve(setMesh->meshHeader.polygon0.num);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < polyNum; i++) {
|
||||
if (setMesh->meshHeader.base.type == 0) {
|
||||
PolygonDlist dlist;
|
||||
|
||||
int32_t polyType = reader->ReadInt8(); // Unused
|
||||
std::string meshOpa = reader->ReadString();
|
||||
std::string meshXlu = reader->ReadString();
|
||||
|
||||
auto opaRes = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(meshOpa.c_str());
|
||||
auto xluRes = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(meshXlu.c_str());
|
||||
dlist.opa = meshOpa != "" ? (Gfx*)(opaRes ? opaRes->GetRawPointer() : nullptr) : 0;
|
||||
dlist.xlu = meshXlu != "" ? (Gfx*)(xluRes ? xluRes->GetRawPointer() : nullptr) : 0;
|
||||
|
||||
setMesh->dlists.push_back(dlist);
|
||||
} else if (setMesh->meshHeader.base.type == 1) {
|
||||
PolygonDlist pType;
|
||||
|
||||
setMesh->meshHeader.polygon1.format = reader->ReadUByte();
|
||||
std::string imgOpa = reader->ReadString();
|
||||
std::string imgXlu = reader->ReadString();
|
||||
|
||||
auto opaRes = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(imgOpa.c_str());
|
||||
auto xluRes = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(imgXlu.c_str());
|
||||
pType.opa = imgOpa != "" ? (Gfx*)(opaRes ? opaRes->GetRawPointer() : nullptr) : 0;
|
||||
pType.xlu = imgXlu != "" ? (Gfx*)(xluRes ? xluRes->GetRawPointer() : nullptr) : 0;
|
||||
|
||||
int32_t bgImageCount = reader->ReadUInt32();
|
||||
setMesh->images.reserve(bgImageCount);
|
||||
|
||||
for (int32_t i = 0; i < bgImageCount; i++) {
|
||||
BgImage image;
|
||||
image.unk_00 = reader->ReadUInt16();
|
||||
image.id = reader->ReadUByte();
|
||||
std::string imagePath = "__OTR__" + reader->ReadString();
|
||||
setMesh->imagePaths.push_back(imagePath);
|
||||
image.source = (void*)setMesh->imagePaths.back().c_str();
|
||||
image.unk_0C = reader->ReadUInt32();
|
||||
image.tlut = reader->ReadUInt32();
|
||||
image.width = reader->ReadUInt16();
|
||||
image.height = reader->ReadUInt16();
|
||||
image.fmt = reader->ReadUByte();
|
||||
image.siz = reader->ReadUByte();
|
||||
image.mode0 = reader->ReadUInt16();
|
||||
image.tlutCount = reader->ReadUInt16();
|
||||
|
||||
if (setMesh->meshHeader.polygon1.format == 1) {
|
||||
setMesh->meshHeader.polygon1.single.source = image.source;
|
||||
setMesh->meshHeader.polygon1.single.unk_0C = image.unk_0C;
|
||||
setMesh->meshHeader.polygon1.single.tlut = (void*)image.tlut; // OTRTODO: type of bgimage.tlut should be uintptr_t
|
||||
setMesh->meshHeader.polygon1.single.width = image.width;
|
||||
setMesh->meshHeader.polygon1.single.height = image.height;
|
||||
setMesh->meshHeader.polygon1.single.fmt = image.fmt;
|
||||
setMesh->meshHeader.polygon1.single.siz = image.siz;
|
||||
setMesh->meshHeader.polygon1.single.mode0 = image.mode0;
|
||||
setMesh->meshHeader.polygon1.single.tlutCount = image.tlutCount;
|
||||
} else {
|
||||
setMesh->images.push_back(image);
|
||||
}
|
||||
}
|
||||
|
||||
if (setMesh->meshHeader.polygon1.format != 1) {
|
||||
setMesh->meshHeader.polygon1.multi.count = bgImageCount;
|
||||
}
|
||||
|
||||
int32_t polyType = reader->ReadInt8(); // Unused??
|
||||
|
||||
std::string meshOpa = reader->ReadString();
|
||||
std::string meshXlu = reader->ReadString();
|
||||
|
||||
opaRes = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(meshOpa.c_str());
|
||||
xluRes = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(meshXlu.c_str());
|
||||
pType.opa = meshOpa != "" ? (Gfx*)(opaRes ? opaRes->GetRawPointer() : nullptr) : 0;
|
||||
pType.xlu = meshXlu != "" ? (Gfx*)(xluRes ? xluRes->GetRawPointer() : nullptr) : 0;
|
||||
|
||||
setMesh->dlists.push_back(pType);
|
||||
} else if (setMesh->meshHeader.base.type == 2) {
|
||||
PolygonDlist2 dlist;
|
||||
|
||||
int32_t polyType = reader->ReadInt8(); // Unused
|
||||
dlist.pos.x = reader->ReadInt16();
|
||||
dlist.pos.y = reader->ReadInt16();
|
||||
dlist.pos.z = reader->ReadInt16();
|
||||
dlist.unk_06 = reader->ReadInt16();
|
||||
|
||||
std::string meshOpa = reader->ReadString();
|
||||
std::string meshXlu = reader->ReadString();
|
||||
|
||||
auto opaRes = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(meshOpa.c_str());
|
||||
auto xluRes = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(meshXlu.c_str());
|
||||
dlist.opa = meshOpa != "" ? (Gfx*)(opaRes ? opaRes->GetRawPointer() : nullptr) : 0;
|
||||
dlist.xlu = meshXlu != "" ? (Gfx*)(xluRes ? xluRes->GetRawPointer() : nullptr) : 0;
|
||||
|
||||
setMesh->dlists2.push_back(dlist);
|
||||
} else {
|
||||
SPDLOG_ERROR("Tried to load mesh in SetMesh scene header with type that doesn't exist: {}", setMesh->meshHeader.base.type);
|
||||
}
|
||||
}
|
||||
|
||||
if (setMesh->meshHeader.base.type == 2) {
|
||||
setMesh->meshHeader.polygon2.start = setMesh->dlists2.data();
|
||||
} else if (setMesh->meshHeader.base.type == 0) {
|
||||
setMesh->meshHeader.polygon0.start = setMesh->dlists.data();
|
||||
} else if (setMesh->meshHeader.base.type == 1) {
|
||||
setMesh->meshHeader.polygon1.multi.list = setMesh->images.data();
|
||||
setMesh->meshHeader.polygon1.dlist = (Gfx*)setMesh->dlists.data();
|
||||
} else {
|
||||
SPDLOG_ERROR("Tried to load mesh in SetMesh scene header with type that doesn't exist: {}", setMesh->meshHeader.base.type);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
16
mm/2s2h/resource/importer/scenecommand/SetMeshFactory.h
Normal file
16
mm/2s2h/resource/importer/scenecommand/SetMeshFactory.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetMeshFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetMeshFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,50 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetMinimapChestsFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetMinimapChests.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
|
||||
std::shared_ptr<IResource> SetMinimapChestsFactory::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetMinimapChests>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetMinimapChestsFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetMinimapChestsFactory with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void SetMinimapChestsFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<SetMinimapChests> chests = std::static_pointer_cast<SetMinimapChests>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, chests);
|
||||
|
||||
ReadCommandId(chests, reader);
|
||||
|
||||
size_t size = reader->ReadUInt32();
|
||||
|
||||
chests->chests.reserve(size);
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
MinimapChestData d;
|
||||
d.unk_0 = reader->ReadUInt16();
|
||||
d.unk_2 = reader->ReadUInt16();
|
||||
d.unk_4 = reader->ReadUInt16();
|
||||
d.unk_6 = reader->ReadUInt16();
|
||||
d.unk_8 = reader->ReadUInt16();
|
||||
chests->chests.emplace_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetMinimapChestsFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource> ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetMinimapChestsFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetMinimapListFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetMinimapList.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource> SetMinimapListFactory::ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetMinimapList>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetMinimapListFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetMinimapListFactory with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
void SetMinimapListFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource) {
|
||||
std::shared_ptr<SetMinimapList> mapList = std::static_pointer_cast<SetMinimapList>(resource);
|
||||
|
||||
ResourceVersionFactory::ParseFileBinary(reader, mapList);
|
||||
|
||||
ReadCommandId(mapList, reader);
|
||||
|
||||
size_t size = reader->ReadUInt32();
|
||||
|
||||
mapList->list.scale = reader->ReadUInt16();
|
||||
mapList->entries.reserve(size);
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
MinimapEntryData data;
|
||||
data.mapId = reader->ReadUInt16();
|
||||
data.unk2 = reader->ReadUInt16();
|
||||
data.unk4 = reader->ReadUInt16();
|
||||
data.unk6 = reader->ReadUInt16();
|
||||
data.unk8 = reader->ReadUInt16();
|
||||
mapList->entries.emplace_back(data);
|
||||
}
|
||||
mapList->list.entry = mapList->entries.data();
|
||||
}
|
||||
} // namespace LUS
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetMinimapListFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource> ReadResource(std::shared_ptr<ResourceInitData> initData,
|
||||
std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetMinimapListFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
@ -0,0 +1,42 @@
|
||||
#include "2s2h/resource/importer/scenecommand/SetObjectListFactory.h"
|
||||
#include "2s2h/resource/type/scenecommand/SetObjectList.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
std::shared_ptr<IResource>
|
||||
SetObjectListFactory::ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) {
|
||||
auto resource = std::make_shared<SetObjectList>(initData);
|
||||
std::shared_ptr<ResourceVersionFactory> factory = nullptr;
|
||||
|
||||
switch (resource->GetInitData()->ResourceVersion) {
|
||||
case 0:
|
||||
factory = std::make_shared<SetObjectListFactoryV0>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (factory == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load SetObjectList with version {}", resource->GetInitData()->ResourceVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
factory->ParseFileBinary(reader, resource);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void LUS::SetObjectListFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
|
||||
std::shared_ptr<IResource> resource)
|
||||
{
|
||||
std::shared_ptr<SetObjectList> setObjectList = std::static_pointer_cast<SetObjectList>(resource);
|
||||
ResourceVersionFactory::ParseFileBinary(reader, setObjectList);
|
||||
|
||||
ReadCommandId(setObjectList, reader);
|
||||
|
||||
setObjectList->numObjects = reader->ReadUInt32();
|
||||
setObjectList->objects.reserve(setObjectList->numObjects);
|
||||
for (uint32_t i = 0; i < setObjectList->numObjects; i++) {
|
||||
setObjectList->objects.push_back(reader->ReadUInt16());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LUS
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "2s2h/resource/importer/scenecommand/SceneCommandFactory.h"
|
||||
|
||||
namespace LUS {
|
||||
class SetObjectListFactory : public SceneCommandFactory {
|
||||
public:
|
||||
std::shared_ptr<IResource>
|
||||
ReadResource(std::shared_ptr<ResourceInitData> initData, std::shared_ptr<BinaryReader> reader) override;
|
||||
};
|
||||
|
||||
class SetObjectListFactoryV0 : public SceneCommandVersionFactory {
|
||||
public:
|
||||
void ParseFileBinary(std::shared_ptr<BinaryReader> reader, std::shared_ptr<IResource> resource) override;
|
||||
};
|
||||
}; // namespace LUS
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user