Skip to content

Commit 2e6f5f7

Browse files
committed
Qt: play SND0.AT3 in game lists when a movie would play
1 parent 6532044 commit 2e6f5f7

9 files changed

Lines changed: 139 additions & 7 deletions

rpcs3/Emu/GameInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct GameInfo
88
std::string path;
99
std::string icon_path;
1010
std::string movie_path;
11+
std::string audio_path;
1112

1213
std::string name;
1314
std::string serial;

rpcs3/rpcs3qt/game_list_frame.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,12 @@ void game_list_frame::OnParsingFinished()
637637
game.has_hover_pam = true;
638638
}
639639

640+
if (std::string audio_path = sfo_dir + "/SND0.AT3"; file_exists(audio_path))
641+
{
642+
game.info.audio_path = std::move(audio_path);
643+
game.has_audio_file = true;
644+
}
645+
640646
const QString serial = QString::fromStdString(game.info.serial);
641647

642648
m_games_mutex.lock();

rpcs3/rpcs3qt/game_list_grid.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,23 @@ void game_list_grid::populate(
109109
}
110110
});
111111

112-
if (play_hover_movies && (game->has_hover_gif || game->has_hover_pam))
112+
if (play_hover_movies && (game->has_hover_gif || game->has_hover_pam || game->has_audio_file))
113113
{
114-
item->set_video_path(game->info.movie_path);
114+
bool check_iso = false;
115115

116-
if (!fs::exists(game->info.movie_path) && is_file_iso(game->info.path))
116+
if (game->has_hover_gif || game->has_hover_pam)
117+
{
118+
item->set_video_path(game->info.movie_path);
119+
check_iso |= !fs::exists(game->info.movie_path);
120+
}
121+
122+
if (game->has_audio_file)
123+
{
124+
item->set_audio_path(game->info.audio_path);
125+
check_iso |= !fs::exists(game->info.audio_path);
126+
}
127+
128+
if (check_iso && is_file_iso(game->info.path))
117129
{
118130
item->set_iso_path(game->info.path);
119131
}

rpcs3/rpcs3qt/game_list_table.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,11 +299,23 @@ void game_list_table::populate(
299299
}
300300
});
301301

302-
if (play_hover_movies && (game->has_hover_gif || game->has_hover_pam))
302+
if (play_hover_movies && (game->has_hover_gif || game->has_hover_pam || game->has_audio_file))
303303
{
304-
icon_item->set_video_path(game->info.movie_path);
304+
bool check_iso = false;
305305

306-
if (!fs::exists(game->info.movie_path) && is_file_iso(game->info.path))
306+
if (game->has_hover_gif || game->has_hover_pam)
307+
{
308+
icon_item->set_video_path(game->info.movie_path);
309+
check_iso |= !fs::exists(game->info.movie_path);
310+
}
311+
312+
if (game->has_audio_file)
313+
{
314+
icon_item->set_audio_path(game->info.audio_path);
315+
check_iso |= !fs::exists(game->info.audio_path);
316+
}
317+
318+
if (check_iso && is_file_iso(game->info.path))
307319
{
308320
icon_item->set_iso_path(game->info.path);
309321
}

rpcs3/rpcs3qt/gui_game_info.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct gui_game_info
2121
bool has_custom_icon = false;
2222
bool has_hover_gif = false;
2323
bool has_hover_pam = false;
24+
bool has_audio_file = false;
2425
bool icon_in_archive = false;
2526
movie_item_base* item = nullptr;
2627

rpcs3/rpcs3qt/qt_video_source.cpp

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
#include "stdafx.h"
22
#include "Emu/System.h"
3+
#include "Emu/system_config.h"
34
#include "qt_video_source.h"
45

56
#include "Loader/ISO.h"
67

8+
#include <QAudioOutput>
79
#include <QFile>
810

11+
static video_source* s_audio_source = nullptr;
12+
static std::unique_ptr<QMediaPlayer> s_audio_player = nullptr;
13+
static std::unique_ptr<QAudioOutput> s_audio_output = nullptr;
14+
static std::unique_ptr<QBuffer> s_audio_buffer = nullptr;
15+
static std::unique_ptr<QByteArray> s_audio_data = nullptr;
16+
917
qt_video_source::qt_video_source()
1018
: video_source()
1119
{
@@ -21,6 +29,11 @@ void qt_video_source::set_video_path(const std::string& video_path)
2129
m_video_path = QString::fromStdString(video_path);
2230
}
2331

32+
void qt_video_source::set_audio_path(const std::string& audio_path)
33+
{
34+
m_audio_path = QString::fromStdString(audio_path);
35+
}
36+
2437
void qt_video_source::set_iso_path(const std::string& iso_path)
2538
{
2639
m_iso_path = iso_path;
@@ -89,7 +102,6 @@ void qt_video_source::init_movie()
89102
m_video_buffer = std::make_unique<QBuffer>(&m_video_data);
90103
m_video_buffer->open(QIODevice::ReadOnly);
91104
m_movie = std::make_unique<QMovie>(m_video_buffer.get());
92-
93105
}
94106

95107
if (!m_movie->isValid())
@@ -179,6 +191,8 @@ void qt_video_source::start_movie()
179191
m_media_player->play();
180192
}
181193

194+
start_audio();
195+
182196
m_active = true;
183197
}
184198

@@ -196,6 +210,71 @@ void qt_video_source::stop_movie()
196210
m_media_player.reset();
197211
m_video_buffer.reset();
198212
m_video_data.clear();
213+
214+
stop_audio();
215+
}
216+
217+
void qt_video_source::start_audio()
218+
{
219+
if (m_audio_path.isEmpty() || s_audio_source == this) return;
220+
221+
if (!s_audio_player)
222+
{
223+
s_audio_output = std::make_unique<QAudioOutput>();
224+
s_audio_player = std::make_unique<QMediaPlayer>();
225+
s_audio_player->setAudioOutput(s_audio_output.get());
226+
}
227+
228+
if (m_iso_path.empty())
229+
{
230+
s_audio_player->setSource(QUrl::fromLocalFile(m_audio_path));
231+
}
232+
else
233+
{
234+
iso_archive archive(m_iso_path);
235+
auto audio_file = archive.open(m_audio_path.toStdString());
236+
const auto audio_size = audio_file.size();
237+
if (audio_size == 0) return;
238+
239+
auto old_audio_data = std::move(s_audio_data);
240+
s_audio_data = std::make_unique<QByteArray>(audio_size, 0);
241+
audio_file.read(s_audio_data->data(), audio_size);
242+
243+
if (!s_audio_buffer)
244+
{
245+
s_audio_buffer = std::make_unique<QBuffer>();
246+
}
247+
248+
s_audio_buffer->setBuffer(s_audio_data.get());
249+
s_audio_buffer->open(QIODevice::ReadOnly);
250+
s_audio_player->setSourceDevice(s_audio_buffer.get());
251+
252+
if (old_audio_data)
253+
{
254+
old_audio_data.reset();
255+
}
256+
}
257+
258+
s_audio_output->setVolume(g_cfg.audio.volume.get() / 100.0f);
259+
s_audio_player->play();
260+
s_audio_source = this;
261+
}
262+
263+
void qt_video_source::stop_audio()
264+
{
265+
if (s_audio_source != this) return;
266+
267+
s_audio_source = nullptr;
268+
269+
if (s_audio_player)
270+
{
271+
s_audio_player->stop();
272+
s_audio_player.reset();
273+
}
274+
275+
s_audio_output.reset();
276+
s_audio_buffer.reset();
277+
s_audio_data.reset();
199278
}
200279

201280
QPixmap qt_video_source::get_movie_image(const QVideoFrame& frame) const
@@ -288,6 +367,14 @@ void qt_video_source_wrapper::set_video_path(const std::string& video_path)
288367
});
289368
}
290369

370+
void qt_video_source_wrapper::set_audio_path(const std::string& audio_path)
371+
{
372+
Emu.CallFromMainThread([this, path = audio_path]()
373+
{
374+
// TODO
375+
});
376+
}
377+
291378
void qt_video_source_wrapper::set_active(bool active)
292379
{
293380
Emu.CallFromMainThread([this, active]()

rpcs3/rpcs3qt/qt_video_source.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ class qt_video_source : public video_source
1919

2020
void set_iso_path(const std::string& iso_path);
2121
void set_video_path(const std::string& video_path) override;
22+
void set_audio_path(const std::string& audio_path) override;
2223
const QString& video_path() const { return m_video_path; }
24+
const QString& audio_path() const { return m_audio_path; }
2325

2426
void get_image(std::vector<u8>& data, int& w, int& h, int& ch, int& bpp) override;
2527
bool has_new() const override { return m_has_new; }
@@ -30,6 +32,9 @@ class qt_video_source : public video_source
3032
void start_movie();
3133
void stop_movie();
3234

35+
void start_audio();
36+
void stop_audio();
37+
3338
QPixmap get_movie_image(const QVideoFrame& frame) const;
3439

3540
void image_change_callback(const QVideoFrame& frame = {}) const;
@@ -44,6 +49,7 @@ class qt_video_source : public video_source
4449
atomic_t<bool> m_has_new = false;
4550

4651
QString m_video_path;
52+
QString m_audio_path;
4753
std::string m_iso_path; // path of the source archive
4854
QByteArray m_video_data{};
4955
QImage m_image{};
@@ -67,6 +73,7 @@ class qt_video_source_wrapper : public video_source
6773
virtual ~qt_video_source_wrapper();
6874

6975
void set_video_path(const std::string& video_path) override;
76+
void set_audio_path(const std::string& audio_path) override;
7077
void set_active(bool active) override;
7178
bool get_active() const override;
7279
bool has_new() const override { return m_qt_video_source && m_qt_video_source->has_new(); }

rpcs3/rpcs3qt/save_manager_dialog.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,11 @@ void save_manager_dialog::UpdateList()
360360
icon_item->set_video_path(movie_path);
361361
}
362362

363+
if (const std::string audio_path = dir_path + "SND0.AT3"; fs::is_file(audio_path))
364+
{
365+
icon_item->set_audio_path(audio_path);
366+
}
367+
363368
icon_item->set_image_change_callback([this, icon_item](const QVideoFrame& frame)
364369
{
365370
if (!icon_item)

rpcs3/util/video_source.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class video_source
99
video_source() {};
1010
virtual ~video_source() {};
1111
virtual void set_video_path(const std::string& video_path) = 0;
12+
virtual void set_audio_path(const std::string& audio_path) = 0;
1213
virtual void set_active(bool active) = 0;
1314
virtual bool get_active() const = 0;
1415
virtual bool has_new() const = 0;

0 commit comments

Comments
 (0)