3DS: Adjustable screen darkening
Jeffrey Pfau jeffrey@endrift.com
Sun, 21 Aug 2016 04:21:59 -0700
4 files changed,
92 insertions(+),
7 deletions(-)
M
CHANGES
→
CHANGES
@@ -9,6 +9,7 @@ - Libretro: Memory map and achievement support (leiradel)
- GUI: Add UI control remapping - GUI: Add fast-forward - Wii: 240p support + - 3DS: Adjustable screen darkening Bugfixes: - SDL: Fix axes being mapped wrong - GBA Memory: Fix mirror on non-overdumped Classic NES games
M
src/platform/3ds/ctr-gpu.c
→
src/platform/3ds/ctr-gpu.c
@@ -130,6 +130,14 @@ C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0);
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE); 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 = { .m = {@@ -139,6 +147,21 @@ 0.0f, 0.0f, 1.0f / activeTexture->height, 0.0f
} }; 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) {
M
src/platform/3ds/ctr-gpu.h
→
src/platform/3ds/ctr-gpu.h
@@ -17,6 +17,8 @@
void ctrSetViewportSize(s16 w, s16 h, bool tilt); 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 ctrAddRect(u32 color, s16 x, s16 y, s16 u, s16 v, s16 w, s16 h); void ctrFlushBatch(void);
M
src/platform/3ds/main.c
→
src/platform/3ds/main.c
@@ -42,6 +42,14 @@ FM_LINEAR_2x,
FM_MAX } 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 AUDIO_SAMPLES 384@@ -86,7 +94,7 @@ if (!C3D_Init(C3D_DEFAULT_CMDBUF_SIZE)) {
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; }@@ -265,6 +273,9 @@ } else {
C3D_TexSetFilter(&upscaleBuffer.colorBuf, GPU_LINEAR, GPU_LINEAR); } } + if (mCoreConfigGetUIntValue(&runner->config, "darkenMode", &mode) && mode < DM_MAX) { + darkenMode = mode; + } frameLimiter = true; runner->core->setAudioBufferSize(runner->core, AUDIO_SAMPLES);@@ -320,6 +331,9 @@ } else {
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) {@@ -374,8 +388,6 @@ screen_h = upscaleBuffer.colorBuf.height;
break; } - u32 color = faded ? 0x3FFFFFFF : 0xFFFFFFFF; - unsigned corew, coreh; core->desiredVideoDimensions(core, &corew, &coreh);@@ -401,7 +413,6 @@ h = coreh;
x = (screen_w - w) / 2; y = (screen_h - h) / 2; ctrSetViewportSize(screen_w, screen_h, true); - ctrActivateTexture(&outputTexture); break; case SM_AF_TOP: case SM_AF_BOTTOM:@@ -416,10 +427,45 @@ w = corew * 2;
h = coreh * 2; } ctrSetViewportSize(screen_w, screen_h, false); - ctrActivateTexture(&outputTexture); 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); ctrFlushBatch();@@ -460,7 +506,7 @@
x = (screen_w - w) / 2; y = (screen_h - h) / 2; 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(); }@@ -771,9 +817,22 @@ "Bilinear (smooter)",
"Bilinear (pixelated)", }, .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, .teardown = 0, .gameLoaded = _gameLoaded,