Skip to content

Commit f5619f0

Browse files
authored
Merge branch 'shadps4-emu:main' into main
2 parents 9c6be07 + 9634487 commit f5619f0

File tree

13 files changed

+181
-43
lines changed

13 files changed

+181
-43
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ PAD DOWN | DOWN |
102102
PAD LEFT | LEFT |
103103
PAD RIGHT | RIGHT |
104104
OPTIONS | RETURN |
105-
TOUCH PAD | SPACE |
105+
BACK BUTTON / TOUCH PAD | SPACE |
106106
L1 | Q |
107107
R1 | U |
108108
L2 | E |

src/common/config.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ static std::string logFilter;
4141
static std::string logType = "async";
4242
static std::string userName = "shadPS4";
4343
static std::string updateChannel;
44+
static std::string backButtonBehavior = "left";
4445
static bool useSpecialPad = false;
4546
static int specialPadClass = 1;
4647
static bool isDebugDump = false;
@@ -123,6 +124,10 @@ std::string getUpdateChannel() {
123124
return updateChannel;
124125
}
125126

127+
std::string getBackButtonBehavior() {
128+
return backButtonBehavior;
129+
}
130+
126131
bool getUseSpecialPad() {
127132
return useSpecialPad;
128133
}
@@ -275,6 +280,10 @@ void setUpdateChannel(const std::string& type) {
275280
updateChannel = type;
276281
}
277282

283+
void setBackButtonBehavior(const std::string& type) {
284+
backButtonBehavior = type;
285+
}
286+
278287
void setUseSpecialPad(bool use) {
279288
useSpecialPad = use;
280289
}
@@ -435,6 +444,7 @@ void load(const std::filesystem::path& path) {
435444
}
436445
isShowSplash = toml::find_or<bool>(general, "showSplash", true);
437446
isAutoUpdate = toml::find_or<bool>(general, "autoUpdate", false);
447+
backButtonBehavior = toml::find_or<std::string>(general, "backButtonBehavior", "left");
438448
}
439449

440450
if (data.contains("Input")) {
@@ -533,6 +543,7 @@ void save(const std::filesystem::path& path) {
533543
data["General"]["updateChannel"] = updateChannel;
534544
data["General"]["showSplash"] = isShowSplash;
535545
data["General"]["autoUpdate"] = isAutoUpdate;
546+
data["General"]["backButtonBehavior"] = backButtonBehavior;
536547
data["Input"]["useSpecialPad"] = useSpecialPad;
537548
data["Input"]["specialPadClass"] = specialPadClass;
538549
data["GPU"]["screenWidth"] = screenWidth;
@@ -591,6 +602,7 @@ void setDefaultValues() {
591602
} else {
592603
updateChannel = "Nightly";
593604
}
605+
backButtonBehavior = "left";
594606
useSpecialPad = false;
595607
specialPadClass = 1;
596608
isDebugDump = false;

src/common/config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ std::string getLogFilter();
2020
std::string getLogType();
2121
std::string getUserName();
2222
std::string getUpdateChannel();
23+
std::string getBackButtonBehavior();
2324

2425
bool getUseSpecialPad();
2526
int getSpecialPadClass();
@@ -54,6 +55,7 @@ void setLanguage(u32 language);
5455
void setNeoMode(bool enable);
5556
void setUserName(const std::string& type);
5657
void setUpdateChannel(const std::string& type);
58+
void setBackButtonBehavior(const std::string& type);
5759

5860
void setUseSpecialPad(bool use);
5961
void setSpecialPadClass(int type);

src/core/file_format/psf.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,12 @@ void PSF::AddBinary(std::string key, std::vector<u8> value, bool update) {
227227
map_binaries.emplace(entry_list.size() - 1, std::move(value));
228228
}
229229

230+
void PSF::AddBinary(std::string key, uint64_t value, bool update) {
231+
std::vector<u8> data(8);
232+
std::memcpy(data.data(), &value, 8);
233+
return AddBinary(std::move(key), std::move(data), update);
234+
}
235+
230236
void PSF::AddString(std::string key, std::string value, bool update) {
231237
auto [it, index] = FindEntry(key);
232238
bool exist = it != entry_list.end();

src/core/file_format/psf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class PSF {
6767
std::optional<s32> GetInteger(std::string_view key) const;
6868

6969
void AddBinary(std::string key, std::vector<u8> value, bool update = false);
70+
void AddBinary(std::string key, uint64_t value, bool update = false); // rsv4 format
7071
void AddString(std::string key, std::string value, bool update = false);
7172
void AddInteger(std::string key, s32 value, bool update = false);
7273

src/core/libraries/save_data/save_instance.cpp

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
#include "core/file_sys/fs.h"
1313
#include "save_instance.h"
1414

15-
constexpr u32 OrbisSaveDataBlocksMax = 32768; // 1 GiB
15+
constexpr auto OrbisSaveDataBlocksMin2 = 96; // 3MiB
16+
constexpr auto OrbisSaveDataBlocksMax = 32768; // 1 GiB
1617
constexpr std::string_view sce_sys = "sce_sys"; // system folder inside save
17-
constexpr std::string_view max_block_file_name = "max_block.txt";
1818

1919
static Core::FileSys::MntPoints* g_mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
2020

@@ -58,18 +58,13 @@ std::filesystem::path SaveInstance::MakeDirSavePath(OrbisUserServiceUserId user_
5858
game_serial / dir_name;
5959
}
6060

61-
int SaveInstance::GetMaxBlocks(const std::filesystem::path& save_path) {
62-
Common::FS::IOFile max_blocks_file{save_path / sce_sys / max_block_file_name,
63-
Common::FS::FileAccessMode::Read};
64-
int max_blocks = 0;
65-
if (max_blocks_file.IsOpen()) {
66-
max_blocks = std::atoi(max_blocks_file.ReadString(16).c_str());
61+
uint64_t SaveInstance::GetMaxBlockFromSFO(const PSF& psf) {
62+
const auto vec = psf.GetBinary(std::string{SaveParams::SAVEDATA_BLOCKS});
63+
if (!vec.has_value()) {
64+
return OrbisSaveDataBlocksMax;
6765
}
68-
if (max_blocks <= 0) {
69-
max_blocks = OrbisSaveDataBlocksMax;
70-
}
71-
72-
return max_blocks;
66+
auto value = vec.value();
67+
return *(uint64_t*)value.data();
7368
}
7469

7570
std::filesystem::path SaveInstance::GetParamSFOPath(const std::filesystem::path& dir_path) {
@@ -92,13 +87,15 @@ void SaveInstance::SetupDefaultParamSFO(PSF& param_sfo, std::string dir_name,
9287
P(String, SaveParams::SAVEDATA_DIRECTORY, std::move(dir_name));
9388
P(Integer, SaveParams::SAVEDATA_LIST_PARAM, 0);
9489
P(String, SaveParams::TITLE_ID, std::move(game_serial));
90+
P(Binary, SaveParams::SAVEDATA_BLOCKS, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
9591
#undef P
9692
}
9793

9894
SaveInstance::SaveInstance(int slot_num, OrbisUserServiceUserId user_id, std::string _game_serial,
9995
std::string_view _dir_name, int max_blocks)
10096
: slot_num(slot_num), user_id(user_id), game_serial(std::move(_game_serial)),
101-
dir_name(_dir_name), max_blocks(max_blocks) {
97+
dir_name(_dir_name),
98+
max_blocks(std::clamp(max_blocks, OrbisSaveDataBlocksMin2, OrbisSaveDataBlocksMax)) {
10299
ASSERT(slot_num >= 0 && slot_num < 16);
103100

104101
save_path = MakeDirSavePath(user_id, game_serial, dir_name);
@@ -187,7 +184,7 @@ void SaveInstance::SetupAndMount(bool read_only, bool copy_icon, bool ignore_cor
187184
}
188185
}
189186

190-
max_blocks = GetMaxBlocks(save_path);
187+
max_blocks = static_cast<int>(GetMaxBlockFromSFO(param_sfo));
191188

192189
g_mnt->Mount(save_path, mount_point, read_only);
193190
mounted = true;
@@ -217,16 +214,13 @@ void SaveInstance::CreateFiles() {
217214
fs::create_directories(sce_sys_dir);
218215

219216
SetupDefaultParamSFO(param_sfo, dir_name, game_serial);
217+
param_sfo.AddBinary(std::string{SaveParams::SAVEDATA_BLOCKS}, max_blocks, true);
220218

221219
const bool ok = param_sfo.Encode(param_sfo_path);
222220
if (!ok) {
223221
throw std::filesystem::filesystem_error("Failed to write param.sfo", param_sfo_path,
224222
std::make_error_code(std::errc::permission_denied));
225223
}
226-
227-
Common::FS::IOFile max_block{sce_sys_dir / max_block_file_name,
228-
Common::FS::FileAccessMode::Write};
229-
max_block.WriteString(std::to_string(max_blocks == 0 ? OrbisSaveDataBlocksMax : max_blocks));
230224
}
231225

232226
} // namespace Libraries::SaveData

src/core/libraries/save_data/save_instance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class SaveInstance {
6262
std::string_view game_serial,
6363
std::string_view dir_name);
6464

65-
static int GetMaxBlocks(const std::filesystem::path& save_path);
65+
static uint64_t GetMaxBlockFromSFO(const PSF& psf);
6666

6767
// Get param.sfo path from a dir_path generated by MakeDirSavePath
6868
static std::filesystem::path GetParamSFOPath(const std::filesystem::path& dir_path);

src/core/libraries/save_data/savedata.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ static Error saveDataMount(const OrbisSaveDataMount2* mount_info,
445445
fs::create_directories(root_save);
446446
const auto available = fs::space(root_save).available;
447447

448-
auto requested_size = mount_info->blocks * OrbisSaveDataBlockSize;
448+
auto requested_size = save_instance.GetMaxBlocks() * OrbisSaveDataBlockSize;
449449
if (requested_size > available) {
450450
mount_result->required_blocks = (requested_size - available) / OrbisSaveDataBlockSize;
451451
return Error::NO_SPACE_FS;
@@ -830,10 +830,11 @@ Error PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond
830830
LOG_ERROR(Lib_SaveData, "Failed to read SFO: {}", fmt::UTF(sfo_path.u8string()));
831831
ASSERT_MSG(false, "Failed to read SFO");
832832
}
833-
map_dir_sfo.emplace(dir_name, std::move(sfo));
834833

835834
size_t size = Common::FS::GetDirectorySize(dir_path);
836-
size_t total = SaveInstance::GetMaxBlocks(dir_path);
835+
size_t total = SaveInstance::GetMaxBlockFromSFO(sfo);
836+
837+
map_dir_sfo.emplace(dir_name, std::move(sfo));
837838
map_free_size.emplace(dir_name, total - size / OrbisSaveDataBlockSize);
838839
map_max_blocks.emplace(dir_name, total);
839840
}

src/qt_gui/check_update.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,17 @@ void CheckUpdate::Install() {
374374
QString userPath;
375375
Common::FS::PathToQString(userPath, Common::FS::GetUserPath(Common::FS::PathType::UserDir));
376376

377-
QString startingUpdate = tr("Starting Update...");
378-
QString tempDirPath = userPath + "/temp_download_update";
379377
QString rootPath;
380378
Common::FS::PathToQString(rootPath, std::filesystem::current_path());
381379

380+
QString tempDirPath = userPath + "/temp_download_update";
381+
QString startingUpdate = tr("Starting Update...");
382+
383+
QString binaryStartingUpdate;
384+
for (QChar c : startingUpdate) {
385+
binaryStartingUpdate.append(QString::number(c.unicode(), 2).rightJustified(16, '0'));
386+
}
387+
382388
QString scriptContent;
383389
QString scriptFileName;
384390
QStringList arguments;
@@ -389,7 +395,13 @@ void CheckUpdate::Install() {
389395
scriptFileName = tempDirPath + "/update.ps1";
390396
scriptContent = QStringLiteral(
391397
"Set-ExecutionPolicy Bypass -Scope Process -Force\n"
392-
"Write-Output '%1'\n"
398+
"$binaryStartingUpdate = '%1'\n"
399+
"$chars = @()\n"
400+
"for ($i = 0; $i -lt $binaryStartingUpdate.Length; $i += 16) {\n"
401+
" $chars += [char]([convert]::ToInt32($binaryStartingUpdate.Substring($i, 16), 2))\n"
402+
"}\n"
403+
"$startingUpdate = -join $chars\n"
404+
"Write-Output $startingUpdate\n"
393405
"Expand-Archive -Path '%2\\temp_download_update.zip' -DestinationPath '%2' -Force\n"
394406
"Start-Sleep -Seconds 3\n"
395407
"Copy-Item -Recurse -Force '%2\\*' '%3\\'\n"
@@ -512,7 +524,12 @@ void CheckUpdate::Install() {
512524
QFile scriptFile(scriptFileName);
513525
if (scriptFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
514526
QTextStream out(&scriptFile);
527+
#ifdef Q_OS_WIN
528+
out << scriptContent.arg(binaryStartingUpdate).arg(tempDirPath).arg(rootPath);
529+
#endif
530+
#if defined(Q_OS_LINUX) || defined(Q_OS_MAC)
515531
out << scriptContent.arg(startingUpdate).arg(tempDirPath).arg(rootPath);
532+
#endif
516533
scriptFile.close();
517534

518535
// Make the script executable on Unix-like systems

src/qt_gui/settings_dialog.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
9898
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Restore Defaults"));
9999
ui->buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close"));
100100

101+
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Left"), "left");
102+
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Center"), "center");
103+
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Right"), "right");
104+
ui->backButtonBehaviorComboBox->addItem(tr("None"), "none");
105+
106+
QString currentBackButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior());
107+
int index = ui->backButtonBehaviorComboBox->findData(currentBackButtonBehavior);
108+
ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0);
109+
101110
connect(ui->tabWidgetSettings, &QTabWidget::currentChanged, this,
102111
[this]() { ui->buttonBox->button(QDialogButtonBox::Close)->setFocus(); });
103112

@@ -151,6 +160,14 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
151160
Config::setBGMvolume(val);
152161
BackgroundMusicPlayer::getInstance().setVolume(val);
153162
});
163+
164+
connect(ui->backButtonBehaviorComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
165+
this, [this](int index) {
166+
if (index >= 0 && index < ui->backButtonBehaviorComboBox->count()) {
167+
QString data = ui->backButtonBehaviorComboBox->itemData(index).toString();
168+
Config::setBackButtonBehavior(data.toStdString());
169+
}
170+
});
154171
}
155172

156173
// GPU TAB
@@ -204,6 +221,7 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
204221
ui->logFilter->installEventFilter(this);
205222
ui->updaterGroupBox->installEventFilter(this);
206223
ui->GUIgroupBox->installEventFilter(this);
224+
ui->backButtonBehaviorGroupBox->installEventFilter(this);
207225

208226
// Graphics
209227
ui->graphicsAdapterGroupBox->installEventFilter(this);
@@ -258,6 +276,10 @@ void SettingsDialog::LoadValuesFromConfig() {
258276
}
259277
}
260278
ui->updateComboBox->setCurrentText(QString::fromStdString(updateChannel));
279+
280+
QString backButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior());
281+
int index = ui->backButtonBehaviorComboBox->findData(backButtonBehavior);
282+
ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0);
261283
}
262284

263285
void SettingsDialog::InitializeEmulatorLanguages() {
@@ -319,6 +341,8 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
319341
text = tr("updaterGroupBox");
320342
} else if (elementName == "GUIgroupBox") {
321343
text = tr("GUIgroupBox");
344+
} else if (elementName == "backButtonBehaviorGroupBox") {
345+
text = tr("backButtonBehaviorGroupBox");
322346
}
323347

324348
// Graphics

src/qt_gui/settings_dialog.ui

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -442,20 +442,44 @@
442442
</layout>
443443
</item>
444444
<item>
445-
<spacer name="horizontalSpacer">
446-
<property name="orientation">
447-
<enum>Qt::Orientation::Horizontal</enum>
448-
</property>
449-
<property name="sizeType">
450-
<enum>QSizePolicy::Policy::Expanding</enum>
451-
</property>
452-
<property name="sizeHint" stdset="0">
453-
<size>
454-
<width>0</width>
455-
<height>0</height>
456-
</size>
457-
</property>
458-
</spacer>
445+
<layout class="QVBoxLayout" name="ControllerTabLayoutRight" stretch="1">
446+
<item>
447+
<widget class="QGroupBox" name="ControllerGroupBox">
448+
<property name="sizePolicy">
449+
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
450+
<horstretch>0</horstretch>
451+
<verstretch>0</verstretch>
452+
</sizepolicy>
453+
</property>
454+
<property name="title">
455+
<string>Controller Settings</string>
456+
</property>
457+
<widget class="QGroupBox" name="backButtonBehaviorGroupBox">
458+
<property name="geometry">
459+
<rect>
460+
<x>12</x>
461+
<y>30</y>
462+
<width>241</width>
463+
<height>65</height>
464+
</rect>
465+
</property>
466+
<property name="title">
467+
<string>Back Button Behavior</string>
468+
</property>
469+
<widget class="QComboBox" name="backButtonBehaviorComboBox">
470+
<property name="geometry">
471+
<rect>
472+
<x>12</x>
473+
<y>30</y>
474+
<width>217</width>
475+
<height>28</height>
476+
</rect>
477+
</property>
478+
</widget>
479+
</widget>
480+
</widget>
481+
</item>
482+
</layout>
459483
</item>
460484
</layout>
461485
</item>

0 commit comments

Comments
 (0)