Compare commits

..

12 Commits

Author SHA1 Message Date
MelonSpeedruns 957ab06fc2 fix autosave spam 2026-05-14 09:36:00 -04:00
MelonSpeedruns fe270d976d Merge remote-tracking branch 'origin/main' into rando/new-item 2026-05-14 09:20:46 -04:00
MelonSpeedruns 9e0966e069 don't change save file length and use unused slot for ghost lantern 2026-05-08 16:32:12 -04:00
MelonSpeedruns b51e672540 Merge remote-tracking branch 'origin/main' into rando/new-item 2026-05-08 15:38:02 -04:00
MelonSpeedruns c844eb2b4a Merge remote-tracking branch 'origin/main' into rando/new-item 2026-05-05 08:33:25 -04:00
MelonSpeedruns 416bfaa90b added light to lantern + proper blue flame particle 2026-05-01 10:17:29 -04:00
MelonSpeedruns 365a0a2188 fire particle + closed link hand 2026-04-28 13:02:31 -04:00
MelonSpeedruns 4ff41fce4e Merge branch 'main' into rando/new-item 2026-04-26 12:10:21 -04:00
MelonSpeedruns a470b73b1b fix weirdnesses with real lantern 2026-04-26 12:10:08 -04:00
MelonSpeedruns 120864a5c9 working lantern model but with hack atm 2026-04-25 18:18:02 -04:00
MelonSpeedruns ba7fc14e87 added poe lantern wip code 2026-04-25 17:17:12 -04:00
MelonSpeedruns c42d10a74b new item code 2026-04-24 16:01:15 -04:00
53 changed files with 521 additions and 539 deletions
-1
View File
@@ -1,7 +1,6 @@
# IDE folders
.idea/
.vs/
.zed/
# Caches
__pycache__
-6
View File
@@ -276,12 +276,6 @@ if (DUSK_ENABLE_SENTRY_NATIVE)
endif ()
endif ()
# Use signed char on ARM to match the original game (and x86)
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _arch)
if(_arch MATCHES "^(arm|aarch64)" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
add_compile_options(-fsigned-char)
endif()
if (CMAKE_SYSTEM_NAME STREQUAL Windows)
set(PLATFORM_NAME win32)
elseif (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+51 -181
View File
@@ -1,165 +1,51 @@
# Building Dusklight
## Dependencies
The following dependencies are required:
### Building
#### Prerequisites
* [CMake 3.25+](https://cmake.org)
* Windows: Install `CMake Tools` in Visual Studio
* macOS: `brew install cmake`
* [Python 3+](https://python.org)
### Windows
* Install [CMake 3.25+](https://cmake.org) by searching `CMake Tools` in Visual Studio
* Install Python 3 from the [Microsoft Store](https://go.microsoft.com/fwlink?linkID=2082640) and verify it's added to `%PATH%` by typing `python` in `cmd`.
Recommended IDEs:
* [Visual Studio 2026 Community](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx). During installation:
* Select `C++ Development` and verify the following packages are included:
* `Windows 11 SDK`
* `CMake Tools`
* `C++ Clang Compiler`
* `C++ Clang-cl`
### macOS
* Make sure [Homebrew](https://brew.sh) is installed
* Install [CMake 3.25+](https://cmake.org)
```sh
brew install cmake
```
* Install Python 3
```sh
brew install python@3
```
Recommended IDEs:
* [Xcode 16.4 or later](https://developer.apple.com/xcode/)
* [Visual Studio Code](https://code.visualstudio.com/download/)
* [CLion](https://www.jetbrains.com/clion/)
### Linux
Actively tested on Ubuntu 24.04, Arch Linux & derivatives.
**Ubuntu 24.04+ packages**
<details>
<summary>Click to expand</summary>
* Run the following command to install the required dependencies:
```sh
sudo apt update && sudo apt install -y \
build-essential \
clang \
cmake \
curl \
git \
libasound2-dev \
libclang-dev \
libcurl4-openssl-dev \
libdbus-1-dev \
libfreetype-dev \
libglu1-mesa-dev \
libgtk-3-dev \
libncurses5-dev \
libpng-dev \
libpulse-dev \
libudev-dev \
libvulkan-dev \
libx11-xcb-dev \
libxcursor-dev \
libxi-dev \
libxinerama-dev \
libxrandr-dev \
libxss-dev \
libxtst-dev \
lld \
ninja-build \
python-is-python3 \
python3 \
python3-markupsafe \
zlib1g-dev
```
</details>
<br>
**Arch Linux packages**
<details>
<summary>Click to expand</summary>
* Run the following command to install the required dependencies:
```sh
sudo pacman -S --needed \
alsa-lib \
base-devel \
clang \
cmake \
freetype2 \
libpulse \
libxrandr \
lld \
llvm \
ninja \
python \
python-markupsafe \
vulkan-headers
```
</details>
<br>
**Fedora packages**
<details>
<summary>Click to expand</summary>
* Run the following command to install the required dependencies:
```sh
sudo dnf install -y \
clang-devel \
cmake \
libpng-devel \
llvm-devel \
ninja-build \
vulkan-headers
```
* It's also important that you install the developer tools and libraries
```sh
sudo dnf groupinstall \
"Development Libraries" "Development Tools"
```
</details>
<br>
Recommended IDEs:
* [CLion](https://www.jetbrains.com/clion/)
* [Visual Studio Code](https://code.visualstudio.com/download/)
## Building
* Clone and initialize the Dusklight repository:
* Windows: [Microsoft Store](https://go.microsoft.com/fwlink?linkID=2082640)
* Verify it's added to `%PATH%` by typing `python` in `cmd`.
* macOS: `brew install python@3`
* **[Windows]** [Visual Studio 2026 Community](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx)
* Select `C++ Development` and verify the following packages are included:
* `Windows 11 SDK`
* `CMake Tools`
* `C++ Clang Compiler`
* `C++ Clang-cl`
* **[macOS]** [Xcode 16.4+](https://developer.apple.com/xcode/download/)
* **[Linux]** Actively tested on Ubuntu 24.04, Arch Linux & derivatives.
* Ubuntu 24.04+ packages
```
build-essential curl git ninja-build clang lld zlib1g-dev libcurl4-openssl-dev \
libglu1-mesa-dev libdbus-1-dev libvulkan-dev libxi-dev libxrandr-dev libasound2-dev libpulse-dev \
libudev-dev libpng-dev libncurses5-dev cmake libx11-xcb-dev python3 python-is-python3 \
libclang-dev libfreetype-dev libxinerama-dev libxcursor-dev python3-markupsafe libgtk-3-dev \
libxss-dev libxtst-dev
```
* Arch Linux packages
```
base-devel cmake ninja llvm vulkan-headers python python-markupsafe clang lld alsa-lib libpulse libxrandr freetype2
```
* Fedora packages
```
cmake vulkan-headers ninja-build clang-devel llvm-devel libpng-devel
```
* It's also important that you install the developer tools and libraries
```
sudo dnf groupinstall "Development Tools" "Development Libraries"
```
#### Setup
Clone and initialize the Dusklight repository
```sh
git clone --recursive https://github.com/TwilitRealm/dusklight.git
git pull
cd dusklight
git pull
git submodule update --init --recursive
```
#### Building
**CLion (Windows / macOS / Linux)**
Open the project directory in CLion. Enable the appropriate presets for your platform:
@@ -178,8 +64,7 @@ cmake --build --preset macos-default-relwithdebinfo
```
Alternate presets available:
* `macos-default-debug`: Clang, Debug
- `macos-default-debug`: Clang, Debug
**ninja (Linux)**
@@ -189,10 +74,9 @@ cmake --build --preset linux-default-relwithdebinfo
```
Alternate presets available:
* `linux-default-debug`: GCC, Debug
* `linux-clang-relwithdebinfo`: Clang, RelWithDebInfo
* `linux-clang-debug`: Clang, Debug
- `linux-default-debug`: GCC, Debug
- `linux-clang-relwithdebinfo`: Clang, RelWithDebInfo
- `linux-clang-debug`: Clang, Debug
**ninja (Windows)**
@@ -202,27 +86,13 @@ cmake --build --preset windows-msvc-relwithdebinfo
```
Alternate presets available:
- `windows-msvc-debug`: MSVC, Debug
- `windows-clang-relwithdebinfo`: Clang-cl, RelWithDebInfo
- `windows-clang-debug`: Clang-cl, Debug
* `windows-msvc-debug`: MSVC, Debug
* `windows-clang-relwithdebinfo`: Clang-cl, RelWithDebInfo
* `windows-clang-debug`: Clang-cl, Debug
## Running
**Windows / Linux**
* Pass the disc image as a positional argument using the `--dvd` flag. Supported formats are: ISO (GCM), RVZ, WIA, WBFS, CISO, GCZ
#### Running
Pass the disc image as a positional argument. Supported formats: ISO (GCM), RVZ, WIA, WBFS, CISO, GCZ
```sh
build/{preset}/dusklight --dvd /path/to/game.iso
```
**macOS**
macOS builds an `.app` bundle which contains the executable and all necessary resources.
* Pass the disc image as a positional argument using the `--dvd` flag. Supported formats are: ISO (GCM), RVZ, WIA, WBFS, CISO, GCZ
```sh
build/{preset}/Dusklight.app/Contents/MacOS/Dusklight --dvd /path/to/game.iso
build/{preset}/dusklight/path/to/game.rvz
```
If no path is specified, Dusklight defaults to `game.iso` in the current working directory.
+21 -23
View File
@@ -1,40 +1,33 @@
# Installing Dusklight on iOS via iloader
# Installing Dusklight on iOS via AltStore
## Prerequisites
- A Windows, Linux, or macOS device
- iOS device connected to computer via USB
- Mac with Homebrew installed
- iPhone connected via USB
- Dusklight IPA file (download the latest `Dusklight-vX.X.X-ios-arm64.ipa` from the [releases page](https://github.com/TwilitRealm/dusk/releases))
- Game disc - `GZ2E01` (Gamecube USA) or `GZ2PE01` (Gamecube PAL)
## 1. Install AltServer
- Executable bundles can be installed from [iloader's main page](https://iloader.app/) or [their GitHub](https://github.com/nab138/iloader) for Windows, Linux, and macOS.
- Windows WILL require iTunes to be installed
- Linux WILL require usbmuxd to be installed, this is installed by default in most distros though
```sh
brew install altserver
open -a AltServer
```
AltServer will appear in your menu bar.
## 2. Enable Developer Mode (iOS 16+)
- On your iPhone, go to **Settings > Privacy & Security > Developer Mode**
- Toggle it on and restart when prompted
## 3. Install Dusklight on Your iPhone
## 3. Install AltStore on Your iPhone
1. Sign into your Apple ID (this is required for registering app IDs, it is sent securely and not stored by iloader)
* You may be prompted to put in a code from your iOS device, do so
2. Plug in your iOS device via USB into your PC. If you're missing a dependency, an error pop-up will tell you to install it
* You will need to hit `Refresh` after plugging it in at this stage so that it can be detected, it does not automatically refresh
3. Leave settings unchanged (the Anisette server should stay Sidestore (.io))
3.(a) Installing SideStore directly is not required, but provides you a way to install Dusklight on your phone without being plugged into a computer later
4. Press `Import IPA` and choose your downloaded `Dusk-v.X.X.X-ios-arm64.ipa`, it will begin installing on your device
**NOTE:** *At various stages, you may be prompted to trust your device, do so*
## 3. Getting Dusk trusted
When installing sideloaded iOS applications, at first you will need to manually trust the app due to Apple's security policies
* Go to **Settings > General > VPN & Device Management**
* Tap the Apple ID you signed into iloader with under "Developer App" and tap **Trust**
* Tap **Allow** on the pop-up
- Click AltServer in the menu bar
- Click **Install AltStore > [Your iPhone]**
- Enter your Apple ID credentials when prompted
- On your iPhone, go to **Settings > General > VPN & Device Management**
- Tap your Apple ID under "Developer App" and tap **Trust**
## 4. Copy Files to Your iPhone
@@ -45,4 +38,9 @@ Transfer the IPA and game disc to your iPhone so they're accessible in the Files
- **USB transfer** - Connect your iPhone and drag files via Finder's sidebar
- **Cloud storage** - Upload to Google Drive, Dropbox, etc. and download on your iPhone
You may now use Dusklight on iOS, iPadOS!
## 5. Install via AltStore
- Open **AltStore** on your iPhone
- Go to the **My Apps** tab
- Tap the **+** button (top left)
- Open the **Files** app and select the `.ipa` file
+1 -1
+10 -1
View File
@@ -15,6 +15,12 @@
# Dependencies that are not packaged in nixpkgs (used by the Linux package build):
buildSources = pkgs: {
aurora-src = pkgs.fetchFromGitHub {
owner = "encounter";
repo = "aurora";
rev = "63606a43265a3bc18dafd500ab4d7a2108f109e6";
hash = "sha256-xBvnAwGwNzav67Ac6oUz7RqDUwqgL2bsME3OOMn8Tqw=";
};
dawn-src = pkgs.fetchzip {
url = "https://github.com/encounter/dawn-build/releases/download/v20260423.175430/dawn-linux-x86_64.tar.gz";
hash = "sha256-HXfKTLHtMPwupnFnaflCARtXVPuS/0PoCePXidjE5xs=";
@@ -53,6 +59,9 @@
name = "dusklight";
src = ./.;
postUnpack = ''
mkdir -p $sourceRoot/extern/aurora
cp -r ${srcs.aurora-src}/. $sourceRoot/extern/aurora/
chmod -R u+w $sourceRoot/extern/aurora
sed -i '/add_subdirectory(tests)/d' $sourceRoot/extern/aurora/CMakeLists.txt
'';
# Remove last line to re-enable tests
@@ -216,4 +225,4 @@
default = mkDevShell (pkgsFor system);
});
};
}
}
+23
View File
@@ -1733,6 +1733,9 @@ public:
int checkNewItemChange(u8 i_selItemIdx);
void deleteEquipItem(BOOL i_isPlaySound, BOOL i_isDeleteKantera);
void setLight();
#if TARGET_PC
void setGhostLanternLight();
#endif
void setFrontRollCrashShock(u8);
void changeWarpMaterial(daAlink_c::daAlink_WARP_MAT_MODE i_matMode);
void commonProcInit(daAlink_c::daAlink_PROC i_procID);
@@ -2656,8 +2659,14 @@ public:
void checkWaterInKandelaar(f32);
void offKandelaarModel();
int kandelaarModelCallBack();
int ghostLanternModelCallBack();
BOOL checkKandelaarEquipAnime() const;
void preKandelaarDraw();
void preGhostLanternDraw();
static void* srchPoe(void*, void*);
#if TARGET_PC
void setGhostLanternModel();
#endif
void setKandelaarModel();
void resetOilBottleModel();
void commonKandelaarPourInit();
@@ -3977,6 +3986,9 @@ public:
/* 0x006FC */ J3DModel* mpKanteraModel;
/* 0x00700 */ J3DModel* mpKanteraGlowModel;
/* 0x00704 */ J3DAnmTextureSRTKey* mpKanteraGlowBtk;
/* 0x006FC */ J3DModel* mpGhostLanternModel;
/* 0x00700 */ J3DModel* mpGhostLanternGlowModel;
/* 0x00704 */ J3DAnmTextureSRTKey* mpGhostLanternGlowBtk;
/* 0x00708 */ J3DModel* mHeldItemModel;
/* 0x0070C */ J3DModel* mpHookTipModel; // related to held item
/* 0x00710 */ J3DModel* field_0x0710; // related to held item
@@ -4373,6 +4385,7 @@ public:
/* 0x03194 */ int field_0x3194;
/* 0x03198 */ int field_0x3198;
/* 0x0319C */ int field_0x319c;
/* 0x0319C */ s32 ghostLanternFlameEffect[2];
/* 0x031A0 */ u32 mModeFlg;
/* 0x031A4 */ int field_0x31a4;
/* 0x031A8 */ u32 field_0x31a8[2];
@@ -4442,6 +4455,9 @@ public:
/* 0x033F4 */ f32 field_0x33f4;
/* 0x033F8 */ f32 field_0x33f8;
/* 0x033FC */ f32 field_0x33fc;
#if TARGET_PC
/* 0x033FC */ f32 current_ghost_lantern_light_power;
#endif
/* 0x03400 */ f32 field_0x3400;
/* 0x03404 */ f32 field_0x3404;
/* 0x03408 */ f32 field_0x3408;
@@ -4509,9 +4525,13 @@ public:
/* 0x035F4 */ cXyz mMidnaAtnPos;
/* 0x03600 */ cXyz mMidnaHairAtnPos;
/* 0x0360C */ cXyz mKandelaarFlamePos;
/* 0x0360C */ cXyz mGhostLanternFlamePos;
/* 0x03618 */ cXyz field_0x3618;
/* 0x03624 */ cXyz field_0x3624;
/* 0x03630 */ cXyz field_0x3630;
/* 0x03618 */ cXyz ghost_lantern_0x3618;
/* 0x03624 */ cXyz ghost_lantern_0x3624;
/* 0x03630 */ cXyz ghost_lantern_0x3630;
/* 0x0363C */ cXyz field_0x363c[4];
/* 0x0366C */ cXyz field_0x366c[4];
/* 0x0369C */ cXyz field_0x369c;
@@ -6821,6 +6841,9 @@ public:
static daAlinkHIO_boom_c0 const mBoomerang;
static daAlinkHIO_bomb_c0 const mBomb;
static daAlinkHIO_huLight_c0 const mLanternPL;
#if TARGET_PC
static daAlinkHIO_huLight_c0 const mGhostLanternPL;
#endif
static daAlinkHIO_kandelaar_c0 const mLantern;
static daAlinkHIO_fmChain_c0 const mFmChain;
static daAlinkHIO_magneBoots_c0 const mIronBoots;
+2
View File
@@ -71,6 +71,7 @@ void item_func_WOOD_STICK();
void item_func_BOOMERANG();
void item_func_SPINNER();
void item_func_IRONBALL();
void item_func_GHOST_LANTERN();
void item_func_BOW();
void item_func_HOOKSHOT();
void item_func_HVY_BOOTS();
@@ -260,6 +261,7 @@ int item_getcheck_func_WOOD_STICK();
int item_getcheck_func_BOOMERANG();
int item_getcheck_func_SPINNER();
int item_getcheck_func_IRONBALL();
int item_getcheck_func_GHOST_LANTERN();
int item_getcheck_func_BOW();
int item_getcheck_func_HOOKSHOT();
int item_getcheck_func_HVY_BOOTS();
+1 -1
View File
@@ -317,7 +317,7 @@ enum {
/* 0xDE */ dItemNo_NOENTRY_222_e,
/* 0xDF */ dItemNo_NOENTRY_223_e,
/* 0xE0 */ dItemNo_POU_SPIRIT_e,
/* 0xE1 */ dItemNo_NOENTRY_225_e,
/* 0xE1 */ dItemNo_GHOST_LANTERN_e,
/* 0xE2 */ dItemNo_NOENTRY_226_e,
/* 0xE3 */ dItemNo_NOENTRY_227_e,
/* 0xE4 */ dItemNo_NOENTRY_228_e,
+2 -2
View File
@@ -86,8 +86,8 @@ public:
/* 0x047 */ u8 field_0x47;
/* 0x048 */ u8 mPoes;
/* 0x049 */ u8 mPoesCopy;
/* 0x04A */ u8 mItems[24];
/* 0x062 */ u8 mItemsCopy[24];
/* 0x04A */ u8 mItems[25];
/* 0x062 */ u8 mItemsCopy[25];
/* 0x07A */ u8 field_0x7a[24];
/* 0x092 */ u8 mSwords[4];
/* 0x096 */ u8 mShields[3];
-1
View File
@@ -5,7 +5,6 @@
#include <m_Do/m_Do_MemCardRWmng.h>
#include <m_Do/m_Do_MemCard.h>
#include <d/actor/d_a_alink.h>
void noAutoSave();
void triggerAutoSave();
-1
View File
@@ -17,7 +17,6 @@ void ensure_initialized();
void begin_record();
void end_record();
void begin_sim_tick();
uint64_t sim_tick_seq();
void begin_frame(bool enabled, bool is_sim_frame, float step);
void interpolate();
float get_interpolation_step();
-5
View File
@@ -72,10 +72,6 @@ struct UserSettings {
ConfigVar<bool> lockAspectRatio;
ConfigVar<bool> enableFpsOverlay;
ConfigVar<int> fpsOverlayCorner;
ConfigVar<int> windowPositionX;
ConfigVar<int> windowPositionY;
ConfigVar<int> windowWidth;
ConfigVar<int> windowHeight;
} video;
struct {
@@ -127,7 +123,6 @@ struct UserSettings {
ConfigVar<BloomMode> bloomMode;
ConfigVar<float> bloomMultiplier;
ConfigVar<bool> disableWaterRefraction;
ConfigVar<bool> enableTextureReplacements;
ConfigVar<bool> enableFrameInterpolation;
ConfigVar<int> internalResolutionScale;
ConfigVar<int> shadowResolutionMultiplier;
+1 -1
View File
@@ -108,7 +108,7 @@ struct fopAcM_search_prm {
struct fOpAcm_HIO_entry_c : public mDoHIO_entry_c {
virtual ~fOpAcm_HIO_entry_c() {}
#if DEBUG && !TARGET_PC
#if DEBUG
void removeHIO(const fopAc_ac_c* i_this) { removeHIO(*i_this); }
void removeHIO(const fopAc_ac_c& i_this) { removeHIO(i_this.base); }
void removeHIO(const fopEn_enemy_c& i_this) { removeHIO(i_this.base); }
+1 -3
View File
@@ -28,9 +28,7 @@
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.adventure-games</string>
<key>LSSupportsGameMode</key>
<true/>
<true/>
</dict>
</plist>
-4
View File
@@ -58,10 +58,6 @@ toast:active {
background-color: rgba(45, 43, 26, 80%);
}*/
b {
font-weight: bold;
}
toast heading {
display: flex;
gap: 18dp;
-4
View File
@@ -14,10 +14,6 @@ body {
color: #E0DBC8;
}
b {
font-weight: bold;
}
window {
display: flex;
flex-flow: column;
+122 -6
View File
@@ -6100,6 +6100,21 @@ void daAlink_c::setItemMatrix(int param_0) {
modelCalc(mpKanteraGlowModel);
}
if (mEquipItem == dItemNo_GHOST_LANTERN_e) {
simpleAnmPlay(mpGhostLanternGlowBtk);
mDoMtx_stack_c::copy(mpLinkModel->getAnmMtx(mLeftItemJntNo));
mDoMtx_stack_c::transM(-2.0f, -0.1f, -0.7f);
mDoMtx_stack_c::XYZrotM(cM_deg2s(100.0f), cM_deg2s(9.3f), cM_deg2s(183.0f));
mDoMtx_stack_c::scaleM(0.75f, 0.75f, 0.75f);
mpGhostLanternModel->setBaseTRMtx(mDoMtx_stack_c::get());
modelCalc(mpGhostLanternModel);
mDoMtx_stack_c::transS(mGhostLanternFlamePos);
mpGhostLanternGlowModel->setBaseTRMtx(mDoMtx_stack_c::get());
modelCalc(mpGhostLanternGlowModel);
}
setSwordPos();
simpleAnmPlay(m_mSwordBtk);
simpleAnmPlay(m_mSwordBrk);
@@ -6920,7 +6935,7 @@ const daAlink_BckData* daAlink_c::getMainBckData(daAlink_c::daAlink_ANM i_anmID)
{dRes_ID_ALANM_BCK_WAITHS_e, dRes_ID_ALANM_BCK_WAITHK_e},
};
if (mEquipItem == dItemNo_KANTERA_e) {
if (mEquipItem == dItemNo_KANTERA_e || mEquipItem == dItemNo_GHOST_LANTERN_e) {
if (i_anmID == ANM_WAIT) {
return &kandelaarAnm[0];
}
@@ -7562,7 +7577,12 @@ void daAlink_c::setBlendMoveAnime(f32 i_morf) {
f32 sp2C;
f32 sp28 = mpHIO->mMove.m.mFootPositionRatio;
BOOL sp24 = checkEventRun();
BOOL sp20 = checkBootsMoveAnime(1) IF_DUSK(&& !dusk::getSettings().game.enableFastIronBoots);
BOOL sp20 = checkBootsMoveAnime(1);
#if TARGET_PC
if (dusk::getSettings().game.enableFastIronBoots) {
sp20 = FALSE;
}
#endif
f32 var_f29;
@@ -8075,7 +8095,7 @@ void daAlink_c::setBlendAtnBackMoveAnime(f32 i_morf) {
daAlink_ANM var_r27;
daAlink_ANM var_r29;
if (checkBootsMoveAnime(1) IF_DUSK(&& !dusk::getSettings().game.enableFastIronBoots)) {
if (checkBootsMoveAnime(1)) {
mMaxSpeed = mpHIO->mAtnMove.m.mMaxBackwardsSpeed;
var_f27 = mpHIO->mAtnMove.m.mMinBackWalkFrame;
var_f31 = mpHIO->mAtnMove.m.mBackWalkChangeRate;
@@ -12062,7 +12082,8 @@ void daAlink_c::itemUnequip(u16 i_itemID, f32 i_playSpeed) {
u16 anm_id;
const daAlinkHIO_anm_c* anm_data;
if (i_itemID == dItemNo_BOOMERANG_e || i_itemID == dItemNo_COPY_ROD_e || i_itemID == dItemNo_KANTERA_e ||
if (i_itemID == dItemNo_BOOMERANG_e || i_itemID == dItemNo_COPY_ROD_e ||
i_itemID == dItemNo_KANTERA_e || i_itemID == dItemNo_GHOST_LANTERN_e ||
i_itemID == dItemNo_HOOKSHOT_e || checkBottleItem(i_itemID))
{
anm_id = dRes_ID_ALANM_BCK_TAKEL_e;
@@ -14152,6 +14173,11 @@ BOOL daAlink_c::setItemModel() {
}
}
if (mEquipItem == dItemNo_GHOST_LANTERN_e) {
setGhostLanternModel();
return 1;
}
if (mEquipItem == dItemNo_KANTERA_e) {
setKandelaarModel();
return 1;
@@ -14493,6 +14519,7 @@ enum daAlink_ItemProc {
/* 13 */ ITEM_PROC_BOTTLE_SWING,
/* 14 */ ITEM_PROC_NOT_USE_ITEM,
/* 15 */ ITEM_PROC_GRASS_WHISTLE,
/* 16 */ ITEM_PROC_GHOST_LANTERN,
};
int daAlink_c::changeItemTriggerKeepProc(u8 i_selItemIdx, int i_procType) {
@@ -14517,7 +14544,8 @@ int daAlink_c::changeItemTriggerKeepProc(u8 i_selItemIdx, int i_procType) {
} else {
procKandelaarPourInit();
}
} else if (i_procType == ITEM_PROC_FISHING_FOOD) {
}
else if (i_procType == ITEM_PROC_FISHING_FOOD) {
procFishingFoodInit();
} else if (i_procType == ITEM_PROC_BOOTS_EQUIP) {
procBootsEquipInit();
@@ -14822,6 +14850,43 @@ void daAlink_c::deleteEquipItem(BOOL i_isPlaySound, BOOL i_isDeleteKantera) {
}
}
#if TARGET_PC
void daAlink_c::setGhostLanternLight() {
const daAlinkHIO_huLight_c1* light_m = &mpHIO->mItem.mGhostLanternPL.m;
BOOL var_r28 = false;
f32 lightPower = 0.0f;
daE_HP_c* foundPoe = (daE_HP_c*)fopAcM_Search(srchPoe, this);
if (mEquipItem == dItemNo_GHOST_LANTERN_e && foundPoe != NULL) {
lightPower = 1.0f;
}
cLib_chaseF(&current_ghost_lantern_light_power, lightPower, 0.25f);
cXyz spB8;
f32 var_f27;
if (current_ghost_lantern_light_power > 0.0f) {
GXColor sp30 = {(u8)light_m->mColorR, (u8)light_m->mColorG, (u8)light_m->mColorB, 0xFF};
sp30.r = 120;
sp30.g = 150;
sp30.b = 150;
Vec sp5C = {0.0f, light_m->mYOffset, light_m->mZOffset};
f32 var_f26;
spB8 = mGhostLanternFlamePos;
var_f27 = 0.0f;
var_f26 = cM_sht2d(-shape_angle.y);
dKy_WolfEyeLight_set(&spB8, var_f27 + light_m->mXAngle, var_f26,
(light_m->mWidth * current_ghost_lantern_light_power) / light_m->mPower, &sp30, current_ghost_lantern_light_power,
light_m->mAngleAttenuationType,
light_m->mDistanceAttenuationType);
}
}
#endif
void daAlink_c::setLight() {
const daAlinkHIO_huLight_c1* light_m = &mpHIO->mItem.mLanternPL.m;
BOOL var_r28 = false;
@@ -18260,7 +18325,8 @@ int daAlink_c::execute() {
resetUpperAnime(UPPER_2, 5.0f);
}
if (mEquipItem == dItemNo_KANTERA_e && checkNoUpperAnime() && !checkKandelaarEquipAnime() &&
if ((mEquipItem == dItemNo_KANTERA_e || mEquipItem == dItemNo_GHOST_LANTERN_e) &&
checkNoUpperAnime() && !checkKandelaarEquipAnime() &&
(checkModeFlg(MODE_UNK_1000) || mProcID == PROC_CROUCH))
{
if (checkReinRide()) {
@@ -18611,8 +18677,29 @@ int daAlink_c::execute() {
setCollision();
setAttentionPos();
setLight();
#if TARGET_PC
setGhostLanternLight();
#endif
setEffect();
if (mEquipItem == dItemNo_GHOST_LANTERN_e) {
cXyz effscale(0.75f, 0.75f, 0.75f);
static u16 particleNmaeDt[2] = {
0x8789,
0x878A,
};
for (s32 i = 0; i < 2; i++) {
ghostLanternFlameEffect[i] = dComIfGp_particle_set(ghostLanternFlameEffect[i], particleNmaeDt[i],
&mGhostLanternFlamePos, 0, &effscale);
}
} else {
for (s32 i = 0; i < 2; i++) {
stopDrawParticle(ghostLanternFlameEffect[i]);
}
}
if (mClothesChangeWaitTimer != 0) {
mDoMtx_stack_c::copy(mpLinkModel->getBaseTRMtx());
@@ -19314,6 +19401,10 @@ void daAlink_c::shadowDraw() {
dComIfGd_addRealShadow(shadowID, mpKanteraModel);
}
if (mEquipItem == dItemNo_GHOST_LANTERN_e) {
dComIfGd_addRealShadow(shadowID, mpGhostLanternModel);
}
if (checkEquipHeavyBoots()) {
for (int i = 0; i < 2; i++) {
dComIfGd_addRealShadow(shadowID, mpLinkBootModels[i]);
@@ -19474,6 +19565,22 @@ int daAlink_c::draw() {
}
}
if (mEquipItem == dItemNo_GHOST_LANTERN_e) {
daE_HP_c* foundPoe = (daE_HP_c*)fopAcM_Search(srchPoe, this);
for (s32 i = 0; i < 2; i++) {
JPABaseEmitter* emitter_gl = dComIfGp_particle_getEmitter(ghostLanternFlameEffect[i]);
if (emitter_gl != NULL) {
emitter_gl->setLocalTranslation({2.5f, -15.0f, 0.0f});
if (checkPlayerNoDraw() || foundPoe == NULL) {
emitter_gl->stopDrawParticle();
} else {
emitter_gl->playDrawParticle();
}
}
}
}
if (mClothesChangeWaitTimer != 0) {
if (mProcID == PROC_METAMORPHOSE) {
if (mProcVar3.field_0x300e > 0) {
@@ -19799,6 +19906,15 @@ int daAlink_c::draw() {
basicModelDraw(mpKanteraGlowModel);
}
if (mEquipItem == dItemNo_GHOST_LANTERN_e) {
daE_HP_c* foundPoe = (daE_HP_c*)fopAcM_Search(srchPoe, this);
modelDraw(mpGhostLanternModel, isPlayerNoDraw);
if (foundPoe != NULL) {
preGhostLanternDraw();
modelDraw(mpGhostLanternGlowModel, isPlayerNoDraw);
}
}
if (checkEquipHeavyBoots()) {
GXColorS10 color = tevStr.TevColor;
for (int i = 0; i < 2; i++) {
+1 -1
View File
@@ -2184,7 +2184,7 @@ void daAlink_c::setGetSubBgm(int i_itemNo) {
/* dItemNo_NOENTRY_222_e */ SETYPE_NONE,
/* dItemNo_NOENTRY_223_e */ SETYPE_NONE,
/* dItemNo_POU_SPIRIT_e */ SETYPE_ITEM_GET_POU,
/* dItemNo_NOENTRY_225_e */ SETYPE_NONE,
/* dItemNo_GHOST_LANTERN_e */ SETYPE_ITEM_GET,
/* dItemNo_NOENTRY_226_e */ SETYPE_NONE,
/* dItemNo_NOENTRY_227_e */ SETYPE_NONE,
/* dItemNo_NOENTRY_228_e */ SETYPE_NONE,
+121
View File
@@ -9,6 +9,7 @@
#include "d/actor/d_a_tag_ss_drink.h"
#include "m_Do/m_Do_lib.h"
#include "SSystem/SComponent/c_math.h"
#include "d/actor/d_a_e_hp.h"
static fopAc_ac_c* daAlink_searchTagKandelaar(fopAc_ac_c* i_actor, void* i_data) {
UNUSED(i_data);
@@ -138,6 +139,50 @@ int daAlink_c::kandelaarModelCallBack() {
return 1;
}
int daAlink_c::ghostLanternModelCallBack() {
cXyz sp44;
mDoMtx_multVecZero(J3DSys::mCurrentMtx, &sp44);
ghost_lantern_0x3630 = ghost_lantern_0x3624;
ghost_lantern_0x3624 = mGhostLanternFlamePos;
cXyz sp38 = (mGhostLanternFlamePos - sp44) + ghost_lantern_0x3618;
sp38.y -= 3.0f;
cXyz sp2C;
mDoMtx_multVec(J3DSys::mCurrentMtx, &cXyz::BaseZ, &sp2C);
s16 var_r29 = sp2C.atan2sX_Z();
mDoMtx_stack_c::YrotS(-var_r29);
mDoMtx_stack_c::multVec(&sp38, &sp38);
s16 var_r28 = cLib_minMaxLimit<s16>(cM_atan2s(-sp38.z, -sp38.y), -0x1800, 0x1800);
s16 var_r27 = cLib_minMaxLimit<s16>(cM_atan2s(sp38.x, JMAFastSqrt(SQUARE(sp38.y) + SQUARE(sp38.z))), -0x1800, 0x1800);
mDoMtx_stack_c::transS(sp44);
if (mProcID != PROC_OPEN_TREASURE && (mProcID != PROC_GET_ITEM || mProcVar4.field_0x3010 == 0)) {
mDoMtx_stack_c::ZXYrotM(var_r28, var_r29, var_r27);
}
static Vec const ghostLanternOffset = {0.0f, -20.0f, 0.0f};
mDoMtx_stack_c::multVec(&ghostLanternOffset, &mGhostLanternFlamePos);
ghost_lantern_0x3618 = (mGhostLanternFlamePos - ghost_lantern_0x3624) * 0.9f;
if (!checkEndResetFlg1(ERFLG1_UNK_8) && mpGhostLanternModel != nullptr) {
f32 scale = JMAFastSqrt(SQUARE(J3DSys::mCurrentMtx[0][0]) + SQUARE(J3DSys::mCurrentMtx[1][0]) + SQUARE(J3DSys::mCurrentMtx[2][0]));
mDoMtx_stack_c::transS(J3DSys::mCurrentMtx[0][3], J3DSys::mCurrentMtx[1][3], J3DSys::mCurrentMtx[2][3]);
mDoMtx_stack_c::ZXYrotM(var_r28, var_r29, var_r27);
mDoMtx_stack_c::ZXYrotM(0, 0, -16384);
mDoMtx_stack_c::scaleM(scale, scale, scale);
mpGhostLanternModel->setAnmMtx(1, mDoMtx_stack_c::get());
cMtx_copy(mDoMtx_stack_c::get(), J3DSys::mCurrentMtx);
}
return 1;
}
static int daAlink_kandelaarModelCallBack(J3DJoint* i_joint, int param_1) {
UNUSED(i_joint);
@@ -150,6 +195,18 @@ static int daAlink_kandelaarModelCallBack(J3DJoint* i_joint, int param_1) {
return 1;
}
static int daAlink_ghostLanternModelCallBack(J3DJoint* i_joint, int param_1) {
UNUSED(i_joint);
daAlink_c* player_p = (daAlink_c*)j3dSys.getModel()->getUserArea();
if (param_1 == 0) {
player_p->ghostLanternModelCallBack();
}
return 1;
}
cXyz* daAlink_c::getKandelaarFlamePos() {
if ((!checkNoResetFlg2(daPy_FLG2(FLG2_UNK_20000 | FLG2_UNK_1)) && !checkEndResetFlg1(ERFLG1_UNK_4)) ||
checkWolf() || !checkNoResetFlg1(FLG1_UNK_80))
@@ -164,6 +221,60 @@ BOOL daAlink_c::checkKandelaarEquipAnime() const {
return checkUpperAnime(dRes_ID_ALANM_BCK_WAITHK_e) || checkUpperAnime(dRes_ID_ALANM_BCK_WAITK_e);
}
void* daAlink_c::srchPoe(void* i_actor, void* i_this) {
if (i_actor != NULL && i_actor != i_this) {
if (fopAcM_IsExecuting(fopAcM_GetID(i_actor)) && fopAcM_GetName(i_actor) == fpcNm_E_HP_e) {
return i_actor;
}
}
return NULL;
}
void daAlink_c::preGhostLanternDraw() {
J3DMaterial* mat_p = mpGhostLanternGlowModel->getModelData()->getMaterialNodePointer(0);
J3DGXColorS10 color;
color.r = 120;
color.g = 150;
color.b = 150;
color.a = 255;
mat_p->setTevColor(1, &color);
color.r = 0;
color.g = 60;
color.b = 101;
mat_p->setTevColor(2, &color);
cXyz proj;
mDoLib_project(&mGhostLanternFlamePos, &proj);
camera_process_class* camera_p = dComIfGp_getCamera(0);
f32 trimHeight;
if (camera_p != NULL) {
trimHeight = camera_p->mCamera.TrimHeight();
} else {
trimHeight = 0.0f;
}
if (proj.x > 0.0f && proj.x < FB_WIDTH && proj.y > trimHeight && proj.y < FB_HEIGHT - trimHeight) {
dComIfGd_peekZ(proj.x, proj.y, &field_0x32c8);
} else {
field_0x32c8 = 0;
}
f32 near_ = dComIfGd_getView()->near_;
f32 far_ = dComIfGd_getView()->far_;
mDoLib_pos2camera(&mGhostLanternFlamePos, &proj);
proj.z += 30.0f;
if (proj.z > -0.01f) {
proj.z = -0.01f;
}
field_0x344c = ((near_ + (far_ * near_) / proj.z) / (far_ - near_) + 1.0f) * 1.6777215E7f;
}
void daAlink_c::preKandelaarDraw() {
J3DMaterial* mat_p = mpKanteraGlowModel->getModelData()->getMaterialNodePointer(0);
@@ -208,6 +319,16 @@ void daAlink_c::preKandelaarDraw() {
field_0x344c = ((near_ + (far_ * near_) / proj.z) / (far_ - near_) + 1.0f) * 1.6777215E7f;
}
void daAlink_c::setGhostLanternModel() {
field_0x2f94 = 0;
mDoMtx_multVecZero(mpLinkModel->getAnmMtx(mLeftItemJntNo), &mGhostLanternFlamePos);
ghost_lantern_0x3630 = ghost_lantern_0x3624;
ghost_lantern_0x3624 = mGhostLanternFlamePos;
ghost_lantern_0x3618 = cXyz::Zero;
}
void daAlink_c::setKandelaarModel() {
field_0x2f94 = 0;
+14 -1
View File
@@ -300,6 +300,7 @@ void daAlink_c::changeWolf() {
mAtSph.SetR(40.0f);
mpKanteraModel = NULL;
mpGhostLanternModel = NULL;
mpLinkHatModel = NULL;
mpLinkFaceModel = NULL;
mpLinkHandModel = NULL;
@@ -406,12 +407,20 @@ void daAlink_c::changeLink(int param_0) {
modelData = static_cast<J3DModelData*>(dComIfG_getObjectRes(mArcName, "ef_ktGlow.bmd"));
mpKanteraGlowModel = initModel(modelData, 0x200);
mpKanteraGlowBtk = static_cast<J3DAnmTextureSRTKey*>(dComIfG_getObjectRes(mArcName, "ef_ktGlow.btk"));
mpKanteraGlowBtk->setFrame(0.0f);
mpKanteraGlowBtk->searchUpdateMaterialID(modelData);
modelData->entryTexMtxAnimator(mpKanteraGlowBtk);
mpGhostLanternModel = initModelEnv(static_cast<J3DModelData*>(dComIfG_getObjectRes("E_HP", "hp_ori.bmd")), 0);
modelData = static_cast<J3DModelData*>(dComIfG_getObjectRes(mArcName, "ef_ktGlow.bmd"));
mpGhostLanternGlowModel = initModel(modelData, 0x200);
mpGhostLanternGlowBtk = static_cast<J3DAnmTextureSRTKey*>(dComIfG_getObjectRes(mArcName, "ef_ktGlow.btk"));
mpGhostLanternGlowBtk->setFrame(0.0f);
mpGhostLanternGlowBtk->searchUpdateMaterialID(modelData);
modelData->entryTexMtxAnimator(mpGhostLanternGlowBtk);
mWoodSwordModel = initModel(static_cast<J3DModelData*>(dComIfG_getObjectRes(mArcName, "al_SWB.bmd")), 0);
mDoExt_setCurrentHeap(current_heap);
@@ -504,6 +513,10 @@ void daAlink_c::changeLink(int param_0) {
mpKanteraModel->setUserArea((uintptr_t)this);
mpKanteraModel->getModelData()->getJointNodePointer(1)->setCallBack(daAlink_kandelaarModelCallBack);
mpGhostLanternModel->setUserArea((uintptr_t)this);
mpGhostLanternModel->getModelData()->getJointNodePointer(1)->setCallBack(daAlink_ghostLanternModelCallBack);
mZ2Link.setLinkState(var_r27);
#if VERSION != VERSION_SHIELD_DEBUG
-18
View File
@@ -157,21 +157,6 @@ static void* s_h_sub(void* i_actor, void* i_data) {
return NULL;
}
#if TARGET_PC
static void sort_target_info_by_id() {
for (int i = 1; i < target_info_count; i++) {
void* key = target_info[i];
fpc_ProcID key_id = fopAcM_GetID(key);
int j = i - 1;
while (j >= 0 && fopAcM_GetID(target_info[j]) > key_id) {
target_info[j + 1] = target_info[j];
j--;
}
target_info[j + 1] = key;
}
}
#endif
static daPillar_c* search_hasira(e_mk_class* i_this) {
fopEn_enemy_c* actor = (fopEn_enemy_c*)&i_this->actor;
daPillar_c* pillar_p;
@@ -185,9 +170,6 @@ static daPillar_c* search_hasira(e_mk_class* i_this) {
if (i_this->firstHasiraFlag == 0) {
i_this->firstHasiraFlag++;
#if TARGET_PC
sort_target_info_by_id();
#endif
return (daPillar_c*)target_info[TREG_S(7) + 5];
}
+4 -10
View File
@@ -22,7 +22,6 @@
#if TARGET_PC
#include "dusk/dusk.h"
#include "dusk/frame_interpolation.h"
namespace {
// FRAME INTERP NOTE: Sim tick control point snapshots for interpolation
@@ -33,7 +32,6 @@ int s_horseReinSimNumPrev;
int s_horseReinSimNumCurr;
bool s_horseReinSimPrevValid;
bool s_horseReinSimCurrValid;
uint64_t s_horseReinSimRolledSeq;
} // namespace
#endif
@@ -3035,14 +3033,10 @@ void daHorse_c::copyReinPos() {
}
#if TARGET_PC
if (field_0x1204 > 0) {
const uint64_t simSeq = dusk::frame_interp::sim_tick_seq();
if (simSeq != s_horseReinSimRolledSeq) {
s_horseReinSimRolledSeq = simSeq;
if (s_horseReinSimCurrValid && s_horseReinSimNumCurr > 0) {
memcpy(s_horseReinSimPrev, s_horseReinSimCurr, s_horseReinSimNumCurr * sizeof(cXyz));
s_horseReinSimNumPrev = s_horseReinSimNumCurr;
s_horseReinSimPrevValid = true;
}
if (s_horseReinSimCurrValid && s_horseReinSimNumCurr > 0) {
memcpy(s_horseReinSimPrev, s_horseReinSimCurr, s_horseReinSimNumCurr * sizeof(cXyz));
s_horseReinSimNumPrev = s_horseReinSimNumCurr;
s_horseReinSimPrevValid = true;
}
memcpy(s_horseReinSimCurr, m_reinLine.getPos(0), field_0x1204 * sizeof(cXyz));
s_horseReinSimNumCurr = field_0x1204;
-4
View File
@@ -1967,11 +1967,7 @@ static void demo_camera_shop(npc_henna_class* i_this) {
i_this->mMsgFlow.init(actor, 0x365, 0, NULL);
/* dSv_event_flag_c::KORO2_ALLCLEAR - Fishing - After all stages (8-8) of roll goal game cleared */
dComIfGs_onEventBit(dSv_event_flag_c::saveBitLabels[0x335]);
#if TARGET_PC
dComIfGp_setItemRupeeCount(dComIfGs_getRupeeMax());
#else
dComIfGp_setItemRupeeCount(1000);
#endif
} else if ((lbl_82_bss_91 & 0x38) == 0) {
i_this->mMsgFlow.init(actor, 0x34f, 0, NULL);
/* dSv_event_flag_c::F_0469 - Fishing Pond - Reserved for fishing */
+1 -2
View File
@@ -299,8 +299,7 @@ int daObjDrop_c::modeParentWait() {
#if TARGET_PC
static inline BOOL checkGetCargoRide() {
if (daPy_getPlayerActorClass()->checkCargoCarry() &&
strcmp(dComIfGp_getStartStageName(), "F_SP112") == 0 &&
if ((daPy_getPlayerActorClass()->checkCargoCarry() && strcmp(dComIfGp_getStartStageName(), "F_SP112") == 0) ||
dComIfGs_isLightDropGetFlag(dComIfGp_getStartStageDarkArea()))
{
return true;
+2 -1
View File
@@ -143,12 +143,13 @@ void dBrightCheck_c::modeMove() {
if (mDoCPd_c::getTrigA(PAD_1) || mDoCPd_c::getTrigStart(PAD_1)) {
mDoAud_seStart(Z2SE_ENTER_GAME, NULL, 0, 0);
#ifdef TARGET_PC
dusk::speedrun::start();
if (dusk::getSettings().game.speedrunMode && !dusk::getSettings().game.hideTvSettingsScreen) {
// start a new run if a run isn't already in progress
if (!dusk::m_speedrunInfo.m_isRunStarted) {
dusk::resetForSpeedrunMode();
dusk::m_speedrunInfo.startRun();
dusk::speedrun::start();
}
}
-8
View File
@@ -19,7 +19,6 @@
#include "d/d_timer.h"
#include "f_op/f_op_msg_mng.h"
#include "f_op/f_op_scene_mng.h"
#include "m_Do/m_Do_MemCard.h"
#include "m_Do/m_Do_Reset.h"
#include "m_Do/m_Do_controller_pad.h"
#include "m_Do/m_Do_graphic.h"
@@ -1239,13 +1238,6 @@ BOOL dComIfG_resetToOpening(scene_class* i_scene) {
}
#endif
#ifdef TARGET_PC
if (!mDoMemCd_isCardCommNone()) {
return 0;
}
g_mDoMemCd_control.SaveSync();
#endif
dComIfG_changeOpeningScene(i_scene, fpcNm_OPENING_SCENE_e);
mDoAud_bgmStop(30);
mDoAud_resetProcess();
+10 -2
View File
@@ -236,7 +236,7 @@ static void (*item_func_ptr[256])() = {
item_func_noentry,
item_func_noentry,
item_func_POU_SPIRIT,
item_func_noentry,
item_func_GHOST_LANTERN,
item_func_noentry,
item_func_noentry,
item_func_noentry,
@@ -504,7 +504,7 @@ static int (*item_getcheck_func_ptr[256])() = {
item_getcheck_func_noentry,
item_getcheck_func_noentry,
item_getcheck_func_POU_SPIRIT,
item_getcheck_func_noentry,
item_getcheck_func_GHOST_LANTERN,
item_getcheck_func_noentry,
item_getcheck_func_noentry,
item_getcheck_func_noentry,
@@ -791,6 +791,10 @@ void item_func_IRONBALL() {
dComIfGs_setItem(SLOT_6, dItemNo_IRONBALL_e);
}
void item_func_GHOST_LANTERN() {
dComIfGs_setItem(SLOT_7, dItemNo_GHOST_LANTERN_e);
}
void item_func_BOW() {
dComIfGs_setItem(SLOT_4, dItemNo_BOW_e);
dComIfGs_setArrowNum(30);
@@ -1453,6 +1457,10 @@ int item_getcheck_func_IRONBALL() {
return dComIfGs_getItem(SLOT_6, true) == dItemNo_IRONBALL_e ? TRUE : FALSE;
}
int item_getcheck_func_GHOST_LANTERN() {
return dComIfGs_getItem(SLOT_7, true) == dItemNo_GHOST_LANTERN_e ? TRUE : FALSE;
}
int item_getcheck_func_BOW() {
return dComIfGs_getItem(SLOT_4, false) == dItemNo_BOW_e ? TRUE : FALSE;
}
-8
View File
@@ -26,10 +26,6 @@
#include "f_op/f_op_overlap_mng.h"
#include "m_Do/m_Do_controller_pad.h"
#ifdef TARGET_PC
#include "dusk/frame_interpolation.h"
#endif
class dDlst_MENU_CAPTURE_c : public dDlst_base_c {
public:
virtual void draw() {
@@ -1092,10 +1088,6 @@ void dMw_c::dMw_ring_create(u8 i_origin) {
}
mpCapture->setCaptureFlag();
#ifdef TARGET_PC
dusk::frame_interp::request_presentation_sync();
#endif
}
bool dMw_c::dMw_ring_delete() {
-13
View File
@@ -18,9 +18,6 @@
#include "d/d_pane_class.h"
#include "dusk/frame_interpolation.h"
#include <cstring>
#if TARGET_PC
#include "dusk/string.hpp"
#endif
#if VERSION == VERSION_GCN_JPN
#define STR_BUF_LEN 528
@@ -2930,12 +2927,6 @@ bool dMeterButton_c::isClose() {
}
void dMeterButton_c::setString(char* i_string, u8 i_button, u8 param_2, u8 param_3) {
#if TARGET_PC
char* i_string_full = i_string;
char i_string_buf[sizeof(mButtonText[0])];
dusk::SafeStringCopyTruncate(i_string_buf, i_string);
i_string = i_string_buf;
#endif
if (strcmp(mButtonText[param_2], i_string) != 0 || field_0x4be[param_2] != i_button) {
if (param_2 == 0 && strcmp(mButtonText[1], i_string) == 0 &&
((i_button == BUTTON_A_e && field_0x4be[1] == BUTTON_A_e) ||
@@ -3031,10 +3022,6 @@ void dMeterButton_c::setString(char* i_string, u8 i_button, u8 param_2, u8 param
strcpy(mButtonText[param_2], i_string);
#if TARGET_PC
i_string = i_string_full;
#endif
if (param_2 == 0) {
if (param_3 != 0) {
field_0x4d9 = param_2;
+7 -10
View File
@@ -77,16 +77,16 @@ static const char* l_mojiEisu[65] = {
// That can't work on a modern platform, so instead I've filled them out ahead of time.
static const char* l_mojiEisuPal_1[65] = {
"A", "N", "\xC0", "\xCF", "1", "B", "O", "\xC1", "\xD0", "2", "C", "P", "\xC2", "\xD1", "3", "D", "Q",
"\xC4", "\xD2", "4", "E", "R", "\xC6", "\xD3", "5", "F", "S", "\xC7", "\xD4", "6", "G", "T", "\xC8", "\xD6",
"7", "H", "U", "\xC9", "\x8C", "8", "I", "V", "\xCA", "\xD9", "9", "J", "W", "\xCB", "\xDA", "0", "K",
"X", "\xCC", "\xDB", ",", "L", "Y", "\xCD", "\xDC", ".", "M", "Z", "\xCE", "\x2D", " ",
"\xC3", "\xD2", "4", "E", "R", "\xC4", "\xD3", "5", "F", "S", "\xC5", "\xD4", "6", "G", "T", "\xC6", "\xD5",
"7", "H", "U", "\xC7", "\xD6", "8", "I", "V", "\xC8", "\xD7", "9", "J", "W", "\xC9", "\xD8", "0", "K",
"X", "\xCA", "\xD9", ",", "L", "Y", "\xCB", "\xDA", ".", "M", "Z", "\xCC", "\xDB", " ",
};
static const char* l_mojiEisuPal_2[65] = {
"a", "n", "\xE0", "\xEF", "1", "b", "o", "\xE1", "\xF0", "2", "c", "p", "\xE2", "\xF1", "3", "d", "q",
"\xE4", "\xF2", "4", "e", "r", "\xE6", "\xF3", "5", "f", "s", "\xE7", "\xF4", "6", "g", "t", "\xE8",
"\xF6", "7", "h", "u", "\xE9", "\x9C", "8", "i", "v", "\xEA", "\xF9", "9", "j", "w", "\xEB", "\xFA", "0",
"k", "x", "\xEC", "\xFB", ",", "l", "y", "\xED", "\xFC", ".", "m", "z", "\xEE", "\xDF", " ",
"\xE3", "\xF2", "4", "e", "r", "\xE4", "\xF3", "5", "f", "s", "\xE5", "\xF4", "6", "g", "t", "\xE6",
"\xF5", "7", "h", "u", "\xE7", "\xF6", "8", "i", "v", "\xE8", "\xF7", "9", "j", "w", "\xE9", "\xF8", "0",
"k", "x", "\xEA", "\xF9", ",", "l", "y", "\xEB", "\xFA", ".", "m", "z", "\xEC", "\xFB", " ",
};
#elif REGION_PAL
static const char* l_mojiEisuPal_1[65] = {
@@ -295,7 +295,6 @@ void dName_c::_move() {
}
} else {
#endif
#if !TARGET_PC
if (mDoCPd_c::getTrigRight(PAD_1)) {
// BUG: this check only fails if the cursor is at exactly 7
// setMoji allows the cursor to reach 8, which is out of bounds here
@@ -312,9 +311,7 @@ void dName_c::_move() {
mCurPos--;
nameCursorMove();
}
} else
#endif
if (mDoCPd_c::getTrigB(PAD_1)) {
} else if (mDoCPd_c::getTrigB(PAD_1)) {
if (mCurPos == 0) {
mDoAud_seStart(Z2SE_SY_MENU_BACK, 0, 0, 0);
field_0x2ac = mSelProc;
+3
View File
@@ -1481,6 +1481,9 @@ void dScnLogo_c::dvdDataLoad() {
OS_REPORT("\x1b[32m%d archiveHeap->getTotalFreeSize %08x\n\x1b[m", 2421, archiveHeap->getTotalFreeSize());
archiveHeap->dump_sort();
rt = dComIfG_setObjectRes("E_HP", (u8)0, NULL);
JUT_ASSERT(2425, rt == 1);
rt = dComIfG_setObjectRes("Alink", (u8)0, NULL);
JUT_ASSERT(2429, rt == 1);
-2
View File
@@ -10,7 +10,6 @@
#include "d/d_meter2_info.h"
#include "d/d_s_name.h"
#include "dusk/imgui/ImGuiConsole.hpp"
#include "dusk/livesplit.h"
#include "dusk/memory.h"
#include "dusk/speedrun.h"
#include "dusk/settings.h"
@@ -423,7 +422,6 @@ void dScnName_c::changeGameScene() {
if (!dusk::m_speedrunInfo.m_isRunStarted) {
dusk::resetForSpeedrunMode();
dusk::m_speedrunInfo.startRun();
dusk::speedrun::start();
}
}
+10 -8
View File
@@ -30,9 +30,7 @@
#if TARGET_PC
#include "dusk/settings.h"
#include <f_ap/f_ap_game.h>
#include "dusk/string.hpp"
#define strcpy dusk::SafeStringCopy
#include <dusk/autosave.h>
#endif
static u8 dSv_item_rename(u8 i_itemNo) {
@@ -351,6 +349,10 @@ void dSv_player_item_c::setItem(int i_slotNo, u8 i_itemNo) {
dComIfGp_setSelectItem(i);
}
}
#if TARGET_PC
triggerAutoSave();
#endif
}
u8 dSv_player_item_c::getItem(int i_slotNo, bool i_checkCombo) const {
@@ -430,11 +432,11 @@ u8 dSv_player_item_c::getItem(int i_slotNo, bool i_checkCombo) const {
}
void dSv_player_item_c::setLineUpItem() {
static u8 i_item_lst[23] = {
static u8 i_item_lst[24] = {
10, 8, 6, 2, 9, 4, 3,
0, 1, 23, 20, 5, 15, 16,
17, 11, 12, 13, 14, 19, 18,
22, 21
0, 1, 7, 23, 20, 5, 15,
16, 17, 11, 12, 13, 14, 19,
18, 22, 21
};
int slot_idx = 0;
@@ -443,7 +445,7 @@ void dSv_player_item_c::setLineUpItem() {
mItemSlots[i] = dItemNo_NONE_e;
}
for (int i = 0; i < 23; i++) {
for (int i = 0; i < 24; i++) {
u8 current = i_item_lst[i];
if (mItems[current] != dItemNo_NONE_e) {
mItemSlots[slot_idx] = current;
+3 -6
View File
@@ -191,17 +191,13 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
}
bool hasJewelRod = false;
bool hasAncientDoc = false;
for (int slot = 0; slot < 24; ++slot) {
for (int slot = 0; slot < 24 && !hasJewelRod; ++slot) {
const u8 item = dComIfGs_getItem(slot, false);
if (item == dItemNo_JEWEL_ROD_e || item == dItemNo_JEWEL_BEE_ROD_e || item == dItemNo_JEWEL_WORM_ROD_e) {
hasJewelRod = true;
}
if (item == dItemNo_ANCIENT_DOCUMENT_e || item == dItemNo_ANCIENT_DOCUMENT2_e || item == dItemNo_AIR_LETTER_e) {
hasAncientDoc = true;
}
}
if (!hasJewelRod || !hasAncientDoc) {
if (!hasJewelRod) {
return;
}
@@ -216,6 +212,7 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
dItemNo_KANTERA_e,
dItemNo_PACHINKO_e,
dItemNo_HAWK_EYE_e,
dItemNo_ANCIENT_DOCUMENT_e,
dItemNo_HORSE_FLUTE_e,
};
for (u8 required : requiredWheelItems) {
+2 -16
View File
@@ -14,23 +14,9 @@ static AutoSaveFuncs AutoSaveFuncsProc[] = {
void noAutoSave() {}
bool canAutoSave() {
daAlink_c* player = (daAlink_c*)daAlink_getAlinkActorClass();
if (player == nullptr) {
return false;
}
if (player->checkCargoCarry() || player->checkCanoeRide()) {
return false;
}
return dusk::getSettings().game.autoSave && shouldAutoSave && mAutoSaveProc == 0 &&
strcmp(dComIfGp_getStartStageName(), "F_SP102") != 0 &&
strcmp(dComIfGp_getStartStageName(), "F_SP112") != 0;
}
void triggerAutoSave() {
if (canAutoSave())
if (dusk::getSettings().game.autoSave && shouldAutoSave && mAutoSaveProc == 0 &&
strcmp(dComIfGp_getStartStageName(), "F_SP102") != 0)
{
mAutoSaveProc = 1;
}
+6 -11
View File
@@ -21,7 +21,6 @@ bool g_sync_presentation = false;
float g_step = 0.0f;
bool g_is_sim_frame = false;
bool g_ui_tick_pending = false;
uint64_t g_sim_tick_seq = 0;
Recording g_current_recording;
Recording g_previous_recording;
@@ -67,18 +66,19 @@ void copy_view_to_snap(CameraSnapshot* dst, const view_class& v) {
}
inline void lerp_matrix(Mtx out, const Mtx lhs, const Mtx rhs, float step) {
const float old_weight = 1.0f - step;
for (size_t row = 0; row < 3; ++row) {
for (size_t col = 0; col < 4; ++col) {
const float l = lhs[row][col];
out[row][col] = l + (rhs[row][col] - l) * step;
out[row][col] = lhs[row][col] * old_weight + rhs[row][col] * step;
}
}
}
inline void lerp_xyz(cXyz* out, const cXyz& lhs, const cXyz& rhs, float step) {
out->x = lhs.x + (rhs.x - lhs.x) * step;
out->y = lhs.y + (rhs.y - lhs.y) * step;
out->z = lhs.z + (rhs.z - lhs.z) * step;
const float old_weight = 1.0f - step;
out->x = lhs.x * old_weight + rhs.x * step;
out->y = lhs.y * old_weight + rhs.y * step;
out->z = lhs.z * old_weight + rhs.z * step;
}
static s16 lerp_bank(s16 a, s16 b, f32 t) {
@@ -135,11 +135,6 @@ void begin_sim_tick() {
s_interpolationCallBackWork.clear();
s_cam_prev = std::move(s_cam_curr);
++g_sim_tick_seq;
}
uint64_t sim_tick_seq() {
return g_sim_tick_seq;
}
void begin_frame(bool enabled, bool is_sim_frame, float step) {
+3 -3
View File
@@ -263,7 +263,7 @@ namespace dusk {
}
if (getSettings().game.enableResetKeybind && ImGui::GetIO().KeyCtrl &&
ImGui::IsKeyReleased(ImGuiKey_R) && !fpcM_SearchByName(fpcNm_LOGO_SCENE_e))
ImGui::IsKeyPressed(ImGuiKey_R) && !fpcM_SearchByName(fpcNm_LOGO_SCENE_e))
{
JUTGamePad::C3ButtonReset::sResetSwitchPushing = true;
}
@@ -322,8 +322,8 @@ namespace dusk {
}
ImGui::PushFont(ImGuiEngine::fontLarge);
ImGuiTextCenter("Failed to initialize any graphics backend.");
ImGuiTextCenter("\nDusklight requires Vulkan 1.1+, or Direct X 12.0.");
ImGuiTextCenter("\nTry updating your Operating System and GPU drivers.");
ImGuiTextCenter("\nYour system may be misconfigured, or your hardware may not support the required versions of any of the available backends.");
ImGuiTextCenter("\nA clean reinstall of Dusklight may help. For further assistance, please visit #tech-support on the Twilit Realm Discord server.");
const auto& style = ImGui::GetStyle();
const auto retrySize = ImGui::CalcTextSize("Retry (Auto backend)");
const auto quitSize = ImGui::CalcTextSize("Quit");
+2 -1
View File
@@ -251,7 +251,7 @@ namespace dusk {
{ dItemNo_NOENTRY_222_e, {"Reserved"} },
{ dItemNo_NOENTRY_223_e, {"Reserved"} },
{ dItemNo_POU_SPIRIT_e, {"Poe Soul"} },
{ dItemNo_NOENTRY_225_e, {"Reserved"} },
{ dItemNo_GHOST_LANTERN_e, {"Ghost Lantern", ITEMTYPE_EQUIP_e} },
{ dItemNo_NOENTRY_226_e, {"Reserved"} },
{ dItemNo_NOENTRY_227_e, {"Reserved"} },
{ dItemNo_NOENTRY_228_e, {"Reserved"} },
@@ -393,6 +393,7 @@ namespace dusk {
{ SLOT_4, dItemNo_BOW_e },
{ SLOT_5, dItemNo_HAWK_EYE_e },
{ SLOT_6, dItemNo_IRONBALL_e },
{ SLOT_7, dItemNo_GHOST_LANTERN_e},
{ SLOT_8, dItemNo_COPY_ROD_e },
{ SLOT_9, dItemNo_HOOKSHOT_e },
{ SLOT_10, dItemNo_W_HOOKSHOT_e },
-13
View File
@@ -1,8 +1,5 @@
#include "dusk/settings.h"
#include "dusk/config.hpp"
#include "dusk/dusk.h"
#include <SDL3/SDL_video.h>
namespace dusk {
@@ -13,10 +10,6 @@ UserSettings g_userSettings = {
.lockAspectRatio {"video.lockAspectRatio", false},
.enableFpsOverlay {"game.enableFpsOverlay", false},
.fpsOverlayCorner {"game.fpsOverlayCorner", 0},
.windowPositionX {"video.windowPositionX", SDL_WINDOWPOS_UNDEFINED},
.windowPositionY {"video.windowPositionY", SDL_WINDOWPOS_UNDEFINED},
.windowWidth {"video.windowWidth", defaultWindowWidth * 2},
.windowHeight {"video.windowHeight", defaultWindowHeight * 2},
},
.audio = {
@@ -65,7 +58,6 @@ UserSettings g_userSettings = {
.bloomMode {"game.bloomMode", BloomMode::Dusk},
.bloomMultiplier {"game.bloomMultiplier", 1.0f},
.disableWaterRefraction {"game.disableWaterRefraction", false},
.enableTextureReplacements {"game.enableTextureReplacements", true},
.enableFrameInterpolation {"game.enableFrameInterpolation", false},
.internalResolutionScale {"game.internalResolutionScale", 0},
.shadowResolutionMultiplier {"game.shadowResolutionMultiplier", 1},
@@ -185,10 +177,6 @@ void registerSettings() {
Register(g_userSettings.video.lockAspectRatio);
Register(g_userSettings.video.enableFpsOverlay);
Register(g_userSettings.video.fpsOverlayCorner);
Register(g_userSettings.video.windowPositionX);
Register(g_userSettings.video.windowPositionY);
Register(g_userSettings.video.windowWidth);
Register(g_userSettings.video.windowHeight);
// Audio
Register(g_userSettings.audio.masterVolume);
@@ -230,7 +218,6 @@ void registerSettings() {
Register(g_userSettings.game.bloomMode);
Register(g_userSettings.game.bloomMultiplier);
Register(g_userSettings.game.disableWaterRefraction);
Register(g_userSettings.game.enableTextureReplacements);
Register(g_userSettings.game.internalResolutionScale);
Register(g_userSettings.game.shadowResolutionMultiplier);
Register(g_userSettings.game.enableDepthOfField);
+48 -83
View File
@@ -37,7 +37,7 @@ Rml::String current_controller_name(int port) {
Rml::String controller_index_name(u32 index) {
const char* name = PADGetNameForControllerIndex(index);
if (name == nullptr) {
return fmt::format("Device {}", index + 1);
return fmt::format("Controller {}", index + 1);
}
return name;
}
@@ -124,7 +124,7 @@ Rml::String native_axis_name(const PADAxisMapping& mapping, SDL_Gamepad* gamepad
return native_button_name(gamepad, static_cast<u32>(mapping.nativeButton));
}
return "Not Bound";
return "Not bound";
}
bool is_dpad_button(PADButton button) {
@@ -162,7 +162,7 @@ bool keyboard_escape_pressed() {
Rml::String keyboard_key_name(s32 scancode) {
if (scancode == PAD_KEY_INVALID) {
return "Not Bound";
return "Not bound";
}
switch (scancode) {
case PAD_KEY_MOUSE_LEFT:
@@ -303,7 +303,7 @@ void ControllerConfigWindow::build_port_tab(Rml::Element* content, int port) {
});
};
addPageButton(Page::Controller, "Device", [port] { return current_controller_name(port); }, [] { return false; });
addPageButton(Page::Controller, "Controller", [port] { return current_controller_name(port); }, [] { return false; });
addPageButton(Page::Buttons, "Buttons", [] { return Rml::String(">"); }, [] { return false; });
addPageButton(Page::Triggers, "Triggers", [] { return Rml::String(">"); }, [] { return false; });
addPageButton(Page::Sticks, "Sticks", [] { return Rml::String(">"); }, [] { return false; });
@@ -349,14 +349,7 @@ void ControllerConfigWindow::build_port_tab(Rml::Element* content, int port) {
rightPane, [](Pane& pane) {
pane.add_text("Treat analog trigger movement as digital L and R button input.");
});
leftPane.register_control(leftPane.add_button("Restore Default Controls").on_pressed([this, port] {
mDoAud_seStartMenu(kSoundClick);
PADRestoreDefaultMapping(port);
}),
rightPane, [](Pane& pane) {
pane.clear();
pane.add_text("Restores all binding configurations for the currently selected device to their defaults.");
});
render_page(rightPane, port, mPage);
}
@@ -372,7 +365,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
[port] { return PADGetIndexForPort(port) < 0 && !keyboard_active(port); },
})
.on_pressed([this, port] {
mDoAud_seStartMenu(kSoundClick);
mDoAud_seStartMenu(kSoundItemChange);
cancel_pending_binding();
PADClearPort(port);
PADSetKeyboardActive(static_cast<u32>(port), FALSE);
@@ -385,7 +378,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
.isSelected = [port] { return keyboard_active(port); },
})
.on_pressed([this, port] {
mDoAud_seStartMenu(kSoundClick);
mDoAud_seStartMenu(kSoundItemChange);
cancel_pending_binding();
PADClearPort(port);
PADSetKeyboardActive(static_cast<u32>(port), TRUE);
@@ -395,7 +388,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
const u32 controllerCount = PADCount();
if (controllerCount == 0) {
pane.add_text("No Device Detected");
pane.add_text("No controllers detected");
break;
}
@@ -407,7 +400,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
[port, i] { return PADGetIndexForPort(port) == static_cast<s32>(i); },
})
.on_pressed([this, port, i] {
mDoAud_seStartMenu(kSoundClick);
mDoAud_seStartMenu(kSoundItemChange);
cancel_pending_binding();
PADSetKeyboardActive(static_cast<u32>(port), FALSE);
PADSetPortForIndex(i, port);
@@ -432,18 +425,17 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
PADKeyButtonBinding* bindings =
PADGetKeyButtonBindings(static_cast<u32>(port), &count);
if (bindings == nullptr) {
return Rml::String("Not Bound");
return Rml::String("Not bound");
}
for (u32 i = 0; i < PAD_BUTTON_COUNT; ++i) {
if (bindings[i].padButton == button) {
return keyboard_key_name(bindings[i].scancode);
}
}
return Rml::String("Not Bound");
return Rml::String("Not bound");
},
})
.on_pressed([this, port, button] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
@@ -470,7 +462,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
u32 buttonCount = 0;
PADButtonMapping* mappings = PADGetButtonMappings(port, &buttonCount);
if (mappings == nullptr) {
pane.add_text("No Device Selected");
pane.add_text("No controller selected");
break;
}
@@ -494,7 +486,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
},
})
.on_pressed([this, port, &mapping] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
@@ -521,7 +512,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
},
})
.on_pressed([this, port, &mapping] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
@@ -545,18 +535,17 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
PADKeyButtonBinding* bindings =
PADGetKeyButtonBindings(static_cast<u32>(port), &count);
if (bindings == nullptr) {
return Rml::String("Not Bound");
return Rml::String("Not bound");
}
for (u32 i = 0; i < PAD_BUTTON_COUNT; ++i) {
if (bindings[i].padButton == button) {
return keyboard_key_name(bindings[i].scancode);
}
}
return Rml::String("Not Bound");
return Rml::String("Not bound");
},
})
.on_pressed([this, port, button] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
@@ -577,18 +566,17 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
PADKeyAxisBinding* bindings =
PADGetKeyAxisBindings(static_cast<u32>(port), &count);
if (bindings == nullptr) {
return Rml::String("Not Bound");
return Rml::String("Not bound");
}
for (u32 i = 0; i < PAD_AXIS_COUNT; ++i) {
if (bindings[i].padAxis == axis) {
return keyboard_key_name(bindings[i].scancode);
}
}
return Rml::String("Not Bound");
return Rml::String("Not bound");
},
})
.on_pressed([this, port, axis] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
@@ -611,7 +599,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
u32 buttonCount = 0;
PADButtonMapping* buttons = PADGetButtonMappings(port, &buttonCount);
if (axes == nullptr && buttons == nullptr) {
pane.add_text("No Device Selected");
pane.add_text("No controller selected");
break;
}
@@ -635,7 +623,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
},
})
.on_pressed([this, port, &mapping] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
@@ -644,33 +631,30 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
}
}
if (getSettings().backend.enableAdvancedSettings) {
pane.add_section("Digital");
if (buttons != nullptr) {
for (u32 i = 0; i < buttonCount; ++i) {
PADButtonMapping& mapping = buttons[i];
if (mapping.padButton != PAD_TRIGGER_L && mapping.padButton != PAD_TRIGGER_R) {
continue;
}
pane.add_select_button({
.key = PADGetButtonName(mapping.padButton),
.getValue =
[this, &mapping, gamepad] {
if (mPendingButtonMapping == &mapping) {
return pending_button_label();
}
return native_button_name(
gamepad, mapping.nativeButton);
},
})
.on_pressed([this, port, &mapping] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
mPendingButtonMapping = &mapping;
});
pane.add_section("Digital");
if (buttons != nullptr) {
for (u32 i = 0; i < buttonCount; ++i) {
PADButtonMapping& mapping = buttons[i];
if (mapping.padButton != PAD_TRIGGER_L && mapping.padButton != PAD_TRIGGER_R) {
continue;
}
pane.add_select_button({
.key = PADGetButtonName(mapping.padButton),
.getValue =
[this, &mapping, gamepad] {
if (mPendingButtonMapping == &mapping) {
return pending_button_label();
}
return native_button_name(
gamepad, mapping.nativeButton);
},
})
.on_pressed([this, port, &mapping] {
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
mPendingButtonMapping = &mapping;
});
}
}
@@ -722,18 +706,17 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
PADKeyAxisBinding* bindings =
PADGetKeyAxisBindings(static_cast<u32>(port), &count);
if (bindings == nullptr) {
return Rml::String("Not Bound");
return Rml::String("Not bound");
}
for (u32 i = 0; i < PAD_AXIS_COUNT; ++i) {
if (bindings[i].padAxis == axis) {
return keyboard_key_name(bindings[i].scancode);
}
}
return Rml::String("Not Bound");
return Rml::String("Not bound");
},
})
.on_pressed([this, port, axis] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
@@ -758,7 +741,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
u32 axisCount = 0;
PADAxisMapping* axes = PADGetAxisMappings(port, &axisCount);
if (axes == nullptr) {
pane.add_text("No Device Selected");
pane.add_text("No controller selected");
break;
}
@@ -779,7 +762,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
},
})
.on_pressed([this, port, &mapping] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
@@ -925,7 +907,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
},
})
.on_pressed([this, port, actionBind] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
@@ -945,7 +926,7 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
u32 buttonCount = 0;
PADButtonMapping* mappings = PADGetButtonMappings(port, &buttonCount);
if (mappings == nullptr) {
pane.add_text("No Device Selected");
pane.add_text("No controller selected");
break;
}
@@ -969,7 +950,6 @@ void ControllerConfigWindow::render_page(Pane& pane, int port, Page page) {
},
})
.on_pressed([this, port, actionBind] {
mDoAud_seStartMenu(kSoundClick);
cancel_pending_binding();
mPendingPort = port;
mPendingBindingArmed = false;
@@ -1033,12 +1013,6 @@ void ControllerConfigWindow::poll_pending_binding() {
const s32 nativeButton = PADGetNativeButtonPressed(mPendingPort);
if (nativeButton != -1) {
const int completedPort = mPendingPort;
if (mPendingButtonMapping->nativeButton == static_cast<u32>(nativeButton) &&
(mPendingButtonMapping->padButton != PAD_BUTTON_A &&
mPendingButtonMapping->padButton != PAD_BUTTON_B)) {
unmap_pending_binding();
return;
}
mPendingButtonMapping->nativeButton = static_cast<u32>(nativeButton);
finish_pending_binding(completedPort);
}
@@ -1049,10 +1023,6 @@ void ControllerConfigWindow::poll_pending_binding() {
const PADSignedNativeAxis nativeAxis = PADGetNativeAxisPulled(mPendingPort);
if (nativeAxis.nativeAxis != -1) {
const int completedPort = mPendingPort;
if (mPendingAxisMapping->nativeAxis.nativeAxis == nativeAxis.nativeAxis) {
unmap_pending_binding();
return;
}
mPendingAxisMapping->nativeAxis = nativeAxis;
mPendingAxisMapping->nativeButton = -1;
finish_pending_binding(completedPort);
@@ -1079,10 +1049,6 @@ void ControllerConfigWindow::poll_pending_binding() {
if (button != -1) {
const int completedPort = mPendingPort;
if (mPendingActionBinding->getValue() == button) {
unmap_pending_binding();
return;
}
mPendingActionBinding->setValue(button);
config::Save();
finish_pending_binding(completedPort);
@@ -1092,7 +1058,6 @@ void ControllerConfigWindow::poll_pending_binding() {
}
void ControllerConfigWindow::finish_pending_binding(int completedPort) {
mDoAud_seStartMenu(kSoundBindingChanged);
mPendingButtonMapping = nullptr;
mPendingAxisMapping = nullptr;
mPendingActionBinding = nullptr;
@@ -1145,11 +1110,11 @@ bool ControllerConfigWindow::pending_input_neutral() const {
}
Rml::String ControllerConfigWindow::pending_button_label() const {
return mPendingBindingArmed ? "Press a Key or Button..." : "Waiting...";
return mPendingBindingArmed ? "Press a button..." : "Waiting...";
}
Rml::String ControllerConfigWindow::pending_axis_label() const {
return mPendingBindingArmed ? "Move Axis or press a Key or Button..." : "Waiting...";
return mPendingBindingArmed ? "Move axis or press a button..." : "Waiting...";
}
void ControllerConfigWindow::cancel_pending_binding() {
@@ -1178,7 +1143,7 @@ void ControllerConfigWindow::finish_pending_key_binding() {
}
Rml::String ControllerConfigWindow::pending_key_label() const {
return mPendingBindingArmed ? "Press a Key or Mouse Button..." : "Waiting...";
return mPendingBindingArmed ? "Press a key or mouse button..." : "Waiting...";
}
void ControllerConfigWindow::stop_rumble_test() {
@@ -1194,7 +1159,7 @@ void ControllerConfigWindow::stop_rumble_test() {
Rml::String native_button_name(SDL_Gamepad* gamepad, u32 buttonUntyped) {
if (buttonUntyped == PAD_NATIVE_BUTTON_INVALID) {
return "Not Bound";
return "Not bound";
}
auto button = static_cast<SDL_GamepadButton>(buttonUntyped);
+1 -1
View File
@@ -450,7 +450,7 @@ std::map<int, itemInfo> itemMap = {
{dItemNo_NOENTRY_222_e, {"Reserved"}},
{dItemNo_NOENTRY_223_e, {"Reserved"}},
{dItemNo_POU_SPIRIT_e, {"Poe Soul"}},
{dItemNo_NOENTRY_225_e, {"Reserved"}},
{dItemNo_GHOST_LANTERN_e, {"Reserved"}},
{dItemNo_NOENTRY_226_e, {"Reserved"}},
{dItemNo_NOENTRY_227_e, {"Reserved"}},
{dItemNo_NOENTRY_228_e, {"Reserved"}},
+1 -1
View File
@@ -211,7 +211,7 @@ GraphicsTuner::GraphicsTuner(GraphicsTunerProps props, bool prelaunch)
SteppedCarousel::Props{
.min = mValueMin,
.max = mValueMax,
.step = props.step,
.step = 1,
.getValue = [this] { return get_value(mOption); },
.onChange = [this](int value) { set_value(mOption, value); },
.formatValue =
-1
View File
@@ -55,7 +55,6 @@ struct GraphicsTunerProps {
int valueMin = 0;
int valueMax = 0;
int defaultValue = 0;
int step = 1;
};
class GraphicsTuner : public Document {
+11 -20
View File
@@ -454,18 +454,10 @@ bool touch_moved_too_far(
return delta.SquaredMagnitude() > threshold * threshold;
}
void emit_key_press(Rml::Context& context, Rml::Input::KeyIdentifier key) noexcept {
context.ProcessMouseLeave();
context.ProcessKeyDown(key, 0);
}
void emit_key_tap(Rml::Context& context, Rml::Input::KeyIdentifier key) noexcept {
emit_key_press(context, key);
context.ProcessKeyUp(key, 0);
}
void dispatch_menu_key(Rml::Context& context) noexcept {
emit_key_tap(context, Rml::Input::KI_F1);
context.ProcessMouseLeave();
context.ProcessKeyDown(Rml::Input::KI_F1, 0);
context.ProcessKeyUp(Rml::Input::KI_F1, 0);
}
bool handle_touch_menu_tap(Rml::Context& context, const SDL_Event& event) noexcept {
@@ -635,9 +627,7 @@ void process_axis_direction(
if (repeat->held) {
if (released) {
if (repeat->pending) {
emit_key_tap(context, repeat->key);
} else {
if (!repeat->pending) {
context.ProcessKeyUp(repeat->key, 0);
}
set_pad_button_held(port, heldPadButton, false);
@@ -668,7 +658,8 @@ void process_axis_direction(
}
begin_gamepad_key(*repeat, key);
emit_key_press(context, key);
context.ProcessMouseLeave();
context.ProcessKeyDown(key, 0);
}
} // namespace
@@ -756,7 +747,8 @@ void handle_event(const SDL_Event& event) noexcept {
}
}
if (!deferred) {
emit_key_press(*context, key);
context->ProcessMouseLeave();
context->ProcessKeyDown(key, 0);
}
}
} else {
@@ -768,9 +760,7 @@ void handle_event(const SDL_Event& event) noexcept {
if (repeat != nullptr) {
*repeat = {};
}
if (wasPending) {
emit_key_tap(*context, key);
} else {
if (!wasPending) {
context->ProcessKeyUp(key, 0);
}
}
@@ -797,7 +787,8 @@ void update_input() noexcept {
repeat.pressedAt = now;
repeat.nextRepeatAt =
repeat.repeatable ? now + kGamepadRepeatInitialDelay : 0.0;
emit_key_press(*context, repeat.key);
context->ProcessMouseLeave();
context->ProcessKeyDown(repeat.key, 0);
continue;
}
+4 -4
View File
@@ -103,13 +103,13 @@ Rml::Element* create_controller_warning(Rml::Element* parent) {
auto* heading = append(elem, "heading");
auto* title = append(heading, "span");
title->SetInnerRML("No Device Assigned");
title->SetInnerRML("No controller assigned");
auto* icon = append(heading, "icon");
icon->SetClass("warning", true);
auto* message = append(elem, "message");
auto* content = append(message, "span");
content->SetInnerRML("Configure <b>Port 1</b> in Settings.");
content->SetInnerRML("Configure controller port 1 in Settings.");
return elem;
}
@@ -147,7 +147,7 @@ Rml::String back_button_name() {
#if defined(TARGET_ANDROID) || (defined(__APPLE__) && TARGET_OS_IOS && !TARGET_OS_MACCATALYST)
constexpr auto kMenuNotificationPrefix = "3-finger tap or";
#else
constexpr auto kMenuNotificationPrefix = "Press <b>F1</b> or";
constexpr auto kMenuNotificationPrefix = "Press F1 or";
#endif
Rml::Element* create_menu_notification(Rml::Element* parent) {
@@ -169,7 +169,7 @@ Rml::Element* create_menu_notification(Rml::Element* parent) {
append(row, "span")->SetInnerRML(kMenuNotificationPrefix);
auto* icon = append(row, "icon");
icon->SetClass("controller", true);
append(row, "span")->SetInnerRML("<b>" + escape(padButton) + "</b>");
append(row, "span")->SetInnerRML(escape(padButton));
append(row, "span")->SetInnerRML("to open menu");
return elem;
+10 -16
View File
@@ -793,16 +793,9 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
.valueMin = 0,
.valueMax = 100,
.defaultValue = 100,
.step = 10,
}, mPrelaunch);
leftPane.add_section("Rendering");
config_bool_select(leftPane, rightPane, getSettings().game.enableTextureReplacements,
{
.key = "Use Texture Pack",
.helpText = "Enable installed texture replacements.",
.onChange = [](bool value) { aurora_set_texture_replacements_enabled(value); },
});
config_bool_select(leftPane, rightPane, getSettings().game.enableFrameInterpolation,
{
.key = "Unlock Framerate",
@@ -836,18 +829,18 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
});
};
leftPane.add_section("Inputs");
leftPane.register_control(leftPane.add_button("Configure Inputs").on_pressed([this] {
leftPane.add_section("Controller");
leftPane.register_control(leftPane.add_button("Configure Controller").on_pressed([this] {
push(std::make_unique<ControllerConfigWindow>(mPrelaunch));
}),
rightPane, [](Pane& pane) {
pane.clear();
pane.add_text("Open input binding configuration.");
pane.add_text("Open controller binding configuration.");
});
config_bool_select(leftPane, rightPane, getSettings().game.allowBackgroundInput,
{
.key = "Allow Background Inputs",
.helpText = "Allow inputs even when the game window is not focused.",
.key = "Allow Background Input",
.helpText = "Allow controller input even when the game window is not focused.",
.onChange = [](bool value) { aurora_set_background_input(value); },
});
@@ -1075,7 +1068,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
addOption("Faster Tears of Light", getSettings().game.fastTears,
"Tears of Light dropped by Shadow Insects pop out faster like the HD version.");
addSpeedrunDisabledOption("Autosave", getSettings().game.autoSave,
"Autosaves the game when going to a new area or opening a dungeon door.");
"Autosaves the game when going to a new area, opening a dungeon door, "
"or getting a new item.");
addOption("Instant Saves", getSettings().game.instantSaves,
"Skips the delay when writing to the Memory Card.");
addOption("Hold B for Instant Text", getSettings().game.instantText,
@@ -1172,7 +1166,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
addCheat("Always Greatspin", getSettings().game.alwaysGreatspin,
"Allows the Great Spin attack without requiring full health.");
addCheat("Fast Iron Boots", getSettings().game.enableFastIronBoots,
"Speeds up movement while heavy, including wearing the Iron Boots, holding the Ball and Chain, wearing Magic Armor without rupees, etc.");
"Speeds up movement while wearing the Iron Boots.");
addCheat("Can Transform Anywhere", getSettings().game.canTransformAnywhere,
"Allows transforming even if NPCs are looking.");
addCheat("Fast Roll", getSettings().game.fastRoll,
@@ -1254,7 +1248,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
});
pane.add_button(
{
.text = "Missing Device",
.text = "Controller",
.isSelected =
[] { return getSettings().game.enableControllerToasts.getValue(); },
})
@@ -1307,7 +1301,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
config_bool_select(leftPane, rightPane, getSettings().game.enableDiscordPresence,
{
.key = "Enable Discord Rich Presence",
.helpText = "Enable Dusklight to integrate with Discord Rich Presence. This allows Discord to show your status in-game.",
.helpText = "Enable Dusk to integrate with Discord Rich Presence. This allows Discord to show your status in-game.",
.onChange = [](bool enabled) {
if (enabled) {
dusk::discord::initialize();
+2 -16
View File
@@ -11,9 +11,7 @@
#include <ranges>
#include "aurora/lib/window.hpp"
#include "dusk/dusk.h"
#include "dusk/io.hpp"
#include "dusk/config.hpp"
#include "input.hpp"
#include "prelaunch.hpp"
#include "window.hpp"
@@ -132,7 +130,7 @@ void handle_event(const SDL_Event& event) noexcept {
if (getSettings().game.enableControllerToasts) {
const char* name = SDL_GetGamepadName(gamepad);
Rml::String content = fmt::format("<span>{}</span>", name ? name : "[Unknown]");
Rml::String title = "Device Connected";
Rml::String title = "Controller connected";
if (const char* icon = connection_state_icon(SDL_GetGamepadConnectionState(gamepad))) {
title = fmt::format(
"<row><span>{}</span> <icon class=\"connection\">&#x{};</icon></row>", title,
@@ -165,24 +163,12 @@ void handle_event(const SDL_Event& event) noexcept {
const char* name = SDL_GetGamepadNameForID(event.gdevice.which);
push_toast({
.type = "controller",
.title = "Device Disconnected",
.title = "Controller disconnected",
.content = name ? name : "[Unknown]",
.duration = std::chrono::seconds(4),
});
}
sConnectedGamepads.erase(event.gdevice.which);
} else if (event.type == SDL_EVENT_WINDOW_MOVED || event.type == SDL_EVENT_WINDOW_RESIZED) {
int x, y;
if (SDL_GetWindowPosition(aurora::window::get_sdl_window(), &x, &y)) {
getSettings().video.windowPositionX.setValue(x);
getSettings().video.windowPositionY.setValue(y);
}
int width, height;
if (SDL_GetWindowSize(aurora::window::get_sdl_window(), &width, &height)) {
getSettings().video.windowWidth.setValue(width);
getSettings().video.windowHeight.setValue(height);
}
config::Save();
}
input::handle_event(event);
}
-4
View File
@@ -26,8 +26,6 @@ struct Toast {
constexpr u32 kSoundClick = Z2SE_SY_CURSOR_OK;
// "Play" button clicked/pressed
constexpr u32 kSoundPlay = Z2SE_SY_ITEM_COMBINE_ON;
// Input binding changed
constexpr u32 kSoundBindingChanged = Z2SE_SY_ITEM_SET_X;
// Menu button pressed (open/close menu bar or hide/show the active window)
constexpr u32 kSoundMenuOpen = Z2SE_SY_MENU_SUB_IN;
@@ -51,8 +49,6 @@ constexpr u32 kSoundItemDisable = Z2SE_SUBJ_VIEW_OUT;
// Achievement unlocked
constexpr u32 kSoundAchievementUnlock = Z2SE_NAVI_FLY;
// Warning prompt
constexpr u32 kSoundWarning = Z2SE_SY_COW_GET_IN;
struct Insets {
float top = 0.0f;
+13 -1
View File
@@ -29,6 +29,8 @@
#include "tracy/Tracy.hpp"
#include <dusk/gamepad_color.h>
#include <dusk/autosave.h>
#include <d/actor/d_a_npc.h>
#include <d/d_item.h>
#endif
fapGm_HIO_c::fapGm_HIO_c() {
@@ -741,11 +743,21 @@ static void fapGm_AfterRecord() {
}
BOOL isRecording = false;
BOOL gotGhostLantern = false;
static void duskExecute() {
handleGamepadColor();
updateAutoSave();
if (daNpcT_chkEvtBit(0x2B6) && !gotGhostLantern) {
execItemGet(dItemNo_GHOST_LANTERN_e);
gotGhostLantern = true;
} else if (!daNpcT_chkEvtBit(0x2B6) && gotGhostLantern) {
dComIfGs_offItemFirstBit(dItemNo_GHOST_LANTERN_e);
dComIfGp_setItem(SLOT_7, dItemNo_NONE_e);
gotGhostLantern = false;
}
if (dusk::getSettings().game.recordingMode) {
Z2GetSoundMgr()->getSeqMgr()->getParams()->moveVolume(0.0f, 0);
Z2GetSoundMgr()->getStreamMgr()->getParams()->moveVolume(0.0f, 0);
@@ -807,7 +819,7 @@ static void duskExecute() {
}
if (dusk::getSettings().game.infiniteRupees) {
dComIfGs_setRupee(dComIfGs_getRupeeMax());
dComIfGs_setRupee(9999);
}
if (dusk::getSettings().game.infiniteOxygen) {
-6
View File
@@ -12,12 +12,6 @@
static int fpcLnIt_MethodCall(create_tag_class* i_createTag, method_filter* i_filter) {
#ifdef TARGET_PC
// on init_state==3 fpcEx_ExecuteQTo already ran (layer_tag.layer is NULL)
if (static_cast<base_process_class*>(i_createTag->mpTagData)->state.init_state == 3) {
return 0;
}
#endif
layer_class* layer = static_cast<base_process_class*>(i_createTag->mpTagData)->layer_tag.layer;
layer_class* save_layer = fpcLy_CurrentLayer();
int ret;
+2 -2
View File
@@ -96,8 +96,8 @@ void mDoLib_project(Vec* src, Vec* dst) {
xSize = FB_WIDTH;
} else {
#if TARGET_PC
xOffset = mDoGph_gInf_c::getMinXF();
xSize = mDoGph_gInf_c::getWidthF();
xOffset = mDoGph_gInf_c::getSafeMinXF();
xSize = viewPort->width * mDoGph_gInf_c::hudAspectScaleUp;
#else
xOffset = viewPort->x_orig;
xSize = viewPort->width;
+5 -5
View File
@@ -551,10 +551,10 @@ int game_main(int argc, char* argv[]) {
config.cachePath = reinterpret_cast<const char*>(cachePathString.c_str());
config.vsync = dusk::getSettings().video.enableVsync;
config.startFullscreen = dusk::getSettings().video.enableFullscreen;
config.windowPosX = dusk::getSettings().video.windowPositionX;
config.windowPosY = dusk::getSettings().video.windowPositionY;
config.windowWidth = dusk::getSettings().video.windowWidth;
config.windowHeight = dusk::getSettings().video.windowHeight;
config.windowPosX = -1;
config.windowPosY = -1;
config.windowWidth = defaultWindowWidth * 2;
config.windowHeight = defaultWindowHeight * 2;
config.desiredBackend = ResolveDesiredBackend(parsed_arg_options);
config.logCallback = &aurora_log_callback;
config.logLevel = startupLogLevel;
@@ -563,7 +563,7 @@ int game_main(int argc, char* argv[]) {
config.allowJoystickBackgroundEvents = dusk::getSettings().game.allowBackgroundInput;
config.pauseOnFocusLost = dusk::getSettings().game.pauseOnFocusLost;
config.imGuiInitCallback = &aurora_imgui_init_callback;
config.allowTextureReplacements = dusk::getSettings().game.enableTextureReplacements;
config.allowTextureReplacements = true;
config.allowTextureDumps = false;
auroraInfo = aurora_initialize(argc, argv, &config);
}