mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-09-08 18:42:27 -04:00
Merge branch 'main' into surround-redux
This commit is contained in:
@@ -4,3 +4,9 @@
|
||||
[submodule "extern/borealis"]
|
||||
path = extern/borealis
|
||||
url = https://github.com/encounter/borealis.git
|
||||
[submodule "mods/randomizer"]
|
||||
path = mods/randomizer
|
||||
url = https://github.com/TwilitRealm/dusklight-randomizer.git
|
||||
[submodule "mods/cosmetics"]
|
||||
path = mods/cosmetics
|
||||
url = https://github.com/TwilitRealm/dusklight-cosmetics
|
||||
|
||||
+7
-76
@@ -72,6 +72,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL Linux)
|
||||
endif ()
|
||||
set(AURORA_ENABLE_DVD ON CACHE BOOL "Enable DVD API support" FORCE)
|
||||
set(AURORA_ENABLE_CARD ON CACHE BOOL "Enable CARD API support" FORCE)
|
||||
set(AURORA_ENABLE_THP ON CACHE BOOL "Enable THP decoder" FORCE)
|
||||
set(AURORA_ENABLE_RMLUI ON CACHE BOOL "Enable RmlUi UI support" FORCE)
|
||||
add_subdirectory(extern/aurora EXCLUDE_FROM_ALL)
|
||||
target_compile_definitions(aurora_mtx PRIVATE MTX_USE_PS=1)
|
||||
@@ -88,7 +89,6 @@ endif ()
|
||||
|
||||
option(DUSK_BUILD_WARNINGS "Enable compiler warnings (off by default)")
|
||||
option(DUSK_SELECTED_OPT "If on, selected parts of the project will be compiled with optimizations on Debug, intending to make the game run at 30 FPS. Note for MSVC: you will need to remove '/RTC1' from your debug flags in CMake.")
|
||||
option(DUSK_MOVIE_SUPPORT "If on, compile against libjpeg-turbo to enable THP file decoding" ON)
|
||||
option(DUSK_PACKAGE_INSTALL "Install Dusklight with a Linux-native file structure" OFF)
|
||||
option(DUSK_GFX_DEBUG_GROUPS "Report debug groups to the native graphics API" ${DUSK_GFX_DEBUG_GROUPS_DEFAULT})
|
||||
option(DUSK_ENABLE_CODE_MODS "Enable code mods" ON)
|
||||
@@ -133,69 +133,6 @@ if (MSVC)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (DUSK_MOVIE_SUPPORT)
|
||||
find_package(libjpeg-turbo 3.0 CONFIG QUIET)
|
||||
if (libjpeg-turbo_FOUND)
|
||||
message(STATUS "dusklight: Using system libjpeg-turbo")
|
||||
else ()
|
||||
message(STATUS "dusklight: Fetching libjpeg-turbo")
|
||||
include(ExternalProject)
|
||||
set(_jpeg_install_dir ${CMAKE_BINARY_DIR}/libjpeg-turbo-install)
|
||||
if (WIN32)
|
||||
set(_jpeg_lib ${_jpeg_install_dir}/lib/turbojpeg-static.lib)
|
||||
else ()
|
||||
set(_jpeg_lib ${_jpeg_install_dir}/lib/libturbojpeg.a)
|
||||
endif ()
|
||||
set(_jpeg_cmake_args
|
||||
-DCMAKE_INSTALL_PREFIX=${_jpeg_install_dir}
|
||||
-DCMAKE_PROJECT_INCLUDE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/WindowsTargetProcessor.cmake
|
||||
-DENABLE_SHARED=OFF
|
||||
-DWITH_TURBOJPEG=ON
|
||||
-DWITH_JAVA=OFF
|
||||
-DCMAKE_INSTALL_LIBDIR=lib
|
||||
)
|
||||
if (CMAKE_TOOLCHAIN_FILE)
|
||||
get_filename_component(_jpeg_toolchain_file "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||
list(APPEND _jpeg_cmake_args -DCMAKE_TOOLCHAIN_FILE=${_jpeg_toolchain_file})
|
||||
endif ()
|
||||
set(_jpeg_passthrough_vars
|
||||
ANDROID_ABI
|
||||
ANDROID_PLATFORM
|
||||
CMAKE_BUILD_TYPE
|
||||
CMAKE_C_COMPILER
|
||||
CMAKE_C_COMPILER_LAUNCHER
|
||||
CMAKE_MAKE_PROGRAM
|
||||
CMAKE_MSVC_RUNTIME_LIBRARY
|
||||
CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
|
||||
CMAKE_OSX_ARCHITECTURES
|
||||
CMAKE_OSX_DEPLOYMENT_TARGET
|
||||
CMAKE_OSX_SYSROOT
|
||||
DEPLOYMENT_TARGET
|
||||
ENABLE_ARC
|
||||
ENABLE_BITCODE
|
||||
PLATFORM
|
||||
)
|
||||
foreach(_var IN LISTS _jpeg_passthrough_vars)
|
||||
if (DEFINED ${_var})
|
||||
list(APPEND _jpeg_cmake_args -D${_var}=${${_var}})
|
||||
endif ()
|
||||
endforeach ()
|
||||
ExternalProject_Add(libjpeg-turbo-ext
|
||||
URL https://github.com/libjpeg-turbo/libjpeg-turbo/archive/refs/tags/3.1.0.tar.gz
|
||||
URL_HASH SHA256=35fec2e1ddfb05ecf6d93e50bc57c1e54bc81c16d611ddf6eff73fff266d8285
|
||||
CMAKE_ARGS ${_jpeg_cmake_args}
|
||||
BUILD_BYPRODUCTS ${_jpeg_lib}
|
||||
)
|
||||
file(MAKE_DIRECTORY ${_jpeg_install_dir}/include)
|
||||
add_library(libjpeg-turbo::turbojpeg-static STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(libjpeg-turbo::turbojpeg-static PROPERTIES
|
||||
IMPORTED_LOCATION ${_jpeg_lib}
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${_jpeg_install_dir}/include
|
||||
)
|
||||
add_dependencies(libjpeg-turbo::turbojpeg-static libjpeg-turbo-ext)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
|
||||
# -Wno-multichar: Multi-character constants ('ABCD') are implementation-defined but all compilers
|
||||
# (CW, GCC, Clang, MSVC) encode them identically in big-endian order.
|
||||
@@ -303,8 +240,8 @@ include(cmake/GameABIConfig.cmake)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
set(GAME_COMPILE_DEFS DUSK_BUILDING_GAME=1)
|
||||
set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd
|
||||
aurora::card borealis::cli borealis::crash borealis::data borealis::disc borealis::discord borealis::file_select borealis::io borealis::log borealis::presentation borealis::sentry borealis::update freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient fmt::fmt
|
||||
set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::pad aurora::mtx aurora::os aurora::dvd aurora::thp
|
||||
aurora::card borealis::cli borealis::crash borealis::data borealis::disc borealis::discord borealis::file_select borealis::io borealis::log borealis::net borealis::presentation borealis::sentry borealis::update borealis::ws freeverb cxxopts::cxxopts absl::flat_hash_map nlohmann_json::nlohmann_json TracyClient fmt::fmt
|
||||
Threads::Threads zstd::libzstd dusklight_game_headers)
|
||||
if (DUSK_HAS_FUNCHOOK)
|
||||
list(APPEND GAME_LIBS funchook-static)
|
||||
@@ -314,15 +251,6 @@ if (WIN32)
|
||||
list(APPEND GAME_LIBS Ws2_32)
|
||||
endif ()
|
||||
|
||||
if (DUSK_MOVIE_SUPPORT)
|
||||
if (TARGET libjpeg-turbo::turbojpeg-static)
|
||||
list(APPEND GAME_LIBS libjpeg-turbo::turbojpeg-static)
|
||||
else ()
|
||||
list(APPEND GAME_LIBS libjpeg-turbo::turbojpeg)
|
||||
endif ()
|
||||
list(APPEND GAME_COMPILE_DEFS MOVIE_SUPPORT=1)
|
||||
endif ()
|
||||
|
||||
if (DUSK_ENABLE_CODE_MODS)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_CODE_MODS=1)
|
||||
endif ()
|
||||
@@ -565,12 +493,15 @@ include(cmake/ModSDK.cmake)
|
||||
|
||||
if (DUSK_ENABLE_CODE_MODS AND CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
add_custom_target(dusklight_mods) # Aggregate target for all in-tree mods
|
||||
add_subdirectory(mods/luau_runtime)
|
||||
add_subdirectory(mods/template_mod)
|
||||
add_subdirectory(mods/ao_mod)
|
||||
add_subdirectory(mods/shadow_mod)
|
||||
add_subdirectory(mods/window_demo)
|
||||
add_subdirectory(mods/flow_demo)
|
||||
add_subdirectory(mods/basic_cosmetics_mod)
|
||||
add_subdirectory(mods/custom_actor_demo)
|
||||
add_subdirectory(mods/cosmetics)
|
||||
add_subdirectory(mods/randomizer)
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
|
||||
+6
-2
@@ -296,8 +296,6 @@ function(add_mod target_name)
|
||||
endif ()
|
||||
target_link_libraries(${target_name} PRIVATE "${_game_lib}")
|
||||
endif ()
|
||||
set_target_properties(${target_name} PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
|
||||
target_compile_definitions(${target_name} PRIVATE _ITERATOR_DEBUG_LEVEL=0)
|
||||
endif ()
|
||||
endif ()
|
||||
if (ARG_RUNTIME_LIBRARIES AND NOT _has_lib)
|
||||
@@ -316,6 +314,7 @@ function(add_mod target_name)
|
||||
set(_package_inputs "${_mod_json}")
|
||||
set(_extra_cmds "")
|
||||
set(_lib_copy_cmd "")
|
||||
set(_lib_strip_cmd "")
|
||||
set(_target_depend "")
|
||||
if (_has_lib)
|
||||
list(APPEND _zip_args lib)
|
||||
@@ -323,6 +322,10 @@ function(add_mod target_name)
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${_stage}/lib/${_lib_platform}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"$<TARGET_FILE:${target_name}>" "${_stage}/lib/${_lib_platform}/${_lib_name}")
|
||||
if (UNIX AND NOT APPLE)
|
||||
set(_lib_strip_cmd COMMAND "${CMAKE_STRIP}" --strip-unneeded
|
||||
"${_stage}/lib/${_lib_platform}/${_lib_name}")
|
||||
endif ()
|
||||
set(_target_depend ${target_name})
|
||||
endif ()
|
||||
string(TOLOWER "${_lib_name}" _lib_name_key)
|
||||
@@ -399,6 +402,7 @@ function(add_mod target_name)
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -rf "${_stage}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${_stage}" "${_output_dir}"
|
||||
${_lib_copy_cmd}
|
||||
${_lib_strip_cmd}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_mod_json}" "${_stage}/mod.json"
|
||||
${_extra_cmds}
|
||||
COMMAND ${CMAKE_COMMAND} -E chdir "${_stage}" ${CMAKE_COMMAND} -E tar cvf "${_out}" --format=zip ${_zip_args}
|
||||
|
||||
+476
-108
@@ -1,35 +1,137 @@
|
||||
# Dusklight Mod API
|
||||
|
||||
Mods are `.dusk` bundles: zip archives that can contain code (in the form of native libraries), resources, DVD overlay
|
||||
Mods are `.dusk` bundles: zip archives that can contain code (native libraries or scripts), resources, DVD overlay
|
||||
files, and texture replacements. Mods may be enabled, disabled and reloaded at runtime.
|
||||
|
||||
When code mods are loaded, they get dynamically linked by the operating system to the running game process. The mod
|
||||
There are three types of mods:
|
||||
|
||||
- **Asset-only mods**: Mods that contain no code, and may replace files on the game disc ("overlays") and provide
|
||||
replacement textures (texture packs).
|
||||
- **Native mods (C++)**: Fully-featured, with the ability to interop with game code and hook functions. Must be compiled
|
||||
for every supported platform. (See [mod-template](https://github.com/TwilitRealm/mod-template))
|
||||
- **Script mods (Luau)**: Simple, widely-compatible, but can only access provided services.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [mod.json](#modjson)
|
||||
2. [Asset-only Mods](#asset-only-mods)
|
||||
3. [Native Mods (C++)](#native-mods)
|
||||
4. [Script Mods (Luau)](#script-mods)
|
||||
5. [Services](#services)
|
||||
6. [Built-in Services](#built-in-services)
|
||||
7. [Hooking Game Functions](#hooking-game-functions)
|
||||
8. [Asset Overlays](#asset-overlays)
|
||||
9. [Runtime Lifecycle](#runtime-lifecycle)
|
||||
10. [Error Handling](#error-handling)
|
||||
11. [Advanced](#advanced)
|
||||
|
||||
---
|
||||
|
||||
## mod.json
|
||||
|
||||
Every mod starts with a single file, a `mod.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "com.example.my_mod",
|
||||
"name": "My Mod",
|
||||
"version": "1.0.0",
|
||||
"author": "Your Name",
|
||||
"description": "A short description shown in the mod manager.",
|
||||
"icon": "res/icon.png",
|
||||
"banner": "res/banner.png"
|
||||
}
|
||||
```
|
||||
|
||||
`id` is required: a unique, stable identifier (reverse-DNS style; periods, underscores, and lowercase alphanumerics).
|
||||
Everything else is optional but recommended.
|
||||
|
||||
`icon` and `banner` are bundle paths to PNG images that display in the in-game mod manager and mod website. A square
|
||||
icon (1:1), and a banner (~3.5:1, minimum 800px width). If omitted, `res/icon.png` and `res/banner.png` are used
|
||||
automatically when present.
|
||||
|
||||
Simply create a zip file with a `mod.json`, and rename it to `.dusk`. That's it!
|
||||
|
||||
---
|
||||
|
||||
## Asset-only Mods
|
||||
|
||||
```
|
||||
my_mod.dusk
|
||||
├── mod.json
|
||||
├── res/ (optional bundled resources)
|
||||
├── overlay/ (optional game file overrides)
|
||||
└── textures/ (optional texture replacements)
|
||||
```
|
||||
|
||||
Place files in `overlay/` to replace the disc version of that file. Examples:
|
||||
|
||||
- `overlay/Movie/demo_movie98_00.thp`: Replaces `Movie/demo_movie98_00.thp` on disc.
|
||||
- `overlay/res/Object/Kmdl/archive/bmwr/al.bmd`: Replaces `archive/bmwr/al.bmd` _within_ `res/Object/Kmdl.arc` without
|
||||
overwriting the entire `.arc`.
|
||||
|
||||
Place textures in `textures/` to automatically register them as texture replacements when active. These follow the same
|
||||
[Dolphin-compatible naming scheme](#textureservice-modssvctextureh) as the user `<data>/texture_replacements/`
|
||||
directory. Directories are scanned recursively. Examples:
|
||||
|
||||
- `textures/tex1_256x128_e6a4c7be9bf48305_14.dds`: Replaces the Hero's Clothes texture.
|
||||
|
||||
Simply zip the `mod.json` and adjacent folders, then rename to `.dusk`. Then, copy the `.dusk` into the user mods
|
||||
folder:
|
||||
|
||||
- Windows: `%APPDATA%\TwilitRealm\Dusklight\mods`
|
||||
- Linux: `~/.local/share/TwilitRealm/Dusklight/mods`
|
||||
- macOS: `~/Library/Application Support/TwilitRealm/Dusklight/mods`
|
||||
|
||||
---
|
||||
|
||||
## Native Mods
|
||||
|
||||
Mods built with [mod-template](https://github.com/TwilitRealm/mod-template) are native C++ mods. Native mods are very
|
||||
powerful and can interact with and [hook](#hooking-game-functions) game code directly. All features are available to
|
||||
native mods.
|
||||
|
||||
Example C++ mod:
|
||||
|
||||
```cpp
|
||||
#include "mods/service.hpp"
|
||||
#include "mods/svc/log.h"
|
||||
|
||||
DEFINE_MOD(); // once, in exactly one translation unit
|
||||
IMPORT_SERVICE(LogService, svc_log); // resolved by the loader before mod_initialize
|
||||
|
||||
extern "C" {
|
||||
|
||||
MOD_EXPORT ModResult mod_initialize(ModError* error) {
|
||||
svc_log->info(mod_ctx, "hello from my_mod");
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
MOD_EXPORT ModResult mod_update(ModError* error) { // called every frame
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
MOD_EXPORT ModResult mod_shutdown(ModError* error) {
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
When native mods are loaded, they get dynamically linked by the operating system to the running game process. The mod
|
||||
exports lifecycle functions that Dusklight calls into (`mod_initialize`, `mod_update`, `mod_shutdown`), and the mod
|
||||
communicates with the host via **services**: plain C APIs, individually versioned. Dusklight exports several built-in
|
||||
services, and mods may export services of their own, permitting framework mods and cross-mod integration.
|
||||
|
||||
Beyond services, mods have full access to the original game's code: include game headers, call directly into any public
|
||||
function, read and write data fields, and hook the vast majority of game functions.
|
||||
Beyond services, native mods have full access to the original game's code: include game headers, call directly into any
|
||||
public function, read and write data fields, and hook the vast majority of game functions.
|
||||
|
||||
## Table of Contents
|
||||
### Quick Start (Native Mods)
|
||||
|
||||
1. [Getting Started](#getting-started)
|
||||
2. [mod.json](#modjson)
|
||||
3. [Anatomy of a Code Mod](#anatomy-of-a-code-mod)
|
||||
4. [Services](#services)
|
||||
5. [Built-in Services](#built-in-services)
|
||||
6. [Hooking Game Functions](#hooking-game-functions)
|
||||
7. [Asset Overlays](#asset-overlays)
|
||||
8. [Runtime Lifecycle](#runtime-lifecycle)
|
||||
9. [Error Handling](#error-handling)
|
||||
10. [Advanced](#advanced)
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
Fork the [mod template](https://github.com/TwilitRealm/mod-template), a self-contained CMake project that uses the
|
||||
Dusklight mod SDK.
|
||||
Create a repository from
|
||||
the [mod-template](https://github.com/new?template_name=mod-template&template_owner=TwilitRealm),
|
||||
a self-contained CMake project that uses the Dusklight mod SDK. It includes a GitHub Actions CI workflow that builds the
|
||||
mod for every supported platform.
|
||||
|
||||
```
|
||||
my_mod/
|
||||
@@ -65,10 +167,12 @@ add_mod(my_mod
|
||||
|
||||
Available features:
|
||||
|
||||
- `fmt`: Provides the header-only `{fmt}` library and the formatted logging helpers in `mods/svc/log.hpp`.
|
||||
- `fmt`: Provides the header-only `{fmt}` library and the formatted logging helpers in
|
||||
[`mods/svc/log.hpp`](../sdk/include/mods/svc/log.hpp).
|
||||
- `game`: Allows calling into and hooking game code. Mods that **only** use services may omit it, providing a wider
|
||||
range of compatibility with Dusklight versions and a slightly faster build process.
|
||||
- `webgpu`: Allows importing the WebGPU API (`webgpu/webgpu.h`). Must be enabled when using
|
||||
- `webgpu`: Allows importing the WebGPU API
|
||||
([`webgpu/webgpu.h`](https://github.com/webgpu-native/webgpu-headers/blob/main/webgpu.h)). Must be enabled when using
|
||||
[GfxService](#gfxservice-modssvcgfxh).
|
||||
|
||||
Building produces `my_mod.dusk` in `build/mods/`. Copy the `.dusk` into the user mods folder:
|
||||
@@ -81,63 +185,101 @@ Passing `--mods <dir>` on the command line replaces the user directory with one
|
||||
|
||||
---
|
||||
|
||||
## mod.json
|
||||
## Script Mods
|
||||
|
||||
For simpler use cases where direct game code access and hooks aren't necessary, Luau mods are also supported.
|
||||
Luau mods do not need to be compiled, and are always supported on all platforms. However, they can only use services
|
||||
that are provided as Luau modules.
|
||||
|
||||
Mods can utilize Luau to add UI elements to their mod panel, use configuration variables, and dynamically swap out
|
||||
models/textures at runtime (e.g. to switch model variants or disable certain replacements) while remaining widely
|
||||
compatible.
|
||||
|
||||
Example mod structure:
|
||||
|
||||
```
|
||||
my_luau_mod.dusk
|
||||
├── mod.json
|
||||
└── res/
|
||||
├── main.luau
|
||||
└── lib/util.luau
|
||||
```
|
||||
|
||||
Set the `runtime` to `dev.twilitrealm.luau@1.0` in `mod.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "com.example.my_mod",
|
||||
"name": "My Mod",
|
||||
"id": "com.example.my_luau_mod",
|
||||
"name": "My Script Mod",
|
||||
"version": "1.0.0",
|
||||
"author": "Your Name",
|
||||
"description": "A short description shown in the mod manager.",
|
||||
"icon": "res/my_icon.png",
|
||||
"banner": "res/my_banner.png"
|
||||
"runtime": "dev.twilitrealm.luau@1.0"
|
||||
}
|
||||
```
|
||||
|
||||
`id` is required: a unique, stable identifier (reverse-DNS style; periods, underscores, and alphanumerics). Everything
|
||||
else is optional but recommended.
|
||||
`res/main.luau` runs once when the mod activates. Register optional update and shutdown callbacks through
|
||||
`dusklight.host`:
|
||||
|
||||
`icon` and `banner` are bundle-relative paths to PNG images for the in-game mod manager: the square icon (e.g.
|
||||
512x512), the banner (~3.5:1). If omitted, `res/icon.png` and `res/banner.png` are used automatically when present.
|
||||
|
||||
---
|
||||
|
||||
## Anatomy of a Code Mod
|
||||
|
||||
```cpp
|
||||
#include "mods/service.hpp"
|
||||
#include "mods/svc/log.h"
|
||||
|
||||
DEFINE_MOD(); // once, in exactly one translation unit
|
||||
IMPORT_SERVICE(LogService, svc_log); // resolved by the loader before mod_initialize
|
||||
|
||||
extern "C" {
|
||||
|
||||
MOD_EXPORT ModResult mod_initialize(ModError* error) {
|
||||
svc_log->info(mod_ctx, "hello from my_mod");
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
MOD_EXPORT ModResult mod_update(ModError* error) { // called every frame
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
MOD_EXPORT ModResult mod_shutdown(ModError* error) {
|
||||
return MOD_OK;
|
||||
}
|
||||
}
|
||||
```lua
|
||||
local host = require("dusklight.host")
|
||||
host.on_update(function()
|
||||
-- Runs every frame
|
||||
end)
|
||||
host.on_shutdown(function()
|
||||
-- Runs on mod deactivation
|
||||
end)
|
||||
```
|
||||
|
||||
All three lifecycle exports are required. `mod_ctx` is your mod's identity token, set by the loader before
|
||||
`mod_initialize` runs. Pass it as the first argument to every service call.
|
||||
Require script modules with `./` or `../` paths relative to the requiring file. The runtime appends `.luau` and rejects
|
||||
paths that escape `res/`.
|
||||
|
||||
The runtime provides these modules:
|
||||
|
||||
- `dusklight.log`: `write`, `trace`, `debug`, `info`, `warn`, and `error`.
|
||||
- `dusklight.host`: host `version`, mod metadata and directories, lifecycle callbacks, and `fail`.
|
||||
- `dusklight.config`: bool, integer, float, and string variables with `get`, `set`, and subscriptions.
|
||||
- `dusklight.resource`: binary-safe reads from the mod's `res/` tree.
|
||||
- `dusklight.overlay`: file and copied-buffer overlays with removable handles.
|
||||
- `dusklight.texture`: encoded-file and raw-data replacements with unregisterable handles.
|
||||
- `dusklight.ui`: Mods panels, controls, lists, windows, dialogs, styles, menu tabs, toasts, and clipboard access.
|
||||
|
||||
For completion and type checking, add `sdk/luau/dusklight.d.luau` to the `luau-lsp.types.definitionFiles` setting.
|
||||
|
||||
Configurable overlay example:
|
||||
|
||||
```lua
|
||||
local config = require("dusklight.config")
|
||||
local overlay = require("dusklight.overlay")
|
||||
|
||||
local hood = config.register({ name = "hood", type = "bool", default = true })
|
||||
local current
|
||||
|
||||
local function apply(enabled)
|
||||
if current then current:remove() end
|
||||
current = overlay.add_file("/res/Object/Alink.arc",
|
||||
enabled and "res/alink_hood.arc" or "res/alink_nohood.arc")
|
||||
end
|
||||
|
||||
hood:subscribe(apply)
|
||||
apply(hood:get())
|
||||
```
|
||||
|
||||
To create a script mod, copy `sdk/luau/template`, edit its manifest and source, then zip the `mod.json` and adjacent
|
||||
folders and rename to `.dusk`. Copy the `.dusk` into the user mods folder:
|
||||
|
||||
- Windows: `%APPDATA%\TwilitRealm\Dusklight\mods`
|
||||
- Linux: `~/.local/share/TwilitRealm/Dusklight/mods`
|
||||
- macOS: `~/Library/Application Support/TwilitRealm/Dusklight/mods`
|
||||
|
||||
**Restrictions:** The Luau VM has no raw filesystem, network, or game-code access. Each script mod has a 64 MiB memory
|
||||
limit. Calls are interrupted after 250 ms for updates and UI callbacks or 5 seconds for lifecycle calls. An uncaught
|
||||
error, timeout, or memory exhaustion fails and disables the mod.
|
||||
|
||||
---
|
||||
|
||||
## Services
|
||||
|
||||
A service is a struct of C function pointers with a version header. You declare what you use at file scope, and the
|
||||
loader resolves it before your mod initializes:
|
||||
A service is a struct of C function pointers with a version header. Import services at file scope, and the loader
|
||||
resolves them before initializing the mod:
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(LogService, svc_log); // required, latest minor version
|
||||
@@ -145,7 +287,7 @@ IMPORT_SERVICE_VERSION(LogService, svc_log, 0); // required, minimum minor ver
|
||||
IMPORT_OPTIONAL_SERVICE(SomeService, svc_maybe); // may be null
|
||||
```
|
||||
|
||||
A service must be imported in only **one** file (usually your `mod.cpp`). Other files may simply use `svc_log` or
|
||||
A service should be imported in only **one** file (usually your `mod.cpp`). Other files may simply use `svc_log` or
|
||||
`mods::log::` after including the appropriate header.
|
||||
|
||||
Each service is individually versioned, and there may be multiple major versions of a service provided at once,
|
||||
@@ -153,26 +295,19 @@ allowing backwards compatibility with older mods while still changing services f
|
||||
bump is a breaking change, treated as a different service entirely. For **additive** changes, a service appends new
|
||||
functions to the end of the struct without breaking existing callers and simply bumps the minor version.
|
||||
|
||||
`IMPORT_SERVICE` and `IMPORT_OPTIONAL_SERVICE` require the latest minor version compiled against, making every field in
|
||||
the service safe to call. A mod can use `IMPORT_SERVICE_VERSION` (or its optional counterpart) with an older minor
|
||||
version to remain compatible with older Dusklight versions, then use `SERVICE_HAS` to check at runtime for fields added
|
||||
after that explicitly requested version.
|
||||
|
||||
The contract (see `sdk/include/mods/api.h` for the full version):
|
||||
|
||||
- **A required import is guaranteed valid.** If the service is missing or too old, the mod fails to load with a clear
|
||||
error. No need to null check at call sites.
|
||||
- **Anything at or below the minor version you imported can be called unconditionally.** The default macros import
|
||||
the service type's current minor version; the versioned macros explicitly override that minimum.
|
||||
- Optional imports may be null; check once in `mod_initialize`.
|
||||
- Fields newer than your imported minor version must be gated behind `SERVICE_HAS(service, ServiceType, field)` plus a
|
||||
null check.
|
||||
`IMPORT_SERVICE` and `IMPORT_OPTIONAL_SERVICE` require the latest minor version compiled against, guaranteeing that
|
||||
every function is present. If a mod doesn't use (or may operate without) functions added in later minor versions, and
|
||||
wants to remain compatible with older Dusklight versions, it may use `IMPORT_SERVICE_VERSION` or
|
||||
`IMPORT_OPTIONAL_SERVICE_VERSION` to require an older minor version. It can then check `SERVICE_HAS` at runtime to see
|
||||
if a newer function is present (i.e. running on a new enough Dusklight version).
|
||||
|
||||
---
|
||||
|
||||
## Built-in Services
|
||||
|
||||
### LogService (`mods/svc/log.h`)
|
||||
### LogService ([`mods/svc/log.h`](../sdk/include/mods/svc/log.h))
|
||||
|
||||
**C++**
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(LogService, svc_log);
|
||||
@@ -183,9 +318,16 @@ svc_log->error(mod_ctx, "very bad");
|
||||
svc_log->write(mod_ctx, LOG_LEVEL_DEBUG, "verbose details");
|
||||
```
|
||||
|
||||
**Luau**
|
||||
|
||||
```lua
|
||||
local log = require("dusklight.log")
|
||||
log.info("spawned the thing")
|
||||
```
|
||||
|
||||
Messages appear in the console prefixed with your mod ID. Messages are plain UTF-8 strings and are copied before the
|
||||
call returns. C++ mods can enable `add_mod(... FEATURES fmt)` and use the formatted logging helpers in
|
||||
`mods/svc/log.hpp`:
|
||||
[`mods/svc/log.hpp`](../sdk/include/mods/svc/log.hpp):
|
||||
|
||||
```cpp
|
||||
#include <mods/svc/log.hpp>
|
||||
@@ -194,11 +336,13 @@ mods::log::info("spawned actor {} at ({}, {})", actorName, x, y);
|
||||
mods::log::warn("health is down to {:.1f}%", healthPercent);
|
||||
```
|
||||
|
||||
### ResourceService (`mods/svc/resource.h`)
|
||||
### ResourceService ([`mods/svc/resource.h`](../sdk/include/mods/svc/resource.h))
|
||||
|
||||
Loads files from the `res/` tree of your `.dusk` archive. Paths are relative to `res/` (pass `"config.txt"`, not
|
||||
`"res/config.txt"`); absolute paths and `..` are rejected.
|
||||
|
||||
**C++**
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(ResourceService, svc_resource);
|
||||
|
||||
@@ -209,10 +353,17 @@ if (svc_resource->load(mod_ctx, "config.txt", &buf) == MOD_OK) {
|
||||
}
|
||||
```
|
||||
|
||||
**Luau**
|
||||
|
||||
```lua
|
||||
local resource = require("dusklight.resource")
|
||||
local contents = resource.load("config.txt")
|
||||
```
|
||||
|
||||
Missing files return `MOD_UNAVAILABLE`. Always `free` what you `load`. The bundle is read-only; use
|
||||
`HostService::data_dir` for persistent storage.
|
||||
|
||||
### FileService (`mods/svc/file.h`)
|
||||
### FileService ([`mods/svc/file.h`](../sdk/include/mods/svc/file.h))
|
||||
|
||||
Provides file and folder pickers, file I/O, exports and folder enumeration.
|
||||
|
||||
@@ -257,9 +408,10 @@ mods::file::export_file(location, "report.txt", [](mods::file::PickResult result
|
||||
`export_file` copies an existing file to a user-selected destination and returns the destination location in its
|
||||
callback. Mod-owned persistent files belong in `HostService::data_dir`.
|
||||
|
||||
### HttpService (`mods/svc/http.h`)
|
||||
### HttpService ([`mods/svc/http.h`](../sdk/include/mods/svc/http.h))
|
||||
|
||||
Asynchronous HTTPS requests supporting HTTP/2 and TLS 1.2+. C++ mods should use the helpers in `mods/svc/http.hpp`:
|
||||
Asynchronous HTTPS requests supporting HTTP/2 and TLS 1.2+. C++ mods should use the helpers in
|
||||
[`mods/svc/http.hpp`](../sdk/include/mods/svc/http.hpp):
|
||||
|
||||
```cpp
|
||||
#include "mods/svc/http.hpp"
|
||||
@@ -299,9 +451,87 @@ For large responses, set `downloadPath` to an absolute path in the calling mod's
|
||||
an empty `body` and the final path in `downloadPath`. Check `Response::ok()` before using the file.
|
||||
`Pending::progress()` reports download progress when the server provides a total size.
|
||||
|
||||
### HostService (`mods/svc/host.h`)
|
||||
### WebSocketService ([`mods/svc/websocket.h`](../sdk/include/mods/svc/websocket.h))
|
||||
|
||||
Mod metadata and runtime interaction with the loader:
|
||||
WebSocket client connections with text or binary messages. Secure `wss://` URLs are supported everywhere. Insecure
|
||||
`ws://` is limited to `localhost`, `127.0.0.1`, and `[::1]`.
|
||||
|
||||
```cpp
|
||||
#include "mods/svc/websocket.hpp"
|
||||
|
||||
IMPORT_SERVICE(WebSocketService, svc_websocket);
|
||||
|
||||
mods::ws::Connection connection;
|
||||
|
||||
MOD_EXPORT ModResult mod_initialize(ModError*) {
|
||||
connection = mods::ws::connect({.url = "wss://example.com/events"});
|
||||
return connection ? MOD_OK : connection.result();
|
||||
}
|
||||
|
||||
MOD_EXPORT ModResult mod_update(ModError*) {
|
||||
mods::ws::Event event;
|
||||
while (mods::ws::poll(event)) {
|
||||
if (event.type == WEBSOCKET_EVENT_MESSAGE) {
|
||||
consume(event.data);
|
||||
} else if (event.type == WEBSOCKET_EVENT_CLOSED) {
|
||||
schedule_reconnect(event.error);
|
||||
}
|
||||
}
|
||||
return MOD_OK;
|
||||
}
|
||||
```
|
||||
|
||||
Keep the `Connection` alive and drain `mods::ws::poll()` regularly, usually on every `mod_update` tick. A connection
|
||||
emits an (optional) `OPEN` event, zero to many `MESSAGE` events, and exactly one `CLOSED` event.
|
||||
|
||||
**Restrictions:** A mod may only open four connections at once. Messages have a 1 MiB limit by default, and may request
|
||||
up to 16 MiB. Unread data is limited to 16 MiB and the outbound queue to 4 MiB. `send` returns `MOD_CONFLICT` when the
|
||||
outbound queue is full. Dropping the `Connection` or deactivating the mod attempts to gracefully close with code 1001,
|
||||
until the close deadline expires.
|
||||
|
||||
### NetService ([`mods/svc/net.h`](../sdk/include/mods/svc/net.h))
|
||||
|
||||
Asynchronous raw TCP and UDP networking. Endpoints can be `tcp://host:port` or `udp://host:port`. TCP connections and
|
||||
`resolve` accept hostnames. Listeners and UDP endpoints require IP literals.
|
||||
|
||||
```cpp
|
||||
#include "mods/svc/net.hpp"
|
||||
|
||||
IMPORT_SERVICE(NetService, svc_net);
|
||||
|
||||
mods::net::BindOutcome bound;
|
||||
mods::net::Socket listener;
|
||||
mods::net::Socket client;
|
||||
|
||||
MOD_EXPORT ModResult mod_initialize(ModError*) {
|
||||
listener = mods::net::listen("tcp://127.0.0.1:0", &bound);
|
||||
client = mods::net::connect(bound.local);
|
||||
return listener && client ? MOD_OK : MOD_ERROR;
|
||||
}
|
||||
|
||||
MOD_EXPORT ModResult mod_update(ModError*) {
|
||||
mods::net::Event event;
|
||||
while (mods::net::poll(event)) {
|
||||
if (event.type == NET_EVENT_ACCEPTED) {
|
||||
remember_client(mods::net::adopt(event.accepted));
|
||||
} else if (event.type == NET_EVENT_STREAM_DATA) {
|
||||
consume(event.data);
|
||||
}
|
||||
}
|
||||
return MOD_OK;
|
||||
}
|
||||
```
|
||||
|
||||
`send` and `send_to` copy the payload and return `MOD_CONFLICT` when the socket's outbound queue is full. `stats`
|
||||
reports queued bytes, traffic, dropped inbound datagrams, and asynchronous UDP send failures.
|
||||
|
||||
**Restrictions:** A mod may only have 32 streams, 4 listeners, 4 UDP sockets, and 8 DNS resolutions active at once.
|
||||
|
||||
### HostService ([`mods/svc/host.h`](../sdk/include/mods/svc/host.h))
|
||||
|
||||
Mod metadata and runtime interaction with the loader.
|
||||
|
||||
**C++**
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(HostService, svc_host);
|
||||
@@ -319,6 +549,20 @@ if (svc_host->data_dir(mod_ctx, &dataDir) == MOD_OK) {
|
||||
svc_host->fail(mod_ctx, MOD_ERROR, "something unrecoverable happened");
|
||||
```
|
||||
|
||||
**Luau**
|
||||
|
||||
```lua
|
||||
local host = require("dusklight.host")
|
||||
local dataDir = host.data_dir()
|
||||
host.on_update(function()
|
||||
-- Runs every frame
|
||||
end)
|
||||
host.on_shutdown(function()
|
||||
-- Runs on mod deactivation
|
||||
end)
|
||||
host.fail("something unrecoverable happened")
|
||||
```
|
||||
|
||||
`get_service`/`publish_service` provide dynamic service lookup; see [Exporting Services](#exporting-services).
|
||||
|
||||
**Lifecycle watches.** If your mod provides a service that hands out per-caller state (registrations, callbacks,
|
||||
@@ -341,17 +585,19 @@ svc_host->watch_mod_lifecycle(mod_ctx, on_mod_lifecycle, nullptr, &watch);
|
||||
`MOD_LIFECYCLE_DETACHED` fires on the game thread at a lifecycle safe point, after the subject's `mod_shutdown` ran and
|
||||
every service dropped its state. For your own mod's teardown, use `mod_shutdown` instead.
|
||||
|
||||
### HookService (`mods/svc/hook.h`)
|
||||
### HookService ([`mods/svc/hook.h`](../sdk/include/mods/svc/hook.h))
|
||||
|
||||
Installs hooks on game functions and resolves symbols by name. You'll rarely call it directly; use the typed helpers in
|
||||
`mods/svc/hook.hpp` described in [Hooking Game Functions](#hooking-game-functions).
|
||||
[`mods/svc/hook.hpp`](../sdk/include/mods/svc/hook.hpp) described in
|
||||
[Hooking Game Functions](#hooking-game-functions).
|
||||
|
||||
### OverlayService (`mods/svc/overlay.h`)
|
||||
### OverlayService ([`mods/svc/overlay.h`](../sdk/include/mods/svc/overlay.h))
|
||||
|
||||
Registers DVD file overlays at runtime: the dynamic counterpart to the static `overlay/` directory (see
|
||||
[Asset Overlays](#asset-overlays)). Overlay a disc path with a file from your bundle, a file within an archive,
|
||||
or with a caller-owned buffer
|
||||
(copied on registration):
|
||||
or with a caller-owned buffer (copied on registration).
|
||||
|
||||
**C++**
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(OverlayService, svc_overlay);
|
||||
@@ -363,6 +609,14 @@ svc_overlay->add_buffer(mod_ctx, "/generated.txt", data, size, nullptr);
|
||||
svc_overlay->remove(mod_ctx, handle);
|
||||
```
|
||||
|
||||
**Luau**
|
||||
|
||||
```lua
|
||||
local overlay = require("dusklight.overlay")
|
||||
local replacement = overlay.add_file("/Movie/demo_movie98_00.thp", "res/replacement.thp")
|
||||
replacement:remove()
|
||||
```
|
||||
|
||||
`disc_path` must be absolute (leading `/`) and is matched against the disc case-insensitively. Paths that don't exist
|
||||
on the disc are added as new files. Changes are applied at the next frame boundary, and data the game already read
|
||||
stays in memory until the file is re-read: sometimes a scene reload, and in the worst case, a full restart.
|
||||
@@ -372,11 +626,13 @@ data get refreshed without a full restart.
|
||||
|
||||
See [Asset Overlays](#asset-overlays) for priority and conflict handling.
|
||||
|
||||
### TextureService (`mods/svc/texture.h`)
|
||||
### TextureService ([`mods/svc/texture.h`](../sdk/include/mods/svc/texture.h))
|
||||
|
||||
Registers texture replacements at runtime: the dynamic counterpart to the static `textures/` directory (see
|
||||
[Asset Overlays](#asset-overlays)). Two forms: raw texel data with an explicit key, or an encoded `.dds`/`.png` from
|
||||
your bundle whose filename encodes the key:
|
||||
your bundle whose filename encodes the key.
|
||||
|
||||
**C++**
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(TextureService, svc_texture);
|
||||
@@ -397,6 +653,14 @@ svc_texture->register_data(mod_ctx, &key, &data, nullptr);
|
||||
svc_texture->unregister(mod_ctx, handle);
|
||||
```
|
||||
|
||||
**Luau**
|
||||
|
||||
```lua
|
||||
local texture = require("dusklight.texture")
|
||||
local replacement = texture.register_file("res/tex1_32x32_$_6.png")
|
||||
replacement:unregister()
|
||||
```
|
||||
|
||||
Filenames use the same Dolphin-style convention as the user's `texture_replacements` directory:
|
||||
`tex1_{w}x{h}_{texhash}[_{tluthash}]_{fmt}.dds|.png`, where hashes may be `$` (wildcard). `_mipN` sidecar files next to
|
||||
a registered file are picked up automatically. Files are decoded lazily on first use by the renderer; raw data is copied
|
||||
@@ -404,11 +668,13 @@ at registration. Registrations follow your mod's lifecycle.
|
||||
|
||||
See [Asset Overlays](#asset-overlays) for priority and conflict handling.
|
||||
|
||||
### ConfigService (`mods/svc/config.h`)
|
||||
### ConfigService ([`mods/svc/config.h`](../sdk/include/mods/svc/config.h))
|
||||
|
||||
Persistent, mod-scoped configuration variables. Each var is stored in the user's `config.json` under
|
||||
`mod.<escaped mod id>.<name>` (escaping: `.` → `_`, `_` → `__`, so `com.example.my_mod` becomes `com_example_my__mod`),
|
||||
next to the host's own settings:
|
||||
next to the host's own settings.
|
||||
|
||||
**C++**
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(ConfigService, svc_config);
|
||||
@@ -432,6 +698,17 @@ void on_speed_changed(ModContext* ctx, ConfigVarHandle var, const ConfigVarValue
|
||||
svc_config->subscribe(mod_ctx, var, on_speed_changed, nullptr, nullptr);
|
||||
```
|
||||
|
||||
**Luau**
|
||||
|
||||
```lua
|
||||
local config = require("dusklight.config")
|
||||
local speed = config.register({ name = "speedMultiplier", type = "float", default = 1.0 })
|
||||
speed:subscribe(function(value, previous)
|
||||
-- React to the new value.
|
||||
end)
|
||||
speed:set(2.0)
|
||||
```
|
||||
|
||||
Types: `CONFIG_VAR_BOOL` (`bool`), `CONFIG_VAR_INT` (`int64_t`), `CONFIG_VAR_FLOAT` (`double`), `CONFIG_VAR_STRING`
|
||||
(UTF-8; `get_string` copies into a caller buffer, pass a `NULL` buffer with size 0 to query the length). Accessors are
|
||||
typed and must match the registration.
|
||||
@@ -440,7 +717,7 @@ Change callbacks fire on the game thread whenever the value changes at runtime (
|
||||
Writes that store the same value are silent. Values applied from `config.json` or `--cvar` at registration do
|
||||
**not** fire callbacks; read the value after `register_var` for the starting state.
|
||||
|
||||
### SaveService (`mods/svc/save.h`)
|
||||
### SaveService ([`mods/svc/save.h`](../sdk/include/mods/svc/save.h))
|
||||
|
||||
Stores named binary blobs for each save slot. Blob names are scoped to the calling mod, and each mod may store up to
|
||||
`SAVE_BLOB_BUDGET_BYTES` per slot. The service copies data passed to `set_blob`.
|
||||
@@ -473,7 +750,7 @@ buffer contract as `get_blob`. Pass a `NULL` buffer to either read function to q
|
||||
are cleared. Observers are removed automatically when the mod is detached, so the output handle is only needed for
|
||||
manual unregistration. Save callbacks run on the game thread.
|
||||
|
||||
### StageService (`mods/svc/stage.h`)
|
||||
### StageService ([`mods/svc/stage.h`](../sdk/include/mods/svc/stage.h))
|
||||
|
||||
Allows making changes to a stage's "stage info" (contents of .dzs/.dzr files).
|
||||
(Currently only supports editing actor nodes.)
|
||||
@@ -522,7 +799,7 @@ Stage names may contain up to 8 characters. For patches and deletions, room `0xf
|
||||
layer; additions require a specific room. Edits are removed when the mod is detached. If multiple mods edit the same
|
||||
record, the later-loaded mod wins.
|
||||
|
||||
### UiService (`mods/svc/ui.h`)
|
||||
### UiService ([`mods/svc/ui.h`](../sdk/include/mods/svc/ui.h))
|
||||
|
||||
Integrate seamlessly with Dusklight's UI system: add controls and buttons to your mod's detail pane in the Mods window,
|
||||
create custom windows and modal dialogs, apply custom RCSS stylesheets (anywhere!), and add menu bar tabs.
|
||||
@@ -532,6 +809,8 @@ content is rebuilt, and `update` runs every frame while that mod is selected. Wh
|
||||
pane carries your mod's id as a `mod-id` attribute (like custom window roots), so scoped RCSS can target it (e.g.
|
||||
`[mod-id="com.example.mod"]`).
|
||||
|
||||
**C++**
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(UiService, svc_ui);
|
||||
|
||||
@@ -555,6 +834,18 @@ panel.update = update;
|
||||
svc_ui->register_mods_panel(mod_ctx, &panel);
|
||||
```
|
||||
|
||||
**Luau**
|
||||
|
||||
```lua
|
||||
local ui = require("dusklight.ui")
|
||||
ui.register_mods_panel({
|
||||
build = function(panel)
|
||||
panel:add_section("Status")
|
||||
panel:add_text("running")
|
||||
end,
|
||||
})
|
||||
```
|
||||
|
||||
Element setters must match the element kind: `elem_set_text`/`elem_set_rml` on text rows, and `elem_set_progress` on
|
||||
progress bars. `elem_set_class` sets or clears an RCSS class on any element handle, for styling via scoped or
|
||||
per-window RCSS. A non-`MOD_OK` result from `build`/`update` fails your mod, as do exceptions thrown from any UI
|
||||
@@ -704,7 +995,7 @@ existing documents restyle immediately, and future ones pick it up when created.
|
||||
host styles and may override them. Scope selectors tightly (use `[mod-id="..."]`!), especially for `UI_SCOPE_WINDOW`,
|
||||
unless changing host UI is intentional.
|
||||
|
||||
### WindowService (`mods/svc/window.h`)
|
||||
### WindowService ([`mods/svc/window.h`](../sdk/include/mods/svc/window.h))
|
||||
|
||||
Allows creating new windows that can be rendered to via `GfxService`.
|
||||
|
||||
@@ -724,12 +1015,13 @@ one present target may be attached to a WindowService window at a time.
|
||||
|
||||
New windows are hidden by default so a mod can finish attaching graphics before calling `show_window`.
|
||||
|
||||
### GfxService (`mods/svc/gfx.h`)
|
||||
### GfxService ([`mods/svc/gfx.h`](../sdk/include/mods/svc/gfx.h))
|
||||
|
||||
**Requires `add_mod(... FEATURES webgpu)`**
|
||||
|
||||
Direct WebGPU access at various stages of the rendering pipeline. Mods use the `wgpu*` C API (via `webgpu/webgpu.h`) for
|
||||
custom draws and compute dispatches. Mods must manage their own WebGPU state, including pipelines and bind groups.
|
||||
Direct WebGPU access at various stages of the rendering pipeline. Mods use the `wgpu*` C API (via
|
||||
[`webgpu/webgpu.h`](https://github.com/webgpu-native/webgpu-headers/blob/main/webgpu.h)) for custom draws and compute
|
||||
dispatches. Mods must manage their own WebGPU state, including pipelines and bind groups.
|
||||
|
||||
```cpp
|
||||
IMPORT_SERVICE(GfxService, svc_gfx);
|
||||
@@ -779,7 +1071,7 @@ To create a `WGPUSurface` manually, `GfxDeviceInfo` holds the `WGPUInstance` and
|
||||
`push_present` must be called every frame from a GfxService stage callback. If surface was lost, `push_present` returns
|
||||
`MOD_ERROR`. Unregister and re-register the target before trying again.
|
||||
|
||||
### CameraService (`mods/svc/camera.h`)
|
||||
### CameraService ([`mods/svc/camera.h`](../sdk/include/mods/svc/camera.h))
|
||||
|
||||
Converts a game view provided by a render callback into WebGPU-convention camera data. Matrix fields are column-major
|
||||
`float[16]` values using the matrix * column-vector convention (transpose of the game's row-major `Mtx`/`Mtx44` layout),
|
||||
@@ -801,7 +1093,7 @@ first in-game frame. Projection matrices match the renderer's WebGPU clip conven
|
||||
Camera operators allow overriding the main camera. When an operator callback returns true, its values replace the camera
|
||||
state for the current frame. Register and unregister using `register_camera_operator` / `unregister_camera_operator`.
|
||||
|
||||
### GameModeService (`mods/svc/game_mode.h`)
|
||||
### GameModeService ([`mods/svc/game_mode.h`](../sdk/include/mods/svc/game_mode.h))
|
||||
|
||||
Allows a mod to register a game mode with callbacks for key gameplay and save lifecycle events. Registered game modes
|
||||
appear in the prelaunch menu. Game modes may use a unique set of saves by configuring `save_name`; leave it empty to use
|
||||
@@ -920,6 +1212,82 @@ svc_game_mode->register_game_mode(mod_ctx, &gameModeDesc);
|
||||
|
||||
```
|
||||
|
||||
### ActorService (`mods/svc/actor.h`)
|
||||
|
||||
A service that manages registering and creating custom actors. These actors will be run by the game as if they are part of the engine. These actors can be created by the game either by its 16-bit actor name, or a 7-character long name that can
|
||||
be loaded by a stage.
|
||||
|
||||
```cpp
|
||||
#include "mods/svc/actor.h"
|
||||
IMPORT_SERVICE(ActorService, svc_actor);
|
||||
|
||||
class myActor_c : public fopAc_ac_c {};
|
||||
|
||||
int myActor_Create(void* i_this) {
|
||||
// Ran several times, until it returns cPhs_COMPLEATE_e to allow for async loading
|
||||
return cPhs_COMPLEATE_e;
|
||||
}
|
||||
|
||||
int myActor_Delete(void* i_this) {
|
||||
// Free resources here
|
||||
return 1;
|
||||
}
|
||||
|
||||
int myActor_Execute(void* i_this) {
|
||||
// Ran once per game tick
|
||||
return 1;
|
||||
}
|
||||
|
||||
int myActor_IsDelete(void* i_this) {
|
||||
// Returns 1 when the actor can be deleted
|
||||
return 1;
|
||||
}
|
||||
|
||||
int myActor_Draw(void* i_this) {
|
||||
// Code to draw the actor
|
||||
return 1;
|
||||
}
|
||||
|
||||
s16 actor_name; // The process name that can be used by the game to load the actor
|
||||
ActorHandle actor_handle;
|
||||
ActorProfileDesc profDesc = {
|
||||
.name = "AUnique", // The name used by the stage loader to load the actor with.
|
||||
// It has a character limit of 7 and must be unique among active
|
||||
// mod actors. Matching a game actor name overrides stage lookup.
|
||||
.priority_group = 7, // When, relative to other actors _Execute should run
|
||||
// See: mods/svc/actor.h
|
||||
.process_size = sizeof(myActor_c),
|
||||
.draw_priority = fpcDwPi_OBJ_LBOX_e, // Defines when the actor should be drawn relative
|
||||
// to other actors (see f_pc_draw_priority.h)
|
||||
.status = fopAcStts_CULL_e | fopAcStts_UNK_0x4000_e | fopAcStts_UNK_0x40000_e,
|
||||
.group = fopAc_ACTOR_e, // Can be fopAc_ACTOR_e, fopAc_PLAYER_e, fopAc_ENEMY_e, or fopAc_NPC_e
|
||||
.cull_type = fopAc_CULLBOX_CUSTOM_e,
|
||||
.create_function = myActor_Create,
|
||||
.delete_function = myActor_Delete,
|
||||
.execute_function = myActor_Execute,
|
||||
.is_delete_function = myActor_IsDelete,
|
||||
.draw_function = myActor_Draw,
|
||||
};
|
||||
svc_actor->register_actor(mod_ctx, &profDesc, &actor_name, &actor_handle);
|
||||
|
||||
// Spawn the actor at the player's position
|
||||
fopAc_ac_c* plr = dComIfGp_getPlayer(0);
|
||||
if (plr) {
|
||||
ActorSpawnParams spawnParams = {
|
||||
.parameters = 0,
|
||||
.argument = 0,
|
||||
.room_num = fopAcM_GetRoomNo(plr),
|
||||
.position = {plr->current.pos.x, plr->current.pos.y, plr->current.pos.z},
|
||||
.angle = {plr->current.angle.x, plr->current.angle.y, plr->current.angle.z},
|
||||
.scale = {1.0f, 1.0f, 1.0f}
|
||||
};
|
||||
ActorId created_actor_id;
|
||||
svc_actor->create_actor(mod_ctx, actor_name, &spawnParams, &created_actor_id);
|
||||
}
|
||||
```
|
||||
|
||||
See `mods/custom_actor_demo` for a more complete example.
|
||||
|
||||
---
|
||||
|
||||
## Hooking Game Functions
|
||||
@@ -927,7 +1295,7 @@ svc_game_mode->register_game_mode(mod_ctx, &gameModeDesc);
|
||||
**Requires `add_mod(... FEATURES game)`**
|
||||
|
||||
Mods may hook the vast majority of game functions, including file-local static, private and virtual functions.
|
||||
`mods/svc/hook.hpp` provides typed helpers over the hook service:
|
||||
[`mods/svc/hook.hpp`](../sdk/include/mods/svc/hook.hpp) provides typed helpers over the hook service:
|
||||
|
||||
```cpp
|
||||
#include "mods/svc/hook.hpp"
|
||||
|
||||
Vendored
+1
-1
Submodule extern/aurora updated: f8573d34e6...749d6ee7a2
Vendored
+1
-1
Submodule extern/borealis updated: 4b76f9ea35...f55910bd79
+9
-1
@@ -1432,7 +1432,6 @@ set(DUSK_FILES
|
||||
src/dusk/dvd_asset.cpp
|
||||
src/dusk/dvd_asset.hpp
|
||||
src/dusk/extras.c
|
||||
src/dusk/frame_interpolation.cpp
|
||||
src/dusk/commands.cpp
|
||||
src/dusk/commands.hpp
|
||||
src/dusk/game_clock.cpp
|
||||
@@ -1462,6 +1461,10 @@ set(DUSK_FILES
|
||||
src/dusk/imgui/ImGuiStateShare.cpp
|
||||
src/dusk/imgui/ImGuiStateShare.hpp
|
||||
src/dusk/imgui/ImGuiStubLog.cpp
|
||||
src/dusk/interp/camera.cpp
|
||||
src/dusk/interp/dual_buffer.cpp
|
||||
src/dusk/interp/frame_interpolation.cpp
|
||||
src/dusk/interp/line.cpp
|
||||
src/dusk/io.cpp
|
||||
src/dusk/iso_validate.cpp
|
||||
src/dusk/language.cpp
|
||||
@@ -1483,12 +1486,14 @@ set(DUSK_FILES
|
||||
src/dusk/mods/loader/prepatch.cpp
|
||||
src/dusk/mods/loader/prepatch.hpp
|
||||
src/dusk/mods/item.hpp
|
||||
src/dusk/mods/item_actor.cpp
|
||||
src/dusk/mods/item_checks.cpp
|
||||
src/dusk/mods/item_gives.cpp
|
||||
src/dusk/mods/log_buffer.cpp
|
||||
src/dusk/mods/log_buffer.hpp
|
||||
src/dusk/mods/manifest.cpp
|
||||
src/dusk/mods/manifest.hpp
|
||||
src/dusk/mods/svc/actor.cpp
|
||||
src/dusk/mods/svc/camera.cpp
|
||||
src/dusk/mods/svc/config.cpp
|
||||
src/dusk/mods/svc/config.hpp
|
||||
@@ -1499,6 +1504,9 @@ set(DUSK_FILES
|
||||
src/dusk/mods/svc/hook.cpp
|
||||
src/dusk/mods/svc/host.cpp
|
||||
src/dusk/mods/svc/http.cpp
|
||||
src/dusk/mods/svc/net.cpp
|
||||
src/dusk/mods/svc/net.hpp
|
||||
src/dusk/mods/svc/websocket.cpp
|
||||
src/dusk/mods/svc/item.cpp
|
||||
src/dusk/mods/svc/item.hpp
|
||||
src/dusk/mods/svc/log.cpp
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "f_pc/f_pc_base.h"
|
||||
#include "SSystem/SComponent/c_bg_s_grp_pass_chk.h"
|
||||
#include "SSystem/SComponent/c_bg_s_poly_pass_chk.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
struct cBgD_Vtx_t : public Vec {};
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define C_M3D_G_TRI_H_
|
||||
|
||||
#include "SSystem/SComponent/c_m3d_g_pla.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
class cM3dGCyl;
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ public:
|
||||
bool update(s32 chan);
|
||||
void bzeroBuffer(s32 chan);
|
||||
|
||||
private:
|
||||
/* 0x00 */ s16* mBuffer[4];
|
||||
};
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ public:
|
||||
static bool checkRadioSensitivity(s32 chan);
|
||||
static bool isSubmitPlayByRadioSensitivity(s32 chan);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif /* Z2AUDIOCS_SPKSPEAKERCTRL_H */
|
||||
|
||||
@@ -28,7 +28,6 @@ public:
|
||||
inline SpkData* getData(void) const { return mData; }
|
||||
inline SpkMixingBuffer* getMixingBuffer(void) const { return mMixingBuffer; }
|
||||
|
||||
private:
|
||||
/* 0x00 */ JKRHeap* mHeap;
|
||||
/* 0x04 */ SpkData* mData;
|
||||
/* 0x08 */ SpkMixingBuffer* mMixingBuffer;
|
||||
|
||||
@@ -31,7 +31,6 @@ public:
|
||||
return (SpkTableParams*)mEntryOffset + num;
|
||||
}
|
||||
|
||||
// private:
|
||||
/* 0x00 */ bool mIsInitialized;
|
||||
/* 0x04 */ s32 mNumOfSound;
|
||||
/* 0x08 */ u32 mEntryOffset;
|
||||
|
||||
@@ -25,7 +25,6 @@ public:
|
||||
inline const void* getResource(void) const { return mWaveData; }
|
||||
inline void* getResource(void) { return mWaveData; }
|
||||
|
||||
private:
|
||||
/* 0x00 */ void* mWaveData;
|
||||
};
|
||||
|
||||
|
||||
@@ -67,7 +67,6 @@ public:
|
||||
void playVoice(int);
|
||||
virtual Z2SoundHandlePool* startCreatureVoice(JAISoundID soundID, s8 reverb);
|
||||
|
||||
private:
|
||||
/* 0xA0 */ s8 mCitizenID;
|
||||
/* 0xA1 */ s8 field_0xa1;
|
||||
/* 0xA2 */ bool mLinkSearch;
|
||||
|
||||
@@ -63,7 +63,6 @@ public:
|
||||
friend class Z2LinkSoundStarter;
|
||||
friend struct Z2RideSoundStarter;
|
||||
|
||||
private:
|
||||
/* 0x90 Z2LinkSoundStarter */
|
||||
/* 0x94 */ Z2SoundObjSimple mKantera;
|
||||
/* 0xB4 */ Vec field_0xb4;
|
||||
@@ -123,7 +122,6 @@ public:
|
||||
|
||||
virtual void deleteObject();
|
||||
|
||||
private:
|
||||
/* 0x90 */ // Z2RideSoundStarter mSoundStarter;
|
||||
/* 0x98 */ bool mLinkRiding;
|
||||
}; // Size: 0x9C
|
||||
@@ -136,7 +134,6 @@ public:
|
||||
Z2SoundHandlePool* startFireSound(u16);
|
||||
Z2SoundHandlePool* startSound(JAISoundID soundID, u32 mapinfo, s8 reverb);
|
||||
|
||||
private:
|
||||
/* 0x20 */ f32 field_0x20;
|
||||
};
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@ public:
|
||||
s32 getBgmLoadStatus(u32 wave) { return getWaveLoadStatus(wave, 1); }
|
||||
u8 getDemoSeWaveNum() { return loadedDemoWave; }
|
||||
|
||||
private:
|
||||
/* 0x00 */ JAISoundID BGM_ID;
|
||||
/* 0x04 */ int sceneNum;
|
||||
/* 0x08 */ int timer;
|
||||
|
||||
@@ -84,7 +84,6 @@ public:
|
||||
void homeMenuSeCallback(s32);
|
||||
#endif
|
||||
|
||||
private:
|
||||
/* 0x000 */ JAISoundHandle mSoundHandle[24];
|
||||
/* 0x060 */ JAISoundHandles mSoundHandles;
|
||||
#if VERSION >= VERSION_WII_USA_R0
|
||||
|
||||
@@ -44,7 +44,6 @@ public:
|
||||
return (Z2SoundHandlePool*)getNth(index);
|
||||
}
|
||||
|
||||
private:
|
||||
/* 0xC */ u8 handleNum_;
|
||||
};
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ public:
|
||||
const JAISeqMgr* getSeqMgr() const { return &seqMgr_; }
|
||||
JAIStreamMgr* getStreamMgr() { return &streamMgr_; }
|
||||
|
||||
private:
|
||||
/* 0x004 */ JAISeMgr seMgr_;
|
||||
/* 0x728 */ JAISeqMgr seqMgr_;
|
||||
/* 0x79C */ JAIStreamMgr streamMgr_;
|
||||
|
||||
@@ -104,7 +104,6 @@ public:
|
||||
JSUList<Z2SoundObjBase>* getAllList() { return &allList_; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
/* 0x00 */ JSUList<Z2CreatureEnemy> field_0x0;
|
||||
#if PARTIAL_DEBUG || DEBUG
|
||||
/* 0x0C */ JSUList<Z2SoundObjBase> allList_;
|
||||
|
||||
@@ -70,7 +70,6 @@ public:
|
||||
u8 getReleaseTimer() { return mReleaseTimer; }
|
||||
u8 getCorrectCurveID() { return mCorrectCurveID; }
|
||||
|
||||
private:
|
||||
/* 0x00 */ JAISoundHandle mWolfHowlHandle;
|
||||
/* 0x04 */ JAISoundHandle mWindStoneHandle;
|
||||
/* 0x08 */ JAISoundHandle mGuideHandle;
|
||||
|
||||
@@ -77,7 +77,6 @@ public:
|
||||
virtual void draw();
|
||||
virtual ~daAlink_blur_c() {}
|
||||
|
||||
// private:
|
||||
/* 0x010 */ ResTIMG* m_blurTex;
|
||||
/* 0x014 */ int field_0x14;
|
||||
/* 0x018 */ u8 field_0x18[4];
|
||||
@@ -113,7 +112,6 @@ public:
|
||||
|
||||
void onAppearFlg() { mAppearFlg = true; }
|
||||
|
||||
private:
|
||||
/* 0x04 */ s16 mHitFlg;
|
||||
/* 0x06 */ s16 mAppearFlg;
|
||||
/* 0x08 */ f32 mKeepMinY;
|
||||
@@ -4558,30 +4556,8 @@ public:
|
||||
bool checkAimContext();
|
||||
bool checkAimInputContext();
|
||||
|
||||
void onIronBallChainInterpCallback();
|
||||
|
||||
static const int IRON_BALL_CHAIN_COUNT = 102;
|
||||
cXyz mIBChainInterpPrevPos[IRON_BALL_CHAIN_COUNT];
|
||||
cXyz mIBChainInterpCurrPos[IRON_BALL_CHAIN_COUNT];
|
||||
csXyz mIBChainInterpPrevAngle[IRON_BALL_CHAIN_COUNT];
|
||||
csXyz mIBChainInterpCurrAngle[IRON_BALL_CHAIN_COUNT];
|
||||
cXyz mIBChainInterpPrevHandRoot;
|
||||
cXyz mIBChainInterpCurrHandRoot;
|
||||
bool mIBChainInterpPrevValid;
|
||||
bool mIBChainInterpCurrValid;
|
||||
|
||||
cXyz mHsChainInterpPrevTop;
|
||||
cXyz mHsChainInterpCurrTop;
|
||||
cXyz mHsChainInterpPrevRoot;
|
||||
cXyz mHsChainInterpCurrRoot;
|
||||
cXyz mHsChainInterpPrevSubRoot;
|
||||
cXyz mHsChainInterpCurrSubRoot;
|
||||
cXyz mHsChainInterpPrevSubTop;
|
||||
cXyz mHsChainInterpCurrSubTop;
|
||||
bool mHsChainInterpPrevValid;
|
||||
bool mHsChainInterpCurrValid;
|
||||
|
||||
bool mIsRollstab = false;
|
||||
void* mAnmBuffers[3] = {};
|
||||
#endif
|
||||
}; // Size: 0x385C
|
||||
|
||||
|
||||
@@ -110,7 +110,6 @@ public:
|
||||
|
||||
void setModelMatrix(MtxP mtx) { mpModel->setBaseTRMtx(mtx); }
|
||||
|
||||
private:
|
||||
/* 0x568 */ J3DModel* mpModel;
|
||||
/* 0x56C */ dBgS_ArrowLinChk field_0x56c;
|
||||
/* 0x5DC */ dBgS_ObjLinChk field_0x5dc;
|
||||
|
||||
@@ -82,7 +82,6 @@ public:
|
||||
u8 onTarget() { return mTarget = true; }
|
||||
u8 isBack() { return arg0; }
|
||||
|
||||
private:
|
||||
/* 0x05AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x05B4 */ mDoExt_McaMorfSO* mpModelMorf;
|
||||
/* 0x05B8 */ J3DModel* mpPartModel;
|
||||
|
||||
@@ -189,7 +189,6 @@ public:
|
||||
void onDemo() { mIsDemo = true; }
|
||||
void offDemo() { mIsDemo = false; }
|
||||
|
||||
private:
|
||||
/* 0x05AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x05B4 */ mDoExt_McaMorfSO* mpMorf;
|
||||
/* 0x05B8 */ mDoExt_McaMorfSO* mpSwordMorf;
|
||||
|
||||
@@ -189,12 +189,6 @@ public:
|
||||
/* 0x2740 */ u8 field_0x2740;
|
||||
/* 0x2744 */ dMsgFlow_c mMsgFlow;
|
||||
#if TARGET_PC
|
||||
cXyz mReinsInterpPrev[2][16];
|
||||
cXyz mReinsInterpCurr[2][16];
|
||||
cXyz mReinsTexInterpPrev[2];
|
||||
cXyz mReinsTexInterpCurr[2];
|
||||
bool mReinsInterpPrevValid;
|
||||
bool mReinsInterpCurrValid;
|
||||
s8 mDemoCamSyncTicks;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -92,7 +92,6 @@ public:
|
||||
bool isDown() { return mDownFlag != 0; }
|
||||
bool isAppear() { return mAppearFlag != 0; }
|
||||
|
||||
private:
|
||||
/* 0x05AC */ request_of_phase_process_class mMgnPhase;
|
||||
/* 0x05B4 */ request_of_phase_process_class mMgnePhase;
|
||||
/* 0x05BC */ mDoExt_McaMorfSO* mpMgnModelMorf;
|
||||
|
||||
@@ -131,7 +131,6 @@ public:
|
||||
int CreateHeap();
|
||||
int create();
|
||||
|
||||
private:
|
||||
/* 0x05AC */ request_of_phase_process_class mPhaseReq1;
|
||||
/* 0x05B4 */ request_of_phase_process_class mPhaseReq2;
|
||||
/* 0x05BC */ J3DModel* mpPartModels[16];
|
||||
|
||||
@@ -80,7 +80,6 @@ public:
|
||||
void setDrawOff() { mIsInactive = 1; }
|
||||
bool isEnemyDemoEnd() { return (u8)mIsEnemyDemoEnd != 0; }
|
||||
|
||||
private:
|
||||
/* 0x05AC */ request_of_phase_process_class mPhase1;
|
||||
/* 0x05B4 */ request_of_phase_process_class mPhase2;
|
||||
/* 0x05BC */ request_of_phase_process_class mPhase3;
|
||||
|
||||
@@ -51,7 +51,6 @@ public:
|
||||
|
||||
void setSubNumber(int i_subNumber) { mSubNumber = i_subNumber; }
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x5B4 */ J3DModel* mpModel;
|
||||
/* 0x5B8 */ Z2Creature mCreatureSound;
|
||||
|
||||
@@ -24,7 +24,6 @@ public:
|
||||
int _delete();
|
||||
int create();
|
||||
|
||||
private:
|
||||
/* 0x5AC */ Mtx field_0x5ac;
|
||||
/* 0x5DC */ cXyz field_0x5dc;
|
||||
/* 0x5E8 */ f32 field_0x5e8;
|
||||
|
||||
@@ -33,7 +33,6 @@ public:
|
||||
bool isSearchContinue() { return mSearchContinue != false; }
|
||||
void offSearchContinue() { mSearchContinue = false; }
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x5B4 */ mDoExt_McaMorfSO* mpMorf;
|
||||
/* 0x5B8 */ mDoExt_brkAnm* mpBrk;
|
||||
|
||||
@@ -57,7 +57,6 @@ public:
|
||||
inline int execute();
|
||||
inline int isDelete();
|
||||
|
||||
private:
|
||||
/* 0x568 */ u8 field_0x568[0x570 - 0x568];
|
||||
/* 0x570 */ daBg_Part mBgParts[6];
|
||||
/* 0x5E8 */ dBgW* mpBgW;
|
||||
|
||||
@@ -25,7 +25,6 @@ public:
|
||||
void onReserve() { mReserve = 1; }
|
||||
void offReserve() { mReserve = 0; }
|
||||
|
||||
private:
|
||||
/* 0x04 */ J2DScreen* m_cursorYellowScrn;
|
||||
/* 0x08 */ J2DPane* m_cursorYellowAllPane;
|
||||
/* 0x0C */ J2DPane* m_cursorYellow0Pane;
|
||||
@@ -126,7 +125,6 @@ public:
|
||||
bool getLockCntMax() { return m_lockCnt >= BOOMERANG_LOCK_MAX; }
|
||||
void onLockDistanceCancel() { onStateFlg0(FLG0_LOCK_DIST_CANCEL); }
|
||||
|
||||
private:
|
||||
/* 0x568 */ J3DModel* mp_boomModel;
|
||||
/* 0x56C */ J3DModel* mp_shippuModel;
|
||||
/* 0x570 */ J3DAnmTextureSRTKey* m_windBtk;
|
||||
|
||||
@@ -65,7 +65,6 @@ public:
|
||||
field_0x1456 = 15;
|
||||
}
|
||||
|
||||
private:
|
||||
/* 0x0568 */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x0570 */ J3DModel* mpModel;
|
||||
/* 0x0574 */ J3DModel* mpPaddleModel;
|
||||
|
||||
@@ -42,7 +42,6 @@ public:
|
||||
void setNoHitTimer() { noHitTimer = 20; }
|
||||
inline int execute();
|
||||
|
||||
private:
|
||||
/* 0x568 */ LIGHT_INFLUENCE mLightInfluence;
|
||||
/* 0x588 */ dCcD_Stts mStts;
|
||||
/* 0x5C4 */ dCcD_Sph mSph;
|
||||
|
||||
@@ -208,7 +208,6 @@ public:
|
||||
u8 getCowIn() { return mCowIn; }
|
||||
u8 getNoNearCheckTimer() { return mNoNearCheckTimer; }
|
||||
|
||||
private:
|
||||
/* 0x568 */ u16 mFlags;
|
||||
/* 0x56c */ request_of_phase_process_class mPhase;
|
||||
/* 0x574 */ mDoExt_McaMorfSO* mpMorf;
|
||||
|
||||
@@ -48,7 +48,6 @@ public:
|
||||
static f32 getFlyInitY() { return 40.0f; }
|
||||
static f32 getFlyInitZ() { return 50.0f; }
|
||||
|
||||
private:
|
||||
/* 0x568 */ J3DModel* mpBallModel;
|
||||
/* 0x56C */ mDoExt_bckAnm mBck;
|
||||
/* 0x588 */ J3DAnmTevRegKey* mpBallBrk;
|
||||
|
||||
@@ -40,7 +40,6 @@ public:
|
||||
};
|
||||
static DUSK_GAME_DATA const BckTbl m_bckIdxTable[];
|
||||
|
||||
private:
|
||||
/* 0x5A0 */ const char* m_arcName;
|
||||
/* 0x5A4 */ request_of_phase_process_class m_phase;
|
||||
/* 0x5AC */ J3DModel* mp_model;
|
||||
|
||||
@@ -101,7 +101,6 @@ public:
|
||||
|
||||
static DUSK_GAME_DATA u16 const m_bckIdxTable[daCstatueType_N][7];
|
||||
|
||||
private:
|
||||
/* 0x568 */ const char* mResName;
|
||||
/* 0x56C */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x574 */ J3DModel* mModel;
|
||||
|
||||
@@ -55,7 +55,6 @@ public:
|
||||
void setOffsetPos(cXyz i_pos) { mOffsetPos = i_pos; }
|
||||
void setMaxScale(f32 i_scale) { mMaxScale = i_scale; }
|
||||
|
||||
private:
|
||||
/* 0x92C */ cXyz mOffsetPos;
|
||||
/* 0x938 */ f32 mMaxScale;
|
||||
/* 0x93C */ u8 field_0x93c;
|
||||
|
||||
@@ -50,7 +50,6 @@ public:
|
||||
|
||||
void setAction(u8 i_action) { mAction = i_action; }
|
||||
|
||||
private:
|
||||
/* 0x568 */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x570 */ J3DModel* mpDoorModel;
|
||||
/* 0x574 */ J3DModel* mpLockModel;
|
||||
|
||||
@@ -76,7 +76,6 @@ public:
|
||||
|
||||
void setAction(u8 action) { mAction = action; }
|
||||
|
||||
private:
|
||||
/* 0x568 */ request_of_phase_process_class mPhase1;
|
||||
/* 0x570 */ request_of_phase_process_class mPhase2;
|
||||
/* 0x578 */ request_of_phase_process_class mPhase3;
|
||||
|
||||
@@ -72,7 +72,6 @@ public:
|
||||
return 1;
|
||||
}
|
||||
|
||||
private:
|
||||
/* 0x568 */ request_of_phase_process_class mPhase1;
|
||||
/* 0x570 */ request_of_phase_process_class mPhase2;
|
||||
/* 0x578 */ request_of_phase_process_class mPhase3;
|
||||
|
||||
@@ -41,7 +41,6 @@ public:
|
||||
|
||||
void setAction(u8 i_action) { mAction = i_action; }
|
||||
|
||||
// private:
|
||||
/* 0x568 */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x570 */ request_of_phase_process_class mPhaseReq2;
|
||||
/* 0x578 */ J3DModel* mpModel;
|
||||
|
||||
@@ -73,7 +73,6 @@ public:
|
||||
void onFlag(u16 flag) { field_0x60c |= flag; }
|
||||
int checkFlag(u16 flag) { return field_0x60c & flag; }
|
||||
|
||||
private:
|
||||
/* 0x568 */ request_of_phase_process_class mPhase1;
|
||||
/* 0x570 */ request_of_phase_process_class mPhase2;
|
||||
/* 0x578 */ J3DModel* mModel1;
|
||||
|
||||
@@ -121,7 +121,6 @@ public:
|
||||
mAction = action;
|
||||
}
|
||||
|
||||
private:
|
||||
/* 0x568 */ request_of_phase_process_class mPhase1;
|
||||
/* 0x570 */ request_of_phase_process_class mPhase2;
|
||||
/* 0x578 */ request_of_phase_process_class mPhase3;
|
||||
|
||||
@@ -49,7 +49,6 @@ public:
|
||||
void setAction(u8 i_action) { mAction = i_action; }
|
||||
u32 getSceneNo() { return fopAcM_GetParamBit(this, 4, 6); }
|
||||
|
||||
// private:
|
||||
/* 0x5A0 */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x5A8 */ J3DModel* mpModel[2];
|
||||
/* 0x5B0 */ dBgW* mpDoorBgW;
|
||||
|
||||
@@ -123,7 +123,6 @@ public:
|
||||
bool checkFlag(u16 flag) { return field_0x68e & flag; }
|
||||
void setAction(u8 action) { mAction = action; }
|
||||
|
||||
private:
|
||||
/* 0x56C */ request_of_phase_process_class mPhase1;
|
||||
/* 0x574 */ request_of_phase_process_class mPhase2;
|
||||
/* 0x57C */ J3DModel* mModel1;
|
||||
|
||||
@@ -48,7 +48,6 @@ public:
|
||||
int CreateHeap();
|
||||
int Create();
|
||||
|
||||
private:
|
||||
/* 0x5AC */ JPABaseEmitter* mpEmitter;
|
||||
/* 0x5B0 */ request_of_phase_process_class m_phase;
|
||||
/* 0x5B8 */ u8 field_0x5b8;
|
||||
|
||||
@@ -45,7 +45,6 @@ public:
|
||||
void setBgId(unsigned int i_bgId) { mBgId = i_bgId; }
|
||||
bool isBomb() { return mIsBomb; }
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x5B4 */ mDoExt_McaMorfSO* mpMorfSO;
|
||||
/* 0x5B8 */ mDoExt_brkAnm* mpBrkAnm;
|
||||
|
||||
@@ -80,12 +80,6 @@ public:
|
||||
/* 0x125C */ u32 field_0x125c;
|
||||
/* 0x1260 */ u8 field_0x1260[0x126C - 0x1260];
|
||||
/* 0x126C */ u8 HIOInit;
|
||||
#if TARGET_PC
|
||||
cXyz mStalkLineInterpPrev[12];
|
||||
cXyz mStalkLineInterpCurr[12];
|
||||
bool mStalkLineInterpPrevValid;
|
||||
bool mStalkLineInterpCurrValid;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(e_db_class) == 0x1270);
|
||||
|
||||
@@ -45,7 +45,6 @@ public:
|
||||
int create();
|
||||
daE_DK_c();
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x5B4 */ mDoExt_McaMorfSO* mpMorfSO;
|
||||
/* 0x5B8 */ mDoExt_McaMorfSO* mpCoreMorfSO;
|
||||
|
||||
@@ -83,7 +83,6 @@ public:
|
||||
MtxP getBackMtx() { return mpMorf->getModel()->getAnmMtx(1); }
|
||||
fpc_ProcID getDemoId() { return mDemoID; }
|
||||
|
||||
private:
|
||||
/* 0x05AC */ request_of_phase_process_class mPhase[3];
|
||||
/* 0x05C4 */ J3DModel* mpChestModel;
|
||||
/* 0x05C8 */ J3DModel* mpSpitModel;
|
||||
|
||||
@@ -40,7 +40,6 @@ public:
|
||||
cPhs_Step create();
|
||||
daE_FB_c();
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x5B4 */ mDoExt_McaMorfSO* mpMorf;
|
||||
/* 0x5B8 */ mDoExt_invisibleModel mInvisibleModel;
|
||||
|
||||
@@ -52,7 +52,6 @@ public:
|
||||
void CreateChk();
|
||||
int Create();
|
||||
|
||||
private:
|
||||
/* 0x5AC */ u8 field_0x5AC[0x5B1 - 0x5AC];
|
||||
/* 0x5B1 */ u8 mUpDownMode;
|
||||
/* 0x5B2 */ u8 field_0x5B2[0x5B6 - 0x5B2];
|
||||
|
||||
@@ -63,7 +63,6 @@ public:
|
||||
s32 CreateHeap();
|
||||
s32 create();
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhaseReq; /**< Phase request used when creating the actor. */
|
||||
/* 0x5B4 */ J3DModel* mpModel; /**< Pointer to the Mini Freezard's model. */
|
||||
/* 0x5B8 */ mDoExt_invisibleModel mInvisibleModel; /**< Invisible model used for the Mini Freezard. */
|
||||
|
||||
@@ -61,7 +61,6 @@ public:
|
||||
|
||||
u8 getGroupNo() { return mGroupNo; }
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x5B4 */ mDoExt_McaMorfSO* mpMorfSO;
|
||||
/* 0x5B8 */ Z2CreatureEnemy mSound;
|
||||
|
||||
@@ -47,7 +47,6 @@ public:
|
||||
bool isBattleOn() { return mIsBattleOn; }
|
||||
bool isAttackStart() { return mIsAttackStart; }
|
||||
|
||||
private:
|
||||
/* 0x05AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x05B4 */ mDoExt_McaMorfSO* mpModelMorf;
|
||||
/* 0x05B8 */ J3DModel* mpSwordModel;
|
||||
|
||||
@@ -62,7 +62,6 @@ public:
|
||||
BOOL checkAction(actionFunc action) { return mAction == action; }
|
||||
BOOL checkOldAction(actionFunc action) { return mOldAction == action; }
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x5B4 */ dBgS_AcchCir mAcchCir;
|
||||
/* 0x5F4 */ dBgS_ObjAcch mObjAcch;
|
||||
|
||||
@@ -73,12 +73,6 @@ public:
|
||||
/* 0x124C */ f32 field_0x124c;
|
||||
/* 0x1250 */ u8 field_0x1250[0x1264 - 0x1250];
|
||||
/* 0x1264 */ u8 HIOInit;
|
||||
#if TARGET_PC
|
||||
cXyz mStalkLineInterpPrev[12];
|
||||
cXyz mStalkLineInterpCurr[12];
|
||||
bool mStalkLineInterpPrevValid;
|
||||
bool mStalkLineInterpCurrValid;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(e_hb_class) == 0x1268);
|
||||
|
||||
@@ -65,7 +65,6 @@ public:
|
||||
void CheckWall();
|
||||
void CreateStyle();
|
||||
int Create();
|
||||
private:
|
||||
/* 0x5AC */ u8 field_0x5ac;
|
||||
/* 0x5AD */ u8 field_0x5ad;
|
||||
/* 0x5AE */ u8 field_0x5ae;
|
||||
|
||||
@@ -64,7 +64,6 @@ public:
|
||||
void setInitPos();
|
||||
int create();
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x5B4 */ request_of_phase_process_class mPhaseReq2;
|
||||
/* 0x5BC */ mDoExt_McaMorfSO* mpMorfSO;
|
||||
|
||||
@@ -49,7 +49,6 @@ public:
|
||||
int CreateHeap();
|
||||
int create();
|
||||
|
||||
private:
|
||||
/* 0x05AC */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x05B4 */ mDoExt_McaMorfSO* mpMorfSO;
|
||||
/* 0x05B8 */ mDoExt_McaMorfSO* mpWeaponMorfSO;
|
||||
|
||||
@@ -44,12 +44,6 @@ public:
|
||||
/* 0x88C */ u8 field_0x88C[0x8C8 - 0x88C];
|
||||
/* 0x8C8 */ s8 field_0x8c8;
|
||||
/* 0x8C9 */ u8 mInitHIO;
|
||||
#if TARGET_PC
|
||||
cXyz mRopeInterpPrev[16];
|
||||
cXyz mRopeInterpCurr[16];
|
||||
bool mRopeInterpPrevValid;
|
||||
bool mRopeInterpCurrValid;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(e_mb_class) == 0x8cc);
|
||||
|
||||
@@ -87,7 +87,6 @@ public:
|
||||
daE_OC_c* getTalkOc() { return mpTalk; }
|
||||
J3DModel* getOcModel() { return mpMorf->getModel(); }
|
||||
|
||||
private:
|
||||
/* 0x5a0 */ request_of_phase_process_class mPhaseReqs[2];
|
||||
/* 0x5bc */ mDoExt_McaMorfSO* mpMorf;
|
||||
/* 0x5c0 */ J3DModel* mpModel;
|
||||
|
||||
@@ -54,7 +54,6 @@ public:
|
||||
u32 checkAction(actionFunc func) { return field_0xb58 == func; }
|
||||
bool checkNormalAttk() { return checkAction(&daE_OctBg_c::normal_attack); }
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x5B4 */ mDoExt_McaMorfSO* field_0x5b4;
|
||||
/* 0x5B8 */ mDoExt_brkAnm* field_0x5b8;
|
||||
|
||||
@@ -54,7 +54,6 @@ public:
|
||||
/* 0x4 */ ACT_DAMAGE,
|
||||
};
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x5B4 */ mDoExt_McaMorfSO* mpMorf;
|
||||
/* 0x5B8 */ J3DModel* mpEggModel;
|
||||
|
||||
@@ -84,7 +84,6 @@ public:
|
||||
u8 SwitchChk() { return mStage; }
|
||||
u8 DoorChk() { return mDoorAction; }
|
||||
|
||||
private:
|
||||
/* 0x5AC */ fpc_ProcID mPuppetID[4];
|
||||
/* 0x5BC */ u8 field_0x5bc[0x5DC - 0x5BC];
|
||||
/* 0x5DC */ u8 mDoorAction;
|
||||
|
||||
@@ -81,15 +81,6 @@ public:
|
||||
/* 0x306D */ u8 field_0x306D[0x307C - 0x306D];
|
||||
/* 0x307C */ u32 mBodyEffEmtrID;
|
||||
/* 0x3080 */ u8 mInitHIO;
|
||||
|
||||
#if TARGET_PC
|
||||
static const int HAIR_STRAND_COUNT = 22;
|
||||
static const int HAIR_SEGMENT_COUNT = 16;
|
||||
cXyz mHairInterpPrev[HAIR_STRAND_COUNT * HAIR_SEGMENT_COUNT];
|
||||
cXyz mHairInterpCurr[HAIR_STRAND_COUNT * HAIR_SEGMENT_COUNT];
|
||||
bool mHairInterpPrevValid;
|
||||
bool mHairInterpCurrValid;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(e_s1_class) == 0x3084);
|
||||
|
||||
@@ -57,7 +57,6 @@ public:
|
||||
int Delete();
|
||||
void setBaseMtx();
|
||||
cPhs_Step Create();
|
||||
private:
|
||||
/* 0x5AC */ int field_0x5ac;
|
||||
/* 0x5B0 */ int field_0x5b0;
|
||||
/* 0x5B4 */ int field_0x5b4;
|
||||
@@ -78,7 +77,6 @@ private:
|
||||
public:
|
||||
/* 0x5EC */ cXyz* field_0x5ec;
|
||||
/* 0x5F0 */ f32 field_0x5f0;
|
||||
private:
|
||||
/* 0x5F4 */ cXyz field_0x5f4;
|
||||
/* 0x600 */ s16 field_0x600;
|
||||
/* 0x602 */ u8 field_0x602;
|
||||
|
||||
@@ -82,7 +82,6 @@ public:
|
||||
bool d_checkOldAction(void (daE_SW_c::*action)()) {
|
||||
return field_0xb0c == action;
|
||||
}
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x5B4 */ mDoExt_McaMorfSO* mpModelMorf;
|
||||
/* 0x5B8 */ Z2CreatureEnemy mSound;
|
||||
|
||||
@@ -47,7 +47,6 @@ public:
|
||||
int CreateHeap();
|
||||
int create();
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhaseReq;
|
||||
/* 0x5B4 */ request_of_phase_process_class mPhaseReq2;
|
||||
/* 0x5BC */ mDoExt_McaMorfSO* mpMorfSO;
|
||||
|
||||
@@ -146,7 +146,6 @@ public:
|
||||
int create();
|
||||
daE_VA_c();
|
||||
|
||||
private:
|
||||
/* 0x005AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x005B4 */ mDoExt_McaMorfSO* mpMorf;
|
||||
/* 0x005B8 */ mDoExt_McaMorfSO* mpEndEfMorf;
|
||||
|
||||
@@ -221,12 +221,6 @@ public:
|
||||
/* 0x17E4 */ u8 field_0x17e4[0x17e8 - 0x17e4];
|
||||
/* 0x17E8 */ f32 ride_speed_max; ///< @brief Speed rate for riding calculations.
|
||||
#if TARGET_PC
|
||||
cXyz himo_mat_interp_prev[2][16];
|
||||
cXyz himo_mat_interp_curr[2][16];
|
||||
cXyz himo_tex_interp_prev[2];
|
||||
cXyz himo_tex_interp_curr[2];
|
||||
bool himo_interp_prev_valid;
|
||||
bool himo_interp_curr_valid;
|
||||
s8 demo_cam_sync_ticks;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -59,7 +59,6 @@ public:
|
||||
void setAttack() { mActionMode = 10; }
|
||||
f32 const getSpeedF() { return speedF; }
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x5B4 */ mDoExt_McaMorfSO* mpModelMorf;
|
||||
/* 0x5B8 */ Z2CreatureEnemy mSound;
|
||||
|
||||
@@ -74,12 +74,6 @@ public:
|
||||
/* 0x1250 */ f32 field_0x1250;
|
||||
/* 0x1254 */ u8 field_0x1254[0x1268 - 0x1254];
|
||||
/* 0x1268 */ u8 field_0x1268;
|
||||
#if TARGET_PC
|
||||
cXyz mLineMatInterpPrev[12];
|
||||
cXyz mLineMatInterpCurr[12];
|
||||
bool mLineMatInterpPrevValid;
|
||||
bool mLineMatInterpCurrValid;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(e_yd_class) == 0x126c);
|
||||
|
||||
@@ -63,15 +63,6 @@ public:
|
||||
/* 0x0BB4 */ yg_ke_s mYgKes[13];
|
||||
/* 0x1880 */ mDoExt_3DlineMat0_c mLineMat;
|
||||
/* 0x189C */ u8 mIsFirstSpawn;
|
||||
|
||||
#if TARGET_PC
|
||||
static const int TENTACLE_STRAND_COUNT = 13;
|
||||
static const int TENTACLE_SEGMENT_COUNT = 10;
|
||||
cXyz mTentacleInterpPrev[TENTACLE_STRAND_COUNT * TENTACLE_SEGMENT_COUNT];
|
||||
cXyz mTentacleInterpCurr[TENTACLE_STRAND_COUNT * TENTACLE_SEGMENT_COUNT];
|
||||
bool mTentacleInterpPrevValid;
|
||||
bool mTentacleInterpCurrValid;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(e_yg_class) == 0x18a0);
|
||||
|
||||
@@ -77,12 +77,6 @@ public:
|
||||
/* 0x1260 */ u32 field_0x1260;
|
||||
/* 0x1260 */ u8 field_0x1264[0x1270 - 0x1264];
|
||||
/* 0x1270 */ bool mIsHIOOwner;
|
||||
#if TARGET_PC
|
||||
cXyz mLineInterpPrev[12];
|
||||
cXyz mLineInterpCurr[12];
|
||||
bool mLineInterpPrevValid;
|
||||
bool mLineInterpCurrValid;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(e_yh_class) == 0x1274);
|
||||
|
||||
@@ -122,7 +122,6 @@ public:
|
||||
u8 getSwitchBit() { return mSwitchBit; }
|
||||
u8 isHide() { return mIsHide; }
|
||||
|
||||
private:
|
||||
/* 0x5AC */ request_of_phase_process_class mPhase;
|
||||
/* 0x5B4 */ mDoExt_McaMorfSO* mpMorf;
|
||||
/* 0x5B8 */ mDoExt_brkAnm* mpBrk;
|
||||
|
||||
@@ -39,7 +39,6 @@ public:
|
||||
int CreateHeap();
|
||||
int create();
|
||||
|
||||
private:
|
||||
/* 0x5ac */ request_of_phase_process_class mPhase;
|
||||
/* 0x5b4 */ mDoExt_McaMorfSO* mpMorf;
|
||||
/* 0x5b8 */ Z2CreatureEnemy mSound;
|
||||
|
||||
@@ -196,9 +196,6 @@ public:
|
||||
void copyReinPos();
|
||||
void setReinPosHandSubstance(int);
|
||||
void setReinPosNormalSubstance();
|
||||
#if TARGET_PC
|
||||
void lerpControlPoints(f32 alpha);
|
||||
#endif
|
||||
void bgCheck();
|
||||
bool checkSpecialWallHitSubstance(cXyz const&) const;
|
||||
void setServiceWaitTimer();
|
||||
|
||||
@@ -140,7 +140,6 @@ public:
|
||||
void setEatYm() { field_0x6d8 |= (u8) 4; }
|
||||
MtxP getMouthMtx() { return mAnm_p->getModel()->getAnmMtx(7); }
|
||||
|
||||
private:
|
||||
/* 0x568 */ request_of_phase_process_class mPhase;
|
||||
/* 0x570 */ mDoExt_McaMorfSO* mAnm_p;
|
||||
/* 0x574 */ Z2CreatureEnemy mSound;
|
||||
|
||||
@@ -92,10 +92,7 @@ public:
|
||||
/* 0x39A4 */ cM_rnd_c mMantRng;
|
||||
#endif
|
||||
};
|
||||
#if TARGET_PC
|
||||
STATIC_ASSERT(sizeof(mant_class) == 0x39ac);
|
||||
#else
|
||||
|
||||
STATIC_ASSERT(sizeof(mant_class) == 0x39a4);
|
||||
#endif
|
||||
|
||||
#endif /* D_A_MANT_H */
|
||||
|
||||
@@ -299,13 +299,6 @@ public:
|
||||
/* 0x168C */ u8 field_0x168c;
|
||||
/* 0x168D */ u8 field_0x168d;
|
||||
/* 0x168E */ u8 HIOInit;
|
||||
|
||||
#if TARGET_PC
|
||||
cXyz mLineInterpPrev[MG_ROD_LURE_LINE_LEN];
|
||||
cXyz mLineInterpCurr[MG_ROD_LURE_LINE_LEN];
|
||||
bool mLineInterpPrevValid;
|
||||
bool mLineInterpCurrValid;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* D_A_MG_ROD_H */
|
||||
|
||||
@@ -423,7 +423,6 @@ public:
|
||||
static DUSK_GAME_DATA daMidna_texData_s const m_texDataTable[21];
|
||||
static DUSK_GAME_DATA daMidna_anmData_s const m_anmDataTable[53];
|
||||
|
||||
// private:
|
||||
/* 0x568 */ request_of_phase_process_class mPhase;
|
||||
/* 0x570 */ J3DModel* mpModel;
|
||||
/* 0x574 */ J3DModel* mpShadowModel;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#if !TARGET_PC
|
||||
#include <thp.h>
|
||||
#else
|
||||
#include <dolphin/thp.h>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#endif
|
||||
@@ -17,29 +18,6 @@ struct daMP_THPReadBuffer {
|
||||
};
|
||||
|
||||
#if TARGET_PC
|
||||
// Copying here because thp.h is probably erroneous in the dolphin lib,
|
||||
// and it's kind of a problem being there (Aurora owns the headers).
|
||||
// TODO: Move this stuff in decomp?
|
||||
typedef struct THPAudioRecordHeader {
|
||||
BE(u32) offsetNextChannel;
|
||||
BE(u32) sampleSize;
|
||||
BE(s16) lCoef[8][2];
|
||||
BE(s16) rCoef[8][2];
|
||||
BE(s16) lYn1;
|
||||
BE(s16) lYn2;
|
||||
BE(s16) rYn1;
|
||||
BE(s16) rYn2;
|
||||
} THPAudioRecordHeader;
|
||||
|
||||
typedef struct THPAudioDecodeInfo {
|
||||
u8* encodeData;
|
||||
u32 offsetNibbles;
|
||||
u8 predictor;
|
||||
u8 scale;
|
||||
s16 yn1;
|
||||
s16 yn2;
|
||||
} THPAudioDecodeInfo;
|
||||
|
||||
typedef struct THPTextureSet {
|
||||
u8* ytexture;
|
||||
u8* utexture;
|
||||
@@ -86,10 +64,6 @@ typedef struct THPHeader {
|
||||
/* 0x2C */ BE(u32) finalFrameDataOffsets;
|
||||
} THPHeader;
|
||||
|
||||
static u32 THPAudioDecode(s16* audioBuffer, u8* audioFrame, s32 flag);
|
||||
static s32 __THPAudioGetNewSample(THPAudioDecodeInfo* info);
|
||||
static void __THPAudioInitialize(THPAudioDecodeInfo* info, u8* ptr);
|
||||
|
||||
#define THP_AUDIO_BUFFER_COUNT 3
|
||||
#define THP_READ_BUFFER_COUNT 10
|
||||
#define THP_TEXTURE_SET_COUNT 3
|
||||
@@ -166,7 +140,6 @@ public:
|
||||
|
||||
static DUSK_GAME_DATA daMP_c* m_myObj;
|
||||
|
||||
private:
|
||||
/* 0x568 */ u32 (*mpGetMovieRestFrame)(void);
|
||||
/* 0x56C */ void (*mpSetPercentMovieVol)(f32);
|
||||
/* 0x570 */ u32 (*mpTHPGetTotalFrame)(void);
|
||||
|
||||
@@ -29,7 +29,7 @@ struct daNpc_GetParam3 { // name unknown
|
||||
};
|
||||
|
||||
class daNpcT_ActorMngr_c {
|
||||
private:
|
||||
public:
|
||||
/* 0x0 */ fpc_ProcID mActorID;
|
||||
|
||||
public:
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
};
|
||||
|
||||
class daNpcT_MatAnm_c : public J3DMaterialAnm {
|
||||
private:
|
||||
public:
|
||||
/* 0x0F4 */ mutable f32 field_0xF4;
|
||||
/* 0x0F8 */ mutable f32 field_0xF8;
|
||||
/* 0x0FC */ f32 mNowOffsetX;
|
||||
@@ -102,7 +102,6 @@ public:
|
||||
}
|
||||
void setOffset(int i_offset) { mOffset = i_offset; }
|
||||
|
||||
private:
|
||||
/* 0x00 */ sequenceStepData_c const* mpSeqData;
|
||||
/* 0x04 */ int mStepNum;
|
||||
/* 0x08 */ int mNo;
|
||||
@@ -217,7 +216,7 @@ public:
|
||||
};
|
||||
|
||||
class daNpcT_JntAnm_c {
|
||||
private:
|
||||
public:
|
||||
/* 0x000 */ daNpcT_ActorMngr_c mActrMngr;
|
||||
/* 0x008 */ cXyz mPos;
|
||||
/* 0x014 */ cXyz mAttnPos;
|
||||
|
||||
@@ -15,7 +15,6 @@ public:
|
||||
fopAc_ac_c* getActor();
|
||||
virtual ~daBaseNpc_acMngr_c() {}
|
||||
|
||||
private:
|
||||
/* 0x04 */ fpc_ProcID mActorId;
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "JSystem/J3DGraphAnimator/J3DMaterialAnm.h"
|
||||
|
||||
class daNpcF_ActorMngr_c {
|
||||
private:
|
||||
public:
|
||||
/* 0x0 */ fpc_ProcID mActorID;
|
||||
|
||||
public:
|
||||
@@ -52,7 +52,7 @@ BOOL daNpcF_chkPassed(cXyz i_pos, dPnt* i_points, u16 i_idx, u16 i_num, BOOL i_i
|
||||
BOOL daNpcF_chkDoBtnEqSpeak(fopAc_ac_c* i_actor_p);
|
||||
|
||||
class daNpcF_SPCurve_c {
|
||||
private:
|
||||
public:
|
||||
/* 0x00 */ u16 mNurbs;
|
||||
/* 0x02 */ u16 field_0x02;
|
||||
/* 0x04 */ u8 mIsReversed;
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
}; // Size: 0x630
|
||||
|
||||
class daNpcF_MatAnm_c : public J3DMaterialAnm {
|
||||
private:
|
||||
public:
|
||||
/* 0x0F4 */ mutable f32 field_0xF4;
|
||||
/* 0x0F8 */ mutable f32 field_0xF8;
|
||||
/* 0x0FC */ f32 mNowOffsetX;
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
};
|
||||
|
||||
class daNpcF_Lookat_c {
|
||||
private:
|
||||
public:
|
||||
/* 0x00 */ cXyz mJointPos[4];
|
||||
/* 0x30 */ cXyz* mAttnPos_p;
|
||||
/* 0x34 */ csXyz mAngularMoveDis[4];
|
||||
@@ -406,7 +406,6 @@ public:
|
||||
STATIC_ASSERT(sizeof(daNpcF_c) == 0xB48);
|
||||
|
||||
class daNpcF_MoveBgActor_c : public daNpcF_c {
|
||||
private:
|
||||
public:
|
||||
// these functions are inferred based on daBaseNpc_moveBgActor_c -
|
||||
// defining them in this order fixes weak function order for this class in d_a_npc
|
||||
|
||||
@@ -174,7 +174,6 @@ public:
|
||||
static DUSK_GAME_DATA char DUSK_CONST* DUSK_CONST mCutNameList[7];
|
||||
static DUSK_GAME_DATA cutFunc DUSK_CONST mCutList[7];
|
||||
|
||||
private:
|
||||
/* 0xE40 */ NPC_ARU_HIO_CLASS* mpHIO;
|
||||
/* 0xE44 */ dCcD_Cyl mCyl;
|
||||
/* 0xF80 */ u8 mType;
|
||||
|
||||
@@ -145,7 +145,6 @@ public:
|
||||
|
||||
static DUSK_GAME_DATA EventFn mEvtSeqList[6];
|
||||
|
||||
private:
|
||||
/* 0xB48 */ Z2Creature mCreatureSound;
|
||||
/* 0xBD8 */ J3DModel* mModelBow;
|
||||
/* 0xBDC */ J3DModel* mModelQuiver;
|
||||
|
||||
@@ -137,7 +137,6 @@ public:
|
||||
|
||||
static DUSK_GAME_DATA EventFn DUSK_CONST mEvtSeqList[2];
|
||||
|
||||
private:
|
||||
/* 0xB48 */ Z2Creature mCreatureSound;
|
||||
/* 0xBD8 */ daNpcF_MatAnm_c* mpMatAnm;
|
||||
/* 0xBDC */ J3DModel* mpModel;
|
||||
|
||||
@@ -143,7 +143,6 @@ public:
|
||||
static DUSK_GAME_DATA char DUSK_CONST* DUSK_CONST mCutNameList[15];
|
||||
static DUSK_GAME_DATA cutFunc DUSK_CONST mCutList[15];
|
||||
|
||||
private:
|
||||
/* 0x0E40 */ mDoExt_McaMorfSO* mpCupModelMorf;
|
||||
/* 0x0E44 */ NPC_BESU_HIO_CLASS* mpHIO;
|
||||
/* 0x0E48 */ J3DModel* mpClothModel[1];
|
||||
|
||||
@@ -168,7 +168,6 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
/* 0xE40 */ NPC_BOU_HIO_CLASS* mpHIO;
|
||||
/* 0xE44 */ dCcD_Cyl mCyl1;
|
||||
/* 0xF80 */ u8 mType;
|
||||
|
||||
@@ -130,7 +130,6 @@ public:
|
||||
|
||||
static DUSK_GAME_DATA eventFunc mEvtSeqList[4];
|
||||
|
||||
private:
|
||||
/* 0xB48 */ Z2Creature mSound;
|
||||
/* 0xBD8 */ daNpcF_MatAnm_c* mpMatAnm;
|
||||
/* 0xBDC */ daNpcF_Lookat_c mLookat;
|
||||
|
||||
@@ -104,7 +104,6 @@ public:
|
||||
|
||||
static DUSK_GAME_DATA eventFunc DUSK_CONST mEvtSeqList[1];
|
||||
|
||||
private:
|
||||
/* 0xB48 */ Z2CreatureCitizen mSound;
|
||||
/* 0xBEC */ u8 field_0xbec[0xbf0 - 0xbec];
|
||||
/* 0xBF0 */ J3DModel* mObjModel;
|
||||
|
||||
@@ -127,7 +127,6 @@ public:
|
||||
static DUSK_GAME_DATA char DUSK_CONST* DUSK_CONST mCutNameList[1];
|
||||
static DUSK_GAME_DATA cutFunc DUSK_CONST mCutList[1];
|
||||
|
||||
private:
|
||||
/* 0x0F7C */ NPC_CLERKA_HIO_CLASS* mpHIO;
|
||||
/* 0x0F80 */ dCcD_Cyl mCyl;
|
||||
/* 0x10BC */ u8 mType;
|
||||
|
||||
@@ -140,7 +140,6 @@ public:
|
||||
static DUSK_GAME_DATA char DUSK_CONST* DUSK_CONST mCutNameList[1];
|
||||
static DUSK_GAME_DATA cutFunc DUSK_CONST mCutList[1];
|
||||
|
||||
private:
|
||||
/* 0x0F7C */ mDoExt_bpkAnm mBpkAnm2;
|
||||
/* 0x0F7C */ NPC_CLERKB_HIO_CLASS* mpHIO;
|
||||
/* 0x0F98 */ dCcD_Cyl mCyl;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user