mirror of https://github.com/mgba-emu/mgba.git
GBA Video: Support highlighting layers
This commit is contained in:
parent
570f2c5f38
commit
f41f3a8478
|
@ -16,6 +16,7 @@ struct GBAVideoRendererSprite {
|
|||
struct GBAObj obj;
|
||||
int16_t y;
|
||||
int16_t endY;
|
||||
int8_t index;
|
||||
};
|
||||
|
||||
int GBAVideoRendererCleanOAM(struct GBAObj* oam, struct GBAVideoRendererSprite* sprites, int offsetY);
|
||||
|
|
|
@ -42,6 +42,7 @@ struct GBAVideoSoftwareBackground {
|
|||
uint16_t mapCache[64];
|
||||
int32_t offsetX;
|
||||
int32_t offsetY;
|
||||
bool highlight;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -105,6 +106,8 @@ struct GBAVideoSoftwareRenderer {
|
|||
enum GBAVideoBlendEffect blendEffect;
|
||||
color_t normalPalette[512];
|
||||
color_t variantPalette[512];
|
||||
color_t highlightPalette[512];
|
||||
color_t highlightVariantPalette[512];
|
||||
|
||||
uint16_t blda;
|
||||
uint16_t bldb;
|
||||
|
@ -144,6 +147,8 @@ struct GBAVideoSoftwareRenderer {
|
|||
|
||||
int start;
|
||||
int end;
|
||||
|
||||
uint8_t lastHighlightAmount;
|
||||
};
|
||||
|
||||
void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer);
|
||||
|
|
|
@ -12,6 +12,7 @@ CXX_GUARD_START
|
|||
|
||||
#include <mgba/core/log.h>
|
||||
#include <mgba/core/timing.h>
|
||||
#include <mgba/gba/interface.h>
|
||||
|
||||
mLOG_DECLARE_CATEGORY(GBA_VIDEO);
|
||||
|
||||
|
@ -192,6 +193,11 @@ struct GBAVideoRenderer {
|
|||
|
||||
bool disableBG[4];
|
||||
bool disableOBJ;
|
||||
|
||||
bool highlightBG[4];
|
||||
bool highlightOBJ[128];
|
||||
color_t highlightColor;
|
||||
uint8_t highlightAmount;
|
||||
};
|
||||
|
||||
struct GBAVideo {
|
||||
|
|
|
@ -191,6 +191,12 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD
|
|||
proxyRenderer->backend->disableBG[2] = proxyRenderer->d.disableBG[2];
|
||||
proxyRenderer->backend->disableBG[3] = proxyRenderer->d.disableBG[3];
|
||||
proxyRenderer->backend->disableOBJ = proxyRenderer->d.disableOBJ;
|
||||
proxyRenderer->backend->highlightBG[0] = proxyRenderer->d.highlightBG[0];
|
||||
proxyRenderer->backend->highlightBG[1] = proxyRenderer->d.highlightBG[1];
|
||||
proxyRenderer->backend->highlightBG[2] = proxyRenderer->d.highlightBG[2];
|
||||
proxyRenderer->backend->highlightBG[3] = proxyRenderer->d.highlightBG[3];
|
||||
memcpy(proxyRenderer->backend->highlightOBJ, proxyRenderer->d.highlightOBJ, sizeof(proxyRenderer->backend->highlightOBJ));
|
||||
proxyRenderer->backend->highlightAmount = proxyRenderer->d.highlightAmount;
|
||||
if (item->address < GBA_VIDEO_VERTICAL_PIXELS) {
|
||||
proxyRenderer->backend->drawScanline(proxyRenderer->backend, item->address);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ int GBAVideoRendererCleanOAM(struct GBAObj* oam, struct GBAVideoRendererSprite*
|
|||
sprites[oamMax].y = y;
|
||||
sprites[oamMax].endY = y + height;
|
||||
sprites[oamMax].obj = obj;
|
||||
sprites[oamMax].index = i;
|
||||
++oamMax;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -482,8 +482,14 @@ void GBAVideoSoftwareRendererDrawBackgroundMode0(struct GBAVideoSoftwareRenderer
|
|||
uint32_t charBase;
|
||||
int variant = background->target1 && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN);
|
||||
color_t* mainPalette = renderer->normalPalette;
|
||||
if (renderer->d.highlightAmount && background->highlight) {
|
||||
mainPalette = renderer->highlightPalette;
|
||||
}
|
||||
if (variant) {
|
||||
mainPalette = renderer->variantPalette;
|
||||
if (renderer->d.highlightAmount && background->highlight) {
|
||||
mainPalette = renderer->highlightVariantPalette;
|
||||
}
|
||||
}
|
||||
color_t* palette = mainPalette;
|
||||
PREPARE_OBJWIN;
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
renderer->row[outX] |= FLAG_OBJWIN; \
|
||||
}
|
||||
|
||||
int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int y) {
|
||||
int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int index, int y) {
|
||||
int width = GBAVideoObjSizes[GBAObjAttributesAGetShape(sprite->a) * 4 + GBAObjAttributesBGetSize(sprite->b)][0];
|
||||
int height = GBAVideoObjSizes[GBAObjAttributesAGetShape(sprite->a) * 4 + GBAObjAttributesBGetSize(sprite->b)][1];
|
||||
int start = renderer->start;
|
||||
|
@ -167,10 +167,16 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
|
|||
}
|
||||
|
||||
color_t* palette = &renderer->normalPalette[0x100];
|
||||
if (renderer->d.highlightAmount && renderer->d.highlightOBJ[index]) {
|
||||
palette = &renderer->highlightPalette[0x100];
|
||||
}
|
||||
color_t* objwinPalette = palette;
|
||||
|
||||
if (variant) {
|
||||
palette = &renderer->variantPalette[0x100];
|
||||
if (renderer->d.highlightAmount && renderer->d.highlightOBJ[index]) {
|
||||
palette = &renderer->highlightVariantPalette[0x100];
|
||||
}
|
||||
if (GBAWindowControlIsBlendEnable(renderer->objwin.packed)) {
|
||||
objwinPalette = palette;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode4(struct GBAVideoSoftwareRenderer
|
|||
void GBAVideoSoftwareRendererDrawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer,
|
||||
struct GBAVideoSoftwareBackground* background, int y);
|
||||
|
||||
int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int y);
|
||||
int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int index, int y);
|
||||
void GBAVideoSoftwareRendererPostprocessSprite(struct GBAVideoSoftwareRenderer* renderer, unsigned priority);
|
||||
|
||||
static inline unsigned _brighten(unsigned color, int y);
|
||||
|
@ -141,11 +141,17 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re
|
|||
int objwinForceEnable = 0; \
|
||||
UNUSED(objwinForceEnable); \
|
||||
color_t* objwinPalette = renderer->normalPalette; \
|
||||
if (renderer->d.highlightAmount && background->highlight) { \
|
||||
objwinPalette = renderer->highlightPalette; \
|
||||
} \
|
||||
UNUSED(objwinPalette); \
|
||||
if (objwinSlowPath) { \
|
||||
if (background->target1 && GBAWindowControlIsBlendEnable(renderer->objwin.packed) && \
|
||||
(renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN)) { \
|
||||
objwinPalette = renderer->variantPalette; \
|
||||
if (renderer->d.highlightAmount && background->highlight) { \
|
||||
palette = renderer->highlightVariantPalette; \
|
||||
} \
|
||||
} \
|
||||
switch (background->index) { \
|
||||
case 0: \
|
||||
|
@ -200,8 +206,14 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re
|
|||
int variant = background->target1 && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && \
|
||||
(renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); \
|
||||
color_t* palette = renderer->normalPalette; \
|
||||
if (renderer->d.highlightAmount && background->highlight) { \
|
||||
palette = renderer->highlightPalette; \
|
||||
} \
|
||||
if (variant) { \
|
||||
palette = renderer->variantPalette; \
|
||||
if (renderer->d.highlightAmount && background->highlight) { \
|
||||
palette = renderer->highlightVariantPalette; \
|
||||
} \
|
||||
} \
|
||||
UNUSED(palette); \
|
||||
PREPARE_OBJWIN;
|
||||
|
|
|
@ -62,6 +62,17 @@ void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) {
|
|||
renderer->d.disableBG[3] = false;
|
||||
renderer->d.disableOBJ = false;
|
||||
|
||||
renderer->d.highlightBG[0] = false;
|
||||
renderer->d.highlightBG[1] = false;
|
||||
renderer->d.highlightBG[2] = false;
|
||||
renderer->d.highlightBG[3] = false;
|
||||
int i;
|
||||
for (i = 0; i < 128; ++i) {
|
||||
renderer->d.highlightOBJ[i] = false;
|
||||
}
|
||||
renderer->d.highlightColor = GBA_COLOR_WHITE;
|
||||
renderer->d.highlightAmount = 0;
|
||||
|
||||
renderer->temporaryBuffer = 0;
|
||||
}
|
||||
|
||||
|
@ -568,6 +579,13 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render
|
|||
softwareRenderer->windows[0].control.packed = 0xFF;
|
||||
}
|
||||
|
||||
if (softwareRenderer->lastHighlightAmount != softwareRenderer->d.highlightAmount) {
|
||||
softwareRenderer->lastHighlightAmount = softwareRenderer->d.highlightAmount;
|
||||
if (softwareRenderer->lastHighlightAmount) {
|
||||
softwareRenderer->blendDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (softwareRenderer->blendDirty) {
|
||||
_updatePalettes(softwareRenderer);
|
||||
softwareRenderer->blendDirty = false;
|
||||
|
@ -595,6 +613,11 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render
|
|||
}
|
||||
}
|
||||
|
||||
softwareRenderer->bg[0].highlight = softwareRenderer->d.highlightBG[0];
|
||||
softwareRenderer->bg[1].highlight = softwareRenderer->d.highlightBG[1];
|
||||
softwareRenderer->bg[2].highlight = softwareRenderer->d.highlightBG[2];
|
||||
softwareRenderer->bg[3].highlight = softwareRenderer->d.highlightBG[3];
|
||||
|
||||
_drawScanline(softwareRenderer, y);
|
||||
|
||||
if (softwareRenderer->target2Bd) {
|
||||
|
@ -828,7 +851,7 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {
|
|||
continue;
|
||||
}
|
||||
|
||||
int drawn = GBAVideoSoftwareRendererPreprocessSprite(renderer, &sprite->obj, localY);
|
||||
int drawn = GBAVideoSoftwareRendererPreprocessSprite(renderer, &sprite->obj, sprite->index, localY);
|
||||
spriteLayers |= drawn << GBAObjAttributesCGetPriority(sprite->obj.c);
|
||||
}
|
||||
if (renderer->spriteCyclesRemaining <= 0) {
|
||||
|
@ -925,4 +948,12 @@ static void _updatePalettes(struct GBAVideoSoftwareRenderer* renderer) {
|
|||
renderer->variantPalette[i] = renderer->normalPalette[i];
|
||||
}
|
||||
}
|
||||
unsigned highlightAmount = renderer->d.highlightAmount >> 4;
|
||||
|
||||
if (highlightAmount) {
|
||||
for (i = 0; i < 512; ++i) {
|
||||
renderer->highlightPalette[i] = _mix(0x10 - highlightAmount, renderer->normalPalette[i], highlightAmount, renderer->d.highlightColor);
|
||||
renderer->highlightVariantPalette[i] = _mix(0x10 - highlightAmount, renderer->variantPalette[i], highlightAmount, renderer->d.highlightColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue