Compare commits

...

6 Commits

Author SHA1 Message Date
gymnast86 9756612b35 Merge branch 'main' of https://github.com/TwilitRealm/dusk into randomizer 2026-07-02 20:01:09 -07:00
gymnast86 49f27acb2b fix rando config not saving when it should 2026-07-02 20:01:02 -07:00
gymnast86 d1ea637d22 add midna hair and charge ring colors 2026-07-02 20:00:47 -07:00
Irastris 42910ab2fd Restore simultaneous gyro and joystick input for first person aiming (#2164) 2026-07-02 00:13:22 -06:00
Olivia!! f54892b2c2 do not disable regular touch input if menu touch is disabled (#2152) 2026-07-02 00:03:53 -06:00
Luke Street f32e069c4b Improve mouse hiding logic (#2163)
* Improve mouse hiding logic

* Restore ImGui logic
2026-07-02 02:03:18 -04:00
16 changed files with 388 additions and 140 deletions
+2
View File
@@ -1556,6 +1556,8 @@ set(DUSK_FILES
src/dusk/action_bindings.cpp
src/dusk/cosmetics/color_utils.hpp
src/dusk/cosmetics/color_utils.cpp
src/dusk/cosmetics/midna_hair_color.hpp
src/dusk/cosmetics/midna_hair_color.cpp
src/dusk/cosmetics/texture_utils.hpp
src/dusk/cosmetics/texture_utils.cpp
# Randomizer files
+4
View File
@@ -3917,6 +3917,10 @@ public:
u16 getEventId() { return mMsgFlow.getEventId(); }
bool checkSwimming() {return checkModeFlg(MODE_SWIMMING);}
BE<short>** getDomeLockChromaTable() {
return &field_0x0724->mAnmCRegDataR;
}
#endif
static daAlink_BckData const m_mainBckShield[20];
+4 -4
View File
@@ -4,9 +4,9 @@
namespace dusk::mouse {
void read();
void getAimDeltas(float& out_yaw, float& out_pitch);
void getCameraDeltas(float& out_yaw, float& out_pitch);
void get_aim_deltas(float& out_yaw, float& out_pitch);
void get_camera_deltas(float& out_yaw, float& out_pitch);
void handle_event(const SDL_Event& event) noexcept;
void onFocusLost();
void onFocusGained();
void on_focus_lost();
void on_focus_gained();
} // namespace dusk::mouse
+3
View File
@@ -329,6 +329,9 @@ struct UserSettings {
ConfigVar<std::string> boomerangColor;
ConfigVar<std::string> ironBootsColor;
ConfigVar<std::string> spinnerColor;
ConfigVar<std::string> midnaHairBaseColor;
ConfigVar<std::string> midnaHairTipsColor;
ConfigVar<std::string> midnaChargeRingColor;
ConfigVar<std::string> linkHairColor;
ConfigVar<std::string> wolfLinkColor;
ConfigVar<std::string> eponaColor;
+5 -12
View File
@@ -122,18 +122,11 @@ BOOL daAlink_c::setBodyAngleToCamera() {
var_f31 /= dComIfGp_getCameraZoomScale(field_0x317c);
}
#if TARGET_PC
if (dusk::getSettings().game.enableMouseAim && checkAimInputContext()) {
sp8 = mBodyAngle.x;
} else
#endif
{
shape_angle.y = shape_angle.y + (var_f31 * cM_ssin(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonXAxis ? -1.0f : 1.0f)));
sp8 = mBodyAngle.x + (var_f31 * cM_scos(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonYAxis ? -1.0f : 1.0f)));
shape_angle.y = shape_angle.y + (var_f31 * cM_ssin(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonXAxis ? -1.0f : 1.0f)));
sp8 = mBodyAngle.x + (var_f31 * cM_scos(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonYAxis ? -1.0f : 1.0f)));
if (checkNotItemSinkLimit() && sp8 > 0 && sp8 > mBodyAngle.x) {
sp8 = mBodyAngle.x;
}
if (checkNotItemSinkLimit() && sp8 > 0 && sp8 > mBodyAngle.x) {
sp8 = mBodyAngle.x;
}
} else {
sp8 = mBodyAngle.x;
@@ -156,7 +149,7 @@ BOOL daAlink_c::setBodyAngleToCamera() {
f32 final_yaw = 0.f;
f32 final_pitch = 0.f;
if (dusk::getSettings().game.enableMouseAim) {
dusk::mouse::getAimDeltas(final_yaw, final_pitch);
dusk::mouse::get_aim_deltas(final_yaw, final_pitch);
}
if (dusk::getSettings().game.enableGyroAim) {
f32 gyro_yaw = 0.f;
+25
View File
@@ -6889,6 +6889,31 @@ void daAlink_c::setWolfLockDomeModel() {
} else {
field_0x0724->setFrame(0.0f);
}
#if TARGET_PC
// Replace charge ring color
const auto& domeRingColorStr = dusk::getSettings().cosmetics.midnaChargeRingColor.getValue();
if (dusk::cosmetics::is_valid_hex_color_str(domeRingColorStr)) {
auto domeRingColor = dusk::cosmetics::hex_color_str_to_gx_color(domeRingColorStr);
const u8 domeWave1RGBA[3] = {domeRingColor.r, domeRingColor.g, domeRingColor.b};
const u8 domeWave2RGBA[3] = {domeRingColor.r, domeRingColor.g, domeRingColor.b};
u8** chromaRegisterTable = reinterpret_cast<u8**>(daAlink_getAlinkActorClass()->getDomeLockChromaTable());
for (int i = 0; i < 3; i++)
{
u8* currentTable = chromaRegisterTable[i];
const u8 currentWave1Color = domeWave1RGBA[i];
const u8 currentWave2Color = domeWave2RGBA[i];
const u8 currentBaseColor = (currentWave1Color + currentWave2Color) / 2;
currentTable[0x3] = currentBaseColor; // Set Alpha for the ring base
currentTable[0x13] = currentWave1Color; // Set Alpha for ring wave 1
currentTable[0x23] = currentWave2Color; // Set Alpha for ring wave 2
currentTable[0xB] = currentBaseColor; // Set Alpha for darkworld ring base
currentTable[0x1B] = currentWave1Color; // Set Alpha for darkworld ring wave 1
currentTable[0x2B] = currentWave2Color; // Set Alpha for darkworld ring wave 2
}
}
#endif
}
void daAlink_c::setWolfBallModel() {
+35 -31
View File
@@ -14,7 +14,11 @@
#include "d/d_msg_object.h"
#include "d/d_s_play.h"
#include "d/d_debug_viewer.h"
#if TARGET_PC
#include "dusk/frame_interpolation.h"
#include "dusk/cosmetics/midna_hair_color.hpp"
#endif
static f32 dummy_lit_3777(int idx, u8 foo) {
Vec dummy_vec = {0.0f, 0.0f, 0.0f};
@@ -686,28 +690,28 @@ cPhs_Step daMidna_c::create() {
mpMorf->modelCalc();
setBodyPartMatrix();
field_0x6e0.r = l_normalColor.r;
field_0x6e0.g = l_normalColor.g;
field_0x6e0.b = l_normalColor.b;
field_0x6e0.a = l_normalColor.a;
field_0x6e0.r = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalColor()->r , l_normalColor.r);
field_0x6e0.g = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalColor()->g , l_normalColor.g);
field_0x6e0.b = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalColor()->b , l_normalColor.b);
field_0x6e0.a = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalColor()->a , l_normalColor.a);
if (dKy_darkworld_check()) {
field_0x6e8.r = l_normalKColor.r;
field_0x6e8.g = l_normalKColor.g;
field_0x6e8.b = l_normalKColor.b;
field_0x6e8.a = l_normalKColor.a;
field_0x6ec.r = l_normalKColor2.r;
field_0x6ec.g = l_normalKColor2.g;
field_0x6ec.b = l_normalKColor2.b;
field_0x6ec.a = l_normalKColor2.a;
field_0x6e8.r = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalKColor()->r, l_normalKColor.r);
field_0x6e8.g = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalKColor()->g, l_normalKColor.g);
field_0x6e8.b = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalKColor()->b, l_normalKColor.b);
field_0x6e8.a = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalKColor()->a, l_normalKColor.a);
field_0x6ec.r = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalKColor2()->r, l_normalKColor2.r);
field_0x6ec.g = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalKColor2()->g, l_normalKColor2.g);
field_0x6ec.b = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalKColor2()->b, l_normalKColor2.b);
field_0x6ec.a = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalKColor2()->a, l_normalKColor2.a);
} else {
field_0x6e8.r = l_lNormalKColor.r;
field_0x6e8.g = l_lNormalKColor.g;
field_0x6e8.b = l_lNormalKColor.b;
field_0x6e8.a = l_lNormalKColor.a;
field_0x6ec.r = l_lNormalKColor2.r;
field_0x6ec.g = l_lNormalKColor2.g;
field_0x6ec.b = l_lNormalKColor2.b;
field_0x6ec.a = l_lNormalKColor2.a;
field_0x6e8.r = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lNormalKColor()->r, l_lNormalKColor.r);
field_0x6e8.g = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lNormalKColor()->g, l_lNormalKColor.g);
field_0x6e8.b = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lNormalKColor()->b, l_lNormalKColor.b);
field_0x6e8.a = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lNormalKColor()->a, l_lNormalKColor.a);
field_0x6ec.r = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lNormalKColor2()->r, l_lNormalKColor2.r);
field_0x6ec.g = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lNormalKColor2()->g, l_lNormalKColor2.g);
field_0x6ec.b = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lNormalKColor2()->b, l_lNormalKColor2.b);
field_0x6ec.a = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lNormalKColor2()->a, l_lNormalKColor2.a);
}
model = mpShadowModel;
@@ -1060,7 +1064,7 @@ void daMidna_c::setBodyPartMatrix() {
const GXColorS10* color;
const GXColor* kcolor1;
const GXColor* kcolor2;
if (bvar2) {
if (bvar8) {
modelData->getMaterialNodePointer(2)->getShape()->show();
@@ -1068,24 +1072,24 @@ void daMidna_c::setBodyPartMatrix() {
modelData->getMaterialNodePointer(1)->getShape()->show();
}
kcolor1 = &l_bigKColor;
kcolor1 = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_bigKColor(), &l_bigKColor);
if (dKy_darkworld_check()) {
color = &l_bigColor;
kcolor2 = &l_normalKColor2;
color = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_bigColor(), &l_bigColor);
kcolor2 = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalKColor2(), &l_normalKColor2);
} else {
color = &l_lBigColor;
kcolor2 = &l_lBigKColor2;
color = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lBigColor(), &l_lBigColor);
kcolor2 = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lBigKColor2(), &l_lBigKColor2);
}
} else {
modelData->getMaterialNodePointer(0)->getShape()->show();
color = &l_normalColor;
color = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalColor(), &l_normalColor);
if (dKy_darkworld_check()) {
kcolor1 = &l_normalKColor;
kcolor2 = &l_normalKColor2;
kcolor1 = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalKColor(), &l_normalKColor);
kcolor2 = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_normalKColor2(), &l_normalKColor2);
} else {
kcolor1 = &l_lNormalKColor;
kcolor2 = &l_lNormalKColor2;
kcolor1 = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lNormalKColor(), &l_lNormalKColor);
kcolor2 = DUSK_IF_ELSE(dusk::cosmetics::get_midna_hair_lNormalKColor2(), &l_lNormalKColor2);
}
}
+1 -1
View File
@@ -7716,7 +7716,7 @@ bool dCamera_c::freeCamera() {
f32 yaw_rad = 0.0f;
f32 pitch_rad = 0.0f;
dusk::mouse::getCameraDeltas(yaw_rad, pitch_rad);
dusk::mouse::get_camera_deltas(yaw_rad, pitch_rad);
if (dusk::getSettings().game.enableMouseCamera && (yaw_rad != 0.0f || pitch_rad != 0.0f) &&
!dComIfGp_checkCameraAttentionStatus(dComIfGp_getPlayerCameraID(0), 0x8))
{
+129
View File
@@ -0,0 +1,129 @@
#include "midna_hair_color.hpp"
#include "dusk/settings.h"
#include <array>
#include <string_view>
#include <unordered_map>
namespace dusk::cosmetics {
static std::unordered_map<std::string_view, std::array<GXColor, 9>> const midnaHairColors = {
{"Default", {{
/*l_lNormalKColor*/ /*l_normalKColor*/ /*l_normalColor*/
{0xFF, 0xDC, 0x00}, {0xB4, 0x87, 0x00}, {0x50, 0x00, 0x00},
/*l_bigKColor*/ /*l_lBigColor*/ /*l_bigColor*/
{0x50, 0x00, 0x00}, {0xFF, 0x78, 0x00}, {0xFF, 0x64, 0x78},
/*l_lNormalKColor2*//*l_normalKColor2*/ /*l_lBigKColor2*/
{0x00, 0xC3, 0xEB}, {0xC3, 0xC3, 0x00}, {0xAA, 0xFF, 0xC3}}}},
{"Pink", {{
{0xF5, 0xCF, 0xF3}, {0xAD, 0x7F, 0x7F}, {0x1B, 0x00, 0x20},
{0x3C, 0x02, 0x58}, {0xE3, 0x72, 0xF2}, {0xE3, 0x5F, 0xF8},
{0xDD, 0x00, 0xEB}, {0xDD, 0x00, 0xC3}, {0xF6, 0x4C, 0xFF}}}},
{"Red", {{
{0xE4, 0x65, 0x41}, {0xA1, 0x3E, 0x22}, {0x21, 0x00, 0x00},
{0x4F, 0x02, 0x01}, {0xF0, 0x3A, 0x25}, {0xF0, 0x30, 0x8C},
{0xEB, 0x00, 0x00}, {0xEB, 0x00, 0x00}, {0xFF, 0x4F, 0x3A}}}},
{"Yellow", {{
{0x91, 0x83, 0x0E}, {0x66, 0x50, 0x07}, {0x0E, 0x0B, 0x00},
{0x24, 0x25, 0x02}, {0xCB, 0xB7, 0x00}, {0xCB, 0x99, 0x78},
{0xEB, 0xDE, 0x00}, {0xEB, 0xDE, 0x00}, {0xFF, 0xF8, 0xBF}}}},
{"Green", {{
{0x35, 0x79, 0x53}, {0x25, 0x4A, 0x2B}, {0x00, 0x0E, 0x05},
{0x0A, 0x29, 0x10}, {0x00, 0xB6, 0x6F}, {0x00, 0x98, 0xB3},
{0x1F, 0xEB, 0x00}, {0x1F, 0xEB, 0x00}, {0x9A, 0xFF, 0x81}}}},
{"Blue", {{
{0x00, 0x72, 0xFF}, {0x00, 0x46, 0x85}, {0x00, 0x08, 0x28},
{0x16, 0x1B, 0x5D}, {0x00, 0x60, 0xFF}, {0x00, 0x50, 0xFF},
{0x00, 0x48, 0xEB}, {0x00, 0x48, 0xC3}, {0x3A, 0x66, 0xFF}}}},
{"Purple", {{
{0x6F, 0x34, 0xFF}, {0x4E, 0x20, 0x85}, {0x0D, 0x00, 0x34},
{0x15, 0x08, 0x79}, {0x62, 0x00, 0xFF}, {0x62, 0x00, 0xFF},
{0x7B, 0x00, 0xEB}, {0x7B, 0x00, 0xC3}, {0x94, 0x3E, 0xFF}}}},
{"Brown", {{
{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x1A, 0x05, 0x00},
{0x3C, 0x19, 0x0E}, {0x3F, 0x1D, 0x0B}, {0x3F, 0x18, 0x7E},
{0x3F, 0x1D, 0x0B}, {0x3F, 0x1D, 0x09}, {0x59, 0x32, 0x1E}}}},
{"White", {{
{0xF0, 0xF1, 0xF1}, {0xA9, 0x94, 0x7E}, {0x09, 0x0B, 0x0C},
{0x22, 0x24, 0x24}, {0xFF, 0xFF, 0xFF}, {0xFF, 0xD5, 0xFF},
{0xEA, 0xEA, 0xEA}, {0xEA, 0xEA, 0xC2}, {0xF3, 0xF3, 0xF3}}}},
{"Black", {{
{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x0B, 0x0B, 0x0B},
{0x23, 0x23, 0x23}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x78},
{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}}}},
};
static struct {
GXColorS10 l_normalColor = { 0x50, 0x00, 0x00, 0x00 };
GXColor l_normalKColor = { 0xB4, 0x87, 0x00, 0x00 };
GXColor l_normalKColor2 = { 0x00, 0xC3, 0xC3, 0x00 };
GXColorS10 l_bigColor = { 0xFF, 0x64, 0x78, 0x00 };
GXColor l_bigKColor = { 0x1E, 0x00, 0x00, 0x00 };
GXColor l_lNormalKColor = { 0xFF, 0xDC, 0x00, 0x00 };
GXColor l_lNormalKColor2 = { 0x00, 0xC3, 0xEB, 0x00 };
GXColorS10 l_lBigColor = { 0xFF, 0x78, 0x00, 0x00 };
GXColor l_lBigKColor2 = { 0xAA, 0xFF, 0xC3, 0x00 };
} currentMidnaHairColors;
void set_all_midna_hair_colors() {
const auto& hairBaseColor = getSettings().cosmetics.midnaHairBaseColor.getValue();
const auto& hairTipsColor = getSettings().cosmetics.midnaHairTipsColor.getValue();
// Don't set colors if either is invalid
if (!midnaHairColors.contains(hairBaseColor) || !midnaHairColors.contains(hairTipsColor)) {
return;
}
// Colors we have to convert to GXColorS10
auto& normalColor = midnaHairColors.at(hairBaseColor)[2];
auto& bigColor = midnaHairColors.at(hairBaseColor)[5];
auto& lBigColor = midnaHairColors.at(hairBaseColor)[4];
currentMidnaHairColors.l_normalColor = GXColorS10{normalColor.r, normalColor.g, normalColor.b};
currentMidnaHairColors.l_normalKColor = midnaHairColors.at(hairBaseColor)[1];
currentMidnaHairColors.l_normalKColor2 = midnaHairColors.at(hairTipsColor)[7];
currentMidnaHairColors.l_bigColor = GXColorS10{bigColor.r, bigColor.g, bigColor.b};
currentMidnaHairColors.l_bigKColor = midnaHairColors.at(hairBaseColor)[3];
currentMidnaHairColors.l_lNormalKColor = midnaHairColors.at(hairBaseColor)[0];
currentMidnaHairColors.l_lNormalKColor2 = midnaHairColors.at(hairTipsColor)[6];
currentMidnaHairColors.l_lBigColor = GXColorS10{lBigColor.r, lBigColor.g, lBigColor.b};
currentMidnaHairColors.l_lBigKColor2 = midnaHairColors.at(hairTipsColor)[8];
}
const GXColorS10* get_midna_hair_normalColor() {
return &currentMidnaHairColors.l_normalColor;
}
const GXColor* get_midna_hair_normalKColor() {
return &currentMidnaHairColors.l_normalKColor;
}
const GXColor* get_midna_hair_normalKColor2() {
return &currentMidnaHairColors.l_normalKColor2;
}
const GXColorS10* get_midna_hair_bigColor() {
return &currentMidnaHairColors.l_bigColor;
}
const GXColor* get_midna_hair_bigKColor() {
return &currentMidnaHairColors.l_bigKColor;
}
const GXColor* get_midna_hair_lNormalKColor() {
return &currentMidnaHairColors.l_lNormalKColor;
}
const GXColor* get_midna_hair_lNormalKColor2() {
return &currentMidnaHairColors.l_lNormalKColor2;
}
const GXColorS10* get_midna_hair_lBigColor() {
return &currentMidnaHairColors.l_lBigColor;
}
const GXColor* get_midna_hair_lBigKColor2() {
return &currentMidnaHairColors.l_lBigKColor2;
}
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include "dolphin/gx/GXStruct.h"
namespace dusk::cosmetics {
void set_all_midna_hair_colors();
const GXColorS10* get_midna_hair_normalColor();
const GXColor* get_midna_hair_normalKColor();
const GXColor* get_midna_hair_normalKColor2();
const GXColorS10* get_midna_hair_bigColor();
const GXColor* get_midna_hair_bigKColor();
const GXColor* get_midna_hair_lNormalKColor();
const GXColor* get_midna_hair_lNormalKColor2();
const GXColorS10* get_midna_hair_lBigColor();
const GXColor* get_midna_hair_lBigKColor2();
}
+1 -1
View File
@@ -314,7 +314,7 @@ void end_game_frame() noexcept {
}
void begin_context(Context context) noexcept {
if (context == Context::None) {
if (context == Context::None || !enabled()) {
return;
}
+74 -52
View File
@@ -1,54 +1,69 @@
#include "dusk/mouse.h"
#include "d/actor/d_a_alink.h"
#include "d/d_com_inf_game.h"
#include "dusk/menu_pointer.h"
#include "dusk/settings.h"
#include "dusk/ui/ui.hpp"
#include "d/actor/d_a_alink.h"
#include "d/d_com_inf_game.h"
#include <aurora/lib/window.hpp>
#include <imgui.h>
#include <SDL3/SDL_mouse.h>
#include <SDL3/SDL_video.h>
#include <aurora/lib/window.hpp>
#include <imgui.h>
#include <chrono>
namespace dusk::mouse {
namespace {
constexpr float kMousePixelToRad = 0.0025f;
constexpr int kIdleHideFrames = 99; // Approx. 3 seconds with 33ms ticks
using Clock = std::chrono::steady_clock;
float s_aim_yaw_rad = 0.0f;
float s_aim_pitch_rad = 0.0f;
float s_camera_yaw_rad = 0.0f;
constexpr float kMousePixelToRad = 0.0025f;
constexpr auto kCursorIdleDuration = std::chrono::seconds(1);
float s_aim_yaw_rad = 0.0f;
float s_aim_pitch_rad = 0.0f;
float s_camera_yaw_rad = 0.0f;
float s_camera_pitch_rad = 0.0f;
int s_idle_frames = 0;
Clock::time_point s_last_cursor_motion = Clock::now();
void reset_deltas() {
s_aim_yaw_rad = s_aim_pitch_rad = 0.0f;
s_camera_yaw_rad = s_camera_pitch_rad = 0.0f;
}
bool queryMouseAimContext() {
bool query_mouse_aim_context() {
return getSettings().game.enableMouseAim.getValue() && dCamera_c::isAimActive();
}
bool wantMouseCapture() {
return getSettings().game.enableMouseCamera.getValue() || queryMouseAimContext();
bool want_mouse_capture() {
return getSettings().game.enableMouseCamera.getValue() || query_mouse_aim_context();
}
bool isWindowFocused(SDL_Window* window) {
bool mouse_input_enabled() {
const auto& game = getSettings().game;
return game.enableMouseAim.getValue() || game.enableMouseCamera.getValue();
}
bool is_window_focused(SDL_Window* window) {
if (window == nullptr) {
return false;
}
return (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0;
}
bool shouldCaptureMouse(SDL_Window* window) {
if (window == nullptr || ui::any_document_visible() || menu_pointer::active()) {
return false;
}
return wantMouseCapture() && isWindowFocused(window);
bool imgui_windows_visible() {
return ImGui::GetIO().MetricsRenderWindows > 0;
}
bool syncCaptureState(SDL_Window* window, bool should_capture) {
bool should_capture_mouse(SDL_Window* window) {
if (window == nullptr || ui::any_document_visible() || imgui_windows_visible() ||
menu_pointer::active())
{
return false;
}
return want_mouse_capture() && is_window_focused(window);
}
bool sync_capture_state(SDL_Window* window, bool should_capture) {
if (window == nullptr) {
reset_deltas();
return false;
@@ -78,7 +93,7 @@ bool syncCaptureState(SDL_Window* window, bool should_capture) {
return is_captured;
}
void accumulateDeltas(float mx_rel, float my_rel, bool camera_active, bool aim_active) {
void accumulate_deltas(float mx_rel, float my_rel, bool camera_active, bool aim_active) {
const auto& game = getSettings().game;
const bool mirror_mode = game.enableMirrorMode.getValue();
const bool invert_y = game.invertMouseY.getValue();
@@ -114,57 +129,62 @@ void set_cursor_visible(bool visible) {
}
}
void update_cursor_visibility(SDL_Window* window, bool captured) {
if (window == nullptr || !isWindowFocused(window)) {
return;
}
bool cursor_idle() {
return Clock::now() - s_last_cursor_motion >= kCursorIdleDuration;
}
bool should_show_cursor(bool captured) {
if (captured) {
s_idle_frames = 0;
set_cursor_visible(false);
return false;
}
if (ui::any_document_visible()) {
return true;
}
if (imgui_windows_visible()) {
return true;
}
if (menu_pointer::enabled() && menu_pointer::active()) {
return true;
}
if (mouse_input_enabled()) {
return false;
}
return !cursor_idle();
}
void update_cursor_visibility(SDL_Window* window, bool captured) {
if (window == nullptr || !is_window_focused(window)) {
return;
}
const ImGuiIO& io = ImGui::GetIO();
if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f) {
s_idle_frames = 0;
set_cursor_visible(true);
return;
}
if (s_idle_frames < kIdleHideFrames) {
++s_idle_frames;
set_cursor_visible(true);
} else {
set_cursor_visible(false);
}
set_cursor_visible(should_show_cursor(captured));
}
} // namespace
void read() {
SDL_Window* window = aurora::window::get_sdl_window();
const bool capture_active = syncCaptureState(window, shouldCaptureMouse(window));
const bool capture_active = sync_capture_state(window, should_capture_mouse(window));
update_cursor_visibility(window, capture_active);
if (!capture_active) {
return;
}
const bool aim_active = capture_active && queryMouseAimContext();
const bool aim_active = capture_active && query_mouse_aim_context();
const bool camera_active = capture_active && getSettings().game.enableMouseCamera;
float mx_rel = 0.0f;
float my_rel = 0.0f;
SDL_GetRelativeMouseState(&mx_rel, &my_rel);
accumulateDeltas(mx_rel, my_rel, camera_active, aim_active);
accumulate_deltas(mx_rel, my_rel, camera_active, aim_active);
}
void getAimDeltas(float& out_yaw, float& out_pitch) {
void get_aim_deltas(float& out_yaw, float& out_pitch) {
out_yaw = s_aim_yaw_rad;
out_pitch = s_aim_pitch_rad;
}
void getCameraDeltas(float& out_yaw, float& out_pitch) {
void get_camera_deltas(float& out_yaw, float& out_pitch) {
out_yaw = 0.0f;
out_pitch = 0.0f;
@@ -178,26 +198,28 @@ void getCameraDeltas(float& out_yaw, float& out_pitch) {
void handle_event(const SDL_Event& event) noexcept {
switch (event.type) {
case SDL_EVENT_MOUSE_MOTION:
s_last_cursor_motion = Clock::now();
break;
case SDL_EVENT_WINDOW_FOCUS_LOST:
onFocusLost();
on_focus_lost();
break;
case SDL_EVENT_WINDOW_FOCUS_GAINED:
onFocusGained();
on_focus_gained();
break;
}
}
void onFocusLost() {
void on_focus_lost() {
SDL_Window* window = aurora::window::get_sdl_window();
if (window != nullptr) {
syncCaptureState(window, false);
sync_capture_state(window, false);
}
s_idle_frames = 0;
set_cursor_visible(true);
}
void onFocusGained() {
void on_focus_gained() {
SDL_Window* window = aurora::window::get_sdl_window();
syncCaptureState(window, shouldCaptureMouse(window));
sync_capture_state(window, should_capture_mouse(window));
}
} // namespace dusk::mouse
+6
View File
@@ -230,6 +230,9 @@ UserSettings g_userSettings = {
.boomerangColor = {"cosmetics.boomerangColor", ""},
.ironBootsColor = {"cosmetics.ironBootsColor", ""},
.spinnerColor = {"cosmetics.spinnerColor", ""},
.midnaHairBaseColor = {"cosmetics.midnaHairBaseColor", "Default"},
.midnaHairTipsColor = {"cosmetics.midnaHairTipsColor", "Default"},
.midnaChargeRingColor = {"cosmetics.midnaChargeRingColor", ""},
.linkHairColor = {"cosmetics.linkHairColor", ""},
.wolfLinkColor = {"cosmetics.wolfLinkColor", ""},
.eponaColor = {"cosmetics.eponaColor", ""},
@@ -424,6 +427,9 @@ void registerSettings() {
Register(g_userSettings.cosmetics.boomerangColor);
Register(g_userSettings.cosmetics.ironBootsColor);
Register(g_userSettings.cosmetics.spinnerColor);
Register(g_userSettings.cosmetics.midnaHairBaseColor);
Register(g_userSettings.cosmetics.midnaHairTipsColor);
Register(g_userSettings.cosmetics.midnaChargeRingColor);
Register(g_userSettings.cosmetics.linkHairColor);
Register(g_userSettings.cosmetics.wolfLinkColor);
Register(g_userSettings.cosmetics.eponaColor);
+74 -37
View File
@@ -1,6 +1,7 @@
#include "cosmetics.hpp"
#include "dusk/config.hpp"
#include "dusk/cosmetics/midna_hair_color.hpp"
#include "dusk/randomizer/generator/utility/string.hpp"
#include "pane.hpp"
#include "string_button.hpp"
@@ -45,7 +46,32 @@ static const auto masterSwordColors = std::unordered_map<std::string, std::strin
{"30d0d0", "Cyan"},
});
void add_cosmetic_option(Pane& leftPane, Pane& rightPane, const char* key, ConfigVar<std::string>& option,
// No custom hex colors for now
static const auto midnaHairColors = std::unordered_map<std::string, std::string>({
{"Default", "Default"},
{"Pink", "Pink"},
{"Red", "Red"},
{"Yellow", "Yellow"},
{"Green", "Green"},
{"Blue", "Blue"},
{"Purple", "Purple"},
{"Brown", "Brown"},
{"White", "White"},
});
static const auto chargeRingColors = std::unordered_map<std::string, std::string>({
{"ff9f9f", "Pink"},
{"ff0000", "Red"},
{"ffff00", "Yellow"},
{"00ff00", "Green"},
{"0000ff", "Blue"},
{"ff00ff", "Purple"},
{"331900", "Brown"},
{"feffff", "White"},
{"000000", "Black"},
});
void add_cosmetic_option(Pane& leftPane, Pane& rightPane, const std::string& key, ConfigVar<std::string>& option,
const std::unordered_map<std::string, std::string>& colorPresets = defaultHexColors) {
leftPane.register_control(leftPane.add_select_button({
.key = key,
@@ -64,42 +90,47 @@ void add_cosmetic_option(Pane& leftPane, Pane& rightPane, const char* key, Confi
pane.clear();
pane.add_rml(fmt::format("Choose {}. Leave blank for default value. A reload or reboot may be required to see color changes ingame.", key));
pane.add_child<StringButton>(StringButton::Props{
.key = "Edit Hex Color",
.getValue = [&option] {
return option;
},
.setValue = [&option](Rml::String str) {
// Make lowercase
for (char& c : str) {
c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
if (!key.starts_with("Midna's Hair")) {
pane.add_child<StringButton>(StringButton::Props{
.key = "Edit Hex Color",
.getValue = [&option] {
return option;
},
.setValue = [&option](Rml::String str) {
// Make lowercase
for (char& c : str) {
c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
}
option.setValue(str);
config::Save();
},
.maxLength = 6,
});
pane.add_button(ControlledButton::Props{
.text = "Default",
.isSelected = [&option] {
return option.getValue().empty();
}
}).on_pressed([key, &option] {
option.setValue("");
if (key.starts_with("Midna's Hair")) {
cosmetics::set_all_midna_hair_colors();
}
option.setValue(str);
config::Save();
},
.maxLength = 6,
});
});
pane.add_button(ControlledButton::Props{
.text = "Default",
.isSelected = [&option] {
return option.getValue().empty();
}
}).on_pressed([&option] {
option.setValue("");
config::Save();
});
pane.add_button(ControlledButton::Props{
.text = "Random Color",
}).on_pressed([&option] {
std::random_device rd{};
std::uniform_int_distribution dist(0, 0xFFFFFF);
std::string hexStr = randomizer::utility::str::intToHex(dist(rd), false);
option.setValue(hexStr);
config::Save();
});
pane.add_button(ControlledButton::Props{
.text = "Random Color",
}).on_pressed([&option] {
std::random_device rd{};
std::uniform_int_distribution dist(0, 0xFFFFFF);
std::string hexStr = randomizer::utility::str::intToHex(dist(rd), 6, false);
option.setValue(hexStr);
config::Save();
});
}
for (const auto& [hexStr, color] : colorPresets) {
pane.add_button(ControlledButton::Props{
@@ -107,8 +138,11 @@ void add_cosmetic_option(Pane& leftPane, Pane& rightPane, const char* key, Confi
.isSelected = [hexStr, &option] {
return option.getValue() == hexStr;
},
}).on_pressed([hexStr, &option] {
}).on_pressed([key, hexStr, &option] {
option.setValue(hexStr);
if (key.starts_with("Midna's Hair")) {
cosmetics::set_all_midna_hair_colors();
}
config::Save();
});
}
@@ -142,13 +176,16 @@ CosmeticsWindow::CosmeticsWindow() {
});
add_tab("Misc. Colors", [this, &cosmetics](Rml::Element* content) {
add_tab("Misc Colors", [this, &cosmetics](Rml::Element* content) {
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
auto& rightPane = add_child<Pane>(content, Pane::Type::Controlled);
add_cosmetic_option(leftPane, rightPane, "Midna's Hair Base Color", cosmetics.midnaHairBaseColor, midnaHairColors);
add_cosmetic_option(leftPane, rightPane, "Midna's Hair Tips Color", cosmetics.midnaHairTipsColor, midnaHairColors);
add_cosmetic_option(leftPane, rightPane, "Midna Charge Ring Color", cosmetics.midnaChargeRingColor, chargeRingColors);
add_cosmetic_option(leftPane, rightPane, "Link's Hair Color", cosmetics.linkHairColor);
add_cosmetic_option(leftPane, rightPane, "Wolf Link Color", cosmetics.wolfLinkColor);
add_cosmetic_option(leftPane, rightPane, "Epona Color", cosmetics.eponaColor);
});
}
}
}
+1
View File
@@ -137,6 +137,7 @@ SelectButton& rando_config_button(
newIndex = 0;
}
setting->SetCurrentOption(newIndex);
SaveRandomizerConfig();
updateRightPane();
};
+5 -2
View File
@@ -49,6 +49,7 @@
#include "SSystem/SComponent/c_API.h"
#include "dusk/android_frame_rate.hpp"
#include "dusk/app_info.hpp"
#include "dusk/cosmetics/midna_hair_color.hpp"
#include "dusk/crash_handler.h"
#include "dusk/crash_reporting.h"
#include "dusk/data.hpp"
@@ -255,12 +256,12 @@ void main01(void) {
goto eventsDone;
case AURORA_PAUSED:
dusk::audio::SetPaused(true);
dusk::mouse::onFocusLost();
dusk::mouse::on_focus_lost();
break;
case AURORA_UNPAUSED:
dusk::audio::SetPaused(false);
dusk::game_clock::reset_frame_timer();
dusk::mouse::onFocusGained();
dusk::mouse::on_focus_gained();
break;
case AURORA_SDL_EVENT:
dusk::mouse::handle_event(event->sdl);
@@ -665,6 +666,8 @@ int game_main(int argc, char* argv[]) {
dusk::audio::SetEnableReverb(dusk::getSettings().audio.enableReverb);
dusk::audio::EnableHrtf = dusk::getSettings().audio.enableHrtf;
dusk::cosmetics::set_all_midna_hair_colors();
// Run ImGui UI loop if Aurora couldn't initialize a backend
if (auroraInfo.backend == BACKEND_NULL) {
launchUILoop();