You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Game Boy模拟器PPU在DMG-acid2测试中出现渲染故障求助

Game Boy模拟器PPU渲染故障求助

我用C语言开发Game Boy模拟器,正在通过DMG-acid2测试ROM对PPU(图像处理器)进行验证。目前其他所有blargg测试ROM均已通过,但PPU存在渲染问题——笑脸图案出现闪烁和区块缺失,故障表现如下:

故障演示

我已经查阅PanDocs排查问题,但未找到原因。以下是相关代码及指定提交哈希下的源码位置:

核心PPU周期处理代码

void tick_ppu(Gameboy *gameboy, uint8_t cycles) {
    if (!(gameboy->ppu.lcdc & 0x80)) {
        gameboy->ppu.ly = 0;
        gameboy->ppu.mode = 0;
        gameboy->ppu.dots = 0;
        return;
    }

    gameboy->ppu.dots += cycles;

    switch (gameboy->ppu.mode) {
        case 2: {
            if (gameboy->ppu.dots >= 80) {
                gameboy->ppu.sprite_count = 0;
                uint8_t sprite_height = (gameboy->ppu.lcdc & 0x04) ? 16 : 8;

                for (int i = 0; i < 40 && gameboy->ppu.sprite_count < 10; i++) {
                    uint8_t y = gameboy->oam[i * 4];
                    int16_t sprite_y = y - 16;

                    if (gameboy->ppu.ly >= sprite_y && gameboy->ppu.ly < sprite_y + sprite_height) {
                        for (int j = 0; j < 4; j++) {
                            gameboy->ppu.sprite_buffer[gameboy->ppu.sprite_count * 4 + j] = gameboy->oam[i * 4 + j];
                        }
                        gameboy->ppu.sprite_count++;
                    }
                }

                gameboy->ppu.mode3_length = 172 + (gameboy->ppu.sprite_count * 8);

                gameboy->ppu.dots = 0;
                gameboy->ppu.mode = 3;
            }
            break;
        }
        case 3: {
            if (gameboy->ppu.dots >= gameboy->ppu.mode3_length) {
                gameboy->ppu.dots = 0;
                gameboy->ppu.mode = 0;
                render_scanline(gameboy);
            }
            break;
        }
        case 0: {
            if (gameboy->ppu.dots >= 204) {
                gameboy->ppu.dots = 0;
                gameboy->ppu.ly++;

                if (gameboy->ppu.ly >= 144) {
                    gameboy->ppu.mode = 1;
                    gameboy->if_reg |= 0x01;
                } else {
                    gameboy->ppu.mode = 2;
                }
            }
            break;
        }
        case 1: {
            if (gameboy->ppu.dots >= 456) {
                gameboy->ppu.dots = 0;
                gameboy->ppu.ly++;

                if (gameboy->ppu.ly >= 154) {
                    gameboy->ppu.ly = 0;
                    gameboy->ppu.mode = 2;
                    gameboy->ppu.window_line = 0;
                }
            }
            break;
        }
    }

    gameboy->ppu.stat = (gameboy->ppu.stat & 0xFC) | (gameboy->ppu.mode & 0x03);

    if (gameboy->ppu.ly == gameboy->ppu.lyc) {
        gameboy->ppu.stat |= 0x04;
        if (gameboy->ppu.stat & 0x40) {
            gameboy->if_reg |= 0x02;
        }
    } else {
        gameboy->ppu.stat &= ~0x04;
    }
}

相关源码位置(提交哈希:b122b11203eb2fe0c62afb4eaac81f80f740b618)

  • render_scanline:cpu.c 第2652行
  • tick_ppu:cpu.c 第2838行
  • init_display:gameboy.c 第42行

内容的提问来源于stack exchange,提问作者Brody Critchlow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 13:27:37