From 62b65e74d81e84aa08c4e3a13396a820a5ed3a28 Mon Sep 17 00:00:00 2001 From: mchughalex <25671999+mchughalex@users.noreply.github.com> Date: Mon, 18 May 2026 23:03:10 +0100 Subject: [PATCH] create Skate 3 recompilation project --- .gitattributes | 1 + .gitignore | 31 + CMakeLists.txt | 161 +++ CMakePresets.json | 97 ++ cmake/CodegenTargets.cmake | 25 + config/eawebkit_functions.toml | 145 +++ config/skate3_functions.toml | 1776 ++++++++++++++++++++++++++++++++ manifests/eawebkit.toml.in | 12 + manifests/skate3.toml.in | 10 + src/exception_compat.cpp | 16 + src/main.cpp | 34 + src/skate3_app.manifest | 22 + src/skate3_app_common.cpp | 684 ++++++++++++ src/skate3_app_common.h | 61 ++ 14 files changed, 3075 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 CMakePresets.json create mode 100644 cmake/CodegenTargets.cmake create mode 100644 config/eawebkit_functions.toml create mode 100644 config/skate3_functions.toml create mode 100644 manifests/eawebkit.toml.in create mode 100644 manifests/skate3.toml.in create mode 100644 src/exception_compat.cpp create mode 100644 src/main.cpp create mode 100644 src/skate3_app.manifest create mode 100644 src/skate3_app_common.cpp create mode 100644 src/skate3_app_common.h diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aff7f7f --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# Build output and generated recompilation sources +/out/ +/build/ +/generated/ + +# Local game dump and retail media. Users must provide their own copy. +/game/ +*.iso +*.xex + +# Local runtime/config overrides +skate3.toml +CMakeUserPresets.json + +# Diagnostics and binary build products +*.log +*.dmp +*.wpix +*_gpu_events.csv +*_gpu_screenshot.png +*.pdb +*.ilk +*.obj +*.lib +*.exe +*.map + +# Editor and CMake scratch +/.vs/ +/.vscode/ +/.cache/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..159c3c1 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,161 @@ +cmake_minimum_required(VERSION 3.25) + +project(skate3 VERSION 0.1.0 LANGUAGES CXX) + +if(WIN32) + enable_language(RC) +endif() + +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +include(cmake/Skate3Version.cmake) + +skate3_resolve_version(SKATE3_FULL_VERSION + FLOOR_VERSION ${PROJECT_VERSION} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +string(REGEX REPLACE "-.*$" "" SKATE3_NUMERIC_VERSION "${SKATE3_FULL_VERSION}") + +if(WIN32) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64") + set(SKATE3_BUILD_PLATFORM "win-amd64") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64") + set(SKATE3_BUILD_PLATFORM "win-arm64") + else() + set(SKATE3_BUILD_PLATFORM "win-${CMAKE_SYSTEM_PROCESSOR}") + endif() +elseif(UNIX AND NOT APPLE) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64") + set(SKATE3_BUILD_PLATFORM "linux-amd64") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64") + set(SKATE3_BUILD_PLATFORM "linux-arm64") + else() + set(SKATE3_BUILD_PLATFORM "linux-${CMAKE_SYSTEM_PROCESSOR}") + endif() +else() + set(SKATE3_BUILD_PLATFORM "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") +endif() + +string(TIMESTAMP SKATE3_BUILD_TIMESTAMP "%Y%m%d_%H%M") +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/src/skate3_version.h.in + ${CMAKE_CURRENT_BINARY_DIR}/include/skate3_version.h + @ONLY +) + +set(REXSDK_DIR + "${CMAKE_CURRENT_SOURCE_DIR}/third_party/rexglue-sdk" + CACHE PATH "Path to the rexglue SDK source tree") +set(SKATE3_GAME_DATA_ROOT + "${CMAKE_CURRENT_SOURCE_DIR}/game" + CACHE PATH "Path to an extracted Skate 3 retail game dump") + +if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64") + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") + add_compile_options(-march=x86-64-v3) + set(SNAPPY_REQUIRE_AVX2 ON CACHE BOOL + "Match Snappy feature detection to the project x86-64-v3 target" FORCE) + set(SNAPPY_HAVE_SSSE3 1 CACHE INTERNAL + "x86-64-v3 requires SSSE3; Snappy checks do not see directory compile options" FORCE) + set(SNAPPY_HAVE_X86_CRC32 1 CACHE INTERNAL + "x86-64-v3 requires SSE4.2 CRC32; Snappy checks do not see directory compile options" FORCE) + set(SNAPPY_HAVE_BMI2 1 CACHE INTERNAL + "x86-64-v3 requires BMI2; Snappy checks do not see directory compile options" FORCE) + elseif(MSVC) + add_compile_options(/arch:AVX2) + endif() +endif() + +file(TO_CMAKE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" SKATE3_SOURCE_DIR_CONFIG) +file(TO_CMAKE_PATH "${SKATE3_GAME_DATA_ROOT}" SKATE3_GAME_DATA_ROOT_CONFIG) + +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/manifests") + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/manifests/skate3.toml.in + ${CMAKE_CURRENT_BINARY_DIR}/manifests/skate3.toml + @ONLY +) +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/manifests/eawebkit.toml.in + ${CMAKE_CURRENT_BINARY_DIR}/manifests/eawebkit.toml + @ONLY +) +set(REXGLUE_ENABLE_TRACY OFF CACHE BOOL "Disable Tracy instrumentation for normal Skate 3 builds" FORCE) +set(REXGLUE_ENABLE_PERF_COUNTERS OFF CACHE BOOL "Enable lightweight rexglue perf counter instrumentation" FORCE) + +include(cmake/RexGlue.cmake) +include(cmake/CodegenTargets.cmake) + +set(SKATE3_COMMON_SOURCES + src/exception_compat.cpp + src/skate3_app_common.cpp + src/skate3_iso_installer.cpp + src/skate3_user_settings.cpp +) + +set(SKATE3_SOURCES + src/main.cpp + ${SKATE3_COMMON_SOURCES} +) + +if(WIN32) + add_executable(skate3 WIN32 ${SKATE3_SOURCES}) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/src/skate3_app.manifest + ${CMAKE_CURRENT_BINARY_DIR}/skate3_app.manifest + COPYONLY + ) + target_link_options(skate3 PRIVATE LINKER:/MANIFESTINPUT:skate3_app.manifest) +else() + add_executable(skate3 ${SKATE3_SOURCES}) +endif() + +target_include_directories(skate3 PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_CURRENT_BINARY_DIR}/include +) +target_compile_definitions(skate3 PRIVATE SKATE3_BUILD_CONFIG="$") + +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/generated/sources.cmake") + include(generated/sources.cmake) + target_sources(skate3 PRIVATE ${GENERATED_SOURCES}) + target_include_directories(skate3 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/generated) +else() + message(STATUS "generated/sources.cmake not found; run the generate-all target before building skate3") +endif() + +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/generated/eawebkit/sources.cmake") + set(_SKATE3_SAVED_GENERATED_SOURCES ${GENERATED_SOURCES}) + include(generated/eawebkit/sources.cmake) + target_sources(skate3 PRIVATE ${GENERATED_SOURCES}) + target_include_directories(skate3 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/generated/eawebkit) + set(GENERATED_SOURCES ${_SKATE3_SAVED_GENERATED_SOURCES}) + unset(_SKATE3_SAVED_GENERATED_SOURCES) +else() + message(STATUS "generated/eawebkit/sources.cmake not found; run the generate-all target before building skate3") +endif() + +target_link_libraries(skate3 PRIVATE rex::runtime) +rexglue_configure_target(skate3) + +if(WIN32) + target_link_libraries(skate3 PRIVATE comdlg32) +endif() + +add_custom_target(skate3_stage_runtime_library + COMMAND ${CMAKE_COMMAND} -E make_directory "$" + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "$" + "$" + DEPENDS rexruntime + VERBATIM +) +add_dependencies(skate3 skate3_stage_runtime_library) + +if(MSVC) + target_compile_options(skate3 PRIVATE /utf-8) +else() + target_compile_options(skate3 PRIVATE -finput-charset=UTF-8 -fexec-charset=UTF-8) +endif() diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..c9256ec --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,97 @@ +{ + "version": 6, + "cmakeMinimumRequired": { + "major": 3, + "minor": 25, + "patch": 0 + }, + "configurePresets": [ + { + "name": "base", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "REXSDK_DIR": "${sourceDir}/third_party/rexglue-sdk", + "SKATE3_GAME_DATA_ROOT": "${sourceDir}/game" + } + }, + { + "name": "linux-base", + "hidden": true, + "inherits": "base", + "cacheVariables": { + "CMAKE_C_COMPILER": "clang-20", + "CMAKE_CXX_COMPILER": "clang++-20", + "CMAKE_LINKER": "ld.lld-20" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + } + }, + { + "name": "debug", + "displayName": "Debug", + "inherits": "base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "release", + "displayName": "Release", + "inherits": "base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "relwithdebinfo", + "displayName": "RelWithDebInfo", + "inherits": "base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "linux-relwithdebinfo", + "displayName": "Linux RelWithDebInfo", + "inherits": "linux-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "linux-release", + "displayName": "Linux Release", + "inherits": "linux-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + } + ], + "buildPresets": [ + { + "name": "debug", + "configurePreset": "debug" + }, + { + "name": "release", + "configurePreset": "release" + }, + { + "name": "relwithdebinfo", + "configurePreset": "relwithdebinfo" + }, + { + "name": "linux-relwithdebinfo", + "configurePreset": "linux-relwithdebinfo" + }, + { + "name": "linux-release", + "configurePreset": "linux-release" + } + ] +} diff --git a/cmake/CodegenTargets.cmake b/cmake/CodegenTargets.cmake new file mode 100644 index 0000000..e6cffe5 --- /dev/null +++ b/cmake/CodegenTargets.cmake @@ -0,0 +1,25 @@ +add_custom_target(generate-skate3 + COMMAND $ codegen + "${CMAKE_CURRENT_BINARY_DIR}/manifests/skate3.toml" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Generating recompiled code for default.xex" + VERBATIM +) + +add_custom_target(generate-eawebkit + COMMAND $ codegen + "${CMAKE_CURRENT_BINARY_DIR}/manifests/eawebkit.toml" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Generating recompiled code for EAWebkit.xex" + VERBATIM +) + +add_dependencies(generate-skate3 generate-eawebkit) + +add_custom_target(generate-all + DEPENDS generate-skate3 generate-eawebkit +) + +add_custom_target(skate3_codegen DEPENDS generate-skate3) +add_custom_target(eawebkit_codegen DEPENDS generate-eawebkit) +add_custom_target(all_codegen DEPENDS generate-all) diff --git a/config/eawebkit_functions.toml b/config/eawebkit_functions.toml new file mode 100644 index 0000000..e0d5895 --- /dev/null +++ b/config/eawebkit_functions.toml @@ -0,0 +1,145 @@ +# Function boundary overrides for EAWebkit codegen. +# Entries define address-taken functions and interior landing points needed by generated code. + +[functions] + +"0x881715C8" = { end = 0x88171F44 } + +"0x880FA358" = {} +"0x88104580" = {} +"0x88104B70" = {} +"0x8810E318" = {} +"0x8810FBF8" = {} +"0x88115080" = {} +"0x881150B8" = {} +"0x881154C8" = {} +"0x881159C0" = {} +"0x88115B88" = {} +"0x88121060" = {} +"0x88121088" = {} +"0x88121090" = {} +"0x88121358" = {} +"0x8812D0D8" = {} +"0x8812D0E0" = {} +"0x88177670" = {} +"0x88177680" = {} +"0x88177690" = {} +"0x881891A0" = {} +"0x881FECA0" = {} +"0x882177A0" = {} +"0x88236C00" = {} +"0x8826F478" = {} +"0x882737C8" = {} +"0x88346DC8" = {} +"0x8834A9A0" = {} +"0x8834F540" = {} +"0x8835BF48" = {} +"0x88369810" = {} +"0x88375488" = {} +"0x88380BF8" = {} +"0x883A5128" = {} +"0x883A5178" = {} +"0x883EBBC0" = {} +"0x883EBBD0" = {} +"0x88404DA0" = {} +"0x8843C140" = {} +"0x88444098" = {} +"0x884440C0" = {} +"0x8844AA28" = {} +"0x8844AA30" = {} +"0x8844AA38" = {} +"0x8844AA40" = {} +"0x88462048" = {} +"0x884655D0" = {} +"0x88465610" = {} +"0x88465F20" = {} +"0x88476088" = { end = 0x8847608C, parent = 0x88476038 } +"0x88476138" = { end = 0x8847613C, parent = 0x88476038 } +"0x88476148" = { end = 0x8847614C, parent = 0x88476038 } +"0x884762D4" = { end = 0x884762D8, parent = 0x88476250 } +"0x884762E0" = { end = 0x884762E4, parent = 0x88476250 } +"0x88476400" = { end = 0x88476404, parent = 0x88476368 } +"0x88476508" = { end = 0x8847650C, parent = 0x88476368 } +"0x88476600" = { end = 0x88476604, parent = 0x88476558 } +"0x88476650" = { end = 0x88476654, parent = 0x88476558 } +"0x884776DC" = { end = 0x884776E0, parent = 0x884776C0 } +"0x8847778C" = { end = 0x88477790, parent = 0x884776C0 } +"0x88477E18" = { end = 0x88477E1C, parent = 0x88477D80 } +"0x88477E34" = { end = 0x88477E38, parent = 0x88477D80 } +"0x88477E04" = { end = 0x88477E08, parent = 0x88477D80 } +"0x884781B4" = { end = 0x884781B8, parent = 0x88478138 } +"0x884781CC" = { end = 0x884781D0, parent = 0x88478138 } +"0x884781A0" = { end = 0x884781A4, parent = 0x88478138 } +"0x88478384" = { end = 0x88478388, parent = 0x88478308 } +"0x88478398" = { end = 0x8847839C, parent = 0x88478308 } +"0x8847D5C8" = { end = 0x8847D5CC, parent = 0x8847D5A0 } +"0x8847D6DC" = { end = 0x8847D6E0, parent = 0x8847D5A0 } +"0x8847E504" = { end = 0x8847E508, parent = 0x8847E438 } +"0x8847E53C" = { end = 0x8847E540, parent = 0x8847E438 } +"0x8847E7B8" = { end = 0x8847E7BC, parent = 0x8847E788 } +"0x8847E7C8" = { end = 0x8847E7CC, parent = 0x8847E788 } +"0x8847E80C" = { end = 0x8847E810, parent = 0x8847E788 } +"0x8847E86C" = { end = 0x8847E870, parent = 0x8847E788 } +"0x8847E884" = { end = 0x8847E888, parent = 0x8847E788 } +"0x8847FBB8" = { end = 0x8847FBBC, parent = 0x8847FB90 } +"0x8847FD04" = { end = 0x8847FD08, parent = 0x8847FB90 } +"0x88481BAC" = { end = 0x88481BB0, parent = 0x88481AA8 } +"0x88481BF4" = { end = 0x88481BF8, parent = 0x88481AA8 } +"0x8848224C" = { end = 0x88482250, parent = 0x88482178 } +"0x88482298" = { end = 0x8848229C, parent = 0x88482178 } +"0x8848249C" = { end = 0x884824A0, parent = 0x884823C8 } +"0x884824E8" = { end = 0x884824EC, parent = 0x884823C8 } +"0x884827FC" = { end = 0x88482800, parent = 0x88482798 } +"0x88482808" = { end = 0x8848280C, parent = 0x88482798 } +"0x884847C4" = { end = 0x884847C8, parent = 0x88484798 } +"0x88484928" = { end = 0x8848492C, parent = 0x88484798 } +"0x88484EF4" = { end = 0x88484EF8, parent = 0x88484EC0 } +"0x88484F10" = { end = 0x88484F14, parent = 0x88484EC0 } +"0x88484F88" = { end = 0x88484F8C, parent = 0x88484F60 } +"0x88484F94" = { end = 0x88484F98, parent = 0x88484F60 } +"0x88487038" = { end = 0x8848703C, parent = 0x88486EA8 } +"0x884870C8" = { end = 0x884870CC, parent = 0x88486EA8 } +"0x884872F4" = { end = 0x884872F8, parent = 0x884872D0 } +"0x88487378" = { end = 0x8848737C, parent = 0x884872D0 } +"0x88487558" = { end = 0x8848755C, parent = 0x884874C8 } +"0x884875A4" = { end = 0x884875A8, parent = 0x884874C8 } +"0x88487774" = { end = 0x88487778, parent = 0x88487748 } +"0x8848777C" = { end = 0x88487780, parent = 0x88487748 } +"0x88487788" = { end = 0x8848778C, parent = 0x88487748 } +"0x884877F0" = { end = 0x884877F4, parent = 0x884877D0 } +"0x884877FC" = { end = 0x88487800, parent = 0x884877D0 } +"0x8848780C" = { end = 0x88487810, parent = 0x884877D0 } +"0x884882B8" = { end = 0x884882BC, parent = 0x88488290 } +"0x88488314" = { end = 0x88488318, parent = 0x88488290 } +"0x8848860C" = { end = 0x88488610, parent = 0x884885B8 } +"0x88488640" = { end = 0x88488644, parent = 0x884885B8 } +"0x8848872C" = { end = 0x88488730, parent = 0x884886E8 } +"0x8848873C" = { end = 0x88488740, parent = 0x884886E8 } +"0x88488758" = { end = 0x8848875C, parent = 0x884886E8 } +"0x88488794" = { end = 0x88488798, parent = 0x884886E8 } +"0x884887C8" = { end = 0x884887CC, parent = 0x884886E8 } +"0x884888E4" = { end = 0x884888E8, parent = 0x884886E8 } +"0x88488A1C" = { end = 0x88488A20, parent = 0x88488968 } +"0x88488A7C" = { end = 0x88488A80, parent = 0x88488968 } +"0x8848921C" = { end = 0x88489220, parent = 0x88489188 } +"0x8848923C" = { end = 0x88489240, parent = 0x88489188 } +"0x88489B34" = { end = 0x88489B38, parent = 0x88489A58 } +"0x88489B7C" = { end = 0x88489B80, parent = 0x88489A58 } +"0x88489FA0" = { end = 0x88489FA4, parent = 0x88489F40 } +"0x88489FB0" = { end = 0x88489FB4, parent = 0x88489F40 } +"0x8848B878" = { end = 0x8848B87C, parent = 0x8848B300 } +"0x8848F838" = { end = 0x8848F83C, parent = 0x8848F7D0 } +"0x8848F858" = { end = 0x8848F85C, parent = 0x8848F7D0 } +"0x8848F868" = { end = 0x8848F86C, parent = 0x8848F7D0 } +"0x8848FE38" = { end = 0x8848FE3C, parent = 0x8848FDA0 } +"0x884905D4" = { end = 0x884905D8, parent = 0x8848FDA0 } +"0x884906EC" = { end = 0x884906F0, parent = 0x88490668 } +"0x884908CC" = { end = 0x884908D0, parent = 0x88490668 } +"0x88490A54" = { end = 0x88490A58, parent = 0x88490960 } +"0x88490A7C" = { end = 0x88490A80, parent = 0x88490960 } +"0x88490FDC" = { end = 0x88490FE0, parent = 0x88490960 } +"0x88490FFC" = { end = 0x88491000, parent = 0x88490960 } +"0x8849100C" = { end = 0x88491010, parent = 0x88490960 } +"0x88491174" = { end = 0x88491178, parent = 0x88490960 } +"0x88491184" = { end = 0x88491188, parent = 0x88490960 } +"0x88491190" = { end = 0x88491194, parent = 0x88490960 } diff --git a/config/skate3_functions.toml b/config/skate3_functions.toml new file mode 100644 index 0000000..1345846 --- /dev/null +++ b/config/skate3_functions.toml @@ -0,0 +1,1776 @@ +# Function boundary overrides for Skate 3 codegen. +# Entries define additional guest function starts, explicit end addresses, and parent relationships. + +[functions] + +"0x82B0C658" = { end = 0x82B0C700 } +"0x82EC9BB0" = { end = 0x82EC9BB8 } +"0x82EC9BB8" = { end = 0x82EC9BC0 } + +"0x82F44E54" = { end = 0x82F4510C } + +"0x829843F0" = { end = 0x8298448C } +"0x82E452D0" = { end = 0x82E45340 } +"0x82DA8DA0" = { end = 0x82DA8DF4 } +"0x82714D30" = { end = 0x82714D74 } +"0x824DAFC8" = { end = 0x824DB004 } +"0x82978258" = { end = 0x8297828C } + +"0x82578A08" = { end = 0x82578A20 } +"0x82983344" = { end = 0x82983368 } +"0x82A190A0" = { end = 0x82A190B8 } +"0x82BCE960" = { end = 0x82BCE98C } +"0x82C00000" = { end = 0x82C000FC } +"0x82CF73C0" = { end = 0x82CF73E8 } +"0x82CFC368" = { end = 0x82CFC38C } +"0x82D99DE0" = { end = 0x82D99E10 } +"0x82EBA290" = { end = 0x82EBA29C, parent = 0x82EB9A50 } +"0x82EBA57C" = { end = 0x82EBA594, parent = 0x82EBA318 } +"0x82EC4520" = { end = 0x82EC4534 } +"0x82ED6BE0" = { end = 0x82ED6C0C } +"0x82F22CEC" = { end = 0x82F22D04, parent = 0x82F22C20 } +"0x82F23AE8" = { end = 0x82F23B10 } +"0x82F23E04" = { end = 0x82F23E1C } +"0x82F24150" = { end = 0x82F24168 } +"0x82F2578C" = { end = 0x82F257B4 } +"0x82F26000" = { end = 0x82F26028 } +"0x82F261E0" = { end = 0x82F261F8 } +"0x82F272CC" = { end = 0x82F272F4 } +"0x82F29230" = { end = 0x82F29248 } +"0x82F29A94" = { end = 0x82F29AAC, parent = 0x82F29928 } +"0x82F29E34" = { end = 0x82F29E4C } +"0x82F2A0A8" = { end = 0x82F2A0B8 } +"0x82F2A0C0" = { end = 0x82F2A0D8 } +"0x82F2ADAC" = { end = 0x82F2ADC4 } +"0x82F2B4C0" = { end = 0x82F2B4D8 } +"0x82F2B71C" = { end = 0x82F2B734 } +"0x82F2B984" = { end = 0x82F2B99C } +"0x82F2D59C" = { end = 0x82F2D5C4 } +"0x82F2F82C" = { end = 0x82F2F844 } +"0x82F31BC4" = { end = 0x82F31BDC } +"0x82F31E24" = { end = 0x82F31E3C, parent = 0x82F31D48 } +"0x82F32288" = { end = 0x82F322A0 } +"0x82F32490" = { end = 0x82F324A4 } +"0x82F32A78" = { end = 0x82F32A9C } +"0x82F32AFC" = { end = 0x82F32B24 } +"0x82F32C4C" = { end = 0x82F32C54 } +"0x82F32CAC" = { end = 0x82F32CB4 } +"0x82F32F2C" = { end = 0x82F32F60 } +"0x82F34604" = { end = 0x82F34688 } +"0x82F34688" = { end = 0x82F346A0 } +"0x82F34CB4" = { end = 0x82F34CF0 } +"0x82F34FAC" = { end = 0x82F34FC4 } +"0x82F35298" = { end = 0x82F352D8 } +"0x82F3553C" = { end = 0x82F35554 } +"0x82F3692C" = { end = 0x82F36938 } + +"0x8270F7E0" = { end = 0x8270F82C } +"0x82B365C4" = { end = 0x82B36D08 } +"0x82420EE0" = { end = 0x82420EFC } +"0x82659930" = { end = 0x826599D8 } +"0x82791850" = { end = 0x82791870, parent = 0x82791618 } +"0x82848684" = { end = 0x82848AA8 } +"0x82886938" = { end = 0x82886940 } +"0x829783C0" = { end = 0x82978438 } +"0x82A1907C" = { end = 0x82A190A0, parent = 0x82A19000 } +"0x82A19094" = { end = 0x82A190A0, parent = 0x82A19000 } +"0x82A3F090" = { end = 0x82A3F13C } +"0x82B7C530" = { end = 0x82B7C564 } +"0x82B7C578" = { end = 0x82B7C5AC } +"0x82B7E2F0" = { end = 0x82B7E340 } +"0x82B90B28" = { end = 0x82B90B5C } +"0x82B958B8" = { end = 0x82B958EC } +"0x82BCA8B0" = { end = 0x82BCA8DC } +"0x82C58F20" = { end = 0x82C58F84 } +"0x82E60000" = { end = 0x82E600A4 } +"0x82EB4F9C" = { end = 0x82EB5060, parent = 0x82EB4F80 } +"0x82EB5128" = { end = 0x82EB5138, parent = 0x82EB4F80 } +"0x82EB5134" = { end = 0x82EB5138, parent = 0x82EB4F80 } +"0x82EB94E8" = { end = 0x82EB9518, parent = 0x82EB9480 } +"0x82EB9508" = { end = 0x82EB9518, parent = 0x82EB9480 } +"0x82EB9518" = { end = 0x82EB9540, parent = 0x82EB9480 } +"0x82EB9AE8" = { end = 0x82EB9BC0, parent = 0x82EB9A50 } +"0x82EBA284" = { end = 0x82EBA290, parent = 0x82EB9A50 } +"0x82EBA39C" = { end = 0x82EBA464, parent = 0x82EBA318 } +"0x82EBA704" = { end = 0x82EBA788, parent = 0x82EBA610 } +"0x82EBA72C" = { end = 0x82EBA788, parent = 0x82EBA610 } +"0x82EBAC8C" = { end = 0x82EBACBC } +"0x82EBACAC" = { end = 0x82EBACBC } +"0x82EBACBC" = { end = 0x82EBACF4, parent = 0x82EBA610 } +"0x82EBAE24" = { end = 0x82EBAE34, parent = 0x82EBA610 } +"0x82EBAE40" = { end = 0x82EBAE58, parent = 0x82EBA610 } +"0x82EC4540" = { end = 0x82EC4554 } +"0x82EC454C" = { end = 0x82EC4554 } +"0x82EC79A8" = { end = 0x82EC79C0, parent = 0x82EC7980 } +"0x82EC79B0" = { end = 0x82EC79C0, parent = 0x82EC7980 } +"0x82EC79C0" = { end = 0x82EC79D0, parent = 0x82EC7980 } +"0x82EE062C" = { end = 0x82EE0648 } +"0x82EE2E80" = { end = 0x82EE2EA0, parent = 0x82EE2E60 } +"0x82EE2E88" = { end = 0x82EE2EA0, parent = 0x82EE2E60 } +"0x82EE2EA0" = { end = 0x82EE2EB4, parent = 0x82EE2E60 } +"0x82F22C3C" = { end = 0x82F22CE4, parent = 0x82F22C20 } +"0x82F238D0" = { end = 0x82F23908 } +"0x82F23920" = { end = 0x82F23934 } +"0x82F23ADC" = { end = 0x82F23AE8 } +"0x82F23DC8" = { end = 0x82F23E04 } +"0x82F24048" = { end = 0x82F24098 } +"0x82F249EC" = { end = 0x82F24A18 } +"0x82F24A04" = { end = 0x82F24A18 } +"0x82F256C0" = { end = 0x82F25750 } +"0x82F25714" = { end = 0x82F25750 } +"0x82F25774" = { end = 0x82F2578C } +"0x82F258D0" = { end = 0x82F258F0 } +"0x82F258DC" = { end = 0x82F258F0 } +"0x82F25CB0" = { end = 0x82F25CE0 } +"0x82F25CCC" = { end = 0x82F25CE0 } +"0x82F25FF4" = { end = 0x82F26000 } +"0x82F261CC" = { end = 0x82F261E0 } +"0x82F271B8" = { end = 0x82F2724C } +"0x82F29220" = { end = 0x82F29230 } +"0x82F2975C" = { end = 0x82F297C0 } +"0x82F2979C" = { end = 0x82F297C0 } +"0x82F2998C" = { end = 0x82F299DC, parent = 0x82F29928 } +"0x82F29D40" = { end = 0x82F29D90 } +"0x82F2AD64" = { end = 0x82F2AD90 } +"0x82F2B474" = { end = 0x82F2B4A0 } +"0x82F2B6E4" = { end = 0x82F2B708 } +"0x82F2B830" = { end = 0x82F2B880 } +"0x82F2D56C" = { end = 0x82F2D59C } +"0x82F2F6E0" = { end = 0x82F2F788 } +"0x82F31B64" = { end = 0x82F31B98 } +"0x82F31DD8" = { end = 0x82F31E18 } +"0x82F3223C" = { end = 0x82F32268 } +"0x82F3232C" = { end = 0x82F3245C } +"0x82F32A5C" = { end = 0x82F32A78 } +"0x82F32AF0" = { end = 0x82F32AFC } +"0x82F32C54" = { end = 0x82F32C6C } +"0x82F32C60" = { end = 0x82F32C6C } +"0x82F32CB4" = { end = 0x82F32CC4 } +"0x82F32CC0" = { end = 0x82F32CC4 } +"0x82F32F10" = { end = 0x82F32F2C } +"0x82F32F1C" = { end = 0x82F32F2C } +"0x82F33F98" = { end = 0x82F34024 } +"0x82F34028" = { end = 0x82F3405C } +"0x82F34C94" = { end = 0x82F34CB4 } +"0x82F34F64" = { end = 0x82F34F90 } +"0x82F35264" = { end = 0x82F35298 } +"0x82F35384" = { end = 0x82F35414 } +"0x82F353EC" = { end = 0x82F35414 } +"0x82F35420" = { end = 0x82F35458 } +"0x82F36938" = { end = 0x82F36948 } + +"0x8270F8D8" = { end = 0x8270F8E4 } +"0x829783DC" = { end = 0x829783E0, parent = 0x829783C0 } +"0x829783E0" = { end = 0x829783F0, parent = 0x829783C0 } +"0x829783F0" = { end = 0x829783F4, parent = 0x829783C0 } +"0x829783F4" = { end = 0x82978410, parent = 0x829783C0 } +"0x82978410" = { end = 0x82978438, parent = 0x829783C0 } +"0x82B36634" = { end = 0x82B36D08, parent = 0x82B365C4 } +"0x82B7C544" = { end = 0x82B7C564 } +"0x82B7C568" = { end = 0x82B7C578 } +"0x82B7C58C" = { end = 0x82B7C5AC } +"0x82B7C5B0" = { end = 0x82B7C5C0 } +"0x82B7E304" = { end = 0x82B7E324, parent = 0x82B7E2F0 } +"0x82B7E324" = { end = 0x82B7E328, parent = 0x82B7E2F0 } +"0x82B7E328" = { end = 0x82B7E340, parent = 0x82B7E2F0 } +"0x82B90B3C" = { end = 0x82B90B5C } +"0x82B90B60" = { end = 0x82B90B78 } +"0x82B958CC" = { end = 0x82B958EC } +"0x82B958F0" = { end = 0x82B95900 } +"0x82C59600" = { end = 0x82C59618, parent = 0x82C58B58 } +"0x82EB9A34" = { end = 0x82EB9A3C, parent = 0x82EB9480 } +"0x82EBA150" = { end = 0x82EBA284, parent = 0x82EB9A50 } +"0x82EBA508" = { end = 0x82EBA57C, parent = 0x82EBA318 } +"0x82EBA798" = { end = 0x82EBAC8C, parent = 0x82EBA610 } +"0x82EBAD0C" = { end = 0x82EBAE24, parent = 0x82EBA610 } +"0x82EC79D0" = { end = 0x82EC79DC, parent = 0x82EC7980 } +"0x82EC79DC" = { end = 0x82EC79F4, parent = 0x82EC7980 } +"0x82EE2EB4" = { end = 0x82EE2FAC, parent = 0x82EE2E60 } +"0x82EE2FAC" = { end = 0x82EE2FB4, parent = 0x82EE2E60 } +"0x82F23934" = { end = 0x82F23938 } +"0x82F23938" = { end = 0x82F23940 } +"0x82F240AC" = { end = 0x82F24150 } +"0x82F258F4" = { end = 0x82F2590C } +"0x82F299F0" = { end = 0x82F29A94, parent = 0x82F29928 } +"0x82F29DA4" = { end = 0x82F29E34 } +"0x82F2B894" = { end = 0x82F2B984 } +"0x82F31B9C" = { end = 0x82F31BC4 } +"0x82F3246C" = { end = 0x82F32490 } +"0x82F34068" = { end = 0x82F340A4 } +"0x82F35460" = { end = 0x82F3553C } + +"0x82791864" = { end = 0x827918B8, parent = 0x82791618 } +"0x827918B8" = { end = 0x827918BC, parent = 0x82791618 } +"0x827918BC" = { end = 0x82791904, parent = 0x82791618 } +"0x82791904" = { end = 0x82791928, parent = 0x82791618 } +"0x82791928" = { end = 0x8279192C, parent = 0x82791618 } +"0x8279192C" = { end = 0x82791944, parent = 0x82791618 } +"0x82791944" = { end = 0x82791960, parent = 0x82791618 } +"0x82791960" = { end = 0x82791968, parent = 0x82791618 } +"0x82791968" = { end = 0x827919A0, parent = 0x82791618 } +"0x827919A0" = { end = 0x827919BC, parent = 0x82791618 } +"0x827919BC" = { end = 0x82791A24, parent = 0x82791618 } +"0x82791A24" = { end = 0x82791A38, parent = 0x82791618 } +"0x82791A38" = { end = 0x82791AA0, parent = 0x82791618 } +"0x82791AA0" = { end = 0x82791AC0, parent = 0x82791618 } +"0x82791AC0" = { end = 0x82791AD0, parent = 0x82791618 } +"0x82791AD0" = { end = 0x82791AE0, parent = 0x82791618 } +"0x82A3EFC8" = { end = 0x82A3EFD4, parent = 0x82A3EE98 } +"0x82A3EFD4" = { end = 0x82A3EFE4, parent = 0x82A3EE98 } +"0x82A3EFE4" = { end = 0x82A3F020, parent = 0x82A3EE98 } +"0x82A3F020" = { end = 0x82A3F090, parent = 0x82A3EE98 } +"0x82B3661C" = { end = 0x82B36630, parent = 0x82B365C4 } +"0x82B36630" = { end = 0x82B36634, parent = 0x82B365C4 } +"0x82B3664C" = { end = 0x82B36D08, parent = 0x82B365C4 } +"0x82C5900C" = { end = 0x82C59048, parent = 0x82C58B58 } +"0x82C59048" = { end = 0x82C59188, parent = 0x82C58B58 } +"0x82C59188" = { end = 0x82C59228, parent = 0x82C58B58 } +"0x82C59228" = { end = 0x82C593F4, parent = 0x82C58B58 } +"0x82C593F4" = { end = 0x82C59424, parent = 0x82C58B58 } +"0x82C59424" = { end = 0x82C594F0, parent = 0x82C58B58 } +"0x82C594F0" = { end = 0x82C59538, parent = 0x82C58B58 } +"0x82C59538" = { end = 0x82C59600, parent = 0x82C58B58 } +"0x82E600A4" = { end = 0x82E600B0 } +"0x82EB5020" = { end = 0x82EB5060, parent = 0x82EB4F80 } +"0x82EB5060" = { end = 0x82EB5084, parent = 0x82EB4F80 } +"0x82EB5084" = { end = 0x82EB509C, parent = 0x82EB4F80 } +"0x82EB509C" = { end = 0x82EB50D4, parent = 0x82EB4F80 } +"0x82EB50D4" = { end = 0x82EB50E4, parent = 0x82EB4F80 } +"0x82EB50E4" = { end = 0x82EB50E8, parent = 0x82EB4F80 } +"0x82EB50E8" = { end = 0x82EB5100, parent = 0x82EB4F80 } +"0x82EB5100" = { end = 0x82EB5128, parent = 0x82EB4F80 } +"0x82EB9530" = { end = 0x82EB9538, parent = 0x82EB9480 } +"0x82EB9538" = { end = 0x82EB9540, parent = 0x82EB9480 } +"0x82EB9540" = { end = 0x82EB9558, parent = 0x82EB9480 } +"0x82EB9558" = { end = 0x82EB9570, parent = 0x82EB9480 } +"0x82EB9570" = { end = 0x82EB9588, parent = 0x82EB9480 } +"0x82EB9588" = { end = 0x82EB95A0, parent = 0x82EB9480 } +"0x82EB95A0" = { end = 0x82EB95B8, parent = 0x82EB9480 } +"0x82EB95B8" = { end = 0x82EB95D0, parent = 0x82EB9480 } +"0x82EB95D0" = { end = 0x82EB95E8, parent = 0x82EB9480 } +"0x82EB95E8" = { end = 0x82EB95F0, parent = 0x82EB9480 } +"0x82EB95F0" = { end = 0x82EB9618, parent = 0x82EB9480 } +"0x82EB9618" = { end = 0x82EB9620, parent = 0x82EB9480 } +"0x82EB9620" = { end = 0x82EB9648, parent = 0x82EB9480 } +"0x82EB9648" = { end = 0x82EB9674, parent = 0x82EB9480 } +"0x82EB9674" = { end = 0x82EB9680, parent = 0x82EB9480 } +"0x82EB9680" = { end = 0x82EB969C, parent = 0x82EB9480 } +"0x82EB969C" = { end = 0x82EB96A0, parent = 0x82EB9480 } +"0x82EB96A0" = { end = 0x82EB96FC, parent = 0x82EB9480 } +"0x82EB96FC" = { end = 0x82EB9790, parent = 0x82EB9480 } +"0x82EB9790" = { end = 0x82EB9798, parent = 0x82EB9480 } +"0x82EB9798" = { end = 0x82EB97A8, parent = 0x82EB9480 } +"0x82EB97A8" = { end = 0x82EB97E8, parent = 0x82EB9480 } +"0x82EB97E8" = { end = 0x82EB9848, parent = 0x82EB9480 } +"0x82EB9848" = { end = 0x82EB9854, parent = 0x82EB9480 } +"0x82EB9854" = { end = 0x82EB98B4, parent = 0x82EB9480 } +"0x82EB98B4" = { end = 0x82EB9974, parent = 0x82EB9480 } +"0x82EB9974" = { end = 0x82EB9A34, parent = 0x82EB9480 } +"0x82EB9BC0" = { end = 0x82EB9C10, parent = 0x82EB9A50 } +"0x82EB9C10" = { end = 0x82EB9C20, parent = 0x82EB9A50 } +"0x82EB9C20" = { end = 0x82EB9C30, parent = 0x82EB9A50 } +"0x82EB9C30" = { end = 0x82EB9C40, parent = 0x82EB9A50 } +"0x82EB9C40" = { end = 0x82EB9C50, parent = 0x82EB9A50 } +"0x82EB9C50" = { end = 0x82EB9C60, parent = 0x82EB9A50 } +"0x82EB9C60" = { end = 0x82EB9C70, parent = 0x82EB9A50 } +"0x82EB9C70" = { end = 0x82EB9CFC, parent = 0x82EB9A50 } +"0x82EB9CFC" = { end = 0x82EB9D08, parent = 0x82EB9A50 } +"0x82EB9D08" = { end = 0x82EB9D64, parent = 0x82EB9A50 } +"0x82EB9D64" = { end = 0x82EB9D78, parent = 0x82EB9A50 } +"0x82EB9D78" = { end = 0x82EB9DA4, parent = 0x82EB9A50 } +"0x82EB9DA4" = { end = 0x82EB9DA8, parent = 0x82EB9A50 } +"0x82EB9DA8" = { end = 0x82EB9E14, parent = 0x82EB9A50 } +"0x82EB9E14" = { end = 0x82EB9E90, parent = 0x82EB9A50 } +"0x82EB9E90" = { end = 0x82EB9ED4, parent = 0x82EB9A50 } +"0x82EB9ED4" = { end = 0x82EB9F40, parent = 0x82EB9A50 } +"0x82EB9F40" = { end = 0x82EB9F64, parent = 0x82EB9A50 } +"0x82EB9F64" = { end = 0x82EB9FA4, parent = 0x82EB9A50 } +"0x82EB9FA4" = { end = 0x82EBA008, parent = 0x82EB9A50 } +"0x82EBA008" = { end = 0x82EBA048, parent = 0x82EB9A50 } +"0x82EBA048" = { end = 0x82EBA0A0, parent = 0x82EB9A50 } +"0x82EBA0A0" = { end = 0x82EBA0E0, parent = 0x82EB9A50 } +"0x82EBA0E0" = { end = 0x82EBA108, parent = 0x82EB9A50 } +"0x82EBA108" = { end = 0x82EBA13C, parent = 0x82EB9A50 } +"0x82EBA13C" = { end = 0x82EBA150, parent = 0x82EB9A50 } +"0x82EBA18C" = { end = 0x82EBA250, parent = 0x82EB9A50 } +"0x82EBA250" = { end = 0x82EBA284, parent = 0x82EB9A50 } +"0x82EBA464" = { end = 0x82EBA490, parent = 0x82EBA318 } +"0x82EBA490" = { end = 0x82EBA4E4, parent = 0x82EBA318 } +"0x82EBA4E4" = { end = 0x82EBA508, parent = 0x82EBA318 } +"0x82EBA510" = { end = 0x82EBA51C, parent = 0x82EBA318 } +"0x82EBA51C" = { end = 0x82EBA57C, parent = 0x82EBA318 } +"0x82EBA788" = { end = 0x82EBA798, parent = 0x82EBA610 } +"0x82EBACF4" = { end = 0x82EBAD0C, parent = 0x82EBA610 } +"0x82EBADF0" = { end = 0x82EBADF8, parent = 0x82EBA610 } +"0x82EBADF8" = { end = 0x82EBAE24, parent = 0x82EBA610 } +"0x82EE0650" = { end = 0x82EE0668 } +"0x82F22CE4" = { end = 0x82F22CEC, parent = 0x82F22C20 } +"0x82F23908" = { end = 0x82F23920 } +"0x82F24098" = { end = 0x82F240AC } +"0x82F24118" = { end = 0x82F24150 } +"0x82F249D8" = { end = 0x82F249EC } +"0x82F256D0" = { end = 0x82F25714 } +"0x82F25750" = { end = 0x82F25774 } +"0x82F25780" = { end = 0x82F2578C } +"0x82F25C9C" = { end = 0x82F25CB0 } +"0x82F27244" = { end = 0x82F2724C } +"0x82F2724C" = { end = 0x82F27280 } +"0x82F27280" = { end = 0x82F272A4 } +"0x82F272A4" = { end = 0x82F272B8 } +"0x82F272B8" = { end = 0x82F272CC } +"0x82F2973C" = { end = 0x82F29744 } +"0x82F29744" = { end = 0x82F2975C } +"0x82F299DC" = { end = 0x82F299F0, parent = 0x82F29928 } +"0x82F29A5C" = { end = 0x82F29A94, parent = 0x82F29928 } +"0x82F29D90" = { end = 0x82F29DA4 } +"0x82F29E10" = { end = 0x82F29E34 } +"0x82F2AD90" = { end = 0x82F2ADAC } +"0x82F2B4A0" = { end = 0x82F2B4C0 } +"0x82F2B708" = { end = 0x82F2B71C } +"0x82F2B880" = { end = 0x82F2B894 } +"0x82F2B900" = { end = 0x82F2B984 } +"0x82F2F788" = { end = 0x82F2F794 } +"0x82F2F794" = { end = 0x82F2F7E4 } +"0x82F2F7E4" = { end = 0x82F2F800 } +"0x82F2F800" = { end = 0x82F2F82C } +"0x82F31B98" = { end = 0x82F31B9C } +"0x82F31BB0" = { end = 0x82F31BC4 } +"0x82F31E18" = { end = 0x82F31E20, parent = 0x82F31D48 } +"0x82F31E20" = { end = 0x82F31E24, parent = 0x82F31D48 } +"0x82F32268" = { end = 0x82F32288 } +"0x82F3245C" = { end = 0x82F32468 } +"0x82F32468" = { end = 0x82F3246C } +"0x82F32F4C" = { end = 0x82F32F60 } +"0x82F34024" = { end = 0x82F34028 } +"0x82F3405C" = { end = 0x82F34068 } +"0x82F34F90" = { end = 0x82F34FAC } +"0x82F353B0" = { end = 0x82F353EC } +"0x82F35414" = { end = 0x82F35420 } +"0x82F3542C" = { end = 0x82F35458 } +"0x82F35458" = { end = 0x82F35460 } +"0x82F3546C" = { end = 0x82F35494 } +"0x82F35494" = { end = 0x82F354AC } +"0x82F354AC" = { end = 0x82F3553C } +"0x82F3694C" = { end = 0x82F36960 } + +"0x82A3F094" = { end = 0x82A3F0B4, parent = 0x82A3EE98 } +"0x82A3F0B4" = { end = 0x82A3F0C4, parent = 0x82A3EE98 } +"0x82A3F0C4" = { end = 0x82A3F0D0, parent = 0x82A3EE98 } +"0x82A3F0D0" = { end = 0x82A3F140, parent = 0x82A3EE98 } +"0x82C59238" = { end = 0x82C593F4, parent = 0x82C58B58 } +"0x82EB50A8" = { end = 0x82EB50D4, parent = 0x82EB4F80 } +"0x82EB5108" = { end = 0x82EB5128, parent = 0x82EB4F80 } +"0x82EB9628" = { end = 0x82EB9648, parent = 0x82EB9480 } +"0x82EB9684" = { end = 0x82EB969C, parent = 0x82EB9480 } +"0x82EB97F4" = { end = 0x82EB9848, parent = 0x82EB9480 } +"0x82EB98B8" = { end = 0x82EB9974, parent = 0x82EB9480 } +"0x82EB9C7C" = { end = 0x82EB9CFC, parent = 0x82EB9A50 } +"0x82EB9F3C" = { end = 0x82EB9F40, parent = 0x82EB9A50 } +"0x82EBA100" = { end = 0x82EBA108, parent = 0x82EB9A50 } +"0x82EBA114" = { end = 0x82EBA13C, parent = 0x82EB9A50 } +"0x82EBA254" = { end = 0x82EBA284, parent = 0x82EB9A50 } +"0x82F27228" = { end = 0x82F27244 } +"0x82F35394" = { end = 0x82F353B0 } + +"0x823C3F80" = { end = 0x823C3F84, parent = 0x823C3E2C } +"0x823C3F88" = { end = 0x823C3F8C, parent = 0x823C3E2C } +"0x823C3F94" = { end = 0x823C3F98, parent = 0x823C3E2C } +"0x823C6ED8" = { end = 0x823C6EDC, parent = 0x823C6E34 } +"0x823CA578" = {} +"0x823EDE18" = { end = 0x823EDE1C, parent = 0x823EDD1C } +"0x823EDE20" = { end = 0x823EDE24, parent = 0x823EDD1C } +"0x823EDEE8" = { end = 0x823EDEEC, parent = 0x823EDD1C } +"0x823EDFA0" = { end = 0x823EDFA4, parent = 0x823EDEF8 } +"0x823EDFA8" = { end = 0x823EDFAC, parent = 0x823EDEF8 } +"0x823FDC70" = {} +"0x8240069C" = { end = 0x824006A0, parent = 0x82400664 } +"0x824584DC" = { end = 0x824584E0, parent = 0x82458278 } +"0x82486F74" = {} +"0x828AAC40" = { end = 0x828AAC44, parent = 0x828AAAE0 } +"0x828AAC4C" = { end = 0x828AAC50, parent = 0x828AAC48 } +"0x828AADA0" = { end = 0x828AADA4, parent = 0x828AAC74 } +"0x828AB358" = { end = 0x828AB35C, parent = 0x828AADA8 } +"0x828AB364" = { end = 0x828AB368, parent = 0x828AB360 } +"0x828BF1E0" = {} +"0x828BF218" = {} +"0x828F2688" = { end = 0x828F268C, parent = 0x828F2628 } +"0x828F8A80" = { end = 0x828F8A84, parent = 0x828F8940 } +"0x829422A8" = { end = 0x829422AC, parent = 0x829421B0 } +"0x829431A8" = { end = 0x829431AC, parent = 0x82943150 } +"0x82E3461C" = { end = 0x82E34620, parent = 0x82E34610 } +"0x82F27440" = {} +"0x82F283BC" = {} +"0x82F283E0" = {} +"0x82F2DBDC" = {} +"0x82F2DC90" = { end = 0x82F2DC94, parent = 0x82F2DC68 } +"0x82F2E760" = { end = 0x82F2E764, parent = 0x82F2E720 } +"0x82F2FA2C" = { end = 0x82F2FA30, parent = 0x82F2F9C8 } + +"0x82B36608" = { end = 0x82B3661C, parent = 0x82B365C4 } + +"0x823C0B70" = { end = 0x823C0B74 } +"0x8243B490" = { end = 0x8243B494 } +"0x82441380" = { end = 0x82441384 } +"0x824432FC" = { end = 0x82443310 } +"0x82470C64" = { end = 0x82470C68 } +"0x824746A8" = { end = 0x824746AC } +"0x824798B8" = { end = 0x824798BC } +"0x8249BC10" = { end = 0x8249BC34 } +"0x824E8214" = { end = 0x824E8218 } +"0x825054D0" = { end = 0x825054F8 } +"0x8250558C" = { end = 0x82505590 } +"0x825058B8" = { end = 0x82505934 } +"0x82509188" = { end = 0x82509194 } +"0x8250BCB8" = { end = 0x8250BCBC } +"0x82520A68" = { end = 0x82520A6C } +"0x82535A54" = { end = 0x82535A58 } +"0x82557EA0" = { end = 0x82557EC8 } +"0x82561094" = { end = 0x82561098 } +"0x82562F78" = { end = 0x82562F7C } +"0x825638EC" = { end = 0x825638F0 } +"0x82565660" = { end = 0x82565664 } +"0x82565990" = { end = 0x82565994 } +"0x82565BA0" = { end = 0x82565BA4 } +"0x8256AD98" = { end = 0x8256ADB0 } +"0x8256ADB0" = { end = 0x8256ADC8 } +"0x8256BE40" = { end = 0x8256BE44 } +"0x82574B90" = { end = 0x82574B94 } +"0x825890C8" = { end = 0x825890D0 } +"0x825890D8" = { end = 0x825890E0 } +"0x825890E0" = { end = 0x825890E8 } +"0x82589138" = { end = 0x82589140 } +"0x82589140" = { end = 0x82589148 } +"0x82589A64" = { end = 0x82589A68 } +"0x825ABE80" = { end = 0x825ABE84 } +"0x825AD354" = { end = 0x825AD358 } +"0x825AF5E0" = { end = 0x825AF5EC } +"0x825B62F4" = { end = 0x825B62F8 } +"0x825B63BC" = { end = 0x825B63C0 } +"0x825B8AFC" = { end = 0x825B8B00 } +"0x825B9F68" = { end = 0x825B9F70 } +"0x825BAAF0" = { end = 0x825BAAF4 } +"0x825CEB30" = { end = 0x825CEB38 } +"0x825E3B60" = { end = 0x825E3B64 } +"0x825E4C28" = { end = 0x825E4C30 } +"0x825EC154" = { end = 0x825EC158 } +"0x825F0190" = { end = 0x825F01AC } +"0x825F01E8" = { end = 0x825F0200 } +"0x825F0200" = { end = 0x825F0218 } +"0x825F02CC" = { end = 0x825F02D0 } +"0x825F1830" = { end = 0x825F184C } +"0x825F1EC4" = { end = 0x825F1EC8 } +"0x825F5AF0" = { end = 0x825F5AF4 } +"0x825FB79C" = { end = 0x825FB7A0 } +"0x8260FF48" = { end = 0x8260FF50 } +"0x826185B0" = { end = 0x826185D0 } +"0x8261BF78" = { end = 0x8261BF98 } +"0x8261C028" = { end = 0x8261C02C } +"0x8261C878" = { end = 0x8261C87C } +"0x8261CFE8" = { end = 0x8261D000 } +"0x8262F9D0" = { end = 0x8262F9D4 } +"0x82639C7C" = { end = 0x82639C80 } +"0x8263A048" = { end = 0x8263A068 } +"0x8263A9A8" = { end = 0x8263A9AC } +"0x8263BC80" = { end = 0x8263BC8C } +"0x826495C4" = { end = 0x826495C8 } +"0x82649E8C" = { end = 0x82649E90 } +"0x8264D198" = { end = 0x8264D19C } +"0x826576C8" = { end = 0x826576CC } +"0x82659F7C" = { end = 0x82659F80 } +"0x8265A800" = { end = 0x8265A804 } +"0x82664818" = { end = 0x8266481C } +"0x826674C4" = { end = 0x826674C8 } +"0x82667D38" = { end = 0x82667D3C } +"0x82670808" = { end = 0x8267080C } +"0x8267C758" = { end = 0x8267C770 } +"0x8267C770" = { end = 0x8267C788 } +"0x8267C978" = { end = 0x8267C97C } +"0x826834D0" = { end = 0x826834D4 } +"0x826856AC" = { end = 0x826856B0 } +"0x8268DCE0" = { end = 0x8268DCE4 } +"0x82690DCC" = { end = 0x82690DD0 } +"0x826BE050" = { end = 0x826BE05C } +"0x826E5CF0" = { end = 0x826E5CF4 } +"0x826EEF00" = { end = 0x826EEF04 } +"0x826EF570" = { end = 0x826EF574 } +"0x82705C18" = { end = 0x82705C20 } +"0x827082F0" = { end = 0x827082F4 } +"0x8270F8D4" = { end = 0x8270F8E4 } +"0x82714CE8" = { end = 0x82714D30 } +"0x8271F588" = { end = 0x8271F5A0 } +"0x82734D80" = { end = 0x82734D84 } +"0x82735908" = { end = 0x82735910 } +"0x827359B0" = { end = 0x827359B8 } +"0x827359D0" = { end = 0x827359D8 } +"0x82736664" = { end = 0x82736668 } +"0x8273A790" = { end = 0x8273A79C } +"0x827402F0" = { end = 0x82740300 } +"0x82740300" = { end = 0x82740310 } +"0x82740310" = { end = 0x82740318 } +"0x82746C40" = { end = 0x82746C44 } +"0x82746CA0" = { end = 0x82746CA4 } +"0x8275B4E0" = { end = 0x8275B4E4 } +"0x82762030" = { end = 0x82762034 } +"0x8276FB48" = { end = 0x8276FB4C } +"0x827720A8" = { end = 0x827720AC } +"0x8278286C" = { end = 0x82782870 } +"0x82784D38" = { end = 0x82784D3C } +"0x827AE4AC" = { end = 0x827AE4B0 } +"0x827AEF58" = { end = 0x827AEF5C } +"0x827AF748" = { end = 0x827AF74C } +"0x827AFA08" = { end = 0x827AFA0C } +"0x827B6ECC" = { end = 0x827B6ED0 } +"0x827BA8D8" = { end = 0x827BA8EC } +"0x827BC08C" = { end = 0x827BC090 } +"0x827BD770" = { end = 0x827BD78C } +"0x827F0CE4" = { end = 0x827F0CE8 } +"0x827FE808" = { end = 0x827FE820 } +"0x827FE820" = { end = 0x827FE838 } +"0x827FE838" = { end = 0x827FE850 } +"0x827FE850" = { end = 0x827FE868 } +"0x82809A90" = { end = 0x82809AB8 } +"0x82809AB8" = { end = 0x82809ABC } +"0x8280C228" = { end = 0x8280C22C } +"0x8280EDE0" = { end = 0x8280EDE8 } +"0x8283C7C8" = { end = 0x8283C7CC } +"0x8284FAC0" = { end = 0x8284FAC4 } +"0x8285F85C" = { end = 0x8285F860 } +"0x8286B694" = { end = 0x8286B698 } +"0x8288522C" = { end = 0x82885230 } +"0x82885CEC" = { end = 0x82885CF0 } +"0x828A07E8" = { end = 0x828A07EC } +"0x828B19B8" = { end = 0x828B19BC } +"0x828BC724" = { end = 0x828BC728 } +"0x828EBA64" = { end = 0x828EBA74 } +"0x8290BB00" = { end = 0x8290BB04 } +"0x82911214" = { end = 0x82911218 } +"0x82916EEC" = { end = 0x82916EF0 } +"0x8291AB70" = { end = 0x8291AB74 } +"0x8291FD90" = { end = 0x8291FD94 } +"0x829347D8" = { end = 0x829347EC } +"0x82939108" = { end = 0x8293910C } +"0x82939630" = { end = 0x8293972C } +"0x82939800" = { end = 0x829398F8 } +"0x82939960" = { end = 0x829399B4 } +"0x82939B58" = { end = 0x82939D34 } +"0x82939E10" = { end = 0x82939EE0 } +"0x8293ABE0" = { end = 0x8293AD14 } +"0x8293ADB8" = { end = 0x8293AE48 } +"0x8293AF40" = { end = 0x8293B02C } +"0x8293B848" = { end = 0x8293B8EC } +"0x8293BA60" = { end = 0x8293BC40 } +"0x8293C058" = { end = 0x8293C140 } +"0x8293C7B0" = { end = 0x8293C890 } +"0x8293CEB8" = { end = 0x8293CF14 } +"0x8293D028" = { end = 0x8293D12C } +"0x8293D210" = { end = 0x8293D2E4 } +"0x8293D340" = { end = 0x8293D38C } +"0x8293D5A8" = { end = 0x8293D644 } +"0x8293D6D8" = { end = 0x8293D774 } +"0x8293DAF8" = { end = 0x8293DB84 } +"0x8293DC78" = { end = 0x8293DCEC } +"0x8293DD98" = { end = 0x8293DDF8 } +"0x8293EBA8" = { end = 0x8293EBAC } +"0x82964B28" = { end = 0x82964B30 } +"0x82964B38" = { end = 0x82964B40 } +"0x82964B40" = { end = 0x82964B48 } +"0x82964B48" = { end = 0x82964B50 } +"0x82964B50" = { end = 0x82964B58 } +"0x8296DB90" = { end = 0x8296DB94 } +"0x82972134" = { end = 0x82972138 } +"0x82972168" = { end = 0x8297216C } +"0x829779D0" = { end = 0x829779DC } +"0x82978330" = { end = 0x82978360 } +"0x82978360" = { end = 0x82978390 } +"0x82978390" = { end = 0x829783C0 } +"0x8297A078" = { end = 0x8297A07C } +"0x829A4160" = { end = 0x829A4168 } +"0x829A4198" = { end = 0x829A41A8 } +"0x829A41A8" = { end = 0x829A41B0 } +"0x829BA4C8" = { end = 0x829BA4D0 } +"0x829C8650" = { end = 0x829C8654 } +"0x829D9C78" = { end = 0x829D9C7C } +"0x829DE7C0" = { end = 0x829DE7C4 } +"0x829DF770" = { end = 0x829DF774 } +"0x829E57F0" = { end = 0x829E5800 } +"0x829E99F8" = { end = 0x829E9A0C } +"0x829EDD30" = { end = 0x829EDD40 } +"0x829EDD40" = { end = 0x829EDD50 } +"0x829EDD60" = { end = 0x829EDD68 } +"0x829EDD78" = { end = 0x829EDD88 } +"0x829EDD88" = { end = 0x829EDD98 } +"0x829EDD98" = { end = 0x829EDDA8 } +"0x829EDDD8" = { end = 0x829EDDE0 } +"0x829EDDF0" = { end = 0x829EDE00 } +"0x829EDE00" = { end = 0x829EDE10 } +"0x829EDE10" = { end = 0x829EDE20 } +"0x829EDE20" = { end = 0x829EDE30 } +"0x829EDE30" = { end = 0x829EDE38 } +"0x829EDE50" = { end = 0x829EDE60 } +"0x829EDE60" = { end = 0x829EDE70 } +"0x829EDE70" = { end = 0x829EDE80 } +"0x829EDE80" = { end = 0x829EDE90 } +"0x82A2EB20" = { end = 0x82A2EB3C } +"0x82A50A4C" = { end = 0x82A50A74 } +"0x82A56344" = { end = 0x82A56348 } +"0x82A597F0" = { end = 0x82A59808 } +"0x82A5E5F8" = { end = 0x82A5E610 } +"0x82A5E920" = { end = 0x82A5E950 } +"0x82A5E950" = { end = 0x82A5E980 } +"0x82A6D928" = { end = 0x82A6D92C } +"0x82A70D50" = { end = 0x82A70D54 } +"0x82A70D88" = { end = 0x82A70D8C } +"0x82A70F40" = { end = 0x82A70F44 } +"0x82A7F960" = { end = 0x82A7F964 } +"0x82A970A4" = { end = 0x82A970A8 } +"0x82AF38F0" = { end = 0x82AF38F4 } +"0x82B0C6FC" = { end = 0x82B0C700, parent = 0x82B0C658 } +"0x82B40E64" = { end = 0x82B40E68 } +"0x82B41588" = { end = 0x82B4158C } +"0x82B42F38" = { end = 0x82B42F3C } +"0x82B44ED8" = { end = 0x82B44EDC } +"0x82B479FC" = { end = 0x82B47A00 } +"0x82B4B06C" = { end = 0x82B4B070 } +"0x82B7C564" = { end = 0x82B7C578 } +"0x82B7C5AC" = { end = 0x82B7C5C0 } +"0x82B7E340" = { end = 0x82B7E348 } +"0x82B90B5C" = { end = 0x82B90B74 } +"0x82B9508C" = { end = 0x82B95090 } +"0x82B958EC" = { end = 0x82B95900 } +"0x82BCCBC8" = { end = 0x82BCCBE8 } +"0x82BCE98C" = { end = 0x82BCE9B0 } +"0x82BCE9B0" = { end = 0x82BCE9B4 } +"0x82BEC484" = { end = 0x82BEC488 } +"0x82BF99F8" = { end = 0x82BF99FC } +"0x82C1C9F8" = { end = 0x82C1CA00 } +"0x82C1F0C0" = { end = 0x82C1F0C8 } +"0x82C2F9A0" = { end = 0x82C2F9C0 } +"0x82C32CF8" = { end = 0x82C32D00 } +"0x82C32D58" = { end = 0x82C32D60 } +"0x82C780D8" = { end = 0x82C780E4 } +"0x82CDE6D4" = { end = 0x82CDE6D8 } +"0x82CDE9A8" = { end = 0x82CDE9AC } +"0x82CE9980" = { end = 0x82CE9984 } +"0x82CEAE04" = { end = 0x82CEAE08 } +"0x82CEF768" = { end = 0x82CEF780 } +"0x82CEF780" = { end = 0x82CEF798 } +"0x82CEF798" = { end = 0x82CEF7B0 } +"0x82CEFC38" = { end = 0x82CEFC50 } +"0x82CEFC50" = { end = 0x82CEFC68 } +"0x82CEFC68" = { end = 0x82CEFC80 } +"0x82CEFFD8" = { end = 0x82CEFFDC } +"0x82CF0064" = { end = 0x82CF0068 } +"0x82CF008C" = { end = 0x82CF0090 } +"0x82CF73E8" = { end = 0x82CF7400 } +"0x82CFC38C" = { end = 0x82CFC3A0 } +"0x82CFC3C0" = { end = 0x82CFC3C8 } +"0x82D282D8" = { end = 0x82D28308 } +"0x82D35060" = { end = 0x82D35064 } +"0x82D9D4B8" = { end = 0x82D9D4BC } +"0x82DCE710" = { end = 0x82DCE714 } +"0x82DE2FA8" = { end = 0x82DE2FAC } +"0x82DE2FD0" = { end = 0x82DE2FD4 } +"0x82DE2FF8" = { end = 0x82DE2FFC } +"0x82DE3020" = { end = 0x82DE3024 } +"0x82DE3A5C" = { end = 0x82DE3A60 } +"0x82DF6028" = { end = 0x82DF6030 } +"0x82DF6040" = { end = 0x82DF6048 } +"0x82DF6060" = { end = 0x82DF6068 } +"0x82DF6070" = { end = 0x82DF6078 } +"0x82DF6078" = { end = 0x82DF6080 } +"0x82DF60A0" = { end = 0x82DF60A8 } +"0x82DF60A8" = { end = 0x82DF60B0 } +"0x82DF60B0" = { end = 0x82DF60B8 } +"0x82DF60E0" = { end = 0x82DF60E8 } +"0x82DF6100" = { end = 0x82DF6108 } +"0x82DF6108" = { end = 0x82DF6110 } +"0x82DF6110" = { end = 0x82DF6118 } +"0x82DF6138" = { end = 0x82DF6140 } +"0x82DF6140" = { end = 0x82DF6148 } +"0x82DF6148" = { end = 0x82DF6150 } +"0x82DF6FE8" = { end = 0x82DF6FF8 } +"0x82DFEF1C" = { end = 0x82DFEF20 } +"0x82E0F4B8" = { end = 0x82E0F4DC } +"0x82E13D20" = { end = 0x82E13D24 } +"0x82E1A998" = { end = 0x82E1A9A0 } +"0x82E1A9A0" = { end = 0x82E1A9A8 } +"0x82E1A9F0" = { end = 0x82E1A9F8 } +"0x82E1AA00" = { end = 0x82E1AA08 } +"0x82E1AA18" = { end = 0x82E1AA20 } +"0x82E1AA38" = { end = 0x82E1AA40 } +"0x82E1AA70" = { end = 0x82E1AA78 } +"0x82E1AAD8" = { end = 0x82E1AAE0 } +"0x82E1C9F8" = { end = 0x82E1CA08 } +"0x82E2A9D0" = { end = 0x82E2A9D4 } +"0x82E2EFD0" = { end = 0x82E2EFEC } +"0x82E39E44" = { end = 0x82E39E48 } +"0x82E40B20" = { end = 0x82E40B24 } +"0x82E574BC" = { end = 0x82E574C0 } +"0x82E57610" = { end = 0x82E57628 } +"0x82E5C22C" = { end = 0x82E5C230 } +"0x82E69E60" = { end = 0x82E69E78 } +"0x82E69E78" = { end = 0x82E69E90 } +"0x82E69E90" = { end = 0x82E69EA8 } +"0x82E70B60" = { end = 0x82E70B64 } +"0x82E70B98" = { end = 0x82E70B9C } +"0x82E7D960" = { end = 0x82E7D98C } +"0x82E7F93C" = { end = 0x82E7F940 } +"0x82EBAE34" = { end = 0x82EBAE58 } +"0x82EBAE90" = { end = 0x82EBAEBC } +"0x82ECBD54" = { end = 0x82ECBD58 } +"0x82ECBD78" = { end = 0x82ECBD7C } +"0x82ECBDA0" = { end = 0x82ECBDA4 } +"0x82ECBDC8" = { end = 0x82ECBDCC } +"0x82ECD360" = { end = 0x82ECD368 } +"0x82ECD370" = { end = 0x82ECD378 } +"0x82ECD378" = { end = 0x82ECD380 } +"0x82ECD380" = { end = 0x82ECD388 } +"0x82ED1938" = { end = 0x82ED1940 } +"0x82ED1940" = { end = 0x82ED1948 } +"0x82ED1948" = { end = 0x82ED1950 } +"0x82ED1950" = { end = 0x82ED1958 } +"0x82ED1960" = { end = 0x82ED1968 } +"0x82ED1968" = { end = 0x82ED1970 } +"0x82ED1970" = { end = 0x82ED1978 } +"0x82ED1978" = { end = 0x82ED1980 } +"0x82ED1BD0" = { end = 0x82ED1BD8 } +"0x82ED1BD8" = { end = 0x82ED1BE0 } +"0x82ED1BE8" = { end = 0x82ED1BF0 } +"0x82ED1BF0" = { end = 0x82ED1BF8 } +"0x82ED1BF8" = { end = 0x82ED1C00 } +"0x82ED1D18" = { end = 0x82ED1D1C } +"0x82ED1D40" = { end = 0x82ED1D44 } +"0x82ED1D68" = { end = 0x82ED1D6C } +"0x82ED2238" = { end = 0x82ED2250 } +"0x82ED3110" = { end = 0x82ED3118 } +"0x82ED3E80" = { end = 0x82ED3E88 } +"0x82ED3E88" = { end = 0x82ED3E90 } +"0x82EE0648" = { end = 0x82EE0668 } +"0x82EE5938" = { end = 0x82EE5940 } +"0x82F00C28" = { end = 0x82F00C2C } +"0x82F00C88" = { end = 0x82F00C8C } +"0x82F00F78" = { end = 0x82F00F7C } +"0x82F01034" = { end = 0x82F01038 } +"0x82F0B6E8" = { end = 0x82F0B6EC } +"0x82F0B718" = { end = 0x82F0B71C } +"0x82F22B20" = { end = 0x82F22B24 } +"0x82F23978" = { end = 0x82F23998 } +"0x82F23B48" = { end = 0x82F23B68 } +"0x82F24A50" = { end = 0x82F24A70 } +"0x82F25944" = { end = 0x82F25964 } +"0x82F25D18" = { end = 0x82F25D38 } +"0x82F26060" = { end = 0x82F26080 } +"0x82F26230" = { end = 0x82F26250 } +"0x82F2732C" = { end = 0x82F27354 } +"0x82F29280" = { end = 0x82F292A0 } +"0x82F29AE4" = { end = 0x82F29B04 } +"0x82F29E84" = { end = 0x82F29EA4 } +"0x82F2ADFC" = { end = 0x82F2AE1C } +"0x82F2B510" = { end = 0x82F2B530 } +"0x82F2B76C" = { end = 0x82F2B78C } +"0x82F2B9D4" = { end = 0x82F2B9F4 } +"0x82F2D5FC" = { end = 0x82F2D61C } +"0x82F31C14" = { end = 0x82F31C34 } +"0x82F31E68" = { end = 0x82F31E84 } +"0x82F322D8" = { end = 0x82F322F8 } +"0x82F340DC" = { end = 0x82F34104 } +"0x82F34D28" = { end = 0x82F34D98 } +"0x82F34FFC" = { end = 0x82F3501C } +"0x82F36948" = { end = 0x82F36960 } +"0x82F6DBCC" = { end = 0x82F6DBD0 } +"0x82F6DEFC" = { end = 0x82F6DF00 } +"0x82F6EF38" = { end = 0x82F6EF3C } +"0x82F6F1A0" = { end = 0x82F6F1A4 } +"0x82F6F6B8" = { end = 0x82F6F6BC } +"0x82F70348" = { end = 0x82F7034C } +"0x82F70388" = { end = 0x82F7038C } +"0x82F703C8" = { end = 0x82F703CC } +"0x82F70408" = { end = 0x82F7040C } +"0x82F70448" = { end = 0x82F7044C } +"0x82F70488" = { end = 0x82F7048C } +"0x82F709A0" = { end = 0x82F709A4 } +"0x82F709F8" = { end = 0x82F709FC } + +"0x823C282C" = { end = 0x823C2878, parent = 0x823C2528 } +"0x823C2A38" = { end = 0x823C2A84, parent = 0x823C2528 } +"0x823C2A94" = { end = 0x823C2AE4, parent = 0x823C2528 } +"0x823C2B54" = { end = 0x823C2BA4, parent = 0x823C2528 } +"0x823C2C74" = { end = 0x823C2CC8, parent = 0x823C2528 } +"0x823C2D2C" = { end = 0x823C2D80, parent = 0x823C2528 } +"0x823C2F48" = { end = 0x823C2F4C, parent = 0x823C2528 } +"0x823C2F58" = { end = 0x823C2FA8, parent = 0x823C2528 } +"0x823C2FB8" = { end = 0x823C3008, parent = 0x823C2528 } +"0x823C3018" = { end = 0x823C3068, parent = 0x823C2528 } +"0x823C3438" = { end = 0x823C3488, parent = 0x823C2528 } +"0x823C3498" = { end = 0x823C34E4, parent = 0x823C2528 } +"0x823C34F4" = { end = 0x823C3540, parent = 0x823C2528 } +"0x823C3674" = { end = 0x823C36C0, parent = 0x823C2528 } +"0x823C3918" = { end = 0x823C3968, parent = 0x823C2528 } +"0x823C3978" = { end = 0x823C39C0, parent = 0x823C2528 } +"0x823C3A40" = { end = 0x823C3A88, parent = 0x823C2528 } +"0x823C3B08" = { end = 0x823C3B50, parent = 0x823C2528 } +"0x823C3BD0" = { end = 0x823C3C18, parent = 0x823C2528 } +"0x823C3C98" = { end = 0x823C3CE0, parent = 0x823C2528 } +"0x823C3D60" = { end = 0x823C3DAC, parent = 0x823C2528 } +"0x823C3E2C" = { end = 0x823C3E78, parent = 0x823C2528 } +"0x823C424C" = { end = 0x823C4298, parent = 0x823C2528 } +"0x823C43A0" = { end = 0x823C43EC, parent = 0x823C2528 } +"0x823C445C" = { end = 0x823C4460, parent = 0x823C2528 } +"0x823C4568" = { end = 0x823C45B4, parent = 0x823C2528 } +"0x823C4994" = { end = 0x823C49DC, parent = 0x823C2528 } +"0x823C4A5C" = { end = 0x823C4AA8, parent = 0x823C2528 } +"0x823C4B28" = { end = 0x823C4B74, parent = 0x823C2528 } +"0x823C4BF4" = { end = 0x823C4C3C, parent = 0x823C2528 } +"0x823C4CBC" = { end = 0x823C4D08, parent = 0x823C2528 } +"0x823C4D88" = { end = 0x823C4DD4, parent = 0x823C2528 } +"0x823C4E54" = { end = 0x823C4EA0, parent = 0x823C2528 } +"0x823C4F20" = { end = 0x823C4F6C, parent = 0x823C2528 } +"0x823C4FEC" = { end = 0x823C5038, parent = 0x823C2528 } +"0x823C53E8" = { end = 0x823C5434, parent = 0x823C2528 } +"0x823C5508" = { end = 0x823C5554, parent = 0x823C2528 } +"0x823C55D4" = { end = 0x823C5620, parent = 0x823C2528 } +"0x823C56A0" = { end = 0x823C56EC, parent = 0x823C2528 } +"0x823C5B7C" = { end = 0x823C5BC8, parent = 0x823C2528 } +"0x823C5C48" = { end = 0x823C5C94, parent = 0x823C2528 } +"0x823C69B4" = { end = 0x823C6A00, parent = 0x823C2528 } +"0x823C6AD8" = { end = 0x823C6B24, parent = 0x823C2528 } +"0x823C6BF8" = { end = 0x823C6C44, parent = 0x823C2528 } +"0x823C6E34" = { end = 0x823C6E80, parent = 0x823C2528 } +"0x823C6EE0" = { end = 0x823C6F30, parent = 0x823C2528 } +"0x823C6FA8" = { end = 0x823C6FF4, parent = 0x823C2528 } +"0x823C79F4" = { end = 0x823C7A40, parent = 0x823C2528 } +"0x823C8278" = { end = 0x823C82C0, parent = 0x823C2528 } +"0x823C8534" = { end = 0x823C8580, parent = 0x823C2528 } +"0x823C8810" = { end = 0x823C8858, parent = 0x823C2528 } +"0x823C8D70" = { end = 0x823C8DBC, parent = 0x823C2528 } +"0x823C9668" = { end = 0x823C96B4, parent = 0x823C9478 } +"0x823C9814" = { end = 0x823C9860, parent = 0x823C9478 } +"0x823C9930" = { end = 0x823C9980, parent = 0x823C9478 } +"0x823C9A50" = { end = 0x823C9AA0, parent = 0x823C9478 } +"0x823C9AB0" = { end = 0x823C9B00, parent = 0x823C9478 } +"0x823CA0C0" = { end = 0x823CA0C4, parent = 0x823C9478 } +"0x823CAA08" = { end = 0x823CAA18, parent = 0x823C9478 } +"0x823CAA18" = { end = 0x823CAA64, parent = 0x823C9478 } +"0x823CABAC" = { end = 0x823CABFC, parent = 0x823C9478 } +"0x823CB26C" = { end = 0x823CB2B8, parent = 0x823C9478 } +"0x823CB38C" = { end = 0x823CB3D8, parent = 0x823C9478 } +"0x823CC40C" = { end = 0x823CC458, parent = 0x823C9478 } +"0x823CCF74" = { end = 0x823CCFC0, parent = 0x823C9478 } +"0x823CD900" = { end = 0x823CD948, parent = 0x823C9478 } +"0x823D7E84" = { end = 0x823D7ED0, parent = 0x823D7368 } +"0x823D7F3C" = { end = 0x823D7F88, parent = 0x823D7368 } +"0x823D7FF4" = { end = 0x823D8040, parent = 0x823D7368 } +"0x823D821C" = { end = 0x823D8220, parent = 0x823D7368 } +"0x823D8454" = { end = 0x823D84A4, parent = 0x823D7368 } +"0x823D84B4" = { end = 0x823D8504, parent = 0x823D7368 } +"0x823D8514" = { end = 0x823D8564, parent = 0x823D7368 } +"0x823D8574" = { end = 0x823D85C4, parent = 0x823D7368 } +"0x823DB164" = { end = 0x823DB1B4, parent = 0x823D7368 } +"0x823DB610" = { end = 0x823DB660, parent = 0x823D7368 } +"0x823DB670" = { end = 0x823DB6C0, parent = 0x823D7368 } +"0x823DB6D0" = { end = 0x823DB720, parent = 0x823D7368 } +"0x823DB730" = { end = 0x823DB780, parent = 0x823D7368 } +"0x823DB790" = { end = 0x823DB7E0, parent = 0x823D7368 } +"0x823DB7F0" = { end = 0x823DB840, parent = 0x823D7368 } +"0x823DB850" = { end = 0x823DB8A0, parent = 0x823D7368 } +"0x823DB8B0" = { end = 0x823DB900, parent = 0x823D7368 } +"0x823DB910" = { end = 0x823DB960, parent = 0x823D7368 } +"0x823DB970" = { end = 0x823DB9C0, parent = 0x823D7368 } +"0x823DB9D0" = { end = 0x823DBA20, parent = 0x823D7368 } +"0x823DBA30" = { end = 0x823DBA80, parent = 0x823D7368 } +"0x823DBA90" = { end = 0x823DBAE0, parent = 0x823D7368 } +"0x823DBAF0" = { end = 0x823DBB40, parent = 0x823D7368 } +"0x823DBB50" = { end = 0x823DBBA0, parent = 0x823D7368 } +"0x823DBBB0" = { end = 0x823DBC00, parent = 0x823D7368 } +"0x823DBC10" = { end = 0x823DBC60, parent = 0x823D7368 } +"0x823DBC70" = { end = 0x823DBCC0, parent = 0x823D7368 } +"0x823DBCD0" = { end = 0x823DBD20, parent = 0x823D7368 } +"0x823DBD30" = { end = 0x823DBD80, parent = 0x823D7368 } +"0x823DBD90" = { end = 0x823DBDE0, parent = 0x823D7368 } +"0x823DBDF0" = { end = 0x823DBE3C, parent = 0x823D7368 } +"0x823DBE4C" = { end = 0x823DBE9C, parent = 0x823D7368 } +"0x823DBEAC" = { end = 0x823DBEFC, parent = 0x823D7368 } +"0x823DBF0C" = { end = 0x823DBF5C, parent = 0x823D7368 } +"0x823DBF6C" = { end = 0x823DBFBC, parent = 0x823D7368 } +"0x823DBFCC" = { end = 0x823DC01C, parent = 0x823D7368 } +"0x823DC02C" = { end = 0x823DC07C, parent = 0x823D7368 } +"0x823DC08C" = { end = 0x823DC0DC, parent = 0x823D7368 } +"0x823DC0EC" = { end = 0x823DC13C, parent = 0x823D7368 } +"0x823DC14C" = { end = 0x823DC19C, parent = 0x823D7368 } +"0x823DC1AC" = { end = 0x823DC1FC, parent = 0x823D7368 } +"0x823DC20C" = { end = 0x823DC25C, parent = 0x823D7368 } +"0x823DC26C" = { end = 0x823DC2BC, parent = 0x823D7368 } +"0x823DC2CC" = { end = 0x823DC31C, parent = 0x823D7368 } +"0x823DC32C" = { end = 0x823DC37C, parent = 0x823D7368 } +"0x823DC38C" = { end = 0x823DC3DC, parent = 0x823D7368 } +"0x823DC3EC" = { end = 0x823DC43C, parent = 0x823D7368 } +"0x823DC44C" = { end = 0x823DC49C, parent = 0x823D7368 } +"0x823DC4AC" = { end = 0x823DC4FC, parent = 0x823D7368 } +"0x823DC50C" = { end = 0x823DC55C, parent = 0x823D7368 } +"0x823DC56C" = { end = 0x823DC5BC, parent = 0x823D7368 } +"0x823DC5CC" = { end = 0x823DC61C, parent = 0x823D7368 } +"0x823DC62C" = { end = 0x823DC67C, parent = 0x823D7368 } +"0x823DC68C" = { end = 0x823DC6DC, parent = 0x823D7368 } +"0x823DC6EC" = { end = 0x823DC73C, parent = 0x823D7368 } +"0x823DC824" = { end = 0x823DC874, parent = 0x823D7368 } +"0x823DC884" = { end = 0x823DC8D4, parent = 0x823D7368 } +"0x823DC8E4" = { end = 0x823DC934, parent = 0x823D7368 } +"0x823DC944" = { end = 0x823DC994, parent = 0x823D7368 } +"0x823DC9A4" = { end = 0x823DC9F4, parent = 0x823D7368 } +"0x823DCA04" = { end = 0x823DCA54, parent = 0x823D7368 } +"0x823DCC70" = { end = 0x823DCCC0, parent = 0x823D7368 } +"0x823DCCD0" = { end = 0x823DCD20, parent = 0x823D7368 } +"0x823DCD30" = { end = 0x823DCD80, parent = 0x823D7368 } +"0x823DCE50" = { end = 0x823DCEA0, parent = 0x823D7368 } +"0x823DCEB0" = { end = 0x823DCF00, parent = 0x823D7368 } +"0x823DCF10" = { end = 0x823DCF60, parent = 0x823D7368 } +"0x823DCFD0" = { end = 0x823DD020, parent = 0x823D7368 } +"0x823DD090" = { end = 0x823DD0E0, parent = 0x823D7368 } +"0x823DD0F0" = { end = 0x823DD140, parent = 0x823D7368 } +"0x823DD150" = { end = 0x823DD1A0, parent = 0x823D7368 } +"0x823DD210" = { end = 0x823DD260, parent = 0x823D7368 } +"0x823DD270" = { end = 0x823DD2C0, parent = 0x823D7368 } +"0x823DD2D0" = { end = 0x823DD320, parent = 0x823D7368 } +"0x823DD330" = { end = 0x823DD380, parent = 0x823D7368 } +"0x823DD390" = { end = 0x823DD3E0, parent = 0x823D7368 } +"0x823DD3F0" = { end = 0x823DD440, parent = 0x823D7368 } +"0x823DD450" = { end = 0x823DD49C, parent = 0x823D7368 } +"0x823DD4AC" = { end = 0x823DD4FC, parent = 0x823D7368 } +"0x823DD50C" = { end = 0x823DD55C, parent = 0x823D7368 } +"0x823DD56C" = { end = 0x823DD5BC, parent = 0x823D7368 } +"0x823DD5CC" = { end = 0x823DD61C, parent = 0x823D7368 } +"0x823DD62C" = { end = 0x823DD67C, parent = 0x823D7368 } +"0x823DD68C" = { end = 0x823DD6DC, parent = 0x823D7368 } +"0x823DD6EC" = { end = 0x823DD73C, parent = 0x823D7368 } +"0x823DD74C" = { end = 0x823DD79C, parent = 0x823D7368 } +"0x823DD7AC" = { end = 0x823DD7FC, parent = 0x823D7368 } +"0x823DD80C" = { end = 0x823DD85C, parent = 0x823D7368 } +"0x823DD86C" = { end = 0x823DD8BC, parent = 0x823D7368 } +"0x823DD8CC" = { end = 0x823DD91C, parent = 0x823D7368 } +"0x823DD92C" = { end = 0x823DD97C, parent = 0x823D7368 } +"0x823DD98C" = { end = 0x823DD9DC, parent = 0x823D7368 } +"0x823DD9EC" = { end = 0x823DDA3C, parent = 0x823D7368 } +"0x823DDDAC" = { end = 0x823DDDFC, parent = 0x823D7368 } +"0x823DE0C4" = { end = 0x823DE114, parent = 0x823D7368 } +"0x823DE124" = { end = 0x823DE174, parent = 0x823D7368 } +"0x823DE184" = { end = 0x823DE1E0, parent = 0x823D7368 } +"0x823DE4B4" = { end = 0x823DE504, parent = 0x823D7368 } +"0x823DEA68" = { end = 0x823DEAB8, parent = 0x823D7368 } +"0x823DEC18" = { end = 0x823DEC68, parent = 0x823D7368 } +"0x823DED50" = { end = 0x823DEDA0, parent = 0x823D7368 } +"0x823DEE28" = { end = 0x823DEE78, parent = 0x823D7368 } +"0x823DEE88" = { end = 0x823DEED8, parent = 0x823D7368 } +"0x823DEEE8" = { end = 0x823DEF38, parent = 0x823D7368 } +"0x823DF1D0" = { end = 0x823DF220, parent = 0x823D7368 } +"0x823DF574" = { end = 0x823DF5C4, parent = 0x823D7368 } +"0x823DF8D4" = { end = 0x823DF924, parent = 0x823D7368 } +"0x823DF934" = { end = 0x823DF990, parent = 0x823D7368 } +"0x823DF9AC" = { end = 0x823DF9FC, parent = 0x823D7368 } +"0x823DFA0C" = { end = 0x823DFA5C, parent = 0x823D7368 } +"0x823DFA6C" = { end = 0x823DFABC, parent = 0x823D7368 } +"0x823DFACC" = { end = 0x823DFB28, parent = 0x823D7368 } +"0x823DFC04" = { end = 0x823DFC54, parent = 0x823D7368 } +"0x823DFC64" = { end = 0x823DFCB4, parent = 0x823D7368 } +"0x823DFD3C" = { end = 0x823DFD8C, parent = 0x823D7368 } +"0x823DFF78" = { end = 0x823DFFC8, parent = 0x823D7368 } +"0x823DFFD8" = { end = 0x823E0034, parent = 0x823D7368 } +"0x823E03BC" = { end = 0x823E0418, parent = 0x823D7368 } +"0x823E0434" = { end = 0x823E0490, parent = 0x823D7368 } +"0x823E04AC" = { end = 0x823E04FC, parent = 0x823D7368 } +"0x823E050C" = { end = 0x823E055C, parent = 0x823D7368 } +"0x823E05CC" = { end = 0x823E061C, parent = 0x823D7368 } +"0x823E074C" = { end = 0x823E079C, parent = 0x823D7368 } +"0x823E080C" = { end = 0x823E085C, parent = 0x823D7368 } +"0x823E086C" = { end = 0x823E08BC, parent = 0x823D7368 } +"0x823E0C5C" = { end = 0x823E0CAC, parent = 0x823D7368 } +"0x823E0EC0" = { end = 0x823E0F10, parent = 0x823D7368 } +"0x823E10C4" = { end = 0x823E1120, parent = 0x823D7368 } +"0x823E1214" = { end = 0x823E1264, parent = 0x823D7368 } +"0x823E141C" = { end = 0x823E1478, parent = 0x823D7368 } +"0x823E1494" = { end = 0x823E14E4, parent = 0x823D7368 } +"0x823E14F4" = { end = 0x823E1544, parent = 0x823D7368 } +"0x823E1554" = { end = 0x823E15A4, parent = 0x823D7368 } +"0x823E15B4" = { end = 0x823E1604, parent = 0x823D7368 } +"0x823E1614" = { end = 0x823E1664, parent = 0x823D7368 } +"0x823E1854" = { end = 0x823E18A4, parent = 0x823D7368 } +"0x823E1BFC" = { end = 0x823E1C4C, parent = 0x823D7368 } +"0x823E1CB4" = { end = 0x823E1CFC, parent = 0x823D7368 } +"0x823E1D7C" = { end = 0x823E1DC4, parent = 0x823D7368 } +"0x823E1EFC" = { end = 0x823E1F00, parent = 0x823D7368 } +"0x823E209C" = { end = 0x823E20E8, parent = 0x823D7368 } +"0x823E411C" = { end = 0x823E4168, parent = 0x823D7368 } +"0x823E41E4" = { end = 0x823E4230, parent = 0x823D7368 } +"0x823E44A0" = { end = 0x823E44EC, parent = 0x823D7368 } +"0x823E475C" = { end = 0x823E47A8, parent = 0x823D7368 } +"0x823E4828" = { end = 0x823E4874, parent = 0x823D7368 } +"0x823E48F4" = { end = 0x823E4940, parent = 0x823D7368 } +"0x823E4DBC" = { end = 0x823E4E08, parent = 0x823D7368 } +"0x823E59B0" = { end = 0x823E59FC, parent = 0x823D7368 } +"0x823E69A0" = { end = 0x823E69EC, parent = 0x823D7368 } +"0x823E74C0" = { end = 0x823E750C, parent = 0x823D7368 } +"0x823E7A54" = { end = 0x823E7AA0, parent = 0x823D7368 } +"0x823E7B20" = { end = 0x823E7B6C, parent = 0x823D7368 } +"0x823E7BEC" = { end = 0x823E7C38, parent = 0x823D7368 } +"0x823E7CB8" = { end = 0x823E7D04, parent = 0x823D7368 } +"0x823E7E50" = { end = 0x823E7E9C, parent = 0x823D7368 } +"0x823E7F1C" = { end = 0x823E7F68, parent = 0x823D7368 } +"0x823E7FE8" = { end = 0x823E8034, parent = 0x823D7368 } +"0x823E87DC" = { end = 0x823E8828, parent = 0x823D7368 } +"0x823E88A8" = { end = 0x823E88F4, parent = 0x823D7368 } +"0x823E8974" = { end = 0x823E89C0, parent = 0x823D7368 } +"0x823E8BD4" = { end = 0x823E8C20, parent = 0x823D7368 } +"0x823E8CA0" = { end = 0x823E8CEC, parent = 0x823D7368 } +"0x823E8F04" = { end = 0x823E8F50, parent = 0x823D7368 } +"0x823E9168" = { end = 0x823E91B4, parent = 0x823D7368 } +"0x823E9344" = { end = 0x823E9390, parent = 0x823D7368 } +"0x823E9410" = { end = 0x823E945C, parent = 0x823D7368 } +"0x823E94DC" = { end = 0x823E9528, parent = 0x823D7368 } +"0x823E95A8" = { end = 0x823E95F4, parent = 0x823D7368 } +"0x823E9674" = { end = 0x823E96C0, parent = 0x823D7368 } +"0x823E973C" = { end = 0x823E9788, parent = 0x823D7368 } +"0x823EA144" = { end = 0x823EA190, parent = 0x823D7368 } +"0x823EA31C" = { end = 0x823EA368, parent = 0x823D7368 } +"0x823EAC04" = { end = 0x823EAC50, parent = 0x823D7368 } +"0x823EAE4C" = { end = 0x823EAE98, parent = 0x823D7368 } +"0x823EC2E0" = { end = 0x823EC32C, parent = 0x823D7368 } +"0x823EC580" = { end = 0x823EC5CC, parent = 0x823D7368 } +"0x823EC6A4" = { end = 0x823EC6F0, parent = 0x823D7368 } +"0x823ECB38" = { end = 0x823ECB84, parent = 0x823D7368 } +"0x823ECC5C" = { end = 0x823ECCA8, parent = 0x823D7368 } +"0x823ECEA4" = { end = 0x823ECEF0, parent = 0x823D7368 } +"0x823ECFC8" = { end = 0x823ED014, parent = 0x823D7368 } +"0x823ED0F0" = { end = 0x823ED13C, parent = 0x823D7368 } +"0x823ED218" = { end = 0x823ED264, parent = 0x823D7368 } +"0x823ED2C0" = { end = 0x823ED30C, parent = 0x823D7368 } +"0x823ED3E4" = { end = 0x823ED430, parent = 0x823D7368 } +"0x823ED508" = { end = 0x823ED554, parent = 0x823D7368 } +"0x823ED74C" = { end = 0x823ED794, parent = 0x823D7368 } +"0x823ED8BC" = { end = 0x823ED904, parent = 0x823D7368 } +"0x823EDBA4" = { end = 0x823EDBF0, parent = 0x823D7368 } +"0x823EDD1C" = { end = 0x823EDD64, parent = 0x823D7368 } +"0x823EDEF8" = { end = 0x823EDF44, parent = 0x823D7368 } +"0x823EE66C" = { end = 0x823EE6B8, parent = 0x823D7368 } +"0x823EE7E8" = { end = 0x823EE834, parent = 0x823D7368 } +"0x823EEAE4" = { end = 0x823EEB30, parent = 0x823D7368 } +"0x823EF22C" = { end = 0x823EF278, parent = 0x823D7368 } +"0x823EF32C" = { end = 0x823EF378, parent = 0x823D7368 } +"0x823EF850" = { end = 0x823EF89C, parent = 0x823D7368 } +"0x823EFA24" = { end = 0x823EFA70, parent = 0x823D7368 } +"0x823EFBF8" = { end = 0x823EFC44, parent = 0x823D7368 } +"0x823EFDCC" = { end = 0x823EFE18, parent = 0x823D7368 } +"0x823EFFA0" = { end = 0x823EFFEC, parent = 0x823D7368 } +"0x823F03A4" = { end = 0x823F03F0, parent = 0x823D7368 } +"0x823F0628" = { end = 0x823F0674, parent = 0x823D7368 } +"0x823F1C50" = { end = 0x823F1CA0, parent = 0x823F0A70 } +"0x823F22B0" = { end = 0x823F2300, parent = 0x823F0A70 } +"0x823F30D8" = { end = 0x823F3128, parent = 0x823F0A70 } +"0x823F31F8" = { end = 0x823F3248, parent = 0x823F0A70 } +"0x823F3724" = { end = 0x823F3780, parent = 0x823F0A70 } +"0x823F3C5C" = { end = 0x823F3CAC, parent = 0x823F0A70 } +"0x823F3CBC" = { end = 0x823F3D0C, parent = 0x823F0A70 } +"0x823F5CE4" = { end = 0x823F5D30, parent = 0x823F0A70 } +"0x823F6120" = { end = 0x823F616C, parent = 0x823F0A70 } +"0x823F61EC" = { end = 0x823F623C, parent = 0x823F0A70 } +"0x823F6DD8" = { end = 0x823F6E24, parent = 0x823F0A70 } +"0x823F7A14" = { end = 0x823F7A5C, parent = 0x823F7820 } +"0x823F7C94" = { end = 0x823F7CE0, parent = 0x823F7820 } +"0x823F7E74" = { end = 0x823F7EC0, parent = 0x823F7820 } +"0x823F8040" = { end = 0x823F8044, parent = 0x823F7820 } +"0x823F83E8" = { end = 0x823F8434, parent = 0x823F7820 } +"0x823F8444" = { end = 0x823F848C, parent = 0x823F7820 } +"0x823F849C" = { end = 0x823F84EC, parent = 0x823F7820 } +"0x823F8634" = { end = 0x823F8680, parent = 0x823F7820 } +"0x823F8690" = { end = 0x823F86DC, parent = 0x823F7820 } +"0x823F86EC" = { end = 0x823F873C, parent = 0x823F7820 } +"0x823F874C" = { end = 0x823F879C, parent = 0x823F7820 } +"0x823F87AC" = { end = 0x823F87FC, parent = 0x823F7820 } +"0x823F880C" = { end = 0x823F8864, parent = 0x823F7820 } +"0x823F8880" = { end = 0x823F88D0, parent = 0x823F7820 } +"0x823F8958" = { end = 0x823F89A8, parent = 0x823F7820 } +"0x823F8A30" = { end = 0x823F8A80, parent = 0x823F7820 } +"0x823F8B08" = { end = 0x823F8B58, parent = 0x823F7820 } +"0x823F8BE0" = { end = 0x823F8C30, parent = 0x823F7820 } +"0x823F8CB8" = { end = 0x823F8D08, parent = 0x823F7820 } +"0x823F8D90" = { end = 0x823F8DE0, parent = 0x823F7820 } +"0x823F8EC8" = { end = 0x823F8F18, parent = 0x823F7820 } +"0x823F8FA0" = { end = 0x823F8FF0, parent = 0x823F7820 } +"0x823F9000" = { end = 0x823F904C, parent = 0x823F7820 } +"0x823F90BC" = { end = 0x823F910C, parent = 0x823F7820 } +"0x823F911C" = { end = 0x823F916C, parent = 0x823F7820 } +"0x823F917C" = { end = 0x823F91CC, parent = 0x823F7820 } +"0x823F91DC" = { end = 0x823F922C, parent = 0x823F7820 } +"0x823F923C" = { end = 0x823F928C, parent = 0x823F7820 } +"0x823F929C" = { end = 0x823F92EC, parent = 0x823F7820 } +"0x823F92FC" = { end = 0x823F934C, parent = 0x823F7820 } +"0x823F935C" = { end = 0x823F93AC, parent = 0x823F7820 } +"0x823F93BC" = { end = 0x823F940C, parent = 0x823F7820 } +"0x823F971C" = { end = 0x823F976C, parent = 0x823F7820 } +"0x823F989C" = { end = 0x823F98EC, parent = 0x823F7820 } +"0x823F98FC" = { end = 0x823F994C, parent = 0x823F7820 } +"0x823F995C" = { end = 0x823F99AC, parent = 0x823F7820 } +"0x823F99BC" = { end = 0x823F9A0C, parent = 0x823F7820 } +"0x823F9A1C" = { end = 0x823F9A6C, parent = 0x823F7820 } +"0x823F9C28" = { end = 0x823F9C78, parent = 0x823F7820 } +"0x823F9EE0" = { end = 0x823F9F28, parent = 0x823F7820 } +"0x823F9FA8" = { end = 0x823F9FF0, parent = 0x823F7820 } +"0x823FA530" = { end = 0x823FA57C, parent = 0x823F7820 } +"0x823FA5FC" = { end = 0x823FA644, parent = 0x823F7820 } +"0x823FAB74" = { end = 0x823FABC0, parent = 0x823F7820 } +"0x823FAC98" = { end = 0x823FACE4, parent = 0x823F7820 } +"0x823FAE14" = { end = 0x823FAE60, parent = 0x823F7820 } +"0x823FB450" = { end = 0x823FB4AC, parent = 0x823FB170 } +"0x823FBB58" = { end = 0x823FBBB4, parent = 0x823FB170 } +"0x823FBBD0" = { end = 0x823FBC2C, parent = 0x823FB170 } +"0x823FDAA4" = { end = 0x823FDAC0, parent = 0x823FD918 } +"0x823FDAC0" = { end = 0x823FDAEC, parent = 0x823FD918 } +"0x823FDAEC" = { end = 0x823FDB0C, parent = 0x823FD918 } +"0x823FDB0C" = { end = 0x823FDB44, parent = 0x823FD918 } +"0x823FDB50" = { end = 0x823FDB84, parent = 0x823FD918 } +"0x823FDB84" = { end = 0x823FDBB8, parent = 0x823FD918 } +"0x823FDBB8" = { end = 0x823FDBD4, parent = 0x823FD918 } +"0x823FDCE4" = { end = 0x823FDD0C, parent = 0x823FD918 } +"0x823FDD0C" = { end = 0x823FDD44, parent = 0x823FD918 } +"0x823FDD44" = { end = 0x823FDD8C, parent = 0x823FD918 } +"0x823FDD8C" = { end = 0x823FDDD4, parent = 0x823FD918 } +"0x823FDDF4" = { end = 0x823FDE3C, parent = 0x823FD918 } +"0x823FDEDC" = { end = 0x823FDF24, parent = 0x823FD918 } +"0x823FDF24" = { end = 0x823FDF6C, parent = 0x823FD918 } +"0x823FDF6C" = { end = 0x823FDFB4, parent = 0x823FD918 } +"0x823FE010" = { end = 0x823FE058, parent = 0x823FD918 } +"0x823FE058" = { end = 0x823FE0A0, parent = 0x823FD918 } +"0x823FE0F0" = { end = 0x823FE138, parent = 0x823FD918 } +"0x823FE138" = { end = 0x823FE180, parent = 0x823FD918 } +"0x823FE180" = { end = 0x823FE1C8, parent = 0x823FD918 } +"0x823FE1C8" = { end = 0x823FE210, parent = 0x823FD918 } +"0x823FE698" = { end = 0x823FE6E0, parent = 0x823FD918 } +"0x823FE71C" = { end = 0x823FE748, parent = 0x823FD918 } +"0x823FE784" = { end = 0x823FE7A0, parent = 0x823FD918 } +"0x823FE7A0" = { end = 0x823FE7F4, parent = 0x823FD918 } +"0x823FE804" = { end = 0x823FE84C, parent = 0x823FD918 } +"0x823FE84C" = { end = 0x823FE894, parent = 0x823FD918 } +"0x823FE894" = { end = 0x823FE8DC, parent = 0x823FD918 } +"0x823FEE7C" = { end = 0x823FEEBC, parent = 0x823FD918 } +"0x823FF688" = { end = 0x823FF6D0, parent = 0x823FF2F8 } +"0x82400644" = { end = 0x82400664, parent = 0x824005E8 } +"0x82400664" = { end = 0x8240069C, parent = 0x824005E8 } +"0x824006B8" = { end = 0x8240070C, parent = 0x824005E8 } +"0x8240070C" = { end = 0x82400754, parent = 0x824005E8 } +"0x82400754" = { end = 0x82400778, parent = 0x824005E8 } +"0x824007CC" = { end = 0x82400810, parent = 0x824005E8 } +"0x82400824" = { end = 0x82400848, parent = 0x824005E8 } +"0x82400848" = { end = 0x8240086C, parent = 0x824005E8 } +"0x824008DC" = { end = 0x82400914, parent = 0x82400880 } +"0x82400930" = { end = 0x82400978, parent = 0x82400880 } +"0x82400A14" = { end = 0x82400A38, parent = 0x82400880 } +"0x82400A38" = { end = 0x82400A5C, parent = 0x82400880 } +"0x82457900" = { end = 0x82457910, parent = 0x82457650 } +"0x82457910" = { end = 0x82457934, parent = 0x82457650 } +"0x8245859C" = { end = 0x824585B4, parent = 0x82458278 } +"0x824585DC" = { end = 0x82458600, parent = 0x82458278 } +"0x824647D0" = { end = 0x824647D4, parent = 0x82464740 } +"0x824647F0" = { end = 0x82464804, parent = 0x82464740 } +"0x824648D4" = { end = 0x824648F0, parent = 0x82464740 } +"0x8246490C" = { end = 0x8246491C, parent = 0x82464740 } +"0x82464A58" = { end = 0x82464AAC, parent = 0x82464740 } +"0x82464C44" = { end = 0x82464C74, parent = 0x82464740 } +"0x82464CD0" = { end = 0x82464CFC, parent = 0x82464740 } +"0x82464DF8" = { end = 0x82464DFC, parent = 0x82464740 } +"0x82464E30" = { end = 0x82464E54, parent = 0x82464740 } +"0x82464E70" = { end = 0x82464E74, parent = 0x82464740 } +"0x82485938" = { end = 0x8248594C, parent = 0x82485898 } +"0x824859C4" = { end = 0x824859D8, parent = 0x82485898 } +"0x82486F58" = { end = 0x82486F6C, parent = 0x82486EE0 } +"0x82487080" = { end = 0x824870BC, parent = 0x82486F88 } +"0x82499814" = { end = 0x8249981C, parent = 0x82499560 } +"0x8249981C" = { end = 0x82499830, parent = 0x82499560 } +"0x82499884" = { end = 0x824998A4, parent = 0x82499560 } +"0x82499DDC" = { end = 0x82499E0C, parent = 0x82499C28 } +"0x824CCF08" = { end = 0x824CCF10, parent = 0x824CCE68 } +"0x824CCF28" = { end = 0x824CCF30, parent = 0x824CCE68 } +"0x8257DE7C" = { end = 0x8257DEC0, parent = 0x8257DCC0 } +"0x8257DEC0" = { end = 0x8257DF04, parent = 0x8257DCC0 } +"0x8257DF44" = { end = 0x8257DF60, parent = 0x8257DCC0 } +"0x8257F9D8" = { end = 0x8257FA5C, parent = 0x8257F968 } +"0x82580044" = { end = 0x82580100, parent = 0x8257F968 } +"0x825865B0" = { end = 0x825865D0, parent = 0x825864C8 } +"0x82586800" = { end = 0x82586820, parent = 0x82586760 } +"0x82586CD8" = { end = 0x82586CF4, parent = 0x82586C10 } +"0x82586D9C" = { end = 0x82586DB8, parent = 0x82586C10 } +"0x825D3B34" = { end = 0x825D3B3C, parent = 0x825D3A08 } +"0x825D3B3C" = { end = 0x825D3B44, parent = 0x825D3A08 } +"0x825D3B54" = { end = 0x825D3B5C, parent = 0x825D3A08 } +"0x825D3B5C" = { end = 0x825D3B64, parent = 0x825D3A08 } +"0x8265684C" = { end = 0x82656854, parent = 0x82656788 } +"0x82656854" = { end = 0x8265685C, parent = 0x82656788 } +"0x8265685C" = { end = 0x82656864, parent = 0x82656788 } +"0x82656864" = { end = 0x8265686C, parent = 0x82656788 } +"0x8265686C" = { end = 0x82656874, parent = 0x82656788 } +"0x82656874" = { end = 0x8265687C, parent = 0x82656788 } +"0x8265687C" = { end = 0x82656884, parent = 0x82656788 } +"0x82656884" = { end = 0x8265688C, parent = 0x82656788 } +"0x8265688C" = { end = 0x82656894, parent = 0x82656788 } +"0x82656894" = { end = 0x8265689C, parent = 0x82656788 } +"0x8265689C" = { end = 0x826568A4, parent = 0x82656788 } +"0x826568AC" = { end = 0x826568B4, parent = 0x82656788 } +"0x826568B4" = { end = 0x826568BC, parent = 0x82656788 } +"0x826568BC" = { end = 0x826568C4, parent = 0x82656788 } +"0x826568C4" = { end = 0x826568CC, parent = 0x82656788 } +"0x826BC8F4" = { end = 0x826BC908, parent = 0x826BC838 } +"0x826BC9A4" = { end = 0x826BC9A8, parent = 0x826BC838 } +"0x826BC9E8" = { end = 0x826BC9EC, parent = 0x826BC838 } +"0x826BCA2C" = { end = 0x826BCA30, parent = 0x826BC838 } +"0x826BCA4C" = { end = 0x826BCA70, parent = 0x826BC838 } +"0x826BCA8C" = { end = 0x826BCAA0, parent = 0x826BC838 } +"0x826BCAE0" = { end = 0x826BCAE4, parent = 0x826BC838 } +"0x826BCB00" = { end = 0x826BCB14, parent = 0x826BC838 } +"0x826BCB54" = { end = 0x826BCB58, parent = 0x826BC838 } +"0x826BCB74" = { end = 0x826BCB88, parent = 0x826BC838 } +"0x826BCBC8" = { end = 0x826BCBCC, parent = 0x826BC838 } +"0x826BCBE8" = { end = 0x826BCC2C, parent = 0x826BC838 } +"0x826E7380" = { end = 0x826E738C, parent = 0x826E72B8 } +"0x826E7458" = { end = 0x826E7468, parent = 0x826E72B8 } +"0x826EAA9C" = { end = 0x826EAAA4, parent = 0x826EAA38 } +"0x826EAD00" = { end = 0x826EAD3C, parent = 0x826EAC58 } +"0x826EB854" = { end = 0x826EB868, parent = 0x826EB358 } +"0x8277B88C" = { end = 0x8277B960, parent = 0x8277B818 } +"0x8277B960" = { end = 0x8277B994, parent = 0x8277B818 } +"0x8277BA00" = { end = 0x8277BA24, parent = 0x8277B818 } +"0x8277BA24" = { end = 0x8277BA48, parent = 0x8277B818 } +"0x8277BA48" = { end = 0x8277BAC4, parent = 0x8277B818 } +"0x8277BB1C" = { end = 0x8277BB40, parent = 0x8277B818 } +"0x8277BB40" = { end = 0x8277BB64, parent = 0x8277B818 } +"0x8277BB64" = { end = 0x8277BB84, parent = 0x8277B818 } +"0x8277BB84" = { end = 0x8277BBA4, parent = 0x8277B818 } +"0x8277BC78" = { end = 0x8277BC88, parent = 0x8277B818 } +"0x8277BC88" = { end = 0x8277BC9C, parent = 0x8277B818 } +"0x8277BD0C" = { end = 0x8277BDE0, parent = 0x8277BCA8 } +"0x8277BDE0" = { end = 0x8277BE0C, parent = 0x8277BCA8 } +"0x8277BE0C" = { end = 0x8277BE24, parent = 0x8277BCA8 } +"0x8277BE80" = { end = 0x8277BEA4, parent = 0x8277BCA8 } +"0x8277C190" = { end = 0x8277C1A4, parent = 0x8277BCA8 } +"0x82835D18" = { end = 0x82835DE4, parent = 0x82835CC0 } +"0x82835DE4" = { end = 0x82835DF8, parent = 0x82835CC0 } +"0x82835DF8" = { end = 0x82835E44, parent = 0x82835CC0 } +"0x82835E5C" = { end = 0x82835E74, parent = 0x82835CC0 } +"0x82835ED8" = { end = 0x82835EEC, parent = 0x82835CC0 } +"0x82835EEC" = { end = 0x82835F04, parent = 0x82835CC0 } +"0x82835F74" = { end = 0x82835FAC, parent = 0x82835CC0 } +"0x82835FD0" = { end = 0x82835FE8, parent = 0x82835CC0 } +"0x82835FE8" = { end = 0x82836040, parent = 0x82835CC0 } +"0x828360B8" = { end = 0x828360C0, parent = 0x82835CC0 } +"0x828A9374" = { end = 0x828A9394, parent = 0x828A9180 } +"0x828A9394" = { end = 0x828A93B8, parent = 0x828A9180 } +"0x828A93B8" = { end = 0x828A93FC, parent = 0x828A9180 } +"0x828A969C" = { end = 0x828A9708, parent = 0x828A9180 } +"0x828A9754" = { end = 0x828A9770, parent = 0x828A9180 } +"0x828AAA78" = { end = 0x828AAAE0, parent = 0x828AA7D0 } +"0x828AAAE0" = { end = 0x828AAB4C, parent = 0x828AA7D0 } +"0x828AAC48" = { end = 0x828AAC4C, parent = 0x828AA7D0 } +"0x828AAC74" = { end = 0x828AAD40, parent = 0x828AA7D0 } +"0x828AADA8" = { end = 0x828AAEA0, parent = 0x828AA7D0 } +"0x828AB360" = { end = 0x828AB364, parent = 0x828AA7D0 } +"0x828AB38C" = { end = 0x828AB484, parent = 0x828AA7D0 } +"0x828AB4F4" = { end = 0x828AB538, parent = 0x828AA7D0 } +"0x828AB784" = { end = 0x828AB81C, parent = 0x828AA7D0 } +"0x828AB9D0" = { end = 0x828AB9FC, parent = 0x828AA7D0 } +"0x828AF3C8" = { end = 0x828AF41C, parent = 0x828AF328 } +"0x828AF41C" = { end = 0x828AF478, parent = 0x828AF328 } +"0x828AF50C" = { end = 0x828AF588, parent = 0x828AF328 } +"0x828AF840" = { end = 0x828AF87C, parent = 0x828AF328 } +"0x828AFC88" = { end = 0x828AFCD0, parent = 0x828AF328 } +"0x828BF1C8" = { end = 0x828BF1E0, parent = 0x828BF170 } +"0x828BF204" = { end = 0x828BF218, parent = 0x828BF170 } +"0x828F26A0" = { end = 0x828F26A4, parent = 0x828F2628 } +"0x828F2858" = { end = 0x828F2884, parent = 0x828F2628 } +"0x828F28C4" = { end = 0x828F28F0, parent = 0x828F2628 } +"0x828F2974" = { end = 0x828F2994, parent = 0x828F2628 } +"0x828F29DC" = { end = 0x828F2A04, parent = 0x828F2628 } +"0x828F35AC" = { end = 0x828F35E4, parent = 0x828F2628 } +"0x828F3804" = { end = 0x828F3820, parent = 0x828F2628 } +"0x828F8910" = { end = 0x828F8918, parent = 0x828F8798 } +"0x828F8B40" = { end = 0x828F8B48, parent = 0x828F8940 } +"0x828F9FBC" = { end = 0x828F9FCC, parent = 0x828F9F28 } +"0x828FA024" = { end = 0x828FA07C, parent = 0x828F9F28 } +"0x828FC3FC" = { end = 0x828FC414, parent = 0x828FC348 } +"0x828FC450" = { end = 0x828FC480, parent = 0x828FC348 } +"0x828FC480" = { end = 0x828FC498, parent = 0x828FC348 } +"0x828FC498" = { end = 0x828FC4A0, parent = 0x828FC348 } +"0x828FD61C" = { end = 0x828FD628, parent = 0x828FD3A0 } +"0x828FD658" = { end = 0x828FD668, parent = 0x828FD3A0 } +"0x829238B0" = { end = 0x829238D0, parent = 0x82923820 } +"0x829238F0" = { end = 0x82923910, parent = 0x82923820 } +"0x82923AAC" = { end = 0x82923AE0, parent = 0x82923820 } +"0x82923B54" = { end = 0x82923B74, parent = 0x82923820 } +"0x82923BB4" = { end = 0x82923BD4, parent = 0x82923820 } +"0x82923BD4" = { end = 0x82923BF4, parent = 0x82923820 } +"0x82923BF4" = { end = 0x82923C10, parent = 0x82923820 } +"0x82923D50" = { end = 0x82923D88, parent = 0x82923820 } +"0x82923F64" = { end = 0x82923F78, parent = 0x82923F18 } +"0x82923F78" = { end = 0x82923FC0, parent = 0x82923F18 } +"0x82923FD4" = { end = 0x82923FF4, parent = 0x82923F18 } +"0x82923FF4" = { end = 0x82924044, parent = 0x82923F18 } +"0x82924044" = { end = 0x82924064, parent = 0x82923F18 } +"0x82924064" = { end = 0x82924080, parent = 0x82923F18 } +"0x82924080" = { end = 0x8292409C, parent = 0x82923F18 } +"0x8292409C" = { end = 0x829240B8, parent = 0x82923F18 } +"0x829240B8" = { end = 0x829240D4, parent = 0x82923F18 } +"0x829240D4" = { end = 0x829240F0, parent = 0x82923F18 } +"0x82927F04" = { end = 0x82927F24, parent = 0x82927E90 } +"0x82927F94" = { end = 0x82927FAC, parent = 0x82927E90 } +"0x82927FAC" = { end = 0x82927FC4, parent = 0x82927E90 } +"0x82927FC4" = { end = 0x82927FDC, parent = 0x82927E90 } +"0x82927FDC" = { end = 0x82927FF4, parent = 0x82927E90 } +"0x82927FF4" = { end = 0x8292800C, parent = 0x82927E90 } +"0x8292800C" = { end = 0x82928020, parent = 0x82927E90 } +"0x82928020" = { end = 0x8292803C, parent = 0x82927E90 } +"0x8292803C" = { end = 0x82928058, parent = 0x82927E90 } +"0x82928058" = { end = 0x82928074, parent = 0x82927E90 } +"0x82928074" = { end = 0x82928090, parent = 0x82927E90 } +"0x82928090" = { end = 0x829280AC, parent = 0x82927E90 } +"0x829280AC" = { end = 0x829280C8, parent = 0x82927E90 } +"0x829280C8" = { end = 0x829280E4, parent = 0x82927E90 } +"0x829280E4" = { end = 0x82928100, parent = 0x82927E90 } +"0x82928100" = { end = 0x82928118, parent = 0x82927E90 } +"0x82928118" = { end = 0x8292812C, parent = 0x82927E90 } +"0x82928140" = { end = 0x829281CC, parent = 0x82927E90 } +"0x829281CC" = { end = 0x829281E4, parent = 0x82927E90 } +"0x829281E4" = { end = 0x829281FC, parent = 0x82927E90 } +"0x829281FC" = { end = 0x82928214, parent = 0x82927E90 } +"0x82928214" = { end = 0x8292822C, parent = 0x82927E90 } +"0x8292822C" = { end = 0x82928244, parent = 0x82927E90 } +"0x82928244" = { end = 0x82928258, parent = 0x82927E90 } +"0x82928258" = { end = 0x82928274, parent = 0x82927E90 } +"0x82928274" = { end = 0x82928290, parent = 0x82927E90 } +"0x82928290" = { end = 0x829282AC, parent = 0x82927E90 } +"0x829282AC" = { end = 0x829282C8, parent = 0x82927E90 } +"0x829282C8" = { end = 0x829282E4, parent = 0x82927E90 } +"0x829282E4" = { end = 0x82928300, parent = 0x82927E90 } +"0x82928300" = { end = 0x8292831C, parent = 0x82927E90 } +"0x8292831C" = { end = 0x82928338, parent = 0x82927E90 } +"0x82928338" = { end = 0x82928350, parent = 0x82927E90 } +"0x82928350" = { end = 0x82928380, parent = 0x82927E90 } +"0x8292857C" = { end = 0x829285BC, parent = 0x82928530 } +"0x829285BC" = { end = 0x82928638, parent = 0x82928530 } +"0x82928714" = { end = 0x82928728, parent = 0x82928530 } +"0x82928728" = { end = 0x82928740, parent = 0x82928530 } +"0x82928740" = { end = 0x82928758, parent = 0x82928530 } +"0x82928758" = { end = 0x82928770, parent = 0x82928530 } +"0x82928770" = { end = 0x82928788, parent = 0x82928530 } +"0x82928788" = { end = 0x829287A0, parent = 0x82928530 } +"0x829287A0" = { end = 0x829287B8, parent = 0x82928530 } +"0x829287B8" = { end = 0x829287D0, parent = 0x82928530 } +"0x829287D0" = { end = 0x829287E8, parent = 0x82928530 } +"0x829287E8" = { end = 0x82928800, parent = 0x82928530 } +"0x82928800" = { end = 0x82928818, parent = 0x82928530 } +"0x82928818" = { end = 0x82928830, parent = 0x82928530 } +"0x82928830" = { end = 0x82928848, parent = 0x82928530 } +"0x82928848" = { end = 0x82928860, parent = 0x82928530 } +"0x8292899C" = { end = 0x829289B4, parent = 0x82928530 } +"0x829289B4" = { end = 0x829289CC, parent = 0x82928530 } +"0x82928A40" = { end = 0x82928A68, parent = 0x82928530 } +"0x82928B4C" = { end = 0x82928BA8, parent = 0x82928AF8 } +"0x82928CC4" = { end = 0x82928CE8, parent = 0x82928AF8 } +"0x82928D0C" = { end = 0x82928D30, parent = 0x82928AF8 } +"0x82928F78" = { end = 0x82928F90, parent = 0x82928AF8 } +"0x82928FFC" = { end = 0x82929014, parent = 0x82928AF8 } +"0x82929014" = { end = 0x8292902C, parent = 0x82928AF8 } +"0x8292902C" = { end = 0x82929044, parent = 0x82928AF8 } +"0x82929044" = { end = 0x8292905C, parent = 0x82928AF8 } +"0x82929070" = { end = 0x8292908C, parent = 0x82928AF8 } +"0x82929150" = { end = 0x82929168, parent = 0x82928AF8 } +"0x82929168" = { end = 0x8292916C, parent = 0x82928AF8 } +"0x8292916C" = { end = 0x8292919C, parent = 0x82928AF8 } +"0x8292A024" = { end = 0x8292A088, parent = 0x82929F00 } +"0x8292A2CC" = { end = 0x8292A2E4, parent = 0x82929F00 } +"0x8292A2E4" = { end = 0x8292A2FC, parent = 0x82929F00 } +"0x8292A2FC" = { end = 0x8292A314, parent = 0x82929F00 } +"0x8292A314" = { end = 0x8292A32C, parent = 0x82929F00 } +"0x8292A32C" = { end = 0x8292A344, parent = 0x82929F00 } +"0x8292A344" = { end = 0x8292A358, parent = 0x82929F00 } +"0x8292A358" = { end = 0x8292A374, parent = 0x82929F00 } +"0x8292A374" = { end = 0x8292A390, parent = 0x82929F00 } +"0x8292A390" = { end = 0x8292A3AC, parent = 0x82929F00 } +"0x8292A3AC" = { end = 0x8292A3C8, parent = 0x82929F00 } +"0x8292A3C8" = { end = 0x8292A3E4, parent = 0x82929F00 } +"0x8292A3E4" = { end = 0x8292A400, parent = 0x82929F00 } +"0x8292A400" = { end = 0x8292A41C, parent = 0x82929F00 } +"0x8292A41C" = { end = 0x8292A438, parent = 0x82929F00 } +"0x8292A438" = { end = 0x8292A450, parent = 0x82929F00 } +"0x8292A450" = { end = 0x8292A4B4, parent = 0x82929F00 } +"0x8292A728" = { end = 0x8292A7B8, parent = 0x8292A6A8 } +"0x8292A938" = { end = 0x8292A954, parent = 0x8292A6A8 } +"0x8292A954" = { end = 0x8292A974, parent = 0x8292A6A8 } +"0x8292A974" = { end = 0x8292A994, parent = 0x8292A6A8 } +"0x8292A994" = { end = 0x8292A9B4, parent = 0x8292A6A8 } +"0x8292A9B4" = { end = 0x8292A9D4, parent = 0x8292A6A8 } +"0x8292A9D4" = { end = 0x8292A9F4, parent = 0x8292A6A8 } +"0x8292AAD4" = { end = 0x8292AAF4, parent = 0x8292A6A8 } +"0x8292ABBC" = { end = 0x8292ABD0, parent = 0x8292A6A8 } +"0x8292ABD0" = { end = 0x8292ABE8, parent = 0x8292A6A8 } +"0x8292ABE8" = { end = 0x8292AC00, parent = 0x8292A6A8 } +"0x8292AC00" = { end = 0x8292AC18, parent = 0x8292A6A8 } +"0x8292AC18" = { end = 0x8292AC30, parent = 0x8292A6A8 } +"0x8292AC30" = { end = 0x8292AC48, parent = 0x8292A6A8 } +"0x8292AC48" = { end = 0x8292AC60, parent = 0x8292A6A8 } +"0x8292AC60" = { end = 0x8292AC78, parent = 0x8292A6A8 } +"0x8292AC78" = { end = 0x8292AC90, parent = 0x8292A6A8 } +"0x8292AC90" = { end = 0x8292ACA8, parent = 0x8292A6A8 } +"0x8292AD34" = { end = 0x8292AD40, parent = 0x8292A6A8 } +"0x8292AD40" = { end = 0x8292AD8C, parent = 0x8292A6A8 } +"0x8292B1D4" = { end = 0x8292B1F0, parent = 0x8292B148 } +"0x8292B3EC" = { end = 0x8292B404, parent = 0x8292B148 } +"0x8292B48C" = { end = 0x8292B4A0, parent = 0x8292B148 } +"0x8292B4A0" = { end = 0x8292B4B8, parent = 0x8292B148 } +"0x8292B4B8" = { end = 0x8292B4D0, parent = 0x8292B148 } +"0x8292B4D0" = { end = 0x8292B4E8, parent = 0x8292B148 } +"0x8292B4E8" = { end = 0x8292B500, parent = 0x8292B148 } +"0x8292B500" = { end = 0x8292B518, parent = 0x8292B148 } +"0x8292B518" = { end = 0x8292B530, parent = 0x8292B148 } +"0x8292B530" = { end = 0x8292B548, parent = 0x8292B148 } +"0x8292B548" = { end = 0x8292B560, parent = 0x8292B148 } +"0x8292B560" = { end = 0x8292B578, parent = 0x8292B148 } +"0x8292B590" = { end = 0x8292B5A8, parent = 0x8292B148 } +"0x8292B5A8" = { end = 0x8292B5C0, parent = 0x8292B148 } +"0x8292B5C0" = { end = 0x8292B5D8, parent = 0x8292B148 } +"0x8292B5EC" = { end = 0x8292B678, parent = 0x8292B148 } +"0x829422B4" = { end = 0x8294231C, parent = 0x829421B0 } +"0x82942560" = { end = 0x829425A4, parent = 0x829421B0 } +"0x829425A4" = { end = 0x829425E0, parent = 0x829421B0 } +"0x82942614" = { end = 0x82942658, parent = 0x829421B0 } +"0x829426B0" = { end = 0x829426FC, parent = 0x829421B0 } +"0x8294270C" = { end = 0x82942728, parent = 0x829421B0 } +"0x82942840" = { end = 0x8294285C, parent = 0x829421B0 } +"0x8294307C" = { end = 0x82943118, parent = 0x82943048 } +"0x82943118" = { end = 0x82943128, parent = 0x82943048 } +"0x82943150" = { end = 0x82943188, parent = 0x82943048 } +"0x8294320C" = { end = 0x8294321C, parent = 0x82943048 } +"0x82943338" = { end = 0x8294339C, parent = 0x82943048 } +"0x82943504" = { end = 0x8294352C, parent = 0x82943048 } +"0x8294352C" = { end = 0x82943554, parent = 0x82943048 } +"0x8294357C" = { end = 0x829435A4, parent = 0x82943048 } +"0x82943644" = { end = 0x8294366C, parent = 0x82943048 } +"0x8294366C" = { end = 0x82943694, parent = 0x82943048 } +"0x82943694" = { end = 0x829436BC, parent = 0x82943048 } +"0x829436E4" = { end = 0x8294370C, parent = 0x82943048 } +"0x8294389C" = { end = 0x829438C4, parent = 0x82943048 } +"0x82944BB4" = { end = 0x82944C68, parent = 0x82944B08 } +"0x82944C88" = { end = 0x82944CA8, parent = 0x82944B08 } +"0x82944CC8" = { end = 0x82944CF0, parent = 0x82944B08 } +"0x82944D1C" = { end = 0x82944D44, parent = 0x82944B08 } +"0x82944F80" = { end = 0x82944FB0, parent = 0x82944B08 } +"0x82945668" = { end = 0x8294566C, parent = 0x82944B08 } +"0x8296DC94" = { end = 0x8296DCA0, parent = 0x8296DB98 } +"0x8296DCDC" = { end = 0x8296DCE8, parent = 0x8296DB98 } +"0x8296DCE8" = { end = 0x8296DCF4, parent = 0x8296DB98 } +"0x8296DCF4" = { end = 0x8296DD00, parent = 0x8296DB98 } +"0x8296DD00" = { end = 0x8296DD04, parent = 0x8296DB98 } +"0x829A6F3C" = { end = 0x829A6F6C, parent = 0x829A6E88 } +"0x829A6F6C" = { end = 0x829A6F9C, parent = 0x829A6E88 } +"0x829A6FCC" = { end = 0x829A6FFC, parent = 0x829A6E88 } +"0x829A705C" = { end = 0x829A708C, parent = 0x829A6E88 } +"0x829A708C" = { end = 0x829A70BC, parent = 0x829A6E88 } +"0x829A717C" = { end = 0x829A71AC, parent = 0x829A6E88 } +"0x829A71DC" = { end = 0x829A720C, parent = 0x829A6E88 } +"0x829A726C" = { end = 0x829A729C, parent = 0x829A6E88 } +"0x829A72CC" = { end = 0x829A72FC, parent = 0x829A6E88 } +"0x82A50C60" = { end = 0x82A50C6C, parent = 0x82A50BC0 } +"0x82A50C80" = { end = 0x82A50C90, parent = 0x82A50BC0 } +"0x82A50CB4" = { end = 0x82A50CB8, parent = 0x82A50BC0 } +"0x82AC1C20" = { end = 0x82AC1C24, parent = 0x82AC1B98 } +"0x82AC27F0" = { end = 0x82AC2830, parent = 0x82AC27A8 } +"0x82AC2C88" = { end = 0x82AC2CA0, parent = 0x82AC27A8 } +"0x82AC2E90" = { end = 0x82AC2EA0, parent = 0x82AC27A8 } +"0x82AC2FB4" = { end = 0x82AC3018, parent = 0x82AC2F40 } +"0x82AC32C0" = { end = 0x82AC3334, parent = 0x82AC2F40 } +"0x82AC33B0" = { end = 0x82AC33E0, parent = 0x82AC2F40 } +"0x82AC3464" = { end = 0x82AC347C, parent = 0x82AC2F40 } +"0x82AC347C" = { end = 0x82AC34B4, parent = 0x82AC2F40 } +"0x82AC366C" = { end = 0x82AC367C, parent = 0x82AC2F40 } +"0x82AEBCE8" = { end = 0x82AEBD0C, parent = 0x82AEBC80 } +"0x82B4B5B4" = { end = 0x82B4B5C0, parent = 0x82B4B300 } +"0x82B4B5C0" = { end = 0x82B4B5CC, parent = 0x82B4B300 } +"0x82B4B5CC" = { end = 0x82B4B5D8, parent = 0x82B4B300 } +"0x82B4B5D8" = { end = 0x82B4B5E4, parent = 0x82B4B300 } +"0x82B4B5E4" = { end = 0x82B4B5F0, parent = 0x82B4B300 } +"0x82B4B5F0" = { end = 0x82B4B5FC, parent = 0x82B4B300 } +"0x82B4B5FC" = { end = 0x82B4B608, parent = 0x82B4B300 } +"0x82B4B608" = { end = 0x82B4B614, parent = 0x82B4B300 } +"0x82B4B614" = { end = 0x82B4B620, parent = 0x82B4B300 } +"0x82B4B620" = { end = 0x82B4B62C, parent = 0x82B4B300 } +"0x82B4B62C" = { end = 0x82B4B638, parent = 0x82B4B300 } +"0x82B4B638" = { end = 0x82B4B644, parent = 0x82B4B300 } +"0x82B4B644" = { end = 0x82B4B650, parent = 0x82B4B300 } +"0x82B4B650" = { end = 0x82B4B65C, parent = 0x82B4B300 } +"0x82B4B65C" = { end = 0x82B4B664, parent = 0x82B4B300 } +"0x82B4B664" = { end = 0x82B4B670, parent = 0x82B4B300 } +"0x82B4B670" = { end = 0x82B4B67C, parent = 0x82B4B300 } +"0x82B4B67C" = { end = 0x82B4B688, parent = 0x82B4B300 } +"0x82B4B688" = { end = 0x82B4B694, parent = 0x82B4B300 } +"0x82B4B694" = { end = 0x82B4B6A0, parent = 0x82B4B300 } +"0x82B4B6A0" = { end = 0x82B4B6AC, parent = 0x82B4B300 } +"0x82B4B6AC" = { end = 0x82B4B6B8, parent = 0x82B4B300 } +"0x82B4B6B8" = { end = 0x82B4B6C0, parent = 0x82B4B300 } +"0x82B55320" = { end = 0x82B55330, parent = 0x82B55160 } +"0x82B6A580" = { end = 0x82B6A58C, parent = 0x82B6A3D8 } +"0x82B6A58C" = { end = 0x82B6A598, parent = 0x82B6A3D8 } +"0x82B6A598" = { end = 0x82B6A5A4, parent = 0x82B6A3D8 } +"0x82B6A5A4" = { end = 0x82B6A5B0, parent = 0x82B6A3D8 } +"0x82B6A5B0" = { end = 0x82B6A5BC, parent = 0x82B6A3D8 } +"0x82B6A5BC" = { end = 0x82B6A5C8, parent = 0x82B6A3D8 } +"0x82B6A5C8" = { end = 0x82B6A5D0, parent = 0x82B6A3D8 } +"0x82B6A5D0" = { end = 0x82B6A5DC, parent = 0x82B6A3D8 } +"0x82B6A5DC" = { end = 0x82B6A5E8, parent = 0x82B6A3D8 } +"0x82B6A5E8" = { end = 0x82B6A5F4, parent = 0x82B6A3D8 } +"0x82B6A5F4" = { end = 0x82B6A5FC, parent = 0x82B6A3D8 } +"0x82BD312C" = { end = 0x82BD3138, parent = 0x82BD30E8 } +"0x82C00A18" = { end = 0x82C00A70, parent = 0x82C00918 } +"0x82C00A9C" = { end = 0x82C00B2C, parent = 0x82C00918 } +"0x82C00BA0" = { end = 0x82C00BBC, parent = 0x82C00918 } +"0x82C00D90" = { end = 0x82C00DB4, parent = 0x82C00918 } +"0x82C00DD8" = { end = 0x82C00E28, parent = 0x82C00918 } +"0x82C00E48" = { end = 0x82C00E5C, parent = 0x82C00918 } +"0x82C00EDC" = { end = 0x82C00EF4, parent = 0x82C00918 } +"0x82C00F48" = { end = 0x82C00FA0, parent = 0x82C00918 } +"0x82C01064" = { end = 0x82C01098, parent = 0x82C00918 } +"0x82C010F0" = { end = 0x82C01124, parent = 0x82C00918 } +"0x82C01228" = { end = 0x82C01240, parent = 0x82C00918 } +"0x82C50784" = { end = 0x82C507B4, parent = 0x82C50320 } +"0x82C507E8" = { end = 0x82C50840, parent = 0x82C50320 } +"0x82C6ABC8" = { end = 0x82C6ABD4, parent = 0x82C6AB70 } +"0x82C6AC50" = { end = 0x82C6AC98, parent = 0x82C6AB70 } +"0x82C6ACFC" = { end = 0x82C6AD10, parent = 0x82C6AB70 } +"0x82C6AE14" = { end = 0x82C6AE18, parent = 0x82C6AB70 } +"0x82C6AE54" = { end = 0x82C6AE58, parent = 0x82C6AB70 } +"0x82C6AE94" = { end = 0x82C6AEAC, parent = 0x82C6AB70 } +"0x82C6AEDC" = { end = 0x82C6AEE4, parent = 0x82C6AB70 } +"0x82C6AF24" = { end = 0x82C6AF30, parent = 0x82C6AB70 } +"0x82C6AF78" = { end = 0x82C6AF98, parent = 0x82C6AB70 } +"0x82C6AFE8" = { end = 0x82C6AFF8, parent = 0x82C6AB70 } +"0x82CF04EC" = { end = 0x82CF0540, parent = 0x82CF0458 } +"0x82CF0540" = { end = 0x82CF0550, parent = 0x82CF0458 } +"0x82CF0550" = { end = 0x82CF0558, parent = 0x82CF0458 } +"0x82CF0558" = { end = 0x82CF0560, parent = 0x82CF0458 } +"0x82CF0560" = { end = 0x82CF0568, parent = 0x82CF0458 } +"0x82CF0568" = { end = 0x82CF056C, parent = 0x82CF0458 } +"0x82CF056C" = { end = 0x82CF0578, parent = 0x82CF0458 } +"0x82CF0578" = { end = 0x82CF0594, parent = 0x82CF0458 } +"0x82CF0770" = { end = 0x82CF0794, parent = 0x82CF06D0 } +"0x82CF0794" = { end = 0x82CF08D0, parent = 0x82CF06D0 } +"0x82CF0ACC" = { end = 0x82CF0B80, parent = 0x82CF06D0 } +"0x82D00ACC" = { end = 0x82D00B3C, parent = 0x82D00A70 } +"0x82D00B3C" = { end = 0x82D00B5C, parent = 0x82D00A70 } +"0x82D00B64" = { end = 0x82D00BC8, parent = 0x82D00A70 } +"0x82D00BD4" = { end = 0x82D00C14, parent = 0x82D00A70 } +"0x82D00C40" = { end = 0x82D00CA4, parent = 0x82D00A70 } +"0x82D00CAC" = { end = 0x82D00CEC, parent = 0x82D00A70 } +"0x82D00D84" = { end = 0x82D00DC4, parent = 0x82D00A70 } +"0x82D00E44" = { end = 0x82D00E54, parent = 0x82D00A70 } +"0x82D00F2C" = { end = 0x82D00F3C, parent = 0x82D00A70 } +"0x82D01014" = { end = 0x82D01024, parent = 0x82D00A70 } +"0x82D01088" = { end = 0x82D010D0, parent = 0x82D00A70 } +"0x82D010E4" = { end = 0x82D010F4, parent = 0x82D00A70 } +"0x82D14EB0" = { end = 0x82D14EBC, parent = 0x82D14DF8 } +"0x82D14ED0" = { end = 0x82D14EEC, parent = 0x82D14DF8 } +"0x82D665EC" = { end = 0x82D66648, parent = 0x82D66498 } +"0x82D66648" = { end = 0x82D66654, parent = 0x82D66498 } +"0x82D66714" = { end = 0x82D6671C, parent = 0x82D66498 } +"0x82D70808" = { end = 0x82D70860, parent = 0x82D70718 } +"0x82D708B8" = { end = 0x82D708C4, parent = 0x82D70718 } +"0x82D708C4" = { end = 0x82D7090C, parent = 0x82D70718 } +"0x82DDCA54" = { end = 0x82DDCA88, parent = 0x82DDC9A8 } +"0x82DDCB30" = { end = 0x82DDCB90, parent = 0x82DDC9A8 } +"0x82DDCCD8" = { end = 0x82DDCCE8, parent = 0x82DDC9A8 } +"0x82E1FE00" = { end = 0x82E1FE30, parent = 0x82E1F590 } +"0x82E1FEE0" = { end = 0x82E1FF10, parent = 0x82E1F590 } +"0x82E20030" = { end = 0x82E20060, parent = 0x82E1F590 } +"0x82E22C08" = { end = 0x82E22C14, parent = 0x82E22B70 } +"0x82E22D08" = { end = 0x82E22D14, parent = 0x82E22B70 } +"0x82E23008" = { end = 0x82E23010, parent = 0x82E22B70 } +"0x82E251E0" = { end = 0x82E25210, parent = 0x82E25138 } +"0x82E253A0" = { end = 0x82E253B8, parent = 0x82E25138 } +"0x82E253B8" = { end = 0x82E253CC, parent = 0x82E25138 } +"0x82E2549C" = { end = 0x82E254B0, parent = 0x82E25138 } +"0x82E2561C" = { end = 0x82E25630, parent = 0x82E25138 } +"0x82E25630" = { end = 0x82E25644, parent = 0x82E25138 } +"0x82E25740" = { end = 0x82E25754, parent = 0x82E25138 } +"0x82E26098" = { end = 0x82E260A8, parent = 0x82E25F58 } +"0x82E2629C" = { end = 0x82E26320, parent = 0x82E25F58 } +"0x82E2B760" = { end = 0x82E2B780, parent = 0x82E2B518 } +"0x82E2B838" = { end = 0x82E2B850, parent = 0x82E2B518 } +"0x82E2B9F0" = { end = 0x82E2BA10, parent = 0x82E2B518 } +"0x82E2BD2C" = { end = 0x82E2BD70, parent = 0x82E2B518 } +"0x82E2BDAC" = { end = 0x82E2BDE8, parent = 0x82E2B518 } +"0x82E2BEB4" = { end = 0x82E2BEFC, parent = 0x82E2B518 } +"0x82E2BEFC" = { end = 0x82E2BF14, parent = 0x82E2B518 } +"0x82E2C380" = { end = 0x82E2C38C, parent = 0x82E2B518 } +"0x82E2C5A8" = { end = 0x82E2C62C, parent = 0x82E2B518 } +"0x82E2C65C" = { end = 0x82E2C6E0, parent = 0x82E2B518 } +"0x82E2C710" = { end = 0x82E2C794, parent = 0x82E2B518 } +"0x82E2C7C4" = { end = 0x82E2C848, parent = 0x82E2B518 } +"0x82E2C878" = { end = 0x82E2C8A8, parent = 0x82E2B518 } +"0x82E2CAB8" = { end = 0x82E2CAE8, parent = 0x82E2B518 } +"0x82E2CB18" = { end = 0x82E2CB48, parent = 0x82E2B518 } +"0x82E2CC98" = { end = 0x82E2CCC8, parent = 0x82E2B518 } +"0x82E2CE18" = { end = 0x82E2CE48, parent = 0x82E2B518 } +"0x82E2CFF8" = { end = 0x82E2D020, parent = 0x82E2B518 } +"0x82E2D12C" = { end = 0x82E2D15C, parent = 0x82E2B518 } +"0x82E2D258" = { end = 0x82E2D2E8, parent = 0x82E2D198 } +"0x82E2D404" = { end = 0x82E2D410, parent = 0x82E2D198 } +"0x82E2D540" = { end = 0x82E2D558, parent = 0x82E2D198 } +"0x82E2D71C" = { end = 0x82E2D774, parent = 0x82E2D198 } +"0x82E2D838" = { end = 0x82E2D890, parent = 0x82E2D198 } +"0x82E2D920" = { end = 0x82E2D96C, parent = 0x82E2D198 } +"0x82E2DA34" = { end = 0x82E2DA6C, parent = 0x82E2D198 } +"0x82E2DA88" = { end = 0x82E2DAC0, parent = 0x82E2D198 } +"0x82E2DB10" = { end = 0x82E2DB44, parent = 0x82E2D198 } +"0x82E2DB44" = { end = 0x82E2DB78, parent = 0x82E2D198 } +"0x82E2DBAC" = { end = 0x82E2DBE0, parent = 0x82E2D198 } +"0x82E2DBE0" = { end = 0x82E2DC14, parent = 0x82E2D198 } +"0x82E2EB58" = { end = 0x82E2EB8C, parent = 0x82E2EB00 } +"0x82E2EB8C" = { end = 0x82E2EBC0, parent = 0x82E2EB00 } +"0x82E2EE44" = { end = 0x82E2EE60, parent = 0x82E2EB00 } +"0x82E2EE78" = { end = 0x82E2EE94, parent = 0x82E2EB00 } +"0x82E2EEAC" = { end = 0x82E2EEC8, parent = 0x82E2EB00 } +"0x82E2F05C" = { end = 0x82E2F098, parent = 0x82E2EFF0 } +"0x82E2F38C" = { end = 0x82E2F3CC, parent = 0x82E2EFF0 } +"0x82E2F4E0" = { end = 0x82E2F508, parent = 0x82E2EFF0 } +"0x82E2F508" = { end = 0x82E2F530, parent = 0x82E2EFF0 } +"0x82E2F530" = { end = 0x82E2F59C, parent = 0x82E2EFF0 } +"0x82E2F640" = { end = 0x82E2F658, parent = 0x82E2EFF0 } +"0x82E32CE8" = { end = 0x82E32D30, parent = 0x82E32C58 } +"0x82E33050" = { end = 0x82E330D8, parent = 0x82E32C58 } +"0x82E33438" = { end = 0x82E334C0, parent = 0x82E32C58 } +"0x82E33B5C" = { end = 0x82E33B7C, parent = 0x82E33A40 } +"0x82E33C7C" = { end = 0x82E33C9C, parent = 0x82E33A40 } +"0x82E33CDC" = { end = 0x82E33CFC, parent = 0x82E33A40 } +"0x82E33D1C" = { end = 0x82E33D3C, parent = 0x82E33A40 } +"0x82E33D3C" = { end = 0x82E33D5C, parent = 0x82E33A40 } +"0x82E33D7C" = { end = 0x82E33D9C, parent = 0x82E33A40 } +"0x82E33DBC" = { end = 0x82E33DDC, parent = 0x82E33A40 } +"0x82E33EFC" = { end = 0x82E33F1C, parent = 0x82E33A40 } +"0x82E33F7C" = { end = 0x82E33F9C, parent = 0x82E33A40 } +"0x82E34610" = { end = 0x82E3461C, parent = 0x82E344F0 } +"0x82E3462C" = { end = 0x82E34650, parent = 0x82E344F0 } +"0x82E3465C" = { end = 0x82E34670, parent = 0x82E344F0 } +"0x82E34670" = { end = 0x82E346BC, parent = 0x82E344F0 } +"0x82E347E4" = { end = 0x82E3480C, parent = 0x82E344F0 } +"0x82E34880" = { end = 0x82E34884, parent = 0x82E344F0 } +"0x82E36C0C" = { end = 0x82E36C30, parent = 0x82E36AB0 } +"0x82E36C70" = { end = 0x82E36C7C, parent = 0x82E36AB0 } +"0x82E36D28" = { end = 0x82E36D34, parent = 0x82E36AB0 } +"0x82E36D34" = { end = 0x82E36D54, parent = 0x82E36AB0 } +"0x82E36E18" = { end = 0x82E36E28, parent = 0x82E36AB0 } +"0x82E36E58" = { end = 0x82E36EDC, parent = 0x82E36AB0 } +"0x82E37168" = { end = 0x82E3717C, parent = 0x82E36AB0 } +"0x82E373D0" = { end = 0x82E373D8, parent = 0x82E37308 } +"0x82E3C670" = { end = 0x82E3C7A0, parent = 0x82E3C5E8 } +"0x82E3C7A0" = { end = 0x82E3C7A8, parent = 0x82E3C5E8 } +"0x82E3C7A8" = { end = 0x82E3C7B0, parent = 0x82E3C5E8 } +"0x82E3C7B0" = { end = 0x82E3C7DC, parent = 0x82E3C5E8 } +"0x82E3C7FC" = { end = 0x82E3C828, parent = 0x82E3C5E8 } +"0x82E3CB64" = { end = 0x82E3CB74, parent = 0x82E3C5E8 } +"0x82E3CB74" = { end = 0x82E3CBA0, parent = 0x82E3C5E8 } +"0x82E3CBF0" = { end = 0x82E3CC1C, parent = 0x82E3C5E8 } +"0x82E3CD04" = { end = 0x82E3CD30, parent = 0x82E3C5E8 } +"0x82E3CE48" = { end = 0x82E3CE4C, parent = 0x82E3C5E8 } +"0x82E3CE4C" = { end = 0x82E3CE54, parent = 0x82E3C5E8 } +"0x82E4A170" = { end = 0x82E4A188, parent = 0x82E4A0A8 } +"0x82E4A200" = { end = 0x82E4A260, parent = 0x82E4A0A8 } +"0x82E4A274" = { end = 0x82E4A288, parent = 0x82E4A0A8 } +"0x82E4A2B0" = { end = 0x82E4A2C4, parent = 0x82E4A0A8 } +"0x82E4A2EC" = { end = 0x82E4A304, parent = 0x82E4A0A8 } +"0x82E4A37C" = { end = 0x82E4A388, parent = 0x82E4A0A8 } +"0x82E4A678" = { end = 0x82E4A6A0, parent = 0x82E4A528 } +"0x82E4A720" = { end = 0x82E4A734, parent = 0x82E4A528 } +"0x82E4A734" = { end = 0x82E4A750, parent = 0x82E4A528 } +"0x82E4A774" = { end = 0x82E4A788, parent = 0x82E4A528 } +"0x82E4A830" = { end = 0x82E4A844, parent = 0x82E4A528 } +"0x82E4A888" = { end = 0x82E4A8B0, parent = 0x82E4A528 } +"0x82E4DD9C" = { end = 0x82E4DDB8, parent = 0x82E4DD18 } +"0x82E4DDC0" = { end = 0x82E4DDCC, parent = 0x82E4DD18 } +"0x82E4DDCC" = { end = 0x82E4DDD0, parent = 0x82E4DD18 } +"0x82F27400" = { end = 0x82F2740C, parent = 0x82F273F0 } +"0x82F2740C" = { end = 0x82F27428, parent = 0x82F273F0 } +"0x82F28378" = { end = 0x82F2838C, parent = 0x82F28368 } +"0x82F2838C" = { end = 0x82F283A8, parent = 0x82F28368 } +"0x82F2DB70" = { end = 0x82F2DBA8, parent = 0x82F2DAB0 } +"0x82F2DBA8" = { end = 0x82F2DBBC, parent = 0x82F2DAB0 } +"0x82F2DBBC" = { end = 0x82F2DBC0, parent = 0x82F2DAB0 } +"0x82F2DBFC" = { end = 0x82F2DC04, parent = 0x82F2DAB0 } +"0x82F2DC1C" = { end = 0x82F2DC34, parent = 0x82F2DAB0 } +"0x82F2DC48" = { end = 0x82F2DC50, parent = 0x82F2DAB0 } +"0x82F2DC68" = { end = 0x82F2DC88, parent = 0x82F2DAB0 } +"0x82F2DC9C" = { end = 0x82F2DCB0, parent = 0x82F2DAB0 } +"0x82F2DD18" = { end = 0x82F2DD24, parent = 0x82F2DAB0 } +"0x82F2DD24" = { end = 0x82F2DD48, parent = 0x82F2DAB0 } +"0x82F2DD58" = { end = 0x82F2DD60, parent = 0x82F2DAB0 } +"0x82F2DD74" = { end = 0x82F2DD88, parent = 0x82F2DAB0 } +"0x82F2DD88" = { end = 0x82F2DDA4, parent = 0x82F2DAB0 } +"0x82F2E8A0" = { end = 0x82F2E8CC, parent = 0x82F2E720 } +"0x82F2EB78" = { end = 0x82F2EBB8, parent = 0x82F2E720 } +"0x82F2EC44" = { end = 0x82F2EC50, parent = 0x82F2E720 } +"0x82F2EC60" = { end = 0x82F2EC74, parent = 0x82F2E720 } +"0x82F2ED50" = { end = 0x82F2ED6C, parent = 0x82F2E720 } +"0x82F2EE74" = { end = 0x82F2EE78, parent = 0x82F2E720 } +"0x82F2EE78" = { end = 0x82F2EE80, parent = 0x82F2E720 } +"0x82F2EE84" = { end = 0x82F2EE8C, parent = 0x82F2E720 } +"0x82F2EE8C" = { end = 0x82F2EE90, parent = 0x82F2E720 } +"0x82F2EE90" = { end = 0x82F2EEBC, parent = 0x82F2E720 } +"0x82F2EECC" = { end = 0x82F2EEDC, parent = 0x82F2E720 } +"0x82F2F030" = { end = 0x82F2F034, parent = 0x82F2E720 } +"0x82F2FB0C" = { end = 0x82F2FB1C, parent = 0x82F2F9C8 } +"0x82F2FE94" = { end = 0x82F2FEA4, parent = 0x82F2F9C8 } +"0x82F30324" = { end = 0x82F30334, parent = 0x82F2F9C8 } +"0x82F30664" = { end = 0x82F30684, parent = 0x82F2F9C8 } + +"0x823CE55C" = { end = 0x823CE568, parent = 0x823CD900 } +"0x823E9210" = { end = 0x823E9344, parent = 0x823E9168 } +"0x823E9218" = { end = 0x823E9344, parent = 0x823E9168 } +"0x823E9D1C" = { end = 0x823EA144, parent = 0x823E973C } +"0x823F4004" = { end = 0x823F5CE4, parent = 0x823F3CBC } +"0x823F6FB4" = { end = 0x823F6FC0, parent = 0x823F6DD8 } +"0x82464E8C" = { end = 0x82464EC0, parent = 0x82464E70 } +"0x82485A18" = { end = 0x82485A38, parent = 0x824859C4 } +"0x825D3B24" = { end = 0x825D3B34, parent = 0x825D3A08 } +"0x825D3B2C" = { end = 0x825D3B34, parent = 0x825D3A08 } +"0x826568D0" = { end = 0x826568E8, parent = 0x826568C4 } +"0x826BCCC4" = { end = 0x826BCCE0, parent = 0x826BCBE8 } +"0x826EAAA4" = { end = 0x826EAAB0, parent = 0x826EAA9C } +"0x826EBF6C" = { end = 0x826EBF78, parent = 0x826EB854 } +"0x8274B278" = { end = 0x8274B3E0, parent = 0x8274B210 } +"0x8274B328" = { end = 0x8274B3E0, parent = 0x8274B210 } +"0x8274D72C" = { end = 0x8274D8D0, parent = 0x8274D6A0 } +"0x828E39B8" = { end = 0x828E3B00, parent = 0x828E3780 } +"0x828F8938" = { end = 0x828F8940, parent = 0x828F8910 } +"0x82923B94" = { end = 0x82923BB4, parent = 0x82923B54 } +"0x82928CE8" = { end = 0x82928D0C, parent = 0x82928CC4 } +"0x8292905C" = { end = 0x82929070, parent = 0x82929044 } +"0x8294393C" = { end = 0x82943968, parent = 0x8294389C } +"0x82AEBEA4" = { end = 0x82AEBEC0, parent = 0x82AEBCE8 } +"0x82C0125C" = { end = 0x82C01268, parent = 0x82C01228 } +"0x82EBA588" = { end = 0x82EBA594, parent = 0x82EBA57C } +"0x82EBAE4C" = { end = 0x82EBAE58, parent = 0x82EBAE40 } +"0x82F22CF8" = { end = 0x82F22D04, parent = 0x82F22CEC } + +"0x8296A510" = {} + +"0x829E7658" = { end = 0x829E7660 } + +"0x82654D98" = { end = 0x82654DB8 } +"0x82654DB8" = { end = 0x82654DDC } + +"0x82663110" = { end = 0x82663130 } +"0x82663130" = { end = 0x82663154 } + +"0x8262B870" = { end = 0x8262B8A0 } + +"0x82CDE398" = { end = 0x82CDE3BC } +"0x82CDE3E8" = { end = 0x82CDE428 } +"0x82E48608" = { end = 0x82E48640 } +"0x82E48640" = { end = 0x82E48678 } + +"0x8293C350" = { end = 0x8293C638, parent = 0x8293C348 } + +"0x82CFC3A0" = { end = 0x82CFC3C0 } + +"0x8246CED8" = { end = 0x8246CF10 } diff --git a/manifests/eawebkit.toml.in b/manifests/eawebkit.toml.in new file mode 100644 index 0000000..b561688 --- /dev/null +++ b/manifests/eawebkit.toml.in @@ -0,0 +1,12 @@ +[project] +sdk_version = "0.8.1.19" +name = "eawebkit" + +[entrypoint] +file_path = "@SKATE3_GAME_DATA_ROOT_CONFIG@/data/webkit/EAWebkit.xex" +out_directory_path = "@SKATE3_SOURCE_DIR_CONFIG@/generated/eawebkit" +includes = [ + "@SKATE3_SOURCE_DIR_CONFIG@/config/eawebkit_functions.toml", +] + +symbol_prefix = "eawebkit_" diff --git a/manifests/skate3.toml.in b/manifests/skate3.toml.in new file mode 100644 index 0000000..78f6328 --- /dev/null +++ b/manifests/skate3.toml.in @@ -0,0 +1,10 @@ +[project] +sdk_version = "0.8.1.19" +name = "skate3" + +[entrypoint] +file_path = "@SKATE3_GAME_DATA_ROOT_CONFIG@/default.xex" +out_directory_path = "@SKATE3_SOURCE_DIR_CONFIG@/generated" +includes = [ + "@SKATE3_SOURCE_DIR_CONFIG@/config/skate3_functions.toml", +] diff --git a/src/exception_compat.cpp b/src/exception_compat.cpp new file mode 100644 index 0000000..1aacae1 --- /dev/null +++ b/src/exception_compat.cpp @@ -0,0 +1,16 @@ +#include "skate3_init.h" + +#include + +extern "C" REX_FUNC(__imp__sub_82F44E40); + +extern "C" REX_FUNC(sub_82F44E40) { + constexpr uint32_t kExceptionTrampoline = 0x83092CC0u; + const uint32_t trampoline = REX_LOAD_U32(kExceptionTrampoline); + if (trampoline == 0u) { + ctx.r3.u64 = 0; + return; + } + + __imp__sub_82F44E40(ctx, base); +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..f79bb10 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,34 @@ +// skate3 - ReXGlue Recompiled Project +// +// This file is yours to edit. 'rexglue migrate' will NOT overwrite it. + +#include "skate3_app_common.h" +#include + +#include +#include + +class Skate3PureApp : public Skate3BaseApp { + public: + using Skate3BaseApp::Skate3BaseApp; + + std::string_view GetBuildTitle() const override { + return SKATE3_BUILD_TITLE; + } + + std::string_view GetBuildStamp() const override { + return SKATE3_BUILD_STAMP; + } + + std::string GetWindowTitle() const override { + return "Skate 3 " SKATE3_BUILD_TITLE; + } + + static std::unique_ptr Create( + rex::ui::WindowedAppContext& ctx) { + return std::unique_ptr( + new Skate3PureApp(ctx, "skate3", skate3_PPCImageConfig)); + } +}; + +REX_DEFINE_APP(skate3, Skate3PureApp::Create) diff --git a/src/skate3_app.manifest b/src/skate3_app.manifest new file mode 100644 index 0000000..f2ecaba --- /dev/null +++ b/src/skate3_app.manifest @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + True/PM + PerMonitorV2,PerMonitor + + + diff --git a/src/skate3_app_common.cpp b/src/skate3_app_common.cpp new file mode 100644 index 0000000..a0784f9 --- /dev/null +++ b/src/skate3_app_common.cpp @@ -0,0 +1,684 @@ +#include "skate3_app_common.h" + +#include "skate3_iso_installer.h" +#include "skate3_user_settings.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#elif defined(__linux__) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if defined(__linux__) +extern char** environ; +#endif + +extern const rex::PPCImageInfo eawebkit_PPCImageConfig; + +// Register multi-entry-function alternate entries that rex's analyzer can't +// lift via config because they overlap with auto-discovered parent functions. +extern "C" REX_FUNC(__restgprlr_19); + +namespace { + +#if defined(__linux__) +std::vector CurrentProcessArgumentsForRestart( + const std::filesystem::path& executable_path) { + std::vector args; + std::ifstream cmdline("/proc/self/cmdline", std::ios::binary); + std::string arg; + char ch = 0; + while (cmdline.get(ch)) { + if (ch == '\0') { + args.push_back(std::move(arg)); + arg.clear(); + } else { + arg.push_back(ch); + } + } + if (!arg.empty()) { + args.push_back(std::move(arg)); + } + + const std::string executable = rex::path_to_utf8(executable_path); + if (args.empty()) { + args.push_back(executable); + } else { + args[0] = executable; + } + return args; +} +#endif + +constexpr std::string_view kUserDirectoryName = "skate3"; +constexpr std::string_view kSettingsFilename = "settings.toml"; + +std::filesystem::path DefaultDocumentsUserRoot() { + return rex::filesystem::GetUserFolder() / std::string(kUserDirectoryName); +} + +std::filesystem::path DefaultRoamingUserRoot() { +#if defined(_WIN32) + char* appdata = nullptr; + size_t appdata_size = 0; + if (_dupenv_s(&appdata, &appdata_size, "APPDATA") == 0 && appdata && *appdata) { + std::filesystem::path result = std::filesystem::path(appdata) / std::string(kUserDirectoryName); + std::free(appdata); + return result; + } + std::free(appdata); +#endif + return DefaultDocumentsUserRoot(); +} + +std::filesystem::path ResolveSkate3UserRoot(const rex::PathConfig& paths) { + const auto executable_root = rex::filesystem::GetExecutableFolder(); + if (std::filesystem::exists(executable_root / "portable.txt")) { + return executable_root; + } + + const auto old_default = DefaultDocumentsUserRoot(); + if (!paths.user_data_root.empty() && paths.user_data_root != old_default) { + return paths.user_data_root; + } + + return DefaultRoamingUserRoot(); +} + +void ConfigureSkate3UserPaths(rex::PathConfig& paths, std::filesystem::path& settings_path, + std::filesystem::path& profiles_path) { + const auto old_user_root = DefaultDocumentsUserRoot(); + const auto old_cache_root = old_user_root / "cache"; + const auto original_cache_root = paths.cache_root; + const auto resolved_user_root = ResolveSkate3UserRoot(paths); + + paths.user_data_root = resolved_user_root; + if (original_cache_root.empty() || original_cache_root == old_cache_root) { + paths.cache_root = resolved_user_root / "cache"; + } + settings_path = resolved_user_root / std::string(kSettingsFilename); + profiles_path = skate3::ProfilesFilePath(resolved_user_root); +} + +bool ConfigContainsAnyKey(const toml::table& table, std::initializer_list keys) { + for (std::string_view key : keys) { + if (table.contains(key)) { + return true; + } + } + return false; +} + +bool DeveloperConfigHasResolutionScaleOverride(const std::filesystem::path& config_path) { + if (config_path.empty() || !std::filesystem::exists(config_path)) { + return false; + } + try { + auto config = toml::parse_file(config_path.string()); + return ConfigContainsAnyKey(config, {"resolution_scale", "draw_resolution_scale_x", + "draw_resolution_scale_y"}); + } catch (const toml::parse_error&) { + return false; + } +} + +constexpr int kDefaultResolutionScale = 2; + +void ApplyFirstRunVideoDefaults(const std::filesystem::path& settings_path, + const std::filesystem::path& developer_config_path) { + if (std::filesystem::exists(settings_path) || + DeveloperConfigHasResolutionScaleOverride(developer_config_path) || + rex::cvar::HasNonDefaultValue("resolution_scale") || + rex::cvar::HasNonDefaultValue("draw_resolution_scale_x") || + rex::cvar::HasNonDefaultValue("draw_resolution_scale_y")) { + return; + } + + const auto scale = std::to_string(kDefaultResolutionScale); + rex::cvar::SetFlagByName("resolution_scale", scale); + rex::cvar::SetFlagByName("draw_resolution_scale_x", scale); + rex::cvar::SetFlagByName("draw_resolution_scale_y", scale); +} + +void LoadAndNormalizeSimpleSettings(const std::filesystem::path& settings_path, + const std::filesystem::path& developer_config_path) { + if (std::filesystem::exists(settings_path)) { + rex::cvar::LoadConfig(settings_path); + } else { + ApplyFirstRunVideoDefaults(settings_path, developer_config_path); + } + rex::ui::EnsureSimpleSettingsConfig(settings_path); +} + +const char* FirstExistingFontPath(std::initializer_list paths) { + for (const char* path : paths) { + if (std::filesystem::exists(path)) { + return path; + } + } + return nullptr; +} + +} // namespace + +// sub_82EBAE4C: alternate entry into sub_82EBAE34 (37 vtable refs in .data). +// Body: lwz r3, 0x164(r31); addi r1, r31, 0x140; b __restgprlr_19 +static void Sub82EBAE4CImpl(PPCContext& ctx, uint8_t* base) { + ctx.r3.u64 = REX_LOAD_U32(ctx.r31.u32 + 0x164); + ctx.r1.s64 = ctx.r31.s64 + 0x140; + __restgprlr_19(ctx, base); +} + +Skate3BaseApp::~Skate3BaseApp() = default; + +void Skate3BaseApp::OnConfigurePaths(rex::PathConfig& paths) { + ConfigureSkate3UserPaths(paths, user_settings_path_, profiles_path_); + config_path_ = paths.config_path; + LoadAndNormalizeSimpleSettings(user_settings_path_, config_path_); +} + +void Skate3BaseApp::OnConfigureFonts(ImFontAtlas* atlas) { + if (!atlas) { + return; + } + + atlas->Clear(); + ImFontConfig font_config; + font_config.OversampleH = 2; + font_config.OversampleV = 2; + font_config.PixelSnapH = false; + + const char* base_font_path = FirstExistingFontPath({ +#if defined(_WIN32) + "C:\\Windows\\Fonts\\Helvetica.ttf", + "C:\\Windows\\Fonts\\helvetica.ttf", + "C:\\Windows\\Fonts\\HelveticaNeue.ttf", + "C:\\Windows\\Fonts\\arial.ttf", +#else + "/usr/share/fonts/truetype/noto/NotoSans-Regular.ttf", + "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf", + "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", + "/usr/local/share/fonts/NotoSans-Regular.ttf", + "/usr/local/share/fonts/LiberationSans-Regular.ttf", +#endif + }); + + if (base_font_path) { + atlas->AddFontFromFileTTF(base_font_path, 16.0f, &font_config, + atlas->GetGlyphRangesDefault()); + } else { + atlas->AddFontDefault(); + } + +#if defined(_WIN32) + const char* jp_font_path = "C:\\Windows\\Fonts\\msgothic.ttc"; + if (std::filesystem::exists(jp_font_path)) { + ImFontConfig jp_font_config; + jp_font_config.MergeMode = true; + jp_font_config.OversampleH = jp_font_config.OversampleV = 1; + jp_font_config.PixelSnapH = true; + jp_font_config.FontNo = 0; + atlas->AddFontFromFileTTF(jp_font_path, 16.0f, &jp_font_config, + atlas->GetGlyphRangesJapanese()); + } +#endif +} + +std::optional Skate3BaseApp::OnFinalizePaths( + const rex::PathConfig& defaults, std::function resume) { + config_path_ = defaults.config_path; + user_settings_path_ = defaults.user_data_root / std::string(kSettingsFilename); + profiles_path_ = skate3::ProfilesFilePath(defaults.user_data_root); + + auto profiles = skate3::LoadProfiles(profiles_path_); + const bool has_profiles_file = std::filesystem::exists(profiles_path_); + skate3::EnsureUsableProfileStore(profiles, "Player"); + if (auto* profile = skate3::FindSelectedProfile(profiles)) { + skate3::ApplyProfileCvars(*profile); + } + + const bool has_config_file = std::filesystem::exists(defaults.config_path); + const bool has_game_path = std::filesystem::is_directory(defaults.game_data_root); + if (!has_profiles_file && has_config_file && has_game_path) { + skate3::SaveProfiles(profiles_path_, profiles); + } + auto runtime_paths = defaults; + if (runtime_paths.game_data_root.empty()) { + runtime_paths.game_data_root = config_path_.parent_path() / "game"; + } + runtime_paths.config_path.clear(); + if (!skate3::IsGameInstalled(runtime_paths.game_data_root)) { + REXLOG_INFO("Game files not found at {}; launching rexglue ISO installer", + runtime_paths.game_data_root.string()); + rex::PathConfig installed_paths; + const bool installed = skate3::RunRexglueIsoInstallWizardBlocking( + app_context(), window(), imgui_drawer(), runtime_paths, installed_paths); + if (!installed) { + app_context().QuitFromUIThread(); + return std::nullopt; + } + return installed_paths; + } + return runtime_paths; +} + +void Skate3BaseApp::OnCreateDialogs(rex::ui::ImGuiDrawer* drawer) { + (void)drawer; + rex::ui::RegisterBind("bind_skate3_menu", "Escape", "Skate 3 settings", [this] { + ToggleSimpleSettings(); + }); + rex::ui::RegisterBind("bind_skate3_menu_alt", "F1", "Skate 3 settings alternate", [this] { + ToggleSimpleSettings(); + }); + rex::ui::RegisterBind("bind_skate3_save_draw_fingerprints", "F8", + "Save draw fingerprint log", [this] { + SaveDrawFingerprintLog(); + }); +} + +void Skate3BaseApp::OnPostSetup() { + ApplySelectedProfileToRuntime(); + ApplyGameplayCursorMode(); + + if (auto* input_system = static_cast(runtime()->input_system())) { + input_system->SetActiveCallback([this]() { + const bool settings_visible = simple_settings_dialog_ && simple_settings_dialog_->visible(); + const bool xam_ui_active = rex::kernel::xam::xeXamIsUIActive(); + return !settings_visible && !xam_ui_active; + }); + input_system->SetMenuChordCallback([this]() { + app_context().CallInUIThreadDeferred([this]() { ToggleSimpleSettings(); }); + }); + } + + if (std::getenv("SKATE3_DISABLE_BIG_ALIASES") == nullptr) { + InstallBigDeviceAliases(); + } + InstallRecipeOverlay(); + + // Register multi-entry-function alternate entries. + runtime()->function_dispatcher()->SetFunction(0x82EBAE4C, &Sub82EBAE4CImpl); + + auto* dispatcher = runtime()->function_dispatcher(); + if (dispatcher->InitializeFunctionTable(eawebkit_PPCImageConfig.code_base, + eawebkit_PPCImageConfig.code_size, + eawebkit_PPCImageConfig.image_base, + eawebkit_PPCImageConfig.image_size)) { + for (int i = 0; eawebkit_PPCImageConfig.func_mappings[i].guest != 0; ++i) { + auto* host = eawebkit_PPCImageConfig.func_mappings[i].host; + if (host) { + dispatcher->SetFunction( + static_cast(eawebkit_PPCImageConfig.func_mappings[i].guest), + host); + } + } + } +} + +void Skate3BaseApp::OnPostLaunchModule(rex::system::XThread* thread) { + (void)thread; + if (std::getenv("SKATE3_INVALIDATE_GPU_MEMORY_EVERY_FRAME") == nullptr) { + return; + } + + auto* graphics_system = + static_cast(runtime()->graphics_system()); + if (!graphics_system) { + return; + } + + invalidate_gpu_memory_thread_running_.store(true, std::memory_order_release); + invalidate_gpu_memory_thread_ = std::thread([this, graphics_system]() { + while (invalidate_gpu_memory_thread_running_.load( + std::memory_order_acquire)) { + graphics_system->InvalidateGpuMemory(); + std::this_thread::sleep_for(std::chrono::milliseconds(16)); + } + }); +} + +void Skate3BaseApp::OnShutdown() { + rex::ui::UnregisterBind("bind_skate3_menu"); + rex::ui::UnregisterBind("bind_skate3_menu_alt"); + rex::ui::UnregisterBind("bind_skate3_save_draw_fingerprints"); + ApplyGameplayCursorMode(); + simple_settings_dialog_.reset(); + StopGpuMemoryInvalidationThread(); +} + +void Skate3BaseApp::OnGuestThreadExit(rex::system::XThread* thread) { + (void)thread; + StopGpuMemoryInvalidationThread(); +} + +void Skate3BaseApp::StopGpuMemoryInvalidationThread() { + invalidate_gpu_memory_thread_running_.store(false, std::memory_order_release); + if (invalidate_gpu_memory_thread_.joinable()) { + invalidate_gpu_memory_thread_.join(); + } +} + +void Skate3BaseApp::ToggleSimpleSettings() { + if (simple_settings_dialog_) { + if (simple_settings_dialog_->visible()) { + simple_settings_dialog_->Hide(); + } else { + ApplySettingsCursorMode(); + simple_settings_dialog_->Show(); + } + return; + } + + auto load_profiles = [this]() { + rex::ui::SimpleProfileState state; + auto store = skate3::LoadProfiles(profiles_path_); + skate3::EnsureUsableProfileStore(store, "Player"); + state.selected_index = 0; + for (int i = 0; i < static_cast(store.profiles.size()); ++i) { + const auto& profile = store.profiles[i]; + state.profiles.push_back({profile.id, profile.gamertag, profile.signed_in}); + if (profile.id == store.selected_profile) { + state.selected_index = i; + } + } + return state; + }; + auto save_profile = [this](int selected_index, std::string gamertag, bool signed_in) { + auto store = skate3::LoadProfiles(profiles_path_); + skate3::EnsureUsableProfileStore(store, "Player"); + if (store.profiles.empty()) { + return; + } + selected_index = std::clamp(selected_index, 0, static_cast(store.profiles.size()) - 1); + auto& profile = store.profiles[selected_index]; + if (!gamertag.empty()) { + profile.gamertag = std::move(gamertag); + } + profile.signed_in = signed_in; + if (!profile.signed_in) { + profile.live_signed_in = false; + } + store.selected_profile = profile.id; + skate3::SaveProfiles(profiles_path_, store); + skate3::ApplyProfileCvars(profile); + ApplySelectedProfileToRuntime(); + }; + auto close_settings = [this]() { ApplyGameplayCursorMode(); }; + auto close_game = [this]() { + app_context().CallInUIThreadDeferred([this]() { + if (window()) { + window()->RequestClose(); + } else { + app_context().QuitFromUIThread(); + } + }); + }; + auto restart_game = [this]() { RestartGame(); }; + simple_settings_dialog_ = + std::make_unique( + imgui_drawer(), user_settings_path_, std::move(load_profiles), std::move(save_profile), + std::move(close_settings), std::move(close_game), std::move(restart_game)); + ApplySettingsCursorMode(); + simple_settings_dialog_->Show(); +} + +void Skate3BaseApp::ApplySettingsCursorMode() { + if (window()) { + window()->SetCursorVisibility(rex::ui::Window::CursorVisibility::kVisible); + } +} + +void Skate3BaseApp::ApplyGameplayCursorMode() { + if (window()) { + window()->SetCursorVisibility(rex::ui::Window::CursorVisibility::kAutoHidden); + } +} + +void Skate3BaseApp::RestartGame() { + app_context().CallInUIThreadDeferred([this]() { +#if defined(_WIN32) + wchar_t executable_path[MAX_PATH] = {}; + if (!GetModuleFileNameW(nullptr, executable_path, MAX_PATH)) { + REXLOG_WARN("Restart requested, but the executable path could not be resolved"); + return; + } + + std::wstring command_line = GetCommandLineW(); + STARTUPINFOW startup_info{}; + startup_info.cb = sizeof(startup_info); + PROCESS_INFORMATION process_info{}; + if (!CreateProcessW(executable_path, command_line.data(), nullptr, nullptr, FALSE, 0, nullptr, + nullptr, &startup_info, &process_info)) { + REXLOG_WARN("Restart requested, but launching a new process failed"); + return; + } + CloseHandle(process_info.hThread); + CloseHandle(process_info.hProcess); +#elif defined(__linux__) + const auto executable_path = rex::filesystem::GetExecutablePath(); + if (executable_path.empty()) { + REXLOG_WARN("Restart requested, but the executable path could not be resolved"); + return; + } + + auto args = CurrentProcessArgumentsForRestart(executable_path); + std::vector argv; + argv.reserve(args.size() + 1); + for (auto& arg : args) { + argv.push_back(arg.data()); + } + argv.push_back(nullptr); + + const std::string executable = rex::path_to_utf8(executable_path); + pid_t child_pid = 0; + const int spawn_result = + posix_spawn(&child_pid, executable.c_str(), nullptr, nullptr, argv.data(), environ); + if (spawn_result != 0) { + REXLOG_WARN("Restart requested, but launching a new process failed: {}", + std::strerror(spawn_result)); + return; + } +#else + REXLOG_WARN("Restart requested, but automatic restart is not implemented on this platform"); + return; +#endif + + if (window()) { + window()->RequestClose(); + } else { + app_context().QuitFromUIThread(); + } + }); +} + +void Skate3BaseApp::SaveDrawFingerprintLog() { +#ifndef REXGLUE_ENABLE_PERF_COUNTERS + REXLOG_WARN("Perf capture is unavailable because perf counters are disabled in this build"); + return; +#else + auto now = std::chrono::system_clock::now(); + std::time_t now_time = std::chrono::system_clock::to_time_t(now); + std::tm local_time{}; +#if defined(_WIN32) + localtime_s(&local_time, &now_time); +#else + localtime_r(&now_time, &local_time); +#endif + + std::ostringstream counters_filename; + counters_filename << "perf_capture_counters_" << std::put_time(&local_time, "%Y%m%d_%H%M%S") + << ".csv"; + std::ostringstream filename; + filename << "perf_capture_draw_fingerprints_" << std::put_time(&local_time, "%Y%m%d_%H%M%S") + << ".csv"; + + std::error_code ec; + std::filesystem::create_directories(cache_root(), ec); + const auto counters_path = cache_root() / counters_filename.str(); + const auto path = cache_root() / filename.str(); + if (rex::perf::StartCapture(counters_path, path)) { + REXLOG_INFO("Started perf capture; counter log will be saved to {}", + counters_path.string()); + REXLOG_INFO("Started perf capture; draw fingerprint log will be saved to {}", + path.string()); + } else { + REXLOG_WARN("Perf capture is already running"); + } +#endif +} + +void Skate3BaseApp::ApplySelectedProfileToRuntime() { + if (!runtime() || !runtime()->kernel_state() || !runtime()->kernel_state()->user_profile()) { + return; + } + auto profiles = skate3::LoadProfiles(profiles_path_); + if (auto* profile = skate3::FindSelectedProfile(profiles)) { + skate3::ApplyProfileCvars(*profile); + runtime()->kernel_state()->user_profile()->SetIdentity(profile->xuid, profile->gamertag); + } +} + +bool Skate3BaseApp::IsRecipeNameChar(char c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || c == '_' || c == '-'; +} + +std::set Skate3BaseApp::DiscoverRecipeAliases( + const std::filesystem::path& content_root) { + static constexpr size_t kScanBytes = 8 * 1024 * 1024; + static constexpr std::string_view kPrefix = "data/content/recipe/"; + + std::set aliases; + std::error_code ec; + for (const auto& entry : std::filesystem::directory_iterator(content_root, ec)) { + if (ec || !entry.is_regular_file() || entry.path().extension() != ".big") { + continue; + } + + std::ifstream stream(entry.path(), std::ios::binary); + if (!stream) { + continue; + } + + std::string buffer; + buffer.resize(kScanBytes); + stream.read(buffer.data(), static_cast(buffer.size())); + buffer.resize(static_cast(stream.gcount())); + + size_t pos = 0; + while ((pos = buffer.find(kPrefix, pos)) != std::string::npos) { + size_t name_start = pos + kPrefix.size(); + size_t name_end = name_start; + while (name_end < buffer.size() && IsRecipeNameChar(buffer[name_end])) { + ++name_end; + } + if (name_end > name_start) { + aliases.insert(buffer.substr(name_start, name_end - name_start)); + } + pos = name_end; + } + } + + return aliases; +} + +void Skate3BaseApp::InstallRecipeOverlay() { + if (recipe_overlay_installed_ || !runtime() || !runtime()->file_system()) { + return; + } + + const auto content_root = game_data_root() / "data" / "content"; + if (!std::filesystem::exists(content_root)) { + return; + } + + const auto aliases = DiscoverRecipeAliases(content_root); + if (aliases.empty()) { + return; + } + + const auto overlay_root = cache_root() / "vfs_recipe_aliases"; + std::error_code ec; + std::filesystem::create_directories(overlay_root, ec); + if (ec) { + return; + } + + size_t created = 0; + for (const auto& alias : aliases) { + std::filesystem::create_directories(overlay_root / alias, ec); + if (!ec) { + ++created; + } + ec.clear(); + } + if (!created) { + return; + } + + auto device = std::make_unique( + "skate3recipe:", overlay_root, true); + if (!device->Initialize()) { + return; + } + + runtime()->file_system()->RegisterDevice(std::move(device)); + runtime()->file_system()->RegisterSymbolicLink( + "\\Device\\Harddisk0\\Partition1\\data\\content\\recipe", + "skate3recipe:"); + recipe_overlay_installed_ = true; +} + +void Skate3BaseApp::InstallBigDeviceAliases() { + if (big_device_aliases_installed_ || !runtime() || !runtime()->file_system()) { + return; + } + + // Skate 3 uses these file-server style schemes for world content probes. + // Route them to the normal title mount so existing disc files resolve. + runtime()->file_system()->RegisterSymbolicLink( + "big:", "\\Device\\Harddisk0\\Partition1"); + runtime()->file_system()->RegisterSymbolicLink( + "dlcbig:", "\\Device\\Harddisk0\\Partition1"); + big_device_aliases_installed_ = true; +} diff --git a/src/skate3_app_common.h b/src/skate3_app_common.h new file mode 100644 index 0000000..a5da3c7 --- /dev/null +++ b/src/skate3_app_common.h @@ -0,0 +1,61 @@ +#pragma once + +#include "generated/skate3_init.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace rex::ui { +class ImGuiDrawer; +} + +class Skate3BaseApp : public rex::ReXApp { + public: + using rex::ReXApp::ReXApp; + ~Skate3BaseApp() override; + + protected: + std::optional OnFinalizePaths( + const rex::PathConfig& defaults, + std::function resume) override; + void OnConfigurePaths(rex::PathConfig& paths) override; + void OnConfigureFonts(ImFontAtlas* atlas) override; + void OnCreateDialogs(rex::ui::ImGuiDrawer* drawer) override; + void OnPostSetup() override; + void OnPostLaunchModule(rex::system::XThread* thread) override; + void OnShutdown() override; + void OnGuestThreadExit(rex::system::XThread* thread) override; + + private: + void StopGpuMemoryInvalidationThread(); + void InstallRecipeOverlay(); + void InstallBigDeviceAliases(); + void ToggleSimpleSettings(); + void ApplySettingsCursorMode(); + void ApplyGameplayCursorMode(); + void RestartGame(); + void SaveDrawFingerprintLog(); + void ApplySelectedProfileToRuntime(); + + static bool IsRecipeNameChar(char c); + static std::set DiscoverRecipeAliases( + const std::filesystem::path& content_root); + + std::filesystem::path config_path_; + std::filesystem::path user_settings_path_; + std::filesystem::path profiles_path_; + std::unique_ptr simple_settings_dialog_; + bool recipe_overlay_installed_ = false; + bool big_device_aliases_installed_ = false; + std::atomic invalidate_gpu_memory_thread_running_{false}; + std::thread invalidate_gpu_memory_thread_; +};