Sort backgrounds

This commit is contained in:
Jeffrey Pfau 2013-04-21 20:59:43 -07:00
parent a6fb91bb7d
commit 764b6010c0
2 changed files with 33 additions and 6 deletions

View File

@ -3,6 +3,8 @@
#include "gba.h" #include "gba.h"
#include "gba-io.h" #include "gba-io.h"
#include <stdlib.h>
static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer);
static void GBAVideoSoftwareRendererDeinit(struct GBAVideoRenderer* renderer); static void GBAVideoSoftwareRendererDeinit(struct GBAVideoRenderer* renderer);
static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
@ -10,7 +12,10 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render
static void GBAVideoSoftwareRendererFinishFrame(struct GBAVideoRenderer* renderer); static void GBAVideoSoftwareRendererFinishFrame(struct GBAVideoRenderer* renderer);
static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRenderer* renderer); static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRenderer* renderer);
static void GBAVideoSoftwareRendererWriteBGCNT(struct GBAVideoSoftwareBackground* bg, uint16_t value); static void GBAVideoSoftwareRendererWriteBGCNT(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* bg, uint16_t value);
static void _sortBackgrounds(struct GBAVideoSoftwareRenderer* renderer);
static int _backgroundComparator(const void* a, const void* b);
void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) {
renderer->d.init = GBAVideoSoftwareRendererInit; renderer->d.init = GBAVideoSoftwareRendererInit;
@ -19,6 +24,11 @@ void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) {
renderer->d.drawScanline = GBAVideoSoftwareRendererDrawScanline; renderer->d.drawScanline = GBAVideoSoftwareRendererDrawScanline;
renderer->d.finishFrame = GBAVideoSoftwareRendererFinishFrame; renderer->d.finishFrame = GBAVideoSoftwareRendererFinishFrame;
renderer->sortedBg[0] = &renderer->bg[0];
renderer->sortedBg[1] = &renderer->bg[1];
renderer->sortedBg[2] = &renderer->bg[2];
renderer->sortedBg[3] = &renderer->bg[3];
{ {
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
renderer->mutex = mutex; renderer->mutex = mutex;
@ -77,19 +87,19 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
break; break;
case REG_BG0CNT: case REG_BG0CNT:
value &= 0xFFCF; value &= 0xFFCF;
GBAVideoSoftwareRendererWriteBGCNT(&softwareRenderer->bg[0], value); GBAVideoSoftwareRendererWriteBGCNT(softwareRenderer, &softwareRenderer->bg[0], value);
break; break;
case REG_BG1CNT: case REG_BG1CNT:
value &= 0xFFCF; value &= 0xFFCF;
GBAVideoSoftwareRendererWriteBGCNT(&softwareRenderer->bg[1], value); GBAVideoSoftwareRendererWriteBGCNT(softwareRenderer, &softwareRenderer->bg[1], value);
break; break;
case REG_BG2CNT: case REG_BG2CNT:
value &= 0xFFCF; value &= 0xFFCF;
GBAVideoSoftwareRendererWriteBGCNT(&softwareRenderer->bg[2], value); GBAVideoSoftwareRendererWriteBGCNT(softwareRenderer, &softwareRenderer->bg[2], value);
break; break;
case REG_BG3CNT: case REG_BG3CNT:
value &= 0xFFCF; value &= 0xFFCF;
GBAVideoSoftwareRendererWriteBGCNT(&softwareRenderer->bg[3], value); GBAVideoSoftwareRendererWriteBGCNT(softwareRenderer, &softwareRenderer->bg[3], value);
break; break;
case REG_BG0HOFS: case REG_BG0HOFS:
value &= 0x01FF; value &= 0x01FF;
@ -173,7 +183,7 @@ static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRendere
renderer->bg[3].enabled = renderer->dispcnt.bg3Enable; renderer->bg[3].enabled = renderer->dispcnt.bg3Enable;
} }
static void GBAVideoSoftwareRendererWriteBGCNT(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 << 13;
@ -182,4 +192,20 @@ static void GBAVideoSoftwareRendererWriteBGCNT(struct GBAVideoSoftwareBackground
bg->screenBase = reg.screenBase << 10; bg->screenBase = reg.screenBase << 10;
bg->overflow = reg.overflow; bg->overflow = reg.overflow;
bg->size = reg.size; bg->size = reg.size;
_sortBackgrounds(renderer);
}
static void _sortBackgrounds(struct GBAVideoSoftwareRenderer* renderer) {
qsort(renderer->sortedBg, 4, sizeof(struct GBAVideoSoftwareBackground*), _backgroundComparator);
}
static int _backgroundComparator(const void* a, const void* b) {
const struct GBAVideoSoftwareBackground* bgA = *(const struct GBAVideoSoftwareBackground**) a;
const struct GBAVideoSoftwareBackground* bgB = *(const struct GBAVideoSoftwareBackground**) b;
if (bgA->priority != bgB->priority) {
return bgB->priority - bgA->priority;
} else {
return bgB->index - bgA->index;
}
} }

View File

@ -36,6 +36,7 @@ struct GBAVideoSoftwareRenderer {
union GBARegisterDISPCNT dispcnt; union GBARegisterDISPCNT dispcnt;
struct GBAVideoSoftwareBackground bg[4]; struct GBAVideoSoftwareBackground bg[4];
struct GBAVideoSoftwareBackground* sortedBg[4];
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_cond_t cond; pthread_cond_t cond;