Add playback of background/title music in game list (#1033)

* add playback of background/title music

* clang_format

* add windows multimedia build instructions

* fix typo accidentally made to arm

* address comments

* loop music

* feedback

* fix CI

* add newline

* playBGM off by default

---------

Co-authored-by: Charles <charles@superfocus.ai>
This commit is contained in:
tGecko 2024-09-26 08:12:41 +02:00 committed by GitHub
parent ddb82a690b
commit 54e2179337
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 181 additions and 17 deletions

View file

@ -0,0 +1,32 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "background_music_player.h"
BackgroundMusicPlayer::BackgroundMusicPlayer(QObject* parent) : QObject(parent) {
m_mediaPlayer = new QMediaPlayer(this);
m_audioOutput = new QAudioOutput(this);
m_mediaPlayer->setAudioOutput(m_audioOutput);
m_mediaPlayer->setLoops(QMediaPlayer::Infinite);
}
void BackgroundMusicPlayer::playMusic(const QString& snd0path) {
if (snd0path.isEmpty()) {
stopMusic();
return;
}
const auto newMusic = QUrl::fromLocalFile(snd0path);
if (m_mediaPlayer->playbackState() == QMediaPlayer::PlayingState &&
m_currentMusic == newMusic) {
// already playing the correct music
return;
}
m_currentMusic = newMusic;
m_mediaPlayer->setSource(newMusic);
m_mediaPlayer->play();
}
void BackgroundMusicPlayer::stopMusic() {
m_mediaPlayer->stop();
}

View file

@ -0,0 +1,28 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QAudioOutput>
#include <QMediaPlayer>
#include <QObject>
class BackgroundMusicPlayer : public QObject {
Q_OBJECT
public:
static BackgroundMusicPlayer& getInstance() {
static BackgroundMusicPlayer instance;
return instance;
}
void playMusic(const QString& snd0path);
void stopMusic();
private:
BackgroundMusicPlayer(QObject* parent = nullptr);
QMediaPlayer* m_mediaPlayer;
QAudioOutput* m_audioOutput;
QUrl m_currentMusic;
};

View file

@ -39,6 +39,15 @@ GameGridFrame::GameGridFrame(std::shared_ptr<GameInfoClass> game_info_get, QWidg
});
}
void GameGridFrame::PlayBackgroundMusic(QTableWidgetItem* item) {
if (!item) {
BackgroundMusicPlayer::getInstance().stopMusic();
return;
}
const auto snd0path = QString::fromStdString(m_game_info->m_games[item->row()].snd0_path);
BackgroundMusicPlayer::getInstance().playMusic(snd0path);
}
void GameGridFrame::PopulateGameGrid(QVector<GameInfo> m_games_search, bool fromSearch) {
QVector<GameInfo> m_games_;
this->clearContents();

View file

@ -5,6 +5,7 @@
#include <QScrollBar>
#include "background_music_player.h"
#include "common/config.h"
#include "game_info.h"
#include "game_list_utils.h"
@ -19,6 +20,7 @@ Q_SIGNALS:
public Q_SLOTS:
void SetGridBackgroundImage(int row, int column);
void RefreshGridBackgroundImage();
void PlayBackgroundMusic(QTableWidgetItem* item);
private:
QImage backgroundImage;

View file

@ -32,6 +32,7 @@ public:
QString iconpath = QString::fromStdString(game.icon_path);
game.icon = QImage(iconpath);
game.pic_path = game.path + "/sce_sys/pic1.png";
game.snd0_path = game.path + "/sce_sys/snd0.at9";
if (const auto title = psf.GetString("TITLE"); title.has_value()) {
game.name = *title;
}

View file

@ -68,6 +68,15 @@ GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get, QWidg
});
}
void GameListFrame::PlayBackgroundMusic(QTableWidgetItem* item) {
if (!item) {
BackgroundMusicPlayer::getInstance().stopMusic();
return;
}
const auto snd0path = QString::fromStdString(m_game_info->m_games[item->row()].snd0_path);
BackgroundMusicPlayer::getInstance().playMusic(snd0path);
}
void GameListFrame::PopulateGameList() {
this->setRowCount(m_game_info->m_games.size());
ResizeIcons(icon_size);

View file

@ -5,6 +5,7 @@
#include <QScrollBar>
#include "background_music_player.h"
#include "game_info.h"
#include "game_list_utils.h"
#include "gui_context_menus.h"
@ -21,6 +22,7 @@ public Q_SLOTS:
void RefreshListBackgroundImage();
void SortNameAscending(int columnIndex);
void SortNameDescending(int columnIndex);
void PlayBackgroundMusic(QTableWidgetItem* item);
private:
void SetTableItem(int row, int column, QString itemStr);

View file

@ -7,6 +7,7 @@ struct GameInfo {
std::string path; // root path of game directory (normally directory that contains eboot.bin)
std::string icon_path; // path of icon0.png
std::string pic_path; // path of pic1.png
std::string snd0_path; // path of snd0.at9
QImage icon;
std::string size;
// variables extracted from param.sfo

View file

@ -501,9 +501,29 @@ void MainWindow::CreateConnects() {
isIconBlack = false;
}
});
connect(m_game_grid_frame.get(), &QTableWidget::cellClicked, this,
&MainWindow::PlayBackgroundMusic);
connect(m_game_list_frame.get(), &QTableWidget::cellClicked, this,
&MainWindow::PlayBackgroundMusic);
}
void MainWindow::PlayBackgroundMusic() {
if (isGameRunning || !Config::getPlayBGM()) {
BackgroundMusicPlayer::getInstance().stopMusic();
return;
}
int itemID = isTableList ? m_game_list_frame->currentItem()->row()
: m_game_grid_frame->crtRow * m_game_grid_frame->columnCnt +
m_game_grid_frame->crtColumn;
const auto snd0path = QString::fromStdString(m_game_info->m_games[itemID].snd0_path);
BackgroundMusicPlayer::getInstance().playMusic(snd0path);
}
void MainWindow::StartGame() {
isGameRunning = true;
BackgroundMusicPlayer::getInstance().stopMusic();
QString gamePath = "";
int table_mode = Config::getTableMode();
if (table_mode == 0) {

View file

@ -7,6 +7,7 @@
#include <QDragEnterEvent>
#include <QTranslator>
#include "background_music_player.h"
#include "common/config.h"
#include "common/path_util.h"
#include "core/file_format/psf.h"
@ -63,9 +64,11 @@ private:
void BootGame();
void AddRecentFiles(QString filePath);
void LoadTranslation();
void PlayBackgroundMusic();
QIcon RecolorIcon(const QIcon& icon, bool isWhite);
bool isIconBlack = false;
bool isTableList = true;
bool isGameRunning = false;
QActionGroup* m_icon_size_act_group = nullptr;
QActionGroup* m_list_mode_act_group = nullptr;
QActionGroup* m_theme_act_group = nullptr;

View file

@ -134,6 +134,9 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
auto checkUpdate = new CheckUpdate(true);
checkUpdate->exec();
});
connect(ui->playBGMCheckBox, &QCheckBox::stateChanged, this,
[](int val) { Config::setPlayBGM(val); });
}
// GPU TAB
@ -192,7 +195,7 @@ void SettingsDialog::LoadValuesFromConfig() {
ui->dumpShadersCheckBox->setChecked(Config::dumpShaders());
ui->nullGpuCheckBox->setChecked(Config::nullGpu());
ui->dumpPM4CheckBox->setChecked(Config::dumpPM4());
ui->playBGMCheckBox->setChecked(Config::getPlayBGM());
ui->fullscreenCheckBox->setChecked(Config::isFullscreenMode());
ui->showSplashCheckBox->setChecked(Config::showSplash());
ui->ps4proCheckBox->setChecked(Config::isNeoMode());

View file

@ -52,7 +52,7 @@
<x>0</x>
<y>0</y>
<width>836</width>
<height>428</height>
<height>432</height>
</rect>
</property>
<property name="sizePolicy">
@ -70,7 +70,7 @@
</attribute>
<layout class="QVBoxLayout" name="generalTabVLayout" stretch="0,0">
<item>
<layout class="QHBoxLayout" name="generalTabHLayout" stretch="1,1,1">
<layout class="QHBoxLayout" name="generalTabHLayoutTop" stretch="1,1,1">
<item>
<layout class="QVBoxLayout" name="systemTabLayoutLeft">
<item>
@ -340,19 +340,55 @@
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="GUITabLayoutMiddle" stretch="1">
<item>
<widget class="QGroupBox" name="GUIgroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>GUI Settings</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget_3">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>241</width>
<height>41</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="playBGMCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Play title music</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>500</width>
<height>20</height>
</size>
<enum>QSizePolicy::Policy::Expanding</enum>
</property>
</spacer>
</item>