From b277f1ccf450e87340afc14aba396221295e6ef7 Mon Sep 17 00:00:00 2001 From: shinyquagsire23 Date: Wed, 27 Jul 2016 00:42:14 -0700 Subject: [PATCH] Add proper ProcUI multitasking to samples --- samples/helloworld/Makefile | 2 +- samples/helloworld/src/main.c | 44 ++++++++++ samples/pong/Makefile | 2 +- samples/pong/src/program.c | 159 ++++++++++++++++++++++------------ 4 files changed, 152 insertions(+), 55 deletions(-) diff --git a/samples/helloworld/Makefile b/samples/helloworld/Makefile index 2db617e..a914be8 100644 --- a/samples/helloworld/Makefile +++ b/samples/helloworld/Makefile @@ -18,7 +18,7 @@ BUILD := build SOURCE := src INCLUDE := include DATA := data -LIBS := -lcoreinit +LIBS := -lcoreinit -lproc_ui CFLAGS += -O2 -Wall -std=c11 CXXFLAGS += -O2 -Wall diff --git a/samples/helloworld/src/main.c b/samples/helloworld/src/main.c index 885d5dc..b738347 100644 --- a/samples/helloworld/src/main.c +++ b/samples/helloworld/src/main.c @@ -1,6 +1,47 @@ #include #include #include +#include +#include + +bool isAppRunning = true; + +void +SaveCallback() +{ + OSSavesDone_ReadyToRelease(); // Required +} + +bool +AppRunning() +{ + if(!OSIsMainCore()) + { + ProcUISubProcessMessages(true); + } + else + { + ProcUIStatus status = ProcUIProcessMessages(true); + + if(status == PROCUI_STATUS_EXITING) + { + // Being closed, deinit, free, and prepare to exit + isAppRunning = false; + ProcUIShutdown(); + } + else if(status == PROCUI_STATUS_RELEASE_FOREGROUND) + { + // Free up MEM1 to next foreground app, deinit screen, etc. + ProcUIDrawDoneRelease(); + } + else if(status == PROCUI_STATUS_IN_FOREGROUND) + { + // Executed while app is in foreground + } + } + + return isAppRunning; +} int CoreEntryPoint(int argc, const char **argv) @@ -12,6 +53,7 @@ CoreEntryPoint(int argc, const char **argv) int main(int argc, char **argv) { + ProcUIInit(&SaveCallback); OSReport("Main thread running on core %d", OSGetCoreId()); // Run thread on core 0 @@ -39,5 +81,7 @@ main(int argc, char **argv) OSReport("Core 0 thread returned %d", resultCore0); OSReport("Core 2 thread returned %d", resultCore2); + + while(AppRunning()); return 0; } diff --git a/samples/pong/Makefile b/samples/pong/Makefile index 3c0b7e8..ef9dadd 100644 --- a/samples/pong/Makefile +++ b/samples/pong/Makefile @@ -18,7 +18,7 @@ BUILD := build SOURCE := src INCLUDE := include DATA := data -LIBS := -lgcc -lcrt -lcoreinit -lvpad -lsysapp +LIBS := -lgcc -lcrt -lcoreinit -lvpad -lproc_ui CFLAGS += -O2 -Wall -std=c11 CXXFLAGS += -O2 -Wall diff --git a/samples/pong/src/program.c b/samples/pong/src/program.c index 884f1d6..0fa69d6 100755 --- a/samples/pong/src/program.c +++ b/samples/pong/src/program.c @@ -1,20 +1,118 @@ #include "program.h" +#include #include #include #include -#include +#include +#include #include -#include -#include #include "memory.h" char log_buf[0x400]; +bool isAppRunning = true; +bool initialized = false; + +void screenInit() +{ + //Grab the buffer size for each screen (TV and gamepad) + int buf0_size = OSScreenGetBufferSizeEx(0); + int buf1_size = OSScreenGetBufferSizeEx(1); + __os_snprintf(log_buf, 0x400, "Screen sizes %x, %x\n", buf0_size, buf1_size); + OSReport(log_buf); + + //Set the buffer area. + screenBuffer = MEM1_alloc(buf0_size + buf1_size, 0x40); + __os_snprintf(log_buf, 0x400, "Allocated screen buffers at %x\n", screenBuffer); + OSReport(log_buf); + + OSScreenSetBufferEx(0, screenBuffer); + OSScreenSetBufferEx(1, (screenBuffer + buf0_size)); + OSReport("Set screen buffers\n"); + + OSScreenEnableEx(0, 1); + OSScreenEnableEx(1, 1); + + //Clear both framebuffers. + for (int ii = 0; ii < 2; ii++) + { + fillScreen(0,0,0,0); + flipBuffers(); + } +} + +void screenDeinit() +{ + for(int ii = 0; ii < 2; ii++) + { + fillScreen(0,0,0,0); + flipBuffers(); + } + + MEM1_free(screenBuffer); +} + +void SaveCallback() +{ + OSSavesDone_ReadyToRelease(); // Required +} + +bool AppRunning() +{ + if(!OSIsMainCore()) + { + ProcUISubProcessMessages(true); + } + else + { + ProcUIStatus status = ProcUIProcessMessages(true); + + if(status == PROCUI_STATUS_EXITING) + { + // Being closed, deinit things and prepare to exit + isAppRunning = false; + + if(initialized) + { + initialized = false; + screenDeinit(); + memoryRelease(); + } + + ProcUIShutdown(); + } + else if(status == PROCUI_STATUS_RELEASE_FOREGROUND) + { + // Free up MEM1 to next foreground app, etc. + initialized = false; + + screenDeinit(); + memoryRelease(); + ProcUIDrawDoneRelease(); + } + else if(status == PROCUI_STATUS_IN_FOREGROUND) + { + // Reallocate MEM1, reinit screen, etc. + if(!initialized) + { + initialized = true; + + memoryInitialize(); + screenInit(); + } + } + } + + return isAppRunning; +} + int main(int argc, char **argv) { - memoryInitialize(); - OSReport("Memory initialized\n"); + OSScreenInit(); + OSReport("Screen initted\n"); + + ProcUIInit(&SaveCallback); /****************************> Globals <****************************/ struct pongGlobals myPongGlobals; @@ -99,40 +197,13 @@ int main(int argc, char **argv) myPongGlobals.renderScoreFlag = 0; OSReport("Globals initialized\n"); - //Call the Screen initilzation function. - OSScreenInit(); - OSReport("Screen initted\n"); - //Grab the buffer size for each screen (TV and gamepad) - int buf0_size = OSScreenGetBufferSizeEx(0); - int buf1_size = OSScreenGetBufferSizeEx(1); - __os_snprintf(log_buf, 0x400, "Screen sizes %x, %x\n", buf0_size, buf1_size); - OSReport(log_buf); - - //Set the buffer area. - screenBuffer = MEM1_alloc(buf0_size + buf1_size, 0x40); - __os_snprintf(log_buf, 0x400, "Allocated screen buffers at %x\n", screenBuffer); - OSReport(log_buf); - - OSScreenSetBufferEx(0, screenBuffer); - OSScreenSetBufferEx(1, (screenBuffer + buf0_size)); - OSReport("Set screen buffers\n"); - - OSScreenEnableEx(0, 1); - OSScreenEnableEx(1, 1); - - //Clear both framebuffers. - for (int ii = 0; ii < 2; ii++) - { - fillScreen(0,0,0,0); - flipBuffers(); - } - OSReport("Screen initialized\n"); - /****************************> VPAD Loop <****************************/ int error; VPADStatus vpad_data; - while (1) + while (AppRunning()) { + if(!initialized) continue; + VPADRead(0, &vpad_data, 1, &error); //Get the status of the gamepad myPongGlobals.button = vpad_data.hold; @@ -160,25 +231,7 @@ int main(int argc, char **argv) //Increment the counter (used for physicals calcuations) myPongGlobals.count+=1; - - //To exit the game - if (myPongGlobals.button & VPAD_BUTTON_HOME) - { - break; - } } - //WARNING: DO NOT CHANGE THIS. YOU MUST CLEAR THE FRAMEBUFFERS AND IMMEDIATELY CALL EXIT FROM THIS FUNCTION. RETURNING TO LOADER CAUSES FREEZE. - for(int ii = 0; ii < 2; ii++) - { - fillScreen(0,0,0,0); - flipBuffers(); - } - - //TODO: This doesn't work? - OSReport("Exiting to menu\n"); - memoryRelease(); - SYSLaunchMenu(); - exit(0); return 0; }