DS Video: Implement master brightness

This commit is contained in:
Vicki Pfau 2017-02-26 20:16:28 -08:00
parent ae5547ea51
commit 756474ac56
5 changed files with 42 additions and 4 deletions

View File

@ -66,6 +66,10 @@ DECL_BIT(DSRegisterPOWCNT1, Swap, 15);
DECL_BIT(GBARegisterBGCNT, ExtPaletteSlot, 13); DECL_BIT(GBARegisterBGCNT, ExtPaletteSlot, 13);
DECL_BITFIELD(DSRegisterMASTER_BRIGHT, uint16_t);
DECL_BITS(DSRegisterMASTER_BRIGHT, Y, 0, 5);
DECL_BITS(DSRegisterMASTER_BRIGHT, Mode, 14, 2);
struct DSVideoRenderer { struct DSVideoRenderer {
void (*init)(struct DSVideoRenderer* renderer); void (*init)(struct DSVideoRenderer* renderer);
void (*reset)(struct DSVideoRenderer* renderer); void (*reset)(struct DSVideoRenderer* renderer);

View File

@ -167,6 +167,9 @@ struct GBAVideoSoftwareRenderer {
int masterEnd; int masterEnd;
int masterHeight; int masterHeight;
int masterScanlines; int masterScanlines;
int masterBright;
int masterBrightY;
}; };
void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer); void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer);

View File

@ -422,9 +422,9 @@ void DS9IOInit(struct DS* ds) {
} }
void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value) { void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value) {
if (address <= DS9_REG_A_BLDY && (address > DS_REG_VCOUNT || address == DS9_REG_A_DISPCNT_LO || address == DS9_REG_A_DISPCNT_HI)) { if ((address <= DS9_REG_A_BLDY && address > DS_REG_VCOUNT) || address == DS9_REG_A_DISPCNT_LO || address == DS9_REG_A_DISPCNT_HI || address == DS9_REG_A_MASTER_BRIGHT) {
value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value); value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value);
} else if (address >= DS9_REG_B_DISPCNT_LO && address <= DS9_REG_B_BLDY) { } else if ((address >= DS9_REG_B_DISPCNT_LO && address <= DS9_REG_B_BLDY) || address == DS9_REG_B_MASTER_BRIGHT) {
value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value); value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value);
} else if ((address >= DS9_REG_RDLINES_COUNT && address <= DS9_REG_VECMTX_RESULT_12) || address == DS9_REG_DISP3DCNT) { } else if ((address >= DS9_REG_RDLINES_COUNT && address <= DS9_REG_VECMTX_RESULT_12) || address == DS9_REG_DISP3DCNT) {
value = DSGXWriteRegister(&ds->gx, address, value); value = DSGXWriteRegister(&ds->gx, address, value);

View File

@ -270,6 +270,20 @@ static uint16_t DSVideoSoftwareRendererWriteVideoRegister(struct DSVideoRenderer
case DS9_REG_B_BG3CNT: case DS9_REG_B_BG3CNT:
_updateCharBase(softwareRenderer, true); _updateCharBase(softwareRenderer, true);
break; break;
case DS9_REG_A_MASTER_BRIGHT:
softwareRenderer->engA.masterBright = DSRegisterMASTER_BRIGHTGetMode(value);
softwareRenderer->engA.masterBrightY = DSRegisterMASTER_BRIGHTGetY(value);
if (softwareRenderer->engA.masterBrightY > 0x10) {
softwareRenderer->engA.masterBrightY = 0x10;
}
break;
case DS9_REG_B_MASTER_BRIGHT:
softwareRenderer->engB.masterBright = DSRegisterMASTER_BRIGHTGetMode(value);
softwareRenderer->engB.masterBrightY = DSRegisterMASTER_BRIGHTGetY(value);
if (softwareRenderer->engB.masterBrightY > 0x10) {
softwareRenderer->engB.masterBrightY = 0x10;
}
break;
case DS9_REG_A_DISPCNT_LO: case DS9_REG_A_DISPCNT_LO:
softwareRenderer->dispcntA &= 0xFFFF0000; softwareRenderer->dispcntA &= 0xFFFF0000;
softwareRenderer->dispcntA |= value; softwareRenderer->dispcntA |= value;
@ -323,9 +337,9 @@ static void DSVideoSoftwareRendererInvalidateExtPal(struct DSVideoRenderer* rend
static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* renderer, int y) { static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* renderer, int y) {
struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer;
int x;
color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y];
if (GBARegisterDISPCNTIsForcedBlank(softwareRenderer->dispcnt)) { if (GBARegisterDISPCNTIsForcedBlank(softwareRenderer->dispcnt)) {
int x;
for (x = 0; x < softwareRenderer->masterEnd; ++x) { for (x = 0; x < softwareRenderer->masterEnd; ++x) {
row[x] = GBA_COLOR_WHITE; row[x] = GBA_COLOR_WHITE;
} }
@ -406,7 +420,22 @@ static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* rend
} }
#endif #endif
#else #else
switch (softwareRenderer->masterBright) {
case 0:
default:
memcpy(row, softwareRenderer->row, softwareRenderer->masterEnd * sizeof(*row)); memcpy(row, softwareRenderer->row, softwareRenderer->masterEnd * sizeof(*row));
break;
case 1:
for (x = 0; x < softwareRenderer->masterEnd; ++x) {
row[x] = _brighten(softwareRenderer->row[x], softwareRenderer->masterBrightY);
}
break;
case 2:
for (x = 0; x < softwareRenderer->masterEnd; ++x) {
row[x] = _darken(softwareRenderer->row[x], softwareRenderer->masterBrightY);
}
break;
}
#endif #endif
} }

View File

@ -95,6 +95,8 @@ static void GBAVideoSoftwareRendererReset(struct GBAVideoRenderer* renderer) {
softwareRenderer->target2Obj = 0; softwareRenderer->target2Obj = 0;
softwareRenderer->target2Bd = 0; softwareRenderer->target2Bd = 0;
softwareRenderer->blendEffect = BLEND_NONE; softwareRenderer->blendEffect = BLEND_NONE;
softwareRenderer->masterBright = 0;
softwareRenderer->masterBrightY = 0;
for (i = 0; i < 1024; i += 2) { for (i = 0; i < 1024; i += 2) {
uint16_t entry; uint16_t entry;
LOAD_16(entry, i, softwareRenderer->d.palette); LOAD_16(entry, i, softwareRenderer->d.palette);