1
0
mirror of https://github.com/dolphin-emu/dolphin synced 2024-06-28 22:46:42 +00:00

Compare commits

...

22 Commits

Author SHA1 Message Date
Geotale
af52ac5a66
Merge fd61f99974 into 10a95a4d5b 2024-06-25 16:10:36 -07:00
OatmealDome
10a95a4d5b
Merge pull request #12890 from OatmealDome/release-stuff
Miscellaneous release string updates
2024-06-25 01:25:08 -04:00
OatmealDome
04b0ceedcd Android: Update copyright year in About dialog to 2024 2024-06-24 15:08:12 -04:00
OatmealDome
9c432e960b AboutDialog: Update copyright year to 2024 2024-06-24 15:06:54 -04:00
OatmealDome
f8f117e599 GeneralPane: Update "Beta" auto update track to "Releases" 2024-06-24 15:06:37 -04:00
JMC47
c536754ffe
Merge pull request #12878 from LillyJadeKatrin/retroachievements-hardcore-state-changed
Decouple Hardcore from EmulationStateChanged
2024-06-23 18:13:56 -04:00
Admiral H. Curtiss
e9e29daca4
Merge pull request #12872 from LillyJadeKatrin/retroachievements-start-session-bug
Add MemoryVerifier to AchievementManager Startup
2024-06-23 21:18:34 +02:00
Admiral H. Curtiss
2aec195ec8
Merge pull request #12876 from dreamsyntax/advanced-cpu-clock-override-step-adjustment
DolphinQt: Adjust CPU Clock Override slider
2024-06-23 15:28:29 +02:00
Admiral H. Curtiss
c337ab6473
Merge pull request #12884 from Tilka/qt_this
DolphinQt: fix some warnings
2024-06-23 15:08:13 +02:00
Admiral H. Curtiss
a75c65bde2
Merge pull request #12879 from LillyJadeKatrin/retroachievements-1200-shines
Trim extra characters from measured progress
2024-06-23 15:05:09 +02:00
Admiral H. Curtiss
28692681ad
Merge pull request #12883 from LillyJadeKatrin/retroachievements-cutoff-text
Fix cut off text in Achievements dialog
2024-06-23 14:59:54 +02:00
LillyJadeKatrin
bf230a9909 Trim extra characters from measured progress
The measured_progress C string for achievements to display potentially contains junk data after the null terminator, which was rendering in the QString in the dialog. This trims those junk characters.
2024-06-22 23:36:06 -04:00
Tillmann Karras
8e7d11d1a1 DolphinQt: fix -Wunused-const-variable warning 2024-06-23 02:38:04 +01:00
Tillmann Karras
5c46716d28 DolphinQt: fix two -Wshadow-uncaptured-local warnings 2024-06-23 02:38:00 +01:00
Tillmann Karras
0f659508ea DolphinQt: fix two -Wunused-lambda-capture warnings
Also clean up signals a bit.
2024-06-23 00:13:58 +01:00
LillyJadeKatrin
aa393dfb6e Add MemoryVerifier to AchievementManager Startup
rc_client calls the provided memory peeker asynchronously in the callback for starting a session, to validate/invalidate the memory used for achievements. Dolphin cannot access memory from any thread but host or CPU so this access has a small chance of being invalid. This commit adds a MemoryVerifier that the AchievementManager will use to perform this, before changing the peek method back to the original MemoryPeeker for normal operation.
2024-06-22 09:31:00 -04:00
LillyJadeKatrin
e1a8dc65ce Fix cut off text in Achievements dialog 2024-06-22 00:26:52 -04:00
LillyJadeKatrin
29f1b82f5e Decouple Hardcore from EmulationStateChanged
Rerendering the entire Achievements dialog every EmulationStateChanged signal is far too often when it turns out that signal fires multiple times to confirm game close, for example. This change results in only the settings changing on EmulationStateChanged, and having the Hardcore mode toggle (which DOES require redrawing the entire dialog) emit its own signal alongside EmulationStateChanged.
2024-06-20 07:59:59 -04:00
dreamsyntax
55ba014fed DolphinQt: Adjust CPU Clock Override slider
CPU Clock Override slider now increments 1% in the UI, with the new lower limit
being 1% instead of 6%.

Prior implementation made it impossible to set exactly 150% in the GUI.
147% -> 152%. Now users can set exact clock % without needing to edit INIs.
2024-06-18 18:52:35 -07:00
Geotale
fd61f99974
Rewrite expression to be in fewer parts
Per change suggested by JosJuice

Co-authored-by: JosJuice <josjuice@gmail.com>
2024-05-28 16:46:59 -05:00
Geotale
c0c8252860 Correct Removal of Loop
This both removes certain undefined behavior accidentally caused as well as properly fixing and testing the expression -- I hadn't built and tested the loop removal despite thinking I had before, oops ^^;
2024-05-27 18:43:50 -05:00
Geotale
f1a2ea5ae8 Properly Round Subnormals
During 25-bit rounding, subnormals are "normalized", which would normally mean that the exponent needs to be able to be lower than -1023 (which is what PPC does internally), but in actuality it's possible to simply modify at what bit rounding occurs and get the same results!
2024-05-27 17:38:35 -05:00
16 changed files with 101 additions and 40 deletions

View File

@ -874,7 +874,7 @@ It can efficiently compress both junk data and encrypted Wii data.
<string name="about_website"><a href="https://dolphin-emu.org/">Website</a></string>
<string name="about_github"><a href="https://github.com/dolphin-emu/dolphin">GitHub</a></string>
<string name="about_support"><a href="https://forums.dolphin-emu.org/">Support</a></string>
<string name="about_copyright_warning">\u00A9 20032015+ Dolphin Team. \u201cGameCube\u201d and \u201cWii\u201d are trademarks of Nintendo. Dolphin is not affiliated with Nintendo in any way.</string>
<string name="about_copyright_warning">\u00A9 20032024+ Dolphin Team. \u201cGameCube\u201d and \u201cWii\u201d are trademarks of Nintendo. Dolphin is not affiliated with Nintendo in any way.</string>
<string name="system_driver">System driver</string>
<string name="system_driver_desc">The GPU driver that is part of the OS.</string>

View File

@ -13,6 +13,7 @@
#include <rcheevos/include/rc_api_info.h>
#include <rcheevos/include/rc_hash.h>
#include "Common/Assert.h"
#include "Common/CommonPaths.h"
#include "Common/FileUtil.h"
#include "Common/Image.h"
@ -22,6 +23,7 @@
#include "Common/WorkQueueThread.h"
#include "Core/Config/AchievementSettings.h"
#include "Core/Core.h"
#include "Core/HW/Memmap.h"
#include "Core/PowerPC/MMU.h"
#include "Core/System.h"
#include "DiscIO/Blob.h"
@ -44,7 +46,7 @@ void AchievementManager::Init()
LoadDefaultBadges();
if (!m_client && Config::Get(Config::RA_ENABLED))
{
m_client = rc_client_create(MemoryPeeker, Request);
m_client = rc_client_create(MemoryVerifier, Request);
std::string host_url = Config::Get(Config::RA_HOST_URL);
if (!host_url.empty())
rc_client_set_host(m_client, host_url.c_str());
@ -120,6 +122,7 @@ void AchievementManager::LoadGame(const std::string& file_path, const DiscIO::Vo
rc_client_set_unofficial_enabled(m_client, Config::Get(Config::RA_UNOFFICIAL_ENABLED));
rc_client_set_encore_mode_enabled(m_client, Config::Get(Config::RA_ENCORE_ENABLED));
rc_client_set_spectator_mode_enabled(m_client, Config::Get(Config::RA_SPECTATOR_ENABLED));
rc_client_set_read_memory_function(m_client, MemoryVerifier);
if (volume)
{
std::lock_guard lg{m_lock};
@ -679,13 +682,14 @@ void AchievementManager::LoadGameCallback(int result, const char* error_message,
}
INFO_LOG_FMT(ACHIEVEMENTS, "Loaded data for game ID {}.", game->id);
AchievementManager::GetInstance().m_display_welcome_message = true;
AchievementManager::GetInstance().FetchGameBadges();
AchievementManager::GetInstance().m_system = &Core::System::GetInstance();
AchievementManager::GetInstance().m_update_callback({.all = true});
auto& instance = AchievementManager::GetInstance();
rc_client_set_read_memory_function(instance.m_client, MemoryPeeker);
instance.m_display_welcome_message = true;
instance.FetchGameBadges();
instance.m_system = &Core::System::GetInstance();
instance.m_update_callback({.all = true});
// Set this to a value that will immediately trigger RP
AchievementManager::GetInstance().m_last_rp_time =
std::chrono::steady_clock::now() - std::chrono::minutes{2};
instance.m_last_rp_time = std::chrono::steady_clock::now() - std::chrono::minutes{2};
}
void AchievementManager::ChangeMediaCallback(int result, const char* error_message,
@ -706,6 +710,7 @@ void AchievementManager::ChangeMediaCallback(int result, const char* error_messa
ERROR_LOG_FMT(ACHIEVEMENTS, "RetroAchievements media change failed: {}", error_message);
}
rc_client_set_read_memory_function(AchievementManager::GetInstance().m_client, MemoryPeeker);
}
void AchievementManager::DisplayWelcomeMessage()
@ -914,11 +919,36 @@ void AchievementManager::Request(const rc_api_request_t* request,
});
}
// Currently, when rc_client calls the memory peek method provided in its constructor (or in
// rc_client_set_read_memory_function) it will do so on the thread that calls DoFrame, which is
// currently the host thread, with one exception: an asynchronous callback in the load game process.
// This is done to validate/invalidate each memory reference in the downloaded assets, mark assets
// as unsupported, and notify the player upon startup that there are unsupported assets and how
// many. As such, all that call needs to do is return the number of bytes that can be read with this
// call. As only the CPU and host threads are allowed to read from memory, I provide a separate
// method for this verification. In lieu of a more convenient set of steps, I provide MemoryVerifier
// to rc_client at construction, and in the Load Game callback, after the verification has been
// complete, I call rc_client_set_read_memory_function to switch to the usual MemoryPeeker for all
// future synchronous calls.
u32 AchievementManager::MemoryVerifier(u32 address, u8* buffer, u32 num_bytes, rc_client_t* client)
{
auto& system = Core::System::GetInstance();
u32 ram_size = system.GetMemory().GetRamSizeReal();
if (address >= ram_size)
return 0;
return std::min(ram_size - address, num_bytes);
}
u32 AchievementManager::MemoryPeeker(u32 address, u8* buffer, u32 num_bytes, rc_client_t* client)
{
if (buffer == nullptr)
return 0u;
auto& system = Core::System::GetInstance();
if (!(Core::IsHostThread() || Core::IsCPUThread()))
{
ASSERT_MSG(ACHIEVEMENTS, false, "MemoryPeeker called from wrong thread");
return 0;
}
Core::CPUThreadGuard threadguard(system);
for (u32 num_read = 0; num_read < num_bytes; num_read++)
{

View File

@ -177,6 +177,7 @@ private:
static void Request(const rc_api_request_t* request, rc_client_server_callback_t callback,
void* callback_data, rc_client_t* client);
static u32 MemoryVerifier(u32 address, u8* buffer, u32 num_bytes, rc_client_t* client);
static u32 MemoryPeeker(u32 address, u8* buffer, u32 num_bytes, rc_client_t* client);
void FetchBadge(Badge* badge, u32 badge_type, const BadgeNameFunction function,
const UpdatedItems callback_data);

View File

@ -92,7 +92,33 @@ inline double Force25Bit(double d)
{
u64 integral = std::bit_cast<u64>(d);
integral = (integral & 0xFFFFFFFFF8000000ULL) + (integral & 0x8000000);
u64 exponent = integral & Common::DOUBLE_EXP;
u64 fraction = integral & Common::DOUBLE_FRAC;
if (exponent == 0 && fraction != 0)
{
// Subnormals get "normalized" before they're rounded
// In the end, this practically just means that the rounding is
// at a different bit
s64 keep_mask = 0xFFFFFFFFF8000000LL;
u64 round = 0x8000000;
// Shift the mask and rounding bit to the right until
// the fraction is "normal"
// That is to say shifting it until the MSB of the fraction
// would escape into the exponent
u32 shift = std::countl_zero(fraction) - (63 - Common::DOUBLE_FRAC_WIDTH);
keep_mask >>= shift;
round >>= shift;
// Round using these shifted values
integral = (integral & keep_mask) + (integral & round);
}
else
{
integral = (integral & 0xFFFFFFFFF8000000ULL) + (integral & 0x8000000);
}
return std::bit_cast<double>(integral);
}

View File

@ -89,7 +89,7 @@ AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent)
// in your translation, please use the type of curly quotes that's appropriate for
// your language. If you aren't sure which type is appropriate, see
// https://en.wikipedia.org/wiki/Quotation_mark#Specific_language_features
tr("\u00A9 2003-2015+ Dolphin Team. \u201cGameCube\u201d and \u201cWii\u201d are "
tr("\u00A9 2003-2024+ Dolphin Team. \u201cGameCube\u201d and \u201cWii\u201d are "
"trademarks of Nintendo. Dolphin is not affiliated with Nintendo in any way.")));
QLabel* logo = new QLabel();

View File

@ -4,10 +4,12 @@
#ifdef USE_RETRO_ACHIEVEMENTS
#include "DolphinQt/Achievements/AchievementBox.h"
#include <QByteArray>
#include <QDateTime>
#include <QHBoxLayout>
#include <QLabel>
#include <QProgressBar>
#include <QSizePolicy>
#include <QVBoxLayout>
#include <QWidget>
@ -30,9 +32,11 @@ AchievementBox::AchievementBox(QWidget* parent, rc_client_achievement_t* achieve
m_badge = new QLabel();
QLabel* title = new QLabel(QString::fromUtf8(achievement->title, strlen(achievement->title)));
title->setWordWrap(true);
title->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
QLabel* description =
new QLabel(QString::fromUtf8(achievement->description, strlen(achievement->description)));
description->setWordWrap(true);
description->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
QLabel* points = new QLabel(tr("%1 points").arg(achievement->points));
m_status = new QLabel();
m_progress_bar = new QProgressBar();
@ -93,7 +97,9 @@ void AchievementBox::UpdateData()
m_progress_bar->setRange(0, 100);
m_progress_bar->setValue(m_achievement->measured_percent);
m_progress_bar->setTextVisible(false);
m_progress_label->setText(QString::fromUtf8(m_achievement->measured_progress, PROGRESS_LENGTH));
m_progress_label->setText(
QString::fromUtf8(m_achievement->measured_progress,
qstrnlen(m_achievement->measured_progress, PROGRESS_LENGTH)));
m_progress_bar->setVisible(true);
}
else

View File

@ -57,8 +57,10 @@ void AchievementLeaderboardWidget::UpdateData(bool clean_all)
m_leaderboard_order[leaderboard->id] = row;
QLabel* a_title = new QLabel(QString::fromUtf8(leaderboard->title));
a_title->setWordWrap(true);
a_title->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
QLabel* a_description = new QLabel(QString::fromUtf8(leaderboard->description));
a_description->setWordWrap(true);
a_description->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
QVBoxLayout* a_col_left = new QVBoxLayout();
a_col_left->addWidget(a_title);
a_col_left->addWidget(a_description);

View File

@ -236,7 +236,10 @@ void AchievementSettingsWidget::ToggleRAIntegration()
else
instance.Shutdown();
if (Config::Get(Config::RA_HARDCORE_ENABLED))
{
emit Settings::Instance().EmulationStateChanged(Core::GetState(Core::System::GetInstance()));
emit Settings::Instance().HardcoreStateChanged();
}
}
void AchievementSettingsWidget::Login()
@ -266,6 +269,7 @@ void AchievementSettingsWidget::ToggleHardcore()
Settings::Instance().SetDebugModeEnabled(false);
}
emit Settings::Instance().EmulationStateChanged(Core::GetState(Core::System::GetInstance()));
emit Settings::Instance().HardcoreStateChanged();
}
void AchievementSettingsWidget::ToggleUnofficial()

View File

@ -34,6 +34,8 @@ AchievementsWindow::AchievementsWindow(QWidget* parent) : QDialog(parent)
});
});
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
[this] { m_settings_widget->UpdateData(); });
connect(&Settings::Instance(), &Settings::HardcoreStateChanged, this,
[this] { AchievementsWindow::UpdateData({.all = true}); });
}

View File

@ -59,8 +59,6 @@
#include "InputCommon/ControllerInterface/CoreDevice.h"
#include "InputCommon/InputConfig.h"
constexpr const char* PROFILES_DIR = "Profiles/";
MappingWindow::MappingWindow(QWidget* parent, Type type, int port_num)
: QDialog(parent), m_port(port_num)
{

View File

@ -299,16 +299,14 @@ void GameList::MakeEmptyView()
size_policy.setRetainSizeWhenHidden(true);
m_empty->setSizePolicy(size_policy);
connect(&Settings::Instance(), &Settings::GameListRefreshRequested, this,
[this, refreshing_msg = refreshing_msg] {
m_empty->setText(refreshing_msg);
m_empty->setEnabled(false);
});
connect(&Settings::Instance(), &Settings::GameListRefreshCompleted, this,
[this, empty_msg = empty_msg] {
m_empty->setText(empty_msg);
m_empty->setEnabled(true);
});
connect(&Settings::Instance(), &Settings::GameListRefreshRequested, this, [this, refreshing_msg] {
m_empty->setText(refreshing_msg);
m_empty->setEnabled(false);
});
connect(&Settings::Instance(), &Settings::GameListRefreshCompleted, this, [this, empty_msg] {
m_empty->setText(empty_msg);
m_empty->setEnabled(true);
});
}
void GameList::resizeEvent(QResizeEvent* event)

View File

@ -354,11 +354,6 @@ void Settings::NotifyRefreshGameListComplete()
emit GameListRefreshCompleted();
}
void Settings::RefreshMetadata()
{
emit MetadataRefreshRequested();
}
void Settings::NotifyMetadataRefreshComplete()
{
emit MetadataRefreshCompleted();

View File

@ -104,7 +104,6 @@ public:
void RefreshGameList();
void NotifyRefreshGameListStarted();
void NotifyRefreshGameListComplete();
void RefreshMetadata();
void NotifyMetadataRefreshComplete();
void ReloadTitleDB();
bool IsAutoRefreshEnabled() const;
@ -224,6 +223,7 @@ signals:
void SDCardInsertionChanged(bool inserted);
void USBKeyboardConnectionChanged(bool connected);
void EnableGfxModsChanged(bool enabled);
void HardcoreStateChanged();
private:
Settings();

View File

@ -100,7 +100,7 @@ void AdvancedPane::CreateLayout()
clock_override_layout->addLayout(cpu_clock_override_slider_layout);
m_cpu_clock_override_slider = new QSlider(Qt::Horizontal);
m_cpu_clock_override_slider->setRange(0, 150);
m_cpu_clock_override_slider->setRange(1, 400);
cpu_clock_override_slider_layout->addWidget(m_cpu_clock_override_slider);
m_cpu_clock_override_slider_label = new QLabel();
@ -203,8 +203,7 @@ void AdvancedPane::ConnectLayout()
});
connect(m_cpu_clock_override_slider, &QSlider::valueChanged, [this](int oc_factor) {
// Vaguely exponential scaling?
const float factor = std::exp2f((m_cpu_clock_override_slider->value() - 100.f) / 25.f);
const float factor = m_cpu_clock_override_slider->value() / 100.f;
Config::SetBaseOrCurrent(Config::MAIN_OVERCLOCK, factor);
Update();
});
@ -271,8 +270,8 @@ void AdvancedPane::Update()
{
const QSignalBlocker blocker(m_cpu_clock_override_slider);
m_cpu_clock_override_slider->setValue(static_cast<int>(
std::round(std::log2f(Config::Get(Config::MAIN_OVERCLOCK)) * 25.f + 100.f)));
m_cpu_clock_override_slider->setValue(
static_cast<int>(std::round(Config::Get(Config::MAIN_OVERCLOCK) * 100.f)));
}
m_cpu_clock_override_slider_label->setText([] {

View File

@ -194,7 +194,7 @@ void GeneralPane::CreateAutoUpdate()
auto_update_group_layout->addRow(tr("&Auto Update:"), m_combobox_update_track);
for (const QString& option :
{tr("Don't Update"), tr("Beta (once a month)"), tr("Dev (multiple times a day)")})
{tr("Don't Update"), tr("Releases (every few months)"), tr("Dev (multiple times a day)")})
m_combobox_update_track->addItem(option);
}

View File

@ -235,15 +235,15 @@ void InterfacePane::ConnectLayout()
connect(m_checkbox_use_builtin_title_database, &QCheckBox::toggled, &Settings::Instance(),
&Settings::GameListRefreshRequested);
connect(m_checkbox_use_covers, &QCheckBox::toggled, &Settings::Instance(),
&Settings::RefreshMetadata);
&Settings::MetadataRefreshRequested);
connect(m_checkbox_show_debugging_ui, &QCheckBox::toggled, &Settings::Instance(),
&Settings::SetDebugModeEnabled);
connect(m_combobox_theme, &QComboBox::currentIndexChanged, this,
[this](int index) { Settings::Instance().TriggerThemeChanged(); });
connect(m_combobox_theme, &QComboBox::currentIndexChanged, &Settings::Instance(),
&Settings::ThemeChanged);
connect(m_combobox_userstyle, &QComboBox::currentIndexChanged, this,
&InterfacePane::OnUserStyleChanged);
connect(m_combobox_language, &QComboBox::currentIndexChanged, this,
[this]() { OnLanguageChanged(); });
&InterfacePane::OnLanguageChanged);
connect(m_checkbox_top_window, &QCheckBox::toggled, &Settings::Instance(),
&Settings::KeepWindowOnTopChanged);
connect(m_radio_cursor_visible_movement, &ConfigRadioInt::OnSelected, &Settings::Instance(),
@ -253,7 +253,7 @@ void InterfacePane::ConnectLayout()
connect(m_radio_cursor_visible_always, &ConfigRadioInt::OnSelected, &Settings::Instance(),
&Settings::CursorVisibilityChanged);
connect(m_checkbox_lock_mouse, &QCheckBox::toggled, &Settings::Instance(),
[this]() { Settings::Instance().LockCursorChanged(); });
&Settings::LockCursorChanged);
}
void InterfacePane::UpdateShowDebuggingCheckbox()