diff --git a/CHANGES b/CHANGES index fbb2b9390..040ee635b 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,7 @@ Features: - Command scripts for CLI debugger (by ahigerd) - ARM disassembler now resolves addresses to symbol names - Add Game Boy Player feature support to ports + - Individual window types can now be toggled in GBA debugging views Emulation fixes: - ARM: Fix ALU reading PC after shifting - ARM: Fix STR storing PC after address calculation diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 0c13834dd..b59d265a2 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -34,6 +34,17 @@ enum GBASIOJOYCommand { JOY_RECV = 0x15 }; +enum GBAVideoLayer { + GBA_LAYER_BG0 = 0, + GBA_LAYER_BG1, + GBA_LAYER_BG2, + GBA_LAYER_BG3, + GBA_LAYER_OBJ, + GBA_LAYER_WIN0, + GBA_LAYER_WIN1, + GBA_LAYER_OBJWIN, +}; + struct GBA; struct GBAAudio; struct GBASIO; diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index c9ae1974a..0a27807b4 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -194,6 +194,8 @@ struct GBAVideoRenderer { bool disableBG[4]; bool disableOBJ; + bool disableWIN[2]; + bool disableOBJWIN; bool highlightBG[4]; bool highlightOBJ[128]; diff --git a/src/gba/core.c b/src/gba/core.c index a36edb826..76820d5d8 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -33,11 +33,14 @@ #include static const struct mCoreChannelInfo _GBAVideoLayers[] = { - { 0, "bg0", "Background 0", NULL }, - { 1, "bg1", "Background 1", NULL }, - { 2, "bg2", "Background 2", NULL }, - { 3, "bg3", "Background 3", NULL }, - { 4, "obj", "Objects", NULL }, + { GBA_LAYER_BG0, "bg0", "Background 0", NULL }, + { GBA_LAYER_BG1, "bg1", "Background 1", NULL }, + { GBA_LAYER_BG2, "bg2", "Background 2", NULL }, + { GBA_LAYER_BG3, "bg3", "Background 3", NULL }, + { GBA_LAYER_OBJ, "obj", "Objects", NULL }, + { GBA_LAYER_WIN0, "win0", "Window 0", NULL }, + { GBA_LAYER_WIN1, "win1", "Window 1", NULL }, + { GBA_LAYER_OBJWIN, "objwin", "Object Window", NULL }, }; static const struct mCoreChannelInfo _GBAAudioChannels[] = { @@ -1038,15 +1041,24 @@ static size_t _GBACoreListAudioChannels(const struct mCore* core, const struct m static void _GBACoreEnableVideoLayer(struct mCore* core, size_t id, bool enable) { struct GBA* gba = core->board; switch (id) { - case 0: - case 1: - case 2: - case 3: + case GBA_LAYER_BG0: + case GBA_LAYER_BG1: + case GBA_LAYER_BG2: + case GBA_LAYER_BG3: gba->video.renderer->disableBG[id] = !enable; break; - case 4: + case GBA_LAYER_OBJ: gba->video.renderer->disableOBJ = !enable; break; + case GBA_LAYER_WIN0: + gba->video.renderer->disableWIN[0] = !enable; + break; + case GBA_LAYER_WIN1: + gba->video.renderer->disableWIN[1] = !enable; + break; + case GBA_LAYER_OBJWIN: + gba->video.renderer->disableOBJWIN = !enable; + break; default: break; } @@ -1075,14 +1087,14 @@ static void _GBACoreEnableAudioChannel(struct mCore* core, size_t id, bool enabl static void _GBACoreAdjustVideoLayer(struct mCore* core, size_t id, int32_t x, int32_t y) { struct GBACore* gbacore = (struct GBACore*) core; switch (id) { - case 0: - case 1: - case 2: - case 3: + case GBA_LAYER_BG0: + case GBA_LAYER_BG1: + case GBA_LAYER_BG2: + case GBA_LAYER_BG3: gbacore->renderer.bg[id].offsetX = x; gbacore->renderer.bg[id].offsetY = y; break; - case 4: + case GBA_LAYER_OBJ: gbacore->renderer.objOffsetX = x; gbacore->renderer.objOffsetY = y; gbacore->renderer.oamDirty = 1; diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index 2ec58cb0d..f96cca31e 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -43,6 +43,9 @@ void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct renderer->d.disableBG[2] = false; renderer->d.disableBG[3] = false; renderer->d.disableOBJ = false; + renderer->d.disableWIN[0] = false; + renderer->d.disableWIN[1] = false; + renderer->d.disableOBJWIN = false; renderer->d.highlightBG[0] = false; renderer->d.highlightBG[1] = false; @@ -202,6 +205,9 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD proxyRenderer->backend->disableBG[2] = proxyRenderer->d.disableBG[2]; proxyRenderer->backend->disableBG[3] = proxyRenderer->d.disableBG[3]; proxyRenderer->backend->disableOBJ = proxyRenderer->d.disableOBJ; + proxyRenderer->backend->disableWIN[0] = proxyRenderer->d.disableWIN[0]; + proxyRenderer->backend->disableWIN[1] = proxyRenderer->d.disableWIN[1]; + proxyRenderer->backend->disableOBJWIN = proxyRenderer->d.disableOBJWIN; proxyRenderer->backend->highlightBG[0] = proxyRenderer->d.highlightBG[0]; proxyRenderer->backend->highlightBG[1] = proxyRenderer->d.highlightBG[1]; proxyRenderer->backend->highlightBG[2] = proxyRenderer->d.highlightBG[2]; @@ -302,6 +308,9 @@ void GBAVideoProxyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) proxyRenderer->backend->disableBG[2] = proxyRenderer->d.disableBG[2]; proxyRenderer->backend->disableBG[3] = proxyRenderer->d.disableBG[3]; proxyRenderer->backend->disableOBJ = proxyRenderer->d.disableOBJ; + proxyRenderer->backend->disableWIN[0] = proxyRenderer->d.disableWIN[0]; + proxyRenderer->backend->disableWIN[1] = proxyRenderer->d.disableWIN[1]; + proxyRenderer->backend->disableOBJWIN = proxyRenderer->d.disableOBJWIN; proxyRenderer->backend->highlightBG[0] = proxyRenderer->d.highlightBG[0]; proxyRenderer->backend->highlightBG[1] = proxyRenderer->d.highlightBG[1]; proxyRenderer->backend->highlightBG[2] = proxyRenderer->d.highlightBG[2]; diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index 514adc724..3fb364f56 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -148,7 +148,7 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re uint32_t flags = GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; flags |= FLAG_TARGET_1 * ((GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && renderer->target1Obj && renderer->blendEffect == BLEND_ALPHA) || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT); flags |= FLAG_OBJWIN * (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN); - if ((flags & FLAG_OBJWIN) && renderer->currentWindow.priority < renderer->objwin.priority) { + if ((flags & FLAG_OBJWIN) && (renderer->currentWindow.priority < renderer->objwin.priority || renderer->d.disableOBJWIN)) { return 0; } int32_t x = (uint32_t) GBAObjAttributesBGetX(sprite->b) << 23; diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 1a746e2a5..9a8fb3b0d 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -61,6 +61,9 @@ void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { renderer->d.disableBG[2] = false; renderer->d.disableBG[3] = false; renderer->d.disableOBJ = false; + renderer->d.disableWIN[0] = false; + renderer->d.disableWIN[1] = false; + renderer->d.disableOBJWIN = false; renderer->d.highlightBG[0] = false; renderer->d.highlightBG[1] = false; @@ -572,10 +575,10 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render softwareRenderer->nWindows = 1; if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) { softwareRenderer->windows[0].control = softwareRenderer->winout; - if (GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt)) { + if (GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) && !renderer->disableWIN[1]) { _breakWindow(softwareRenderer, &softwareRenderer->winN[1], y); } - if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt)) { + if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) && !renderer->disableWIN[0]) { _breakWindow(softwareRenderer, &softwareRenderer->winN[0], y); } } else { diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 3d33a97de..649c16e92 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -154,16 +154,44 @@ void FrameView::updateTilesGBA(bool) { uint16_t* io = static_cast(m_controller->thread()->core->board)->memory.io; QRgb backdrop = M_RGB5_TO_RGB8(static_cast(m_controller->thread()->core->board)->video.palette[0]); - m_gbaDispcnt = io[REG_DISPCNT >> 1]; - int mode = GBARegisterDISPCNTGetMode(m_gbaDispcnt); + GBARegisterDISPCNT gbaDispcnt = io[REG_DISPCNT >> 1]; + int mode = GBARegisterDISPCNTGetMode(gbaDispcnt); std::array enabled{ - bool(GBARegisterDISPCNTIsBg0Enable(m_gbaDispcnt)), - bool(GBARegisterDISPCNTIsBg1Enable(m_gbaDispcnt)), - bool(GBARegisterDISPCNTIsBg2Enable(m_gbaDispcnt)), - bool(GBARegisterDISPCNTIsBg3Enable(m_gbaDispcnt)), + bool(GBARegisterDISPCNTIsBg0Enable(gbaDispcnt)), + bool(GBARegisterDISPCNTIsBg1Enable(gbaDispcnt)), + bool(GBARegisterDISPCNTIsBg2Enable(gbaDispcnt)), + bool(GBARegisterDISPCNTIsBg3Enable(gbaDispcnt)), }; + if (GBARegisterDISPCNTIsWin0Enable(gbaDispcnt)) { + m_queue.append({ + { LayerId::WINDOW, 0 }, + !m_disabled.contains({ LayerId::WINDOW, 0 }), + {}, + {}, {0, 0}, true, false + }); + } + + if (GBARegisterDISPCNTIsWin1Enable(gbaDispcnt)) { + m_queue.append({ + { LayerId::WINDOW, 1 }, + !m_disabled.contains({ LayerId::WINDOW, 1 }), + {}, + {}, {0, 0}, true, false + }); + } + + if (GBARegisterDISPCNTIsObjwinEnable(gbaDispcnt)) { + m_queue.append({ + { LayerId::WINDOW, 2 }, + !m_disabled.contains({ LayerId::WINDOW, 2 }), + {}, + {}, {0, 0}, true, false + }); + + } + for (int priority = 0; priority < 4; ++priority) { for (int sprite = 0; sprite < 128; ++sprite) { ObjInfo info; @@ -271,6 +299,9 @@ void FrameView::injectGBA() { gba->video.renderer->highlightBG[layer.id.index] = true; } break; + case LayerId::WINDOW: + m_vl->enableVideoLayer(m_vl, GBA_LAYER_WIN0 + layer.id.index, layer.enabled); + break; } } if (m_overrideBackdrop.isValid()) { @@ -521,6 +552,11 @@ QString FrameView::LayerId::readable() const { break; case WINDOW: typeStr = tr("Window"); +#ifdef M_CORE_GBA + if (index == 2) { + return tr("Objwin"); + } +#endif break; case SPRITE: typeStr = tr("Sprite"); diff --git a/src/platform/qt/FrameView.h b/src/platform/qt/FrameView.h index 96794005b..c3054b2a7 100644 --- a/src/platform/qt/FrameView.h +++ b/src/platform/qt/FrameView.h @@ -112,10 +112,6 @@ private: ColorPicker m_backdropPicker; QColor m_overrideBackdrop; -#ifdef M_CORE_GBA - uint16_t m_gbaDispcnt; -#endif - std::shared_ptr m_callbackLocker{std::make_shared(true)}; };