Merge branch 'main' of https://github.com/TwilitRealm/dusklight into randomizer

This commit is contained in:
gymnast86
2026-06-15 06:04:32 -04:00
12 changed files with 133 additions and 91 deletions
+1 -1
+3
View File
@@ -157,6 +157,9 @@ public:
int getDispType() const;
void _move(f32, f32, int, f32);
void _draw();
#if TARGET_PC
bool refreshTextureSize();
#endif
virtual ~dMap_c() {
#if DEBUG
+3
View File
@@ -134,6 +134,9 @@ struct UserSettings {
ConfigVar<bool> enableFpsOverlay;
ConfigVar<int> fpsOverlayCorner;
ConfigVar<int> maxFrameRate;
ConfigVar<bool> rememberWindowSize;
ConfigVar<int> lastWindowWidth;
ConfigVar<int> lastWindowHeight;
} video;
struct {
+10
View File
@@ -6882,6 +6882,16 @@ static int daNpc_Ks_Delete(npc_ks_class* i_this) {
i_this->model->stopZelAnime();
}
#if TARGET_PC
if (leader == i_this) {
leader = NULL;
}
if (saru_p[i_this->set_id] == i_this) {
saru_p[i_this->set_id] = NULL;
}
#endif
return 1;
}
+22
View File
@@ -1213,6 +1213,10 @@ void dMap_c::changeTextureSize(int param_1, int param_2, int param_3) {
JUT_ASSERT(2672, mImage_p != NULL);
JUT_ASSERT(2673, mResTIMG != NULL);
#if TARGET_PC
GXDestroyCopyTex(mImage_p);
#endif
mTexSizeX = param_1 >> param_3;
mTexSizeY = param_2 >> param_3;
@@ -1226,6 +1230,24 @@ void dMap_c::changeTextureSize(int param_1, int param_2, int param_3) {
}
#endif
#if TARGET_PC
bool dMap_c::refreshTextureSize() {
JUT_ASSERT(2688, mImage_p != NULL);
JUT_ASSERT(2689, mResTIMG != NULL);
const u16 oldWidth = mResTIMG->width;
const u16 oldHeight = mResTIMG->height;
makeResTIMG(mResTIMG, mTexSizeX, mTexSizeY, mImage_p, (u8*)m_res, 0x33);
if (mResTIMG->width == oldWidth && mResTIMG->height == oldHeight) {
return false;
}
GXDestroyCopyTex(mImage_p);
return true;
}
#endif
void dMap_c::_remove() {
if (mImage_p != NULL) {
#if TARGET_PC
+46 -33
View File
@@ -15,32 +15,49 @@
#include <cstring>
#ifdef TARGET_PC
#include <span>
#include <numbers>
#include <array>
#include "dusk/settings.h"
#include "m_Do/m_Do_graphic.h"
#include <dolphin/gx/GXAurora.h>
#include <aurora/math.hpp>
constexpr u16 kPreferredMapResolutionMultiplier = 4;
constexpr u32 kMaxMapRenderPixels = 4096 * 4096;
constexpr u16 kMapImageSide = 16 * kPreferredMapResolutionMultiplier;
#include <algorithm>
#include <array>
#include <cmath>
#include <functional>
#include <limits>
#include <numbers>
#include <span>
constexpr u16 kMapIconResolutionMultiplier = 4;
constexpr u16 kMapImageSide = 16 * kMapIconResolutionMultiplier;
constexpr u32 kMapImageTotalPixels = kMapImageSide * kMapImageSide;
typedef std::function<u8(size_t, size_t)> PaintI8Fn;
u16 map_resolution_multiplier(u16 width, u16 height) {
const u32 basePixels = static_cast<u32>(width) * height;
if (basePixels == 0) {
return 1;
u16 scaled_map_axis(u16 value, f32 scale) {
const auto scaledValue =
static_cast<u32>(std::max(1.0f, std::round(static_cast<f32>(value) * scale)));
return static_cast<u16>(std::min<u32>(scaledValue, std::numeric_limits<u16>::max()));
}
aurora::Vec2<u16> map_render_size_for(u16 width, u16 height) {
if (width == 0 || height == 0) {
return {width, height};
}
u16 scale = kPreferredMapResolutionMultiplier;
while (scale > 1) {
const u32 scalePixels = static_cast<u32>(scale) * scale;
if (basePixels <= kMaxMapRenderPixels / scalePixels) {
break;
}
scale--;
}
return scale;
u32 renderWidth = 0;
u32 renderHeight = 0;
AuroraGetRenderSize(&renderWidth, &renderHeight);
const f32 logicalWidth = std::max(mDoGph_gInf_c::getWidthF(), 1.0f);
const f32 logicalHeight = std::max(mDoGph_gInf_c::getHeightF(), 1.0f);
const f32 irScaleX = renderWidth > 0 ? static_cast<f32>(renderWidth) / logicalWidth : 1.0f;
const f32 irScaleY = renderHeight > 0 ? static_cast<f32>(renderHeight) / logicalHeight : 1.0f;
const f32 hudScale = std::clamp(dusk::getSettings().game.hudScale.getValue(), 0.5f, 2.0f);
return {
scaled_map_axis(width, irScaleX * hudScale),
scaled_map_axis(height, irScaleY * hudScale),
};
}
void paint_i8(std::span<u8> dst, size_t width, PaintI8Fn paint) {
@@ -496,9 +513,9 @@ void dRenderingMap_c::makeResTIMG(ResTIMG* p_image, u16 width, u16 height, u8* p
p_image->format = GX_TF_C8;
p_image->alphaEnabled = 2;
#ifdef TARGET_PC
const u16 scale = map_resolution_multiplier(width, height);
p_image->width = width * scale;
p_image->height = height * scale;
const auto [rw, rh] = map_render_size_for(width, height);
p_image->width = rw;
p_image->height = rh;
#else
p_image->width = width;
p_image->height = height;
@@ -581,16 +598,14 @@ void dRenderingFDAmap_c::drawBack() const {
void dRenderingFDAmap_c::preRenderingMap() {
#ifdef TARGET_PC
const u16 scale = map_resolution_multiplier(mTexWidth, mTexHeight);
const u16 w = mTexWidth * scale;
const u16 h = mTexHeight * scale;
GXCreateFrameBuffer(w, h);
const auto [rw, rh] = map_render_size_for(mTexWidth, mTexHeight);
GXCreateFrameBuffer(rw, rh);
// Set logical viewport dimensions
GXSetViewport(0.0f, 0.0f, mTexWidth, mTexHeight, 0.0f, 1.0f);
GXSetScissor(0, 0, mTexWidth, mTexHeight);
// Set render viewport dimensions
GXSetViewportRender(0.0f, 0.0f, w, h, 0.0f, 1.0f);
GXSetScissorRender(0, 0, w, h);
GXSetViewportRender(0.0f, 0.0f, rw, rh, 0.0f, 1.0f);
GXSetScissorRender(0, 0, rw, rh);
#else
GXSetViewport(0.0f, 0.0f, mTexWidth, mTexHeight, 0.0f, 1.0f);
GXSetScissor(0, 0, mTexWidth, mTexHeight);
@@ -628,11 +643,9 @@ void dRenderingFDAmap_c::preRenderingMap() {
void dRenderingFDAmap_c::postRenderingMap() {
GXSetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL);
#ifdef TARGET_PC
const u16 scale = map_resolution_multiplier(mTexWidth, mTexHeight);
const u16 w = mTexWidth * scale;
const u16 h = mTexHeight * scale;
GXSetTexCopySrc(0, 0, w, h);
GXSetTexCopyDst(w, h, GX_CTF_R8, GX_FALSE);
const auto [rw, rh] = map_render_size_for(mTexWidth, mTexHeight);
GXSetTexCopySrc(0, 0, rw, rh);
GXSetTexCopyDst(rw, rh, GX_CTF_R8, GX_FALSE);
GXCopyTex(field_0x4, GX_TRUE);
GXRestoreFrameBuffer();
#else
+6
View File
@@ -539,6 +539,12 @@ void dMeterMap_c::_move(u32 param_0) {
}
#endif
#if TARGET_PC
if (mMap->refreshTextureSize()) {
mMapJ2DPicture->changeTexture(mMap->getResTIMGPointer(), 0);
}
#endif
int stayNo = dComIfGp_roomControl_getStayNo();
field_0x14 = param_0;
+6
View File
@@ -11,6 +11,9 @@ UserSettings g_userSettings = {
.enableFpsOverlay {"game.enableFpsOverlay", false},
.fpsOverlayCorner {"game.fpsOverlayCorner", 0},
.maxFrameRate {"video.maxFrameRate", 240},
.rememberWindowSize {"video.rememberWindowSize", false},
.lastWindowWidth {"video.lastWindowWidth", 0},
.lastWindowHeight {"video.lastWindowHeight", 0},
},
.audio = {
@@ -206,6 +209,9 @@ void registerSettings() {
Register(g_userSettings.video.enableFpsOverlay);
Register(g_userSettings.video.fpsOverlayCorner);
Register(g_userSettings.video.maxFrameRate);
Register(g_userSettings.video.rememberWindowSize);
Register(g_userSettings.video.lastWindowWidth);
Register(g_userSettings.video.lastWindowHeight);
// Audio
Register(g_userSettings.audio.masterVolume);
+2 -42
View File
@@ -13,6 +13,7 @@
#include <SDL3/SDL_gamepad.h>
#include <SDL3/SDL_timer.h>
#include <algorithm>
#include <aurora/gfx.h>
#include <dolphin/pad.h>
#include <m_Do/m_Do_main.h>
@@ -187,43 +188,6 @@ void remove_element(Rml::Element*& elem) noexcept {
} // namespace
// https://vplesko.com/posts/how_to_implement_an_fps_counter.html
void Overlay::advance_fps_counter(float& outFps, Uint64 perfFreq) {
if (perfFreq == 0) {
outFps = 0.f;
return;
}
const Uint64 curr = SDL_GetPerformanceCounter();
if (!mFpsHavePrevCounter) {
mFpsPrevCounter = curr;
mFpsHavePrevCounter = true;
outFps = 0.f;
return;
}
const Uint64 processingTicks = curr - mFpsPrevCounter;
mFpsPrevCounter = curr;
mFpsFrameEvents.push_back({curr, processingTicks});
mFpsSumTicks += processingTicks;
while (!mFpsFrameEvents.empty() && mFpsFrameEvents.front().endCounter + perfFreq < curr) {
mFpsSumTicks -= mFpsFrameEvents.front().processingTicks;
mFpsFrameEvents.pop_front();
}
const auto n = mFpsFrameEvents.size();
if (n == 0 || mFpsSumTicks == 0) {
outFps = 0.f;
return;
}
const double avgSeconds =
static_cast<double>(mFpsSumTicks) / static_cast<double>(n) / static_cast<double>(perfFreq);
outFps = static_cast<float>(1.0 / avgSeconds);
}
static std::string FormatTime(OSTime ticks) {
OSCalendarTime t;
OSTicksToCalendarTime(ticks, &t);
@@ -276,8 +240,7 @@ void Overlay::update() {
mFpsCounter->SetAttribute("corner", kFpsCorners[idx]);
const Uint64 perfFreq = SDL_GetPerformanceFrequency();
float fps = 0.f;
advance_fps_counter(fps, perfFreq);
float fps = aurora_get_fps();
const Uint64 now = SDL_GetPerformanceCounter();
// Limit updates to twice per second
@@ -290,9 +253,6 @@ void Overlay::update() {
}
} else {
mFpsCounter->RemoveAttribute("open");
mFpsFrameEvents.clear();
mFpsSumTicks = 0;
mFpsHavePrevCounter = false;
mFpsLastUpdate = 0;
}
}
-13
View File
@@ -3,7 +3,6 @@
#include "document.hpp"
#include <chrono>
#include <deque>
namespace dusk::ui {
@@ -26,19 +25,7 @@ protected:
Rml::Element* mSpeedrunIgt = nullptr;
clock::time_point mCurrentToastStartTime;
clock::time_point mMenuNotificationStartTime;
struct FpsFrameEvent {
Uint64 endCounter;
Uint64 processingTicks;
};
std::deque<FpsFrameEvent> mFpsFrameEvents;
Uint64 mFpsSumTicks = 0;
bool mFpsHavePrevCounter = false;
Uint64 mFpsPrevCounter = 0;
Uint64 mFpsLastUpdate = 0;
void advance_fps_counter(float& outFps, Uint64 perfFreq);
};
} // namespace dusk::ui
+15
View File
@@ -802,6 +802,21 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
pane.add_rml(
"<br/>Display the current framerate in a corner of the screen while playing.");
});
config_bool_select(leftPane, rightPane, getSettings().video.rememberWindowSize,
{
.key = "Remember Window Size",
.helpText = "Save and restore the previous session's window size when opening Dusklight.",
.onChange =
[](bool value) {
if (value && !dusk::getSettings().video.enableFullscreen) {
const auto windowSize = aurora::window::get_window_size();
dusk::getSettings().video.lastWindowWidth.setValue(windowSize.width);
dusk::getSettings().video.lastWindowHeight.setValue(windowSize.height);
dusk::config::Save();
}
},
.isDisabled = [] { return IsMobile; },
});
leftPane.add_section("Resolution");
graphics_tuner_control(*this, leftPane, rightPane,
getSettings().game.internalResolutionScale,
+19 -2
View File
@@ -265,6 +265,13 @@ void main01(void) {
dusk::ui::handle_event(event->sdl);
dusk::g_imguiConsole.HandleSDLEvent(event->sdl);
break;
case AURORA_WINDOW_RESIZED:
if (dusk::getSettings().video.rememberWindowSize && !dusk::getSettings().video.enableFullscreen) {
dusk::getSettings().video.lastWindowWidth.setValue(event->windowSize.width);
dusk::getSettings().video.lastWindowHeight.setValue(event->windowSize.height);
dusk::config::Save();
}
break;
case AURORA_DISPLAY_SCALE_CHANGED:
dusk::ImGuiEngine_Initialize(event->windowSize.scale);
break;
@@ -601,8 +608,18 @@ int game_main(int argc, char* argv[]) {
config.startFullscreen = dusk::getSettings().video.enableFullscreen;
config.windowPosX = -1;
config.windowPosY = -1;
config.windowWidth = defaultWindowWidth * 2;
config.windowHeight = defaultWindowHeight * 2;
const int lastWindowWidth = dusk::getSettings().video.lastWindowWidth.getValue();
const int lastWindowHeight = dusk::getSettings().video.lastWindowHeight.getValue();
if (dusk::getSettings().video.rememberWindowSize && lastWindowWidth > 0 && lastWindowHeight > 0) {
config.windowWidth = lastWindowWidth;
config.windowHeight = lastWindowHeight;
} else {
config.windowWidth = defaultWindowWidth * 2;
config.windowHeight = defaultWindowHeight * 2;
}
config.desiredBackend = ResolveDesiredBackend(parsed_arg_options);
config.logCallback = &aurora_log_callback;
config.logLevel = startupLogLevel;