all repos — mgba @ 0c18e415e8fa7973e5e79ad22d9c934786ed833b

mGBA Game Boy Advance Emulator

Use bitfields for windows
Jeffrey Pfau jeffrey@endrift.com
Mon, 06 Oct 2014 00:16:33 -0700
commit

0c18e415e8fa7973e5e79ad22d9c934786ed833b

parent

3a09353ff82a3779591d6dd967d84bbadd44a131

2 files changed, 45 insertions(+), 55 deletions(-)

jump to
M src/gba/renderers/video-software.csrc/gba/renderers/video-software.c

@@ -105,18 +105,10 @@ softwareRenderer->blda = 0;

softwareRenderer->bldb = 0; softwareRenderer->bldy = 0; - softwareRenderer->winN[0].h.packed = 0; - softwareRenderer->winN[0].v.packed = 0; - softwareRenderer->winN[0].control.packed = 0; - softwareRenderer->winN[0].control.priority = 0; - softwareRenderer->winN[1].h.packed = 0; - softwareRenderer->winN[1].v.packed = 0; - softwareRenderer->winN[1].control.packed = 0; - softwareRenderer->winN[1].control.priority = 1; - softwareRenderer->objwin.packed = 0; - softwareRenderer->objwin.priority = 2; - softwareRenderer->winout.packed = 0; - softwareRenderer->winout.priority = 3; + softwareRenderer->winN[0] = (struct WindowN) { .control = { .priority = 0 } }; + softwareRenderer->winN[1] = (struct WindowN) { .control = { .priority = 1 } }; + softwareRenderer->objwin = (struct WindowControl) { .priority = 2 }; + softwareRenderer->winout = (struct WindowControl) { .priority = 3 }; softwareRenderer->oamMax = 0; softwareRenderer->mosaic.packed = 0;

@@ -276,7 +268,8 @@ }

_updatePalettes(softwareRenderer); break; case REG_WIN0H: - softwareRenderer->winN[0].h.packed = value; + softwareRenderer->winN[0].h.end = value; + softwareRenderer->winN[0].h.start = value >> 8; if (softwareRenderer->winN[0].h.start > VIDEO_HORIZONTAL_PIXELS && softwareRenderer->winN[0].h.start > softwareRenderer->winN[0].h.end) { softwareRenderer->winN[0].h.start = 0; }

@@ -285,7 +278,8 @@ softwareRenderer->winN[0].h.end = VIDEO_HORIZONTAL_PIXELS;

} break; case REG_WIN1H: - softwareRenderer->winN[1].h.packed = value; + softwareRenderer->winN[1].h.end = value; + softwareRenderer->winN[1].h.start = value >> 8; if (softwareRenderer->winN[1].h.start > VIDEO_HORIZONTAL_PIXELS && softwareRenderer->winN[1].h.start > softwareRenderer->winN[1].h.end) { softwareRenderer->winN[1].h.start = 0; }

@@ -294,7 +288,8 @@ softwareRenderer->winN[1].h.end = VIDEO_HORIZONTAL_PIXELS;

} break; case REG_WIN0V: - softwareRenderer->winN[0].v.packed = value; + softwareRenderer->winN[0].v.end = value; + softwareRenderer->winN[0].v.start = value >> 8; if (softwareRenderer->winN[0].v.start > VIDEO_VERTICAL_PIXELS && softwareRenderer->winN[0].v.start > softwareRenderer->winN[0].v.end) { softwareRenderer->winN[0].v.start = 0; }

@@ -303,7 +298,8 @@ softwareRenderer->winN[0].v.end = VIDEO_VERTICAL_PIXELS;

} break; case REG_WIN1V: - softwareRenderer->winN[1].v.packed = value; + softwareRenderer->winN[1].v.end = value; + softwareRenderer->winN[1].v.start = value >> 8; if (softwareRenderer->winN[1].v.start > VIDEO_VERTICAL_PIXELS && softwareRenderer->winN[1].v.start > softwareRenderer->winN[1].v.end) { softwareRenderer->winN[1].v.start = 0; }

@@ -469,7 +465,7 @@ x = 0;

for (w = 0; w < softwareRenderer->nWindows; ++w) { // TOOD: handle objwin on backdrop uint32_t backdrop = FLAG_UNWRITTEN | FLAG_PRIORITY | FLAG_IS_BACKGROUND; - if (!softwareRenderer->target1Bd || softwareRenderer->blendEffect == BLEND_NONE || softwareRenderer->blendEffect == BLEND_ALPHA || !softwareRenderer->windows[w].control.blendEnable) { + if (!softwareRenderer->target1Bd || softwareRenderer->blendEffect == BLEND_NONE || softwareRenderer->blendEffect == BLEND_ALPHA || !GBAWindowControlIsBlendEnable(softwareRenderer->windows[w].control.packed)) { backdrop |= softwareRenderer->normalPalette[0]; } else { backdrop |= softwareRenderer->variantPalette[0];

@@ -486,7 +482,7 @@ if (softwareRenderer->target2Bd) {

x = 0; for (w = 0; w < softwareRenderer->nWindows; ++w) { uint32_t backdrop = FLAG_UNWRITTEN; - if (!softwareRenderer->target1Bd || softwareRenderer->blendEffect == BLEND_NONE || softwareRenderer->blendEffect == BLEND_ALPHA || !softwareRenderer->windows[w].control.blendEnable) { + if (!softwareRenderer->target1Bd || softwareRenderer->blendEffect == BLEND_NONE || softwareRenderer->blendEffect == BLEND_ALPHA || !GBAWindowControlIsBlendEnable(softwareRenderer->windows[w].control.packed)) { backdrop |= softwareRenderer->normalPalette[0]; } else { backdrop |= softwareRenderer->variantPalette[0];

@@ -625,8 +621,8 @@ }

#define TEST_LAYER_ENABLED(X) \ (renderer->bg[X].enabled && \ - (renderer->currentWindow.bg ## X ## Enable || \ - (GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt) && renderer->objwin.bg ## X ## Enable)) && \ + (GBAWindowControlIsBg ## X ## Enable(renderer->currentWindow.packed) || \ + (GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt) && GBAWindowControlIsBg ## X ## Enable (renderer->objwin.packed))) && \ renderer->bg[X].priority == priority) static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {

@@ -643,7 +639,7 @@ for (w = 0; w < renderer->nWindows; ++w) {

renderer->start = renderer->end; renderer->end = renderer->windows[w].endX; renderer->currentWindow = renderer->windows[w].control; - if (!renderer->currentWindow.objEnable) { + if (!GBAWindowControlIsObjEnable(renderer->currentWindow.packed)) { continue; } int i;

@@ -817,27 +813,27 @@ int objwinOnly = 0; \

int objwinForceEnable = 0; \ color_t* objwinPalette; \ if (objwinSlowPath) { \ - if (background->target1 && renderer->objwin.blendEnable && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN)) { \ + if (background->target1 && GBAWindowControlIsBlendEnable(renderer->objwin.packed) && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN)) { \ objwinPalette = renderer->variantPalette; \ } else { \ objwinPalette = renderer->normalPalette; \ } \ switch (background->index) { \ case 0: \ - objwinForceEnable = renderer->objwin.bg0Enable && renderer->currentWindow.bg0Enable; \ - objwinOnly = !renderer->objwin.bg0Enable; \ + objwinForceEnable = GBAWindowControlIsBg0Enable(renderer->objwin.packed) && GBAWindowControlIsBg0Enable(renderer->currentWindow.packed); \ + objwinOnly = !GBAWindowControlIsBg0Enable(renderer->objwin.packed); \ break; \ case 1: \ - objwinForceEnable = renderer->objwin.bg1Enable && renderer->currentWindow.bg1Enable; \ - objwinOnly = !renderer->objwin.bg1Enable; \ + objwinForceEnable = GBAWindowControlIsBg1Enable(renderer->objwin.packed) && GBAWindowControlIsBg1Enable(renderer->currentWindow.packed); \ + objwinOnly = !GBAWindowControlIsBg1Enable(renderer->objwin.packed); \ break; \ case 2: \ - objwinForceEnable = renderer->objwin.bg2Enable && renderer->currentWindow.bg2Enable; \ - objwinOnly = !renderer->objwin.bg2Enable; \ + objwinForceEnable = GBAWindowControlIsBg2Enable(renderer->objwin.packed) && GBAWindowControlIsBg2Enable(renderer->currentWindow.packed); \ + objwinOnly = !GBAWindowControlIsBg2Enable(renderer->objwin.packed); \ break; \ case 3: \ - objwinForceEnable = renderer->objwin.bg3Enable && renderer->currentWindow.bg3Enable; \ - objwinOnly = !renderer->objwin.bg3Enable; \ + objwinForceEnable = GBAWindowControlIsBg3Enable(renderer->objwin.packed) && GBAWindowControlIsBg3Enable(renderer->currentWindow.packed); \ + objwinOnly = !GBAWindowControlIsBg3Enable(renderer->objwin.packed); \ break; \ } \ }

@@ -1215,7 +1211,7 @@ flags |= FLAG_TARGET_2 * background->target2;

uint32_t screenBase; uint32_t charBase; - int variant = background->target1 && renderer->currentWindow.blendEnable && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); + int variant = background->target1 && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); color_t* mainPalette = renderer->normalPalette; if (variant) { mainPalette = renderer->variantPalette;

@@ -1274,7 +1270,7 @@ \

int flags = (background->priority << OFFSET_PRIORITY) | (background->index << OFFSET_INDEX) | FLAG_IS_BACKGROUND; \ flags |= FLAG_TARGET_1 * (background->target1 && renderer->blendEffect == BLEND_ALPHA); \ flags |= FLAG_TARGET_2 * background->target2; \ - int variant = background->target1 && renderer->currentWindow.blendEnable && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); \ + int variant = background->target1 && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); \ color_t* palette = renderer->normalPalette; \ if (variant) { \ palette = renderer->variantPalette; \

@@ -1516,13 +1512,13 @@ int height = _objSizes[GBAObjAttributesAGetShape(sprite->a) * 8 + GBAObjAttributesBGetSize(sprite->b) * 2 + 1];

int start = renderer->start; int end = renderer->end; uint32_t flags = GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; - flags |= FLAG_TARGET_1 * ((renderer->currentWindow.blendEnable && renderer->target1Obj && renderer->blendEffect == BLEND_ALPHA) || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT); + 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); int32_t x = GBAObjAttributesBGetX(sprite->b) << 23; x >>= 23; uint16_t* vramBase = &renderer->d.vram[BASE_TILE >> 1]; unsigned charBase = GBAObjAttributesCGetTile(sprite->c) * 0x20; - int variant = renderer->target1Obj && renderer->currentWindow.blendEnable && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); + int variant = renderer->target1Obj && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT && renderer->target2Bd) { // Hack: if a sprite is blended, then the variant palette is not used, but we don't know if it's blended in advance variant = 0;

@@ -1620,7 +1616,7 @@

int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt); int objwinDisable = 0; if (objwinSlowPath) { - objwinDisable = !renderer->objwin.objEnable; + objwinDisable = !GBAWindowControlIsObjEnable(renderer->objwin.packed); } if (objwinSlowPath && objwinDisable) { for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; ++x, ++pixel) {
M src/gba/renderers/video-software.hsrc/gba/renderers/video-software.h

@@ -73,27 +73,21 @@ #define FLAG_ORDER_MASK 0xF8000000

#define IS_WRITABLE(PIXEL) ((PIXEL) & 0xFE000000) -union WindowRegion { - struct { - uint8_t end; - uint8_t start; - }; - uint16_t packed; +struct WindowRegion { + uint8_t end; + uint8_t start; }; +DECL_BITFIELD(GBAWindowControl, uint8_t); +DECL_BIT(GBAWindowControl, Bg0Enable, 0); +DECL_BIT(GBAWindowControl, Bg1Enable, 1); +DECL_BIT(GBAWindowControl, Bg2Enable, 2); +DECL_BIT(GBAWindowControl, Bg3Enable, 3); +DECL_BIT(GBAWindowControl, ObjEnable, 4); +DECL_BIT(GBAWindowControl, BlendEnable, 5); + struct WindowControl { - union { - struct { - unsigned bg0Enable : 1; - unsigned bg1Enable : 1; - unsigned bg2Enable : 1; - unsigned bg3Enable : 1; - unsigned objEnable : 1; - unsigned blendEnable : 1; - unsigned : 2; - }; - uint8_t packed; - }; + GBAWindowControl packed; int8_t priority; };

@@ -140,8 +134,8 @@ uint16_t packed;

} mosaic; struct WindowN { - union WindowRegion h; - union WindowRegion v; + struct WindowRegion h; + struct WindowRegion v; struct WindowControl control; } winN[2];