Skip to content

Commit

Permalink
Merge pull request #13 from hrydgard/master
Browse files Browse the repository at this point in the history
Merge pull request hrydgard#17297 from hrydgard/socom-clut-trickery
  • Loading branch information
fengjixuchui authored Apr 18, 2023
2 parents a235e0d + a20c620 commit 6dafe86
Show file tree
Hide file tree
Showing 31 changed files with 303 additions and 125 deletions.
1 change: 1 addition & 0 deletions Core/Compatibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) {
CheckSetting(iniFile, gameID, "BlockTransferDepth", &flags_.BlockTransferDepth);
CheckSetting(iniFile, gameID, "DaxterRotatedAnalogStick", &flags_.DaxterRotatedAnalogStick);
CheckSetting(iniFile, gameID, "ForceMaxDepthResolution", &flags_.ForceMaxDepthResolution);
CheckSetting(iniFile, gameID, "SOCOMClut8Replacement", &flags_.SOCOMClut8Replacement);
}

void Compatibility::CheckVRSettings(IniFile &iniFile, const std::string &gameID) {
Expand Down
1 change: 1 addition & 0 deletions Core/Compatibility.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ struct CompatFlags {
bool BlockTransferDepth;
bool DaxterRotatedAnalogStick;
bool ForceMaxDepthResolution;
bool SOCOMClut8Replacement;
};

struct VRCompat {
Expand Down
2 changes: 1 addition & 1 deletion Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ static const ConfigSetting controlSettings[] = {
ConfigSetting("AnalogIsCircular", &g_Config.bAnalogIsCircular, false, CfgFlag::PER_GAME),
ConfigSetting("AnalogAutoRotSpeed", &g_Config.fAnalogAutoRotSpeed, 8.0f, CfgFlag::PER_GAME),

ConfigSetting("AnalogLimiterDeadzone", &g_Config.fAnalogLimiterDeadzone, 0.25f, CfgFlag::DEFAULT),
ConfigSetting("AnalogLimiterDeadzone", &g_Config.fAnalogLimiterDeadzone, 0.6f, CfgFlag::DEFAULT),

ConfigSetting("LeftStickHeadScale", &g_Config.fLeftStickHeadScale, 1.0f, CfgFlag::PER_GAME),
ConfigSetting("RightStickHeadScale", &g_Config.fRightStickHeadScale, 1.0f, CfgFlag::PER_GAME),
Expand Down
1 change: 1 addition & 0 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ struct Config {
// Auto rotation speed
float fAnalogAutoRotSpeed;

// Sets up how much the analog limiter button restricts digital->analog input.
float fAnalogLimiterDeadzone;

bool bMouseControl;
Expand Down
36 changes: 31 additions & 5 deletions Core/ControlMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,23 @@ void ControlMapper::SetPSPAxis(int device, int stick, char axis, float value) {

if (!ignore) {
history_[stick][axisId] = value;
float x, y;
ConvertAnalogStick(history_[stick][0], history_[stick][1], &x, &y);
converted_[stick][0] = x;
converted_[stick][1] = y;
setPSPAnalog_(stick, x, y);

UpdateAnalogOutput(stick);
}
}

void ControlMapper::UpdateAnalogOutput(int stick) {
float x, y;
ConvertAnalogStick(history_[stick][0], history_[stick][1], &x, &y);
if (virtKeyOn_[VIRTKEY_ANALOG_LIGHTLY - VIRTKEY_FIRST]) {
x *= g_Config.fAnalogLimiterDeadzone;
y *= g_Config.fAnalogLimiterDeadzone;
}
converted_[stick][0] = x;
converted_[stick][1] = y;
setPSPAnalog_(stick, x, y);
}

static int RotatePSPKeyCode(int x) {
switch (x) {
case CTRL_UP: return CTRL_RIGHT;
Expand Down Expand Up @@ -249,6 +258,7 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) {
updatePSPButtons_(buttonMask & changedButtonMask, (~buttonMask) & changedButtonMask);

bool keyInputUsed = changedButtonMask != 0;
bool updateAnalogSticks = false;

// OK, handle all the virtual keys next. For these we need to do deltas here and send events.
for (int i = 0; i < VIRTKEY_COUNT; i++) {
Expand Down Expand Up @@ -322,12 +332,28 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) {
if (!bPrevValue && bValue) {
// INFO_LOG(G3D, "vkeyon %s", KeyMap::GetVirtKeyName(vkId));
onVKey(vkId, true);
virtKeyOn_[vkId - VIRTKEY_FIRST] = true;

if (vkId == VIRTKEY_ANALOG_LIGHTLY) {
updateAnalogSticks = true;
}
} else if (bPrevValue && !bValue) {
// INFO_LOG(G3D, "vkeyoff %s", KeyMap::GetVirtKeyName(vkId));
onVKey(vkId, false);
virtKeyOn_[vkId - VIRTKEY_FIRST] = false;

if (vkId == VIRTKEY_ANALOG_LIGHTLY) {
updateAnalogSticks = true;
}
}
}

if (updateAnalogSticks) {
// If "lightly" (analog limiter) was toggled, we need to update both computed stick outputs.
UpdateAnalogOutput(0);
UpdateAnalogOutput(1);
}

return keyInputUsed;
}

Expand Down
2 changes: 2 additions & 0 deletions Core/ControlMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ class ControlMapper {
float MapAxisValue(float value, int vkId, const InputMapping &mapping, const InputMapping &changedMapping, bool *oppositeTouched);

void SetPSPAxis(int deviceId, int stick, char axis, float value);
void UpdateAnalogOutput(int stick);

void onVKey(int vkey, bool down);
void onVKeyAnalog(int deviceId, int vkey, float value);

// To track mappable virtual keys. We can have as many as we want.
float virtKeys_[VIRTKEY_COUNT]{};
bool virtKeyOn_[VIRTKEY_COUNT]{}; // Track boolean output separaately since thresholds may differ.

int lastNonDeadzoneDeviceID_[2]{};

Expand Down
3 changes: 2 additions & 1 deletion Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ void Core_MemoryException(u32 address, u32 accessSize, u32 pc, MemoryExceptionTy
}
}

void Core_MemoryExceptionInfo(u32 address, u32 pc, u32 accessSize, MemoryExceptionType type, std::string additionalInfo, bool forceReport) {
void Core_MemoryExceptionInfo(u32 address, u32 accessSize, u32 pc, MemoryExceptionType type, std::string additionalInfo, bool forceReport) {
const char *desc = MemoryExceptionTypeAsString(type);
// In jit, we only flush PC when bIgnoreBadMemAccess is off.
if (g_Config.iCpuCore == (int)CPUCore::JIT && g_Config.bIgnoreBadMemAccess) {
Expand All @@ -483,6 +483,7 @@ void Core_MemoryExceptionInfo(u32 address, u32 pc, u32 accessSize, MemoryExcepti
e.info = additionalInfo;
e.memory_type = type;
e.address = address;
e.accessSize = accessSize;
e.stackTrace = stackTrace;
e.pc = pc;
Core_EnableStepping(true, "memory.exception", address);
Expand Down
7 changes: 4 additions & 3 deletions Core/HLE/HLE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,10 +794,11 @@ size_t hleFormatLogArgs(char *message, size_t sz, const char *argmask) {
case 's':
if (Memory::IsValidAddress(regval)) {
const char *s = Memory::GetCharPointer(regval);
if (strnlen(s, 64) >= 64) {
APPEND_FMT("%.64s...", Memory::GetCharPointer(regval));
const int safeLen = Memory::ValidSize(regval, 128);
if (strnlen(s, safeLen) >= safeLen) {
APPEND_FMT("%.*s...", safeLen, Memory::GetCharPointer(regval));
} else {
APPEND_FMT("%s", Memory::GetCharPointer(regval));
APPEND_FMT("%.*s", safeLen, Memory::GetCharPointer(regval));
}
} else {
APPEND_FMT("(invalid)");
Expand Down
11 changes: 6 additions & 5 deletions Core/HLE/sceKernelModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,7 @@ void PSPModule::Cleanup() {
}
}

static void __SaveDecryptedEbootToStorageMedia(const u8 *decryptedEbootDataPtr, const u32 length) {
static void SaveDecryptedEbootToStorageMedia(const u8 *decryptedEbootDataPtr, const u32 length, const char *name) {
if (!decryptedEbootDataPtr) {
ERROR_LOG(SCEMODULE, "Error saving decrypted EBOOT.BIN: invalid pointer");
return;
Expand All @@ -895,7 +895,7 @@ static void __SaveDecryptedEbootToStorageMedia(const u8 *decryptedEbootDataPtr,
return;
}

const std::string filenameToDumpTo = g_paramSFO.GetDiscID() + ".BIN";
const std::string filenameToDumpTo = StringFromFormat("%s_%s.BIN", g_paramSFO.GetDiscID().c_str(), name);
const Path dumpDirectory = GetSysDirectory(DIRECTORY_DUMP);
const Path fullPath = dumpDirectory / filenameToDumpTo;

Expand Down Expand Up @@ -1264,9 +1264,10 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load

// If we've made it this far, it should be safe to dump.
if (g_Config.bDumpDecryptedEboot) {
INFO_LOG(SCEMODULE, "Dumping decrypted EBOOT.BIN to file.");
const u32 dumpLength = ret;
__SaveDecryptedEbootToStorageMedia(ptr, dumpLength);
// Copy the name to ensure it's null terminated.
char name[32]{};
strncpy(name, head->modname, ARRAY_SIZE(head->modname));
SaveDecryptedEbootToStorageMedia(ptr, (u32)elfSize, name);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion Core/MIPS/ARM/ArmJit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ void ArmJit::DoState(PointerWrap &p)
Do(p, js.startDefaultPrefix);
if (s >= 2) {
Do(p, js.hasSetRounding);
js.lastSetRounding = 0;
if (p.mode == PointerWrap::MODE_READ) {
js.lastSetRounding = 0;
}
} else {
js.hasSetRounding = 1;
}
Expand Down
4 changes: 3 additions & 1 deletion Core/MIPS/ARM64/Arm64Jit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ void Arm64Jit::DoState(PointerWrap &p) {
Do(p, js.startDefaultPrefix);
if (s >= 2) {
Do(p, js.hasSetRounding);
js.lastSetRounding = 0;
if (p.mode == PointerWrap::MODE_READ) {
js.lastSetRounding = 0;
}
} else {
js.hasSetRounding = 1;
}
Expand Down
4 changes: 3 additions & 1 deletion Core/MIPS/MIPS/MipsJit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ void MipsJit::DoState(PointerWrap &p)
Do(p, js.startDefaultPrefix);
if (s >= 2) {
Do(p, js.hasSetRounding);
js.lastSetRounding = 0;
if (p.mode == PointerWrap::MODE_READ) {
js.lastSetRounding = 0;
}
} else {
js.hasSetRounding = 1;
}
Expand Down
4 changes: 3 additions & 1 deletion Core/MIPS/fake/FakeJit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ void FakeJit::DoState(PointerWrap &p) {
Do(p, js.startDefaultPrefix);
if (s >= 2) {
Do(p, js.hasSetRounding);
js.lastSetRounding = 0;
if (p.mode == PointerWrap::MODE_READ) {
js.lastSetRounding = 0;
}
} else {
js.hasSetRounding = 1;
}
Expand Down
6 changes: 3 additions & 3 deletions Core/MIPS/x86/Jit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b) {
CMP(32, MatR(RAX), Imm32(CORE_NEXTFRAME));
}
FixupBranch skipCheck = J_CC(CC_LE, true);
MOV(32, MIPSSTATE_VAR(pc), Imm32(GetCompilerPC() + 4));
// All cases of AFTER_CORE_STATE should update PC. We don't update here.
RegCacheState state;
GetStateAndFlushAll(state);
WriteSyscallExit();
Expand Down Expand Up @@ -697,7 +697,7 @@ void Jit::WriteExit(u32 destination, int exit_num) {
CMP(32, MatR(RAX), Imm32(CORE_NEXTFRAME));
}
FixupBranch skipCheck = J_CC(CC_LE);
MOV(32, MIPSSTATE_VAR(pc), Imm32(GetCompilerPC()));
// All cases of AFTER_CORE_STATE should update PC. We don't update here.
WriteSyscallExit();
SetJumpTarget(skipCheck);
}
Expand Down Expand Up @@ -753,7 +753,7 @@ void Jit::WriteExitDestInReg(X64Reg reg) {
CMP(32, MatR(temp), Imm32(CORE_NEXTFRAME));
}
FixupBranch skipCheck = J_CC(CC_LE);
MOV(32, MIPSSTATE_VAR(pc), Imm32(GetCompilerPC()));
// All cases of AFTER_CORE_STATE should update PC. We don't update here.
WriteSyscallExit();
SetJumpTarget(skipCheck);
}
Expand Down
7 changes: 7 additions & 0 deletions GPU/Common/DepalettizeShaderCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config) {
if (shiftedMask & 0x7C00) writer.C(" int b = int(color.b * 31.99);\n"); else writer.C(" int b = 0;\n");
if (shiftedMask & 0x8000) writer.C(" int a = int(color.a);\n"); else writer.C(" int a = 0;\n");
writer.C(" int index = (a << 15) | (b << 10) | (g << 5) | (r);\n");

if (config.textureFormat == GE_TFMT_CLUT8) {
// SOCOM case. #16210
// To debug the issue, remove this shift to see the texture (check for clamping etc).
writer.C(" index >>= 8;\n");
}

break;
case GE_FORMAT_DEPTH16:
// Decode depth buffer.
Expand Down
2 changes: 1 addition & 1 deletion GPU/Common/Draw2D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ Draw2DPipeline *Draw2D::Create2DPipeline(std::function<Draw2DPipelineInfo (Shade

ShaderModule *fs = draw_->CreateShaderModule(ShaderStage::Fragment, shaderLanguageDesc.shaderLanguage, (const uint8_t *)fsCode, strlen(fsCode), info.tag);

_assert_(fs);
_assert_msg_(fs, "Failed to create shader module!\n%s", fsCode);

// verts have positions in 2D clip coordinates.
static const InputLayoutDesc desc = {
Expand Down
5 changes: 5 additions & 0 deletions GPU/Common/FramebufferManagerCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,11 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) {
}
}

// Reject too-tiny framebuffers to display (Godfather, see issue #16915).
if (vfb && vfb->height < 64) {
vfb = nullptr;
}

if (!vfb) {
if (Memory::IsValidAddress(fbaddr)) {
// The game is displaying something directly from RAM. In GTA, it's decoded video.
Expand Down
31 changes: 26 additions & 5 deletions GPU/Common/TextureCacheCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1028,18 +1028,28 @@ bool TextureCacheCommon::MatchFramebuffer(
}

// Check works for D16 too.
// These are combinations that we have special-cased handling for. There are more
// ones possible, but rare - we'll add them as we find them used.
const bool matchingClutFormat =
(fb_format == GE_FORMAT_DEPTH16 && entry.format == GE_TFMT_CLUT16) ||
(fb_format == GE_FORMAT_DEPTH16 && entry.format == GE_TFMT_5650) ||
(fb_format == GE_FORMAT_8888 && entry.format == GE_TFMT_CLUT32) ||
(fb_format != GE_FORMAT_8888 && entry.format == GE_TFMT_CLUT16) ||
(fb_format == GE_FORMAT_8888 && entry.format == GE_TFMT_CLUT8);
(fb_format == GE_FORMAT_8888 && entry.format == GE_TFMT_CLUT8) ||
(fb_format == GE_FORMAT_5551 && entry.format == GE_TFMT_CLUT8 && PSP_CoreParameter().compat.flags().SOCOMClut8Replacement);

const int texBitsPerPixel = std::max(1U, (u32)textureBitsPerPixel[entry.format]);
const int texBitsPerPixel = TextureFormatBitsPerPixel(entry.format);
const int byteOffset = texaddr - addr;
if (byteOffset > 0) {
int texbpp = texBitsPerPixel;
if (fb_format == GE_FORMAT_5551 && entry.format == GE_TFMT_CLUT8) {
// In this case we treat CLUT8 as if it were CLUT16, see issue #16210. So we need
// to compute the x offset appropriately.
texbpp = 16;
}

matchInfo->yOffset = byteOffset / fb_stride_in_bytes;
matchInfo->xOffset = 8 * (byteOffset % fb_stride_in_bytes) / texBitsPerPixel;
matchInfo->xOffset = 8 * (byteOffset % fb_stride_in_bytes) / texbpp;
} else if (byteOffset < 0) {
int texelOffset = 8 * byteOffset / texBitsPerPixel;
// We don't support negative Y offsets, and negative X offsets are only for the Killzone workaround.
Expand All @@ -1066,7 +1076,7 @@ bool TextureCacheCommon::MatchFramebuffer(
// Trying to play it safe. Below 0x04110000 is almost always framebuffers.
// TODO: Maybe we can reduce this check and find a better way above 0x04110000?
if (matchInfo->yOffset > MAX_SUBAREA_Y_OFFSET_SAFE && addr > 0x04110000 && !PSP_CoreParameter().compat.flags().AllowLargeFBTextureOffsets) {
WARN_LOG_REPORT_ONCE(subareaIgnored, G3D, "Ignoring possible texturing from framebuffer at %08x +%dx%d / %dx%d", fb_address, matchInfo->xOffset, matchInfo->yOffset, framebuffer->width, framebuffer->height);
WARN_LOG_ONCE(subareaIgnored, G3D, "Ignoring possible texturing from framebuffer at %08x +%dx%d / %dx%d", fb_address, matchInfo->xOffset, matchInfo->yOffset, framebuffer->width, framebuffer->height);
return false;
}

Expand Down Expand Up @@ -1133,6 +1143,11 @@ void TextureCacheCommon::SetTextureFramebuffer(const AttachCandidate &candidate)
gstate_c.curTextureWidth = framebuffer->bufferWidth;
gstate_c.curTextureHeight = framebuffer->bufferHeight;

if (candidate.channel == RASTER_COLOR && gstate.getTextureFormat() == GE_TFMT_CLUT8 && framebuffer->fb_format == GE_FORMAT_5551 && PSP_CoreParameter().compat.flags().SOCOMClut8Replacement) {
// See #16210. UV must be adjusted as if the texture was twice the width.
gstate_c.curTextureWidth *= 2.0f;
}

if (needsDepthXSwizzle) {
gstate_c.curTextureWidth = RoundUpToPowerOf2(gstate_c.curTextureWidth);
}
Expand Down Expand Up @@ -2145,6 +2160,7 @@ void TextureCacheCommon::ApplyTexture() {
}
}

// Can we depalettize at all? This refers to both in-fragment-shader depal and "traditional" depal through a separate pass.
static bool CanDepalettize(GETextureFormat texFormat, GEBufferFormat bufferFormat) {
if (IsClutFormat(texFormat)) {
switch (bufferFormat) {
Expand All @@ -2155,6 +2171,10 @@ static bool CanDepalettize(GETextureFormat texFormat, GEBufferFormat bufferForma
if (texFormat == GE_TFMT_CLUT16) {
return true;
}
if (texFormat == GE_TFMT_CLUT8 && bufferFormat == GE_FORMAT_5551 && PSP_CoreParameter().compat.flags().SOCOMClut8Replacement) {
// Wacky case from issue #16210 (SOCOM etc).
return true;
}
break;
case GE_FORMAT_8888:
if (texFormat == GE_TFMT_CLUT32 || texFormat == GE_TFMT_CLUT8) { // clut8 takes a special depal mode.
Expand Down Expand Up @@ -2214,7 +2234,8 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
bool useShaderDepal = framebufferManager_->GetCurrentRenderVFB() != framebuffer &&
!depth && clutRenderAddress_ == 0xFFFFFFFF &&
!gstate_c.curTextureIs3D &&
draw_->GetShaderLanguageDesc().bitwiseOps;
draw_->GetShaderLanguageDesc().bitwiseOps &&
!(texFormat == GE_TFMT_CLUT8 && framebuffer->fb_format == GE_FORMAT_5551); // socom

switch (draw_->GetShaderLanguageDesc().shaderLanguage) {
case ShaderLanguage::HLSL_D3D9:
Expand Down
19 changes: 19 additions & 0 deletions GPU/Common/TextureDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,25 @@
#define DO_NOT_VECTORIZE_LOOP
#endif

const u8 textureBitsPerPixel[16] = {
16, //GE_TFMT_5650,
16, //GE_TFMT_5551,
16, //GE_TFMT_4444,
32, //GE_TFMT_8888,
4, //GE_TFMT_CLUT4,
8, //GE_TFMT_CLUT8,
16, //GE_TFMT_CLUT16,
32, //GE_TFMT_CLUT32,
4, //GE_TFMT_DXT1,
8, //GE_TFMT_DXT3,
8, //GE_TFMT_DXT5,
0, // INVALID,
0, // INVALID,
0, // INVALID,
0, // INVALID,
0, // INVALID,
};

#ifdef _M_SSE

static u32 QuickTexHashSSE2(const void *checkp, u32 size) {
Expand Down
Loading

0 comments on commit 6dafe86

Please sign in to comment.