Merge pull request #6388 from unknownbrackets/ui-tweaks

Show game background during controller/keyboard game selection
This commit is contained in:
Henrik Rydgård
2014-06-22 08:53:11 +02:00
9 changed files with 267 additions and 76 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ enum PBPSubFile {
PBP_PARAM_SFO,
PBP_ICON0_PNG,
PBP_ICON1_PMF,
PBP_UNKNOWN_PNG, // PIC0?
PBP_PIC0_PNG,
PBP_PIC1_PNG,
PBP_SND0_AT3,
PBP_EXECUTABLE_PSP,
+1 -1
View File
@@ -240,7 +240,7 @@ void GenerateDepalShader100(char *buffer, GEBufferFormat pixelFormat) {
case GE_FORMAT_565:
if ((mask & (mask + 1)) == 0 && shift < 16) {
const u8 shifts[16] = {0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4};
const u32 multipliers[16] = {31, 31, 31, 31, 31, 63, 63, 63, 63, 63, 63, 31, 31, 31, 31, 31};
const int multipliers[16] = {31, 31, 31, 31, 31, 63, 63, 63, 63, 63, 63, 31, 31, 31, 31, 31};
const char *rgba = "rrrrrggggggbbbbb";
const u8 rgba_shift = shifts[shift];
if (rgba_shift == 0 && mask == multipliers[shift]) {
+73 -57
View File
@@ -293,12 +293,26 @@ public:
}
delete [] contents;
}
info_->iconDataLoaded = true;
}
if (info_->wantBG) {
if (info_->wantFlags & GAMEINFO_WANTBG) {
if (pbp.GetSubFileSize(PBP_PIC0_PNG) > 0) {
lock_guard lock(info_->lock);
pbp.GetSubFileAsString(PBP_PIC0_PNG, &info_->pic0TextureData);
info_->pic0DataLoaded = true;
}
if (pbp.GetSubFileSize(PBP_PIC1_PNG) > 0) {
lock_guard lock(info_->lock);
pbp.GetSubFileAsString(PBP_PIC1_PNG, &info_->pic1TextureData);
info_->pic1DataLoaded = true;
}
}
if (info_->wantFlags & GAMEINFO_WANTSND) {
if (pbp.GetSubFileSize(PBP_SND0_AT3) > 0) {
lock_guard lock(info_->lock);
pbp.GetSubFileAsString(PBP_SND0_AT3, &info_->sndFileData);
info_->sndDataLoaded = true;
}
}
}
@@ -319,6 +333,7 @@ handleELF:
if (contents) {
lock_guard lock(info_->lock);
info_->iconTextureData = std::string((const char *)contents, sz);
info_->iconDataLoaded = true;
}
delete [] contents;
}
@@ -339,10 +354,17 @@ handleELF:
}
ReadFileToString(&umd, "/PSP_GAME/ICON0.PNG", &info_->iconTextureData, &info_->lock);
if (info_->wantBG) {
info_->iconDataLoaded = true;
if (info_->wantFlags & GAMEINFO_WANTBG) {
ReadFileToString(&umd, "/PSP_GAME/PIC0.PNG", &info_->pic0TextureData, &info_->lock);
info_->pic0DataLoaded = true;
ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
info_->pic1DataLoaded = true;
}
if (info_->wantFlags & GAMEINFO_WANTSND) {
ReadFileToString(&umd, "/PSP_GAME/SND0.AT3", &info_->sndFileData, &info_->lock);
info_->pic1DataLoaded = true;
}
ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
break;
}
case FILETYPE_PSP_ISO:
@@ -365,10 +387,16 @@ handleELF:
info_->paramSFO.ReadSFO((const u8 *)paramSFOcontents.data(), paramSFOcontents.size());
info_->ParseParamSFO();
if (info_->wantBG) {
if (info_->wantFlags & GAMEINFO_WANTBG) {
ReadFileToString(&umd, "/PSP_GAME/PIC0.PNG", &info_->pic0TextureData, &info_->lock);
info_->pic0DataLoaded = true;
ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
info_->pic1DataLoaded = true;
}
if (info_->wantFlags & GAMEINFO_WANTSND) {
ReadFileToString(&umd, "/PSP_GAME/SND0.AT3", &info_->sndFileData, &info_->lock);
info_->pic1DataLoaded = true;
}
ReadFileToString(&umd, "/PSP_GAME/PIC1.PNG", &info_->pic1TextureData, &info_->lock);
}
// Fall back to unknown icon if ISO is broken/is a homebrew ISO, override is allowed though
@@ -382,12 +410,12 @@ handleELF:
}
delete [] contents;
}
info_->iconDataLoaded = true;
break;
}
case FILETYPE_ARCHIVE_ZIP:
info_->paramSFOLoaded = true;
info_->wantBG = false;
{
// Read standard icon
size_t sz;
@@ -395,6 +423,7 @@ handleELF:
if (contents) {
lock_guard lock(info_->lock);
info_->iconTextureData = std::string((const char *)contents, sz);
info_->iconDataLoaded = true;
}
delete [] contents;
}
@@ -402,7 +431,6 @@ handleELF:
case FILETYPE_ARCHIVE_RAR:
info_->paramSFOLoaded = true;
info_->wantBG = false;
{
// Read standard icon
size_t sz;
@@ -410,6 +438,7 @@ handleELF:
if (contents) {
lock_guard lock(info_->lock);
info_->iconTextureData = std::string((const char *)contents, sz);
info_->iconDataLoaded = true;
}
delete [] contents;
}
@@ -418,12 +447,10 @@ handleELF:
case FILETYPE_NORMAL_DIRECTORY:
default:
info_->paramSFOLoaded = true;
info_->wantBG = false;
break;
}
// probably only want these when we ask for the background image...
// should maybe flip the flag to "onlyIcon"
if (info_->wantBG) {
if (info_->wantFlags & GAMEINFO_WANTSIZE) {
info_->gameSize = info_->GetGameSizeInBytes();
info_->saveDataSize = info_->GetSaveDataSizeInBytes();
info_->installDataSize = info_->GetInstallDataSizeInBytes();
@@ -455,8 +482,7 @@ void GameInfoCache::Shutdown() {
StopProcessingWorkQueue(gameInfoWQ_);
}
void GameInfoCache::Save()
{
void GameInfoCache::Save() {
// TODO
}
@@ -515,61 +541,31 @@ void GameInfoCache::FlushBGs() {
delete iter->second->pic1Texture;
iter->second->pic1Texture = 0;
}
iter->second->wantBG = false;
iter->second->wantFlags &= ~GAMEINFO_WANTBG;
}
}
// This may run off-main-thread and we thus can't use the global
// pspFileSystem (well, we could with synchronization but there might not
// even be a game running).
GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, bool wantBG) {
GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, int wantFlags) {
GameInfo *info = 0;
auto iter = info_.find(gamePath);
if (iter != info_.end()) {
GameInfo *info = iter->second;
if (!info->wantBG && wantBG) {
info = iter->second;
if ((info->wantFlags & wantFlags) != wantFlags) {
// Need to start over. We'll just add a new work item.
delete info; // Hm, how dangerous is this? There might be a race condition here.
goto again;
}
{
lock_guard lock(info->lock);
if (info->iconTextureData.size()) {
// We'd have to split up Texture->LoadPNG though, creating some intermediate Image class maybe.
info->iconTexture = new Texture();
if (info->iconTexture->LoadPNG((const u8 *)info->iconTextureData.data(), info->iconTextureData.size(), false)) {
info->timeIconWasLoaded = time_now_d();
} else {
delete info->iconTexture;
info->iconTexture = 0;
}
info->iconTextureData.clear();
}
if (info->iconDataLoaded) {
SetupTexture(info, info->iconTextureData, info->iconTexture, info->timeIconWasLoaded);
}
{
lock_guard lock(info->lock);
if (info->pic0TextureData.size()) {
info->pic0Texture = new Texture();
if (info->pic0Texture->LoadPNG((const u8 *)info->pic0TextureData.data(), info->pic0TextureData.size(), false)) {
info->timePic0WasLoaded = time_now_d();
} else {
delete info->pic0Texture;
info->pic0Texture = 0;
}
info->pic0TextureData.clear();
}
if (info->pic0DataLoaded) {
SetupTexture(info, info->pic0TextureData, info->pic0Texture, info->timePic0WasLoaded);
}
{
lock_guard lock(info->lock);
if (info->pic1TextureData.size()) {
info->pic1Texture = new Texture();
if (info->pic1Texture->LoadPNG((const u8 *)info->pic1TextureData.data(), info->pic1TextureData.size(), false)) {
info->timePic1WasLoaded = time_now_d();
} else {
delete info->pic1Texture;
info->pic1Texture = 0;
}
info->pic1TextureData.clear();
}
if (info->pic1DataLoaded) {
SetupTexture(info, info->pic1TextureData, info->pic1Texture, info->timePic1WasLoaded);
}
iter->second->lastAccessedTime = time_now_d();
return iter->second;
@@ -577,8 +573,13 @@ GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, bool wantBG) {
again:
GameInfo *info = new GameInfo();
info->wantBG = wantBG;
if (!info) {
info = new GameInfo();
}
{
lock_guard lock(info->lock);
info->wantFlags |= wantFlags;
}
GameInfoWorkItem *item = new GameInfoWorkItem(gamePath, info);
gameInfoWQ_->Add(item);
@@ -586,3 +587,18 @@ again:
info_[gamePath] = info;
return info;
}
void GameInfoCache::SetupTexture(GameInfo *info, std::string &textureData, Texture *&tex, double &loadTime) {
if (textureData.size()) {
if (!tex) {
tex = new Texture();
if (tex->LoadPNG((const u8 *)textureData.data(), textureData.size(), false)) {
loadTime = time_now_d();
} else {
delete tex;
tex = 0;
}
}
textureData.clear();
}
}
+59 -3
View File
@@ -42,11 +42,58 @@ enum GameRegion {
GAMEREGION_MAX,
};
enum GameInfoWantFlags {
GAMEINFO_WANTBG = 0x01,
GAMEINFO_WANTSIZE = 0x02,
GAMEINFO_WANTSND = 0x04,
};
// TODO: Need to fix c++11 still on Symbian and use std::atomic<bool> instead.
class CompletionFlag {
public:
CompletionFlag() : pending(1) {
}
void SetDone() {
#if defined(_WIN32)
_WriteBarrier();
pending = 0;
#else
__sync_lock_release(&pending);
#endif
}
bool IsDone() {
const bool done = pending == 0;
#if defined(_WIN32)
_ReadBarrier();
#else
__sync_synchronize();
#endif
return done;
}
CompletionFlag &operator =(const bool &v) {
pending = v ? 0 : 1;
return *this;
}
operator bool() {
return IsDone();
}
private:
volatile u32 pending;
DISALLOW_COPY_AND_ASSIGN(CompletionFlag);
};
class GameInfo {
public:
GameInfo()
: disc_total(0), disc_number(0), region(-1), fileType(FILETYPE_UNKNOWN), paramSFOLoaded(false),
iconTexture(NULL), pic0Texture(NULL), pic1Texture(NULL), wantBG(false),
iconTexture(NULL), pic0Texture(NULL), pic1Texture(NULL), wantFlags(0),
timeIconWasLoaded(0.0), timePic0WasLoaded(0.0), timePic1WasLoaded(0.0),
gameSize(0), saveDataSize(0), installDataSize(0) {}
bool DeleteGame(); // Better be sure what you're doing when calling this.
@@ -87,7 +134,9 @@ public:
std::string pic1TextureData;
Texture *pic1Texture;
bool wantBG;
std::string sndFileData;
int wantFlags;
double lastAccessedTime;
@@ -97,6 +146,11 @@ public:
double timePic0WasLoaded;
double timePic1WasLoaded;
CompletionFlag iconDataLoaded;
CompletionFlag pic0DataLoaded;
CompletionFlag pic1DataLoaded;
CompletionFlag sndDataLoaded;
u64 gameSize;
u64 saveDataSize;
u64 installDataSize;
@@ -116,7 +170,7 @@ public:
// but filled in later asynchronously in the background. So keep calling this,
// redrawing the UI often. Only set wantBG if you really want it because
// it's big. bgTextures may be discarded over time as well.
GameInfo *GetInfo(const std::string &gamePath, bool wantBG);
GameInfo *GetInfo(const std::string &gamePath, int wantFlags);
void Decimate(); // Deletes old info.
void FlushBGs(); // Gets rid of all BG textures.
@@ -125,6 +179,8 @@ public:
void Load();
private:
void SetupTexture(GameInfo *info, std::string &textureData, Texture *&tex, double &loadTime);
// Maps ISO path to info.
std::map<std::string, GameInfo *> info_;
+18 -9
View File
@@ -15,6 +15,7 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <algorithm>
#include "base/colorutil.h"
#include "base/timeutil.h"
#include "gfx_es2/draw_buffer.h"
@@ -34,7 +35,7 @@
#include "Core/Config.h"
void GameScreen::CreateViews() {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, true);
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
I18NCategory *d = GetI18NCategory("Dialog");
I18NCategory *ga = GetI18NCategory("Game");
@@ -91,13 +92,21 @@ void GameScreen::update(InputState &input) {
UIScreen::update(input);
I18NCategory *ga = GetI18NCategory("Game");
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, true);
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (tvTitle_)
tvTitle_->SetText(info->title + " (" + info->id + ")");
if (info->iconTexture && texvGameIcon_) {
texvGameIcon_->SetTexture(info->iconTexture);
uint32_t color = whiteAlpha(ease((time_now_d() - info->timeIconWasLoaded) * 3));
// Fade the icon with the background.
double loadTime = info->timeIconWasLoaded;
if (info->pic1Texture) {
loadTime = std::max(loadTime, info->timePic1WasLoaded);
}
if (info->pic0Texture) {
loadTime = std::max(loadTime, info->timePic0WasLoaded);
}
uint32_t color = whiteAlpha(ease((time_now_d() - loadTime) * 3));
texvGameIcon_->SetColor(color);
}
@@ -144,7 +153,7 @@ UI::EventReturn GameScreen::OnPlay(UI::EventParams &e) {
}
UI::EventReturn GameScreen::OnGameSettings(UI::EventParams &e) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, true);
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (info && info->paramSFOLoaded) {
std::string discID = info->paramSFO.GetValueString("DISC_ID");
screenManager()->push(new GameSettingsScreen(gamePath_, discID));
@@ -155,7 +164,7 @@ UI::EventReturn GameScreen::OnGameSettings(UI::EventParams &e) {
UI::EventReturn GameScreen::OnDeleteSaveData(UI::EventParams &e) {
I18NCategory *d = GetI18NCategory("Dialog");
I18NCategory *ga = GetI18NCategory("Game");
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, true);
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (info) {
screenManager()->push(
new PromptScreen(d->T("DeleteConfirmAll", "Do you really want to delete all\nyour save data for this game?"), ga->T("ConfirmDelete"), d->T("Cancel"),
@@ -167,7 +176,7 @@ UI::EventReturn GameScreen::OnDeleteSaveData(UI::EventParams &e) {
}
void GameScreen::CallbackDeleteSaveData(bool yes) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, false);
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
if (yes) {
info->DeleteAllSaveData();
info->saveDataSize = 0;
@@ -178,7 +187,7 @@ void GameScreen::CallbackDeleteSaveData(bool yes) {
UI::EventReturn GameScreen::OnDeleteGame(UI::EventParams &e) {
I18NCategory *d = GetI18NCategory("Dialog");
I18NCategory *ga = GetI18NCategory("Game");
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, true);
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (info) {
screenManager()->push(
new PromptScreen(d->T("DeleteConfirmGame", "Do you really want to delete this game\nfrom your device? You can't undo this."), ga->T("ConfirmDelete"), d->T("Cancel"),
@@ -189,7 +198,7 @@ UI::EventReturn GameScreen::OnDeleteGame(UI::EventParams &e) {
}
void GameScreen::CallbackDeleteGame(bool yes) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, false);
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
if (yes) {
info->DeleteGame();
g_gameInfoCache.Clear();
@@ -198,7 +207,7 @@ void GameScreen::CallbackDeleteGame(bool yes) {
}
UI::EventReturn GameScreen::OnCreateShortcut(UI::EventParams &e) {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, false);
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
if (info) {
host->CreateDesktopShortcut(gamePath_, info->title);
}
+1 -1
View File
@@ -54,7 +54,7 @@ extern bool iosCanUseJit;
#endif
void GameSettingsScreen::CreateViews() {
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, true);
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
cap60FPS_ = g_Config.iForceMaxEmulatedFPS == 60;
+101 -2
View File
@@ -138,7 +138,13 @@ public:
}
}
virtual void FocusChanged(int focusFlags) {
UI::Clickable::FocusChanged(focusFlags);
TriggerOnHighlight(focusFlags);
}
UI::Event OnHoldClick;
UI::Event OnHighlight;
private:
void TriggerOnHoldClick() {
@@ -149,6 +155,13 @@ private:
down_ = false;
OnHoldClick.Trigger(e);
}
void TriggerOnHighlight(int focusFlags) {
UI::EventParams e;
e.v = this;
e.s = gamePath_;
e.a = focusFlags;
OnHighlight.Trigger(e);
}
bool gridStyle_;
std::string gamePath_;
@@ -160,7 +173,7 @@ private:
};
void GameButton::Draw(UIContext &dc) {
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath_, false);
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath_, 0);
Texture *texture = 0;
u32 color = 0, shadowColor = 0;
@@ -376,6 +389,7 @@ public:
UI::Event OnChoice;
UI::Event OnHoldChoice;
UI::Event OnHighlight;
UI::Choice *HomebrewStoreButton() { return homebrewStoreButton_; }
private:
@@ -386,6 +400,7 @@ private:
UI::EventReturn GameButtonClick(UI::EventParams &e);
UI::EventReturn GameButtonHoldClick(UI::EventParams &e);
UI::EventReturn GameButtonHighlight(UI::EventParams &e);
UI::EventReturn NavigateClick(UI::EventParams &e);
UI::EventReturn LayoutChange(UI::EventParams &e);
UI::EventReturn LastClick(UI::EventParams &e);
@@ -568,6 +583,7 @@ void GameBrowser::Refresh() {
GameButton *b = gameList_->Add(gameButtons[i]);
b->OnClick.Handle(this, &GameBrowser::GameButtonClick);
b->OnHoldClick.Handle(this, &GameBrowser::GameButtonHoldClick);
b->OnHighlight.Handle(this, &GameBrowser::GameButtonHighlight);
}
// Show a button to toggle pinning at the very end.
@@ -667,6 +683,12 @@ UI::EventReturn GameBrowser::GameButtonHoldClick(UI::EventParams &e) {
return UI::EVENT_DONE;
}
UI::EventReturn GameBrowser::GameButtonHighlight(UI::EventParams &e) {
// Insta-update - here we know we are already on the right thread.
OnHighlight.Trigger(e);
return UI::EVENT_DONE;
}
UI::EventReturn GameBrowser::NavigateClick(UI::EventParams &e) {
DirButton *button = static_cast<DirButton *>(e.v);
std::string text = button->GetPath();
@@ -680,7 +702,7 @@ UI::EventReturn GameBrowser::NavigateClick(UI::EventParams &e) {
return UI::EVENT_DONE;
}
MainScreen::MainScreen() : backFromStore_(false) {
MainScreen::MainScreen() : highlightProgress_(0.0f), prevHighlightProgress_(0.0f), backFromStore_(false) {
System_SendMessage("event", "mainscreen");
}
@@ -736,6 +758,9 @@ void MainScreen::CreateViews() {
tabRecentGames->OnHoldChoice.Handle(this, &MainScreen::OnGameSelected);
tabAllGames->OnHoldChoice.Handle(this, &MainScreen::OnGameSelected);
tabHomebrew->OnHoldChoice.Handle(this, &MainScreen::OnGameSelected);
tabRecentGames->OnHighlight.Handle(this, &MainScreen::OnGameHighlight);
tabAllGames->OnHighlight.Handle(this, &MainScreen::OnGameHighlight);
tabHomebrew->OnHighlight.Handle(this, &MainScreen::OnGameHighlight);
if (g_Config.recentIsos.size() > 0) {
leftColumn->SetCurrentTab(0);
@@ -884,6 +909,59 @@ UI::EventReturn MainScreen::OnLoadFile(UI::EventParams &e) {
return UI::EVENT_DONE;
}
extern void DrawBackground(UIContext &dc, float alpha);
void MainScreen::DrawBackground(UIContext &dc) {
UIScreenWithBackground::DrawBackground(dc);
if (highlightedGamePath_.empty() && prevHighlightedGamePath_.empty()) {
return;
}
if (DrawBackgroundFor(dc, prevHighlightedGamePath_, 1.0f - prevHighlightProgress_)) {
if (prevHighlightProgress_ < 1.0f) {
prevHighlightProgress_ += 1.0f / 20.0f;
}
}
if (!highlightedGamePath_.empty()) {
if (DrawBackgroundFor(dc, highlightedGamePath_, highlightProgress_)) {
if (highlightProgress_ < 1.0f) {
highlightProgress_ += 1.0f / 20.0f;
}
}
}
}
bool MainScreen::DrawBackgroundFor(UIContext &dc, const std::string &gamePath, float progress) {
dc.Flush();
GameInfo *ginfo = 0;
if (!gamePath.empty()) {
ginfo = g_gameInfoCache.GetInfo(gamePath, GAMEINFO_WANTBG);
// Loading texture data may bind a texture.
dc.RebindTexture();
// Let's not bother if there's no picture.
if (!ginfo || (!ginfo->pic1Texture && !ginfo->pic0Texture)) {
return false;
}
} else {
return false;
}
if (ginfo->pic1Texture) {
ginfo->pic1Texture->Bind(0);
} else if (ginfo->pic0Texture) {
ginfo->pic0Texture->Bind(0);
}
uint32_t color = whiteAlpha(ease(progress)) & 0xFFc0c0c0;
dc.Draw()->DrawTexRect(dc.GetBounds(), 0,0,1,1, color);
dc.Flush();
dc.RebindTexture();
return true;
}
UI::EventReturn MainScreen::OnGameSelected(UI::EventParams &e) {
#ifdef _WIN32
std::string path = ReplaceAll(e.s, "\\", "/");
@@ -894,6 +972,27 @@ UI::EventReturn MainScreen::OnGameSelected(UI::EventParams &e) {
return UI::EVENT_DONE;
}
UI::EventReturn MainScreen::OnGameHighlight(UI::EventParams &e) {
#ifdef _WIN32
std::string path = ReplaceAll(e.s, "\\", "/");
#else
std::string path = e.s;
#endif
if (!highlightedGamePath_.empty() || (e.a == FF_LOSTFOCUS && highlightedGamePath_ == path)) {
if (prevHighlightedGamePath_.empty() || prevHighlightProgress_ >= 0.75f) {
prevHighlightedGamePath_ = highlightedGamePath_;
prevHighlightProgress_ = 1.0 - highlightProgress_;
}
highlightedGamePath_.clear();
}
if (e.a == FF_GOTFOCUS) {
highlightedGamePath_ = path;
highlightProgress_ = 0.0f;
}
return UI::EVENT_DONE;
}
UI::EventReturn MainScreen::OnGameSelectedInstant(UI::EventParams &e) {
#ifdef _WIN32
std::string path = ReplaceAll(e.s, "\\", "/");
+8
View File
@@ -37,13 +37,17 @@ public:
protected:
virtual void CreateViews();
virtual void DrawBackground(UIContext &dc);
virtual void update(InputState &input);
virtual void sendMessage(const char *message, const char *value);
virtual void dialogFinished(const Screen *dialog, DialogResult result);
private:
bool DrawBackgroundFor(UIContext &dc, const std::string &gamePath, float progress);
UI::EventReturn OnGameSelected(UI::EventParams &e);
UI::EventReturn OnGameSelectedInstant(UI::EventParams &e);
UI::EventReturn OnGameHighlight(UI::EventParams &e);
// Event handlers
UI::EventReturn OnLoadFile(UI::EventParams &e);
UI::EventReturn OnGameSettings(UI::EventParams &e);
@@ -60,6 +64,10 @@ private:
UI::LinearLayout *upgradeBar_;
UI::TabHolder *tabHolder_;
std::string highlightedGamePath_;
std::string prevHighlightedGamePath_;
float highlightProgress_;
float prevHighlightProgress_;
bool backFromStore_;
};
+5 -2
View File
@@ -105,20 +105,23 @@ void DrawBackground(UIContext &dc, float alpha = 1.0f) {
}
void DrawGameBackground(UIContext &dc, const std::string &gamePath) {
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath, true);
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath, GAMEINFO_WANTBG);
dc.Flush();
if (ginfo) {
bool hasPic = false;
double loadTime;
if (ginfo->pic1Texture) {
ginfo->pic1Texture->Bind(0);
loadTime = ginfo->timePic1WasLoaded;
hasPic = true;
} else if (ginfo->pic0Texture) {
ginfo->pic0Texture->Bind(0);
loadTime = ginfo->timePic0WasLoaded;
hasPic = true;
}
if (hasPic) {
uint32_t color = whiteAlpha(ease((time_now_d() - ginfo->timePic1WasLoaded) * 3)) & 0xFFc0c0c0;
uint32_t color = whiteAlpha(ease((time_now_d() - loadTime) * 3)) & 0xFFc0c0c0;
dc.Draw()->DrawTexRect(dc.GetBounds(), 0,0,1,1, color);
dc.Flush();
dc.RebindTexture();