Skip to content

Commit e313840

Browse files
authored
Merge branch 'master' into add_bd_support
2 parents deaf731 + e05d359 commit e313840

17 files changed

Lines changed: 109 additions & 75 deletions

.github/workflows/rpcs3.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ jobs:
235235
fetch-depth: 0
236236

237237
- name: Setup NuGet
238-
uses: nuget/setup-nuget@v2
238+
uses: nuget/setup-nuget@v4
239239

240240
- name: Restore NuGet packages
241241
run: nuget restore rpcs3.sln

3rdparty/7zip/7zip

Submodule 7zip updated 72 files

rpcs3/Emu/Io/usb_device.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@ void usb_device::get_location(u8* location) const
2424
memcpy(location, this->location.data(), 7);
2525
}
2626

27+
const UsbDeviceEndpoint* usb_device::find_endpoint(u8 endpoint_addr) const
28+
{
29+
for (const auto& config_node : device.subnodes)
30+
{
31+
if (config_node.bDescriptorType != USB_DESCRIPTOR_CONFIG)
32+
continue;
33+
34+
for (const auto& node : config_node.subnodes)
35+
{
36+
if (node.bDescriptorType == USB_DESCRIPTOR_ENDPOINT && node._endpoint.bEndpointAddress == endpoint_addr)
37+
return &node._endpoint;
38+
}
39+
}
40+
return nullptr;
41+
}
42+
2743
void usb_device::read_descriptors()
2844
{
2945
}
@@ -88,6 +104,15 @@ void usb_device_passthrough::send_libusb_transfer(libusb_transfer* transfer)
88104
default:
89105
{
90106
sys_usbd.error("Unexpected error from libusb_submit_transfer: %d(%s)", res, libusb_error_name(res));
107+
108+
// Mark as a failed fake transfer so the USB manager processes a completion
109+
// instead of leaving the request stuck in the busy state forever.
110+
UsbTransfer* usbd_transfer = static_cast<UsbTransfer*>(transfer->user_data);
111+
usbd_transfer->busy = true;
112+
usbd_transfer->fake = true;
113+
usbd_transfer->expected_result = EHCI_CC_HALTED;
114+
usbd_transfer->expected_count = 0;
115+
usbd_transfer->expected_time = get_timestamp();
91116
return;
92117
}
93118
}
@@ -163,7 +188,23 @@ void usb_device_passthrough::control_transfer(u8 bmRequestType, u8 bRequest, u16
163188

164189
void usb_device_passthrough::interrupt_transfer(u32 buf_size, u8* buf, u32 endpoint, UsbTransfer* transfer)
165190
{
166-
libusb_fill_interrupt_transfer(transfer->transfer, lusb_handle, endpoint, buf, buf_size, callback_transfer, transfer, 0);
191+
// Pick the libusb helper matching the endpoint's actual transfer type. The PS3 USB
192+
// stack routes both bulk and interrupt transfers through this method, but submitting
193+
// an interrupt URB to a bulk endpoint fails with EINVAL on Linux.
194+
const UsbDeviceEndpoint* ep_desc = find_endpoint(static_cast<u8>(endpoint));
195+
const bool is_bulk = ep_desc && (ep_desc->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK;
196+
197+
sys_usbd.notice("USIO debug: submitting passthrough transfer endpoint=0x%x dir=%s size=0x%x type=%s",
198+
endpoint, (endpoint & LIBUSB_ENDPOINT_IN) ? "IN" : "OUT", buf_size, is_bulk ? "bulk" : "interrupt");
199+
200+
if (is_bulk)
201+
{
202+
libusb_fill_bulk_transfer(transfer->transfer, lusb_handle, endpoint, buf, buf_size, callback_transfer, transfer, 0);
203+
}
204+
else
205+
{
206+
libusb_fill_interrupt_transfer(transfer->transfer, lusb_handle, endpoint, buf, buf_size, callback_transfer, transfer, 0);
207+
}
167208
send_libusb_transfer(transfer->transfer);
168209
}
169210

rpcs3/Emu/Io/usb_device.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ class usb_device
238238
virtual void isochronous_transfer(UsbTransfer* transfer) = 0;
239239

240240
public:
241+
// Look up an endpoint descriptor by address in the descriptor tree
242+
const UsbDeviceEndpoint* find_endpoint(u8 endpoint_addr) const;
243+
241244
// device ID if the device has been ldded(0 otherwise)
242245
u32 assigned_number = 0;
243246
// base device descriptor, every other descriptor is a subnode

rpcs3/main_application.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#include "main_application.h"
33
#include "display_sleep_control.h"
44
#include "gamemode_control.h"
5-
#include "rpcs3qt/gui_settings.h"
65
#include "rpcs3qt/config_database.h"
76

87
#include "util/types.hpp"
@@ -418,8 +417,7 @@ EmuCallbacks main_application::CreateCallbacks()
418417

419418
sys_log.notice("Trying to retrieve database config for: '%s'", title_id);
420419

421-
const auto settings = std::make_shared<gui_settings>();
422-
config_database config_db(settings, nullptr);
420+
config_database config_db(nullptr);
423421
config_db.request_config_database(false);
424422

425423
if (!config_db.has_config(title_id))

rpcs3/rpcs3.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static const bool s_init_locale = []()
8585

8686
static semaphore<> s_qt_init;
8787

88-
static atomic_t<bool> s_headless = false;
88+
atomic_t<bool> g_headless = false;
8989
static atomic_t<bool> s_no_gui = false;
9090
static atomic_t<char*> s_argv0 = nullptr;
9191
static bool s_is_error_launch = false;
@@ -214,7 +214,7 @@ std::set<std::string> get_one_drive_paths()
214214

215215
std::string_view text = s_is_error_launch ? _text : buf;
216216

217-
if (s_headless)
217+
if (g_headless)
218218
{
219219
utils::attach_console(utils::console_stream::std_err, true);
220220

@@ -977,7 +977,7 @@ int run_rpcs3(int argc, char** argv)
977977
}
978978
else if (headless_application* headless_app = qobject_cast<headless_application*>(app.data()))
979979
{
980-
s_headless = true;
980+
g_headless = true;
981981

982982
headless_app->SetActiveUser(active_user);
983983

@@ -1200,7 +1200,7 @@ int run_rpcs3(int argc, char** argv)
12001200
{
12011201
sys_log.error("Booting savestate '%s' failed: reason: %s", path, error);
12021202

1203-
if (s_headless || s_no_gui)
1203+
if (g_headless || s_no_gui)
12041204
{
12051205
report_fatal_error(fmt::format("Booting savestate '%s' failed!\n\nReason: %s", path, error));
12061206
}
@@ -1223,7 +1223,7 @@ int run_rpcs3(int argc, char** argv)
12231223
{
12241224
sys_log.error("Booting rsx capture '%s' failed", path);
12251225

1226-
if (s_headless || s_no_gui)
1226+
if (g_headless || s_no_gui)
12271227
{
12281228
report_fatal_error(fmt::format("Booting rsx capture '%s' failed!", path));
12291229
}
@@ -1332,20 +1332,20 @@ int run_rpcs3(int argc, char** argv)
13321332
{
13331333
sys_log.error("Booting '%s' with cli argument failed: reason: %s", path, error);
13341334

1335-
if (s_headless || s_no_gui)
1335+
if (g_headless || s_no_gui)
13361336
{
13371337
report_fatal_error(fmt::format("Booting '%s' failed!\n\nReason: %s", path, error));
13381338
}
13391339
}
13401340
});
13411341
}
1342-
else if (s_headless || s_no_gui)
1342+
else if (g_headless || s_no_gui)
13431343
{
13441344
// If launched from CMD
13451345
utils::attach_console(utils::console_stream::std_out | utils::console_stream::std_err, false);
13461346

1347-
sys_log.error("Cannot run %s mode without boot target. Terminating...", s_headless ? "headless" : "no-gui");
1348-
fprintf(stderr, "Cannot run %s mode without boot target. Terminating...\n", s_headless ? "headless" : "no-gui");
1347+
sys_log.error("Cannot run %s mode without boot target. Terminating...", g_headless ? "headless" : "no-gui");
1348+
fprintf(stderr, "Cannot run %s mode without boot target. Terminating...\n", g_headless ? "headless" : "no-gui");
13491349

13501350
if (s_no_gui)
13511351
{

rpcs3/rpcs3qt/config_database.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@
66

77
LOG_CHANNEL(gui_log, "GUI");
88

9-
config_database::config_database(std::shared_ptr<gui_settings> settings, QWidget* parent)
9+
config_database::config_database(QWidget* parent)
1010
: QObject(parent)
11-
, m_gui_settings(std::move(settings))
1211
{
13-
m_filepath = m_gui_settings->GetSettingsDir() + "/config_database.dat";
14-
m_downloader = new downloader(parent);
12+
m_filepath = gui_settings::GetSettingsDir() + "config_database.dat";
1513
request_config_database();
1614

17-
connect(m_downloader, &downloader::signal_download_error, this, &config_database::handle_download_error);
18-
connect(m_downloader, &downloader::signal_download_finished, this, &config_database::handle_download_finished);
19-
connect(m_downloader, &downloader::signal_download_canceled, this, &config_database::handle_download_canceled);
15+
if (parent)
16+
{
17+
m_downloader = new downloader(parent);
18+
connect(m_downloader, &downloader::signal_download_error, this, &config_database::handle_download_error);
19+
connect(m_downloader, &downloader::signal_download_finished, this, &config_database::handle_download_finished);
20+
connect(m_downloader, &downloader::signal_download_canceled, this, &config_database::handle_download_canceled);
21+
}
2022
}
2123

2224
config_database::~config_database()
@@ -89,7 +91,7 @@ void config_database::request_config_database(bool online)
8991
const std::string url = "https://api.rpcs3.net/config/?api=v1";
9092
gui_log.notice("Beginning config database download from: %s", url);
9193

92-
m_downloader->start(url, true, true, true, tr("Downloading Config Database"));
94+
ensure(m_downloader)->start(url, true, true, true, tr("Downloading Config Database"));
9395

9496
Q_EMIT download_started();
9597
}

rpcs3/rpcs3qt/config_database.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44
#include <optional>
55

66
class downloader;
7-
class gui_settings;
87

98
class config_database : public QObject
109
{
1110
Q_OBJECT
1211

1312
public:
14-
config_database(std::shared_ptr<gui_settings> settings, QWidget* parent);
13+
config_database(QWidget* parent);
1514
virtual ~config_database();
1615

1716
bool has_config(const std::string& title_id) const;
@@ -35,7 +34,6 @@ private Q_SLOTS:
3534
/** Creates new set from the database. Returns config for the optional serial. */
3635
std::optional<std::string> read_json(const QByteArray& data, bool after_download, const std::string& serial = "");
3736

38-
std::shared_ptr<gui_settings> m_gui_settings;
3937
QString m_filepath;
4038
downloader* m_downloader = nullptr;
4139

rpcs3/rpcs3qt/game_compatibility.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,19 @@
1313

1414
LOG_CHANNEL(compat_log, "Compat");
1515

16-
game_compatibility::game_compatibility(std::shared_ptr<gui_settings> settings, QWidget* parent)
16+
game_compatibility::game_compatibility(QWidget* parent)
1717
: QObject(parent)
18-
, m_gui_settings(std::move(settings))
1918
{
20-
m_filepath = m_gui_settings->GetSettingsDir() + "/compat_database.dat";
21-
m_downloader = new downloader(parent);
19+
m_filepath = gui_settings::GetSettingsDir() + "compat_database.dat";
2220
RequestCompatibility();
2321

24-
connect(m_downloader, &downloader::signal_download_error, this, &game_compatibility::handle_download_error);
25-
connect(m_downloader, &downloader::signal_download_finished, this, &game_compatibility::handle_download_finished);
26-
connect(m_downloader, &downloader::signal_download_canceled, this, &game_compatibility::handle_download_canceled);
22+
if (parent)
23+
{
24+
m_downloader = new downloader(parent);
25+
connect(m_downloader, &downloader::signal_download_error, this, &game_compatibility::handle_download_error);
26+
connect(m_downloader, &downloader::signal_download_finished, this, &game_compatibility::handle_download_finished);
27+
connect(m_downloader, &downloader::signal_download_canceled, this, &game_compatibility::handle_download_canceled);
28+
}
2729
}
2830

2931
void game_compatibility::handle_download_error(const QString& error)
@@ -227,7 +229,7 @@ void game_compatibility::RequestCompatibility(bool online)
227229
const std::string url = "https://rpcs3.net/compatibility?api=v1&export";
228230
compat_log.notice("Beginning compatibility database download from: %s", url);
229231

230-
m_downloader->start(url, true, true, true, tr("Downloading Database"));
232+
ensure(m_downloader)->start(url, true, true, true, tr("Downloading Database"));
231233

232234
// We want to retrieve a new database, therefore refresh game list and indicate that
233235
Q_EMIT DownloadStarted();

rpcs3/rpcs3qt/game_compatibility.h

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <QJsonObject>
88

99
class downloader;
10-
class gui_settings;
1110

1211
namespace compat
1312
{
@@ -120,29 +119,9 @@ class game_compatibility : public QObject
120119
{
121120
Q_OBJECT
122121

123-
private:
124-
const std::map<QString, compat::status> Status_Data =
125-
{
126-
{ "Playable", { 0, "", "#1ebc61", tr("Playable"), tr("Games that can be properly played from start to finish") } },
127-
{ "Ingame", { 1, "", "#f9b32f", tr("Ingame"), tr("Games that either can't be finished, have serious glitches or have insufficient performance") } },
128-
{ "Intro", { 2, "", "#e08a1e", tr("Intro"), tr("Games that display image but don't make it past the menus") } },
129-
{ "Loadable", { 3, "", "#e74c3c", tr("Loadable"), tr("Games that display a black screen with a framerate on the window's title") } },
130-
{ "Nothing", { 4, "", "#455556", tr("Nothing"), tr("Games that don't initialize properly, not loading at all and/or crashing the emulator") } },
131-
{ "NoResult", { 5, "", "", tr("No results found"), tr("There is no entry for this game or application in the compatibility database yet.") } },
132-
{ "NoData", { 6, "", "", tr("Database missing"), tr("Right click here and download the current database.\nMake sure you are connected to the internet.") } },
133-
{ "Download", { 7, "", "", tr("Retrieving..."), tr("Downloading the compatibility database. Please wait...") } }
134-
};
135-
std::shared_ptr<gui_settings> m_gui_settings;
136-
QString m_filepath;
137-
downloader* m_downloader = nullptr;
138-
std::map<std::string, compat::status> m_compat_database;
139-
140-
/** Creates new map from the database */
141-
bool handle_json(const QByteArray& data, bool after_download);
142-
143122
public:
144123
/** Handles reads, writes and downloads for the compatibility database */
145-
game_compatibility(std::shared_ptr<gui_settings> settings, QWidget* parent);
124+
game_compatibility(QWidget* parent);
146125

147126
/** Reads database. If online set to true: Downloads and writes the database to file */
148127
void RequestCompatibility(bool online = false);
@@ -166,4 +145,23 @@ private Q_SLOTS:
166145
void handle_download_error(const QString& error);
167146
void handle_download_finished(const QByteArray& content);
168147
void handle_download_canceled();
148+
149+
private:
150+
/** Creates new map from the database */
151+
bool handle_json(const QByteArray& data, bool after_download);
152+
153+
const std::map<QString, compat::status> Status_Data =
154+
{
155+
{ "Playable", { 0, "", "#1ebc61", tr("Playable"), tr("Games that can be properly played from start to finish") } },
156+
{ "Ingame", { 1, "", "#f9b32f", tr("Ingame"), tr("Games that either can't be finished, have serious glitches or have insufficient performance") } },
157+
{ "Intro", { 2, "", "#e08a1e", tr("Intro"), tr("Games that display image but don't make it past the menus") } },
158+
{ "Loadable", { 3, "", "#e74c3c", tr("Loadable"), tr("Games that display a black screen with a framerate on the window's title") } },
159+
{ "Nothing", { 4, "", "#455556", tr("Nothing"), tr("Games that don't initialize properly, not loading at all and/or crashing the emulator") } },
160+
{ "NoResult", { 5, "", "", tr("No results found"), tr("There is no entry for this game or application in the compatibility database yet.") } },
161+
{ "NoData", { 6, "", "", tr("Database missing"), tr("Right click here and download the current database.\nMake sure you are connected to the internet.") } },
162+
{ "Download", { 7, "", "", tr("Retrieving..."), tr("Downloading the compatibility database. Please wait...") } }
163+
};
164+
QString m_filepath;
165+
downloader* m_downloader = nullptr;
166+
std::map<std::string, compat::status> m_compat_database;
169167
};

0 commit comments

Comments
 (0)