Start replacing packed structs with flags
@@ -61,4 +61,19 @@ #define STORE_32(SRC, ADDR, ARR) ((uint32_t*) ARR)[(ADDR) >> 2] = SRC
#define STORE_16(SRC, ADDR, ARR) ((uint16_t*) ARR)[(ADDR) >> 1] = SRC #endif +#define MAKE_MASK(START, END) (((1 << ((END) - (START))) - 1) << (START)) +#define CHECK_BITS(SRC, START, END) ((SRC) & MAKE_MASK(START, END)) +#define EXT_BITS(SRC, START, END) (((SRC) >> (START)) & ((1 << ((END) - (START))) - 1)) + +#define DECL_BITFIELD(NAME, TYPE) typedef TYPE NAME + +#define DECL_BITS(TYPE, FIELD, START, SIZE) \ + static inline TYPE TYPE ## Is ## FIELD (TYPE src) { \ + return CHECK_BITS(src, (START), (START) + (SIZE)); \ + } \ + static inline TYPE TYPE ## Get ## FIELD (TYPE src) { \ + return EXT_BITS(src, (START), (START) + (SIZE)); \ + } + +#define DECL_BIT(TYPE, FIELD, BIT) DECL_BITS(TYPE, FIELD, BIT, 1) #endif
@@ -125,25 +125,21 @@ #define GBA_TEXT_MAP_HFLIP(MAP) ((MAP) & 0x0400)
#define GBA_TEXT_MAP_VFLIP(MAP) ((MAP) & 0x0800) #define GBA_TEXT_MAP_PALETTE(MAP) (((MAP) & 0xF000) >> 12) -union GBARegisterDISPCNT { - struct { - unsigned mode : 3; - unsigned cgb : 1; - unsigned frameSelect : 1; - unsigned hblankIntervalFree : 1; - unsigned objCharacterMapping : 1; - unsigned forcedBlank : 1; - unsigned bg0Enable : 1; - unsigned bg1Enable : 1; - unsigned bg2Enable : 1; - unsigned bg3Enable : 1; - unsigned objEnable : 1; - unsigned win0Enable : 1; - unsigned win1Enable : 1; - unsigned objwinEnable : 1; - }; - uint16_t packed; -}; +DECL_BITFIELD(GBARegisterDISPCNT, uint16_t); +DECL_BITS(GBARegisterDISPCNT, Mode, 0, 3); +DECL_BIT(GBARegisterDISPCNT, Cgb, 3); +DECL_BIT(GBARegisterDISPCNT, FrameSelect, 4); +DECL_BIT(GBARegisterDISPCNT, HblankIntervalFree, 5); +DECL_BIT(GBARegisterDISPCNT, ObjCharacterMapping, 6); +DECL_BIT(GBARegisterDISPCNT, ForcedBlank, 7); +DECL_BIT(GBARegisterDISPCNT, Bg0Enable, 8); +DECL_BIT(GBARegisterDISPCNT, Bg1Enable, 9); +DECL_BIT(GBARegisterDISPCNT, Bg2Enable, 10); +DECL_BIT(GBARegisterDISPCNT, Bg3Enable, 11); +DECL_BIT(GBARegisterDISPCNT, ObjEnable, 12); +DECL_BIT(GBARegisterDISPCNT, Win0Enable, 13); +DECL_BIT(GBARegisterDISPCNT, Win1Enable, 14); +DECL_BIT(GBARegisterDISPCNT, ObjwinEnable, 15); union GBARegisterDISPSTAT { struct {
@@ -77,7 +77,7 @@ static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer) {
struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; int i; - softwareRenderer->dispcnt.packed = 0x0080; + softwareRenderer->dispcnt = 0x0080; softwareRenderer->target1Obj = 0; softwareRenderer->target1Bd = 0;@@ -142,7 +142,7 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) {
struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; switch (address) { case REG_DISPCNT: - softwareRenderer->dispcnt.packed = value; + softwareRenderer->dispcnt = value; GBAVideoSoftwareRendererUpdateDISPCNT(softwareRenderer); break; case REG_BG0CNT:@@ -417,7 +417,7 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) {
struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; - if (softwareRenderer->dispcnt.forcedBlank) { + if (GBARegisterDISPCNTIsForcedBlank(softwareRenderer->dispcnt)) { int x; for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; ++x) { row[x] = GBA_COLOR_WHITE;@@ -435,12 +435,12 @@ }
softwareRenderer->windows[0].endX = VIDEO_HORIZONTAL_PIXELS; softwareRenderer->nWindows = 1; - if (softwareRenderer->dispcnt.win0Enable || softwareRenderer->dispcnt.win1Enable || softwareRenderer->dispcnt.objwinEnable) { + if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) { softwareRenderer->windows[0].control = softwareRenderer->winout; - if (softwareRenderer->dispcnt.win1Enable && y < softwareRenderer->winN[1].v.end && y >= softwareRenderer->winN[1].v.start) { + if (GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) && y < softwareRenderer->winN[1].v.end && y >= softwareRenderer->winN[1].v.start) { _breakWindow(softwareRenderer, &softwareRenderer->winN[1]); } - if (softwareRenderer->dispcnt.win0Enable && y < softwareRenderer->winN[0].v.end && y >= softwareRenderer->winN[0].v.start) { + if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) && y < softwareRenderer->winN[0].v.end && y >= softwareRenderer->winN[0].v.start) { _breakWindow(softwareRenderer, &softwareRenderer->winN[0]); } } else {@@ -524,10 +524,10 @@ }
} static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRenderer* renderer) { - renderer->bg[0].enabled = renderer->dispcnt.bg0Enable; - renderer->bg[1].enabled = renderer->dispcnt.bg1Enable; - renderer->bg[2].enabled = renderer->dispcnt.bg2Enable; - renderer->bg[3].enabled = renderer->dispcnt.bg3Enable; + renderer->bg[0].enabled = GBARegisterDISPCNTGetBg0Enable(renderer->dispcnt); + renderer->bg[1].enabled = GBARegisterDISPCNTGetBg1Enable(renderer->dispcnt); + renderer->bg[2].enabled = GBARegisterDISPCNTGetBg2Enable(renderer->dispcnt); + renderer->bg[3].enabled = GBARegisterDISPCNTGetBg3Enable(renderer->dispcnt); } static void GBAVideoSoftwareRendererWriteBGCNT(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* bg, uint16_t value) {@@ -629,14 +629,14 @@
#define TEST_LAYER_ENABLED(X) \ (renderer->bg[X].enabled && \ (renderer->currentWindow.bg ## X ## Enable || \ - (renderer->dispcnt.objwinEnable && renderer->objwin.bg ## X ## Enable)) && \ + (GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt) && renderer->objwin.bg ## X ## Enable)) && \ renderer->bg[X].priority == priority) static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) { int w; renderer->end = 0; int spriteLayers = 0; - if (renderer->dispcnt.objEnable) { + if (GBARegisterDISPCNTIsObjEnable(renderer->dispcnt)) { if (renderer->oamDirty) { _cleanOAM(renderer); }@@ -680,14 +680,14 @@ for (w = 0; w < renderer->nWindows; ++w) {
renderer->start = renderer->end; renderer->end = renderer->windows[w].endX; renderer->currentWindow = renderer->windows[w].control; - if (TEST_LAYER_ENABLED(0) && renderer->dispcnt.mode < 2) { + if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(renderer->dispcnt) < 2) { _drawBackgroundMode0(renderer, &renderer->bg[0], y); } - if (TEST_LAYER_ENABLED(1) && renderer->dispcnt.mode < 2) { + if (TEST_LAYER_ENABLED(1) && GBARegisterDISPCNTGetMode(renderer->dispcnt) < 2) { _drawBackgroundMode0(renderer, &renderer->bg[1], y); } if (TEST_LAYER_ENABLED(2)) { - switch (renderer->dispcnt.mode) { + switch (GBARegisterDISPCNTGetMode(renderer->dispcnt)) { case 0: _drawBackgroundMode0(renderer, &renderer->bg[2], y); break;@@ -707,7 +707,7 @@ break;
} } if (TEST_LAYER_ENABLED(3)) { - switch (renderer->dispcnt.mode) { + switch (GBARegisterDISPCNTGetMode(renderer->dispcnt)) { case 0: _drawBackgroundMode0(renderer, &renderer->bg[3], y); break;@@ -819,7 +819,7 @@ localY = 7 - localY; \
} #define PREPARE_OBJWIN \ - int objwinSlowPath = renderer->dispcnt.objwinEnable; \ + int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt); \ int objwinOnly = 0; \ int objwinForceEnable = 0; \ color_t* objwinPalette; \@@ -1377,7 +1377,7 @@ BACKGROUND_BITMAP_INIT;
uint16_t color; uint32_t offset = 0; - if (renderer->dispcnt.frameSelect) { + if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) { offset = 0xA000; }@@ -1405,7 +1405,7 @@ BACKGROUND_BITMAP_INIT;
uint32_t color; uint32_t offset = 0; - if (renderer->dispcnt.frameSelect) { + if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) { offset = 0xA000; }@@ -1481,7 +1481,7 @@ SPRITE_DRAW_PIXEL_ ## DEPTH ## _ ## TYPE(localX); \
} #define SPRITE_XBASE_16(localX) unsigned xBase = (localX & ~0x7) * 4 + ((localX >> 1) & 2); -#define SPRITE_YBASE_16(localY) unsigned yBase = (localY & ~0x7) * (renderer->dispcnt.objCharacterMapping ? width >> 1 : 0x80) + (localY & 0x7) * 4; +#define SPRITE_YBASE_16(localY) unsigned yBase = (localY & ~0x7) * (GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? width >> 1 : 0x80) + (localY & 0x7) * 4; #define SPRITE_DRAW_PIXEL_16_NORMAL(localX) \ unsigned tileData = vramBase[((yBase + charBase + xBase) & 0x7FFF) >> 1]; \@@ -1498,7 +1498,7 @@ renderer->row[outX] |= FLAG_OBJWIN; \
} #define SPRITE_XBASE_256(localX) unsigned xBase = (localX & ~0x7) * 8 + (localX & 6); -#define SPRITE_YBASE_256(localY) unsigned yBase = (localY & ~0x7) * (renderer->dispcnt.objCharacterMapping ? width : 0x80) + (localY & 0x7) * 8; +#define SPRITE_YBASE_256(localY) unsigned yBase = (localY & ~0x7) * (GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? width : 0x80) + (localY & 0x7) * 8; #define SPRITE_DRAW_PIXEL_256_NORMAL(localX) \ unsigned tileData = vramBase[((yBase + charBase + xBase) & 0x7FFF) >> 1]; \@@ -1630,7 +1630,7 @@ int x;
uint32_t* pixel = renderer->row; uint32_t flags = FLAG_TARGET_2 * renderer->target2Obj; - int objwinSlowPath = renderer->dispcnt.objwinEnable; + int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt); int objwinDisable = 0; if (objwinSlowPath) { objwinDisable = !renderer->objwin.objEnable;
@@ -113,7 +113,7 @@
color_t* outputBuffer; unsigned outputBufferStride; - union GBARegisterDISPCNT dispcnt; + GBARegisterDISPCNT dispcnt; uint32_t row[VIDEO_HORIZONTAL_PIXELS]; uint32_t spriteLayer[VIDEO_HORIZONTAL_PIXELS];