Compare commits
10 Commits
924b17371d
...
6fce063893
Author | SHA1 | Date |
---|---|---|
Aneesh Maganti | 6fce063893 | |
OatmealDome | 795e78685f | |
JMC47 | f65465b96c | |
Aneesh Maganti | d232c689cb | |
aminoa | b54bf24a4e | |
Admiral H. Curtiss | c3086f24c9 | |
OatmealDome | 5578160880 | |
OatmealDome | 4fc259710f | |
OatmealDome | 89016834cf | |
Charlese2 | 635f588690 |
|
@ -30,6 +30,8 @@ if(GIT_FOUND)
|
|||
ERROR_QUIET)
|
||||
endif()
|
||||
|
||||
string(TIMESTAMP DOLPHIN_WC_BUILD_DATE "%Y-%m-%d" UTC)
|
||||
|
||||
# version number
|
||||
set(DOLPHIN_VERSION_MAJOR "2412")
|
||||
set(DOLPHIN_VERSION_MINOR "0")
|
||||
|
@ -67,3 +69,7 @@ configure_source_file("Source/Core/Common/scmrev.h")
|
|||
if(APPLE)
|
||||
configure_source_file("Source/Core/VersionInfo.plist")
|
||||
endif()
|
||||
|
||||
if(LINUX)
|
||||
configure_source_file("Flatpak/org.DolphinEmu.dolphin-emu.metainfo.xml")
|
||||
endif()
|
||||
|
|
|
@ -789,6 +789,13 @@ if(APPLE)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Flatpak)
|
||||
if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/Flatpak/org.DolphinEmu.dolphin-emu.metainfo.xml)
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/Flatpak/org.DolphinEmu.dolphin-emu.metainfo.xml)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(Git)
|
||||
if(NOT GIT_FOUND)
|
||||
set(GIT_EXECUTABLE "")
|
||||
|
@ -796,7 +803,7 @@ endif()
|
|||
add_custom_target(
|
||||
dolphin_scmrev
|
||||
${CMAKE_COMMAND} -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} -DDISTRIBUTOR=${DISTRIBUTOR} -DDOLPHIN_DEFAULT_UPDATE_TRACK=${DOLPHIN_DEFAULT_UPDATE_TRACK} -DGIT_FOUND=${GIT_FOUND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DDOLPHIN_WC_REVISION=${DOLPHIN_WC_REVISION} -DDOLPHIN_WC_DESCRIBE=${DOLPHIN_WC_DESCRIBE} -DDOLPHIN_WC_BRANCH=${DOLPHIN_WC_BRANCH} -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} -P ${CMAKE_CURRENT_SOURCE_DIR}/CMake/ScmRevGen.cmake
|
||||
BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/Source/Core/Common/scmrev.h" "${CMAKE_CURRENT_BINARY_DIR}/Source/Core/DolphinQt/Info.plist" "${CMAKE_CURRENT_BINARY_DIR}/Source/Core/MacUpdater/Info.plist"
|
||||
BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/Source/Core/Common/scmrev.h" "${CMAKE_CURRENT_BINARY_DIR}/Source/Core/DolphinQt/Info.plist" "${CMAKE_CURRENT_BINARY_DIR}/Source/Core/MacUpdater/Info.plist" "${CMAKE_CURRENT_BINARY_DIR}/Flatpak/org.DolphinEmu.dolphin-emu.metainfo.xml"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,48 @@
|
|||
# GS2E78 - Summoner 2
|
||||
|
||||
[OnFrame]
|
||||
# Add memory patches to be applied every frame here.
|
||||
# This game will reinitialize the sound system buffers during transitions while
|
||||
# sounds are still being played. There are still pointers in the sound list to
|
||||
# sounds in those buffers when the buffers get cleared, so the game crashes with
|
||||
# a null pointer dereference.
|
||||
#
|
||||
# This patch will clean up the pending sound list during sound system
|
||||
# reinitialization before continuing to the sound system initialization call
|
||||
# previously at 0x8017E338.
|
||||
$Fix Sound System Crash
|
||||
0x8017E338:dword:0x480954C9
|
||||
0x80213800:dword:0x9421FFE0
|
||||
0x80213804:dword:0x7C0802A6
|
||||
0x80213808:dword:0x90010024
|
||||
0x8021380C:dword:0x93E1001C
|
||||
0x80213810:dword:0x93C10018
|
||||
0x80213814:dword:0x93A10014
|
||||
0x80213818:dword:0x7C7D1B78
|
||||
0x8021381C:dword:0x4BF7A7D1
|
||||
0x80213820:dword:0x83CDA0C0
|
||||
0x80213824:dword:0x7C7F1B78
|
||||
0x80213828:dword:0x48000010
|
||||
0x8021382C:dword:0x807E0008
|
||||
0x80213830:dword:0x4BF8C721
|
||||
0x80213834:dword:0x83DE0000
|
||||
0x80213838:dword:0x281E0000
|
||||
0x8021383C:dword:0x4082FFF0
|
||||
0x80213840:dword:0x38000000
|
||||
0x80213844:dword:0x7FE3FB78
|
||||
0x80213848:dword:0x900DA0C0
|
||||
0x8021384C:dword:0x4BF7A7C9
|
||||
0x80213850:dword:0x7FA3EB78
|
||||
0x80213854:dword:0x4BF6A49D
|
||||
0x80213858:dword:0x80010024
|
||||
0x8021385C:dword:0x83E1001C
|
||||
0x80213860:dword:0x83C10018
|
||||
0x80213864:dword:0x83A10014
|
||||
0x80213868:dword:0x7C0803A6
|
||||
0x8021386C:dword:0x38210020
|
||||
0x80213870:dword:0x4E800020
|
||||
|
||||
[OnFrame_Enabled]
|
||||
$Fix Sound System Crash
|
||||
|
||||
[ActionReplay]
|
||||
# Add action replay cheats here.
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
DATE=$(git log -1 --pretty=%cd --date=iso8601 --date=format:'%Y-%m-%d')
|
||||
sed -i -e "s/@DATE_PLACEHOLDER/${DATE}/" org.DolphinEmu.dolphin-emu.metainfo.xml
|
||||
VERSION=$(git describe --tags | sed -E 's/^([0-9]+-[0-9]+).*/\1/')
|
||||
sed -i -e "s/@VERSION_PLACEHOLDER/${VERSION}/" org.DolphinEmu.dolphin-emu.metainfo.xml
|
||||
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
<id>dolphin-emu.desktop</id>
|
||||
</provides>
|
||||
<releases>
|
||||
<release version="@VERSION_PLACEHOLDER" date="@DATE_PLACEHOLDER"/>
|
||||
<release version="${DOLPHIN_WC_DESCRIBE}" date="${DOLPHIN_WC_BUILD_DATE}"/>
|
||||
</releases>
|
||||
<url type="homepage">https://dolphin-emu.org</url>
|
||||
<url type="bugtracker">https://bugs.dolphin-emu.org/projects/emulator/issues</url>
|
||||
|
@ -46,4 +46,7 @@
|
|||
<url type="contact">https://dolphin-emu.org/docs/faq/#ive-got-idea-make-dolphin-better-how-should-i-tell</url>
|
||||
<url type="vcs-browser">https://github.com/dolphin-emu/dolphin</url>
|
||||
<url type="contribute">https://github.com/dolphin-emu/dolphin/blob/master/Contributing.md</url>
|
||||
<custom>
|
||||
<value key="flathub::manifest">https://github.com/dolphin-emu/dolphin/blob/${DOLPHIN_WC_REVISION}/Flatpak/org.DolphinEmu.dolphin-emu.yml</value>
|
||||
</custom>
|
||||
</component>
|
||||
|
|
|
@ -52,6 +52,7 @@ modules:
|
|||
|
||||
- name: dolphin-emu
|
||||
buildsystem: cmake-ninja
|
||||
builddir: true
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=Release
|
||||
- -DENABLE_ALSA=OFF
|
||||
|
@ -61,17 +62,13 @@ modules:
|
|||
cleanup:
|
||||
- /share/man
|
||||
post-install:
|
||||
- install -D -t ${FLATPAK_DEST}/bin/ dolphin-emu-wrapper
|
||||
- "${FLATPAK_BUILDER_BUILDDIR}/Flatpak/fill_release_node.sh"
|
||||
- install -Dm644 -t ${FLATPAK_DEST}/share/metainfo/ org.DolphinEmu.dolphin-emu.metainfo.xml
|
||||
- install -D -t ${FLATPAK_DEST}/bin/ ../dolphin-emu-wrapper
|
||||
- install -Dm644 -t ${FLATPAK_DEST}/share/metainfo/ Flatpak/org.DolphinEmu.dolphin-emu.metainfo.xml
|
||||
- desktop-file-edit --set-key=Exec --set-value='/app/bin/dolphin-emu-wrapper'
|
||||
/app/share/applications/dolphin-emu.desktop
|
||||
sources:
|
||||
- type: dir
|
||||
path: ..
|
||||
- type: file
|
||||
path: org.DolphinEmu.dolphin-emu.metainfo.xml.in
|
||||
dest-filename: org.DolphinEmu.dolphin-emu.metainfo.xml
|
||||
- type: script
|
||||
commands:
|
||||
- |
|
||||
|
|
|
@ -541,6 +541,8 @@ add_library(core
|
|||
SysConf.h
|
||||
System.cpp
|
||||
System.h
|
||||
TimePlayed.cpp
|
||||
TimePlayed.h
|
||||
TitleDatabase.cpp
|
||||
TitleDatabase.h
|
||||
WC24PatchEngine.cpp
|
||||
|
|
|
@ -459,6 +459,8 @@ const Info<bool> MAIN_GAMELIST_COLUMN_BLOCK_SIZE{{System::Main, "GameList", "Col
|
|||
false};
|
||||
const Info<bool> MAIN_GAMELIST_COLUMN_COMPRESSION{{System::Main, "GameList", "ColumnCompression"},
|
||||
false};
|
||||
const Info<bool> MAIN_GAMELIST_COLUMN_TIME_PLAYED{{System::Main, "GameList", "ColumnTimePlayed"},
|
||||
true};
|
||||
const Info<bool> MAIN_GAMELIST_COLUMN_TAGS{{System::Main, "GameList", "ColumnTags"}, false};
|
||||
|
||||
// Main.FifoPlayer
|
||||
|
|
|
@ -295,6 +295,7 @@ extern const Info<bool> MAIN_GAMELIST_COLUMN_FILE_SIZE;
|
|||
extern const Info<bool> MAIN_GAMELIST_COLUMN_FILE_FORMAT;
|
||||
extern const Info<bool> MAIN_GAMELIST_COLUMN_BLOCK_SIZE;
|
||||
extern const Info<bool> MAIN_GAMELIST_COLUMN_COMPRESSION;
|
||||
extern const Info<bool> MAIN_GAMELIST_COLUMN_TIME_PLAYED;
|
||||
extern const Info<bool> MAIN_GAMELIST_COLUMN_TAGS;
|
||||
|
||||
// Main.FifoPlayer
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
@ -98,6 +99,42 @@ void SConfig::LoadSettings()
|
|||
Config::Load();
|
||||
}
|
||||
|
||||
const std::string& SConfig::GetGameID() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_metadata_lock);
|
||||
return m_game_id;
|
||||
}
|
||||
|
||||
const std::string& SConfig::GetGameTDBID() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_metadata_lock);
|
||||
return m_gametdb_id;
|
||||
}
|
||||
|
||||
const std::string& SConfig::GetTitleName() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_metadata_lock);
|
||||
return m_title_name;
|
||||
}
|
||||
|
||||
const std::string& SConfig::GetTitleDescription() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_metadata_lock);
|
||||
return m_title_description;
|
||||
}
|
||||
|
||||
u64 SConfig::GetTitleID() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_metadata_lock);
|
||||
return m_title_id;
|
||||
}
|
||||
|
||||
u16 SConfig::GetRevision() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_metadata_lock);
|
||||
return m_revision;
|
||||
}
|
||||
|
||||
void SConfig::ResetRunningGameMetadata()
|
||||
{
|
||||
SetRunningGameMetadata("00000000", "", 0, 0, DiscIO::Region::Unknown);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
@ -58,15 +59,16 @@ struct SConfig
|
|||
std::string m_strSRAM;
|
||||
|
||||
std::string m_debugger_game_id;
|
||||
|
||||
// TODO: remove this as soon as the ticket view hack in IOS/ES/Views is dropped.
|
||||
bool m_disc_booted_from_game_list = false;
|
||||
|
||||
const std::string& GetGameID() const { return m_game_id; }
|
||||
const std::string& GetGameTDBID() const { return m_gametdb_id; }
|
||||
const std::string& GetTitleName() const { return m_title_name; }
|
||||
const std::string& GetTitleDescription() const { return m_title_description; }
|
||||
u64 GetTitleID() const { return m_title_id; }
|
||||
u16 GetRevision() const { return m_revision; }
|
||||
const std::string& GetGameID() const;
|
||||
const std::string& GetGameTDBID() const;
|
||||
const std::string& GetTitleName() const;
|
||||
const std::string& GetTitleDescription() const;
|
||||
u64 GetTitleID() const;
|
||||
u16 GetRevision() const;
|
||||
void ResetRunningGameMetadata();
|
||||
void SetRunningGameMetadata(const DiscIO::Volume& volume, const DiscIO::Partition& partition);
|
||||
void SetRunningGameMetadata(const IOS::ES::TMDReader& tmd, DiscIO::Platform platform);
|
||||
|
@ -114,6 +116,7 @@ private:
|
|||
u64 title_id, u16 revision, DiscIO::Region region);
|
||||
|
||||
static SConfig* m_Instance;
|
||||
mutable std::mutex m_metadata_lock;
|
||||
|
||||
std::string m_game_id;
|
||||
std::string m_gametdb_id;
|
||||
|
|
|
@ -10,16 +10,20 @@
|
|||
#include "AudioCommon/AudioCommon.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Event.h"
|
||||
#include "Common/Timer.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/CPUThreadConfigCallback.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/PowerPC/GDBStub.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/TimePlayed.h"
|
||||
#include "VideoCommon/Fifo.h"
|
||||
|
||||
namespace CPU
|
||||
{
|
||||
|
||||
CPUManager::CPUManager(Core::System& system) : m_system(system)
|
||||
{
|
||||
}
|
||||
|
@ -63,6 +67,34 @@ void CPUManager::ExecutePendingJobs(std::unique_lock<std::mutex>& state_lock)
|
|||
}
|
||||
}
|
||||
|
||||
void CPUManager::StartTimePlayedTimer()
|
||||
{
|
||||
// Steady clock for greater accuracy of timing
|
||||
std::chrono::steady_clock timer;
|
||||
auto prev_time = timer.now();
|
||||
|
||||
while (true)
|
||||
{
|
||||
const std::string game_id = SConfig::GetInstance().GetGameID();
|
||||
TimePlayed time_played(game_id);
|
||||
auto curr_time = timer.now();
|
||||
|
||||
// Check that emulation is not paused
|
||||
if (m_state == State::Running)
|
||||
{
|
||||
auto diff_time = std::chrono::duration_cast<std::chrono::milliseconds>(curr_time - prev_time);
|
||||
time_played.AddTime(diff_time);
|
||||
}
|
||||
|
||||
prev_time = curr_time;
|
||||
|
||||
if (m_state == State::PowerDown)
|
||||
return;
|
||||
|
||||
m_time_played_finish_sync.WaitFor(std::chrono::seconds(30));
|
||||
}
|
||||
}
|
||||
|
||||
void CPUManager::Run()
|
||||
{
|
||||
auto& power_pc = m_system.GetPowerPC();
|
||||
|
@ -71,6 +103,9 @@ void CPUManager::Run()
|
|||
// We can't rely on PowerPC::Init doing it, since it's called from EmuThread.
|
||||
PowerPC::RoundingModeUpdated(power_pc.GetPPCState());
|
||||
|
||||
// Start a separate time tracker thread
|
||||
auto timing = std::thread(&CPUManager::StartTimePlayedTimer, this);
|
||||
|
||||
std::unique_lock state_lock(m_state_change_lock);
|
||||
while (m_state != State::PowerDown)
|
||||
{
|
||||
|
@ -165,6 +200,11 @@ void CPUManager::Run()
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// m_timer_finish.notify_one();
|
||||
m_time_played_finish_sync.Set();
|
||||
timing.join();
|
||||
|
||||
state_lock.unlock();
|
||||
Host_UpdateDisasmDialog();
|
||||
}
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <Common/Event.h>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
namespace Common
|
||||
|
||||
{
|
||||
class Event;
|
||||
}
|
||||
|
@ -102,6 +104,7 @@ public:
|
|||
private:
|
||||
void FlushStepSyncEventLocked();
|
||||
void ExecutePendingJobs(std::unique_lock<std::mutex>& state_lock);
|
||||
void StartTimePlayedTimer();
|
||||
void RunAdjacentSystems(bool running);
|
||||
bool SetStateLocked(State s);
|
||||
|
||||
|
@ -133,6 +136,7 @@ private:
|
|||
bool m_state_cpu_step_instruction = false;
|
||||
Common::Event* m_state_cpu_step_instruction_sync = nullptr;
|
||||
std::queue<std::function<void()>> m_pending_jobs;
|
||||
Common::Event m_time_played_finish_sync;
|
||||
|
||||
Core::System& m_system;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "TimePlayed.h"
|
||||
|
||||
// used for QT interface - general access to time played for games
|
||||
TimePlayed::TimePlayed()
|
||||
{
|
||||
m_game_id = "None";
|
||||
ini_path = File::GetUserPath(D_CONFIG_IDX) + "TimePlayed.ini";
|
||||
ini.Load(ini_path);
|
||||
time_list = ini.GetOrCreateSection("Time Played");
|
||||
}
|
||||
|
||||
void FilterUnsafeCharacters(std::string& game_id)
|
||||
{
|
||||
const std::string forbiddenChars = "\\/:?\"<>|";
|
||||
for (auto& chr : game_id)
|
||||
{
|
||||
if (forbiddenChars.find(chr) != std::string::npos)
|
||||
{
|
||||
chr = '_';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TimePlayed::TimePlayed(std::string game_id)
|
||||
{
|
||||
// filter for unsafe characters
|
||||
FilterUnsafeCharacters(game_id);
|
||||
|
||||
m_game_id = game_id;
|
||||
ini_path = File::GetUserPath(D_CONFIG_IDX) + "TimePlayed.ini";
|
||||
ini.Load(ini_path);
|
||||
time_list = ini.GetOrCreateSection("Time Played");
|
||||
}
|
||||
|
||||
void TimePlayed::AddTime(std::chrono::milliseconds time_emulated)
|
||||
{
|
||||
if (m_game_id == "None")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
u64 previous_time;
|
||||
time_list->Get(m_game_id, &previous_time);
|
||||
time_list->Set(m_game_id, previous_time + u64(time_emulated.count()));
|
||||
ini.Save(ini_path);
|
||||
}
|
||||
|
||||
u64 TimePlayed::GetTimePlayed()
|
||||
{
|
||||
if (m_game_id == "None")
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 previous_time;
|
||||
time_list->Get(m_game_id, &previous_time);
|
||||
return previous_time;
|
||||
}
|
||||
|
||||
u64 TimePlayed::GetTimePlayed(std::string game_id)
|
||||
{
|
||||
FilterUnsafeCharacters(game_id);
|
||||
u64 previous_time;
|
||||
time_list->Get(game_id, &previous_time);
|
||||
return previous_time;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/IniFile.h"
|
||||
|
||||
class TimePlayed
|
||||
{
|
||||
public:
|
||||
TimePlayed();
|
||||
TimePlayed(std::string game_id);
|
||||
|
||||
void AddTime(std::chrono::milliseconds time_emulated);
|
||||
|
||||
u64 GetTimePlayed();
|
||||
u64 GetTimePlayed(std::string game_id);
|
||||
|
||||
private:
|
||||
std::string m_game_id;
|
||||
Common::IniFile ini;
|
||||
std::string ini_path;
|
||||
|
||||
Common::IniFile::Section* time_list;
|
||||
};
|
|
@ -459,6 +459,7 @@
|
|||
<ClInclude Include="Core\SyncIdentifier.h" />
|
||||
<ClInclude Include="Core\SysConf.h" />
|
||||
<ClInclude Include="Core\System.h" />
|
||||
<ClInclude Include="Core\TimePlayed.h" />
|
||||
<ClInclude Include="Core\TitleDatabase.h" />
|
||||
<ClInclude Include="Core\WC24PatchEngine.h" />
|
||||
<ClInclude Include="Core\WiiRoot.h" />
|
||||
|
@ -1125,6 +1126,7 @@
|
|||
<ClCompile Include="Core\State.cpp" />
|
||||
<ClCompile Include="Core\SysConf.cpp" />
|
||||
<ClCompile Include="Core\System.cpp" />
|
||||
<ClCompile Include="Core\TimePlayed.cpp" />
|
||||
<ClCompile Include="Core\TitleDatabase.cpp" />
|
||||
<ClCompile Include="Core\WiiRoot.cpp" />
|
||||
<ClCompile Include="Core\WiiUtils.cpp" />
|
||||
|
|
|
@ -208,6 +208,7 @@ void GameList::MakeListView()
|
|||
SetResizeMode(Column::FileFormat, Mode::Fixed);
|
||||
SetResizeMode(Column::BlockSize, Mode::Fixed);
|
||||
SetResizeMode(Column::Compression, Mode::Fixed);
|
||||
SetResizeMode(Column::TimePlayed, Mode::Interactive);
|
||||
SetResizeMode(Column::Tags, Mode::Interactive);
|
||||
|
||||
// Cells have 3 pixels of padding, so the width of these needs to be image width + 6. Banners
|
||||
|
@ -273,6 +274,7 @@ void GameList::UpdateColumnVisibility()
|
|||
SetVisiblity(Column::FileFormat, Config::Get(Config::MAIN_GAMELIST_COLUMN_FILE_FORMAT));
|
||||
SetVisiblity(Column::BlockSize, Config::Get(Config::MAIN_GAMELIST_COLUMN_BLOCK_SIZE));
|
||||
SetVisiblity(Column::Compression, Config::Get(Config::MAIN_GAMELIST_COLUMN_COMPRESSION));
|
||||
SetVisiblity(Column::TimePlayed, Config::Get(Config::MAIN_GAMELIST_COLUMN_TIME_PLAYED));
|
||||
SetVisiblity(Column::Tags, Config::Get(Config::MAIN_GAMELIST_COLUMN_TAGS));
|
||||
}
|
||||
|
||||
|
@ -1005,6 +1007,7 @@ void GameList::OnColumnVisibilityToggled(const QString& row, bool visible)
|
|||
{tr("File Format"), Column::FileFormat},
|
||||
{tr("Block Size"), Column::BlockSize},
|
||||
{tr("Compression"), Column::Compression},
|
||||
{tr("Time Played"), Column::TimePlayed},
|
||||
{tr("Tags"), Column::Tags},
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <QRegularExpression>
|
||||
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/TimePlayed.h"
|
||||
|
||||
#include "DiscIO/Enums.h"
|
||||
|
||||
|
@ -57,6 +58,7 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
|
|||
return QVariant();
|
||||
|
||||
const UICommon::GameFile& game = *m_games[index.row()];
|
||||
TimePlayed timer;
|
||||
|
||||
switch (static_cast<Column>(index.column()))
|
||||
{
|
||||
|
@ -187,6 +189,22 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
|
|||
return compression.isEmpty() ? tr("No Compression") : compression;
|
||||
}
|
||||
break;
|
||||
case Column::TimePlayed:
|
||||
if (role == Qt::DisplayRole || role == SORT_ROLE)
|
||||
{
|
||||
std::string game_id = game.GetGameID();
|
||||
std::chrono::milliseconds total_time(timer.GetTimePlayed(game_id));
|
||||
std::chrono::minutes total_minutes =
|
||||
std::chrono::duration_cast<std::chrono::minutes>(total_time);
|
||||
std::chrono::hours total_hours = std::chrono::duration_cast<std::chrono::hours>(total_time);
|
||||
|
||||
// i18n: A time displayed as hours and minutes
|
||||
QString formatted_time = tr("%1h %2m")
|
||||
.arg(total_hours.count())
|
||||
.arg(total_minutes.count() - total_hours.count() * 60);
|
||||
return formatted_time;
|
||||
}
|
||||
break;
|
||||
case Column::Tags:
|
||||
if (role == Qt::DisplayRole || role == SORT_ROLE)
|
||||
{
|
||||
|
@ -232,6 +250,8 @@ QVariant GameListModel::headerData(int section, Qt::Orientation orientation, int
|
|||
return tr("Block Size");
|
||||
case Column::Compression:
|
||||
return tr("Compression");
|
||||
case Column::TimePlayed:
|
||||
return tr("Time Played");
|
||||
case Column::Tags:
|
||||
return tr("Tags");
|
||||
default:
|
||||
|
|
|
@ -58,6 +58,7 @@ public:
|
|||
FileFormat,
|
||||
BlockSize,
|
||||
Compression,
|
||||
TimePlayed,
|
||||
Tags,
|
||||
Count,
|
||||
};
|
||||
|
|
|
@ -701,6 +701,7 @@ void MenuBar::AddListColumnsMenu(QMenu* view_menu)
|
|||
{tr("File Format"), &Config::MAIN_GAMELIST_COLUMN_FILE_FORMAT},
|
||||
{tr("Block Size"), &Config::MAIN_GAMELIST_COLUMN_BLOCK_SIZE},
|
||||
{tr("Compression"), &Config::MAIN_GAMELIST_COLUMN_COMPRESSION},
|
||||
{tr("Time Played"), &Config::MAIN_GAMELIST_COLUMN_TIME_PLAYED},
|
||||
{tr("Tags"), &Config::MAIN_GAMELIST_COLUMN_TAGS}};
|
||||
|
||||
QActionGroup* column_group = new QActionGroup(this);
|
||||
|
|
Loading…
Reference in New Issue