1#if defined(__EMSCRIPTEN__)
5#define PLATFORM "Switch"
7#define PLATFORM "Wii U"
8#include <coreinit/core.h>
9#include <coreinit/foreground.h>
10#include <proc_ui/procui.h>
11#include <sysapp/launch.h>
15#define PLATFORM "Console"
19#include "../libs/resinfs/include/romfs-wiiu.h"
22#include "RootDisplay.hpp"
24#include "DownloadQueue.hpp"
26#include "TextElement.hpp"
31CST_Renderer* RootDisplay::renderer = NULL;
32CST_Window* RootDisplay::window = NULL;
33RootDisplay* RootDisplay::mainDisplay = NULL;
34bool RootDisplay::isDebug =
false;
36std::vector<std::unique_ptr<Screen>> RootDisplay::screenStack;
37std::vector<std::function<void()>> RootDisplay::deferredActions;
38bool RootDisplay::isProcessingEvents =
false;
40int RootDisplay::screenWidth = 1280;
41int RootDisplay::screenHeight = 720;
42float RootDisplay::dpiScale = 1.0f;
43float RootDisplay::globalScale = 1.0f;
45bool RootDisplay::idleCursorPulsing =
false;
47RootDisplay::RootDisplay()
58 this->
width = SCREEN_WIDTH;
59 this->height = SCREEN_HEIGHT;
61 this->hasBackground =
true;
68 RootDisplay::dpiScale = CST_GetDpiScale();
71 this->backgroundColor = fromRGB(30, 30, 30);
74#if defined(WII) || defined(WII_MOCK)
76 setScreenResolution(854, 480);
77#elif defined(_3DS) || defined(_3DS_MOCK)
78 setScreenResolution(400, 480);
81 setScreenResolution(1280, 720);
84 this->events = std::make_unique<InputEvents>();
88 TextElement::loadI18nCache(
"en-us");
94 DownloadQueue::init();
97void RootDisplay::initMusic()
102 AppletType at = appletGetAppletType();
103 if (at != AppletType_Application && at != AppletType_SystemApplication) {
112void RootDisplay::startMusic()
114 CST_FadeInMusic(
this);
117void RootDisplay::setScreenResolution(
int width,
int height)
120 SCREEN_WIDTH =
width;
121 SCREEN_HEIGHT = height;
124 this->width = SCREEN_WIDTH;
125 this->height = SCREEN_HEIGHT;
128 CST_SetWindowSize(window, SCREEN_WIDTH / RootDisplay::dpiScale, SCREEN_HEIGHT / RootDisplay::dpiScale);
130 RootDisplay::deferAction([]() {
132 for (
auto& screen : screenStack) {
139void RootDisplay::pushScreen(std::unique_ptr<Screen> screen)
144 screenStack.push_back(std::move(screen));
148void RootDisplay::popScreen()
150 if (isProcessingEvents) {
153 if (!screenStack.empty()) {
154 screenStack.pop_back();
155 if (mainDisplay) mainDisplay->needsRedraw = true;
160 if (!screenStack.empty()) {
161 screenStack.pop_back();
167void RootDisplay::clearScreens()
169 if (isProcessingEvents) {
181void RootDisplay::deferAction(std::function<
void()> action)
184 deferredActions.push_back(std::move(
action));
187void RootDisplay::processDeferredActions()
190 auto actionsToRun = std::move(deferredActions);
191 deferredActions.clear();
193 for (
auto&
action : actionsToRun) {
200Screen* RootDisplay::topScreen()
202 return screenStack.empty() ? nullptr : screenStack.back().get();
205bool RootDisplay::hasScreens()
207 return !screenStack.empty();
210RootDisplay::~RootDisplay()
218 DownloadQueue::quit();
222#if defined(USE_RAMFS)
234 if (!screenStack.empty()) {
235 result = screenStack.back()->process(event) ||
event->isTouchDrag();
247 if (!screenStack.empty())
251 for (
const auto& screen : screenStack) {
252 screen->render(
this);
266void RootDisplay::update()
278 CST_RenderPresent(this->renderer);
282void RootDisplay::requestQuit()
285 if (hasRequestedQuit) {
288 hasRequestedQuit =
true;
294 this->isAppRunning =
false;
298int RootDisplay::mainLoop()
303 auto updateDisplay = +[](
void* display) ->
unsigned int {
304 ((RootDisplay*)display)->futureRedrawCounter = 10;
307 ProcUIRegisterCallback(PROCUI_CALLBACK_ACQUIRE, updateDisplay,
this, 100);
311 auto actuallyQuit = +[](
void* display) ->
unsigned int {
312 ((RootDisplay*)display)->isAppRunning =
false;
315 ProcUIRegisterCallback(PROCUI_CALLBACK_EXIT, actuallyQuit,
this, 100);
320 bool atLeastOneNewEvent =
false;
321 bool viewChanged =
false;
323 int frameStart = CST_GetTicks();
326 DownloadQueue::downloadQueue->process();
329 while (events->update())
331 isProcessingEvents =
true;
334 viewChanged |= this->
process(events.get());
335 atLeastOneNewEvent =
true;
337 isProcessingEvents =
false;
340 if (this->canUseSelectToExit && events->pressed(SELECT_BUTTON)) {
345 if ((!atLeastOneNewEvent && !viewChanged))
347 isProcessingEvents =
true;
349 viewChanged |= this->
process(events.get());
350 isProcessingEvents =
false;
354 processDeferredActions();
364 int delayTime = (CST_GetTicks() - frameStart);
368 CST_Delay(16 - delayTime);
std::vector< std::unique_ptr< Element, std::function< void(Element *)> > > elements
visible GUI child elements of this element
int width
width and height of this element (must be manually set, isn't usually calculated (but is in some case...
virtual void render(Element *parent)
display the current state of the display
virtual bool process(InputEvents *event)
process any input that is received for this element
bool needsRedraw
whether or not this element needs the screen redrawn next time it's processed
Element * parent
the parent element (reference only, not owned)
std::function< void()> action
the action to call (from binded callback) on touch or button selection https://stackoverflow....
bool process(InputEvents *event)
process any input that is received for this element
void render(Element *parent)
display the current state of the display