diff --git a/Core/MemMap.h b/Core/MemMap.h index d0cac9f082..7383b719ea 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -261,6 +261,10 @@ inline bool IsVRAMAddress(const u32 address) { inline bool IsDepthTexVRAMAddress(const u32 address) { return ((address & 0x3FE00000) == 0x04200000) || ((address & 0x3FE00000) == 0x04600000); } +inline bool IsKernelAddress(const u32 address) { + return ((address & 0x3F800000) == 0x08000000); +} + bool IsScratchpadAddress(const u32 address); // Used for auto-converted char * parameters, which can sometimes legitimately be null - diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 35b15f97db..56b8508522 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -506,7 +506,10 @@ TexCacheEntry *TextureCacheCommon::SetTexture() { } entry = entryNew; - if (g_Config.bTextureBackoffCache) { + if (Memory::IsKernelAddress(texaddr)) { + // It's the builtin font texture. + entry->status = TexCacheEntry::STATUS_RELIABLE; + } else if (g_Config.bTextureBackoffCache) { entry->status = TexCacheEntry::STATUS_HASHING; } else { entry->status = TexCacheEntry::STATUS_UNRELIABLE; @@ -568,10 +571,9 @@ std::vector TextureCacheCommon::GetFramebufferCandidates(const FramebufferNotificationChannel channel = Memory::IsDepthTexVRAMAddress(entry.addr) ? FramebufferNotificationChannel::NOTIFY_FB_DEPTH : FramebufferNotificationChannel::NOTIFY_FB_COLOR; - auto framebuffers = framebufferManager_->Framebuffers(); + const std::vector &framebuffers = framebufferManager_->Framebuffers(); - for (size_t i = 0, n = framebuffers.size(); i < n; ++i) { - auto framebuffer = framebuffers[i]; + for (VirtualFramebuffer *framebuffer : framebuffers) { FramebufferMatchInfo match = MatchFramebuffer(entry, framebuffer, texAddrOffset, channel); switch (match.match) { case FramebufferMatch::VALID: @@ -707,7 +709,8 @@ void TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const c ReleaseTexture(entry, true); entry->status &= ~TexCacheEntry::STATUS_IS_SCALED; } - // Clear the reliable bit if set. + + // Mark as hashing, if marked as reliable. if (entry->GetHashStatus() == TexCacheEntry::STATUS_RELIABLE) { entry->SetHashStatus(TexCacheEntry::STATUS_HASHING); } @@ -723,7 +726,6 @@ void TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const c } } - entry->status |= TexCacheEntry::STATUS_UNRELIABLE; if (entry->numFrames < TEXCACHE_FRAME_CHANGE_FREQUENT) { if (entry->status & TexCacheEntry::STATUS_FREE_CHANGE) { entry->status &= ~TexCacheEntry::STATUS_FREE_CHANGE; @@ -1073,9 +1075,8 @@ void TextureCacheCommon::LoadClut(u32 clutAddr, u32 loadBytes) { static const u32 MAX_CLUT_OFFSET = 4096; clutRenderOffset_ = MAX_CLUT_OFFSET; - auto framebuffers = framebufferManager_->Framebuffers(); - for (size_t i = 0, n = framebuffers.size(); i < n; ++i) { - auto framebuffer = framebuffers[i]; + const std::vector &framebuffers = framebufferManager_->Framebuffers(); + for (VirtualFramebuffer *framebuffer : framebuffers) { const u32 fb_address = framebuffer->fb_address & 0x3FFFFFFF; const u32 bpp = framebuffer->drawnFormat == GE_FORMAT_8888 ? 4 : 2; u32 offset = clutFramebufAddr - fb_address; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 1a89c9879a..336c359476 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1231,7 +1231,7 @@ void GPUCommon::Execute_Origin(u32 op, u32 diff) { void GPUCommon::Execute_Jump(u32 op, u32 diff) { const u32 target = gstate_c.getRelativeAddress(op & 0x00FFFFFC); if (!Memory::IsValidAddress(target)) { - ERROR_LOG_REPORT(G3D, "JUMP to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); + ERROR_LOG(G3D, "JUMP to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); UpdateState(GPUSTATE_ERROR); return; } @@ -1253,7 +1253,7 @@ void GPUCommon::Execute_BJump(u32 op, u32 diff) { UpdatePC(currentList->pc, target - 4); currentList->pc = target - 4; // pc will be increased after we return, counteract that } else { - ERROR_LOG_REPORT(G3D, "BJUMP to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); + ERROR_LOG(G3D, "BJUMP to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); UpdateState(GPUSTATE_ERROR); } } @@ -1264,7 +1264,7 @@ void GPUCommon::Execute_Call(u32 op, u32 diff) { const u32 target = gstate_c.getRelativeAddress(op & 0x00FFFFFC); if (!Memory::IsValidAddress(target)) { - ERROR_LOG_REPORT(G3D, "CALL to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); + ERROR_LOG(G3D, "CALL to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); UpdateState(GPUSTATE_ERROR); return; } @@ -1297,7 +1297,7 @@ void GPUCommon::DoExecuteCall(u32 target) { } if (currentList->stackptr == ARRAY_SIZE(currentList->stack)) { - ERROR_LOG_REPORT(G3D, "CALL: Stack full!"); + ERROR_LOG(G3D, "CALL: Stack full!"); } else { auto &stackEntry = currentList->stack[currentList->stackptr++]; stackEntry.pc = retval; @@ -1310,7 +1310,7 @@ void GPUCommon::DoExecuteCall(u32 target) { void GPUCommon::Execute_Ret(u32 op, u32 diff) { if (currentList->stackptr == 0) { - DEBUG_LOG_REPORT(G3D, "RET: Stack empty!"); + DEBUG_LOG(G3D, "RET: Stack empty!"); } else { auto &stackEntry = currentList->stack[--currentList->stackptr]; gstate_c.offsetAddr = stackEntry.offsetAddr; diff --git a/ext/native/util/text/wrap_text.cpp b/ext/native/util/text/wrap_text.cpp index c052056034..6f829b4163 100644 --- a/ext/native/util/text/wrap_text.cpp +++ b/ext/native/util/text/wrap_text.cpp @@ -130,8 +130,8 @@ void WordWrapper::AppendWord(int endIndex, bool addNewline) { scanForNewline_ = false; } else { // We may have appended a newline - check. - size_t pos = out_.substr(lastLineStart_).find_last_of("\n"); - if (pos != out_.npos) { + size_t pos = out_.find_last_of("\n"); + if (pos != out_.npos && pos >= lastLineStart_) { lastLineStart_ += pos; } } @@ -143,6 +143,10 @@ void WordWrapper::Wrap() { // First, let's check if it fits as-is. size_t len = strlen(str_); + + // We know it'll be approximately this size. It's fine if the guess is a little off. + out_.reserve(len + len / 16); + if (MeasureWidth(str_, len) <= maxW_) { // If it fits, we don't need to go through each character. out_ = str_;