mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-11 05:26:24 +02:00
Fix the gemini-written video player to actually work
This commit is contained in:
1 parent
250c52d1d7
commit
e50199ad0a
18 files changed
+415
-132
No files matched your search
+110
-3
@@ -42,6 +42,7 @@
|
||||
#include "Core/Util/GameDB.h"
|
||||
#include "Core/Util/RecentFiles.h"
|
||||
#include "Core/Util/PathUtil.h"
|
||||
#include "Core/Util/VideoPlayer.h"
|
||||
#include "UI/OnScreenDisplay.h"
|
||||
#include "UI/Background.h"
|
||||
#include "UI/CwCheatScreen.h"
|
||||
@@ -56,7 +57,95 @@
|
||||
#include "UI/SavedataScreen.h"
|
||||
#include "UI/MiscViews.h"
|
||||
|
||||
constexpr GameInfoFlags g_desiredFlags = GameInfoFlags::PARAM_SFO | GameInfoFlags::ICON | GameInfoFlags::PIC0 | GameInfoFlags::PIC1 | GameInfoFlags::UNCOMPRESSED_SIZE | GameInfoFlags::SIZE | GameInfoFlags::SAVEDATA_SIZE;
|
||||
constexpr GameInfoFlags g_desiredFlags = GameInfoFlags::PARAM_SFO | GameInfoFlags::ICON | GameInfoFlags::PIC0 | GameInfoFlags::PIC1 | GameInfoFlags::ICON1_PMF | GameInfoFlags::UNCOMPRESSED_SIZE | GameInfoFlags::SIZE | GameInfoFlags::SAVEDATA_SIZE;
|
||||
|
||||
class PMFView : public UI::InertView {
|
||||
public:
|
||||
PMFView(std::string data, UI::LayoutParams *params) : UI::InertView(params), data_(data) {
|
||||
startTime_ = Instant::Now();
|
||||
player_ = pmf_create();
|
||||
if (0 == pmf_init(player_, (const uint8_t *)data_.data(), data_.size(), &width_, &height_)) {
|
||||
|
||||
} else {
|
||||
ERROR_LOG(Log::G3D, "Couldn't load pmf");
|
||||
pmf_destroy(player_);
|
||||
player_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
~PMFView() {
|
||||
if (curFrame_) {
|
||||
curFrame_->Release();
|
||||
curFrame_ = nullptr;
|
||||
}
|
||||
|
||||
if (player_) {
|
||||
pmf_destroy(player_);
|
||||
player_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceLost() override {
|
||||
if (curFrame_) {
|
||||
curFrame_->Release();
|
||||
curFrame_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override {
|
||||
// Just use the video size.
|
||||
w = width_;
|
||||
h = height_;
|
||||
}
|
||||
|
||||
void Draw(UIContext &dc) override {
|
||||
if (!player_) {
|
||||
return;
|
||||
}
|
||||
|
||||
Draw::DrawContext *draw = dc.GetDrawContext();
|
||||
|
||||
std::vector<u8> frame(width_ * height_ * 4);
|
||||
if (pmf_update(player_, startTime_.ElapsedSeconds(), frame.data())) {
|
||||
if (curFrame_) {
|
||||
curFrame_->Release();
|
||||
curFrame_ = nullptr;
|
||||
}
|
||||
|
||||
Draw::TextureDesc desc{};
|
||||
desc.width = width_;
|
||||
desc.height = height_;
|
||||
desc.depth = 1;
|
||||
desc.format = Draw::DataFormat::R8G8B8A8_UNORM;
|
||||
desc.generateMips = false;
|
||||
desc.tag = "pmf_frame";
|
||||
desc.type = Draw::TextureType::LINEAR2D;
|
||||
desc.mipLevels = 1;
|
||||
desc.initData.push_back(frame.data());
|
||||
|
||||
curFrame_ = draw->CreateTexture(desc);
|
||||
}
|
||||
|
||||
if (curFrame_) {
|
||||
int dropsize = 5;
|
||||
dc.Draw()->DrawImage4Grid(dc.GetTheme().dropShadow4Grid, bounds_.x - dropsize * 1.5f, bounds_.y - dropsize * 1.5f, bounds_.x2() + dropsize * 1.5f, bounds_.y2() + dropsize * 1.5f, 0xFF000000, 1.0f);
|
||||
dc.Flush();
|
||||
draw->BindTexture(0, curFrame_);
|
||||
dc.Draw()->DrawTexRect(bounds_, 0, 0, 1.0f, 1.0f, 0xFFFFFFFF);
|
||||
dc.Flush();
|
||||
}
|
||||
|
||||
dc.RebindTexture();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string data_;
|
||||
Draw::Texture *curFrame_ = nullptr;
|
||||
PMFPlayer *player_ = nullptr;
|
||||
Instant startTime_;
|
||||
int width_ = 0;
|
||||
int height_ = 0;
|
||||
};
|
||||
|
||||
GameScreen::GameScreen(const Path &gamePath, bool inGame) : UITwoPaneBaseDialogScreen(gamePath, TwoPaneFlags::SettingsToTheRight | TwoPaneFlags::CustomContextMenu), inGame_(inGame) {
|
||||
g_BackgroundAudio.SetGame(gamePath);
|
||||
@@ -92,8 +181,13 @@ void GameScreen::update() {
|
||||
bool recreate = false;
|
||||
|
||||
if (knownFlags_ != hasFlags) {
|
||||
bool justAudio = ((u32)knownFlags_ ^ (u32)hasFlags) == (u32)GameInfoFlags::SND;
|
||||
|
||||
knownFlags_ = hasFlags;
|
||||
recreate = true;
|
||||
// don't need to recreate if the audio loaded.
|
||||
if (!justAudio) {
|
||||
recreate = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Has the user requested a CRC32?
|
||||
@@ -130,6 +224,7 @@ static bool FileTypeHasIcon(IdentifiedFileType fileType) {
|
||||
case IdentifiedFileType::PSP_ISO_NP:
|
||||
case IdentifiedFileType::PSP_ISO:
|
||||
case IdentifiedFileType::PSP_UMD_VIDEO_ISO:
|
||||
case IdentifiedFileType::PSP_DISC_DIRECTORY:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -191,7 +286,7 @@ void GameScreen::CreateContentViews(UI::ViewGroup *parent) {
|
||||
mainGameInfo = new LinearLayout(ORIENT_VERTICAL);
|
||||
leftColumn->Add(new Spacer(8.0f));
|
||||
if (fileTypeHasIcon && !(info_->icon.dataLoaded && info_->icon.data.empty())) {
|
||||
leftColumn->Add(new GameImageView(gamePath_, GameInfoFlags::ICON, 2.0f, new LinearLayoutParams(UI::Margins(0))));
|
||||
leftColumn->Add(new GameImageView(gamePath_, GameInfoFlags::ICON, 2.0f, new LinearLayoutParams(144 * 2, 80 * 2, UI::Margins(0))));
|
||||
}
|
||||
leftColumn->Add(mainGameInfo);
|
||||
} else {
|
||||
@@ -205,6 +300,18 @@ void GameScreen::CreateContentViews(UI::ViewGroup *parent) {
|
||||
}
|
||||
mainGameInfo->SetSpacing(3.0f);
|
||||
|
||||
if (pmf_player_available() && fileTypeHasIcon && (knownFlags_ & GameInfoFlags::ICON1_PMF) && !info_->icon1pmf.empty()) {
|
||||
std::string pmfData;
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(info_->lock);
|
||||
pmfData = info_->icon1pmf;
|
||||
}
|
||||
|
||||
if (!pmfData.empty()) {
|
||||
leftColumn->Add(new PMFView(pmfData, new LinearLayoutParams(144 * 2, 80 * 2, UI::Margins(0, 10))));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<GameDBInfo> dbInfos;
|
||||
const bool inGameDB = g_gameDB.GetGameInfos(info_->id_version, &dbInfos);
|
||||
|
||||
|
||||
Reference in new issue
Block a user