mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Merge pull request #20207 from hrydgard/hle-work
DisableHLE: Add compat flag for sceFont, add ability to make flags permanent
This commit is contained in:
12 files changed
+93
-58
No files matched your search
@@ -1,3 +1,4 @@
|
||||
#include <algorithm>
|
||||
#include <cstdarg>
|
||||
#include <climits>
|
||||
#include <cstdio>
|
||||
@@ -166,7 +167,8 @@ StringWriter &StringWriter::F(const char *format, ...) {
|
||||
}
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
p_ += vsnprintf(p_, remainder, format, args);
|
||||
int wouldHaveBeenWritten = vsnprintf(p_, remainder, format, args);
|
||||
p_ += std::min((int)remainder, wouldHaveBeenWritten);
|
||||
va_end(args);
|
||||
return *this;
|
||||
}
|
||||
@@ -149,6 +149,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) {
|
||||
CheckSetting(iniFile, gameID, "ForceEnableGPUReadback", &flags_.ForceEnableGPUReadback);
|
||||
CheckSetting(iniFile, gameID, "UseFFMPEGFindStreamInfo", &flags_.UseFFMPEGFindStreamInfo);
|
||||
CheckSetting(iniFile, gameID, "SoftwareRasterDepth", &flags_.SoftwareRasterDepth);
|
||||
CheckSetting(iniFile, gameID, "DisableHLESceFont", &flags_.DisableHLESceFont);
|
||||
}
|
||||
|
||||
void Compatibility::CheckVRSettings(IniFile &iniFile, const std::string &gameID) {
|
||||
|
||||
@@ -112,6 +112,7 @@ struct CompatFlags {
|
||||
bool ForceEnableGPUReadback;
|
||||
bool UseFFMPEGFindStreamInfo;
|
||||
bool SoftwareRasterDepth;
|
||||
bool DisableHLESceFont;
|
||||
};
|
||||
|
||||
struct VRCompat {
|
||||
|
||||
+2
-3
@@ -124,9 +124,8 @@ enum class DisableHLEFlags : int {
|
||||
scePsmfPlayer = (1 << 3),
|
||||
sceMpeg = (1 << 4),
|
||||
sceMp3 = (1 << 5),
|
||||
sceJpeg = (1 << 6),
|
||||
sceParseHttp = (1 << 7),
|
||||
Count = 8,
|
||||
sceParseHttp = (1 << 6),
|
||||
Count = 7,
|
||||
// TODO: Some of the networking libraries may be interesting candidates, like HTTP.
|
||||
};
|
||||
ENUM_CLASS_BITOPS(DisableHLEFlags);
|
||||
|
||||
+30
-10
@@ -122,6 +122,7 @@ static const HLEModuleMeta g_moduleMeta[] = {
|
||||
{"SceFont_Library", "sceLibFttt", DisableHLEFlags::sceFont},
|
||||
{"SceHttp_Library", "sceHttp"},
|
||||
{"sceMpeg_library", "sceMpeg", DisableHLEFlags::sceMpeg},
|
||||
{"sceMp3_Library", "sceMp3", DisableHLEFlags::sceMp3},
|
||||
{"sceNetAdhocctl_Library"},
|
||||
{"sceNetAdhocDownload_Library"},
|
||||
{"sceNetAdhocMatching_Library"},
|
||||
@@ -154,9 +155,9 @@ static const HLEModuleMeta g_moduleMeta[] = {
|
||||
{"SceParseHTTPheader_Library", "sceParseHttp", DisableHLEFlags::sceParseHttp},
|
||||
{"SceParseURI_Library"},
|
||||
// Guessing these names
|
||||
{"sceJpeg", "sceJpeg", DisableHLEFlags::sceJpeg},
|
||||
{"sceJpeg_library", "sceJpeg", DisableHLEFlags::sceJpeg},
|
||||
{"sceJpeg_Library", "sceJpeg", DisableHLEFlags::sceJpeg},
|
||||
{"sceJpeg", "sceJpeg"},
|
||||
{"sceJpeg_library", "sceJpeg"},
|
||||
{"sceJpeg_Library", "sceJpeg"},
|
||||
};
|
||||
|
||||
const HLEModuleMeta *GetHLEModuleMeta(std::string_view modname) {
|
||||
@@ -186,20 +187,39 @@ const HLEModuleMeta *GetHLEModuleMetaByImport(std::string_view importModuleName)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DisableHLEFlags AlwaysDisableHLEFlags() {
|
||||
// Once a module seems stable to load properly, we'll graduate it here.
|
||||
// This will hide the checkbox, too.
|
||||
// return DisableHLEFlags::scePsmf | DisableHLEFlags::scePsmfPlayer;
|
||||
return (DisableHLEFlags)0;
|
||||
}
|
||||
|
||||
// Process compat flags.
|
||||
static DisableHLEFlags GetDisableHLEFlags() {
|
||||
DisableHLEFlags flags = (DisableHLEFlags)g_Config.iDisableHLE | AlwaysDisableHLEFlags();
|
||||
if (PSP_CoreParameter().compat.flags().DisableHLESceFont) {
|
||||
flags |= DisableHLEFlags::sceFont;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
// Note: name is the modname from prx, not the export module name!
|
||||
bool ShouldHLEModule(std::string_view modname, bool *wasDisabled) {
|
||||
if (wasDisabled) {
|
||||
*wasDisabled = false;
|
||||
bool ShouldHLEModule(std::string_view modname, bool *wasDisabledManually) {
|
||||
if (wasDisabledManually) {
|
||||
*wasDisabledManually = false;
|
||||
}
|
||||
const HLEModuleMeta *meta = GetHLEModuleMeta(modname);
|
||||
if (!meta) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool disabled = meta->disableFlag & (DisableHLEFlags)g_Config.iDisableHLE;
|
||||
bool disabled = meta->disableFlag & GetDisableHLEFlags();
|
||||
if (disabled) {
|
||||
if (wasDisabled) {
|
||||
*wasDisabled = true;
|
||||
if (wasDisabledManually) {
|
||||
// We don't show notifications if a flag has "graduated".
|
||||
if (!(meta->disableFlag & AlwaysDisableHLEFlags())) {
|
||||
*wasDisabledManually = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -210,7 +230,7 @@ bool ShouldHLEModuleByImportName(std::string_view name) {
|
||||
// Check our special metadata lookup. Should probably be merged with the main one.
|
||||
const HLEModuleMeta *meta = GetHLEModuleMetaByImport(name);
|
||||
if (meta) {
|
||||
bool disabled = meta->disableFlag & (DisableHLEFlags)g_Config.iDisableHLE;
|
||||
bool disabled = meta->disableFlag & GetDisableHLEFlags();
|
||||
return !disabled;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -107,7 +107,7 @@ struct HLEModuleMeta {
|
||||
|
||||
const HLEModuleMeta *GetHLEModuleMetaByFlag(DisableHLEFlags flag);
|
||||
const HLEModuleMeta *GetHLEModuleMeta(std::string_view modname);
|
||||
bool ShouldHLEModule(std::string_view modname, bool *wasDisabled = nullptr);
|
||||
bool ShouldHLEModule(std::string_view modname, bool *wasDisabledManually = nullptr);
|
||||
bool ShouldHLEModuleByImportName(std::string_view importModuleName);
|
||||
|
||||
const char *GetHLEFuncName(std::string_view module, u32 nib);
|
||||
@@ -121,6 +121,7 @@ u32 GetNibByName(std::string_view module, std::string_view function);
|
||||
void RegisterHLEModule(std::string_view name, int numFunctions, const HLEFunction *funcTable);
|
||||
int GetNumRegisteredHLEModules();
|
||||
const HLEModule *GetHLEModuleByIndex(int index);
|
||||
DisableHLEFlags AlwaysDisableHLEFlags();
|
||||
|
||||
// Run the current thread's callbacks after the syscall finishes.
|
||||
void hleCheckCurrentCallbacks();
|
||||
|
||||
+37
-34
@@ -49,33 +49,26 @@ static_assert(sizeof(SceAudiocodecCodec) == 128);
|
||||
//
|
||||
// Known byte values.
|
||||
|
||||
void CalculateInputBytesAndChannels(const SceAudiocodecCodec *ctx, int codec, int *inputBytes, int *channels) {
|
||||
void CalculateInputBytesAndChannelsAt3Plus(const SceAudiocodecCodec *ctx, int *inputBytes, int *channels) {
|
||||
*inputBytes = 0;
|
||||
*channels = 2;
|
||||
switch (codec) {
|
||||
case PSP_CODEC_AT3PLUS:
|
||||
{
|
||||
int size = ctx->unk41 * 8 + 8;
|
||||
// No idea if this is accurate, this is just a guess...
|
||||
if (ctx->unk40 & 8) {
|
||||
*channels = 2;
|
||||
} else {
|
||||
*channels = 1;
|
||||
}
|
||||
switch (size) {
|
||||
case 0x118:
|
||||
case 0x178:
|
||||
case 0x230:
|
||||
case 0x2E8:
|
||||
// These have been seen before, let's return it.
|
||||
*inputBytes = size;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int size = ctx->unk41 * 8 + 8;
|
||||
// No idea if this is accurate, this is just a guess...
|
||||
if (ctx->unk40 & 8) {
|
||||
*channels = 2;
|
||||
} else {
|
||||
*channels = 1;
|
||||
}
|
||||
switch (size) {
|
||||
case 0x118:
|
||||
case 0x178:
|
||||
case 0x230:
|
||||
case 0x2E8:
|
||||
// These have been seen before, let's return it.
|
||||
*inputBytes = size;
|
||||
return;
|
||||
default:
|
||||
// Unsupported codec, ignore.
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -118,29 +111,39 @@ void __AudioCodecShutdown() {
|
||||
|
||||
// TODO: Actually support mono output.
|
||||
static int __AudioCodecInitCommon(u32 ctxPtr, int codec, bool mono) {
|
||||
PSPAudioType audioType = (PSPAudioType)codec;
|
||||
const PSPAudioType audioType = (PSPAudioType)codec;
|
||||
if (!IsValidCodec(audioType)) {
|
||||
return hleLogError(Log::ME, SCE_KERNEL_ERROR_OUT_OF_RANGE, "Invalid codec");
|
||||
}
|
||||
|
||||
if (removeDecoder(ctxPtr)) {
|
||||
WARN_LOG_REPORT(Log::HLE, "sceAudiocodecInit(%08x, %d): replacing existing context", ctxPtr, codec);
|
||||
}
|
||||
|
||||
// Initialize the codec memory.
|
||||
auto ctx = PSPPointer<SceAudiocodecCodec>::Create(ctxPtr);
|
||||
ctx->unk_init = 0x5100601; // Firmware version indicator?
|
||||
ctx->err = 0;
|
||||
|
||||
if (codec == 0x1002) {
|
||||
int inFrameBytes = 0;
|
||||
int channels = 2;
|
||||
|
||||
// Special actions for some codecs.
|
||||
switch (audioType) {
|
||||
case PSP_CODEC_MP3:
|
||||
ctx->mp3_9999 = 9999;
|
||||
break;
|
||||
case PSP_CODEC_AAC:
|
||||
// AAC / mp4
|
||||
// offsets 40-42 are a 24-bit LE number specifying the sample rate. It's 32000, 44100 or 48000.
|
||||
// neededMem has been set to 0x18f20.
|
||||
break;
|
||||
case PSP_CODEC_AT3PLUS:
|
||||
CalculateInputBytesAndChannelsAt3Plus(ctx, &inFrameBytes, &channels);
|
||||
break;
|
||||
}
|
||||
|
||||
// Create audio decoder for given audio codec and push it into AudioList
|
||||
if (removeDecoder(ctxPtr)) {
|
||||
WARN_LOG_REPORT(Log::HLE, "sceAudiocodecInit(%08x, %d): replacing existing context", ctxPtr, codec);
|
||||
}
|
||||
|
||||
int inFrameBytes;
|
||||
int channels;
|
||||
CalculateInputBytesAndChannels(ctx, codec, &inFrameBytes, &channels);
|
||||
|
||||
if (inFrameBytes) {
|
||||
INFO_LOG(Log::ME, "sceAudioDecoder: Creating codec with %04x frame size and %d channels, codec %04x", inFrameBytes, channels, codec);
|
||||
AudioDecoder *decoder = CreateAudioDecoder(audioType, 44100, channels, inFrameBytes);
|
||||
@@ -177,7 +180,7 @@ static int sceAudiocodecDecode(u32 ctxPtr, int codec) {
|
||||
auto ctx = PSPPointer<SceAudiocodecCodec>::Create(ctxPtr); // On game-owned heap, no need to allocate.
|
||||
int inFrameBytes;
|
||||
int channels;
|
||||
CalculateInputBytesAndChannels(ctx, codec, &inFrameBytes, &channels);
|
||||
CalculateInputBytesAndChannelsAt3Plus(ctx, &inFrameBytes, &channels);
|
||||
|
||||
// find a decoder in audioList
|
||||
auto decoder = findDecoder(ctxPtr);
|
||||
|
||||
@@ -26,7 +26,7 @@ enum PSPAudioType {
|
||||
PSP_CODEC_AT3PLUS = 0x00001000,
|
||||
PSP_CODEC_AT3 = 0x00001001,
|
||||
PSP_CODEC_MP3 = 0x00001002,
|
||||
PSP_CODEC_AAC = 0x00001003,
|
||||
PSP_CODEC_AAC = 0x00001003, // sceMp4 decodes this in an mp4 container
|
||||
PSP_CODEC_WMA = 0x00001005,
|
||||
};
|
||||
|
||||
|
||||
@@ -1058,7 +1058,7 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
|
||||
}
|
||||
|
||||
if (wasDisabled) {
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, StringFromFormat("HLE for %s has been manually disabled", head->modname));
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, StringFromFormat("HLE for '%s' has been manually disabled", head->modname));
|
||||
}
|
||||
const u8 *in = ptr;
|
||||
const auto isGzip = head->comp_attribute & 1;
|
||||
|
||||
+6
-3
@@ -787,9 +787,12 @@ const HLEFunction sceReg[] = {
|
||||
{ 0x2D211135, &WrapI_IUI<sceRegGetKeys>, "sceRegGetKeys", 'i', "ipi" },
|
||||
{ 0xC5768D02, &WrapI_ICUU<sceRegGetKeyInfoByName>, "sceRegGetKeyInfoByName", 'i', "isxx" },
|
||||
{ 0x30BE0259, &WrapI_ICUU<sceRegGetKeyValueByName>, "sceRegGetKeyValueByName", 'i', "isxx" },
|
||||
// { 0x4CA16893, &WrapI_I<sceRegRemoveCategory>, "sceRegRemoveCategory", 'i', "i" },
|
||||
// { 0x3615BC87, &WrapI_I<sceRegRemoveKey>, "sceRegRemoveKey", 'i', "i" },
|
||||
// { 0x9B25EDF1, &WrapI_I<sceRegExit>, "sceRegExit", 'i', "i" },
|
||||
{ 0x4CA16893, &WrapI_IC<sceRegRemoveCategory>, "sceRegRemoveCategory", 'i', "i" },
|
||||
{ 0x3615BC87, nullptr, "sceRegRemoveKey", 'i', "i" },
|
||||
{ 0x9B25EDF1, nullptr, "sceRegExit", 'i', "i" },
|
||||
// TODO: Add test for these.
|
||||
{ 0xBE8C1263, nullptr, "sceRegGetCategoryNumAtRoot", 'i', "ii" },
|
||||
{ 0x835ECE6F, nullptr, "sceRegGetCategoryListAtRoot", 'i', "ipi" },
|
||||
};
|
||||
|
||||
void Register_sceReg() {
|
||||
|
||||
@@ -1996,11 +1996,16 @@ void DeveloperToolsScreen::CreateViews() {
|
||||
list->Add(new BitCheckBox(&g_Config.iDumpFileTypes, (int)DumpFileType::Atrac3, dev->T("Atrac3/3+")));
|
||||
|
||||
list->Add(new ItemHeader("Disable HLE (experimental! Not expected to work yet)"));
|
||||
|
||||
for (int i = 0; i < (int)DisableHLEFlags::Count; i++) {
|
||||
DisableHLEFlags flag = (DisableHLEFlags)(1 << i);
|
||||
const HLEModuleMeta *meta = GetHLEModuleMetaByFlag(flag);
|
||||
if (meta) {
|
||||
list->Add(new BitCheckBox(&g_Config.iDisableHLE, (int)flag, meta->modname));
|
||||
|
||||
// Show a checkbox, unless the setting has graduated to always on.
|
||||
if (!(flag & AlwaysDisableHLEFlags())) {
|
||||
const HLEModuleMeta *meta = GetHLEModuleMetaByFlag(flag);
|
||||
if (meta) {
|
||||
list->Add(new BitCheckBox(&g_Config.iDisableHLE, (int)flag, meta->modname));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1500,7 +1500,7 @@ static void DrawModules(const MIPSDebugInterface *debug, ImConfig &cfg, ImContro
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 255, 255, 170));
|
||||
}
|
||||
ImGui::Text("%s %d.%d (%s)\n", mod->GetName(), mod->nm.version[1], mod->nm.version[0], mod->isFake ? "FAKE/HLE" : "normal");
|
||||
ImGui::Text("Attr: %08x (%s)\n", (mod->nm.attribute & 0x1000) ? "Kernel" : "User");
|
||||
ImGui::Text("Attr: %08x (%s)\n", mod->nm.attribute, (mod->nm.attribute & 0x1000) ? "Kernel" : "User");
|
||||
char buf[512];
|
||||
mod->GetLongInfo(buf, sizeof(buf));
|
||||
ImGui::TextUnformatted(buf);
|
||||
|
||||
Reference in new issue
Block a user