DS Video: Draw full width

This commit is contained in:
Vicki Pfau 2017-02-22 00:23:18 -08:00
parent 2d7b1099a9
commit 9ecaaa5d4a
6 changed files with 40 additions and 39 deletions

View File

@ -103,7 +103,7 @@ struct WindowControl {
#define MAX_WINDOW 5 #define MAX_WINDOW 5
struct Window { struct Window {
uint8_t endX; uint16_t endX;
struct WindowControl control; struct WindowControl control;
}; };
@ -117,8 +117,8 @@ struct GBAVideoSoftwareRenderer {
GBARegisterDISPCNT dispcnt; GBARegisterDISPCNT dispcnt;
uint32_t row[VIDEO_HORIZONTAL_PIXELS]; uint32_t row[256];
uint32_t spriteLayer[VIDEO_HORIZONTAL_PIXELS]; uint32_t spriteLayer[256];
int32_t spriteCyclesRemaining; int32_t spriteCyclesRemaining;
// BLDCNT // BLDCNT
@ -159,6 +159,7 @@ struct GBAVideoSoftwareRenderer {
int start; int start;
int end; int end;
int masterEnd;
}; };
void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer); void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer);

View File

@ -41,10 +41,10 @@ static void DSVideoSoftwareRendererInit(struct DSVideoRenderer* renderer) {
struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer; struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer;
softwareRenderer->engA.d.palette = &renderer->palette[0]; softwareRenderer->engA.d.palette = &renderer->palette[0];
softwareRenderer->engA.d.oam = &renderer->oam->oam[0]; softwareRenderer->engA.d.oam = &renderer->oam->oam[0];
// TODO: VRAM softwareRenderer->engA.masterEnd = DS_VIDEO_HORIZONTAL_PIXELS;
softwareRenderer->engB.d.palette = &renderer->palette[512]; softwareRenderer->engB.d.palette = &renderer->palette[512];
softwareRenderer->engB.d.oam = &renderer->oam->oam[1]; softwareRenderer->engB.d.oam = &renderer->oam->oam[1];
// TODO: VRAM softwareRenderer->engB.masterEnd = DS_VIDEO_HORIZONTAL_PIXELS;
DSVideoSoftwareRendererReset(renderer); DSVideoSoftwareRendererReset(renderer);
} }
@ -96,7 +96,6 @@ static uint16_t DSVideoSoftwareRendererWriteVideoRegister(struct DSVideoRenderer
case DS9_REG_A_DISPCNT_LO: case DS9_REG_A_DISPCNT_LO:
softwareRenderer->dispcntA &= 0xFFFF0000; softwareRenderer->dispcntA &= 0xFFFF0000;
softwareRenderer->dispcntA |= value; softwareRenderer->dispcntA |= value;
softwareRenderer->engA.d.writeVideoRegister(&softwareRenderer->engA.d, address, value & 0xFF87);
GBAVideoSoftwareRendererUpdateDISPCNTA(softwareRenderer); GBAVideoSoftwareRendererUpdateDISPCNTA(softwareRenderer);
break; break;
case DS9_REG_A_DISPCNT_HI: case DS9_REG_A_DISPCNT_HI:

View File

@ -99,10 +99,10 @@ void GBAVideoSoftwareRendererDrawBackgroundMode3(struct GBAVideoSoftwareRenderer
int outX; int outX;
uint32_t* pixel; uint32_t* pixel;
for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) { for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
BACKGROUND_BITMAP_ITERATE(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); BACKGROUND_BITMAP_ITERATE(renderer->masterEnd, VIDEO_VERTICAL_PIXELS);
if (!mosaicWait) { if (!mosaicWait) {
LOAD_16(color, ((localX >> 8) + (localY >> 8) * VIDEO_HORIZONTAL_PIXELS) << 1, renderer->d.vramBG[0]); LOAD_16(color, ((localX >> 8) + (localY >> 8) * renderer->masterEnd) << 1, renderer->d.vramBG[0]);
#ifndef COLOR_16_BIT #ifndef COLOR_16_BIT
unsigned color32; unsigned color32;
color32 = 0; color32 = 0;
@ -152,10 +152,10 @@ void GBAVideoSoftwareRendererDrawBackgroundMode4(struct GBAVideoSoftwareRenderer
int outX; int outX;
uint32_t* pixel; uint32_t* pixel;
for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) { for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
BACKGROUND_BITMAP_ITERATE(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); BACKGROUND_BITMAP_ITERATE(renderer->masterEnd, VIDEO_VERTICAL_PIXELS);
if (!mosaicWait) { if (!mosaicWait) {
color = ((uint8_t*)renderer->d.vramBG[0])[offset + (localX >> 8) + (localY >> 8) * VIDEO_HORIZONTAL_PIXELS]; color = ((uint8_t*)renderer->d.vramBG[0])[offset + (localX >> 8) + (localY >> 8) * renderer->masterEnd];
mosaicWait = mosaicH; mosaicWait = mosaicH;
} else { } else {

View File

@ -366,7 +366,7 @@
if (background->mosaic && GBAMosaicControlGetBgH(renderer->mosaic)) { \ if (background->mosaic && GBAMosaicControlGetBgH(renderer->mosaic)) { \
int mosaicH = GBAMosaicControlGetBgH(renderer->mosaic) + 1; \ int mosaicH = GBAMosaicControlGetBgH(renderer->mosaic) + 1; \
int x; \ int x; \
int mosaicWait = (mosaicH - outX + VIDEO_HORIZONTAL_PIXELS * mosaicH) % mosaicH; \ int mosaicWait = (mosaicH - outX + renderer->masterEnd * mosaicH) % mosaicH; \
int carryData = 0; \ int carryData = 0; \
paletteData = 0; /* Quiets compiler warning */ \ paletteData = 0; /* Quiets compiler warning */ \
DRAW_BACKGROUND_MODE_0_MOSAIC_ ## BPP (BLEND, OBJWIN) \ DRAW_BACKGROUND_MODE_0_MOSAIC_ ## BPP (BLEND, OBJWIN) \
@ -401,7 +401,7 @@
/*! TODO: Make sure these lines can be removed */ \ /*! TODO: Make sure these lines can be removed */ \
/*!*/ pixel = &renderer->row[outX]; \ /*!*/ pixel = &renderer->row[outX]; \
outX += (tileEnd - tileX) * 8; \ outX += (tileEnd - tileX) * 8; \
/*!*/ if (VIDEO_CHECKS && UNLIKELY(outX > VIDEO_HORIZONTAL_PIXELS)) { \ /*!*/ if (VIDEO_CHECKS && UNLIKELY(outX > renderer->masterEnd)) { \
/*!*/ mLOG(GBA_VIDEO, FATAL, "Out of bounds background draw would occur!"); \ /*!*/ mLOG(GBA_VIDEO, FATAL, "Out of bounds background draw would occur!"); \
/*!*/ return; \ /*!*/ return; \
/*!*/ } \ /*!*/ } \
@ -419,7 +419,7 @@
if (VIDEO_CHECKS && UNLIKELY(&renderer->row[outX] != pixel)) { \ if (VIDEO_CHECKS && UNLIKELY(&renderer->row[outX] != pixel)) { \
mLOG(GBA_VIDEO, FATAL, "Background draw ended in the wrong place! Diff: %" PRIXPTR, &renderer->row[outX] - pixel); \ mLOG(GBA_VIDEO, FATAL, "Background draw ended in the wrong place! Diff: %" PRIXPTR, &renderer->row[outX] - pixel); \
} \ } \
if (VIDEO_CHECKS && UNLIKELY(outX > VIDEO_HORIZONTAL_PIXELS)) { \ if (VIDEO_CHECKS && UNLIKELY(outX > renderer->masterEnd)) { \
mLOG(GBA_VIDEO, FATAL, "Out of bounds background draw occurred!"); \ mLOG(GBA_VIDEO, FATAL, "Out of bounds background draw occurred!"); \
return; \ return; \
} }

View File

@ -279,8 +279,8 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
SPRITE_TRANSFORMED_LOOP(256, NORMAL); SPRITE_TRANSFORMED_LOOP(256, NORMAL);
} }
} }
if (x + totalWidth > VIDEO_HORIZONTAL_PIXELS) { if (x + totalWidth > renderer->masterEnd) {
renderer->spriteCyclesRemaining -= (x + totalWidth - VIDEO_HORIZONTAL_PIXELS) * 2; renderer->spriteCyclesRemaining -= (x + totalWidth - renderer->masterEnd) * 2;
} }
} else { } else {
int outX = x >= start ? x : start; int outX = x >= start ? x : start;
@ -340,8 +340,8 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
SPRITE_NORMAL_LOOP(256, NORMAL); SPRITE_NORMAL_LOOP(256, NORMAL);
} }
} }
if (x + width > VIDEO_HORIZONTAL_PIXELS) { if (x + width > renderer->masterEnd) {
renderer->spriteCyclesRemaining -= x + width - VIDEO_HORIZONTAL_PIXELS; renderer->spriteCyclesRemaining -= x + width - renderer->masterEnd;
} }
} }
return 1; return 1;

View File

@ -63,6 +63,7 @@ void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) {
renderer->d.disableBG[3] = false; renderer->d.disableBG[3] = false;
renderer->d.disableOBJ = false; renderer->d.disableOBJ = false;
renderer->tileStride = 0x20; renderer->tileStride = 0x20;
renderer->masterEnd = VIDEO_HORIZONTAL_PIXELS;
renderer->temporaryBuffer = 0; renderer->temporaryBuffer = 0;
} }
@ -73,10 +74,10 @@ static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer) {
struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer;
int y; int y;
for (y = 0; y < VIDEO_VERTICAL_PIXELS; ++y) { for (y = 0; y < softwareRenderer->masterEnd; ++y) {
color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y];
int x; int x;
for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; ++x) { for (x = 0; x < softwareRenderer->masterEnd; ++x) {
row[x] = GBA_COLOR_WHITE; row[x] = GBA_COLOR_WHITE;
} }
} }
@ -271,26 +272,26 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
case REG_WIN0H: case REG_WIN0H:
softwareRenderer->winN[0].h.end = value; softwareRenderer->winN[0].h.end = value;
softwareRenderer->winN[0].h.start = value >> 8; 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) { if (softwareRenderer->winN[0].h.start > softwareRenderer->masterEnd && softwareRenderer->winN[0].h.start > softwareRenderer->winN[0].h.end) {
softwareRenderer->winN[0].h.start = 0; softwareRenderer->winN[0].h.start = 0;
} }
if (softwareRenderer->winN[0].h.end > VIDEO_HORIZONTAL_PIXELS) { if (softwareRenderer->winN[0].h.end > softwareRenderer->masterEnd) {
softwareRenderer->winN[0].h.end = VIDEO_HORIZONTAL_PIXELS; softwareRenderer->winN[0].h.end = softwareRenderer->masterEnd;
if (softwareRenderer->winN[0].h.start > VIDEO_HORIZONTAL_PIXELS) { if (softwareRenderer->winN[0].h.start > softwareRenderer->masterEnd) {
softwareRenderer->winN[0].h.start = VIDEO_HORIZONTAL_PIXELS; softwareRenderer->winN[0].h.start = softwareRenderer->masterEnd;
} }
} }
break; break;
case REG_WIN1H: case REG_WIN1H:
softwareRenderer->winN[1].h.end = value; softwareRenderer->winN[1].h.end = value;
softwareRenderer->winN[1].h.start = value >> 8; 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) { if (softwareRenderer->winN[1].h.start > softwareRenderer->masterEnd && softwareRenderer->winN[1].h.start > softwareRenderer->winN[1].h.end) {
softwareRenderer->winN[1].h.start = 0; softwareRenderer->winN[1].h.start = 0;
} }
if (softwareRenderer->winN[1].h.end > VIDEO_HORIZONTAL_PIXELS) { if (softwareRenderer->winN[1].h.end > softwareRenderer->masterEnd) {
softwareRenderer->winN[1].h.end = VIDEO_HORIZONTAL_PIXELS; softwareRenderer->winN[1].h.end = softwareRenderer->masterEnd;
if (softwareRenderer->winN[1].h.start > VIDEO_HORIZONTAL_PIXELS) { if (softwareRenderer->winN[1].h.start > softwareRenderer->masterEnd) {
softwareRenderer->winN[1].h.start = VIDEO_HORIZONTAL_PIXELS; softwareRenderer->winN[1].h.start = softwareRenderer->masterEnd;
} }
} }
break; break;
@ -394,10 +395,10 @@ static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, stru
} else if (y >= win->v.end && y < win->v.start) { } else if (y >= win->v.end && y < win->v.start) {
return; return;
} }
if (win->h.end > VIDEO_HORIZONTAL_PIXELS || win->h.end < win->h.start) { if (win->h.end > softwareRenderer->masterEnd || win->h.end < win->h.start) {
struct WindowN splits[2] = { *win, *win }; struct WindowN splits[2] = { *win, *win };
splits[0].h.start = 0; splits[0].h.start = 0;
splits[1].h.end = VIDEO_HORIZONTAL_PIXELS; splits[1].h.end = softwareRenderer->masterEnd;
_breakWindowInner(softwareRenderer, &splits[0]); _breakWindowInner(softwareRenderer, &splits[0]);
_breakWindowInner(softwareRenderer, &splits[1]); _breakWindowInner(softwareRenderer, &splits[1]);
} else { } else {
@ -487,21 +488,21 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render
color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y];
if (GBARegisterDISPCNTIsForcedBlank(softwareRenderer->dispcnt)) { if (GBARegisterDISPCNTIsForcedBlank(softwareRenderer->dispcnt)) {
int x; int x;
for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; ++x) { for (x = 0; x < softwareRenderer->masterEnd; ++x) {
row[x] = GBA_COLOR_WHITE; row[x] = GBA_COLOR_WHITE;
} }
return; return;
} }
int x; int x;
for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; x += 4) { for (x = 0; x < softwareRenderer->masterEnd; x += 4) {
softwareRenderer->spriteLayer[x] = FLAG_UNWRITTEN; softwareRenderer->spriteLayer[x] = FLAG_UNWRITTEN;
softwareRenderer->spriteLayer[x + 1] = FLAG_UNWRITTEN; softwareRenderer->spriteLayer[x + 1] = FLAG_UNWRITTEN;
softwareRenderer->spriteLayer[x + 2] = FLAG_UNWRITTEN; softwareRenderer->spriteLayer[x + 2] = FLAG_UNWRITTEN;
softwareRenderer->spriteLayer[x + 3] = FLAG_UNWRITTEN; softwareRenderer->spriteLayer[x + 3] = FLAG_UNWRITTEN;
} }
softwareRenderer->windows[0].endX = VIDEO_HORIZONTAL_PIXELS; softwareRenderer->windows[0].endX = softwareRenderer->masterEnd;
softwareRenderer->nWindows = 1; softwareRenderer->nWindows = 1;
if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) { if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) {
softwareRenderer->windows[0].control = softwareRenderer->winout; softwareRenderer->windows[0].control = softwareRenderer->winout;
@ -586,14 +587,14 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render
#ifdef COLOR_16_BIT #ifdef COLOR_16_BIT
#if defined(__ARM_NEON) && !defined(__APPLE__) #if defined(__ARM_NEON) && !defined(__APPLE__)
_to16Bit(row, softwareRenderer->row, VIDEO_HORIZONTAL_PIXELS); _to16Bit(row, softwareRenderer->row, softwareRenderer->masterEnd);
#else #else
for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; ++x) { for (x = 0; x < softwareRenderer->masterEnd; ++x) {
row[x] = softwareRenderer->row[x]; row[x] = softwareRenderer->row[x];
} }
#endif #endif
#else #else
memcpy(row, softwareRenderer->row, VIDEO_HORIZONTAL_PIXELS * sizeof(*row)); memcpy(row, softwareRenderer->row, softwareRenderer->masterEnd * sizeof(*row));
#endif #endif
} }
@ -601,7 +602,7 @@ static void GBAVideoSoftwareRendererFinishFrame(struct GBAVideoRenderer* rendere
struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer;
if (softwareRenderer->temporaryBuffer) { if (softwareRenderer->temporaryBuffer) {
mappedMemoryFree(softwareRenderer->temporaryBuffer, VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * 4); mappedMemoryFree(softwareRenderer->temporaryBuffer, softwareRenderer->masterEnd * VIDEO_VERTICAL_PIXELS * 4);
softwareRenderer->temporaryBuffer = 0; softwareRenderer->temporaryBuffer = 0;
} }
softwareRenderer->bg[2].sx = softwareRenderer->bg[2].refx; softwareRenderer->bg[2].sx = softwareRenderer->bg[2].refx;
@ -622,7 +623,7 @@ static void GBAVideoSoftwareRendererPutPixels(struct GBAVideoRenderer* renderer,
const color_t* colorPixels = pixels; const color_t* colorPixels = pixels;
unsigned i; unsigned i;
for (i = 0; i < VIDEO_VERTICAL_PIXELS; ++i) { for (i = 0; i < VIDEO_VERTICAL_PIXELS; ++i) {
memmove(&softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * i], &colorPixels[stride * i], VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); memmove(&softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * i], &colorPixels[stride * i], softwareRenderer->masterEnd * BYTES_PER_PIXEL);
} }
} }