From 43b1bf7afa588c3d5aa23554faedfe0eaad8eac8 Mon Sep 17 00:00:00 2001 From: Gericom Date: Sun, 8 Mar 2026 11:32:48 +0100 Subject: [PATCH] Fix vram corruption when using the cheat panel in vertical grid mode The graphics of an animated nds icon are now not all uploaded to vram at the same time. There are now 1024 bytes available for each icon (previously 4096). Double buffering is used to upload the new icon frame every time it changes. --- arm9/source/romBrowser/FileType/FileIcon.h | 4 +- .../romBrowser/FileType/Nds/NdsFileIcon.cpp | 64 +++++++++---------- .../romBrowser/FileType/Nds/NdsFileIcon.h | 6 +- .../romBrowser/FileType/Nds/ndsBanner.h | 5 +- .../source/romBrowser/FileType/StaticIcon.cpp | 2 +- arm9/source/romBrowser/FileType/StaticIcon.h | 2 +- .../Theme/Material/MaterialFileIcon.cpp | 2 +- .../Theme/Material/MaterialFileIcon.h | 2 +- 8 files changed, 45 insertions(+), 42 deletions(-) diff --git a/arm9/source/romBrowser/FileType/FileIcon.h b/arm9/source/romBrowser/FileType/FileIcon.h index f03ea27..514aa4f 100644 --- a/arm9/source/romBrowser/FileType/FileIcon.h +++ b/arm9/source/romBrowser/FileType/FileIcon.h @@ -5,7 +5,7 @@ class PaletteManager; class GraphicsContext; -#define FILE_ICON_VRAM_SIZE 4096 +#define FILE_ICON_VRAM_SIZE 1024 /// @brief Abstract base class representing a file icon. class FileIcon @@ -15,7 +15,7 @@ public: /// @brief Uploads the graphics of this icon to the specified \p vram address. /// @param vram The vram address to load the graphics to. - virtual void UploadGraphics(vu16* vram) const = 0; + virtual void UploadGraphics(vu16* vram) = 0; /// @brief Updates this icon. virtual void Update() { } diff --git a/arm9/source/romBrowser/FileType/Nds/NdsFileIcon.cpp b/arm9/source/romBrowser/FileType/Nds/NdsFileIcon.cpp index 24cb48c..6cefc01 100644 --- a/arm9/source/romBrowser/FileType/Nds/NdsFileIcon.cpp +++ b/arm9/source/romBrowser/FileType/Nds/NdsFileIcon.cpp @@ -1,5 +1,4 @@ #include "common.h" -#include #include #include "gui/PaletteManager.h" #include "gui/OamManager.h" @@ -25,30 +24,37 @@ NdsFileIcon::NdsFileIcon(const nds_banner_t* banner) const auto& token = _banner->animation.animTokens[i]; if (token.duration == NDS_BANNER_ANIM_DURATION_CONTROL_FRAME) { - _loop = token.control != NDS_BANNER_ANIM_CONTROL_STOP; + _loop = token.control != NDS_BANNER_ANIM_CONTROL_STOP; _lastAnimToken = i - 1; break; } else + { length += token.duration; + } } _animLength = length; _tokenStartTimes[NDS_BANNER_ANIM_TOKEN_COUNT] = _animLength; } } -void NdsFileIcon::UploadGraphics(vu16* vram) const +void NdsFileIcon::UploadGraphics(vu16* vram) { - if (_animated) - dma_ntrCopy32(3, _banner->animation.iconGfx, vram, sizeof(_banner->animation.iconGfx)); - else + _vramAddress = vram; + _currentVramSlot = 0; + _currentGfxIdx = -1; + if (!_animated) + { dma_ntrCopy32(3, _banner->iconGfx, vram, sizeof(_banner->iconGfx)); + } } void NdsFileIcon::Update() { if (!_animated) + { return; + } _frame %= _animLength; @@ -71,48 +77,30 @@ void NdsFileIcon::Update() break; } else if (_frame < midTime) + { end = mid - 1; + } else + { start = mid + 1; + } } _animTokenIdx = start; } if (++_frame == _animLength) + { _frame = 0; - - - // if (++_durationCounter < _banner->animation.animTokens[_animTokenIdx].duration) - // return; - - // _durationCounter = 0; - - // if (++_animTokenIdx >= NDS_BANNER_ANIM_TOKEN_COUNT) - // { - // _animTokenIdx = 0; - // return; - // } - - // if (_banner->animation.animTokens[_animTokenIdx].duration == NDS_BANNER_ANIM_DURATION_CONTROL_FRAME) - // { - // switch (_banner->animation.animTokens[_animTokenIdx].control) - // { - // case NDS_BANNER_ANIM_CONTROL_LOOP: - // _animTokenIdx = 0; - // break; - - // case NDS_BANNER_ANIM_CONTROL_STOP: - // _animTokenIdx--; - // break; - // } - // } + } } void NdsFileIcon::Draw(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& backgroundColor) { if (!graphicsContext.IsVisible(Rectangle(_position, 32, 32))) + { return; + } const u16* palette = _animated ? _banner->animation.iconPltt[_banner->animation.animTokens[_animTokenIdx].plttIdx] @@ -123,7 +111,17 @@ void NdsFileIcon::Draw(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& bac u32 vramOffset = _vramOffset; if (_animated) - vramOffset += _banner->animation.animTokens[_animTokenIdx].gfxIdx * 512; + { + int gfxIdx = _banner->animation.animTokens[_animTokenIdx].gfxIdx; + if (gfxIdx != _currentGfxIdx) + { + _currentVramSlot = 1 - _currentVramSlot; + _currentGfxIdx = gfxIdx; + dma_ntrCopy32(3, &_banner->animation.iconGfx[gfxIdx][0], (u8*)_vramAddress + (_currentVramSlot * NDS_BANNER_ICON_SIZE), NDS_BANNER_ICON_SIZE); + } + + vramOffset += _currentVramSlot * NDS_BANNER_ICON_SIZE; + } auto builder = OamBuilder::OamWithSize<32, 32>( _position, vramOffset >> 7) diff --git a/arm9/source/romBrowser/FileType/Nds/NdsFileIcon.h b/arm9/source/romBrowser/FileType/Nds/NdsFileIcon.h index d212580..611ea3f 100644 --- a/arm9/source/romBrowser/FileType/Nds/NdsFileIcon.h +++ b/arm9/source/romBrowser/FileType/Nds/NdsFileIcon.h @@ -8,7 +8,7 @@ class NdsFileIcon : public FileIcon public: explicit NdsFileIcon(const nds_banner_t* banner); - void UploadGraphics(vu16* vram) const override; + void UploadGraphics(vu16* vram) override; void Update() override; void Draw(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& backgroundColor) override; @@ -21,4 +21,8 @@ private: u32 _animLength; u16 _tokenStartTimes[65]; bool _loop; + + vu16* _vramAddress = nullptr; + int _currentVramSlot = 0; + int _currentGfxIdx = -1; }; \ No newline at end of file diff --git a/arm9/source/romBrowser/FileType/Nds/ndsBanner.h b/arm9/source/romBrowser/FileType/Nds/ndsBanner.h index 917d8c4..4c930c5 100644 --- a/arm9/source/romBrowser/FileType/Nds/ndsBanner.h +++ b/arm9/source/romBrowser/FileType/Nds/ndsBanner.h @@ -46,10 +46,11 @@ typedef struct } nds_banner_anim_token_t; #define NDS_BANNER_ANIM_TOKEN_COUNT 64 +#define NDS_BANNER_ICON_SIZE 512 typedef struct { - u8 iconGfx[8][0x200]; + u8 iconGfx[8][NDS_BANNER_ICON_SIZE]; u16 iconPltt[8][16]; nds_banner_anim_token_t animTokens[NDS_BANNER_ANIM_TOKEN_COUNT]; } nds_banner_anim_t; @@ -57,7 +58,7 @@ typedef struct typedef struct { nds_banner_header_t header; - u8 iconGfx[0x200]; + u8 iconGfx[NDS_BANNER_ICON_SIZE]; u16 iconPltt[16]; char16_t title[16][128]; nds_banner_anim_t animation; diff --git a/arm9/source/romBrowser/FileType/StaticIcon.cpp b/arm9/source/romBrowser/FileType/StaticIcon.cpp index 7b1e78a..d1f84c1 100644 --- a/arm9/source/romBrowser/FileType/StaticIcon.cpp +++ b/arm9/source/romBrowser/FileType/StaticIcon.cpp @@ -7,7 +7,7 @@ #include "gui/palette/DirectPalette.h" #include "StaticIcon.h" -void StaticIcon::UploadGraphics(vu16* vram) const +void StaticIcon::UploadGraphics(vu16* vram) { dma_ntrCopy32(3, _tileData, vram, 512); } diff --git a/arm9/source/romBrowser/FileType/StaticIcon.h b/arm9/source/romBrowser/FileType/StaticIcon.h index f8c0e16..69f896e 100644 --- a/arm9/source/romBrowser/FileType/StaticIcon.h +++ b/arm9/source/romBrowser/FileType/StaticIcon.h @@ -7,7 +7,7 @@ public: StaticIcon(const u8* tileData, const u16* paletteData) : _tileData(tileData), _paletteData(paletteData) { } - void UploadGraphics(vu16* vram) const override; + void UploadGraphics(vu16* vram) override; void Update() override; void Draw(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& backgroundColor) override; diff --git a/arm9/source/romBrowser/Theme/Material/MaterialFileIcon.cpp b/arm9/source/romBrowser/Theme/Material/MaterialFileIcon.cpp index 5e299cf..e77fcb3 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialFileIcon.cpp +++ b/arm9/source/romBrowser/Theme/Material/MaterialFileIcon.cpp @@ -24,7 +24,7 @@ MaterialFileIcon::MaterialFileIcon(const TCHAR* name, const MaterialColorScheme* _displayName[i] = 0; } -void MaterialFileIcon::UploadGraphics(vu16* vram) const +void MaterialFileIcon::UploadGraphics(vu16* vram) { dma_ntrCopy32(3, GetIconTiles(), vram, 32 * 32 / 2); diff --git a/arm9/source/romBrowser/Theme/Material/MaterialFileIcon.h b/arm9/source/romBrowser/Theme/Material/MaterialFileIcon.h index 567568b..8aa2e4e 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialFileIcon.h +++ b/arm9/source/romBrowser/Theme/Material/MaterialFileIcon.h @@ -11,7 +11,7 @@ public: MaterialFileIcon(const TCHAR* name, const MaterialColorScheme* materialColorScheme, const IFontRepository* fontRepository); - void UploadGraphics(vu16* vram) const override; + void UploadGraphics(vu16* vram) override; void Draw(GraphicsContext& graphicsContext, const Rgb<8, 8, 8>& backgroundColor) override; protected: