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
- Libretro: Settings for using BIOS and skipping intro
- Libretro: Customizable idle loop removal
- Implemented cycle counting for sprite rendering
Bugfixes:
- Util: Fix PowerPC PNG read/write pixel order
- VFS: Fix VFileReadline and remove _vfdReadline

View File

@ -178,6 +178,10 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
if (GBAObjAttributesAIsTransformed(sprite->a)) {
int totalWidth = width << GBAObjAttributesAGetDoubleSize(sprite->a);
int totalHeight = height << GBAObjAttributesAGetDoubleSize(sprite->a);
renderer->spriteCyclesRemaining -= 10 + totalWidth * 2;
if (renderer->spriteCyclesRemaining <= 0) {
return 0;
}
struct GBAOAMMatrix mat;
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);
@ -212,6 +216,10 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
}
}
} else {
renderer->spriteCyclesRemaining -= width;
if (renderer->spriteCyclesRemaining <= 0) {
return 0;
}
int outX = x >= start ? x : start;
int condition = x + width;
int mosaicH = 1;

View File

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

View File

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

View File

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