mirror of https://github.com/mgba-emu/mgba.git
Wii: Add pixelated resample filter
This commit is contained in:
parent
addc3abd74
commit
8dbef1f0e3
1
CHANGES
1
CHANGES
|
@ -86,6 +86,7 @@ Misc:
|
||||||
- PSP2: Stop underclocking when menuing
|
- PSP2: Stop underclocking when menuing
|
||||||
- GUI: Increase scrolling speed
|
- GUI: Increase scrolling speed
|
||||||
- Qt: Rearchitect game closing codepath
|
- Qt: Rearchitect game closing codepath
|
||||||
|
- Wii: Add pixelated resample filter
|
||||||
|
|
||||||
0.4.1: (2016-07-11)
|
0.4.1: (2016-07-11)
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|
|
@ -42,7 +42,8 @@ static enum ScreenMode {
|
||||||
|
|
||||||
static enum FilterMode {
|
static enum FilterMode {
|
||||||
FM_NEAREST,
|
FM_NEAREST,
|
||||||
FM_LINEAR,
|
FM_LINEAR_1x,
|
||||||
|
FM_LINEAR_2x,
|
||||||
FM_MAX
|
FM_MAX
|
||||||
} filterMode = FM_NEAREST;
|
} filterMode = FM_NEAREST;
|
||||||
|
|
||||||
|
@ -73,7 +74,6 @@ static void _drawEnd(void);
|
||||||
static uint32_t _pollInput(const struct mInputMap*);
|
static uint32_t _pollInput(const struct mInputMap*);
|
||||||
static enum GUICursorState _pollCursor(unsigned* x, unsigned* y);
|
static enum GUICursorState _pollCursor(unsigned* x, unsigned* y);
|
||||||
static void _guiPrepare(void);
|
static void _guiPrepare(void);
|
||||||
static void _guiFinish(void);
|
|
||||||
|
|
||||||
static void _setup(struct mGUIRunner* runner);
|
static void _setup(struct mGUIRunner* runner);
|
||||||
static void _gameLoaded(struct mGUIRunner* runner);
|
static void _gameLoaded(struct mGUIRunner* runner);
|
||||||
|
@ -97,6 +97,8 @@ static float guiScale = GUI_SCALE;
|
||||||
static Mtx model, view, modelview;
|
static Mtx model, view, modelview;
|
||||||
static uint16_t* texmem;
|
static uint16_t* texmem;
|
||||||
static GXTexObj tex;
|
static GXTexObj tex;
|
||||||
|
static uint16_t* rescaleTexmem;
|
||||||
|
static GXTexObj rescaleTex;
|
||||||
static int32_t tiltX;
|
static int32_t tiltX;
|
||||||
static int32_t tiltY;
|
static int32_t tiltY;
|
||||||
static int32_t gyroZ;
|
static int32_t gyroZ;
|
||||||
|
@ -279,6 +281,10 @@ int main(int argc, char* argv[]) {
|
||||||
texmem = memalign(32, 256 * 256 * BYTES_PER_PIXEL);
|
texmem = memalign(32, 256 * 256 * BYTES_PER_PIXEL);
|
||||||
memset(texmem, 0, 256 * 256 * BYTES_PER_PIXEL);
|
memset(texmem, 0, 256 * 256 * BYTES_PER_PIXEL);
|
||||||
GX_InitTexObj(&tex, texmem, 256, 256, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
GX_InitTexObj(&tex, texmem, 256, 256, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||||
|
rescaleTexmem = memalign(32, 512 * 512 * BYTES_PER_PIXEL);
|
||||||
|
memset(rescaleTexmem, 0, 512 * 512 * BYTES_PER_PIXEL);
|
||||||
|
GX_InitTexObj(&rescaleTex, rescaleTexmem, 512, 512, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||||
|
GX_InitTexObjFilterMode(&rescaleTex, GX_LINEAR, GX_LINEAR);
|
||||||
|
|
||||||
VIDEO_SetPostRetraceCallback(_retraceCallback);
|
VIDEO_SetPostRetraceCallback(_retraceCallback);
|
||||||
|
|
||||||
|
@ -300,7 +306,7 @@ int main(int argc, char* argv[]) {
|
||||||
_drawStart, _drawEnd,
|
_drawStart, _drawEnd,
|
||||||
_pollInput, _pollCursor,
|
_pollInput, _pollCursor,
|
||||||
0,
|
0,
|
||||||
_guiPrepare, _guiFinish,
|
_guiPrepare, 0,
|
||||||
|
|
||||||
GUI_PARAMS_TRAIL
|
GUI_PARAMS_TRAIL
|
||||||
},
|
},
|
||||||
|
@ -443,9 +449,10 @@ int main(int argc, char* argv[]) {
|
||||||
.state = 0,
|
.state = 0,
|
||||||
.validStates = (const char*[]) {
|
.validStates = (const char*[]) {
|
||||||
"Pixelated",
|
"Pixelated",
|
||||||
"Resampled",
|
"Bilinear (smoother)",
|
||||||
|
"Bilinear (pixelated)",
|
||||||
},
|
},
|
||||||
.nStates = 2
|
.nStates = 3
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.nConfigExtra = 3,
|
.nConfigExtra = 3,
|
||||||
|
@ -502,6 +509,8 @@ int main(int argc, char* argv[]) {
|
||||||
mGUIDeinit(&runner);
|
mGUIDeinit(&runner);
|
||||||
|
|
||||||
free(fifo);
|
free(fifo);
|
||||||
|
free(texmem);
|
||||||
|
free(rescaleTexmem);
|
||||||
|
|
||||||
free(outputBuffer);
|
free(outputBuffer);
|
||||||
GUIFontDestroy(font);
|
GUIFontDestroy(font);
|
||||||
|
@ -628,14 +637,6 @@ void _guiPrepare(void) {
|
||||||
_reproj2(vmode->fbWidth * guiScale * wAdjust, vmode->efbHeight * guiScale * hAdjust);
|
_reproj2(vmode->fbWidth * guiScale * wAdjust, vmode->efbHeight * guiScale * hAdjust);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _guiFinish(void) {
|
|
||||||
if (screenMode == SM_PA) {
|
|
||||||
_reproj(corew * scaleFactor, coreh * scaleFactor);
|
|
||||||
} else {
|
|
||||||
_reproj2(corew, coreh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _setup(struct mGUIRunner* runner) {
|
void _setup(struct mGUIRunner* runner) {
|
||||||
runner->core->setRotation(runner->core, &rotation);
|
runner->core->setRotation(runner->core, &rotation);
|
||||||
runner->core->setRumble(runner->core, &rumble);
|
runner->core->setRumble(runner->core, &rumble);
|
||||||
|
@ -733,15 +734,15 @@ void _unpaused(struct mGUIRunner* runner) {
|
||||||
filterMode = mode;
|
filterMode = mode;
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case FM_NEAREST:
|
case FM_NEAREST:
|
||||||
|
case FM_LINEAR_2x:
|
||||||
default:
|
default:
|
||||||
GX_InitTexObjFilterMode(&tex, GX_NEAR, GX_NEAR);
|
GX_InitTexObjFilterMode(&tex, GX_NEAR, GX_NEAR);
|
||||||
break;
|
break;
|
||||||
case FM_LINEAR:
|
case FM_LINEAR_1x:
|
||||||
GX_InitTexObjFilterMode(&tex, GX_LINEAR, GX_LINEAR);
|
GX_InitTexObjFilterMode(&tex, GX_LINEAR, GX_LINEAR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_guiFinish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _drawFrame(struct mGUIRunner* runner, bool faded) {
|
void _drawFrame(struct mGUIRunner* runner, bool faded) {
|
||||||
|
@ -788,10 +789,46 @@ void _drawFrame(struct mGUIRunner* runner, bool faded) {
|
||||||
|
|
||||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
|
||||||
s16 vertSize = 256;
|
s16 vertSize = 256;
|
||||||
|
|
||||||
|
if (filterMode == FM_LINEAR_2x) {
|
||||||
|
Mtx44 proj;
|
||||||
|
guOrtho(proj, 0, vmode->efbHeight, 0, vmode->fbWidth, 0, 300);
|
||||||
|
GX_LoadProjectionMtx(proj, GX_ORTHOGRAPHIC);
|
||||||
|
|
||||||
|
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
||||||
|
GX_Position2s16(0, 512);
|
||||||
|
GX_Color1u32(0xFFFFFFFF);
|
||||||
|
GX_TexCoord2s16(0, 1);
|
||||||
|
|
||||||
|
GX_Position2s16(512, 512);
|
||||||
|
GX_Color1u32(0xFFFFFFFF);
|
||||||
|
GX_TexCoord2s16(1, 1);
|
||||||
|
|
||||||
|
GX_Position2s16(512, 0);
|
||||||
|
GX_Color1u32(0xFFFFFFFF);
|
||||||
|
GX_TexCoord2s16(1, 0);
|
||||||
|
|
||||||
|
GX_Position2s16(0, 0);
|
||||||
|
GX_Color1u32(0xFFFFFFFF);
|
||||||
|
GX_TexCoord2s16(0, 0);
|
||||||
|
GX_End();
|
||||||
|
|
||||||
|
GX_SetTexCopySrc(0, 0, 512, 512);
|
||||||
|
GX_SetTexCopyDst(512, 512, GX_TF_RGB565, GX_FALSE);
|
||||||
|
GX_CopyTex(rescaleTexmem, GX_TRUE);
|
||||||
|
GX_LoadTexObj(&rescaleTex, GX_TEXMAP0);
|
||||||
|
}
|
||||||
|
|
||||||
if (screenMode == SM_PA) {
|
if (screenMode == SM_PA) {
|
||||||
vertSize *= scaleFactor;
|
vertSize *= scaleFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (screenMode == SM_PA) {
|
||||||
|
_reproj(corew * scaleFactor, coreh * scaleFactor);
|
||||||
|
} else {
|
||||||
|
_reproj2(corew, coreh);
|
||||||
|
}
|
||||||
|
|
||||||
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
||||||
GX_Position2s16(0, vertSize);
|
GX_Position2s16(0, vertSize);
|
||||||
GX_Color1u32(color);
|
GX_Color1u32(color);
|
||||||
|
@ -854,17 +891,13 @@ void _incrementScreenMode(struct mGUIRunner* runner) {
|
||||||
filterMode = (mode >> 1) % FM_MAX;
|
filterMode = (mode >> 1) % FM_MAX;
|
||||||
mCoreConfigSetUIntValue(&runner->config, "screenMode", screenMode);
|
mCoreConfigSetUIntValue(&runner->config, "screenMode", screenMode);
|
||||||
mCoreConfigSetUIntValue(&runner->config, "filter", filterMode);
|
mCoreConfigSetUIntValue(&runner->config, "filter", filterMode);
|
||||||
if (screenMode == SM_PA) {
|
|
||||||
_reproj(corew * scaleFactor, coreh * scaleFactor);
|
|
||||||
} else {
|
|
||||||
_reproj2(corew, coreh);
|
|
||||||
}
|
|
||||||
switch (filterMode) {
|
switch (filterMode) {
|
||||||
case FM_NEAREST:
|
case FM_NEAREST:
|
||||||
|
case FM_LINEAR_2x:
|
||||||
default:
|
default:
|
||||||
GX_InitTexObjFilterMode(&tex, GX_NEAR, GX_NEAR);
|
GX_InitTexObjFilterMode(&tex, GX_NEAR, GX_NEAR);
|
||||||
break;
|
break;
|
||||||
case FM_LINEAR:
|
case FM_LINEAR_1x:
|
||||||
GX_InitTexObjFilterMode(&tex, GX_LINEAR, GX_LINEAR);
|
GX_InitTexObjFilterMode(&tex, GX_LINEAR, GX_LINEAR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue