GBA Video: Implement naive cycle counting for sprite rendering

This commit is contained in:
Jeffrey Pfau 2016-01-04 01:14:44 -08:00
parent 0f7449d9f3
commit bfd73a793d
5 changed files with 17 additions and 0 deletions

View File

@ -14,6 +14,7 @@ Features:
- OpenEmu core for OS X - OpenEmu core for OS X
- Libretro: Settings for using BIOS and skipping intro - Libretro: Settings for using BIOS and skipping intro
- Libretro: Customizable idle loop removal - Libretro: Customizable idle loop removal
- Implemented cycle counting for sprite rendering
Bugfixes: Bugfixes:
- Util: Fix PowerPC PNG read/write pixel order - Util: Fix PowerPC PNG read/write pixel order
- VFS: Fix VFileReadline and remove _vfdReadline - VFS: Fix VFileReadline and remove _vfdReadline

View File

@ -178,6 +178,10 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
if (GBAObjAttributesAIsTransformed(sprite->a)) { if (GBAObjAttributesAIsTransformed(sprite->a)) {
int totalWidth = width << GBAObjAttributesAGetDoubleSize(sprite->a); int totalWidth = width << GBAObjAttributesAGetDoubleSize(sprite->a);
int totalHeight = height << GBAObjAttributesAGetDoubleSize(sprite->a); int totalHeight = height << GBAObjAttributesAGetDoubleSize(sprite->a);
renderer->spriteCyclesRemaining -= 10 + totalWidth * 2;
if (renderer->spriteCyclesRemaining <= 0) {
return 0;
}
struct GBAOAMMatrix mat; struct GBAOAMMatrix mat;
LOAD_16(mat.a, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].a); LOAD_16(mat.a, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].a);
LOAD_16(mat.b, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].b); LOAD_16(mat.b, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].b);
@ -212,6 +216,10 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
} }
} }
} else { } else {
renderer->spriteCyclesRemaining -= width;
if (renderer->spriteCyclesRemaining <= 0) {
return 0;
}
int outX = x >= start ? x : start; int outX = x >= start ? x : start;
int condition = x + width; int condition = x + width;
int mosaicH = 1; int mosaicH = 1;

View File

@ -748,6 +748,7 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {
if (renderer->oamDirty) { if (renderer->oamDirty) {
_cleanOAM(renderer); _cleanOAM(renderer);
} }
renderer->spriteCyclesRemaining = GBARegisterDISPCNTIsHblankIntervalFree(renderer->dispcnt) ? OBJ_HBLANK_FREE_LENGTH : OBJ_LENGTH;
int mosaicV = GBAMosaicControlGetObjV(renderer->mosaic) + 1; int mosaicV = GBAMosaicControlGetObjV(renderer->mosaic) + 1;
int mosaicY = y - (y % mosaicV); int mosaicY = y - (y % mosaicV);
for (w = 0; w < renderer->nWindows; ++w) { for (w = 0; w < renderer->nWindows; ++w) {
@ -761,6 +762,9 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {
int drawn; int drawn;
for (i = 0; i < renderer->oamMax; ++i) { for (i = 0; i < renderer->oamMax; ++i) {
int localY = y; int localY = y;
if (renderer->spriteCyclesRemaining <= 0) {
break;
}
struct GBAVideoSoftwareSprite* sprite = &renderer->sprites[i]; struct GBAVideoSoftwareSprite* sprite = &renderer->sprites[i];
if (GBAObjAttributesAIsMosaic(sprite->obj.a)) { if (GBAObjAttributesAIsMosaic(sprite->obj.a)) {
localY = mosaicY; localY = mosaicY;

View File

@ -122,6 +122,7 @@ struct GBAVideoSoftwareRenderer {
uint32_t row[VIDEO_HORIZONTAL_PIXELS]; uint32_t row[VIDEO_HORIZONTAL_PIXELS];
uint32_t spriteLayer[VIDEO_HORIZONTAL_PIXELS]; uint32_t spriteLayer[VIDEO_HORIZONTAL_PIXELS];
int32_t spriteCyclesRemaining;
// BLDCNT // BLDCNT
unsigned target1Obj; unsigned target1Obj;

View File

@ -38,6 +38,9 @@ enum {
VIDEO_TOTAL_LENGTH = VIDEO_HORIZONTAL_LENGTH * VIDEO_VERTICAL_TOTAL_PIXELS, VIDEO_TOTAL_LENGTH = VIDEO_HORIZONTAL_LENGTH * VIDEO_VERTICAL_TOTAL_PIXELS,
OBJ_HBLANK_FREE_LENGTH = 954,
OBJ_LENGTH = 1210,
BASE_TILE = 0x00010000 BASE_TILE = 0x00010000
}; };