GBA Video: OBJWIN can change blend params after OBJ is drawn (fixes #921)

This commit is contained in:
Vicki Pfau 2017-10-26 19:52:48 -07:00
parent 24f3b5f11d
commit 65534d5dcd
9 changed files with 24 additions and 15 deletions

View File

@ -22,6 +22,7 @@ Bugfixes:
- GB Video: Fix loading states while in mode 3 - GB Video: Fix loading states while in mode 3
- GB Video: Only trigger STAT write IRQs when screen is on (fixes mgba.io/i/912) - GB Video: Only trigger STAT write IRQs when screen is on (fixes mgba.io/i/912)
- GBA Cheats: Fix PARv3 slide codes (fixes mgba.io/i/919) - GBA Cheats: Fix PARv3 slide codes (fixes mgba.io/i/919)
- GBA Video: OBJWIN can change blend params after OBJ is drawn (fixes mgba.io/i/921)
Misc: Misc:
- GBA Timer: Use global cycles for timers - GBA Timer: Use global cycles for timers
- GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722) - GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722)

View File

@ -156,26 +156,26 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
return 0; return 0;
} }
int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt) && GBAWindowControlGetBlendEnable(renderer->objwin.packed) != GBAWindowControlIsBlendEnable(renderer->currentWindow.packed);
int variant = renderer->target1Obj && int variant = renderer->target1Obj &&
GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) &&
(renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN);
if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) { if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT || objwinSlowPath) {
int target2 = renderer->target2Bd << 4; int target2 = renderer->target2Bd;
target2 |= renderer->bg[0].target2 << (renderer->bg[0].priority); target2 |= renderer->bg[0].target2;
target2 |= renderer->bg[1].target2 << (renderer->bg[1].priority); target2 |= renderer->bg[1].target2;
target2 |= renderer->bg[2].target2 << (renderer->bg[2].priority); target2 |= renderer->bg[2].target2;
target2 |= renderer->bg[3].target2 << (renderer->bg[3].priority); target2 |= renderer->bg[3].target2;
if ((1 << GBAObjAttributesCGetPriority(sprite->c)) <= target2) { if (target2) {
flags |= FLAG_REBLEND; flags |= FLAG_REBLEND;
variant = 0; variant = 0;
} else if (!target2) { } else {
flags &= ~FLAG_TARGET_1; flags &= ~FLAG_TARGET_1;
} }
} }
color_t* palette = &renderer->normalPalette[0x100]; color_t* palette = &renderer->normalPalette[0x100];
color_t* objwinPalette = palette; color_t* objwinPalette = palette;
int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt) && GBAWindowControlGetBlendEnable(renderer->objwin.packed) != GBAWindowControlIsBlendEnable(renderer->currentWindow.packed);
if (variant) { if (variant) {
palette = &renderer->variantPalette[0x100]; palette = &renderer->variantPalette[0x100];

View File

@ -43,7 +43,7 @@ static inline void _compositeBlendObjwin(struct GBAVideoSoftwareRenderer* render
if (current & FLAG_TARGET_1 && color & FLAG_TARGET_2) { if (current & FLAG_TARGET_1 && color & FLAG_TARGET_2) {
color = _mix(renderer->blda, current, renderer->bldb, color); color = _mix(renderer->blda, current, renderer->bldb, color);
} else { } else {
color = (current & 0x00FFFFFF) | (current & FLAG_REBLEND); color = (current & 0x00FFFFFF) | (current & (FLAG_REBLEND | FLAG_OBJWIN));
} }
} else { } else {
color = (color & ~FLAG_TARGET_2) | (current & FLAG_OBJWIN); color = (color & ~FLAG_TARGET_2) | (current & FLAG_OBJWIN);
@ -59,7 +59,7 @@ static inline void _compositeBlendNoObjwin(struct GBAVideoSoftwareRenderer* rend
if (current & FLAG_TARGET_1 && color & FLAG_TARGET_2) { if (current & FLAG_TARGET_1 && color & FLAG_TARGET_2) {
color = _mix(renderer->blda, current, renderer->bldb, color); color = _mix(renderer->blda, current, renderer->bldb, color);
} else { } else {
color = (current & 0x00FFFFFF) | (current & FLAG_REBLEND); color = (current & 0x00FFFFFF) | (current & (FLAG_REBLEND | FLAG_OBJWIN));
} }
} else { } else {
color = color & ~FLAG_TARGET_2; color = color & ~FLAG_TARGET_2;
@ -73,7 +73,7 @@ static inline void _compositeNoBlendObjwin(struct GBAVideoSoftwareRenderer* rend
if (color < current) { if (color < current) {
color |= (current & FLAG_OBJWIN); color |= (current & FLAG_OBJWIN);
} else { } else {
color = (current & 0x00FFFFFF) | (current & FLAG_REBLEND); color = (current & 0x00FFFFFF) | (current & (FLAG_REBLEND | FLAG_OBJWIN));
} }
*pixel = color; *pixel = color;
} }
@ -82,7 +82,7 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re
uint32_t current) { uint32_t current) {
UNUSED(renderer); UNUSED(renderer);
if (color >= current) { if (color >= current) {
color = (current & 0x00FFFFFF) | (current & FLAG_REBLEND); color = (current & 0x00FFFFFF) | (current & (FLAG_REBLEND | FLAG_OBJWIN));
} }
*pixel = color; *pixel = color;
} }

View File

@ -621,6 +621,14 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render
} }
if (softwareRenderer->target1Obj && (softwareRenderer->blendEffect == BLEND_DARKEN || softwareRenderer->blendEffect == BLEND_BRIGHTEN)) { if (softwareRenderer->target1Obj && (softwareRenderer->blendEffect == BLEND_DARKEN || softwareRenderer->blendEffect == BLEND_BRIGHTEN)) {
x = 0; x = 0;
uint32_t mask = 0xFF000000 & ~FLAG_OBJWIN;
uint32_t match = FLAG_REBLEND;
if (GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) {
mask |= FLAG_OBJWIN;
if (GBAWindowControlIsBlendEnable(softwareRenderer->objwin.packed)) {
match |= FLAG_OBJWIN;
}
}
for (w = 0; w < softwareRenderer->nWindows; ++w) { for (w = 0; w < softwareRenderer->nWindows; ++w) {
if (!GBAWindowControlIsBlendEnable(softwareRenderer->windows[w].control.packed)) { if (!GBAWindowControlIsBlendEnable(softwareRenderer->windows[w].control.packed)) {
continue; continue;
@ -629,14 +637,14 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render
if (softwareRenderer->blendEffect == BLEND_DARKEN) { if (softwareRenderer->blendEffect == BLEND_DARKEN) {
for (; x < end; ++x) { for (; x < end; ++x) {
uint32_t color = softwareRenderer->row[x]; uint32_t color = softwareRenderer->row[x];
if ((color & 0xFF000000) == FLAG_REBLEND) { if ((color & mask) == match) {
softwareRenderer->row[x] = _darken(color, softwareRenderer->bldy); softwareRenderer->row[x] = _darken(color, softwareRenderer->bldy);
} }
} }
} else if (softwareRenderer->blendEffect == BLEND_BRIGHTEN) { } else if (softwareRenderer->blendEffect == BLEND_BRIGHTEN) {
for (; x < end; ++x) { for (; x < end; ++x) {
uint32_t color = softwareRenderer->row[x]; uint32_t color = softwareRenderer->row[x];
if ((color & 0xFF000000) == FLAG_REBLEND) { if ((color & mask) == match) {
softwareRenderer->row[x] = _brighten(color, softwareRenderer->bldy); softwareRenderer->row[x] = _brighten(color, softwareRenderer->bldy);
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB