Merge pull request #14041 from unknownbrackets/ui-crc

UI: Add button to show CRC on feedback screen
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2021-02-17 09:52:51 +01:00
commit 8f0d7cdf57
10 files changed
+103 -10

No files matched your search

+3 -1
View File
@@ -50,11 +50,13 @@ BlockDevice *constructBlockDevice(FileLoader *fileLoader) {
return new FileBlockDevice(fileLoader);
}
u32 BlockDevice::CalculateCRC() {
u32 BlockDevice::CalculateCRC(volatile bool *cancel) {
u32 crc = crc32(0, Z_NULL, 0);
u8 block[2048];
for (u32 i = 0; i < GetNumBlocks(); ++i) {
if (cancel && *cancel)
return 0;
if (!ReadBlock(i, block, true)) {
ERROR_LOG(FILESYS, "Failed to read block for CRC");
return 0;
+1 -1
View File
@@ -47,7 +47,7 @@ public:
virtual u32 GetNumBlocks() = 0;
virtual bool IsDisc() = 0;
u32 CalculateCRC();
u32 CalculateCRC(volatile bool *cancel = nullptr);
void NotifyReadError();
protected:
+29 -5
View File
@@ -102,6 +102,8 @@ namespace Reporting
static std::condition_variable crcCond;
static std::string crcFilename;
static std::map<std::string, u32> crcResults;
static volatile bool crcPending = false;
static volatile bool crcCancel = false;
static std::thread crcThread;
static int CalculateCRCThread() {
@@ -113,7 +115,7 @@ namespace Reporting
u32 crc = 0;
if (blockDevice) {
crc = blockDevice->CalculateCRC();
crc = blockDevice->CalculateCRC(&crcCancel);
}
delete blockDevice;
@@ -121,6 +123,7 @@ namespace Reporting
std::lock_guard<std::mutex> guard(crcLock);
crcResults[crcFilename] = crc;
crcPending = false;
crcCond.notify_one();
return 0;
@@ -136,18 +139,18 @@ namespace Reporting
return;
}
if (crcFilename == gamePath) {
if (crcPending) {
// Already in process.
return;
}
crcFilename = gamePath;
crcPending = true;
crcCancel = false;
crcThread = std::thread(CalculateCRCThread);
}
bool HasCRC(const std::string &gamePath) {
QueueCRC(gamePath);
std::lock_guard<std::mutex> guard(crcLock);
return crcResults.find(gamePath) != crcResults.end();
}
@@ -167,6 +170,26 @@ namespace Reporting
return it->second;
}
static uint32_t RetrieveCRCUnlessPowerSaving(const std::string &gamePath) {
// It's okay to use it if we have it already.
if (Core_GetPowerSaving() && !HasCRC(gamePath)) {
return 0;
}
return RetrieveCRC(gamePath);
}
static void PurgeCRC() {
std::unique_lock<std::mutex> guard(crcLock);
crcCancel = true;
while (crcPending) {
crcCond.wait(guard);
}
if (crcThread.joinable())
crcThread.join();
}
// Returns the full host (e.g. report.ppsspp.org:80.)
std::string ServerHost()
{
@@ -325,6 +348,7 @@ namespace Reporting
compatThread.join();
if (messageThread.joinable())
messageThread.join();
PurgeCRC();
// Just so it can be enabled in the menu again.
Init();
@@ -472,7 +496,7 @@ namespace Reporting
postdata.Add("graphics", StringFromFormat("%d", payload.int1));
postdata.Add("speed", StringFromFormat("%d", payload.int2));
postdata.Add("gameplay", StringFromFormat("%d", payload.int3));
postdata.Add("crc", StringFromFormat("%08x", Core_GetPowerSaving() ? 0 : RetrieveCRC(PSP_CoreParameter().fileToStart)));
postdata.Add("crc", StringFromFormat("%08x", RetrieveCRCUnlessPowerSaving(PSP_CoreParameter().fileToStart)));
postdata.Add("suggestions", payload.string1 != "perfect" && payload.string1 != "playable" ? "1" : "0");
AddScreenshotData(postdata, payload.string2);
payload.string1.clear();
+4 -1
View File
@@ -87,7 +87,10 @@ namespace Reporting
// Get the latest compatibility result. Only valid when GetStatus() is not BUSY.
std::vector<std::string> CompatibilitySuggestions();
// Queues game for CRC hash if needed, and returns true if the hash is available.
// Queues game for CRC hash if needed.
void QueueCRC(const std::string &gamePath);
// Returns true if the hash is available, does not queue if not.
bool HasCRC(const std::string &gamePath);
// Blocks until the CRC hash is available for game, and returns it.
+10 -1
View File
@@ -1657,8 +1657,11 @@ void FramebufferManagerCommon::ApplyClearToMemory(int x1, int y1, int x2, int y2
return;
}
}
if (!Memory::IsValidAddress(gstate.getFrameBufAddress())) {
return;
}
u8 *addr = Memory::GetPointer(gstate.getFrameBufAddress());
u8 *addr = Memory::GetPointerUnchecked(gstate.getFrameBufAddress());
const int bpp = gstate.FrameBufFormat() == GE_FORMAT_8888 ? 4 : 2;
u32 clearBits = clearColor;
@@ -1988,6 +1991,8 @@ bool FramebufferManagerCommon::GetFramebuffer(u32 fb_address, int fb_stride, GEB
}
if (!vfb) {
if (!Memory::IsValidAddress(fb_address))
return false;
// If there's no vfb and we're drawing there, must be memory?
buffer = GPUDebugBuffer(Memory::GetPointer(fb_address), fb_stride, 512, format);
return true;
@@ -2043,6 +2048,8 @@ bool FramebufferManagerCommon::GetDepthbuffer(u32 fb_address, int fb_stride, u32
}
if (!vfb) {
if (!Memory::IsValidAddress(z_address))
return false;
// If there's no vfb and we're drawing there, must be memory?
buffer = GPUDebugBuffer(Memory::GetPointer(z_address), z_stride, 512, GPU_DBG_FORMAT_16BIT);
return true;
@@ -2078,6 +2085,8 @@ bool FramebufferManagerCommon::GetStencilbuffer(u32 fb_address, int fb_stride, G
}
if (!vfb) {
if (!Memory::IsValidAddress(fb_address))
return false;
// If there's no vfb and we're drawing there, must be memory?
// TODO: Actually get the stencil.
buffer = GPUDebugBuffer(Memory::GetPointer(fb_address), fb_stride, 512, GPU_DBG_FORMAT_8888);
+2
View File
@@ -464,6 +464,8 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
}
if (!vfb) {
if (!Memory::IsValidAddress(fb_address))
return false;
// If there's no vfb and we're drawing there, must be memory?
buffer = GPUDebugBuffer(Memory::GetPointer(fb_address), fb_stride, 512, fb_format);
return true;
+13
View File
@@ -27,10 +27,12 @@
#include "Common/Data/Text/I18n.h"
#include "Common/Data/Encoding/Utf8.h"
#include "Common/File/FileUtil.h"
#include "Common/StringUtils.h"
#include "Common/System/System.h"
#include "Common/System/NativeApp.h"
#include "Core/Host.h"
#include "Core/Config.h"
#include "Core/Reporting.h"
#include "Core/System.h"
#include "UI/CwCheatScreen.h"
#include "UI/EmuScreen.h"
@@ -92,12 +94,16 @@ void GameScreen::CreateViews() {
tvInstallDataSize_->SetVisibility(V_GONE);
tvRegion_ = infoLayout->Add(new TextView("", ALIGN_LEFT, true, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
tvRegion_->SetShadow(true);
tvCRC_ = infoLayout->Add(new TextView("", ALIGN_LEFT, true, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
tvCRC_->SetShadow(true);
tvCRC_->SetVisibility(Reporting::HasCRC(gamePath_) ? V_VISIBLE : V_GONE);
} else {
tvTitle_ = nullptr;
tvGameSize_ = nullptr;
tvSaveDataSize_ = nullptr;
tvInstallDataSize_ = nullptr;
tvRegion_ = nullptr;
tvCRC_ = nullptr;
}
ViewGroup *rightColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(300, FILL_PARENT, actionMenuMargins));
@@ -234,6 +240,13 @@ void GameScreen::render() {
}
}
if (tvCRC_ && Reporting::HasCRC(gamePath_)) {
auto rp = GetI18NCategory("Reporting");
std::string crc = StringFromFormat("%08X", Reporting::RetrieveCRC(gamePath_));
tvCRC_->SetText(ReplaceAll(rp->T("FeedbackCRCValue", "Disc CRC: [VALUE]"), "[VALUE]", crc));
tvCRC_->SetVisibility(UI::V_VISIBLE);
}
if (!info->id.empty()) {
btnGameSettings_->SetVisibility(info->hasConfig ? UI::V_VISIBLE : UI::V_GONE);
btnDeleteGameConfig_->SetVisibility(info->hasConfig ? UI::V_VISIBLE : UI::V_GONE);
+1
View File
@@ -67,6 +67,7 @@ private:
UI::TextView *tvSaveDataSize_;
UI::TextView *tvInstallDataSize_;
UI::TextView *tvRegion_;
UI::TextView *tvCRC_;
UI::Choice *btnGameSettings_;
UI::Choice *btnCreateGameConfig_;
+35 -1
View File
@@ -195,6 +195,7 @@ void ReportScreen::update() {
}
}
UIDialogScreenWithGameBackground::update();
UpdateCRCInfo();
}
void ReportScreen::resized() {
@@ -269,7 +270,7 @@ void ReportScreen::CreateViews() {
}
#ifdef MOBILE_DEVICE
if (!Core_GetPowerSaving()) {
if (!Core_GetPowerSaving() && !Reporting::HasCRC(gamePath_)) {
auto crcWarning = new TextView(rp->T("FeedbackIncludeCRC", "Note: Battery will be used to send a disc CRC"), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5)));
crcWarning->SetShadow(true);
crcWarning->SetEnabledPtr(&enableReporting_);
@@ -277,6 +278,11 @@ void ReportScreen::CreateViews() {
}
#endif
crcInfo_ = new TextView("", FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5)));
crcInfo_->SetShadow(true);
crcInfo_->SetVisibility(V_GONE);
leftColumnItems->Add(crcInfo_);
if (tookScreenshot_ && !screenshotFilename_.empty()) {
leftColumnItems->Add(new CheckBox(&includeScreenshot_, rp->T("FeedbackIncludeScreen", "Include a screenshot")))->SetEnabledPtr(&enableReporting_);
screenshot_ = leftColumnItems->Add(new AsyncImageFileView(screenshotFilename_, IS_KEEP_ASPECT, nullptr, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, Margins(12, 0))));
@@ -300,6 +306,8 @@ void ReportScreen::CreateViews() {
rightColumnItems->SetSpacing(0.0f);
rightColumnItems->Add(new Choice(rp->T("Open Browser")))->OnClick.Handle(this, &ReportScreen::HandleBrowser);
showCrcButton_ = new Choice(rp->T("Show disc CRC"));
rightColumnItems->Add(showCrcButton_)->OnClick.Handle(this, &ReportScreen::HandleShowCRC);
submit_ = new Choice(rp->T("Submit Feedback"));
rightColumnItems->Add(submit_)->OnClick.Handle(this, &ReportScreen::HandleSubmit);
UpdateSubmit();
@@ -314,12 +322,32 @@ void ReportScreen::CreateViews() {
leftColumn->Add(leftColumnItems);
rightColumn->Add(rightColumnItems);
UpdateCRCInfo();
}
void ReportScreen::UpdateSubmit() {
submit_->SetEnabled(enableReporting_ && overall_ != ReportingOverallScore::INVALID && graphics_ >= 0 && speed_ >= 0 && gameplay_ >= 0);
}
void ReportScreen::UpdateCRCInfo() {
auto rp = GetI18NCategory("Reporting");
std::string updated;
if (Reporting::HasCRC(gamePath_)) {
std::string crc = StringFromFormat("%08X", Reporting::RetrieveCRC(gamePath_));
updated = ReplaceAll(rp->T("FeedbackCRCValue", "Disc CRC: [VALUE]"), "[VALUE]", crc);
} else if (showCRC_) {
updated = rp->T("FeedbackCRCCalculating", "Disc CRC: Calculating...");
}
if (!updated.empty()) {
crcInfo_->SetText(updated);
crcInfo_->SetVisibility(V_VISIBLE);
showCrcButton_->SetEnabled(false);
}
}
void ReportScreen::UpdateOverallDescription() {
auto rp = GetI18NCategory("Reporting");
const char *desc;
@@ -366,6 +394,12 @@ EventReturn ReportScreen::HandleBrowser(EventParams &e) {
return EVENT_DONE;
}
EventReturn ReportScreen::HandleShowCRC(EventParams &e) {
Reporting::QueueCRC(gamePath_);
showCRC_ = true;
return EVENT_DONE;
}
ReportFinishScreen::ReportFinishScreen(const std::string &gamePath, ReportingOverallScore score)
: UIDialogScreenWithGameBackground(gamePath), score_(score) {
}
+5
View File
@@ -42,17 +42,21 @@ protected:
void resized() override;
void CreateViews() override;
void UpdateSubmit();
void UpdateCRCInfo();
void UpdateOverallDescription();
UI::EventReturn HandleChoice(UI::EventParams &e);
UI::EventReturn HandleSubmit(UI::EventParams &e);
UI::EventReturn HandleBrowser(UI::EventParams &e);
UI::EventReturn HandleShowCRC(UI::EventParams &e);
UI::EventReturn HandleReportingChange(UI::EventParams &e);
UI::Choice *submit_ = nullptr;
UI::View *screenshot_ = nullptr;
UI::TextView *reportingNotice_ = nullptr;
UI::TextView *overallDescription_ = nullptr;
UI::TextView *crcInfo_ = nullptr;
UI::Choice *showCrcButton_ = nullptr;
std::string screenshotFilename_;
ReportingOverallScore overall_ = ReportingOverallScore::INVALID;
@@ -63,6 +67,7 @@ protected:
bool ratingEnabled_;
bool tookScreenshot_ = false;
bool includeScreenshot_ = true;
bool showCRC_ = false;
};
class ReportFinishScreen : public UIDialogScreenWithGameBackground {