3DS: Reload screen mode and improve screen cleanup (fixes #127)

This commit is contained in:
Jeffrey Pfau 2015-09-21 22:54:54 -07:00
parent 71aa72c4d3
commit 273a21eb25
1 changed files with 42 additions and 24 deletions

View File

@ -49,13 +49,20 @@ static int16_t* audioRight = 0;
static size_t audioPos = 0; static size_t audioPos = 0;
static struct ctrTexture gbaOutputTexture; static struct ctrTexture gbaOutputTexture;
static int guiDrawn; static int guiDrawn;
static int screenCleanup;
enum { enum {
GUI_ACTIVE = 1, GUI_ACTIVE = 1,
GUI_THIS_FRAME = 2, GUI_THIS_FRAME = 2,
GUI_CLEANUP_1 = 4, };
GUI_CLEANUP_2 = 8,
GUI_CLEANUP = GUI_CLEANUP_1 | GUI_CLEANUP_2 enum {
SCREEN_CLEANUP_TOP_1 = 1,
SCREEN_CLEANUP_TOP_2 = 2,
SCREEN_CLEANUP_TOP = SCREEN_CLEANUP_TOP_1 | SCREEN_CLEANUP_TOP_2,
SCREEN_CLEANUP_BOTTOM_1 = 4,
SCREEN_CLEANUP_BOTTOM_2 = 8,
SCREEN_CLEANUP_BOTTOM = SCREEN_CLEANUP_BOTTOM_1 | SCREEN_CLEANUP_BOTTOM_2,
}; };
extern bool allocateRomBuffer(void); extern bool allocateRomBuffer(void);
@ -81,18 +88,32 @@ static void _drawEnd(void) {
void* outputFramebuffer = gfxGetFramebuffer(screen, GFX_LEFT, &height, &width); void* outputFramebuffer = gfxGetFramebuffer(screen, GFX_LEFT, &height, &width);
ctrGpuEndFrame(screen, outputFramebuffer, width, height); ctrGpuEndFrame(screen, outputFramebuffer, width, height);
if (guiDrawn & (GUI_CLEANUP | GUI_THIS_FRAME | GUI_ACTIVE) && screen == GFX_TOP) { if (screen != GFX_BOTTOM) {
if (!(guiDrawn & (GUI_THIS_FRAME | GUI_ACTIVE))) { if (guiDrawn & (GUI_THIS_FRAME | GUI_ACTIVE)) {
void* outputFramebuffer = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, &height, &width);
ctrGpuEndFrame(GFX_BOTTOM, outputFramebuffer, width, height);
} else if (screenCleanup & SCREEN_CLEANUP_BOTTOM) {
ctrGpuBeginFrame(GFX_BOTTOM); ctrGpuBeginFrame(GFX_BOTTOM);
if (guiDrawn & GUI_CLEANUP_1) { if (screenCleanup & SCREEN_CLEANUP_BOTTOM_1) {
guiDrawn &= ~GUI_CLEANUP_1; screenCleanup &= ~SCREEN_CLEANUP_BOTTOM_1;
} else if (guiDrawn & GUI_CLEANUP_2) { } else if (screenCleanup & SCREEN_CLEANUP_BOTTOM_2) {
guiDrawn &= ~GUI_CLEANUP_2; screenCleanup &= ~SCREEN_CLEANUP_BOTTOM_2;
}
} }
void* outputFramebuffer = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, &height, &width); void* outputFramebuffer = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, &height, &width);
ctrGpuEndFrame(GFX_BOTTOM, outputFramebuffer, width, height); ctrGpuEndFrame(GFX_BOTTOM, outputFramebuffer, width, height);
} }
}
if ((screenCleanup & SCREEN_CLEANUP_TOP) && screen != GFX_TOP) {
ctrGpuBeginFrame(GFX_TOP);
if (screenCleanup & SCREEN_CLEANUP_TOP_1) {
screenCleanup &= ~SCREEN_CLEANUP_TOP_1;
} else if (screenCleanup & SCREEN_CLEANUP_TOP_2) {
screenCleanup &= ~SCREEN_CLEANUP_TOP_2;
}
void* outputFramebuffer = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &height, &width);
ctrGpuEndFrame(GFX_TOP, outputFramebuffer, width, height);
}
ctrGpuEndDrawing(); ctrGpuEndDrawing();
} }
@ -113,7 +134,7 @@ static int _batteryState(void) {
} }
static void _guiPrepare(void) { static void _guiPrepare(void) {
guiDrawn = GUI_ACTIVE | GUI_THIS_FRAME | GUI_CLEANUP; guiDrawn = GUI_ACTIVE | GUI_THIS_FRAME;
int screen = screenMode < SM_PA_TOP ? GFX_BOTTOM : GFX_TOP; int screen = screenMode < SM_PA_TOP ? GFX_BOTTOM : GFX_TOP;
if (screen == GFX_BOTTOM) { if (screen == GFX_BOTTOM) {
return; return;
@ -126,6 +147,7 @@ static void _guiPrepare(void) {
static void _guiFinish(void) { static void _guiFinish(void) {
guiDrawn &= ~GUI_ACTIVE; guiDrawn &= ~GUI_ACTIVE;
screenCleanup |= SCREEN_CLEANUP_BOTTOM;
} }
static void _setup(struct GBAGUIRunner* runner) { static void _setup(struct GBAGUIRunner* runner) {
@ -167,6 +189,11 @@ static void _gameLoaded(struct GBAGUIRunner* runner) {
csndPlaySound(0x8, SOUND_REPEAT | SOUND_FORMAT_16BIT, 32768, 1.0, -1.0, audioLeft, audioLeft, AUDIO_SAMPLE_BUFFER * sizeof(int16_t)); csndPlaySound(0x8, SOUND_REPEAT | SOUND_FORMAT_16BIT, 32768, 1.0, -1.0, audioLeft, audioLeft, AUDIO_SAMPLE_BUFFER * sizeof(int16_t));
csndPlaySound(0x9, SOUND_REPEAT | SOUND_FORMAT_16BIT, 32768, 1.0, 1.0, audioRight, audioRight, AUDIO_SAMPLE_BUFFER * sizeof(int16_t)); csndPlaySound(0x9, SOUND_REPEAT | SOUND_FORMAT_16BIT, 32768, 1.0, 1.0, audioRight, audioRight, AUDIO_SAMPLE_BUFFER * sizeof(int16_t));
} }
unsigned mode;
if (GBAConfigGetUIntValue(&runner->context.config, "screenMode", &mode) && mode != screenMode) {
screenMode = mode;
screenCleanup |= SCREEN_CLEANUP_BOTTOM | SCREEN_CLEANUP_TOP;
}
} }
static void _gameUnloaded(struct GBAGUIRunner* runner) { static void _gameUnloaded(struct GBAGUIRunner* runner) {
@ -292,19 +319,10 @@ static uint16_t _pollGameInput(struct GBAGUIRunner* runner) {
static void _incrementScreenMode(struct GBAGUIRunner* runner) { static void _incrementScreenMode(struct GBAGUIRunner* runner) {
UNUSED(runner); UNUSED(runner);
// Clear the buffer screenCleanup |= SCREEN_CLEANUP_TOP | SCREEN_CLEANUP_BOTTOM;
_drawStart();
_drawEnd();
_drawStart();
_drawEnd();
unsigned mode;
if (GBAConfigGetUIntValue(&runner->context.config, "screenMode", &mode) && mode != screenMode) {
screenMode = mode;
} else {
screenMode = (screenMode + 1) % SM_MAX; screenMode = (screenMode + 1) % SM_MAX;
GBAConfigSetUIntValue(&runner->context.config, "screenMode", screenMode); GBAConfigSetUIntValue(&runner->context.config, "screenMode", screenMode);
} }
}
static uint32_t _pollInput(void) { static uint32_t _pollInput(void) {
hidScanInput(); hidScanInput();