Start implementing modes 1/2

This commit is contained in:
Jeffrey Pfau 2013-05-04 00:51:40 -07:00
parent 7373c37e19
commit fb2ddd6c32
2 changed files with 185 additions and 11 deletions

View File

@ -14,10 +14,19 @@ 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 GBAVideoSoftwareRendererWriteBGPA(struct GBAVideoSoftwareBackground* bg, uint16_t value);
static void GBAVideoSoftwareRendererWriteBGPB(struct GBAVideoSoftwareBackground* bg, uint16_t value);
static void GBAVideoSoftwareRendererWriteBGPC(struct GBAVideoSoftwareBackground* bg, uint16_t value);
static void GBAVideoSoftwareRendererWriteBGPD(struct GBAVideoSoftwareBackground* bg, uint16_t value);
static void GBAVideoSoftwareRendererWriteBGX_LO(struct GBAVideoSoftwareBackground* bg, uint16_t value);
static void GBAVideoSoftwareRendererWriteBGX_HI(struct GBAVideoSoftwareBackground* bg, uint16_t value);
static void GBAVideoSoftwareRendererWriteBGY_LO(struct GBAVideoSoftwareBackground* bg, uint16_t value);
static void GBAVideoSoftwareRendererWriteBGY_HI(struct GBAVideoSoftwareBackground* bg, uint16_t value);
static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer* renderer, uint16_t value); static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer* renderer, uint16_t value);
static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y); static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y);
static void _drawBackgroundMode0(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int y); static void _drawBackgroundMode0(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int y);
static void _drawBackgroundMode2(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int y);
static void _preprocessTransformedSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBATransformedObj* sprite, int y); static void _preprocessTransformedSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBATransformedObj* sprite, int y);
static void _preprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int y); static void _preprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int y);
static void _postprocessSprite(struct GBAVideoSoftwareRenderer* renderer, int priority); static void _postprocessSprite(struct GBAVideoSoftwareRenderer* renderer, int priority);
@ -160,6 +169,54 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
value &= 0x01FF; value &= 0x01FF;
softwareRenderer->bg[3].y = value; softwareRenderer->bg[3].y = value;
break; break;
case REG_BG2PA:
GBAVideoSoftwareRendererWriteBGPA(&softwareRenderer->bg[2], value);
break;
case REG_BG2PB:
GBAVideoSoftwareRendererWriteBGPB(&softwareRenderer->bg[2], value);
break;
case REG_BG2PC:
GBAVideoSoftwareRendererWriteBGPC(&softwareRenderer->bg[2], value);
break;
case REG_BG2PD:
GBAVideoSoftwareRendererWriteBGPD(&softwareRenderer->bg[2], value);
break;
case REG_BG2X_LO:
GBAVideoSoftwareRendererWriteBGX_LO(&softwareRenderer->bg[2], value);
break;
case REG_BG2X_HI:
GBAVideoSoftwareRendererWriteBGX_HI(&softwareRenderer->bg[2], value);
break;
case REG_BG2Y_LO:
GBAVideoSoftwareRendererWriteBGY_LO(&softwareRenderer->bg[2], value);
break;
case REG_BG2Y_HI:
GBAVideoSoftwareRendererWriteBGY_HI(&softwareRenderer->bg[2], value);
break;
case REG_BG3PA:
GBAVideoSoftwareRendererWriteBGPA(&softwareRenderer->bg[3], value);
break;
case REG_BG3PB:
GBAVideoSoftwareRendererWriteBGPB(&softwareRenderer->bg[3], value);
break;
case REG_BG3PC:
GBAVideoSoftwareRendererWriteBGPC(&softwareRenderer->bg[3], value);
break;
case REG_BG3PD:
GBAVideoSoftwareRendererWriteBGPD(&softwareRenderer->bg[3], value);
break;
case REG_BG3X_LO:
GBAVideoSoftwareRendererWriteBGX_LO(&softwareRenderer->bg[3], value);
break;
case REG_BG3X_HI:
GBAVideoSoftwareRendererWriteBGX_HI(&softwareRenderer->bg[3], value);
break;
case REG_BG3Y_LO:
GBAVideoSoftwareRendererWriteBGY_LO(&softwareRenderer->bg[3], value);
break;
case REG_BG3Y_HI:
GBAVideoSoftwareRendererWriteBGY_HI(&softwareRenderer->bg[3], value);
break;
case REG_BLDCNT: case REG_BLDCNT:
GBAVideoSoftwareRendererWriteBLDCNT(softwareRenderer, value); GBAVideoSoftwareRendererWriteBLDCNT(softwareRenderer, value);
break; break;
@ -244,6 +301,11 @@ static void GBAVideoSoftwareRendererFinishFrame(struct GBAVideoRenderer* rendere
} }
} }
pthread_mutex_unlock(&softwareRenderer->mutex); pthread_mutex_unlock(&softwareRenderer->mutex);
softwareRenderer->bg[2].sx = softwareRenderer->bg[2].refx;
softwareRenderer->bg[2].sy = softwareRenderer->bg[2].refy;
softwareRenderer->bg[3].sx = softwareRenderer->bg[3].refx;
softwareRenderer->bg[3].sy = softwareRenderer->bg[3].refy;
} }
static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRenderer* renderer) { static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRenderer* renderer) {
@ -265,6 +327,46 @@ static void GBAVideoSoftwareRendererWriteBGCNT(struct GBAVideoSoftwareRenderer*
bg->size = reg.size; bg->size = reg.size;
} }
static void GBAVideoSoftwareRendererWriteBGPA(struct GBAVideoSoftwareBackground* bg, uint16_t value) {
bg->dx = value;
}
static void GBAVideoSoftwareRendererWriteBGPB(struct GBAVideoSoftwareBackground* bg, uint16_t value) {
bg->dmx = value;
}
static void GBAVideoSoftwareRendererWriteBGPC(struct GBAVideoSoftwareBackground* bg, uint16_t value) {
bg->dy = value;
}
static void GBAVideoSoftwareRendererWriteBGPD(struct GBAVideoSoftwareBackground* bg, uint16_t value) {
bg->dmy = value;
}
static void GBAVideoSoftwareRendererWriteBGX_LO(struct GBAVideoSoftwareBackground* bg, uint16_t value) {
bg->refx = (bg->refx & 0xFFFF0000) | value;
bg->sx = bg->refx;
}
static void GBAVideoSoftwareRendererWriteBGX_HI(struct GBAVideoSoftwareBackground* bg, uint16_t value) {
bg->refx = (bg->refx & 0x0000FFFF) | (value << 16);
bg->refx <<= 4;
bg->refx >>= 4;
bg->sx = bg->refx;
}
static void GBAVideoSoftwareRendererWriteBGY_LO(struct GBAVideoSoftwareBackground* bg, uint16_t value) {
bg->refy = (bg->refy & 0xFFFF0000) | value;
bg->sy = bg->refy;
}
static void GBAVideoSoftwareRendererWriteBGY_HI(struct GBAVideoSoftwareBackground* bg, uint16_t value) {
bg->refy = (bg->refy & 0x0000FFFF) | (value << 16);
bg->refy <<= 4;
bg->refy >>= 4;
bg->sy = bg->refy;
}
static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer* renderer, uint16_t value) { static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer* renderer, uint16_t value) {
union { union {
struct { struct {
@ -324,10 +426,36 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {
int priority; int priority;
for (priority = 0; priority < 4; ++priority) { for (priority = 0; priority < 4; ++priority) {
_postprocessSprite(renderer, priority); _postprocessSprite(renderer, priority);
for (i = 0; i < 4; ++i) { if (renderer->bg[0].enabled && renderer->bg[0].priority == priority && renderer->dispcnt.mode < 2) {
if (renderer->bg[i].enabled && renderer->bg[i].priority == priority) { _drawBackgroundMode0(renderer, &renderer->bg[0], y);
_drawBackgroundMode0(renderer, &renderer->bg[i], y); }
if (renderer->bg[1].enabled && renderer->bg[1].priority == priority && renderer->dispcnt.mode < 2) {
_drawBackgroundMode0(renderer, &renderer->bg[1], y);
}
if (renderer->bg[2].enabled && renderer->bg[2].priority == priority) {
switch (renderer->dispcnt.mode) {
case 0:
_drawBackgroundMode0(renderer, &renderer->bg[2], y);
break;
case 1:
case 2:
_drawBackgroundMode2(renderer, &renderer->bg[2], y);
break;
} }
renderer->bg[2].sx += renderer->bg[2].dmx;
renderer->bg[2].sy += renderer->bg[2].dmy;
}
if (renderer->bg[3].enabled && renderer->bg[3].priority == priority) {
switch (renderer->dispcnt.mode) {
case 0:
_drawBackgroundMode0(renderer, &renderer->bg[3], y);
break;
case 2:
_drawBackgroundMode2(renderer, &renderer->bg[3], y);
break;
}
renderer->bg[3].sx += renderer->bg[3].dmx;
renderer->bg[3].sy += renderer->bg[3].dmy;
} }
} }
} }
@ -670,6 +798,52 @@ static void _drawBackgroundMode0(struct GBAVideoSoftwareRenderer* renderer, stru
} }
} }
static void _drawBackgroundMode2(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int unused) {
(void)(unused);
int sizeAdjusted = 0x8000 << background->size;
int32_t x = background->sx - background->dx;
int32_t y = background->sy - background->dy;
int32_t localX;
int32_t localY;
int flags = (background->priority << OFFSET_PRIORITY) | FLAG_IS_BACKGROUND;
flags |= FLAG_TARGET_1 * (background->target1 && renderer->blendEffect == BLEND_ALPHA);
flags |= FLAG_TARGET_2 * background->target2;
uint32_t screenBase = background->screenBase;
uint32_t charBase = background->charBase;
uint8_t mapData;
uint8_t tileData;
int variant = background->target1 && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN);
int outX;
for (outX = 0; outX < VIDEO_HORIZONTAL_PIXELS; ++outX) {
x += background->dx;
y += background->dy;
if (background->overflow) {
localX = x & (sizeAdjusted - 1);
localY = y & (sizeAdjusted - 1);
} else if (x < 0 || y < 0 || x >= sizeAdjusted || y >= sizeAdjusted) {
continue;
} else {
localX = x;
localY = y;
}
mapData = ((uint8_t*)renderer->d.vram)[screenBase + (localX >> 11) + (((localY >> 7) & 0x7F0) << background->size)];
tileData = ((uint8_t*)renderer->d.vram)[charBase + (mapData << 6) + ((localY & 0x700) >> 5) + ((localX & 0x700) >> 8)];
if (tileData && !(renderer->row[outX] & FLAG_FINALIZED)) {
if (!variant) {
_composite(renderer, outX, renderer->normalPalette[tileData] | flags);
} else {
_composite(renderer, outX, renderer->variantPalette[tileData] | flags);
}
}
}
}
static const int _objSizes[32] = { static const int _objSizes[32] = {
8, 8, 8, 8,
16, 16, 16, 16,

View File

@ -19,14 +19,14 @@ struct GBAVideoSoftwareBackground {
int target2; int target2;
uint16_t x; uint16_t x;
uint16_t y; uint16_t y;
uint32_t refx; int32_t refx;
uint32_t refy; int32_t refy;
uint16_t dx; int16_t dx;
uint16_t dmx; int16_t dmx;
uint16_t dy; int16_t dy;
uint16_t dmy; int16_t dmy;
uint32_t sx; int32_t sx;
uint32_t sy; int32_t sy;
}; };
enum BlendEffect { enum BlendEffect {