mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-21 21:40:32 -04:00
Random UI and README tweaks (#653)
This commit is contained in:
@@ -1,37 +1,48 @@
|
||||

|
||||
<div align="center">
|
||||
<img src="res/logo-mascot.png" alt="Logo" width="640">
|
||||
|
||||
- ### **[Official Website](https://twilitrealm.dev)**
|
||||
- ### **[Discord](https://discord.gg/QACynxeyna)**
|
||||
<p align="center">
|
||||
<a href="https://twilitrealm.dev">Official Website</a>
|
||||
•
|
||||
<a href="https://discord.gg/QACynxeyna">Discord</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
# Overview
|
||||
|
||||
Dusk is a reverse-engineered reimplementation of Twilight Princess.
|
||||
|
||||
It aims to be as accurate as possible to the original while also providing new options, enhancements, and tools to customize your experience.
|
||||
|
||||
# Setup
|
||||
**⚠️ Dusk does NOT provide any copyrighted assets. You must provide your own copy of the game.**
|
||||
|
||||
### 1. Verify your ROM dump
|
||||
First make sure your dump of the game is clean and supported by Dusk. You can do this by checking the sha1 hash of your dump against this list of supported versions.
|
||||
> [!IMPORTANT]
|
||||
> Dusk does *not* provide any copyrighted assets. You must provide your own copy of the original game.
|
||||
|
||||
| Version | sha1 hash |
|
||||
|--------------| ---------------------------------------- |
|
||||
| GameCube USA | 75edd3ddff41f125d1b4ce1a40378f1b565519e7 |
|
||||
| GameCube PAL | 2601822a488eeb86fb89db16ca8f29c2c953e1ca |
|
||||
### 1. Verify your dump
|
||||
|
||||
First, make sure your dump of the game is clean and supported by Dusk. You can do this by checking the SHA-1 hash of your dump against this list of supported versions:
|
||||
|
||||
| Version | SHA-1 hash |
|
||||
|--------------| ------------------------------------------ |
|
||||
| GameCube USA | `75edd3ddff41f125d1b4ce1a40378f1b565519e7` |
|
||||
| GameCube EUR | `2601822a488eeb86fb89db16ca8f29c2c953e1ca` |
|
||||
|
||||
### 2. Download [Dusk](https://github.com/TwilitRealm/dusk/releases)
|
||||
|
||||
### 3. Setup the game
|
||||
- Extract the zip folder
|
||||
- Launch Dusk
|
||||
- Select Options, then set the ISO Path to your supported game dump
|
||||
- Press Start Game to play!
|
||||
|
||||

|
||||
- Extract the .zip file
|
||||
- Launch Dusk
|
||||
- Press **Select Disc Image**, navigate to your game dump, and select the file
|
||||
- Press **Start Game** to play!
|
||||
|
||||
# Building
|
||||
|
||||
If you'd like to build Dusk from source, please read the [build instructions](docs/building.md).
|
||||
|
||||
Pull Requests are welcomed! Note that we do not accept contributions that are primarily AI generated and will close your PR if we suspect as much.
|
||||
Pull requests are welcomed! Note that we do not accept contributions that are primarily AI-generated and will close your PR if we suspect as much.
|
||||
|
||||
# Credits
|
||||
|
||||
Special thanks to the [TP decompilation](https://github.com/zeldaret/tp) team, the GC/Wii decompilation community, the [Aurora](https://github.com/encounter/aurora) developers, the [TP speedrunning community](https://zsrtp.link), and all [contributors](https://github.com/TwilitRealm/dusk/graphs/contributors).
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 82 KiB |
+34
-10
@@ -104,13 +104,14 @@ hero img {
|
||||
decorator: horizontal-gradient(#FEE685FF #FEE68500);
|
||||
}
|
||||
|
||||
disk-status {
|
||||
disc-info {
|
||||
position: absolute;
|
||||
left: 96dp;
|
||||
bottom: 72dp;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8dp;
|
||||
gap: 12dp;
|
||||
font-size: 24dp;
|
||||
}
|
||||
|
||||
version-info {
|
||||
@@ -119,30 +120,53 @@ version-info {
|
||||
bottom: 72dp;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8dp;
|
||||
gap: 12dp;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.status,
|
||||
.version {
|
||||
font-size: 24dp;
|
||||
}
|
||||
|
||||
.status,
|
||||
.update {
|
||||
#disc-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8dp;
|
||||
}
|
||||
|
||||
#disc-status[status=good] {
|
||||
color: #D8F999;
|
||||
}
|
||||
|
||||
.status[bad] {
|
||||
#disc-status[status=bad] {
|
||||
color: #FFC9C9;
|
||||
}
|
||||
|
||||
#disc-status icon {
|
||||
display: block;
|
||||
width: 24dp;
|
||||
height: 24dp;
|
||||
font-family: "Material Symbols Rounded";
|
||||
font-weight: normal;
|
||||
font-size: 24dp;
|
||||
}
|
||||
|
||||
#disc-status[status=good] icon {
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
#disc-status[status=bad] icon {
|
||||
decorator: text("" center center);
|
||||
}
|
||||
|
||||
#disc-version {
|
||||
font-size: 20dp;
|
||||
}
|
||||
|
||||
/* TODO: Hidden until an actual update checker is introduced */
|
||||
.update {
|
||||
display: none;
|
||||
font-size: 16dp;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
color: #D8F999;
|
||||
}
|
||||
|
||||
.detail,
|
||||
|
||||
+27
-18
@@ -28,10 +28,13 @@ const Rml::String kDocumentSource = R"RML(
|
||||
</hero>
|
||||
<div id="menu-list" />
|
||||
</menu>
|
||||
<disk-status class="intro-item delay-4">
|
||||
<span id="status" class="status" />
|
||||
<span id="detail" class="detail" />
|
||||
</disk-status>
|
||||
<disc-info class="intro-item delay-4">
|
||||
<div id="disc-status">
|
||||
<icon />
|
||||
<span id="disc-status-label" />
|
||||
</div>
|
||||
<span id="disc-version" class="detail" />
|
||||
</disc-info>
|
||||
<version-info class="intro-item delay-5">
|
||||
<div class="version">Version <span id="version-text"></span></div>
|
||||
<div class="update"><span>Update available!</span> Download</div>
|
||||
@@ -113,7 +116,7 @@ Prelaunch::Prelaunch() : Document(kDocumentSource), mRoot(mDocument->GetElementB
|
||||
if (auto* menuList = mDocument->GetElementById("menu-list")) {
|
||||
const bool hasValidPath = is_selected_path_valid();
|
||||
mMenuButtons.push_back(
|
||||
std::make_unique<Button>(menuList, hasValidPath ? "Start Game" : "Select Disk Image"));
|
||||
std::make_unique<Button>(menuList, hasValidPath ? "Start Game" : "Select Disc Image"));
|
||||
mMenuButtons.back()->on_pressed([this] {
|
||||
if (!is_selected_path_valid()) {
|
||||
open_iso_picker();
|
||||
@@ -133,8 +136,8 @@ Prelaunch::Prelaunch() : Document(kDocumentSource), mRoot(mDocument->GetElementB
|
||||
apply_intro_animation(mMenuButtons.back()->root(), "delay-3");
|
||||
}
|
||||
|
||||
mDiscStatus = mDocument->GetElementById("status");
|
||||
mDiscDetail = mDocument->GetElementById("detail");
|
||||
mDiscStatus = mDocument->GetElementById("disc-status");
|
||||
mDiscDetail = mDocument->GetElementById("disc-version");
|
||||
mVersion = mDocument->GetElementById("version-text");
|
||||
|
||||
listen(mDocument, Rml::EventId::Transitionend, [this](Rml::Event& event) {
|
||||
@@ -185,27 +188,34 @@ void Prelaunch::update() {
|
||||
}
|
||||
|
||||
if (!mMenuButtons.empty()) {
|
||||
mMenuButtons[0]->set_text(hasValidPath ? "Start Game" : "Select Disk Image");
|
||||
mMenuButtons[0]->set_text(hasValidPath ? "Start Game" : "Select Disc Image");
|
||||
}
|
||||
if (mDiscStatus != nullptr) {
|
||||
|
||||
const auto discStatusLabel = mDiscStatus->GetElementById("disc-status-label");
|
||||
|
||||
if (mDiscStatus != nullptr && discStatusLabel != nullptr) {
|
||||
if (hasValidPath) {
|
||||
mDiscStatus->RemoveAttribute("bad");
|
||||
mDiscStatus->SetInnerRML("Disc Ready");
|
||||
mDiscStatus->SetAttribute("status", "good");
|
||||
discStatusLabel->SetInnerRML("Disc ready.");
|
||||
} else {
|
||||
mDiscStatus->SetAttribute("bad", "");
|
||||
mDiscStatus->SetInnerRML("Disk Not Found");
|
||||
mDiscStatus->SetAttribute("status", "bad");
|
||||
discStatusLabel->SetInnerRML("Disc not found.");
|
||||
}
|
||||
}
|
||||
if (mDiscDetail != nullptr) {
|
||||
if (hasValidPath) {
|
||||
mDiscDetail->SetProperty(Rml::PropertyId::Display, Rml::Style::Display::Block);
|
||||
mDiscDetail->SetInnerRML(state.isPal ? "GameCube • PAL" : "GameCube • USA");
|
||||
mDiscDetail->SetInnerRML(state.isPal ? "GameCube • EUR" : "GameCube • USA");
|
||||
} else {
|
||||
mDiscDetail->SetProperty(Rml::PropertyId::Display, Rml::Style::Display::None);
|
||||
}
|
||||
}
|
||||
if (mVersion != nullptr) {
|
||||
mVersion->SetInnerRML(escape(DUSK_WC_DESCRIBE));
|
||||
std::string_view versionStr(DUSK_WC_DESCRIBE);
|
||||
if (versionStr[0] == 'v') {
|
||||
versionStr = versionStr.substr(1);
|
||||
}
|
||||
mVersion->SetInnerRML(escape(versionStr));
|
||||
}
|
||||
|
||||
Document::update();
|
||||
@@ -239,9 +249,8 @@ bool Prelaunch::handle_nav_command(Rml::Event& event, NavCommand cmd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const auto buttonCount = static_cast<int>(mMenuButtons.size());
|
||||
int i = (focusedButton + direction) % buttonCount;
|
||||
if (i < 0) i += buttonCount;
|
||||
const auto n = static_cast<int>(mMenuButtons.size());
|
||||
int i = ((focusedButton + direction) % n + n) % n;
|
||||
while (i >= 0 && i < mMenuButtons.size()) {
|
||||
if (mMenuButtons[i]->focus()) {
|
||||
event.StopPropagation();
|
||||
|
||||
Reference in New Issue
Block a user