diff --git a/assets/org-icon.svg b/assets/org-icon.svg
new file mode 100644
index 0000000000..b1e82ead45
--- /dev/null
+++ b/assets/org-icon.svg
@@ -0,0 +1,66 @@
+
diff --git a/extern/aurora b/extern/aurora
index f845a5a58c..4cd8d2f009 160000
--- a/extern/aurora
+++ b/extern/aurora
@@ -1 +1 @@
-Subproject commit f845a5a58cfb576049e9ba8392c5c5ca61d550b6
+Subproject commit 4cd8d2f009f6e38ac96cdf1ea249d0c155af9fcb
diff --git a/libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp b/libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp
index 32f0e4eed9..c3c72310a0 100644
--- a/libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp
+++ b/libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp
@@ -556,8 +556,8 @@ void J3DModelLoader::readVertexData(const J3DVertexBlock& block, J3DVertexData&
if (attr == GX_VA_POS) {
// can be a little off due to 0x20 alignment, account for that
- u32 expect = ((data.mVtxNum * vertStride) + 0x1F) & ~0x1F;
- JUT_ASSERT(1234, expect == addrDiff);
+ // u32 expect = ((data.mVtxNum * vertStride) + 0x1F) & ~0x1F;
+ // JUT_ASSERT(1234, expect == addrDiff);
} else if (attr == GX_VA_NRM) {
data.mNrmNum = num;
} else if (attr == GX_VA_CLR0) {
diff --git a/res/org-icon-center.png b/res/org-icon-center.png
new file mode 100644
index 0000000000..b3ec7e1f6b
Binary files /dev/null and b/res/org-icon-center.png differ
diff --git a/res/org-icon-inner.png b/res/org-icon-inner.png
new file mode 100644
index 0000000000..4b3c864c74
Binary files /dev/null and b/res/org-icon-inner.png differ
diff --git a/res/org-icon-outer.png b/res/org-icon-outer.png
new file mode 100644
index 0000000000..6cbcf084d2
Binary files /dev/null and b/res/org-icon-outer.png differ
diff --git a/res/org-icon.png b/res/org-icon.png
index b7a0614b9b..288dc8768f 100644
Binary files a/res/org-icon.png and b/res/org-icon.png differ
diff --git a/res/rml/overlay.rcss b/res/rml/overlay.rcss
index 416252a66b..e9c4644476 100644
--- a/res/rml/overlay.rcss
+++ b/res/rml/overlay.rcss
@@ -111,4 +111,54 @@ icon.trophy {
height: 24dp;
font-size: 24dp;
decorator: text("" center center);
+}
+
+logo {
+ position: absolute;
+ width: 100dp;
+ height: 100dp;
+ bottom: 40dp;
+ left: 40dp;
+ opacity: 0;
+ transition: opacity 0.5s linear-in-out;
+}
+
+logo[open] {
+ opacity: 0.65;
+}
+
+logo img {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ filter: drop-shadow(#0008 0 0 14dp);
+ transform-origin: center;
+}
+
+logo img.inner {
+ animation: 24s linear-in-out infinite logo-inner-spin;
+}
+
+logo img.outer {
+ animation: 8s linear-in-out infinite logo-outer-spin;
+}
+
+@keyframes logo-inner-spin {
+ from {
+ transform: rotate(360deg);
+ }
+ to {
+ transform: rotate(0deg);
+ }
+}
+
+@keyframes logo-outer-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
}
\ No newline at end of file
diff --git a/res/rml/window.rcss b/res/rml/window.rcss
index c35670904e..24f616e500 100644
--- a/res/rml/window.rcss
+++ b/res/rml/window.rcss
@@ -104,6 +104,10 @@ window content pane > * {
flex: 0 0 auto;
}
+window content pane:last-of-type > div {
+ line-height: 1.625;
+}
+
window content pane > spacer {
display: block;
/* Completes the 24dp bottom inset after the pane's 8dp gap. */
diff --git a/src/d/actor/d_a_alink_dusk.cpp b/src/d/actor/d_a_alink_dusk.cpp
index d53476aa91..8c1d415ae0 100644
--- a/src/d/actor/d_a_alink_dusk.cpp
+++ b/src/d/actor/d_a_alink_dusk.cpp
@@ -44,16 +44,14 @@ void daAlink_c::handleWolfHowl() {
bool canHowl = false;
if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY) && !checkMagneBootsOn()) {
- if (!checkForestOldCentury()) {
- if (checkMidnaRide()) {
- if ((checkWolf() &&
- (checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
- (!checkWolf() &&
- (checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
- (checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
- {
- canHowl = true;
- }
+ if (checkMidnaRide()) {
+ if ((checkWolf() &&
+ (checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
+ (!checkWolf() &&
+ (checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
+ (checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
+ {
+ canHowl = true;
}
}
}
@@ -124,16 +122,14 @@ void daAlink_c::handleQuickTransform() {
bool canTransform = false;
if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY) && !checkMagneBootsOn()) {
- if (!checkForestOldCentury()) {
- if (checkMidnaRide()) {
- if ((checkWolf() &&
- (checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
- (!checkWolf() &&
- (checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
- (checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
- {
- canTransform = true;
- }
+ if (checkMidnaRide()) {
+ if ((checkWolf() &&
+ (checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) ||
+ (!checkWolf() &&
+ (checkEventRun() || getMidnaActor()->checkMetamorphoseEnable()) &&
+ (checkModeFlg(4) || dComIfGp_checkPlayerStatus0(0, 0x10))))
+ {
+ canTransform = true;
}
}
}
diff --git a/src/d/d_map.cpp b/src/d/d_map.cpp
index d4e5a98888..25d792f309 100644
--- a/src/d/d_map.cpp
+++ b/src/d/d_map.cpp
@@ -1595,7 +1595,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
calcMapCmPerTexel(field_0x80, &field_0x58);
getPack(field_0x80, &mPackX, &mPackZ);
- mCenterX += mPackX;
+ mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX;
mCenterZ -= mPackZ;
mCenterX += field_0x64;
mCenterZ += mPackPlusZ;
@@ -1657,7 +1657,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
calcMapCmPerTexel(field_0x80, &field_0x58);
getPack(field_0x80, &mPackX, &mPackZ);
- mCenterX += mPackX;
+ mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX;
mCenterZ -= mPackZ;
}
break;
@@ -1737,7 +1737,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
calcMapCmPerTexel(field_0x80, &field_0x58);
getPack(field_0x80, &mPackX, &mPackZ);
- mCenterX += mPackX;
+ mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -mPackX :) mPackX;
mCenterZ -= mPackZ;
field_0x8f = 4;
#if DEBUG
@@ -1829,7 +1829,7 @@ void dMap_c::_move(f32 i_centerX, f32 i_centerZ, int i_roomNo, f32 param_3) {
sp14 += temp_f31_2 * (spC - sp14);
sp10 += temp_f31_2 * (sp8 - sp10);
- mCenterX += sp14;
+ mCenterX += IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -sp14 :) sp14;
mCenterZ -= sp10;
break;
}
diff --git a/src/d/d_menu_dmap.cpp b/src/d/d_menu_dmap.cpp
index 8ef7fadd4b..b39c9bb287 100644
--- a/src/d/d_menu_dmap.cpp
+++ b/src/d/d_menu_dmap.cpp
@@ -942,7 +942,10 @@ void dMenu_DmapBg_c::draw() {
f32 local_28c = mpBackTexture->getBounds().i.x;
mpBackTexture->setBlackWhite(color_black, color_white);
mpBackTexture->draw(local_28c, field_0xd94 + mpBackTexture->getBounds().i.y, mpBackTexture->getWidth(),
- mpBackTexture->getHeight(), false, false, false);
+ mpBackTexture->getHeight(),
+ IF_DUSK(dusk::getSettings().game.enableMirrorMode ? true :) false,
+ false,
+ false);
grafContext->scissor(field_0xd94 + mDoGph_gInf_c::getMinXF(),
scissor_top, mDoGph_gInf_c::getWidthF(),
diff --git a/src/d/d_menu_dmap_map.cpp b/src/d/d_menu_dmap_map.cpp
index 9100a7d63a..0bb9717952 100644
--- a/src/d/d_menu_dmap_map.cpp
+++ b/src/d/d_menu_dmap_map.cpp
@@ -368,7 +368,7 @@ void dMenu_StageMapCtrl_c::initGetTreasureList(u8 param_0, s8 param_1) {
}
inline static s16 rightModeCnvRot(s16 param_0) {
- return param_0;
+ return IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -param_0 :) param_0;
}
bool dMenu_StageMapCtrl_c::getTreasureList(f32* o_posX, f32* o_posY, s8* param_2, u8* o_swbit,
@@ -405,7 +405,7 @@ bool dMenu_StageMapCtrl_c::getTreasureList(f32* o_posX, f32* o_posY, s8* param_2
}
inline static f32 rightModeCnvPos(f32 param_0) {
- return param_0;
+ return IF_DUSK(dusk::getSettings().game.enableMirrorMode ? -param_0 :) param_0;
}
void dMenu_StageMapCtrl_c::cnvPosTo2Dpos(f32 param_0, f32 param_1, f32* param_2,
diff --git a/src/dusk/autosave.cpp b/src/dusk/autosave.cpp
index f9b76f4c67..779cb19915 100644
--- a/src/dusk/autosave.cpp
+++ b/src/dusk/autosave.cpp
@@ -1,4 +1,5 @@
#include "dusk/autosave.h"
+#include "dusk/ui/ui.hpp"
#include "imgui/ImGuiConsole.hpp"
u8 mSaveBuffer[QUEST_LOG_SIZE * 3];
@@ -83,6 +84,9 @@ void waitingForWrite() {
}
void endAutoSave() {
- dusk::g_imguiConsole.AddToast("Saving...", 2.0f);
+ dusk::ui::push_toast({
+ .type = "autosave",
+ .duration = std::chrono::milliseconds(1500),
+ });
mAutoSaveProc = 0;
}
\ No newline at end of file
diff --git a/src/dusk/ui/graphics_tuner.cpp b/src/dusk/ui/graphics_tuner.cpp
index 390d4f9971..6ccabd3f1d 100644
--- a/src/dusk/ui/graphics_tuner.cpp
+++ b/src/dusk/ui/graphics_tuner.cpp
@@ -157,15 +157,16 @@ void SteppedCarousel::apply(int value) {
Rml::String format_graphics_setting_value(GraphicsOption option, int value) {
switch (option) {
- case GraphicsOption::InternalResolution:
+ case GraphicsOption::InternalResolution: {
+ u32 width = 0;
+ u32 height = 0;
+ AuroraGetRenderSize(&width, &height);
if (value <= 0) {
- return "Auto";
+ return fmt::format("Auto ({}×{})", width, height);
} else {
- u32 width = 0;
- u32 height = 0;
- AuroraGetRenderSize(&width, &height);
return fmt::format("{}× ({}×{})", value, width, height);
}
+ }
case GraphicsOption::ShadowResolution:
return fmt::format("{}×", value);
case GraphicsOption::BloomMode:
diff --git a/src/dusk/ui/overlay.cpp b/src/dusk/ui/overlay.cpp
index a222f1e8ff..109ea7e0a3 100644
--- a/src/dusk/ui/overlay.cpp
+++ b/src/dusk/ui/overlay.cpp
@@ -22,30 +22,41 @@ const Rml::String kDocumentSource = R"RML(
)RML";
Rml::Element* create_toast(Rml::Element* parent, const Toast& toast) {
- auto* elem = append(parent, "toast");
- if (!toast.type.empty()) {
- elem->SetClass(toast.type, true);
- }
- {
- auto* heading = append(elem, "heading");
- auto* span = append(heading, "span");
- span->SetInnerRML(toast.title);
- if (toast.type == "achievement") {
- auto* icon = append(heading, "icon");
- icon->SetClass("trophy", true);
- mDoAud_seStartMenu(kSoundAchievementUnlock);
+ if (toast.type == "autosave") {
+ Rml::Factory::InstanceElementText(parent, R"RML(
+
+
+
+
+
+)RML");
+ return parent->GetFirstChild();
+ } else {
+ auto* elem = append(parent, "toast");
+ if (!toast.type.empty()) {
+ elem->SetClass(toast.type, true);
}
+ {
+ auto* heading = append(elem, "heading");
+ auto* span = append(heading, "span");
+ span->SetInnerRML(toast.title);
+ if (toast.type == "achievement") {
+ auto* icon = append(heading, "icon");
+ icon->SetClass("trophy", true);
+ mDoAud_seStartMenu(kSoundAchievementUnlock);
+ }
+ }
+ {
+ auto* message = append(elem, "message");
+ auto* span = append(message, "span");
+ span->SetInnerRML(toast.content);
+ }
+ {
+ auto* progress = append(elem, "progress");
+ progress->SetAttribute("value", 1.f);
+ }
+ return elem;
}
- {
- auto* message = append(elem, "message");
- auto* span = append(message, "span");
- span->SetInnerRML(toast.content);
- }
- {
- auto* progress = append(elem, "progress");
- progress->SetAttribute("value", 1.f);
- }
- return elem;
}
} // namespace