[记录]GBA反编译上踩过的一些坑

[记录]GBA反编译上踩过的一些坑

以下的内容仅仅适用于宝可梦三代正作,并非所有的GBA游戏

一、LoadSpritePalettes未正确结束导致的oam调色板溢出

LoadSpritePalettes会把oam调色板数据数组整个加载到oam色板区域,但是需要{}用于结尾

二、重新加载现有sprite的图像和色板时可能会出现短暂的花屏

疑似色板和图片配合的不是很好,原版的背包解决思路是创建两个sprite相互切换显示,或者像电脑里那样添加马赛克过渡效果

三、BeginNormalPaletteFade时有短暂的bg或者obj突然显示在屏幕内

疑似LoadPalette函数会把色板同时加载到gPlttBufferUnfaded和gPlttBufferFaded内,运行VBlank回调时会把gPlttBufferFaded加载到GBA的调色板显存里,导致有一瞬的图像显示出来
解决办法:在BeginNormalPaletteFade前添加BlendPalettes,将当前gPlttBufferFaded刷成黑色

BlendPalettes(PALETTES_ALL, 16, RGB_BLACK);     // 
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);

四、结构体内的图片数据起始地址没有对齐导致图片出错

图片[1]-[记录]GBA反编译上踩过的一些坑-宝可梦营地

图片在解压到结构体内时如果数据没有四对齐可能会出现类似上图的错误

// 错误示范
struct test
{
    u8 unk0;
    u8 pictureData[64 * 64 / 2];
};

五、DecompressAndCopyTileDataToVram函数使用后未及时清理

使用DecompressAndCopyTileDataToVram函数时会在内存里malloc一块区域来存放解压后的tiles/tilemap数据,但是并不会及时释放该内存,需要在其之后使用FreeTempTileDataBuffersIfPossible等待所有bg数据加载完毕并清理

        case 0:
            DecompressAndCopyTileDataToVram(0, gPokedexTiles, 0, 0, 0);
            sPokedexMain->infoSeq++;
            break;
        case 1:
            if (!FreeTempTileDataBuffersIfPossible())
            {
                sPokedexMain->infoSeq++;
            }
            break;

六、图块加载和色板加载不同步导致瞬时花屏

在做gif播放时遇到的情况[GBA教程]pokeemerald实现播放gif动态图片-宝可梦营地,在已经有图片的基础上再次加载新的tiles和色板时可能会出现色板比tiles早一帧出现效果导致会有一瞬间的色板和tile对不上的情况

hua

出现这个问题的原理可能是tiles使用了LZ77UnCompVram直接解压到了gba的tile内存,而色板则要等到vblank callback期间才会加载上去,这里我的办法是在LZ77UnCompVram前加载色板

DmaCopy16(3, sTitleScreenBackgroundPalTable[gTasks[taskId].data[0] % NELEMS(sTitleScreenBackgroundPalTable)], (void *)PLTT, BG_PLTT_SIZE);
LZ77UnCompVram(sTitleScreenBackgroundGfxTable[gTasks[taskId].data[0] % NELEMS(sTitleScreenBackgroundGfxTable)], (void *)(BG_CHAR_ADDR(0)));

当然,或许使用DecompressAndCopyTileDataToVram或者LoadBgTiles之类的函数,让色板和bg一起通过dma加载会更好

上述问题二可能也能使用这个问题解决

© 版权声明
THE END
喜欢就支持一下吧
点赞1 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容