mirror of https://github.com/mgba-emu/mgba.git
GBA Video: Add window toggling
This commit is contained in:
parent
9064cb107b
commit
c8e1e14d3f
1
CHANGES
1
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -194,6 +194,8 @@ struct GBAVideoRenderer {
|
|||
|
||||
bool disableBG[4];
|
||||
bool disableOBJ;
|
||||
bool disableWIN[2];
|
||||
bool disableOBJWIN;
|
||||
|
||||
bool highlightBG[4];
|
||||
bool highlightOBJ[128];
|
||||
|
|
|
@ -33,11 +33,14 @@
|
|||
#include <mgba-util/vfs.h>
|
||||
|
||||
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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -154,16 +154,44 @@ void FrameView::updateTilesGBA(bool) {
|
|||
|
||||
uint16_t* io = static_cast<GBA*>(m_controller->thread()->core->board)->memory.io;
|
||||
QRgb backdrop = M_RGB5_TO_RGB8(static_cast<GBA*>(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<bool, 4> 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");
|
||||
|
|
|
@ -112,10 +112,6 @@ private:
|
|||
ColorPicker m_backdropPicker;
|
||||
QColor m_overrideBackdrop;
|
||||
|
||||
#ifdef M_CORE_GBA
|
||||
uint16_t m_gbaDispcnt;
|
||||
#endif
|
||||
|
||||
std::shared_ptr<bool> m_callbackLocker{std::make_shared<bool>(true)};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue