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-inner.png b/res/org-icon-inner.png
new file mode 100644
index 0000000000..7dbeb9dabc
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..f8ceaafe3e 100644
--- a/res/rml/overlay.rcss
+++ b/res/rml/overlay.rcss
@@ -111,4 +111,41 @@ icon.trophy {
height: 24dp;
font-size: 24dp;
decorator: text("" center center);
-}
\ No newline at end of file
+}
+
+logo {
+ position: absolute;
+ width: 100dp;
+ height: 100dp;
+ bottom: 40dp;
+ left: 40dp;
+ opacity: 0;
+ transition: opacity 0.5s linear-in-out;
+}
+
+logo[open] {
+ opacity: 1;
+}
+
+logo img {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ filter: drop-shadow(#0008 0 0 14dp);
+}
+
+logo img.outer {
+ transform-origin: center;
+ animation: 8s linear-in-out infinite logo-outer-spin;
+}
+
+@keyframes logo-outer-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
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..381be0c41e 100644
--- a/src/dusk/ui/overlay.cpp
+++ b/src/dusk/ui/overlay.cpp
@@ -22,30 +22,40 @@ 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