Refactor BREAK_WINDOW into _breakWindow, fix bug cleaning up extra windows

This commit is contained in:
Jeffrey Pfau 2013-10-10 01:40:49 -07:00
parent 2ef64ede02
commit e789b324dc
2 changed files with 65 additions and 62 deletions

View File

@ -69,8 +69,8 @@ static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer) {
softwareRenderer->bldb = 0; softwareRenderer->bldb = 0;
softwareRenderer->bldy = 0; softwareRenderer->bldy = 0;
softwareRenderer->win0.priority = 0; softwareRenderer->winN[0].control.priority = 0;
softwareRenderer->win1.priority = 1; softwareRenderer->winN[1].control.priority = 1;
softwareRenderer->objwin.priority = 2; softwareRenderer->objwin.priority = 2;
softwareRenderer->winout.priority = 3; softwareRenderer->winout.priority = 3;
@ -228,32 +228,32 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
_updatePalettes(softwareRenderer); _updatePalettes(softwareRenderer);
break; break;
case REG_WIN0H: case REG_WIN0H:
softwareRenderer->win0H.packed = value; softwareRenderer->winN[0].h.packed = value;
if (softwareRenderer->win0H.start > softwareRenderer->win0H.end || softwareRenderer->win0H.end > VIDEO_HORIZONTAL_PIXELS) { if (softwareRenderer->winN[0].h.start > softwareRenderer->winN[0].h.end || softwareRenderer->winN[0].h.end > VIDEO_HORIZONTAL_PIXELS) {
softwareRenderer->win0H.end = VIDEO_HORIZONTAL_PIXELS; softwareRenderer->winN[0].h.end = VIDEO_HORIZONTAL_PIXELS;
} }
break; break;
case REG_WIN1H: case REG_WIN1H:
softwareRenderer->win1H.packed = value; softwareRenderer->winN[1].h.packed = value;
if (softwareRenderer->win1H.start > softwareRenderer->win1H.end || softwareRenderer->win1H.end > VIDEO_HORIZONTAL_PIXELS) { if (softwareRenderer->winN[1].h.start > softwareRenderer->winN[1].h.end || softwareRenderer->winN[1].h.end > VIDEO_HORIZONTAL_PIXELS) {
softwareRenderer->win1H.end = VIDEO_HORIZONTAL_PIXELS; softwareRenderer->winN[1].h.end = VIDEO_HORIZONTAL_PIXELS;
} }
break; break;
case REG_WIN0V: case REG_WIN0V:
softwareRenderer->win0V.packed = value; softwareRenderer->winN[0].v.packed = value;
if (softwareRenderer->win0V.start > softwareRenderer->win0V.end || softwareRenderer->win0V.end > VIDEO_HORIZONTAL_PIXELS) { if (softwareRenderer->winN[0].v.start > softwareRenderer->winN[0].v.end || softwareRenderer->winN[0].v.end > VIDEO_HORIZONTAL_PIXELS) {
softwareRenderer->win0V.end = VIDEO_VERTICAL_PIXELS; softwareRenderer->winN[0].v.end = VIDEO_VERTICAL_PIXELS;
} }
break; break;
case REG_WIN1V: case REG_WIN1V:
softwareRenderer->win1V.packed = value; softwareRenderer->winN[1].v.packed = value;
if (softwareRenderer->win1V.start > softwareRenderer->win1V.end || softwareRenderer->win1V.end > VIDEO_HORIZONTAL_PIXELS) { if (softwareRenderer->winN[1].v.start > softwareRenderer->winN[1].v.end || softwareRenderer->winN[1].v.end > VIDEO_HORIZONTAL_PIXELS) {
softwareRenderer->win1V.end = VIDEO_VERTICAL_PIXELS; softwareRenderer->winN[1].v.end = VIDEO_VERTICAL_PIXELS;
} }
break; break;
case REG_WININ: case REG_WININ:
softwareRenderer->win0.packed = value; softwareRenderer->winN[0].control.packed = value;
softwareRenderer->win1.packed = value >> 8; softwareRenderer->winN[1].control.packed = value >> 8;
break; break;
case REG_WINOUT: case REG_WINOUT:
softwareRenderer->winout.packed = value; softwareRenderer->winout.packed = value;
@ -298,43 +298,47 @@ static void GBAVideoSoftwareRendererWritePalette(struct GBAVideoRenderer* render
} }
} }
#define BREAK_WINDOW(WIN) \ static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win) {
int activeWindow; \ int activeWindow;
int startX = 0; \ int startX = 0;
if (softwareRenderer->WIN ## H.end > 0) { \ if (win->h.end > 0) {
for (activeWindow = 0; activeWindow < softwareRenderer->nWindows; ++activeWindow) { \ for (activeWindow = 0; activeWindow < softwareRenderer->nWindows; ++activeWindow) {
if (softwareRenderer->WIN ## H.start < softwareRenderer->windows[activeWindow].endX) { \ if (win->h.start < softwareRenderer->windows[activeWindow].endX) {
struct Window oldWindow = softwareRenderer->windows[activeWindow]; \ // Insert a window before the end of the active window
if (softwareRenderer->WIN ## H.start > startX) { \ struct Window oldWindow = softwareRenderer->windows[activeWindow];
int nextWindow = softwareRenderer->nWindows; \ if (win->h.start > startX) {
++softwareRenderer->nWindows; \ // And after the start of the active window
for (; nextWindow > activeWindow; --nextWindow) { \ int nextWindow = softwareRenderer->nWindows;
softwareRenderer->windows[nextWindow] = softwareRenderer->windows[nextWindow - 1]; \ ++softwareRenderer->nWindows;
} \ for (; nextWindow > activeWindow; --nextWindow) {
softwareRenderer->windows[activeWindow].endX = softwareRenderer->WIN ## H.start; \ softwareRenderer->windows[nextWindow] = softwareRenderer->windows[nextWindow - 1];
++activeWindow; \ }
} \ softwareRenderer->windows[activeWindow].endX = win->h.start;
softwareRenderer->windows[activeWindow].control = softwareRenderer->WIN; \ ++activeWindow;
softwareRenderer->windows[activeWindow].endX = softwareRenderer->WIN ## H.end; \ }
if (softwareRenderer->WIN ## H.end >= oldWindow.endX) { \ softwareRenderer->windows[activeWindow].control = win->control;
for (++activeWindow; softwareRenderer->WIN ## H.end >= softwareRenderer->windows[activeWindow].endX && softwareRenderer->nWindows > 1; ++activeWindow) { \ softwareRenderer->windows[activeWindow].endX = win->h.end;
softwareRenderer->windows[activeWindow] = softwareRenderer->windows[activeWindow + 1]; \ if (win->h.end >= oldWindow.endX) {
--softwareRenderer->nWindows; \ // Trim off extra windows we've overwritten
} \ for (++activeWindow; win->h.end >= softwareRenderer->windows[activeWindow].endX && softwareRenderer->nWindows > activeWindow; ++activeWindow) {
} else { \ softwareRenderer->windows[activeWindow] = softwareRenderer->windows[activeWindow + 1];
++activeWindow; \ --softwareRenderer->nWindows;
int nextWindow = softwareRenderer->nWindows; \ }
++softwareRenderer->nWindows; \ } else {
for (; nextWindow > activeWindow; --nextWindow) { \ ++activeWindow;
softwareRenderer->windows[nextWindow] = softwareRenderer->windows[nextWindow - 1]; \ int nextWindow = softwareRenderer->nWindows;
} \ ++softwareRenderer->nWindows;
softwareRenderer->windows[activeWindow] = oldWindow; \ for (; nextWindow > activeWindow; --nextWindow) {
} \ softwareRenderer->windows[nextWindow] = softwareRenderer->windows[nextWindow - 1];
break; \ }
} \ softwareRenderer->windows[activeWindow] = oldWindow;
startX = softwareRenderer->windows[activeWindow].endX; \ }
} \ break;
}
startX = softwareRenderer->windows[activeWindow].endX;
}
} }
}
static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) {
struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer;
@ -354,11 +358,11 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render
softwareRenderer->nWindows = 1; softwareRenderer->nWindows = 1;
if (softwareRenderer->dispcnt.win0Enable || softwareRenderer->dispcnt.win1Enable || softwareRenderer->dispcnt.objwinEnable) { if (softwareRenderer->dispcnt.win0Enable || softwareRenderer->dispcnt.win1Enable || softwareRenderer->dispcnt.objwinEnable) {
softwareRenderer->windows[0].control = softwareRenderer->winout; softwareRenderer->windows[0].control = softwareRenderer->winout;
if (softwareRenderer->dispcnt.win1Enable && y < softwareRenderer->win1V.end && y >= softwareRenderer->win1V.start) { if (softwareRenderer->dispcnt.win1Enable && y < softwareRenderer->winN[1].v.end && y >= softwareRenderer->winN[1].v.start) {
BREAK_WINDOW(win1); _breakWindow(softwareRenderer, &softwareRenderer->winN[1]);
} }
if (softwareRenderer->dispcnt.win0Enable && y < softwareRenderer->win0V.end && y >= softwareRenderer->win0V.start) { if (softwareRenderer->dispcnt.win0Enable && y < softwareRenderer->winN[0].v.end && y >= softwareRenderer->winN[0].v.start) {
BREAK_WINDOW(win0); _breakWindow(softwareRenderer, &softwareRenderer->winN[0]);
} }
} else { } else {
softwareRenderer->windows[0].control.packed = 0xFF; softwareRenderer->windows[0].control.packed = 0xFF;

View File

@ -114,13 +114,12 @@ struct GBAVideoSoftwareRenderer {
uint16_t bldb; uint16_t bldb;
uint16_t bldy; uint16_t bldy;
union WindowRegion win0H; struct WindowN {
union WindowRegion win0V; union WindowRegion h;
union WindowRegion win1H; union WindowRegion v;
union WindowRegion win1V; union WindowControl control;
} winN[2];
union WindowControl win0;
union WindowControl win1;
union WindowControl winout; union WindowControl winout;
union WindowControl objwin; union WindowControl objwin;