From 784e803f98eb74392ed7faf8955df7d88c9fffa2 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sat, 30 Jan 2021 07:03:52 +0800 Subject: [PATCH 1/2] Add CRC32 calc Fix #13964 Thanks @unknownbrackets --- UI/GameScreen.cpp | 29 +++++++++++++++++++++++++++++ UI/GameScreen.h | 4 ++++ 2 files changed, 33 insertions(+) diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index 697a2145c9..61d72a9fd7 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -40,6 +40,7 @@ #include "UI/MiscScreens.h" #include "UI/MainScreen.h" #include "UI/BackgroundAudio.h" +#include "Core/Reporting.h" GameScreen::GameScreen(const std::string &gamePath) : UIDialogScreenWithGameBackground(gamePath) { g_BackgroundAudio.SetGame(gamePath); @@ -48,6 +49,27 @@ GameScreen::GameScreen(const std::string &gamePath) : UIDialogScreenWithGameBack GameScreen::~GameScreen() { } +template std::string int2hexstr(I w, size_t hex_len = sizeof(I) << 1) { + static const char* digits = "0123456789ABCDEF"; + std::string rc(hex_len, '0'); + for (size_t i = 0, j = (hex_len - 1) * 4; i < hex_len; ++i, j -= 4) + rc[i] = digits[(w >> j) & 0x0f]; + return rc; +} + +void GameScreen::update() { + UIScreen::update(); + + // Has the user requested a CRC32? + if (CRC32string == "...") { + // Wait until the CRC32 is ready. It might take time on some devices. + if (Reporting::HasCRC(gamePath_)) { + uint32_t crcvalue = Reporting::RetrieveCRC(gamePath_); + CRC32string = int2hexstr(crcvalue); + } + } +} + void GameScreen::CreateViews() { std::shared_ptr info = g_gameInfoCache->GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE); @@ -143,6 +165,7 @@ void GameScreen::CreateViews() { btnSetBackground_ = rightColumnItems->Add(new Choice(ga->T("Use UI background"))); btnSetBackground_->OnClick.Handle(this, &GameScreen::OnSetBackground); btnSetBackground_->SetVisibility(V_GONE); + rightColumnItems->Add(new ChoiceWithValueDisplay(&CRC32string, ga->T("CRC32 CALC"), (const char*)nullptr))->OnClick.Handle(this, &GameScreen::OnDoCRC32); } UI::Choice *GameScreen::AddOtherChoice(UI::Choice *choice) { @@ -265,6 +288,12 @@ UI::EventReturn GameScreen::OnCwCheat(UI::EventParams &e) { return UI::EVENT_DONE; } +UI::EventReturn GameScreen::OnDoCRC32(UI::EventParams& e) { + CRC32string = "..."; + return UI::EVENT_DONE; +} + + UI::EventReturn GameScreen::OnSwitchBack(UI::EventParams &e) { TriggerFinish(DR_OK); return UI::EVENT_DONE; diff --git a/UI/GameScreen.h b/UI/GameScreen.h index 2e7fa3f596..ca9c0793bf 100644 --- a/UI/GameScreen.h +++ b/UI/GameScreen.h @@ -33,6 +33,8 @@ public: GameScreen(const std::string &gamePath); ~GameScreen(); + void update() override; + void render() override; std::string tag() const override { return "game"; } @@ -43,6 +45,7 @@ protected: void CallbackDeleteSaveData(bool yes); void CallbackDeleteGame(bool yes); bool isRecentGame(const std::string &gamePath); + std::string CRC32string = ""; private: UI::Choice *AddOtherChoice(UI::Choice *choice); @@ -60,6 +63,7 @@ private: UI::EventReturn OnDeleteConfig(UI::EventParams &e); UI::EventReturn OnCwCheat(UI::EventParams &e); UI::EventReturn OnSetBackground(UI::EventParams &e); + UI::EventReturn OnDoCRC32(UI::EventParams& e); // As we load metadata in the background, we need to be able to update these after the fact. UI::TextView *tvTitle_; From a74e1a422d2d7b93707a9ded7baa9a5d5a8b1989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 21 Aug 2021 20:58:25 +0200 Subject: [PATCH 2/2] GameScreen: Minor logic cleanup, remove Calculate CRC button when not needed. --- Core/MIPS/fake/FakeJit.h | 140 +++++++++++++++++++-------------------- Core/Reporting.cpp | 17 ++++- Core/Reporting.h | 2 + UI/GameScreen.cpp | 16 ++++- UI/GameScreen.h | 25 ++++--- 5 files changed, 115 insertions(+), 85 deletions(-) diff --git a/Core/MIPS/fake/FakeJit.h b/Core/MIPS/fake/FakeJit.h index 8c3403d566..42aa342c67 100644 --- a/Core/MIPS/fake/FakeJit.h +++ b/Core/MIPS/fake/FakeJit.h @@ -35,16 +35,16 @@ class FakeJit : public FakeGen::FakeXCodeBlock, public JitInterface, public MIPS public: FakeJit(MIPSState *mipsState); - void DoState(PointerWrap &p); + void DoState(PointerWrap &p) override; static void DoDummyState(PointerWrap &p); const JitOptions &GetJitOptions() { return jo; } - void Comp_Generic(MIPSOpcode op); + void Comp_Generic(MIPSOpcode op) override; - void RunLoopUntil(u64 globalticks); + void RunLoopUntil(u64 globalticks) override; - void Compile(u32 em_address); // Compiles a block at current MIPS PC + void Compile(u32 em_address) override; // Compiles a block at current MIPS PC const u8 *DoJit(u32 em_address, JitBlock *b); const u8 *GetCrashHandler() const override { return nullptr; } @@ -55,80 +55,80 @@ public: void EatInstruction(MIPSOpcode op); void AddContinuedBlock(u32 dest); - void Comp_RunBlock(MIPSOpcode op); - void Comp_ReplacementFunc(MIPSOpcode op); + void Comp_RunBlock(MIPSOpcode op) override; + void Comp_ReplacementFunc(MIPSOpcode op) override; // Ops - void Comp_ITypeMem(MIPSOpcode op) {} - void Comp_Cache(MIPSOpcode op) {} + void Comp_ITypeMem(MIPSOpcode op) override {} + void Comp_Cache(MIPSOpcode op) override {} - void Comp_RelBranch(MIPSOpcode op) {} - void Comp_RelBranchRI(MIPSOpcode op) {} - void Comp_FPUBranch(MIPSOpcode op) {} - void Comp_FPULS(MIPSOpcode op) {} - void Comp_FPUComp(MIPSOpcode op) {} - void Comp_Jump(MIPSOpcode op) {} - void Comp_JumpReg(MIPSOpcode op) {} - void Comp_Syscall(MIPSOpcode op) {} - void Comp_Break(MIPSOpcode op) {} + void Comp_RelBranch(MIPSOpcode op) override {} + void Comp_RelBranchRI(MIPSOpcode op) override {} + void Comp_FPUBranch(MIPSOpcode op) override {} + void Comp_FPULS(MIPSOpcode op) override {} + void Comp_FPUComp(MIPSOpcode op) override {} + void Comp_Jump(MIPSOpcode op) override {} + void Comp_JumpReg(MIPSOpcode op) override {} + void Comp_Syscall(MIPSOpcode op) override {} + void Comp_Break(MIPSOpcode op) override {} - void Comp_IType(MIPSOpcode op) {} - void Comp_RType2(MIPSOpcode op) {} - void Comp_RType3(MIPSOpcode op) {} - void Comp_ShiftType(MIPSOpcode op) {} - void Comp_Allegrex(MIPSOpcode op) {} - void Comp_Allegrex2(MIPSOpcode op) {} - void Comp_VBranch(MIPSOpcode op) {} - void Comp_MulDivType(MIPSOpcode op) {} - void Comp_Special3(MIPSOpcode op) {} + void Comp_IType(MIPSOpcode op) override {} + void Comp_RType2(MIPSOpcode op) override {} + void Comp_RType3(MIPSOpcode op) override {} + void Comp_ShiftType(MIPSOpcode op) override {} + void Comp_Allegrex(MIPSOpcode op) override {} + void Comp_Allegrex2(MIPSOpcode op) override {} + void Comp_VBranch(MIPSOpcode op) override {} + void Comp_MulDivType(MIPSOpcode op) override {} + void Comp_Special3(MIPSOpcode op) override {} - void Comp_FPU3op(MIPSOpcode op) {} - void Comp_FPU2op(MIPSOpcode op) {} - void Comp_mxc1(MIPSOpcode op) {} + void Comp_FPU3op(MIPSOpcode op) override {} + void Comp_FPU2op(MIPSOpcode op) override {} + void Comp_mxc1(MIPSOpcode op) override {} - void Comp_DoNothing(MIPSOpcode op) {} + void Comp_DoNothing(MIPSOpcode op) override {} - void Comp_SV(MIPSOpcode op) {} - void Comp_SVQ(MIPSOpcode op) {} - void Comp_VPFX(MIPSOpcode op) {} - void Comp_VVectorInit(MIPSOpcode op) {} - void Comp_VMatrixInit(MIPSOpcode op) {} - void Comp_VDot(MIPSOpcode op) {} - void Comp_VecDo3(MIPSOpcode op) {} - void Comp_VV2Op(MIPSOpcode op) {} - void Comp_Mftv(MIPSOpcode op) {} - void Comp_Vmfvc(MIPSOpcode op) {} - void Comp_Vmtvc(MIPSOpcode op) {} - void Comp_Vmmov(MIPSOpcode op) {} - void Comp_VScl(MIPSOpcode op) {} - void Comp_Vmmul(MIPSOpcode op) {} - void Comp_Vmscl(MIPSOpcode op) {} - void Comp_Vtfm(MIPSOpcode op) {} - void Comp_VHdp(MIPSOpcode op) {} - void Comp_VCrs(MIPSOpcode op) {} - void Comp_VDet(MIPSOpcode op) {} - void Comp_Vi2x(MIPSOpcode op) {} - void Comp_Vx2i(MIPSOpcode op) {} - void Comp_Vf2i(MIPSOpcode op) {} - void Comp_Vi2f(MIPSOpcode op) {} - void Comp_Vh2f(MIPSOpcode op) {} - void Comp_Vcst(MIPSOpcode op) {} - void Comp_Vhoriz(MIPSOpcode op) {} - void Comp_VRot(MIPSOpcode op) {} - void Comp_VIdt(MIPSOpcode op) {} - void Comp_Vcmp(MIPSOpcode op) {} - void Comp_Vcmov(MIPSOpcode op) {} - void Comp_Viim(MIPSOpcode op) {} - void Comp_Vfim(MIPSOpcode op) {} - void Comp_VCrossQuat(MIPSOpcode op) {} - void Comp_Vsgn(MIPSOpcode op) {} - void Comp_Vocp(MIPSOpcode op) {} - void Comp_ColorConv(MIPSOpcode op) {} - void Comp_Vbfy(MIPSOpcode op) {} + void Comp_SV(MIPSOpcode op) override {} + void Comp_SVQ(MIPSOpcode op) override {} + void Comp_VPFX(MIPSOpcode op) override {} + void Comp_VVectorInit(MIPSOpcode op) override {} + void Comp_VMatrixInit(MIPSOpcode op) override {} + void Comp_VDot(MIPSOpcode op) override {} + void Comp_VecDo3(MIPSOpcode op) override {} + void Comp_VV2Op(MIPSOpcode op) override {} + void Comp_Mftv(MIPSOpcode op) override {} + void Comp_Vmfvc(MIPSOpcode op) override {} + void Comp_Vmtvc(MIPSOpcode op) override {} + void Comp_Vmmov(MIPSOpcode op) override {} + void Comp_VScl(MIPSOpcode op) override {} + void Comp_Vmmul(MIPSOpcode op) override {} + void Comp_Vmscl(MIPSOpcode op) override {} + void Comp_Vtfm(MIPSOpcode op) override {} + void Comp_VHdp(MIPSOpcode op) override {} + void Comp_VCrs(MIPSOpcode op) override {} + void Comp_VDet(MIPSOpcode op) override {} + void Comp_Vi2x(MIPSOpcode op) override {} + void Comp_Vx2i(MIPSOpcode op) override {} + void Comp_Vf2i(MIPSOpcode op) override {} + void Comp_Vi2f(MIPSOpcode op) override {} + void Comp_Vh2f(MIPSOpcode op) override {} + void Comp_Vcst(MIPSOpcode op) override {} + void Comp_Vhoriz(MIPSOpcode op) override {} + void Comp_VRot(MIPSOpcode op) override {} + void Comp_VIdt(MIPSOpcode op) override {} + void Comp_Vcmp(MIPSOpcode op) override {} + void Comp_Vcmov(MIPSOpcode op) override {} + void Comp_Viim(MIPSOpcode op) override {} + void Comp_Vfim(MIPSOpcode op) override {} + void Comp_VCrossQuat(MIPSOpcode op) override {} + void Comp_Vsgn(MIPSOpcode op) override {} + void Comp_Vocp(MIPSOpcode op) override {} + void Comp_ColorConv(MIPSOpcode op) override {} + void Comp_Vbfy(MIPSOpcode op) override {} - int Replace_fabsf() { return 0; } + int Replace_fabsf() override { return 0; } - JitBlockCache *GetBlockCache() { return &blocks; } + JitBlockCache *GetBlockCache() override { return &blocks; } JitBlockCacheDebugInterface *GetBlockCacheDebugInterface() override { return &blocks; } MIPSOpcode GetOriginalOp(MIPSOpcode op) override { return op; } @@ -147,7 +147,7 @@ public: void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override {} void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override {} - void EatPrefix() { js.EatPrefix(); } + void EatPrefix() override { js.EatPrefix(); } private: void GenerateFixedCode(); diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 49e9565564..c5bab7ac6e 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -138,9 +138,11 @@ namespace Reporting if (crcPending) { // Already in process. + INFO_LOG(SYSTEM, "CRC already pending"); return; } + INFO_LOG(SYSTEM, "Starting CRC calculation"); crcFilename = gamePath; crcPending = true; crcCancel = false; @@ -178,15 +180,24 @@ namespace Reporting static void PurgeCRC() { std::unique_lock guard(crcLock); - crcCancel = true; - while (crcPending) { - crcCond.wait(guard); + if (crcPending) { + INFO_LOG(SYSTEM, "Cancelling CRC calculation"); + crcCancel = true; + while (crcPending) { + crcCond.wait(guard); + } + } else { + INFO_LOG(SYSTEM, "no CRC pending"); } if (crcThread.joinable()) crcThread.join(); } + void CancelCRC() { + PurgeCRC(); + } + // Returns the full host (e.g. report.ppsspp.org:80.) std::string ServerHost() { diff --git a/Core/Reporting.h b/Core/Reporting.h index fb16689bf8..4971d4b489 100644 --- a/Core/Reporting.h +++ b/Core/Reporting.h @@ -63,6 +63,8 @@ namespace Reporting // Returns true if the hash is available, does not queue if not. bool HasCRC(const Path &gamePath); + void CancelCRC(); + // Blocks until the CRC hash is available for game, and returns it. // To avoid stalling, call HasCRC() in update() or similar and call this if it returns true. uint32_t RetrieveCRC(const Path &gamePath); diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index 567d06e2c4..02d2c57c25 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -49,6 +49,9 @@ GameScreen::GameScreen(const Path &gamePath) : UIDialogScreenWithGameBackground( } GameScreen::~GameScreen() { + if (CRC32string == "...") { + Reporting::CancelCRC(); + } } template std::string int2hexstr(I w, size_t hex_len = sizeof(I) << 1) { @@ -68,6 +71,9 @@ void GameScreen::update() { if (Reporting::HasCRC(gamePath_)) { uint32_t crcvalue = Reporting::RetrieveCRC(gamePath_); CRC32string = int2hexstr(crcvalue); + tvCRC_->SetVisibility(UI::V_VISIBLE); + tvCRC_->SetText(CRC32string); + btnCalcCRC_->SetVisibility(UI::V_GONE); } } } @@ -171,7 +177,13 @@ void GameScreen::CreateViews() { btnSetBackground_ = rightColumnItems->Add(new Choice(ga->T("Use UI background"))); btnSetBackground_->OnClick.Handle(this, &GameScreen::OnSetBackground); btnSetBackground_->SetVisibility(V_GONE); - rightColumnItems->Add(new ChoiceWithValueDisplay(&CRC32string, ga->T("CRC32 CALC"), (const char*)nullptr))->OnClick.Handle(this, &GameScreen::OnDoCRC32); + + if (!Reporting::HasCRC(gamePath_)) { + btnCalcCRC_ = rightColumnItems->Add(new ChoiceWithValueDisplay(&CRC32string, ga->T("Calculate CRC"), (const char*)nullptr)); + btnCalcCRC_->OnClick.Handle(this, &GameScreen::OnDoCRC32); + } else { + btnCalcCRC_ = nullptr; + } } UI::Choice *GameScreen::AddOtherChoice(UI::Choice *choice) { @@ -303,6 +315,8 @@ UI::EventReturn GameScreen::OnCwCheat(UI::EventParams &e) { UI::EventReturn GameScreen::OnDoCRC32(UI::EventParams& e) { CRC32string = "..."; + Reporting::QueueCRC(gamePath_); + btnCalcCRC_->SetEnabled(false); return UI::EVENT_DONE; } diff --git a/UI/GameScreen.h b/UI/GameScreen.h index 974ba8424d..1cae1f79f5 100644 --- a/UI/GameScreen.h +++ b/UI/GameScreen.h @@ -66,18 +66,21 @@ private: UI::EventReturn OnDoCRC32(UI::EventParams& e); // As we load metadata in the background, we need to be able to update these after the fact. - UI::TextView *tvTitle_; - UI::TextView *tvGameSize_; - UI::TextView *tvSaveDataSize_; - UI::TextView *tvInstallDataSize_; - UI::TextView *tvRegion_; - UI::TextView *tvCRC_; + UI::TextView *tvTitle_ = nullptr; + UI::TextView *tvGameSize_ = nullptr; + UI::TextView *tvSaveDataSize_ = nullptr; + UI::TextView *tvInstallDataSize_ = nullptr; + UI::TextView *tvRegion_ = nullptr; + UI::TextView *tvCRC_ = nullptr; + + UI::Choice *btnGameSettings_ = nullptr; + UI::Choice *btnCreateGameConfig_ = nullptr; + UI::Choice *btnDeleteGameConfig_ = nullptr; + UI::Choice *btnDeleteSaveData_ = nullptr; + UI::Choice *btnSetBackground_ = nullptr; + + UI::Choice *btnCalcCRC_ = nullptr; - UI::Choice *btnGameSettings_; - UI::Choice *btnCreateGameConfig_; - UI::Choice *btnDeleteGameConfig_; - UI::Choice *btnDeleteSaveData_; - UI::Choice *btnSetBackground_; std::vector otherChoices_; std::vector saveDirs; std::string CRC32string;