From 8322117aab2460df3a68caa04a11b7286f21bd2b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 17 Jul 2017 10:03:05 -0700 Subject: [PATCH] DS Video: Fix affine parameter advancing (fixes #802) --- CHANGES | 1 + src/ds/renderers/software.c | 43 ++++++++++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index cd50be6d3..2d8136431 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,7 @@ Bugfixes: - DS GX: Fixed viewport calculations (fixes mgba.io/i/709) - DS Video: Fix display capture blending value 16 (fixes mgba.io/i/757) - DS GX: Properly center cross product in polygon normal calculations + - DS Video: Fix affine parameter advancing (fixes mgba.io/i/802) Misc: - DS GX: Clean up and unify texture mapping - DS Core: Add symbol loading diff --git a/src/ds/renderers/software.c b/src/ds/renderers/software.c index ccf5dabb3..d0250480d 100644 --- a/src/ds/renderers/software.c +++ b/src/ds/renderers/software.c @@ -392,11 +392,6 @@ static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* rend memset(softwareRenderer->alphaA, softwareRenderer->blda, sizeof(softwareRenderer->alphaA)); memset(softwareRenderer->alphaB, softwareRenderer->bldb, sizeof(softwareRenderer->alphaB)); - softwareRenderer->bg[2].sx = softwareRenderer->bg[2].refx + softwareRenderer->bg[2].dmx * y; - softwareRenderer->bg[2].sy = softwareRenderer->bg[2].refy + softwareRenderer->bg[2].dmy * y; - softwareRenderer->bg[3].sx = softwareRenderer->bg[3].refx + softwareRenderer->bg[3].dmx * y; - softwareRenderer->bg[3].sy = softwareRenderer->bg[3].refy + softwareRenderer->bg[3].dmy * y; - int w; unsigned priority; for (priority = 0; priority < 4; ++priority) { @@ -499,6 +494,38 @@ static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* rend GBAVideoSoftwareRendererPostprocessBuffer(softwareRenderer); } +static void _advanceAffine(struct GBAVideoSoftwareRenderer* softwareRenderer) { + switch (GBARegisterDISPCNTGetMode(softwareRenderer->dispcnt)) { + case 2: + case 4: + case 5: + softwareRenderer->bg[2].sx += softwareRenderer->bg[2].dmx; + softwareRenderer->bg[2].sy += softwareRenderer->bg[2].dmy; + // Fall through + case 1: + case 3: + softwareRenderer->bg[3].sx += softwareRenderer->bg[3].dmx; + softwareRenderer->bg[3].sy += softwareRenderer->bg[3].dmy; + break; + } +} + +static void _deadvanceAffine(struct GBAVideoSoftwareRenderer* softwareRenderer) { + switch (GBARegisterDISPCNTGetMode(softwareRenderer->dispcnt)) { + case 2: + case 4: + case 5: + softwareRenderer->bg[2].sx -= softwareRenderer->bg[2].dmx; + softwareRenderer->bg[2].sy -= softwareRenderer->bg[2].dmy; + // Fall through + case 1: + case 3: + softwareRenderer->bg[3].sx -= softwareRenderer->bg[3].dmx; + softwareRenderer->bg[3].sy -= softwareRenderer->bg[3].dmy; + break; + } +} + static void _drawScanlineA(struct DSVideoSoftwareRenderer* softwareRenderer, int y) { memcpy(softwareRenderer->engA.d.vramBG, softwareRenderer->d.vramABG, sizeof(softwareRenderer->engA.d.vramBG)); memcpy(softwareRenderer->engA.d.vramOBJ, softwareRenderer->d.vramAOBJ, sizeof(softwareRenderer->engA.d.vramOBJ)); @@ -541,6 +568,8 @@ static void _drawScanlineA(struct DSVideoSoftwareRenderer* softwareRenderer, int break; } + _advanceAffine(&softwareRenderer->engA); + #ifdef COLOR_16_BIT #if defined(__ARM_NEON) && !defined(__APPLE__) _to16Bit(row, softwareRenderer->engA.row, DS_VIDEO_HORIZONTAL_PIXELS); @@ -586,6 +615,8 @@ static void _drawScanlineB(struct DSVideoSoftwareRenderer* softwareRenderer, int break; } + _advanceAffine(&softwareRenderer->engB); + #ifdef COLOR_16_BIT #if defined(__ARM_NEON) && !defined(__APPLE__) _to16Bit(row, softwareRenderer->engB.row, DS_VIDEO_HORIZONTAL_PIXELS); @@ -642,7 +673,9 @@ static void DSVideoSoftwareRendererDrawScanline(struct DSVideoRenderer* renderer static void DSVideoSoftwareRendererDrawScanlineDirectly(struct DSVideoRenderer* renderer, int y, color_t* scanline) { struct DSVideoSoftwareRenderer* softwareRenderer = (struct DSVideoSoftwareRenderer*) renderer; + _deadvanceAffine(&softwareRenderer->engA); DSVideoSoftwareRendererDrawGBAScanline(&softwareRenderer->engA.d, softwareRenderer->d.gx, y); + _advanceAffine(&softwareRenderer->engA); memcpy(scanline, softwareRenderer->engA.row, softwareRenderer->engA.masterEnd * sizeof(*scanline)); }