mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-06-03 14:14:59 -06:00
Fixes regressions and issues causing PSP emulated games to not run. (#4389)
* Fixes PSP emulation with the following changes: 1. Reserved Memory cannot be mapped, this seems to be incorrect and the PSP emulation relies on reserving then mapping memory at startup. From other logs, this may affect PS2 emulation as well. 2. Temp directory output may have garbase and the API is not null terminating the output, resulting in failures when the file path is not valid. 3. Fix misaligned images when viewport is sized for PSP. This fixes garbage in movies on the PSP emulator, making the movies viewable, scaled correctly for the screen. 4. Some PSP moves render incorrectly without sceVideodec2GetAvcPictureInfo 5. Fix dirty hash size calculation and RGB4444 mapping to fix textures These changes combined allow Jean d'Arc, LocoRoco and Patapon to run decently. * fix formatting * null terminate the temp path rather than using memset * fix memory mapping in a more correct way * revert RGB4444 changes as it breaks other games color mapping
This commit is contained in:
parent
6e675c32f2
commit
b48d917e29
@ -402,6 +402,7 @@ int PS4_SYSV_ABI sceAppContentTemporaryDataMount2(OrbisAppContentTemporaryDataOp
|
|||||||
}
|
}
|
||||||
static constexpr std::string_view TmpMount = "/temp0";
|
static constexpr std::string_view TmpMount = "/temp0";
|
||||||
TmpMount.copy(mountPoint->data, TmpMount.size());
|
TmpMount.copy(mountPoint->data, TmpMount.size());
|
||||||
|
mountPoint->data[TmpMount.size()] = '\0';
|
||||||
LOG_INFO(Lib_AppContent, "sceAppContentTemporaryDataMount2: option = {}, mountPoint = {}",
|
LOG_INFO(Lib_AppContent, "sceAppContentTemporaryDataMount2: option = {}, mountPoint = {}",
|
||||||
option, mountPoint->data);
|
option, mountPoint->data);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
|||||||
@ -229,6 +229,12 @@ s32 PS4_SYSV_ABI sceVideodec2GetPictureInfo(const OrbisVideodec2OutputInfo* outp
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceVideodec2GetAvcPictureInfo(const OrbisVideodec2OutputInfo* outputInfo,
|
||||||
|
void* p1stPictureInfoOut, void* p2ndPictureInfoOut) {
|
||||||
|
LOG_TRACE(Lib_Vdec2, "called");
|
||||||
|
return sceVideodec2GetPictureInfo(outputInfo, p1stPictureInfoOut, p2ndPictureInfoOut);
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("RnDibcGCPKw", "libSceVideodec2", 1, "libSceVideodec2",
|
LIB_FUNCTION("RnDibcGCPKw", "libSceVideodec2", 1, "libSceVideodec2",
|
||||||
sceVideodec2QueryComputeMemoryInfo);
|
sceVideodec2QueryComputeMemoryInfo);
|
||||||
@ -246,6 +252,8 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
|||||||
LIB_FUNCTION("wJXikG6QFN8", "libSceVideodec2", 1, "libSceVideodec2", sceVideodec2Reset);
|
LIB_FUNCTION("wJXikG6QFN8", "libSceVideodec2", 1, "libSceVideodec2", sceVideodec2Reset);
|
||||||
LIB_FUNCTION("NtXRa3dRzU0", "libSceVideodec2", 1, "libSceVideodec2",
|
LIB_FUNCTION("NtXRa3dRzU0", "libSceVideodec2", 1, "libSceVideodec2",
|
||||||
sceVideodec2GetPictureInfo);
|
sceVideodec2GetPictureInfo);
|
||||||
|
LIB_FUNCTION("kjrLbcyhEiw", "libSceVideodec2", 1, "libSceVideodec2",
|
||||||
|
sceVideodec2GetAvcPictureInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Videodec2
|
} // namespace Libraries::Videodec2
|
||||||
|
|||||||
@ -137,5 +137,8 @@ s32 PS4_SYSV_ABI sceVideodec2Reset(OrbisVideodec2Decoder decoder);
|
|||||||
s32 PS4_SYSV_ABI sceVideodec2GetPictureInfo(const OrbisVideodec2OutputInfo* outputInfo,
|
s32 PS4_SYSV_ABI sceVideodec2GetPictureInfo(const OrbisVideodec2OutputInfo* outputInfo,
|
||||||
void* p1stPictureInfo, void* p2ndPictureInfo);
|
void* p1stPictureInfo, void* p2ndPictureInfo);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceVideodec2GetAvcPictureInfo(const OrbisVideodec2OutputInfo* outputInfo,
|
||||||
|
void* p1stPictureInfoOut, void* p2ndPictureInfoOut);
|
||||||
|
|
||||||
void RegisterLib(Core::Loader::SymbolsResolver* sym);
|
void RegisterLib(Core::Loader::SymbolsResolver* sym);
|
||||||
} // namespace Libraries::Videodec2
|
} // namespace Libraries::Videodec2
|
||||||
|
|||||||
@ -133,7 +133,7 @@ s32 VdecDecoder::Decode(const OrbisVideodec2InputData& inputData,
|
|||||||
|
|
||||||
// Only set framePitchInBytes if the game uses the newer struct version.
|
// Only set framePitchInBytes if the game uses the newer struct version.
|
||||||
if (outputInfo.thisSize == sizeof(OrbisVideodec2OutputInfo)) {
|
if (outputInfo.thisSize == sizeof(OrbisVideodec2OutputInfo)) {
|
||||||
outputInfo.framePitchInBytes = frame->linesize[0];
|
outputInfo.framePitchInBytes = frame->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outputInfo.isValid) {
|
if (outputInfo.isValid) {
|
||||||
@ -201,7 +201,7 @@ s32 VdecDecoder::Flush(OrbisVideodec2FrameBuffer& frameBuffer,
|
|||||||
outputInfo.codecType = 1; // FIXME: Hardcoded to AVC
|
outputInfo.codecType = 1; // FIXME: Hardcoded to AVC
|
||||||
outputInfo.frameWidth = frame->width;
|
outputInfo.frameWidth = frame->width;
|
||||||
outputInfo.frameHeight = frame->height;
|
outputInfo.frameHeight = frame->height;
|
||||||
outputInfo.framePitch = frame->linesize[0];
|
outputInfo.framePitch = frame->width;
|
||||||
outputInfo.frameBufferSize = frameBuffer.frameBufferSize;
|
outputInfo.frameBufferSize = frameBuffer.frameBufferSize;
|
||||||
outputInfo.frameBuffer = frameBuffer.frameBuffer;
|
outputInfo.frameBuffer = frameBuffer.frameBuffer;
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ s32 VdecDecoder::Flush(OrbisVideodec2FrameBuffer& frameBuffer,
|
|||||||
|
|
||||||
// Only set framePitchInBytes if the game uses the newer struct version.
|
// Only set framePitchInBytes if the game uses the newer struct version.
|
||||||
if (outputInfo.thisSize == sizeof(OrbisVideodec2OutputInfo)) {
|
if (outputInfo.thisSize == sizeof(OrbisVideodec2OutputInfo)) {
|
||||||
outputInfo.framePitchInBytes = frame->linesize[0];
|
outputInfo.framePitchInBytes = frame->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Should we add picture info here too?
|
// FIXME: Should we add picture info here too?
|
||||||
|
|||||||
@ -720,7 +720,7 @@ s32 MemoryManager::MapFile(void** out_addr, VAddr virtual_addr, u64 size, Memory
|
|||||||
prot &= ~MemoryProt::CpuExec;
|
prot &= ~MemoryProt::CpuExec;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (True(flags & MemoryMapFlags::Fixed) && False(flags & MemoryMapFlags::NoOverwrite)) {
|
if (True(flags & MemoryMapFlags::Fixed) && True(flags & MemoryMapFlags::NoOverwrite)) {
|
||||||
ASSERT_MSG(IsValidMapping(virtual_addr, size), "Attempted to access invalid address {:#x}",
|
ASSERT_MSG(IsValidMapping(virtual_addr, size), "Attempted to access invalid address {:#x}",
|
||||||
virtual_addr);
|
virtual_addr);
|
||||||
auto vma = FindVMA(virtual_addr)->second;
|
auto vma = FindVMA(virtual_addr)->second;
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
|
#include "common/div_ceil.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
#include "core/emulator_settings.h"
|
#include "core/emulator_settings.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
@ -731,7 +732,10 @@ void TextureCache::RefreshImage(Image& image) {
|
|||||||
const auto addr = std::bit_cast<u8*>(image.info.guest_address);
|
const auto addr = std::bit_cast<u8*>(image.info.guest_address);
|
||||||
const u32 w = std::min(image.info.size.width, u32(8));
|
const u32 w = std::min(image.info.size.width, u32(8));
|
||||||
const u32 h = std::min(image.info.size.height, u32(8));
|
const u32 h = std::min(image.info.size.height, u32(8));
|
||||||
const u32 size = w * h * image.info.num_bits >> (3 + image.info.props.is_block ? 4 : 0);
|
|
||||||
|
const u32 s_w = image.info.props.is_block ? Common::DivCeil(w, 4u) : w;
|
||||||
|
const u32 s_h = image.info.props.is_block ? Common::DivCeil(h, 4u) : h;
|
||||||
|
const u32 size = s_w * s_h * (image.info.num_bits / 8);
|
||||||
const u64 hash = XXH3_64bits(addr, size);
|
const u64 hash = XXH3_64bits(addr, size);
|
||||||
if (image.hash == hash) {
|
if (image.hash == hash) {
|
||||||
image.flags &= ~ImageFlagBits::MaybeCpuDirty;
|
image.flags &= ~ImageFlagBits::MaybeCpuDirty;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user