From a2c356f16ea664433619dfb8632f13b0fefff887 Mon Sep 17 00:00:00 2001 From: Daniel Simpkins Date: Sat, 21 Jan 2023 09:30:45 -0500 Subject: [PATCH 1/2] Core: Added playtime counter on a per ROM basis. --- Source/Project64-core/Multilanguage.h | 1 + Source/Project64-core/Multilanguage/Language.cpp | 1 + Source/Project64-core/RomList/RomList.cpp | 11 +++++++++++ Source/Project64-core/RomList/RomList.h | 7 +++++++ Source/Project64-core/Settings.cpp | 2 ++ Source/Project64-core/Settings/SettingsID.h | 2 ++ Source/Project64/UserInterface/MainWindow.cpp | 10 ++++++++++ Source/Project64/UserInterface/MainWindow.h | 4 ++++ Source/Project64/UserInterface/RomBrowser.cpp | 7 +++++++ Source/Project64/UserInterface/RomBrowser.h | 1 + 10 files changed, 46 insertions(+) diff --git a/Source/Project64-core/Multilanguage.h b/Source/Project64-core/Multilanguage.h index 23edadc13..e2f111d27 100644 --- a/Source/Project64-core/Multilanguage.h +++ b/Source/Project64-core/Multilanguage.h @@ -195,6 +195,7 @@ enum LanguageStringID RB_FORCE_FEEDBACK = 318, RB_FILE_FORMAT = 319, RB_NAME = 321, + RB_PLAYTIME = 3114, // Select ROM SELECT_ROM_DIR = 320, diff --git a/Source/Project64-core/Multilanguage/Language.cpp b/Source/Project64-core/Multilanguage/Language.cpp index 18c4d0f15..22b7faa0d 100644 --- a/Source/Project64-core/Multilanguage/Language.cpp +++ b/Source/Project64-core/Multilanguage/Language.cpp @@ -145,6 +145,7 @@ void CLanguage::LoadDefaultStrings(void) DEF_STR(RB_FORCE_FEEDBACK, "Force Feedback"); DEF_STR(RB_FILE_FORMAT, "File Format"); DEF_STR(RB_NAME, "Name"); + DEF_STR(RB_PLAYTIME, "Playtime"); // Select ROM DEF_STR(SELECT_ROM_DIR, "Select current ROM directory"); diff --git a/Source/Project64-core/RomList/RomList.cpp b/Source/Project64-core/RomList/RomList.cpp index ea2bbb2ef..6cfcb4d1a 100644 --- a/Source/Project64-core/RomList/RomList.cpp +++ b/Source/Project64-core/RomList/RomList.cpp @@ -44,6 +44,7 @@ CRomList::CRomList() : m_NotesIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Notes).c_str()); m_ExtIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_ExtInfo).c_str()); m_RomIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_RomDatabase).c_str()); + m_PlaytimeFile = std::make_unique(g_Settings->LoadStringVal(SupportFile_Playtime).c_str()); #ifdef _WIN32 m_ZipIniFile = new CIniFile(g_Settings->LoadStringVal(RomList_7zipCache).c_str()); #endif @@ -89,6 +90,16 @@ CRomList::~CRomList() WriteTrace(TraceRomList, TraceVerbose, "Done"); } +uint32_t CRomList::LoadPlaytime(const std::string & ApplicationName) +{ + return m_PlaytimeFile->GetNumber(ApplicationName.c_str(), "Playtime", 0); +} + +void CRomList::SavePlaytime(const std::string & ApplicationName, uint32_t Playtime) +{ + m_PlaytimeFile->SaveNumber(ApplicationName.c_str(), "Playtime", Playtime); +} + void CRomList::RefreshRomList(void) { if (m_RefreshThread.isRunning()) diff --git a/Source/Project64-core/RomList/RomList.h b/Source/Project64-core/RomList/RomList.h index 24e98841e..aeb856029 100644 --- a/Source/Project64-core/RomList/RomList.h +++ b/Source/Project64-core/RomList/RomList.h @@ -1,10 +1,13 @@ #pragma once + #include #include #include #include #include #include +#include +#include class CRomList { @@ -51,6 +54,9 @@ public: void RefreshRomList(void); void LoadRomList(void); + uint32_t LoadPlaytime(const std::string & ApplicationName); + void SavePlaytime(const std::string & ApplicationName, uint32_t Playtime); + protected: typedef std::vector ROMINFO_LIST; @@ -87,6 +93,7 @@ private: CIniFile * m_NotesIniFile; CIniFile * m_ExtIniFile; CIniFile * m_RomIniFile; + std::unique_ptr m_PlaytimeFile; #ifdef _WIN32 CIniFile * m_ZipIniFile; #endif diff --git a/Source/Project64-core/Settings.cpp b/Source/Project64-core/Settings.cpp index 98603325d..392cd9d58 100644 --- a/Source/Project64-core/Settings.cpp +++ b/Source/Project64-core/Settings.cpp @@ -80,6 +80,8 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory) AddHandler(Cmd_ComboDiskFile, new CSettingTypeTempString("")); // Support files + AddHandler(SupportFile_Playtime, new CSettingTypeApplicationPath("Settings", "Playtime", SupportFile_PlaytimeDefault)); + AddHandler(SupportFile_PlaytimeDefault, new CSettingTypeRelativePath("Config", "Playtime.rdn")); AddHandler(SupportFile_SettingsDirectory, new CSettingTypeTempString("")); AddHandler(SupportFile_Settings, new CSettingTypeApplicationPath("Settings", "ConfigFile", SupportFile_SettingsDefault)); AddHandler(SupportFile_SettingsDefault, new CSettingTypeRelativePath("Config", "Project64.cfg")); diff --git a/Source/Project64-core/Settings/SettingsID.h b/Source/Project64-core/Settings/SettingsID.h index cee4c49bc..4f8b32076 100644 --- a/Source/Project64-core/Settings/SettingsID.h +++ b/Source/Project64-core/Settings/SettingsID.h @@ -18,6 +18,8 @@ enum SettingID Cmd_ShowHelp, // Support files + SupportFile_Playtime, + SupportFile_PlaytimeDefault, SupportFile_SettingsDirectory, SupportFile_Settings, SupportFile_SettingsDefault, diff --git a/Source/Project64/UserInterface/MainWindow.cpp b/Source/Project64/UserInterface/MainWindow.cpp index 2020514f0..e1c8e09ee 100644 --- a/Source/Project64/UserInterface/MainWindow.cpp +++ b/Source/Project64/UserInterface/MainWindow.cpp @@ -227,10 +227,19 @@ void CMainGui::GamePaused(CMainGui * Gui) Gui->RefreshMenu(); } +void CMainGui::SavePlaytime() +{ + auto Now = std::chrono::steady_clock::now(); + uint32_t Elapsed = std::chrono::duration_cast(Now - m_CurrentPlaytime).count(); + auto PastPlaytime = CRomList::LoadPlaytime(g_Settings->LoadStringVal(Rdb_GoodName)); + CRomList::SavePlaytime(g_Settings->LoadStringVal(Rdb_GoodName), PastPlaytime + Elapsed); +} + void CMainGui::GameCpuRunning(CMainGui * Gui) { if (g_Settings->LoadBool(GameRunning_CPU_Running)) { + Gui->m_CurrentPlaytime = std::chrono::steady_clock::now(); Gui->MakeWindowOnTop(UISettingsLoadBool(UserInterface_AlwaysOnTop)); Gui->HideRomList(); if (UISettingsLoadBool(Setting_AutoFullscreen)) @@ -251,6 +260,7 @@ void CMainGui::GameCpuRunning(CMainGui * Gui) } else { + Gui->SavePlaytime(); if (Gui->m_CheatsUI.m_hWnd != nullptr) { Gui->m_CheatsUI.SendMessage(WM_COMMAND, MAKELONG(IDCANCEL, 0)); diff --git a/Source/Project64/UserInterface/MainWindow.h b/Source/Project64/UserInterface/MainWindow.h index a048ee8aa..ce95936e0 100644 --- a/Source/Project64/UserInterface/MainWindow.h +++ b/Source/Project64/UserInterface/MainWindow.h @@ -7,6 +7,7 @@ #include #include #include +#include class CGfxPlugin; // Plugin that controls the rendering class CAudioPlugin; // Plugin for audio, need the hwnd @@ -119,6 +120,7 @@ private: void AddRecentRom(const char * ImagePath); void SetWindowCaption(const wchar_t * Caption); void ShowRomBrowser(void); + void SavePlaytime(void); static LRESULT CALLBACK MainGui_Proc(HWND, DWORD, DWORD, DWORD); @@ -156,4 +158,6 @@ private: bool m_SaveRomBrowserPos; LONG m_SaveRomBrowserTop; LONG m_SaveRomBrowserLeft; + + std::chrono::steady_clock::time_point m_CurrentPlaytime; }; diff --git a/Source/Project64/UserInterface/RomBrowser.cpp b/Source/Project64/UserInterface/RomBrowser.cpp index 9462ef842..427a80017 100644 --- a/Source/Project64/UserInterface/RomBrowser.cpp +++ b/Source/Project64/UserInterface/RomBrowser.cpp @@ -59,6 +59,7 @@ void CRomBrowser::GetFieldInfo(ROMBROWSER_FIELDS_LIST & Fields, bool UseDefault AddField(Fields, "Players", -1, RB_Players, 100, RB_PLAYERS, UseDefault); AddField(Fields, "Force Feedback", -1, RB_ForceFeedback, 100, RB_FORCE_FEEDBACK, UseDefault); AddField(Fields, "File Format", -1, RB_FileFormat, 100, RB_FILE_FORMAT, UseDefault); + AddField(Fields, "Playtime", -1, RB_Playtime, 200, RB_PLAYTIME, UseDefault); } int32_t CRomBrowser::CalcSortPosition(uint32_t lParam) @@ -845,6 +846,12 @@ void CRomBrowser::RomList_GetDispInfo(uint32_t pnmh) default: swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"Unknown (%X)", pRomInfo->FileFormat); break; } break; + case RB_Playtime: + { + auto Playtime = LoadPlaytime(stdstr(pRomInfo->GoodName)); + swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"%02d:%02d:%02d", Playtime / 3600, (Playtime / 60) % 60, Playtime % 60); + break; + } default: wcsncpy(lpdi->item.pszText, L" ", lpdi->item.cchTextMax); } if (lpdi->item.pszText == nullptr || wcslen(lpdi->item.pszText) == 0) diff --git a/Source/Project64/UserInterface/RomBrowser.h b/Source/Project64/UserInterface/RomBrowser.h index b3f34996d..04badd30d 100644 --- a/Source/Project64/UserInterface/RomBrowser.h +++ b/Source/Project64/UserInterface/RomBrowser.h @@ -146,6 +146,7 @@ private: RB_Players = 18, RB_ForceFeedback = 19, RB_FileFormat = 20, + RB_Playtime = 21, }; enum From a1c465baafbaa998572e6715ee5e3d49f1b23eb4 Mon Sep 17 00:00:00 2001 From: Daniel Simpkins Date: Sun, 22 Jan 2023 11:14:04 -0500 Subject: [PATCH 2/2] Use rom hash for playtime identifier. Fixed issue with double counting time when switching to fullscreen mode. --- Source/Project64-core/RomList/RomList.cpp | 12 ++++++++---- Source/Project64-core/RomList/RomList.h | 4 ++-- Source/Project64/UserInterface/MainWindow.cpp | 13 ++++++++----- Source/Project64/UserInterface/MainWindow.h | 2 +- Source/Project64/UserInterface/RomBrowser.cpp | 3 ++- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Source/Project64-core/RomList/RomList.cpp b/Source/Project64-core/RomList/RomList.cpp index 6cfcb4d1a..b98154c08 100644 --- a/Source/Project64-core/RomList/RomList.cpp +++ b/Source/Project64-core/RomList/RomList.cpp @@ -90,14 +90,18 @@ CRomList::~CRomList() WriteTrace(TraceRomList, TraceVerbose, "Done"); } -uint32_t CRomList::LoadPlaytime(const std::string & ApplicationName) +uint32_t CRomList::LoadPlaytime(const std::string & RomIniKey) { - return m_PlaytimeFile->GetNumber(ApplicationName.c_str(), "Playtime", 0); + return m_PlaytimeFile->GetNumber(RomIniKey.c_str(), "Playtime", 0); } -void CRomList::SavePlaytime(const std::string & ApplicationName, uint32_t Playtime) +void CRomList::SavePlaytime(uint32_t ElapsedPlaytime) { - m_PlaytimeFile->SaveNumber(ApplicationName.c_str(), "Playtime", Playtime); + auto RomIniKey = g_Settings->LoadStringVal(Game_IniKey); + auto CurrentPlaytime = LoadPlaytime(RomIniKey); + auto RomGoodName = g_Settings->LoadStringVal(Rdb_GoodName); + m_PlaytimeFile->SaveString(RomIniKey.c_str(), "Name", RomGoodName.c_str()); + m_PlaytimeFile->SaveNumber(RomIniKey.c_str(), "Playtime", CurrentPlaytime + ElapsedPlaytime); } void CRomList::RefreshRomList(void) diff --git a/Source/Project64-core/RomList/RomList.h b/Source/Project64-core/RomList/RomList.h index aeb856029..82764af1d 100644 --- a/Source/Project64-core/RomList/RomList.h +++ b/Source/Project64-core/RomList/RomList.h @@ -54,8 +54,8 @@ public: void RefreshRomList(void); void LoadRomList(void); - uint32_t LoadPlaytime(const std::string & ApplicationName); - void SavePlaytime(const std::string & ApplicationName, uint32_t Playtime); + uint32_t LoadPlaytime(const std::string & RomIniKey); + void SavePlaytime(uint32_t ElapsedPlaytime); protected: typedef std::vector ROMINFO_LIST; diff --git a/Source/Project64/UserInterface/MainWindow.cpp b/Source/Project64/UserInterface/MainWindow.cpp index e1c8e09ee..0a7726558 100644 --- a/Source/Project64/UserInterface/MainWindow.cpp +++ b/Source/Project64/UserInterface/MainWindow.cpp @@ -229,17 +229,20 @@ void CMainGui::GamePaused(CMainGui * Gui) void CMainGui::SavePlaytime() { - auto Now = std::chrono::steady_clock::now(); - uint32_t Elapsed = std::chrono::duration_cast(Now - m_CurrentPlaytime).count(); - auto PastPlaytime = CRomList::LoadPlaytime(g_Settings->LoadStringVal(Rdb_GoodName)); - CRomList::SavePlaytime(g_Settings->LoadStringVal(Rdb_GoodName), PastPlaytime + Elapsed); + if (m_CurrentPlaytime.second) + { + auto Now = std::chrono::steady_clock::now(); + auto ElapsedPlaytime = std::chrono::duration_cast(Now - m_CurrentPlaytime.first).count(); + CRomList::SavePlaytime(static_cast(ElapsedPlaytime)); + m_CurrentPlaytime.second = false; + } } void CMainGui::GameCpuRunning(CMainGui * Gui) { if (g_Settings->LoadBool(GameRunning_CPU_Running)) { - Gui->m_CurrentPlaytime = std::chrono::steady_clock::now(); + Gui->m_CurrentPlaytime = {std::chrono::steady_clock::now(), true}; Gui->MakeWindowOnTop(UISettingsLoadBool(UserInterface_AlwaysOnTop)); Gui->HideRomList(); if (UISettingsLoadBool(Setting_AutoFullscreen)) diff --git a/Source/Project64/UserInterface/MainWindow.h b/Source/Project64/UserInterface/MainWindow.h index ce95936e0..3fdf571f0 100644 --- a/Source/Project64/UserInterface/MainWindow.h +++ b/Source/Project64/UserInterface/MainWindow.h @@ -159,5 +159,5 @@ private: LONG m_SaveRomBrowserTop; LONG m_SaveRomBrowserLeft; - std::chrono::steady_clock::time_point m_CurrentPlaytime; + std::pair m_CurrentPlaytime; }; diff --git a/Source/Project64/UserInterface/RomBrowser.cpp b/Source/Project64/UserInterface/RomBrowser.cpp index 427a80017..9c8f1263e 100644 --- a/Source/Project64/UserInterface/RomBrowser.cpp +++ b/Source/Project64/UserInterface/RomBrowser.cpp @@ -848,7 +848,8 @@ void CRomBrowser::RomList_GetDispInfo(uint32_t pnmh) break; case RB_Playtime: { - auto Playtime = LoadPlaytime(stdstr(pRomInfo->GoodName)); + auto RomIdent = stdstr_f("%08X-%08X-C:%X", pRomInfo->CRC1, pRomInfo->CRC2, pRomInfo->Country); + auto Playtime = LoadPlaytime(RomIdent); swprintf(lpdi->item.pszText, lpdi->item.cchTextMax / sizeof(wchar_t), L"%02d:%02d:%02d", Playtime / 3600, (Playtime / 60) % 60, Playtime % 60); break; }