all repos — mgba @ bfd73a793def72f49243a9566526c6904593336b

mGBA Game Boy Advance Emulator

GBA Video: Implement naive cycle counting for sprite rendering
Jeffrey Pfau jeffrey@endrift.com
Mon, 04 Jan 2016 01:14:44 -0800
commit

bfd73a793def72f49243a9566526c6904593336b

parent

0f7449d9f3fa4d5d5bc6ca5b30851aba702f8293

M CHANGESCHANGES

@@ -14,6 +14,7 @@ - Libretro: Allow blocking opposing directional input

- 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
M src/gba/renderers/software-obj.csrc/gba/renderers/software-obj.c

@@ -178,6 +178,10 @@ uint32_t current;

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 @@ SPRITE_TRANSFORMED_LOOP(256, NORMAL);

} } } else { + renderer->spriteCyclesRemaining -= width; + if (renderer->spriteCyclesRemaining <= 0) { + return 0; + } int outX = x >= start ? x : start; int condition = x + width; int mosaicH = 1;
M src/gba/renderers/video-software.csrc/gba/renderers/video-software.c

@@ -748,6 +748,7 @@ if (GBARegisterDISPCNTIsObjEnable(renderer->dispcnt) && !renderer->d.disableOBJ) {

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 @@ int i;

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;
M src/gba/renderers/video-software.hsrc/gba/renderers/video-software.h

@@ -122,6 +122,7 @@ GBARegisterDISPCNT dispcnt;

uint32_t row[VIDEO_HORIZONTAL_PIXELS]; uint32_t spriteLayer[VIDEO_HORIZONTAL_PIXELS]; + int32_t spriteCyclesRemaining; // BLDCNT unsigned target1Obj;
M src/gba/video.hsrc/gba/video.h

@@ -38,6 +38,9 @@ VIDEO_VERTICAL_TOTAL_PIXELS = VIDEO_VERTICAL_PIXELS + VIDEO_VBLANK_PIXELS,

VIDEO_TOTAL_LENGTH = VIDEO_HORIZONTAL_LENGTH * VIDEO_VERTICAL_TOTAL_PIXELS, + OBJ_HBLANK_FREE_LENGTH = 954, + OBJ_LENGTH = 1210, + BASE_TILE = 0x00010000 };