Merge pull request #5388 from unknownbrackets/reporting

Adjust reporting to track and send more things
This commit is contained in:
Henrik Rydgård 2014-02-10 09:48:20 +01:00
commit 25bf95fcf3
20 changed files with 768 additions and 631 deletions

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,8 @@ namespace http {
class Downloader;
}
struct UrlEncoder;
struct Config {
public:
Config();
@ -317,6 +319,8 @@ public:
void ResetControlLayout();
void GetReportingInfo(UrlEncoder &data);
private:
std::string iniFilename_;
std::string controllerIniFilename_;

View File

@ -133,6 +133,7 @@ void __KernelInit()
__HeapInit();
SaveState::Init(); // Must be after IO, as it may create a directory
Reporting::Init();
// "Internal" PSP libraries
__PPGeInit();

View File

@ -20,7 +20,9 @@
#include "Common/CPUDetect.h"
#include "Core/CoreTiming.h"
#include "Core/Config.h"
#include "Core/SaveState.h"
#include "Core/System.h"
#include "Core/FileSystems/MetaFileSystem.h"
#include "Core/HLE/sceDisplay.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/ELF/ParamSFO.h"
@ -35,6 +37,7 @@
#include "base/buffer.h"
#include "thread/thread.h"
#include <set>
#include <stdlib.h>
#include <cstdarg>
@ -48,6 +51,10 @@ namespace Reporting
static u32 spamProtectionCount = 0;
// Temporarily stores a reference to the hostname.
static std::string lastHostname;
// Keeps track of report-only-once identifiers.
static std::set<std::string> logOnceUsed;
// Keeps track of whether a harmful setting was ever used.
static bool everUnsupported = false;
enum RequestType
{
@ -189,26 +196,58 @@ namespace Reporting
#endif
}
int Process(int pos)
void Init()
{
Payload &payload = payloadBuffer[pos];
// New game, clean slate.
spamProtectionCount = 0;
logOnceUsed.clear();
everUnsupported = false;
}
std::string gpuPrimary, gpuFull;
if (gpu)
gpu->GetReportingInfo(gpuPrimary, gpuFull);
void UpdateConfig()
{
if (!IsSupported())
everUnsupported = true;
}
UrlEncoder postdata;
postdata.Add("version", PPSSPP_GIT_VERSION);
bool ShouldLogOnce(const char *identifier)
{
// True if it wasn't there already -> so yes, log.
return logOnceUsed.insert(identifier).second;
}
void AddGameInfo(UrlEncoder &postdata)
{
// TODO: Maybe ParamSFOData shouldn't include nulls in std::strings? Don't work to break savedata, though...
postdata.Add("game", StripTrailingNull(g_paramSFO.GetValueString("DISC_ID")) + "_" + StripTrailingNull(g_paramSFO.GetValueString("DISC_VERSION")));
postdata.Add("game_title", StripTrailingNull(g_paramSFO.GetValueString("TITLE")));
postdata.Add("sdkver", sceKernelGetCompiledSdkVersion());
}
void AddSystemInfo(UrlEncoder &postdata)
{
std::string gpuPrimary, gpuFull;
if (gpu)
gpu->GetReportingInfo(gpuPrimary, gpuFull);
postdata.Add("version", PPSSPP_GIT_VERSION);
postdata.Add("gpu", gpuPrimary);
postdata.Add("gpu_full", gpuFull);
postdata.Add("cpu", cpu_info.Summarize());
postdata.Add("platform", GetPlatformIdentifer());
postdata.Add("sdkver", sceKernelGetCompiledSdkVersion());
}
void AddConfigInfo(UrlEncoder &postdata)
{
postdata.Add("pixel_width", PSP_CoreParameter().pixelWidth);
postdata.Add("pixel_height", PSP_CoreParameter().pixelHeight);
g_Config.GetReportingInfo(postdata);
}
void AddGameplayInfo(UrlEncoder &postdata)
{
// Just to get an idea of how long they played.
postdata.Add("ticks", (const uint64_t)CoreTiming::GetTicks());
if (g_Config.iShowFPSCounter && g_Config.iShowFPSCounter < 4)
@ -219,7 +258,18 @@ namespace Reporting
postdata.Add("fps", fps);
}
// TODO: Settings, savestate/savedata status, some measure of speed/fps?
postdata.Add("savestate_used", SaveState::HasLoadedState());
}
int Process(int pos)
{
Payload &payload = payloadBuffer[pos];
UrlEncoder postdata;
AddSystemInfo(postdata);
AddGameInfo(postdata);
AddConfigInfo(postdata);
AddGameplayInfo(postdata);
switch (payload.type)
{
@ -239,15 +289,20 @@ namespace Reporting
bool IsSupported()
{
// Disabled when using certain hacks, because they make for poor reports.
// TODO: Numbers to avoid dependency on GLES code.
if (g_Config.iRenderingMode >= FBO_READFBOMEMORY_MIN)
return false;
// Some users run the exe from a zip or something, and don't have fonts.
// This breaks things, but let's not report it since it's confusing.
if (!pspFileSystem.GetFileInfo("flash0:/font").exists)
return false;
return true;
}
bool IsEnabled()
{
if (g_Config.sReportHost.empty() || !IsSupported())
if (g_Config.sReportHost.empty() || !IsSupported() || everUnsupported)
return false;
// Disabled by default for now.
if (g_Config.sReportHost.compare("default") == 0)

View File

@ -24,19 +24,25 @@
#define NOTICE_LOG_REPORT(t,...) { NOTICE_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); }
#define INFO_LOG_REPORT(t,...) { INFO_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); }
#define DEBUG_LOG_REPORT_ONCE(n,t,...) { static bool n = false; if (!n) { n = true; DEBUG_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } }
#define ERROR_LOG_REPORT_ONCE(n,t,...) { static bool n = false; if (!n) { n = true; ERROR_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } }
#define WARN_LOG_REPORT_ONCE(n,t,...) { static bool n = false; if (!n) { n = true; WARN_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } }
#define NOTICE_LOG_REPORT_ONCE(n,t,...) { static bool n = false; if (!n) { n = true; NOTICE_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } }
#define INFO_LOG_REPORT_ONCE(n,t,...) { static bool n = false; if (!n) { n = true; INFO_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } }
#define DEBUG_LOG_REPORT_ONCE(n,t,...) { if (Reporting::ShouldLogOnce(#n)) { DEBUG_LOG_REPORT(t, __VA_ARGS__); } }
#define ERROR_LOG_REPORT_ONCE(n,t,...) { if (Reporting::ShouldLogOnce(#n)) { ERROR_LOG_REPORT(t, __VA_ARGS__); } }
#define WARN_LOG_REPORT_ONCE(n,t,...) { if (Reporting::ShouldLogOnce(#n)) { WARN_LOG_REPORT(t, __VA_ARGS__); } }
#define NOTICE_LOG_REPORT_ONCE(n,t,...) { if (Reporting::ShouldLogOnce(#n)) { NOTICE_LOG_REPORT(t, __VA_ARGS__); } }
#define INFO_LOG_REPORT_ONCE(n,t,...) { if (Reporting::ShouldLogOnce(#n)) { INFO_LOG_REPORT(t, __VA_ARGS__); } }
#define ERROR_LOG_ONCE(n,t,...) { static bool n = false; if (!n) { n = true; ERROR_LOG(t, __VA_ARGS__); } }
#define WARN_LOG_ONCE(n,t,...) { static bool n = false; if (!n) { n = true; WARN_LOG(t, __VA_ARGS__); } }
#define NOTICE_LOG_ONCE(n,t,...) { static bool n = false; if (!n) { n = true; NOTICE_LOG(t, __VA_ARGS__); } }
#define INFO_LOG_ONCE(n,t,...) { static bool n = false; if (!n) { n = true; INFO_LOG(t, __VA_ARGS__); } }
#define ERROR_LOG_ONCE(n,t,...) { if (Reporting::ShouldLogOnce(#n)) { ERROR_LOG(t, __VA_ARGS__); } }
#define WARN_LOG_ONCE(n,t,...) { if (Reporting::ShouldLogOnce(#n)) { WARN_LOG(t, __VA_ARGS__); } }
#define NOTICE_LOG_ONCE(n,t,...) { if (Reporting::ShouldLogOnce(#n)) { NOTICE_LOG(t, __VA_ARGS__); } }
#define INFO_LOG_ONCE(n,t,...) { if (Reporting::ShouldLogOnce(#n)) { INFO_LOG(t, __VA_ARGS__); } }
namespace Reporting
{
// Should be called whenever a new game is loaded to forget things.
void Init();
// Should be called whenever the game configuration changes.
void UpdateConfig();
// Returns whether or not the reporting system is currently enabled.
bool IsEnabled();
@ -51,4 +57,7 @@ namespace Reporting
// Report a message string, using the format string as a key.
void ReportMessage(const char *message, ...);
// Returns true if that identifier has not been logged yet.
bool ShouldLogOnce(const char *identifier);
}

View File

@ -203,6 +203,7 @@ namespace SaveState
static bool needsProcess = false;
static std::vector<Operation> pending;
static std::recursive_mutex mutex;
static bool hasLoadedState = false;
// TODO: Should this be configurable?
static const int REWIND_NUM_STATES = 20;
@ -430,6 +431,11 @@ namespace SaveState
rewindStates.Save();
}
bool HasLoadedState()
{
return hasLoadedState;
}
void Process()
{
#ifndef MOBILE_DEVICE
@ -474,6 +480,7 @@ namespace SaveState
if (result == CChunkFileReader::ERROR_NONE) {
osm.Show(s->T("Loaded State"), 2.0);
callbackResult = true;
hasLoadedState = true;
} else if (result == CChunkFileReader::ERROR_BROKEN_STATE) {
HandleFailure();
osm.Show(i18nLoadFailure, 2.0);
@ -513,12 +520,14 @@ namespace SaveState
if (result == CChunkFileReader::ERROR_NONE) {
osm.Show(s->T("Loaded State"), 2.0);
callbackResult = true;
hasLoadedState = true;
} else if (result == CChunkFileReader::ERROR_BROKEN_STATE) {
// Cripes. Good news is, we might have more. Let's try those too, better than a reset.
if (HandleFailure()) {
// Well, we did rewind, even if too much...
osm.Show(s->T("Loaded State"), 2.0);
callbackResult = true;
hasLoadedState = true;
} else {
osm.Show(i18nLoadFailure, 2.0);
callbackResult = false;
@ -547,5 +556,7 @@ namespace SaveState
std::lock_guard<std::recursive_mutex> guard(mutex);
rewindStates.Clear();
hasLoadedState = false;
}
}

View File

@ -63,6 +63,9 @@ namespace SaveState
// Returns true if there are rewind snapshots available.
bool CanRewind();
// Returns true if a savestate has been used during this session.
bool HasLoadedState();
// Check if there's any save stating needing to be done. Normally called once per frame.
void Process();
};

View File

@ -132,7 +132,7 @@ public:
}
break;
default:
ERROR_LOG_REPORT_ONCE(fmt, G3D, "Reader: Unsupported Pos Format %d", decFmt_.posfmt);
ERROR_LOG_REPORT_ONCE(fmtpos, G3D, "Reader: Unsupported Pos Format %d", decFmt_.posfmt);
memset(pos, 0, sizeof(float) * 3);
break;
}
@ -180,7 +180,7 @@ public:
}
break;
default:
ERROR_LOG_REPORT_ONCE(fmt, G3D, "Reader: Unsupported Pos Format %d", decFmt_.posfmt);
ERROR_LOG_REPORT_ONCE(fmtz16, G3D, "Reader: Unsupported Pos Format %d", decFmt_.posfmt);
memset(pos, 0, sizeof(float) * 3);
break;
}
@ -211,7 +211,7 @@ public:
}
break;
default:
ERROR_LOG_REPORT_ONCE(fmt, G3D, "Reader: Unsupported Nrm Format %d", decFmt_.nrmfmt);
ERROR_LOG_REPORT_ONCE(fmtnrm, G3D, "Reader: Unsupported Nrm Format %d", decFmt_.nrmfmt);
memset(nrm, 0, sizeof(float) * 3);
break;
}
@ -259,7 +259,7 @@ public:
}
break;
default:
ERROR_LOG_REPORT_ONCE(fmt, G3D, "Reader: Unsupported UV Format %d", decFmt_.uvfmt);
ERROR_LOG_REPORT_ONCE(fmtuv, G3D, "Reader: Unsupported UV Format %d", decFmt_.uvfmt);
memset(uv, 0, sizeof(float) * 2);
break;
}
@ -278,7 +278,7 @@ public:
memcpy(color, data_ + decFmt_.c0off, 16);
break;
default:
ERROR_LOG_REPORT_ONCE(fmt, G3D, "Reader: Unsupported C0 Format %d", decFmt_.c0fmt);
ERROR_LOG_REPORT_ONCE(fmtc0, G3D, "Reader: Unsupported C0 Format %d", decFmt_.c0fmt);
memset(color, 0, sizeof(float) * 4);
break;
}
@ -301,7 +301,7 @@ public:
}
break;
default:
ERROR_LOG_REPORT_ONCE(fmt, G3D, "Reader: Unsupported C0 Format %d", decFmt_.c0fmt);
ERROR_LOG_REPORT_ONCE(fmtc0_8888, G3D, "Reader: Unsupported C0 Format %d", decFmt_.c0fmt);
memset(color, 0, sizeof(float) * 4);
break;
}
@ -321,7 +321,7 @@ public:
memcpy(color, data_ + decFmt_.c1off, 12);
break;
default:
ERROR_LOG_REPORT_ONCE(fmt, G3D, "Reader: Unsupported C1 Format %d", decFmt_.c1fmt);
ERROR_LOG_REPORT_ONCE(fmtc1, G3D, "Reader: Unsupported C1 Format %d", decFmt_.c1fmt);
memset(color, 0, sizeof(float) * 3);
break;
}
@ -348,7 +348,7 @@ public:
case DEC_U16_3: for (int i = 0; i < 3; i++) weights[i] = s[i] * (1.f / 32768.f); break;
case DEC_U16_4: for (int i = 0; i < 4; i++) weights[i] = s[i] * (1.f / 32768.f); break;
default:
ERROR_LOG_REPORT_ONCE(fmt0, G3D, "Reader: Unsupported W0 Format %d", decFmt_.w0fmt);
ERROR_LOG_REPORT_ONCE(fmtw0, G3D, "Reader: Unsupported W0 Format %d", decFmt_.w0fmt);
memset(weights, 0, sizeof(float) * 4);
break;
}
@ -376,7 +376,7 @@ public:
case DEC_U16_3: for (int i = 0; i < 3; i++) weights[i+4] = s[i] * (1.f / 32768.f); break;
case DEC_U16_4: for (int i = 0; i < 4; i++) weights[i+4] = s[i] * (1.f / 32768.f); break;
default:
ERROR_LOG_REPORT_ONCE(fmt1, G3D, "Reader: Unsupported W1 Format %d", decFmt_.w1fmt);
ERROR_LOG_REPORT_ONCE(fmtw1, G3D, "Reader: Unsupported W1 Format %d", decFmt_.w1fmt);
memset(weights + 4, 0, sizeof(float) * 4);
break;
}

View File

@ -647,7 +647,7 @@ void VertexDecoder::SetVertexType(u32 fmt, VertexDecoderJitCache *jitCache) {
memset(&decFmt, 0, sizeof(decFmt));
if (morphcount > 1) {
DEBUG_LOG_REPORT_ONCE(m, G3D,"VTYPE with morph used: THRU=%i TC=%i COL=%i POS=%i NRM=%i WT=%i NW=%i IDX=%i MC=%i", (int)throughmode, tc,col,pos,nrm,weighttype,nweights,idx,morphcount);
DEBUG_LOG_REPORT_ONCE(vtypeM, G3D,"VTYPE with morph used: THRU=%i TC=%i COL=%i POS=%i NRM=%i WT=%i NW=%i IDX=%i MC=%i", (int)throughmode, tc,col,pos,nrm,weighttype,nweights,idx,morphcount);
} else {
DEBUG_LOG(G3D,"VTYPE: THRU=%i TC=%i COL=%i POS=%i NRM=%i WT=%i NW=%i IDX=%i MC=%i", (int)throughmode, tc,col,pos,nrm,weighttype,nweights,idx,morphcount);
}

View File

@ -33,8 +33,6 @@
#include "UI/UIShader.h"
#include "UI/GameSettingsScreen.h"
extern void DrawBackground(float alpha);
class ControlMapper : public UI::LinearLayout {
public:
ControlMapper(int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams = 0);

View File

@ -37,7 +37,6 @@
static bool enableAll = false;
static std::vector<std::string> cheatList;
extern void DrawBackground(float alpha);
static CWCheatEngine *cheatEngine2;
static std::deque<bool> bEnableCheat;

View File

@ -35,6 +35,7 @@
#include "Core/CoreParameter.h"
#include "Core/Core.h"
#include "Core/Host.h"
#include "Core/Reporting.h"
#include "Core/System.h"
#include "GPU/GPUState.h"
#include "GPU/GPUInterface.h"
@ -202,6 +203,7 @@ void EmuScreen::sendMessage(const char *message, const char *value) {
gpu->ClearCacheNextFrame();
gpu->Resized();
}
Reporting::UpdateConfig();
RecreateViews();
} else if (!strcmp(message, "gpu dump next frame")) {
if (gpu) gpu->DumpNextFrame();

View File

@ -87,36 +87,6 @@ void GameScreen::CreateViews() {
UI::SetFocusedView(play);
}
void DrawBackground(float alpha);
void GameScreen::DrawBackground(UIContext &dc) {
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath_, true);
dc.Flush();
dc.RebindTexture();
::DrawBackground(1.0f);
dc.Flush();
if (ginfo && ginfo->pic1Texture) {
ginfo->pic1Texture->Bind(0);
uint32_t color = whiteAlpha(ease((time_now_d() - ginfo->timePic1WasLoaded) * 3)) & 0xFFc0c0c0;
dc.Draw()->DrawTexRect(0,0,dp_xres, dp_yres, 0,0,1,1,color);
dc.Flush();
dc.RebindTexture();
}
/*
if (ginfo && ginfo->pic0Texture) {
ginfo->pic0Texture->Bind(0);
// Pic0 is drawn in the bottom right corner, overlaying pic1.
float sizeX = dp_xres / 480 * ginfo->pic0Texture->Width();
float sizeY = dp_yres / 272 * ginfo->pic0Texture->Height();
uint32_t color = whiteAlpha(ease((time_now_d() - ginfo->timePic1WasLoaded) * 2)) & 0xFFc0c0c0;
ui_draw2d.DrawTexRect(dp_xres - sizeX, dp_yres - sizeY, dp_xres, dp_yres, 0,0,1,1,color);
ui_draw2d.Flush();
dc.RebindTexture();
}*/
}
void GameScreen::update(InputState &input) {
UIScreen::update(input);
@ -235,7 +205,7 @@ UI::EventReturn GameScreen::OnCreateShortcut(UI::EventParams &e) {
return UI::EVENT_DONE;
}
bool GameScreen::isRecentGame(std::string gamePath) {
bool GameScreen::isRecentGame(const std::string &gamePath) {
for (auto it = g_Config.recentIsos.begin(); it != g_Config.recentIsos.end(); ++it) {
#ifdef _WIN32
if (!strcmpIgnore((*it).c_str(), gamePath.c_str(), "\\","/"))

View File

@ -17,6 +17,7 @@
#pragma once
#include "UI/MiscScreens.h"
#include "base/functional.h"
#include "ui/ui_screen.h"
@ -26,18 +27,17 @@
// Uses GameInfoCache heavily to implement the functionality.
// Should possibly merge this with the PauseScreen.
class GameScreen : public UIDialogScreen {
class GameScreen : public UIDialogScreenWithGameBackground {
public:
GameScreen(std::string gamePath) : gamePath_(gamePath) {}
GameScreen(const std::string &gamePath) : UIDialogScreenWithGameBackground(gamePath) {}
virtual void update(InputState &input);
protected:
virtual void CreateViews();
virtual void DrawBackground(UIContext &dc);
void CallbackDeleteSaveData(bool yes);
void CallbackDeleteGame(bool yes);
bool isRecentGame(std::string gamePath);
bool isRecentGame(const std::string &gamePath);
private:
// Event handlers
@ -50,8 +50,6 @@ private:
UI::EventReturn OnRemoveFromRecent(UI::EventParams &e);
UI::EventReturn OnShowInFolder(UI::EventParams &e);
std::string gamePath_;
// As we load metadata in the background, we need to be able to update these after the fact.
UI::TextureView *texvGameIcon_;
UI::TextView *tvTitle_;

View File

@ -394,6 +394,7 @@ UI::EventReturn GameSettingsScreen::OnResolutionChange(UI::EventParams &e) {
if (gpu) {
gpu->Resized();
}
Reporting::UpdateConfig();
return UI::EVENT_DONE;
}
@ -404,8 +405,6 @@ UI::EventReturn GameSettingsScreen::OnShaderChange(UI::EventParams &e) {
return UI::EVENT_DONE;
}
void DrawBackground(float alpha);
UI::EventReturn GameSettingsScreen::OnDumpNextFrameToLog(UI::EventParams &e) {
if (gpu) {
gpu->DumpNextFrame();
@ -413,34 +412,6 @@ UI::EventReturn GameSettingsScreen::OnDumpNextFrameToLog(UI::EventParams &e) {
return UI::EVENT_DONE;
}
void GameSettingsScreen::DrawBackground(UIContext &dc) {
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath_, true);
dc.Flush();
dc.RebindTexture();
::DrawBackground(1.0f);
dc.Flush();
if (ginfo && ginfo->pic1Texture) {
ginfo->pic1Texture->Bind(0);
uint32_t color = whiteAlpha(ease((time_now_d() - ginfo->timePic1WasLoaded) * 3)) & 0xFFc0c0c0;
dc.Draw()->DrawTexRect(0,0,dp_xres, dp_yres, 0,0,1,1,color);
dc.Flush();
dc.RebindTexture();
}
/*
if (ginfo && ginfo->pic0Texture) {
ginfo->pic0Texture->Bind(0);
// Pic0 is drawn in the bottom right corner, overlaying pic1.
float sizeX = dp_xres / 480 * ginfo->pic0Texture->Width();
float sizeY = dp_yres / 272 * ginfo->pic0Texture->Height();
uint32_t color = whiteAlpha(ease((time_now_d() - ginfo->timePic1WasLoaded) * 2)) & 0xFFc0c0c0;
ui_draw2d.DrawTexRect(dp_xres - sizeX, dp_yres - sizeY, dp_xres, dp_yres, 0,0,1,1,color);
ui_draw2d.Flush();
dc.RebindTexture();
}*/
}
void GameSettingsScreen::update(InputState &input) {
UIScreen::update(input);
g_Config.iForceMaxEmulatedFPS = cap60FPS_ ? 60 : 0;
@ -528,6 +499,7 @@ UI::EventReturn GameSettingsScreen::OnPostProcShaderChange(UI::EventParams &e) {
if (gpu) {
gpu->Resized();
}
Reporting::UpdateConfig();
return UI::EVENT_DONE;
}
UI::EventReturn GameSettingsScreen::OnDeveloperTools(UI::EventParams &e) {

View File

@ -22,10 +22,10 @@
// Per-game settings screen - enables you to configure graphic options, control options, etc
// per game.
class GameSettingsScreen : public UIDialogScreenWithBackground {
class GameSettingsScreen : public UIDialogScreenWithGameBackground {
public:
GameSettingsScreen(std::string gamePath, std::string gameID = "")
: gamePath_(gamePath), gameID_(gameID), iAlternateSpeedPercent_(3), enableReports_(false) {}
: UIDialogScreenWithGameBackground(gamePath), gameID_(gameID), iAlternateSpeedPercent_(3), enableReports_(false) {}
virtual void update(InputState &input);
virtual void onFinish(DialogResult result);
@ -34,12 +34,11 @@ public:
protected:
virtual void CreateViews();
virtual void DrawBackground(UIContext &dc);
virtual void sendMessage(const char *message, const char *value);
void CallbackRestoreDefaults(bool yes);
private:
std::string gamePath_, gameID_;
std::string gameID_;
// As we load metadata in the background, we need to be able to update these after the fact.
UI::TextView *tvTitle_;

View File

@ -31,6 +31,7 @@
#include "Common/FileUtil.h"
#include "Core/System.h"
#include "Core/Host.h"
#include "Core/Reporting.h"
#include "Core/SaveState.h"
#include "UI/EmuScreen.h"
@ -961,34 +962,6 @@ void GamePauseScreen::update(InputState &input) {
UIScreen::update(input);
}
void DrawBackground(float alpha);
void GamePauseScreen::DrawBackground(UIContext &dc) {
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath_, true);
dc.Flush();
if (ginfo) {
bool hasPic = false;
if (ginfo->pic1Texture) {
ginfo->pic1Texture->Bind(0);
hasPic = true;
} else if (ginfo->pic0Texture) {
ginfo->pic0Texture->Bind(0);
hasPic = true;
}
if (hasPic) {
uint32_t color = whiteAlpha(ease((time_now_d() - ginfo->timePic1WasLoaded) * 3)) & 0xFFc0c0c0;
dc.Draw()->DrawTexRect(0,0,dp_xres, dp_yres, 0,0,1,1, color);
dc.Flush();
dc.RebindTexture();
} else {
::DrawBackground(1.0f);
dc.RebindTexture();
dc.Flush();
}
}
}
GamePauseScreen::~GamePauseScreen() {
if (saveSlots_ != NULL) {
g_Config.iCurrentStateSlot = saveSlots_->GetSelection();
@ -1076,6 +1049,7 @@ void GamePauseScreen::onFinish(DialogResult result) {
// Do we really always need to "gpu->Resized" here?
if (gpu)
gpu->Resized();
Reporting::UpdateConfig();
}
UI::EventReturn GamePauseScreen::OnExitToMenu(UI::EventParams &e) {

View File

@ -63,15 +63,14 @@ private:
bool backFromStore_;
};
class GamePauseScreen : public UIDialogScreen {
class GamePauseScreen : public UIDialogScreenWithGameBackground {
public:
GamePauseScreen(const std::string &filename) : UIDialogScreen(), gamePath_(filename), saveSlots_(NULL) {}
GamePauseScreen(const std::string &filename) : UIDialogScreenWithGameBackground(filename), saveSlots_(NULL) {}
virtual ~GamePauseScreen();
virtual void onFinish(DialogResult result);
protected:
virtual void DrawBackground(UIContext &dc);
virtual void CreateViews();
virtual void update(InputState &input);
virtual void sendMessage(const char *message, const char *value);
@ -90,8 +89,6 @@ private:
UI::EventReturn OnSwitchUMD(UI::EventParams &e);
std::string gamePath_;
UI::ChoiceStrip *saveSlots_;
UI::Choice *saveStateButton_;
UI::Choice *loadStateButton_;

View File

@ -30,6 +30,7 @@
#include "UI/MiscScreens.h"
#include "UI/EmuScreen.h"
#include "UI/MainScreen.h"
#include "UI/GameInfoCache.h"
#include "Core/Config.h"
#include "Core/Host.h"
#include "Core/System.h"
@ -99,6 +100,32 @@ void DrawBackground(float alpha) {
}
}
void DrawGameBackground(UIContext &dc, const std::string &gamePath) {
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath, true);
dc.Flush();
if (ginfo) {
bool hasPic = false;
if (ginfo->pic1Texture) {
ginfo->pic1Texture->Bind(0);
hasPic = true;
} else if (ginfo->pic0Texture) {
ginfo->pic0Texture->Bind(0);
hasPic = true;
}
if (hasPic) {
uint32_t color = whiteAlpha(ease((time_now_d() - ginfo->timePic1WasLoaded) * 3)) & 0xFFc0c0c0;
dc.Draw()->DrawTexRect(0,0,dp_xres, dp_yres, 0,0,1,1, color);
dc.Flush();
dc.RebindTexture();
} else {
::DrawBackground(1.0f);
dc.RebindTexture();
dc.Flush();
}
}
}
void HandleCommonMessages(const char *message, const char *value, ScreenManager *manager) {
if (!strcmp(message, "clear jit")) {
if (MIPSComp::jit && PSP_IsInited()) {
@ -112,6 +139,14 @@ void UIScreenWithBackground::DrawBackground(UIContext &dc) {
dc.Flush();
}
void UIScreenWithGameBackground::DrawBackground(UIContext &dc) {
DrawGameBackground(dc, gamePath_);
}
void UIDialogScreenWithGameBackground::DrawBackground(UIContext &dc) {
DrawGameBackground(dc, gamePath_);
}
void UIScreenWithBackground::sendMessage(const char *message, const char *value) {
HandleCommonMessages(message, value, screenManager());
I18NCategory *de = GetI18NCategory("Developer");

View File

@ -39,6 +39,15 @@ protected:
virtual UI::EventReturn OnLanguageChange(UI::EventParams &e);
};
class UIScreenWithGameBackground : public UIScreenWithBackground {
public:
UIScreenWithGameBackground(const std::string &gamePath)
: UIScreenWithBackground(), gamePath_(gamePath) {}
virtual void DrawBackground(UIContext &dc);
protected:
std::string gamePath_;
};
class UIDialogScreenWithBackground : public UIDialogScreen {
public:
UIDialogScreenWithBackground() : UIDialogScreen() {}
@ -48,6 +57,15 @@ protected:
virtual UI::EventReturn OnLanguageChange(UI::EventParams &e);
};
class UIDialogScreenWithGameBackground : public UIDialogScreenWithBackground {
public:
UIDialogScreenWithGameBackground(const std::string &gamePath)
: UIDialogScreenWithBackground(), gamePath_(gamePath) {}
virtual void DrawBackground(UIContext &dc);
protected:
std::string gamePath_;
};
class PromptScreen : public UIDialogScreenWithBackground {
public:
PromptScreen(std::string message, std::string yesButtonText, std::string noButtonText,