Start drawing backgrounds

This commit is contained in:
Jeffrey Pfau 2013-04-22 01:11:48 -07:00
parent 764b6010c0
commit 060ae364b5
3 changed files with 54 additions and 22 deletions

View File

@ -90,10 +90,10 @@ union GBAOAM {
union GBATextMapData { union GBATextMapData {
struct { struct {
unsigned tile : 9; unsigned tile : 10;
unsigned hflip : 1; unsigned hflip : 1;
unsigned vflip : 1; unsigned vflip : 1;
unsigned palette : 5; unsigned palette : 4;
}; };
uint16_t packed; uint16_t packed;
}; };

View File

@ -14,6 +14,8 @@ static void GBAVideoSoftwareRendererFinishFrame(struct GBAVideoRenderer* rendere
static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRenderer* renderer); static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRenderer* renderer);
static void GBAVideoSoftwareRendererWriteBGCNT(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* bg, uint16_t value); static void GBAVideoSoftwareRendererWriteBGCNT(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* bg, uint16_t value);
static void _drawBackgroundMode0(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int y);
static void _sortBackgrounds(struct GBAVideoSoftwareRenderer* renderer); static void _sortBackgrounds(struct GBAVideoSoftwareRenderer* renderer);
static int _backgroundComparator(const void* a, const void* b); static int _backgroundComparator(const void* a, const void* b);
@ -141,30 +143,26 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
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;
int x;
uint16_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; uint16_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y];
if (softwareRenderer->dispcnt.forcedBlank) { if (softwareRenderer->dispcnt.forcedBlank) {
for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; ++x) { for (int x = 0; x < VIDEO_HORIZONTAL_PIXELS; ++x) {
row[x] = 0x7FFF; row[x] = 0x7FFF;
} }
return; return;
} }
for (x = 0; x < 16; ++x) {
row[(x * 15) + 0] = renderer->palette[x + (y / 5) * 16]; for (int i = 0; i < 4; ++i) {
row[(x * 15) + 1] = renderer->palette[x + (y / 5) * 16]; if (softwareRenderer->sortedBg[i]->enabled) {
row[(x * 15) + 2] = renderer->palette[x + (y / 5) * 16]; _drawBackgroundMode0(softwareRenderer, softwareRenderer->sortedBg[i], y);
row[(x * 15) + 3] = renderer->palette[x + (y / 5) * 16]; }
row[(x * 15) + 4] = renderer->palette[x + (y / 5) * 16]; }
row[(x * 15) + 5] = renderer->palette[x + (y / 5) * 16]; for (int x = 0; x < VIDEO_HORIZONTAL_PIXELS; ++x) {
row[(x * 15) + 6] = renderer->palette[x + (y / 5) * 16]; for (int i = 0; i < 4; ++i) {
row[(x * 15) + 7] = renderer->palette[x + (y / 5) * 16]; if (softwareRenderer->sortedBg[i]->enabled) {
row[(x * 15) + 8] = renderer->palette[x + (y / 5) * 16]; row[x] = softwareRenderer->sortedBg[i]->internalBuffer[x];
row[(x * 15) + 9] = renderer->palette[x + (y / 5) * 16]; break;
row[(x * 15) + 10] = renderer->palette[x + (y / 5) * 16]; }
row[(x * 15) + 11] = renderer->palette[x + (y / 5) * 16]; }
row[(x * 15) + 12] = renderer->palette[x + (y / 5) * 16];
row[(x * 15) + 13] = renderer->palette[x + (y / 5) * 16];
row[(x * 15) + 14] = renderer->palette[x + (y / 5) * 16];
} }
} }
@ -186,16 +184,49 @@ static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRendere
static void GBAVideoSoftwareRendererWriteBGCNT(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* bg, uint16_t value) { static void GBAVideoSoftwareRendererWriteBGCNT(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* bg, uint16_t value) {
union GBARegisterBGCNT reg = { .packed = value }; union GBARegisterBGCNT reg = { .packed = value };
bg->priority = reg.priority; bg->priority = reg.priority;
bg->charBase = reg.charBase << 13; bg->charBase = reg.charBase << 14;
bg->mosaic = reg.mosaic; bg->mosaic = reg.mosaic;
bg->multipalette = reg.multipalette; bg->multipalette = reg.multipalette;
bg->screenBase = reg.screenBase << 10; bg->screenBase = reg.screenBase << 11;
bg->overflow = reg.overflow; bg->overflow = reg.overflow;
bg->size = reg.size; bg->size = reg.size;
_sortBackgrounds(renderer); _sortBackgrounds(renderer);
} }
static void _drawBackgroundMode0(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int y) {
int start = 0;
int end = VIDEO_HORIZONTAL_PIXELS;
int inX = start + background->x;
int inY = y + background->y;
union GBATextMapData mapData;
unsigned yBase = inY & 0xF8;
if (background->size & 2) {
yBase += inY & 0x100;
} else if (background->size == 3) {
yBase += (inY & 0x100) << 1;
}
unsigned xBase;
uint32_t screenBase;
uint32_t charBase;
for (int outX = start; outX < end; ++outX) {
xBase = (outX + inX) & 0xF8;
if (background->size & 1) {
xBase += ((outX + inX) & 0x100) << 3;
}
screenBase = (background->screenBase >> 1) + (xBase >> 3) + (yBase << 2);
mapData.packed = renderer->d.vram[screenBase];
charBase = ((background->charBase + mapData.tile << 5) >> 1) + ((inY & 0x7) << 1) + (((outX + inX) >> 2) & 1);
uint16_t tileData = renderer->d.vram[charBase];
tileData >>= ((outX + inX) & 0x3) << 2;
background->internalBuffer[outX] = renderer->d.palette[(tileData & 0xF) | (mapData.palette << 4)];
}
}
static void _sortBackgrounds(struct GBAVideoSoftwareRenderer* renderer) { static void _sortBackgrounds(struct GBAVideoSoftwareRenderer* renderer) {
qsort(renderer->sortedBg, 4, sizeof(struct GBAVideoSoftwareBackground*), _backgroundComparator); qsort(renderer->sortedBg, 4, sizeof(struct GBAVideoSoftwareBackground*), _backgroundComparator);
} }

View File

@ -25,6 +25,7 @@ struct GBAVideoSoftwareBackground {
uint16_t dmy; uint16_t dmy;
uint32_t sx; uint32_t sx;
uint32_t sy; uint32_t sy;
uint16_t internalBuffer[VIDEO_HORIZONTAL_PIXELS];
}; };
struct GBAVideoSoftwareRenderer { struct GBAVideoSoftwareRenderer {