3DS: Adjustable screen darkening

This commit is contained in:
Jeffrey Pfau 2016-08-21 04:21:59 -07:00
parent 2e9b88f5be
commit ef4e67889c
4 changed files with 92 additions and 7 deletions

View File

@ -9,6 +9,7 @@ Features:
- GUI: Add UI control remapping - GUI: Add UI control remapping
- GUI: Add fast-forward - GUI: Add fast-forward
- Wii: 240p support - Wii: 240p support
- 3DS: Adjustable screen darkening
Bugfixes: Bugfixes:
- SDL: Fix axes being mapped wrong - SDL: Fix axes being mapped wrong
- GBA Memory: Fix mirror on non-overdumped Classic NES games - GBA Memory: Fix mirror on non-overdumped Classic NES games

View File

@ -130,6 +130,14 @@ void ctrActivateTexture(C3D_Tex* texture) {
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE); C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE); C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE);
} }
env = C3D_GetTexEnv(1);
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
C3D_TexEnvSrc(env, C3D_Both, GPU_PREVIOUS, 0, 0);
C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE);
env = C3D_GetTexEnv(2);
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
C3D_TexEnvSrc(env, C3D_Both, GPU_PREVIOUS, 0, 0);
C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE);
C3D_Mtx textureMtx = { C3D_Mtx textureMtx = {
.m = { .m = {
@ -141,6 +149,21 @@ void ctrActivateTexture(C3D_Tex* texture) {
C3D_FVUnifMtx2x4(GPU_GEOMETRY_SHADER, GSH_FVEC_textureMtx, &textureMtx); C3D_FVUnifMtx2x4(GPU_GEOMETRY_SHADER, GSH_FVEC_textureMtx, &textureMtx);
} }
void ctrTextureMultiply(void) {
C3D_TexEnv* env = C3D_GetTexEnv(1);
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
C3D_TexEnvSrc(env, C3D_Both, GPU_PREVIOUS, GPU_TEXTURE0, 0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
}
void ctrTextureBias(u32 color) {
C3D_TexEnv* env = C3D_GetTexEnv(2);
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
C3D_TexEnvSrc(env, C3D_Both, GPU_PREVIOUS, GPU_CONSTANT, 0);
C3D_TexEnvFunc(env, C3D_Both, GPU_ADD);
C3D_TexEnvColor(env, color);
}
void ctrAddRectEx(u32 color, s16 x, s16 y, s16 w, s16 h, s16 u, s16 v, s16 uw, s16 vh, float rotate) { void ctrAddRectEx(u32 color, s16 x, s16 y, s16 w, s16 h, s16 u, s16 v, s16 uw, s16 vh, float rotate) {
if (x >= 400 && w >= 0) { if (x >= 400 && w >= 0) {
return; return;

View File

@ -17,6 +17,8 @@ void ctrDeinitGpu(void);
void ctrSetViewportSize(s16 w, s16 h, bool tilt); void ctrSetViewportSize(s16 w, s16 h, bool tilt);
void ctrActivateTexture(C3D_Tex* texture); void ctrActivateTexture(C3D_Tex* texture);
void ctrTextureMultiply(void);
void ctrTextureBias(u32 color);
void ctrAddRectEx(u32 color, s16 x, s16 y, s16 w, s16 h, s16 u, s16 v, s16 uw, s16 vh, float rotate); void ctrAddRectEx(u32 color, s16 x, s16 y, s16 w, s16 h, s16 u, s16 v, s16 uw, s16 vh, float rotate);
void ctrAddRect(u32 color, s16 x, s16 y, s16 u, s16 v, s16 w, s16 h); void ctrAddRect(u32 color, s16 x, s16 y, s16 u, s16 v, s16 w, s16 h);
void ctrFlushBatch(void); void ctrFlushBatch(void);

View File

@ -42,6 +42,14 @@ static enum FilterMode {
FM_MAX FM_MAX
} filterMode = FM_LINEAR_2x; } filterMode = FM_LINEAR_2x;
static enum DarkenMode {
DM_NATIVE,
DM_MULT,
DM_MULT_SCALE,
DM_MULT_SCALE_BIAS,
DM_MAX
} darkenMode = DM_NATIVE;
#define _3DS_INPUT 0x3344534B #define _3DS_INPUT 0x3344534B
#define AUDIO_SAMPLES 384 #define AUDIO_SAMPLES 384
@ -86,7 +94,7 @@ static bool _initGpu(void) {
return false; return false;
} }
if (!C3D_RenderBufInit(&topScreen, 240, 400, GPU_RB_RGB8, 0) || !C3D_RenderBufInit(&bottomScreen, 240, 320, GPU_RB_RGB8, 0) || !C3D_RenderBufInit(&upscaleBuffer, 512, 512, GPU_RB_RGB565, 0)) { if (!C3D_RenderBufInit(&topScreen, 240, 400, GPU_RB_RGB8, 0) || !C3D_RenderBufInit(&bottomScreen, 240, 320, GPU_RB_RGB8, 0) || !C3D_RenderBufInit(&upscaleBuffer, 512, 512, GPU_RB_RGB8, 0)) {
return false; return false;
} }
@ -265,6 +273,9 @@ static void _setup(struct mGUIRunner* runner) {
C3D_TexSetFilter(&upscaleBuffer.colorBuf, GPU_LINEAR, GPU_LINEAR); C3D_TexSetFilter(&upscaleBuffer.colorBuf, GPU_LINEAR, GPU_LINEAR);
} }
} }
if (mCoreConfigGetUIntValue(&runner->config, "darkenMode", &mode) && mode < DM_MAX) {
darkenMode = mode;
}
frameLimiter = true; frameLimiter = true;
runner->core->setAudioBufferSize(runner->core, AUDIO_SAMPLES); runner->core->setAudioBufferSize(runner->core, AUDIO_SAMPLES);
@ -320,6 +331,9 @@ static void _gameLoaded(struct mGUIRunner* runner) {
C3D_TexSetFilter(&upscaleBuffer.colorBuf, GPU_LINEAR, GPU_LINEAR); C3D_TexSetFilter(&upscaleBuffer.colorBuf, GPU_LINEAR, GPU_LINEAR);
} }
} }
if (mCoreConfigGetUIntValue(&runner->config, "darkenMode", &mode) && mode < DM_MAX) {
darkenMode = mode;
}
} }
static void _gameUnloaded(struct mGUIRunner* runner) { static void _gameUnloaded(struct mGUIRunner* runner) {
@ -374,8 +388,6 @@ static void _drawTex(struct mCore* core, bool faded) {
break; break;
} }
u32 color = faded ? 0x3FFFFFFF : 0xFFFFFFFF;
unsigned corew, coreh; unsigned corew, coreh;
core->desiredVideoDimensions(core, &corew, &coreh); core->desiredVideoDimensions(core, &corew, &coreh);
@ -401,7 +413,6 @@ static void _drawTex(struct mCore* core, bool faded) {
x = (screen_w - w) / 2; x = (screen_w - w) / 2;
y = (screen_h - h) / 2; y = (screen_h - h) / 2;
ctrSetViewportSize(screen_w, screen_h, true); ctrSetViewportSize(screen_w, screen_h, true);
ctrActivateTexture(&outputTexture);
break; break;
case SM_AF_TOP: case SM_AF_TOP:
case SM_AF_BOTTOM: case SM_AF_BOTTOM:
@ -416,10 +427,45 @@ static void _drawTex(struct mCore* core, bool faded) {
h = coreh * 2; h = coreh * 2;
} }
ctrSetViewportSize(screen_w, screen_h, false); ctrSetViewportSize(screen_w, screen_h, false);
ctrActivateTexture(&outputTexture);
break; break;
} }
ctrActivateTexture(&outputTexture);
u32 color;
if (!faded) {
color = 0xFFFFFFFF;
switch (darkenMode) {
case DM_NATIVE:
case DM_MAX:
break;
case DM_MULT_SCALE_BIAS:
ctrTextureBias(0x070707);
// Fall through
case DM_MULT_SCALE:
color = 0xFF707070;
// Fall through
case DM_MULT:
ctrTextureMultiply();
break;
}
} else {
color = 0xFF484848;
switch (darkenMode) {
case DM_NATIVE:
case DM_MAX:
break;
case DM_MULT_SCALE_BIAS:
ctrTextureBias(0x030303);
// Fall through
case DM_MULT_SCALE:
color = 0xFF303030;
// Fall through
case DM_MULT:
ctrTextureMultiply();
break;
}
}
ctrAddRectEx(color, x, y, w, h, 0, 0, corew, coreh, 0); ctrAddRectEx(color, x, y, w, h, 0, 0, corew, coreh, 0);
ctrFlushBatch(); ctrFlushBatch();
@ -460,7 +506,7 @@ static void _drawTex(struct mCore* core, bool faded) {
x = (screen_w - w) / 2; x = (screen_w - w) / 2;
y = (screen_h - h) / 2; y = (screen_h - h) / 2;
ctrActivateTexture(&upscaleBuffer.colorBuf); ctrActivateTexture(&upscaleBuffer.colorBuf);
ctrAddRectEx(color, x, y, w, h, 0, 0, corew, coreh, 0); ctrAddRectEx(0xFFFFFFFF, x, y, w, h, 0, 0, corew, coreh, 0);
ctrFlushBatch(); ctrFlushBatch();
} }
@ -771,9 +817,22 @@ int main() {
"Bilinear (pixelated)", "Bilinear (pixelated)",
}, },
.nStates = 3 .nStates = 3
},
{
.title = "Screen darkening",
.data = "darkenMode",
.submenu = 0,
.state = DM_NATIVE,
.validStates = (const char*[]) {
"None",
"Dark",
"Very dark",
"Grayed",
},
.nStates = 4
} }
}, },
.nConfigExtra = 2, .nConfigExtra = 3,
.setup = _setup, .setup = _setup,
.teardown = 0, .teardown = 0,
.gameLoaded = _gameLoaded, .gameLoaded = _gameLoaded,