mirror of https://github.com/mgba-emu/mgba.git
Preprocess OBJ heights
This commit is contained in:
parent
04c3b61d1c
commit
a8921116dc
|
@ -5,6 +5,25 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
static const int _objSizes[32] = {
|
||||||
|
8, 8,
|
||||||
|
16, 16,
|
||||||
|
32, 32,
|
||||||
|
64, 64,
|
||||||
|
16, 8,
|
||||||
|
32, 8,
|
||||||
|
32, 16,
|
||||||
|
64, 32,
|
||||||
|
8, 16,
|
||||||
|
8, 32,
|
||||||
|
16, 32,
|
||||||
|
32, 64,
|
||||||
|
0, 0,
|
||||||
|
0, 0,
|
||||||
|
0, 0,
|
||||||
|
0, 0
|
||||||
|
};
|
||||||
|
|
||||||
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 void GBAVideoSoftwareRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam);
|
static void GBAVideoSoftwareRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam);
|
||||||
|
@ -351,6 +370,12 @@ static void _cleanOAM(struct GBAVideoSoftwareRenderer* renderer) {
|
||||||
for (i = 0; i < 128; ++i) {
|
for (i = 0; i < 128; ++i) {
|
||||||
struct GBAObj* obj = &renderer->d.oam->obj[i];
|
struct GBAObj* obj = &renderer->d.oam->obj[i];
|
||||||
if (obj->transformed || !obj->disable) {
|
if (obj->transformed || !obj->disable) {
|
||||||
|
int height = _objSizes[obj->shape * 8 + obj->size * 2 + 1];
|
||||||
|
if (obj->transformed) {
|
||||||
|
height <<= ((struct GBATransformedObj*) obj)->doublesize;
|
||||||
|
}
|
||||||
|
renderer->sprites[oamMax].y = obj->y;
|
||||||
|
renderer->sprites[oamMax].endY = obj->y + height;
|
||||||
renderer->sprites[oamMax].obj = *obj;
|
renderer->sprites[oamMax].obj = *obj;
|
||||||
++oamMax;
|
++oamMax;
|
||||||
}
|
}
|
||||||
|
@ -570,6 +595,8 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {
|
||||||
if (renderer->oamDirty) {
|
if (renderer->oamDirty) {
|
||||||
_cleanOAM(renderer);
|
_cleanOAM(renderer);
|
||||||
}
|
}
|
||||||
|
int mosaicV = renderer->mosaic.objV + 1;
|
||||||
|
int mosaicY = y - (y % mosaicV);
|
||||||
for (w = 0; w < renderer->nWindows; ++w) {
|
for (w = 0; w < renderer->nWindows; ++w) {
|
||||||
renderer->start = renderer->end;
|
renderer->start = renderer->end;
|
||||||
renderer->end = renderer->windows[w].endX;
|
renderer->end = renderer->windows[w].endX;
|
||||||
|
@ -580,11 +607,18 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {
|
||||||
int i;
|
int i;
|
||||||
int drawn;
|
int drawn;
|
||||||
for (i = 0; i < renderer->oamMax; ++i) {
|
for (i = 0; i < renderer->oamMax; ++i) {
|
||||||
|
int localY = y;
|
||||||
struct GBAVideoSoftwareSprite* sprite = &renderer->sprites[i];
|
struct GBAVideoSoftwareSprite* sprite = &renderer->sprites[i];
|
||||||
|
if (sprite->obj.mosaic) {
|
||||||
|
localY = mosaicY;
|
||||||
|
}
|
||||||
|
if ((localY < sprite->y && (sprite->endY - 256 < 0 || localY >= sprite->endY - 256)) || localY >= sprite->endY) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (sprite->obj.transformed) {
|
if (sprite->obj.transformed) {
|
||||||
drawn = _preprocessTransformedSprite(renderer, &sprite->tobj, y);
|
drawn = _preprocessTransformedSprite(renderer, &sprite->tobj, localY);
|
||||||
} else {
|
} else {
|
||||||
drawn = _preprocessSprite(renderer, &sprite->obj, y);
|
drawn = _preprocessSprite(renderer, &sprite->obj, localY);
|
||||||
}
|
}
|
||||||
spriteLayers |= drawn << sprite->obj.priority;
|
spriteLayers |= drawn << sprite->obj.priority;
|
||||||
}
|
}
|
||||||
|
@ -1231,25 +1265,6 @@ static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, stru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int _objSizes[32] = {
|
|
||||||
8, 8,
|
|
||||||
16, 16,
|
|
||||||
32, 32,
|
|
||||||
64, 64,
|
|
||||||
16, 8,
|
|
||||||
32, 8,
|
|
||||||
32, 16,
|
|
||||||
64, 32,
|
|
||||||
8, 16,
|
|
||||||
8, 32,
|
|
||||||
16, 32,
|
|
||||||
32, 64,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SPRITE_NORMAL_LOOP(DEPTH, TYPE) \
|
#define SPRITE_NORMAL_LOOP(DEPTH, TYPE) \
|
||||||
SPRITE_YBASE_ ## DEPTH(inY); \
|
SPRITE_YBASE_ ## DEPTH(inY); \
|
||||||
for (; outX < condition; ++outX, inX += xOffset) { \
|
for (; outX < condition; ++outX, inX += xOffset) { \
|
||||||
|
@ -1329,15 +1344,8 @@ static const int _objSizes[32] = {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _preprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int y) {
|
static int _preprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int y) {
|
||||||
int height = _objSizes[sprite->shape * 8 + sprite->size * 2 + 1];
|
|
||||||
if (sprite->mosaic) {
|
|
||||||
int mosaicV = renderer->mosaic.objV + 1;
|
|
||||||
y -= y % mosaicV;
|
|
||||||
}
|
|
||||||
if ((y < sprite->y && (sprite->y + height - 256 < 0 || y >= sprite->y + height - 256)) || y >= sprite->y + height) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int width = _objSizes[sprite->shape * 8 + sprite->size * 2];
|
int width = _objSizes[sprite->shape * 8 + sprite->size * 2];
|
||||||
|
int height = _objSizes[sprite->shape * 8 + sprite->size * 2 + 1];
|
||||||
int start = renderer->start;
|
int start = renderer->start;
|
||||||
int end = renderer->end;
|
int end = renderer->end;
|
||||||
uint32_t flags = sprite->priority << OFFSET_PRIORITY;
|
uint32_t flags = sprite->priority << OFFSET_PRIORITY;
|
||||||
|
@ -1402,13 +1410,10 @@ static int _preprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct G
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _preprocessTransformedSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBATransformedObj* sprite, int y) {
|
static int _preprocessTransformedSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBATransformedObj* sprite, int y) {
|
||||||
int height = _objSizes[sprite->shape * 8 + sprite->size * 2 + 1];
|
|
||||||
int totalHeight = height << sprite->doublesize;
|
|
||||||
if ((y < sprite->y && (sprite->y + totalHeight - 256 < 0 || y >= sprite->y + totalHeight - 256)) || y >= sprite->y + totalHeight) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int width = _objSizes[sprite->shape * 8 + sprite->size * 2];
|
int width = _objSizes[sprite->shape * 8 + sprite->size * 2];
|
||||||
|
int height = _objSizes[sprite->shape * 8 + sprite->size * 2 + 1];
|
||||||
int totalWidth = width << sprite->doublesize;
|
int totalWidth = width << sprite->doublesize;
|
||||||
|
int totalHeight = height << sprite->doublesize;
|
||||||
int start = renderer->start;
|
int start = renderer->start;
|
||||||
int end = renderer->end;
|
int end = renderer->end;
|
||||||
uint32_t flags = sprite->priority << OFFSET_PRIORITY;
|
uint32_t flags = sprite->priority << OFFSET_PRIORITY;
|
||||||
|
|
|
@ -16,6 +16,8 @@ struct GBAVideoSoftwareSprite {
|
||||||
struct GBAObj obj;
|
struct GBAObj obj;
|
||||||
struct GBATransformedObj tobj;
|
struct GBATransformedObj tobj;
|
||||||
};
|
};
|
||||||
|
int y;
|
||||||
|
int endY;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GBAVideoSoftwareBackground {
|
struct GBAVideoSoftwareBackground {
|
||||||
|
|
Loading…
Reference in New Issue