Start replacing packed structs with flags

This commit is contained in:
Jeffrey Pfau 2014-09-30 22:50:27 -07:00
parent 3cd0b50bce
commit 5874d416df
4 changed files with 53 additions and 42 deletions

View File

@ -61,4 +61,19 @@
#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

View File

@ -125,25 +125,21 @@ union GBAOAM {
#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 {

View File

@ -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 GBAVideoRender
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* render
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 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render
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 GBAVideoSoftwareRendererPutPixels(struct GBAVideoRenderer* renderer,
}
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 @@ static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer*
#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 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {
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 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {
}
}
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 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re
}
#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 @@ static void _drawBackgroundMode4(struct GBAVideoSoftwareRenderer* renderer, stru
uint16_t color;
uint32_t offset = 0;
if (renderer->dispcnt.frameSelect) {
if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) {
offset = 0xA000;
}
@ -1405,7 +1405,7 @@ static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, stru
uint32_t color;
uint32_t offset = 0;
if (renderer->dispcnt.frameSelect) {
if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) {
offset = 0xA000;
}
@ -1481,7 +1481,7 @@ static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, stru
}
#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 @@ static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, stru
}
#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 @@ static void _postprocessSprite(struct GBAVideoSoftwareRenderer* renderer, unsign
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;

View File

@ -113,7 +113,7 @@ struct GBAVideoSoftwareRenderer {
color_t* outputBuffer;
unsigned outputBufferStride;
union GBARegisterDISPCNT dispcnt;
GBARegisterDISPCNT dispcnt;
uint32_t row[VIDEO_HORIZONTAL_PIXELS];
uint32_t spriteLayer[VIDEO_HORIZONTAL_PIXELS];