Merge pull request #20218 from hrydgard/misc-fixes

Misc fixes and cleanup, use DisableHLE with "sceCcc"
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2025-04-07 14:30:58 +02:00
commit 0dec3526a5
23 files changed
+173 -62

No files matched your search

+2 -1
View File
@@ -47,7 +47,8 @@ static void *g_assertCancelCallbackUserData = 0;
void SetAssertDialogParent(void *handle) {
#if PPSSPP_PLATFORM(WINDOWS)
g_dialogParent = (HWND)handle;
// I thought this would be nice, but for some reason the dialog becomes invisible.
// g_dialogParent = (HWND)handle;
#endif
}
+18 -7
View File
@@ -1016,7 +1016,6 @@ void TabHolder::AddTabDeferred(std::string_view title, std::function<ViewGroup *
tabTweens_.push_back(nullptr);
createFuncs_.push_back(createCb);
// Pre-create the first tab in a non-deferred way.
if (tabs_.size() == 1) {
EnsureTab(0);
}
@@ -1031,7 +1030,7 @@ void TabHolder::EnsureAllCreated() {
}
}
void TabHolder::EnsureTab(int index) {
bool TabHolder::EnsureTab(int index) {
_dbg_assert_(index >= 0 && index < createFuncs_.size());
if (!tabs_[index]) {
@@ -1045,16 +1044,24 @@ void TabHolder::EnsureTab(int index) {
contents_->Add(tabContents);
tabContents->ReplaceLayoutParams(new AnchorLayoutParams(FILL_PARENT, FILL_PARENT));
return true;
} else {
return false;
}
}
void TabHolder::SetCurrentTab(int tab, bool skipTween) {
bool TabHolder::SetCurrentTab(int tab, bool skipTween) {
if (tab >= (int)tabs_.size()) {
// Ignore
return;
return false;
}
EnsureTab(tab);
bool created = false;
if (tab != currentTab_) {
_dbg_assert_(tabs_[currentTab_]); // we should always have a tab to switch *from*.
created = EnsureTab(tab);
}
auto setupTween = [&](View *view, AnchorTranslateTween *&tween) {
_dbg_assert_(view != nullptr);
@@ -1100,9 +1107,10 @@ void TabHolder::SetCurrentTab(int tab, bool skipTween) {
tabs_[tab]->SetVisibility(V_VISIBLE);
currentTab_ = tab;
EnsureTab(currentTab_);
}
tabStrip_->SetSelection(tab, false);
return created;
}
EventReturn TabHolder::OnTabClick(EventParams &e) {
@@ -1132,7 +1140,10 @@ void TabHolder::PersistData(PersistStatus status, std::string anonId, PersistMap
case PERSIST_RESTORE:
if (buffer.size() == 1) {
SetCurrentTab(buffer[0], true);
if (SetCurrentTab(buffer[0], true)) {
// Re-run PersistData. TODO: Only need to do it for the new tab.
ViewGroup::PersistData(status, anonId, storage);
}
}
break;
}
+3 -2
View File
@@ -305,7 +305,8 @@ public:
void AddBack(UIScreen *parent);
void SetCurrentTab(int tab, bool skipTween = false);
// Returns true if the tab wasn't created before (but is now).
bool SetCurrentTab(int tab, bool skipTween = false);
int GetCurrentTab() const { return currentTab_; }
std::string DescribeLog() const override { return "TabHolder: " + View::DescribeLog(); }
@@ -323,7 +324,7 @@ public:
private:
void AddTabContents(std::string_view title, ViewGroup *tabContents);
EventReturn OnTabClick(EventParams &e);
void EnsureTab(int index);
bool EnsureTab(int index); // return true if it actually created a tab.
View *bannerView_ = nullptr;
LinearLayout *tabContainer_ = nullptr;
+2 -1
View File
@@ -125,7 +125,8 @@ enum class DisableHLEFlags : int {
sceMpeg = (1 << 4),
sceMp3 = (1 << 5),
sceParseHttp = (1 << 6),
Count = 7,
sceCcc = (1 << 7), // character conversion library.
Count = 8,
// TODO: Some of the networking libraries may be interesting candidates, like HTTP.
};
ENUM_CLASS_BITOPS(DisableHLEFlags);
+4 -3
View File
@@ -139,7 +139,7 @@ static const HLEModuleMeta g_moduleMeta[] = {
{"sceSsl_Module"},
{"sceDEFLATE_Library"},
{"sceMD5_Library"},
{"sceMemab"},
{"sceMemab"}, // Underlying AdHoc crypto library
{"sceAvcodec_driver"},
{"sceAudiocodec_Driver"},
{"sceAudiocodec"},
@@ -151,7 +151,7 @@ static const HLEModuleMeta g_moduleMeta[] = {
{"scePsmfP_library", "scePsmfPlayer", DisableHLEFlags::scePsmfPlayer},
{"scePsmfPlayer", "scePsmfPlayer", DisableHLEFlags::scePsmfPlayer},
{"sceSAScore", "sceSasCore"},
{"sceCcc_Library", "sceCcc"},
{"sceCcc_Library", "sceCcc", DisableHLEFlags::sceCcc},
{"SceParseHTTPheader_Library", "sceParseHttp", DisableHLEFlags::sceParseHttp},
{"SceParseURI_Library"},
// Guessing these names
@@ -192,7 +192,8 @@ DisableHLEFlags AlwaysDisableHLEFlags() {
// This will hide the checkbox in Developer Settings, too.
//
// PSMF testing issue: #20200
return DisableHLEFlags::scePsmf | DisableHLEFlags::scePsmfPlayer;
// sceCcc is simply a character conversion library, zero deps. If available we just load it.
return DisableHLEFlags::scePsmf | DisableHLEFlags::scePsmfPlayer | DisableHLEFlags::sceCcc;
}
// Process compat flags.
-1
View File
@@ -28,7 +28,6 @@
#include "Core/Reporting.h"
#include "Core/Config.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/HW/MediaEngine.h"
#include "Core/HW/BufferQueue.h"
#include "Core/HLE/sceKernel.h"
+60 -15
View File
@@ -131,6 +131,7 @@ static int __AudioCodecInitCommon(u32 ctxPtr, int codec, bool mono) {
// Special actions for some codecs.
switch (audioType) {
case PSP_CODEC_MP3:
_dbg_assert_(ctx->inited == 1);
ctx->mp3_9999 = 9999;
break;
case PSP_CODEC_AAC:
@@ -219,14 +220,38 @@ static int sceAudiocodecDecode(u32 ctxPtr, int codec) {
return hleLogInfo(Log::ME, 0, "codec %s", GetCodecName(codec));
}
// This is used by sceMp3, in Beats.
// Is the return value the only output?
static int sceAudiocodecGetInfo(u32 ctxPtr, int codec) {
ERROR_LOG_REPORT(Log::ME, "UNIMPL sceAudiocodecGetInfo(%08x, %i (%s))", ctxPtr, codec, GetCodecName(codec));
return 0;
if (codec < 0x1000 || codec >= 0x1006) {
return hleLogError(Log::ME, SCE_KERNEL_ERROR_BAD_ARGUMENT, "invalid codec");
}
auto ctx = PSPPointer<SceAudiocodecCodec>::Create(ctxPtr); // On game-owned heap, no need to allocate.
// Write some expected values.
switch (codec) {
case PSP_CODEC_MP3:
// When this is called, the caller has written:
// * inptr
// * outptr
// * formatOutSamples = 0x5A1
// Our response is written to a bunch of fields, but I really don't know much
// about what the values are - this is handled internally in the ME.
ctx->mp3_3 = 3;
ctx->mp3_9 = 9;
ctx->mp3_0 = 0;
ctx->mp3_1 = 1;
ctx->mp3_1_first = 1;
break;
}
return hleLogInfo(Log::ME, 0, "codec=%s", GetCodecName(codec));
}
static int sceAudiocodecCheckNeedMem(u32 ctxPtr, int codec) {
if (codec < 0x1000 || codec >= 0x1006) {
return hleLogError(Log::ME, 0x80000004, "invalid codec");
return hleLogError(Log::ME, SCE_KERNEL_ERROR_BAD_ARGUMENT, "invalid codec");
}
if (!Memory::IsValidRange(ctxPtr, sizeof(SceAudiocodecCodec))) {
@@ -247,6 +272,9 @@ static int sceAudiocodecCheckNeedMem(u32 ctxPtr, int codec) {
case 0x1001:
ctx->neededMem = 0x3de0;
break;
case 0x1002:
ctx->neededMem = 0x3b68;
break;
case 0x1003:
// Kosmodrones uses sceAudiocodec directly (no intermediate library).
INFO_LOG(Log::ME, "CheckNeedMem for codec %04x: format %02x %02x", ctx->unk40, ctx->unk41);
@@ -262,7 +290,15 @@ static int sceAudiocodecCheckNeedMem(u32 ctxPtr, int codec) {
static int sceAudiocodecGetEDRAM(u32 ctxPtr, int codec) {
auto ctx = PSPPointer<SceAudiocodecCodec>::Create(ctxPtr); // On game-owned heap, no need to allocate.
// TODO: Set this a bit more dynamically. No idea what the allocation algorithm is...
ctx->allocMem = 0x0018ea90;
switch (codec) {
case PSP_CODEC_MP3:
ctx->allocMem = 0x001B3124;
break;
case PSP_CODEC_AT3:
default:
ctx->allocMem = 0x0018ea90;
break;
}
ctx->edramAddr = (ctx->allocMem + 0x3f) & ~0x3f; // round up to 64 bytes.
return hleLogInfo(Log::ME, 0, "edram address set to %08x", ctx->edramAddr);
}
@@ -274,25 +310,34 @@ static int sceAudiocodecReleaseEDRAM(u32 ctxPtr, int id) {
return hleLogWarning(Log::ME, 0, "failed to remove decoder");
}
static int sceAudiocodecGetOutputBytes(u32 ctxPtr, int codec) {
static int sceAudiocodecGetOutputBytes(u32 ctxPtr, int codec, u32 outBytesAddr) {
if (!Memory::IsValid4AlignedAddress(outBytesAddr)) {
// Not tested
return hleLogError(Log::ME, SCE_MP3_ERROR_BAD_ADDR);
}
int bytes = 0;
switch (codec) {
case 0x1000: return hleLogInfo(Log::ME, 0x2000); // Atrac3+
case 0x1001: return hleLogInfo(Log::ME, 0x1000); // Atrac3
case PSP_CODEC_AT3PLUS: bytes = 0x2000; break;
case PSP_CODEC_AT3: bytes = 0x1000; break; // Atrac3
case PSP_CODEC_MP3: bytes = 0x1200; break;
default:
return hleLogWarning(Log::ME, 0, "Block size query not implemented for codec %04x", codec);
}
Memory::WriteUnchecked_U32(bytes, outBytesAddr);
return hleLogInfo(Log::ME, 0);
}
const HLEFunction sceAudiocodec[] = {
{0X70A703F8, &WrapI_UI<sceAudiocodecDecode>, "sceAudiocodecDecode", 'i', "xi"},
{0X5B37EB1D, &WrapI_UI<sceAudiocodecInit>, "sceAudiocodecInit", 'i', "xi"},
{0X8ACA11D5, &WrapI_UI<sceAudiocodecGetInfo>, "sceAudiocodecGetInfo", 'i', "xi"},
{0X3A20A200, &WrapI_UI<sceAudiocodecGetEDRAM>, "sceAudiocodecGetEDRAM", 'i', "xi"},
{0X29681260, &WrapI_UI<sceAudiocodecReleaseEDRAM>, "sceAudiocodecReleaseEDRAM", 'i', "xi"},
{0X9D3F790C, &WrapI_UI<sceAudiocodecCheckNeedMem>, "sceAudiocodecCheckNeedMem", 'i', "xi"},
{0X59176A0F, &WrapI_UI<sceAudiocodecGetOutputBytes>, "sceAudiocodecGetOutputBytes", 'i', "xxx" }, // params are context, codec, outptr
{0X3DD7EE1A, &WrapI_UI<sceAudiocodecInitMono>, "sceAudiocodecInitMono", 'i', "xi"}, // Used by sceAtrac for MOut* functions.
{0X70A703F8, &WrapI_UI<sceAudiocodecDecode>, "sceAudiocodecDecode", 'i', "xx"},
{0X5B37EB1D, &WrapI_UI<sceAudiocodecInit>, "sceAudiocodecInit", 'i', "xx"},
{0X8ACA11D5, &WrapI_UI<sceAudiocodecGetInfo>, "sceAudiocodecGetInfo", 'i', "xx"},
{0X3A20A200, &WrapI_UI<sceAudiocodecGetEDRAM>, "sceAudiocodecGetEDRAM", 'i', "xx"},
{0X29681260, &WrapI_UI<sceAudiocodecReleaseEDRAM>, "sceAudiocodecReleaseEDRAM", 'i', "xx"},
{0X9D3F790C, &WrapI_UI<sceAudiocodecCheckNeedMem>, "sceAudiocodecCheckNeedMem", 'i', "xx"},
{0X59176A0F, &WrapI_UIU<sceAudiocodecGetOutputBytes>, "sceAudiocodecGetOutputBytes", 'i', "xxp" }, // params are context, codec, outptr
{0X3DD7EE1A, &WrapI_UI<sceAudiocodecInitMono>, "sceAudiocodecInitMono", 'i', "xx"}, // Used by sceAtrac for MOut* functions.
};
void Register_sceAudiocodec() {
+5 -5
View File
@@ -67,16 +67,16 @@ struct SceAudiocodecCodec {
s32 unk48; // 30 Atrac3 (non-+) related. Zero with Atrac3+.
s32 unk52; // 34
s32 mp3_9999; // 38 // unk56
s32 unk60;
s32 mp3_3; // unk60 gets the value 3
s32 unk64; // Atrac3+ size related
s32 unk68;
s32 unk72;
s32 mp3_9;
s32 mp3_0;
s32 unk76;
s32 unk80;
s32 unk84;
s32 mp3_1_first;
s32 unk88;
s32 unk92;
s32 unk96;
s32 mp3_1;
s32 unk100;
u32 allocMem; // 104
// make sure the size is 128
+9 -3
View File
@@ -1180,9 +1180,15 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
// If we've made it this far, it should be safe to dump.
// Copy the name to ensure it's null terminated.
char name[32]{};
strncpy(name, head->modname, ARRAY_SIZE(head->modname));
DumpFileIfEnabled(ptr, (u32)elfSize, name, DumpFileType::EBOOT);
// TODO: How do we determine if it's the eboot?
if (endsWith(filename, "BOOT.BIN")) {
DumpFileIfEnabled(ptr, (u32)elfSize, "EBOOT.BIN", DumpFileType::EBOOT);
} else {
char name[32]{};
strncpy(name, head->modname, ARRAY_SIZE(head->modname));
DumpFileIfEnabled(ptr, (u32)elfSize, name, DumpFileType::PRX);
}
}
}
-1
View File
@@ -76,7 +76,6 @@
#include "Core/HLE/FunctionWrappers.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/HLE/sceMp3.h"
#include "Core/HW/MediaEngine.h"
#include "Core/HW/SimpleAudioDec.h"
#include "Core/MemMap.h"
#include "Core/Reporting.h"
+2
View File
@@ -15,6 +15,8 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
// NOTE: See note in header file. scePsmf/scePsmf are now unmaintained legacy.
#include "Common/Serialize/Serializer.h"
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/Serialize/SerializeMap.h"
+6
View File
@@ -15,6 +15,12 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
// NOTE: This is now unmaintained legacy code. scePsmf/scePsmfPlayer is just a wrapper over sceMpeg
// which is always shipped by games that use it, so we simply load the libraries now and focus
// on emulating sceMpeg as accurately as possible. We might actually go one step deeper if we can
// figure out sceVideocodec, as sceMpeg is also often shipped.
#pragma once
void Register_scePsmf();
+1 -1
View File
@@ -283,7 +283,7 @@ static u32 _sceSasCoreWithMix(u32 core, u32 inoutAddr, int leftVolume, int right
return hleReportError(Log::sceSas, SCE_SAS_ERROR_INVALID_PARAMETER, "invalid address");
}
if (sas->outputMode == PSP_SAS_OUTPUTMODE_RAW) {
return hleReportError(Log::sceSas, 0x80000004, "unsupported outputMode");
return hleReportError(Log::sceSas, SCE_KERNEL_ERROR_BAD_ARGUMENT, "unsupported outputMode");
}
if (!__KernelIsDispatchEnabled()) {
return hleLogError(Log::sceSas, SCE_KERNEL_ERROR_CAN_NOT_WAIT, "dispatch disabled");
+1 -1
View File
@@ -532,7 +532,7 @@ u32 GPUCommon::Continue(bool *runList) {
else
{
if (sceKernelGetCompiledSdkVersion() >= 0x02000000)
return 0x80000004;
return 0x80000004; // matches SCE_KERNEL_ERROR_BAD_ARGUMENT but doesn't really seem like it. Maybe that error code is more general.
return -1;
}
+3
View File
@@ -1283,6 +1283,9 @@ void EmuScreen::deviceLost() {
UIScreen::deviceLost();
if (imguiInited_) {
if (imDebugger_) {
imDebugger_->DeviceLost();
}
ImGui_ImplThin3d_DestroyDeviceObjects();
}
}
+3 -2
View File
@@ -474,6 +474,7 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings)
PopupMultiChoice *depthRasterMode = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iDepthRasterMode, gr->T("Lens flare occlusion"), depthRasterModes, 0, ARRAY_SIZE(depthRasterModes), I18NCat::GRAPHICS, screenManager()));
depthRasterMode->SetDisabledPtr(&g_Config.bSoftwareRendering);
depthRasterMode->SetChoiceIcon(3, ImageID("I_WARNING")); // It's a performance trap.
CheckBox *texBackoff = graphicsSettings->Add(new CheckBox(&g_Config.bTextureBackoffCache, gr->T("Lazy texture caching", "Lazy texture caching (speedup)")));
texBackoff->SetDisabledPtr(&g_Config.bSoftwareRendering);
@@ -1913,8 +1914,6 @@ void DeveloperToolsScreen::CreateViews() {
cpuTests->SetEnabled(TestsAvailable());
#endif
list->Add(new CheckBox(&g_Config.bUseOldAtrac, dev->T("Use the old sceAtrac implementation")));
AddOverlayList(list, screenManager());
list->Add(new CheckBox(&g_Config.bEnableLogging, dev->T("Enable Logging")))->OnClick.Handle(this, &DeveloperToolsScreen::OnLoggingChanged);
@@ -1990,6 +1989,8 @@ void DeveloperToolsScreen::CreateViews() {
auto displayRefreshRate = list->Add(new PopupSliderChoice(&g_Config.iDisplayRefreshRate, 60, 1000, 60, dev->T("Display refresh rate"), 1, screenManager()));
displayRefreshRate->SetFormat(si->T("%d Hz"));
list->Add(new CheckBox(&g_Config.bUseOldAtrac, dev->T("Use the old sceAtrac implementation")));
list->Add(new ItemHeader("Dump file types"));
list->Add(new BitCheckBox(&g_Config.iDumpFileTypes, (int)DumpFileType::EBOOT, dev->T("Dump Decrypted Eboot", "Dump Decrypted EBOOT.BIN (If Encrypted) When Booting Game")));
list->Add(new BitCheckBox(&g_Config.iDumpFileTypes, (int)DumpFileType::PRX, dev->T("PRX")));
+25 -10
View File
@@ -649,12 +649,28 @@ static void DrawInternals(ImConfig &cfg) {
{DIRECTORY_CUSTOM_THEMES, "CUSTOM_THEMES"},
};
if (ImGui::CollapsingHeader("Directories", ImGuiTreeNodeFlags_DefaultOpen)) {
if (ImGui::CollapsingHeader("GetSysDirectory")) {
for (auto &dir : dirs) {
ImGui::Text("%s: %s", dir.name, GetSysDirectory(dir.dir).c_str());
}
}
if (ImGui::CollapsingHeader("Memory")) {
ImGui::Text("Base pointer: %p", Memory::base);
ImGui::Text("Main memory size: %08x", Memory::g_MemorySize);
if (ImGui::Button("Copy to clipboard")) {
System_CopyStringToClipboard(StringFromFormat("0x%p", Memory::base));
}
}
if (ImGui::CollapsingHeader("ImGui state")) {
const auto &io = ImGui::GetIO();
ImGui::Text("WantCaptureMouse: %s", BoolStr(io.WantCaptureMouse));
ImGui::Text("WantCaptureKeyboard: %s", BoolStr(io.WantCaptureKeyboard));
ImGui::Text("WantCaptureMouseUnlessPopupClose: %s", BoolStr(io.WantCaptureMouseUnlessPopupClose));
ImGui::Text("WantTextInput: %s", BoolStr(io.WantTextInput));
}
ImGui::End();
}
@@ -672,15 +688,6 @@ static void DrawAdhoc(ImConfig &cfg) {
default: break;
}
auto &io = ImGui::GetIO();
/*
ImGui::Text("WantCaptureMouse: %s", BoolStr(io.WantCaptureMouse));
ImGui::Text("WantCaptureKeyboard: %s", BoolStr(io.WantCaptureKeyboard));
ImGui::Text("WantCaptureMouseUnlessPopupClose: %s", BoolStr(io.WantCaptureMouseUnlessPopupClose));
ImGui::Text("WantTextInput: %s", BoolStr(io.WantTextInput));
*/
ImGui::Text("sceNetAdhoc inited: %s", BoolStr(netAdhocInited));
ImGui::Text("sceNetAdhocctl inited: %s", BoolStr(netAdhocctlInited));
ImGui::Text("sceNetAdhocctl state: %s", AdhocCtlStateToString(NetAdhocctl_GetState()));
@@ -1710,6 +1717,9 @@ void DrawHLEModules(ImConfig &config) {
case 'I': amask[i] = 'd'; break;
case 'f':
case 'F': amask[i] = 'x'; break;
default:
// others go straight through (p)
break;
}
}
w.F("%s 0x%08x %d %s", func.name, func.ID, strlen(func.argmask), amask.c_str()).endl();
@@ -2422,6 +2432,11 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, ImConfig &cfg, ImContro
ImGui::End();
}
void ImDebugger::DeviceLost() {
pixelViewer_.DeviceLost();
geDebugger_.DeviceLost();
}
Path ImDebugger::ConfigPath() {
return GetSysDirectory(DIRECTORY_SYSTEM) / "imdebugger.ini";
}
+1
View File
@@ -237,6 +237,7 @@ public:
void PostCmd(ImCommand cmd) {
externalCommand_ = cmd;
}
void DeviceLost();
private:
Path ConfigPath();
+22 -1
View File
@@ -197,6 +197,13 @@ ImGePixelViewer::~ImGePixelViewer() {
texture_->Release();
}
void ImGePixelViewer::DeviceLost() {
if (texture_) {
texture_->Release();
texture_ = nullptr;
}
}
bool ImGePixelViewer::Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *draw, float zoom) {
if (dirty_) {
UpdateTexture(draw);
@@ -269,8 +276,9 @@ void ImGePixelViewer::UpdateTexture(Draw::DrawContext *draw) {
int bpp = BufferFormatBytesPerPixel(format);
int srcBytes = width * stride * bpp;
if (stride > width)
if (stride > width) {
srcBytes -= stride - width;
}
if (Memory::ValidSize(addr, srcBytes) != srcBytes) {
// TODO: Show a message that the address is out of bounds.
return;
@@ -375,6 +383,13 @@ ImGeReadbackViewer::~ImGeReadbackViewer() {
delete[] data_;
}
void ImGeReadbackViewer::DeviceLost() {
if (texture_) {
texture_->Release();
texture_ = nullptr;
}
}
bool ImGeReadbackViewer::Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *draw, float zoom) {
FramebufferManagerCommon *fbmanager = gpuDebug->GetFramebufferManagerCommon();
if (!vfb || !vfb->fbo || !fbmanager) {
@@ -461,6 +476,7 @@ bool ImGeReadbackViewer::Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *dr
bool ImGeReadbackViewer::FormatValueAt(char *buf, size_t bufSize, int x, int y) const {
if (!vfb || !vfb->fbo || !data_) {
snprintf(buf, bufSize, "N/A");
return true;
}
int bpp = (int)Draw::DataFormatSizeInBytes(readbackFmt_);
int offset = (y * vfb->fbo->Width() + x) * bpp;
@@ -751,6 +767,11 @@ ImGeDebuggerWindow::ImGeDebuggerWindow() {
selectedAspect_ = Draw::Aspect::COLOR_BIT;
}
void ImGeDebuggerWindow::DeviceLost() {
rbViewer_.DeviceLost();
swViewer_.DeviceLost();
}
void ImGeDebuggerWindow::NotifyStep() {
reloadPreview_ = true;
disasmView_.NotifyStep();
+6
View File
@@ -70,6 +70,7 @@ struct ImGePixelViewer : public PixelLookup {
dirty_ = true;
}
bool FormatValueAt(char *buf, size_t bufSize, int x, int y) const override;
void DeviceLost();
uint32_t addr = 0x04110000;
uint16_t stride = 512;
@@ -95,6 +96,7 @@ struct ImGeReadbackViewer : public PixelLookup {
dirty_ = true;
}
bool FormatValueAt(char *buf, size_t bufSize, int x, int y) const override;
void DeviceLost();
// TODO: This is unsafe! If you load state for example with the debugger open...
// We need to re-fetch this each frame from the parameters.
@@ -124,6 +126,9 @@ public:
viewer_.stride = stride;
viewer_.format = format;
}
void DeviceLost() {
viewer_.DeviceLost();
}
private:
ImGePixelViewer viewer_;
@@ -140,6 +145,7 @@ public:
return "GE Debugger";
}
void NotifyStep();
void DeviceLost();
private:
ImGeDisasmView disasmView_;
-1
View File
@@ -94,7 +94,6 @@ void TabbedUIDialogScreenWithGameBackground::CreateViews() {
noSearchResults_ = searchSettings->Add(new TextView("", new LinearLayoutParams(Margins(20, 5))));
}, true);
}
}
}
-1
View File
@@ -67,7 +67,6 @@ void MainThread_Start(bool separateEmuThread) {
void MainThread_Stop() {
// Already stopped?
UpdateUIState(UISTATE_EXIT);
Core_Stop();
_dbg_assert_(mainThread.joinable());
mainThread.join();
}
-6
View File
@@ -1247,12 +1247,6 @@ ULJS19067 = true
ULAS42247 = true
ULAS42318 = true
[DisableFirstFrameReadback]
# SOCOM: Fireteam Bravo 3 (see issue #18958, hopefully fixes crash in Stockpile mission, #10461)
UCES-01242 = true
NPJG-00035 = true
NPHG-00032 = true
[MpegAvcWarmUp]
# God Eater issue #13527 ,It is custom mpeg library that required sceMpegGetAvcAu return ERROR_MPEG_NO_DATA but break FIFA 14 issue #14086
# God Eater 1