git subrepo clone --force https://github.com/WerWolv/libtesla Source/sys-clk-OC/overlay/lib/tesla/
subrepo: subdir: "Source/sys-clk-OC/overlay/lib/tesla" merged: "779b4ea" upstream: origin: "https://github.com/WerWolv/libtesla" branch: "master" commit: "779b4ea" git-subrepo: version: "0.4.5" origin: "https://github.com/ingydotnet/git-subrepo" commit: "dbb99be"
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/WerWolv/libtesla
|
remote = https://github.com/WerWolv/libtesla
|
||||||
branch = master
|
branch = master
|
||||||
commit = b32acbca64c78bf37bc456bd386cd6b7148842c8
|
commit = 779b4ead7df6b277b947a535544aa519785c437e
|
||||||
parent = 8d06bd060457ebf5c647c69e95c645d5a8198d75
|
parent = 3b9fed9f6b06581a0748fcfbcf992929919c01b5
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.5
|
cmdver = 0.4.5
|
||||||
|
|||||||
@@ -210,7 +210,8 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param f wrapped function
|
* @param f wrapped function
|
||||||
*/
|
*/
|
||||||
static inline void doWithSmSession(std::function<void()> f) {
|
template<typename F>
|
||||||
|
static inline void doWithSmSession(F f) {
|
||||||
smInitialize();
|
smInitialize();
|
||||||
f();
|
f();
|
||||||
smExit();
|
smExit();
|
||||||
@@ -222,7 +223,8 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param f wrapped function
|
* @param f wrapped function
|
||||||
*/
|
*/
|
||||||
static inline void doWithSDCardHandle(std::function<void()> f) {
|
template<typename F>
|
||||||
|
static inline void doWithSDCardHandle(F f) {
|
||||||
fsdevMountSdmc();
|
fsdevMountSdmc();
|
||||||
f();
|
f();
|
||||||
fsdevUnmountDevice("sdmc");
|
fsdevUnmountDevice("sdmc");
|
||||||
@@ -233,15 +235,17 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param f wrapped function
|
* @param f wrapped function
|
||||||
*/
|
*/
|
||||||
|
template<typename F>
|
||||||
class ScopeGuard {
|
class ScopeGuard {
|
||||||
ScopeGuard(const ScopeGuard&) = delete;
|
ScopeGuard(const ScopeGuard&) = delete;
|
||||||
ScopeGuard& operator=(const ScopeGuard&) = delete;
|
ScopeGuard& operator=(const ScopeGuard&) = delete;
|
||||||
private:
|
private:
|
||||||
std::function<void()> f;
|
F f;
|
||||||
|
bool canceled = false;
|
||||||
public:
|
public:
|
||||||
ALWAYS_INLINE ScopeGuard(std::function<void()> f) : f(std::move(f)) { }
|
ALWAYS_INLINE ScopeGuard(F f) : f(std::move(f)) { }
|
||||||
ALWAYS_INLINE ~ScopeGuard() { if (f) { f(); } }
|
ALWAYS_INLINE ~ScopeGuard() { if (!canceled) { f(); } }
|
||||||
void dismiss() { f = nullptr; }
|
void dismiss() { canceled = true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -530,26 +534,14 @@ namespace tsl {
|
|||||||
* @param h Height
|
* @param h Height
|
||||||
*/
|
*/
|
||||||
inline void enableScissoring(s32 x, s32 y, s32 w, s32 h) {
|
inline void enableScissoring(s32 x, s32 y, s32 w, s32 h) {
|
||||||
if (this->m_scissoring)
|
this->m_scissoringStack.emplace(x, y, w, h);
|
||||||
this->m_scissoringStack.push_back(this->m_currScissorConfig);
|
|
||||||
else
|
|
||||||
this->m_scissoring = true;
|
|
||||||
|
|
||||||
this->m_currScissorConfig = { x, y, w, h };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disables scissoring
|
* @brief Disables scissoring
|
||||||
*/
|
*/
|
||||||
inline void disableScissoring() {
|
inline void disableScissoring() {
|
||||||
if (this->m_scissoringStack.size() > 0) {
|
this->m_scissoringStack.pop();
|
||||||
this->m_currScissorConfig = this->m_scissoringStack.back();
|
|
||||||
this->m_scissoringStack.pop_back();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this->m_scissoring = false;
|
|
||||||
this->m_currScissorConfig = { 0 };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -797,7 +789,7 @@ namespace tsl {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 key = (static_cast<u64>(currCharacter) << 32) | static_cast<u64>(std::bit_cast<u32>(fontSize));
|
u64 key = (static_cast<u64>(currCharacter) << 32) | static_cast<u64>(monospace) << 31 | static_cast<u64>(std::bit_cast<u32>(fontSize));
|
||||||
|
|
||||||
Glyph *glyph = nullptr;
|
Glyph *glyph = nullptr;
|
||||||
|
|
||||||
@@ -936,9 +928,7 @@ namespace tsl {
|
|||||||
Framebuffer m_framebuffer;
|
Framebuffer m_framebuffer;
|
||||||
void *m_currentFramebuffer = nullptr;
|
void *m_currentFramebuffer = nullptr;
|
||||||
|
|
||||||
bool m_scissoring = false;
|
std::stack<ScissoringConfig> m_scissoringStack;
|
||||||
ScissoringConfig m_currScissorConfig;
|
|
||||||
std::vector<ScissoringConfig> m_scissoringStack;
|
|
||||||
|
|
||||||
stbtt_fontinfo m_stdFont, m_localFont, m_extFont;
|
stbtt_fontinfo m_stdFont, m_localFont, m_extFont;
|
||||||
bool m_hasLocalFont = false;
|
bool m_hasLocalFont = false;
|
||||||
@@ -1015,11 +1005,12 @@ namespace tsl {
|
|||||||
* @return Offset
|
* @return Offset
|
||||||
*/
|
*/
|
||||||
u32 getPixelOffset(s32 x, s32 y) {
|
u32 getPixelOffset(s32 x, s32 y) {
|
||||||
if (this->m_scissoring) {
|
if (!this->m_scissoringStack.empty()) {
|
||||||
if (x < this->m_currScissorConfig.x ||
|
auto currScissorConfig = this->m_scissoringStack.top();
|
||||||
y < this->m_currScissorConfig.y ||
|
if (x < currScissorConfig.x ||
|
||||||
x > this->m_currScissorConfig.x + this->m_currScissorConfig.w ||
|
y < currScissorConfig.y ||
|
||||||
y > this->m_currScissorConfig.y + this->m_currScissorConfig.h)
|
x > currScissorConfig.x + currScissorConfig.w ||
|
||||||
|
y > currScissorConfig.y + currScissorConfig.h)
|
||||||
return UINT32_MAX;
|
return UINT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1088,7 +1079,25 @@ namespace tsl {
|
|||||||
if (!this->m_initialized)
|
if (!this->m_initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
framebufferClose(&this->m_framebuffer);
|
//framebufferClose(&this->m_framebuffer);
|
||||||
|
Framebuffer* fb = &this->m_framebuffer;
|
||||||
|
if (!fb || !fb->has_init)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fb->buf_linear)
|
||||||
|
free(fb->buf_linear);
|
||||||
|
|
||||||
|
if (fb->buf) {
|
||||||
|
nwindowReleaseBuffers(fb->win);
|
||||||
|
nvMapClose(&fb->map);
|
||||||
|
free(fb->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(fb, 0, sizeof(*fb));
|
||||||
|
nvFenceExit();
|
||||||
|
nvMapExit();
|
||||||
|
svcSleepThread(10'000'000);
|
||||||
|
nvExit();
|
||||||
nwindowClose(&this->m_window);
|
nwindowClose(&this->m_window);
|
||||||
viDestroyManagedLayer(&this->m_layer);
|
viDestroyManagedLayer(&this->m_layer);
|
||||||
viCloseDisplay(&this->m_display);
|
viCloseDisplay(&this->m_display);
|
||||||
@@ -1268,7 +1277,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param renderer
|
* @param renderer
|
||||||
*/
|
*/
|
||||||
virtual void frame(gfx::Renderer *renderer) final {
|
void frame(gfx::Renderer *renderer) {
|
||||||
renderer->enableScissoring(0, 0, tsl::cfg::FramebufferWidth, tsl::cfg::FramebufferHeight);
|
renderer->enableScissoring(0, 0, tsl::cfg::FramebufferWidth, tsl::cfg::FramebufferHeight);
|
||||||
|
|
||||||
if (this->m_focused)
|
if (this->m_focused)
|
||||||
@@ -1290,7 +1299,7 @@ namespace tsl {
|
|||||||
* @brief Forces a layout recreation of a element
|
* @brief Forces a layout recreation of a element
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void invalidate() final {
|
void invalidate() {
|
||||||
const auto& parent = this->getParent();
|
const auto& parent = this->getParent();
|
||||||
|
|
||||||
if (parent == nullptr)
|
if (parent == nullptr)
|
||||||
@@ -1304,7 +1313,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param direction Direction to shake highlight in
|
* @param direction Direction to shake highlight in
|
||||||
*/
|
*/
|
||||||
virtual void shakeHighlight(FocusDirection direction) final {
|
void shakeHighlight(FocusDirection direction) {
|
||||||
this->m_highlightShaking = true;
|
this->m_highlightShaking = true;
|
||||||
this->m_highlightShakingDirection = direction;
|
this->m_highlightShakingDirection = direction;
|
||||||
this->m_highlightShakingStartTime = std::chrono::system_clock::now();
|
this->m_highlightShakingStartTime = std::chrono::system_clock::now();
|
||||||
@@ -1314,14 +1323,14 @@ namespace tsl {
|
|||||||
* @brief Triggers the blue click animation to signal a element has been clicked on
|
* @brief Triggers the blue click animation to signal a element has been clicked on
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void triggerClickAnimation() final {
|
void triggerClickAnimation() {
|
||||||
this->m_clickAnimationProgress = tsl::style::ListItemHighlightLength;
|
this->m_clickAnimationProgress = tsl::style::ListItemHighlightLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resets the click animation progress, canceling the animation
|
* @brief Resets the click animation progress, canceling the animation
|
||||||
*/
|
*/
|
||||||
virtual void resetClickAnimation() final {
|
void resetClickAnimation() {
|
||||||
this->m_clickAnimationProgress = 0;
|
this->m_clickAnimationProgress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1634,7 +1643,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param content Element
|
* @param content Element
|
||||||
*/
|
*/
|
||||||
virtual void setContent(Element *content) final {
|
void setContent(Element *content) {
|
||||||
if (this->m_contentElement != nullptr)
|
if (this->m_contentElement != nullptr)
|
||||||
delete this->m_contentElement;
|
delete this->m_contentElement;
|
||||||
|
|
||||||
@@ -1651,7 +1660,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param title Title to change to
|
* @param title Title to change to
|
||||||
*/
|
*/
|
||||||
virtual void setTitle(const std::string &title) final {
|
void setTitle(const std::string &title) {
|
||||||
this->m_title = title;
|
this->m_title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1660,7 +1669,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param title Subtitle to change to
|
* @param title Subtitle to change to
|
||||||
*/
|
*/
|
||||||
virtual void setSubtitle(const std::string &subtitle) final {
|
void setSubtitle(const std::string &subtitle) {
|
||||||
this->m_subtitle = subtitle;
|
this->m_subtitle = subtitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1736,7 +1745,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param content Element
|
* @param content Element
|
||||||
*/
|
*/
|
||||||
virtual void setContent(Element *content) final {
|
void setContent(Element *content) {
|
||||||
if (this->m_contentElement != nullptr)
|
if (this->m_contentElement != nullptr)
|
||||||
delete this->m_contentElement;
|
delete this->m_contentElement;
|
||||||
|
|
||||||
@@ -1753,7 +1762,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param header Header custom drawer
|
* @param header Header custom drawer
|
||||||
*/
|
*/
|
||||||
virtual void setHeader(CustomDrawer *header) final {
|
void setHeader(CustomDrawer *header) {
|
||||||
if (this->m_header != nullptr)
|
if (this->m_header != nullptr)
|
||||||
delete this->m_header;
|
delete this->m_header;
|
||||||
|
|
||||||
@@ -1937,7 +1946,7 @@ namespace tsl {
|
|||||||
* @param index Index in the list where the item should be inserted. -1 or greater list size will insert it at the end
|
* @param index Index in the list where the item should be inserted. -1 or greater list size will insert it at the end
|
||||||
* @param height Height of the element. Don't set this parameter for libtesla to try and figure out the size based on the type
|
* @param height Height of the element. Don't set this parameter for libtesla to try and figure out the size based on the type
|
||||||
*/
|
*/
|
||||||
virtual void addItem(Element *element, u16 height = 0, ssize_t index = -1) final {
|
void addItem(Element *element, u16 height = 0, ssize_t index = -1) {
|
||||||
if (element != nullptr) {
|
if (element != nullptr) {
|
||||||
if (height != 0)
|
if (height != 0)
|
||||||
element->setBoundaries(this->getX(), this->getY(), this->getWidth(), height);
|
element->setBoundaries(this->getX(), this->getY(), this->getWidth(), height);
|
||||||
@@ -1974,7 +1983,7 @@ namespace tsl {
|
|||||||
* @brief Removes all children from the list later on
|
* @brief Removes all children from the list later on
|
||||||
* @warning When clearing a list, make sure none of the its children are focused. Call \ref Gui::removeFocus before.
|
* @warning When clearing a list, make sure none of the its children are focused. Call \ref Gui::removeFocus before.
|
||||||
*/
|
*/
|
||||||
virtual void clear() final {
|
void clear() {
|
||||||
this->m_clearList = true;
|
this->m_clearList = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2780,7 +2789,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @return Top level element
|
* @return Top level element
|
||||||
*/
|
*/
|
||||||
virtual elm::Element* getTopElement() final {
|
elm::Element* getTopElement() {
|
||||||
return this->m_topElement;
|
return this->m_topElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2789,7 +2798,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @return Focused element
|
* @return Focused element
|
||||||
*/
|
*/
|
||||||
virtual elm::Element* getFocusedElement() final {
|
elm::Element* getFocusedElement() {
|
||||||
return this->m_focusedElement;
|
return this->m_focusedElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2800,7 +2809,7 @@ namespace tsl {
|
|||||||
* @param element Element to focus
|
* @param element Element to focus
|
||||||
* @param direction Focus direction
|
* @param direction Focus direction
|
||||||
*/
|
*/
|
||||||
virtual void requestFocus(elm::Element *element, FocusDirection direction, bool shake = true) final {
|
void requestFocus(elm::Element *element, FocusDirection direction, bool shake = true) {
|
||||||
elm::Element *oldFocus = this->m_focusedElement;
|
elm::Element *oldFocus = this->m_focusedElement;
|
||||||
|
|
||||||
if (element != nullptr) {
|
if (element != nullptr) {
|
||||||
@@ -2823,7 +2832,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param element Element to remove focus from. Pass nullptr to remove the focus unconditionally
|
* @param element Element to remove focus from. Pass nullptr to remove the focus unconditionally
|
||||||
*/
|
*/
|
||||||
virtual void removeFocus(elm::Element* element = nullptr) final {
|
void removeFocus(elm::Element* element = nullptr) {
|
||||||
if (element == nullptr || element == this->m_focusedElement) {
|
if (element == nullptr || element == this->m_focusedElement) {
|
||||||
if (this->m_focusedElement != nullptr) {
|
if (this->m_focusedElement != nullptr) {
|
||||||
this->m_focusedElement->setFocused(false);
|
this->m_focusedElement->setFocused(false);
|
||||||
@@ -2832,7 +2841,7 @@ namespace tsl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void restoreFocus() final {
|
void restoreFocus() {
|
||||||
this->m_initialFocusSet = false;
|
this->m_initialFocusSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2853,16 +2862,16 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @param renderer
|
* @param renderer
|
||||||
*/
|
*/
|
||||||
virtual void draw(gfx::Renderer *renderer) final {
|
void draw(gfx::Renderer *renderer) {
|
||||||
if (this->m_topElement != nullptr)
|
if (this->m_topElement != nullptr)
|
||||||
this->m_topElement->draw(renderer);
|
this->m_topElement->draw(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool initialFocusSet() final {
|
bool initialFocusSet() {
|
||||||
return this->m_initialFocusSet;
|
return this->m_initialFocusSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void markInitialFocusSet() final {
|
void markInitialFocusSet() {
|
||||||
this->m_initialFocusSet = true;
|
this->m_initialFocusSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2928,7 +2937,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @return Current Gui reference
|
* @return Current Gui reference
|
||||||
*/
|
*/
|
||||||
virtual std::unique_ptr<tsl::Gui>& getCurrentGui() final {
|
std::unique_ptr<tsl::Gui>& getCurrentGui() {
|
||||||
return this->m_guiStack.top();
|
return this->m_guiStack.top();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2936,7 +2945,7 @@ namespace tsl {
|
|||||||
* @brief Shows the Gui
|
* @brief Shows the Gui
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void show() final {
|
void show() {
|
||||||
if (this->m_disableNextAnimation) {
|
if (this->m_disableNextAnimation) {
|
||||||
this->m_animationCounter = 5;
|
this->m_animationCounter = 5;
|
||||||
this->m_disableNextAnimation = false;
|
this->m_disableNextAnimation = false;
|
||||||
@@ -2956,7 +2965,7 @@ namespace tsl {
|
|||||||
* @brief Hides the Gui
|
* @brief Hides the Gui
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void hide() final {
|
void hide() {
|
||||||
if (this->m_disableNextAnimation) {
|
if (this->m_disableNextAnimation) {
|
||||||
this->m_animationCounter = 0;
|
this->m_animationCounter = 0;
|
||||||
this->m_disableNextAnimation = false;
|
this->m_disableNextAnimation = false;
|
||||||
@@ -2974,7 +2983,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @return whether fade animation is playing
|
* @return whether fade animation is playing
|
||||||
*/
|
*/
|
||||||
virtual bool fadeAnimationPlaying() final {
|
bool fadeAnimationPlaying() {
|
||||||
return this->m_fadeInAnimationPlaying || this->m_fadeOutAnimationPlaying;
|
return this->m_fadeInAnimationPlaying || this->m_fadeOutAnimationPlaying;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2983,7 +2992,7 @@ namespace tsl {
|
|||||||
* @note This makes the Tesla overlay exit and return back to the Tesla-Menu
|
* @note This makes the Tesla overlay exit and return back to the Tesla-Menu
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void close() final {
|
void close() {
|
||||||
this->m_shouldClose = true;
|
this->m_shouldClose = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3028,7 +3037,7 @@ namespace tsl {
|
|||||||
* @brief Initializes the Renderer
|
* @brief Initializes the Renderer
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void initScreen() final {
|
void initScreen() {
|
||||||
gfx::Renderer::get().init();
|
gfx::Renderer::get().init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3036,7 +3045,7 @@ namespace tsl {
|
|||||||
* @brief Exits the Renderer
|
* @brief Exits the Renderer
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void exitScreen() final {
|
void exitScreen() {
|
||||||
gfx::Renderer::get().exit();
|
gfx::Renderer::get().exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3045,7 +3054,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @return should hide
|
* @return should hide
|
||||||
*/
|
*/
|
||||||
virtual bool shouldHide() final {
|
bool shouldHide() {
|
||||||
return this->m_shouldHide;
|
return this->m_shouldHide;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3054,7 +3063,7 @@ namespace tsl {
|
|||||||
*
|
*
|
||||||
* @return should close
|
* @return should close
|
||||||
*/
|
*/
|
||||||
virtual bool shouldClose() final {
|
bool shouldClose() {
|
||||||
return this->m_shouldClose;
|
return this->m_shouldClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3062,7 +3071,7 @@ namespace tsl {
|
|||||||
* @brief Handles fade in and fade out animations of the Overlay
|
* @brief Handles fade in and fade out animations of the Overlay
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void animationLoop() final {
|
void animationLoop() {
|
||||||
if (this->m_fadeInAnimationPlaying) {
|
if (this->m_fadeInAnimationPlaying) {
|
||||||
this->m_animationCounter++;
|
this->m_animationCounter++;
|
||||||
|
|
||||||
@@ -3086,7 +3095,7 @@ namespace tsl {
|
|||||||
* @brief Main loop
|
* @brief Main loop
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void loop() final {
|
void loop() {
|
||||||
auto& renderer = gfx::Renderer::get();
|
auto& renderer = gfx::Renderer::get();
|
||||||
|
|
||||||
renderer.startFrame();
|
renderer.startFrame();
|
||||||
@@ -3108,7 +3117,7 @@ namespace tsl {
|
|||||||
* @param rightJoyStick Right joystick position
|
* @param rightJoyStick Right joystick position
|
||||||
* @return Weather or not the input has been consumed
|
* @return Weather or not the input has been consumed
|
||||||
*/
|
*/
|
||||||
virtual void handleInput(u64 keysDown, u64 keysHeld, bool touchDetected, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) final {
|
void handleInput(u64 keysDown, u64 keysHeld, bool touchDetected, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) {
|
||||||
static HidTouchState initialTouchPos = { 0 };
|
static HidTouchState initialTouchPos = { 0 };
|
||||||
static HidTouchState oldTouchPos = { 0 };
|
static HidTouchState oldTouchPos = { 0 };
|
||||||
static bool oldTouchDetected = false;
|
static bool oldTouchDetected = false;
|
||||||
@@ -3247,7 +3256,7 @@ namespace tsl {
|
|||||||
* @brief Clears the screen
|
* @brief Clears the screen
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void clearScreen() final {
|
void clearScreen() {
|
||||||
auto& renderer = gfx::Renderer::get();
|
auto& renderer = gfx::Renderer::get();
|
||||||
|
|
||||||
renderer.startFrame();
|
renderer.startFrame();
|
||||||
@@ -3259,7 +3268,7 @@ namespace tsl {
|
|||||||
* @brief Reset hide and close flags that were previously set by \ref Overlay::close() or \ref Overlay::hide()
|
* @brief Reset hide and close flags that were previously set by \ref Overlay::close() or \ref Overlay::hide()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void resetFlags() final {
|
void resetFlags() {
|
||||||
this->m_shouldHide = false;
|
this->m_shouldHide = false;
|
||||||
this->m_shouldClose = false;
|
this->m_shouldClose = false;
|
||||||
}
|
}
|
||||||
@@ -3268,7 +3277,7 @@ namespace tsl {
|
|||||||
* @brief Disables the next animation that would play
|
* @brief Disables the next animation that would play
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void disableNextAnimation() final {
|
void disableNextAnimation() {
|
||||||
this->m_disableNextAnimation = true;
|
this->m_disableNextAnimation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3340,7 +3349,7 @@ namespace tsl {
|
|||||||
struct SharedThreadData {
|
struct SharedThreadData {
|
||||||
bool running = false;
|
bool running = false;
|
||||||
|
|
||||||
Event comboEvent = { 0 }, homeButtonPressEvent = { 0 }, powerButtonPressEvent = { 0 };
|
Event comboEvent = { 0 };
|
||||||
|
|
||||||
bool overlayOpen = false;
|
bool overlayOpen = false;
|
||||||
|
|
||||||
@@ -3380,15 +3389,25 @@ namespace tsl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Input polling loop thread
|
* @brief Background event polling loop thread
|
||||||
*
|
*
|
||||||
* @tparam launchFlags Launch flags
|
|
||||||
* @param args Used to pass in a pointer to a \ref SharedThreadData struct
|
* @param args Used to pass in a pointer to a \ref SharedThreadData struct
|
||||||
*/
|
*/
|
||||||
template<impl::LaunchFlags launchFlags>
|
static void backgroundEventPoller(void *args) {
|
||||||
static void hidInputPoller(void *args) {
|
|
||||||
SharedThreadData *shData = static_cast<SharedThreadData*>(args);
|
SharedThreadData *shData = static_cast<SharedThreadData*>(args);
|
||||||
|
|
||||||
|
// To prevent focus glitchout, close the overlay immediately when the home button gets pressed
|
||||||
|
Event homeButtonPressEvent = {};
|
||||||
|
hidsysAcquireHomeButtonEventHandle(&homeButtonPressEvent, false);
|
||||||
|
eventClear(&homeButtonPressEvent);
|
||||||
|
hlp::ScopeGuard homeButtonEventGuard([&] { eventClose(&homeButtonPressEvent); });
|
||||||
|
|
||||||
|
// To prevent focus glitchout, close the overlay immediately when the power button gets pressed
|
||||||
|
Event powerButtonPressEvent = {};
|
||||||
|
hidsysAcquireSleepButtonEventHandle(&powerButtonPressEvent, false);
|
||||||
|
eventClear(&powerButtonPressEvent);
|
||||||
|
hlp::ScopeGuard powerButtonEventGuard([&] { eventClose(&powerButtonPressEvent); });
|
||||||
|
|
||||||
// Parse Tesla settings
|
// Parse Tesla settings
|
||||||
impl::parseOverlaySettings();
|
impl::parseOverlaySettings();
|
||||||
|
|
||||||
@@ -3405,8 +3424,20 @@ namespace tsl {
|
|||||||
// Drop all inputs from the previous overlay
|
// Drop all inputs from the previous overlay
|
||||||
padUpdate(&pad);
|
padUpdate(&pad);
|
||||||
|
|
||||||
while (shData->running) {
|
enum WaiterObject {
|
||||||
|
WaiterObject_HomeButton,
|
||||||
|
WaiterObject_PowerButton,
|
||||||
|
|
||||||
|
WaiterObject_Count
|
||||||
|
};
|
||||||
|
|
||||||
|
// Construct waiter
|
||||||
|
Waiter objects[2] = {
|
||||||
|
[WaiterObject_HomeButton] = waiterForEvent(&homeButtonPressEvent),
|
||||||
|
[WaiterObject_PowerButton] = waiterForEvent(&powerButtonPressEvent),
|
||||||
|
};
|
||||||
|
|
||||||
|
while (shData->running) {
|
||||||
// Scan for input changes
|
// Scan for input changes
|
||||||
padUpdate(&pad);
|
padUpdate(&pad);
|
||||||
|
|
||||||
@@ -3436,60 +3467,26 @@ namespace tsl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//20 ms
|
//20 ms
|
||||||
svcSleepThread(20'000'000ul);
|
s32 idx = 0;
|
||||||
}
|
Result rc = waitObjects(&idx, objects, WaiterObject_Count, 20'000'000ul);
|
||||||
}
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Home button detection loop thread
|
|
||||||
* @note This makes sure that focus cannot glitch out when pressing the home button
|
|
||||||
*
|
|
||||||
* @param args Used to pass in a pointer to a \ref SharedThreadData struct
|
|
||||||
*/
|
|
||||||
static void homeButtonDetector(void *args) {
|
|
||||||
SharedThreadData *shData = static_cast<SharedThreadData*>(args);
|
|
||||||
|
|
||||||
// To prevent focus glitchout, close the overlay immediately when the home button gets pressed
|
|
||||||
hidsysAcquireHomeButtonEventHandle(&shData->homeButtonPressEvent, false);
|
|
||||||
eventClear(&shData->homeButtonPressEvent);
|
|
||||||
|
|
||||||
while (shData->running) {
|
|
||||||
if (R_SUCCEEDED(eventWait(&shData->homeButtonPressEvent, 100'000'000))) {
|
|
||||||
eventClear(&shData->homeButtonPressEvent);
|
|
||||||
|
|
||||||
if (shData->overlayOpen) {
|
if (shData->overlayOpen) {
|
||||||
tsl::Overlay::get()->hide();
|
tsl::Overlay::get()->hide();
|
||||||
shData->overlayOpen = false;
|
shData->overlayOpen = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
switch (idx) {
|
||||||
|
case WaiterObject_HomeButton:
|
||||||
/**
|
eventClear(&homeButtonPressEvent);
|
||||||
* @brief Power button detection loop thread
|
break;
|
||||||
* @note This makes sure that focus cannot glitch out when pressing the power button
|
case WaiterObject_PowerButton:
|
||||||
*
|
eventClear(&powerButtonPressEvent);
|
||||||
* @param args Used to pass in a pointer to a \ref SharedThreadData struct
|
break;
|
||||||
*/
|
|
||||||
static void powerButtonDetector(void *args) {
|
|
||||||
SharedThreadData *shData = static_cast<SharedThreadData*>(args);
|
|
||||||
|
|
||||||
// To prevent focus glitchout, close the overlay immediately when the power button gets pressed
|
|
||||||
hidsysAcquireSleepButtonEventHandle(&shData->powerButtonPressEvent, false);
|
|
||||||
eventClear(&shData->powerButtonPressEvent);
|
|
||||||
|
|
||||||
while (shData->running) {
|
|
||||||
if (R_SUCCEEDED(eventWait(&shData->powerButtonPressEvent, 100'000'000))) {
|
|
||||||
eventClear(&shData->powerButtonPressEvent);
|
|
||||||
|
|
||||||
if (shData->overlayOpen) {
|
|
||||||
tsl::Overlay::get()->hide();
|
|
||||||
shData->overlayOpen = false;
|
|
||||||
}
|
}
|
||||||
|
} else if (rc != KERNELRESULT(TimedOut)) {
|
||||||
|
ASSERT_FATAL(rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3542,18 +3539,12 @@ namespace tsl {
|
|||||||
|
|
||||||
shData.running = true;
|
shData.running = true;
|
||||||
|
|
||||||
Thread hidPollerThread, homeButtonDetectorThread, powerButtonDetectorThread;
|
Thread backgroundThread;
|
||||||
threadCreate(&hidPollerThread, impl::hidInputPoller<launchFlags>, &shData, nullptr, 0x1000, 0x10, -2);
|
threadCreate(&backgroundThread, impl::backgroundEventPoller, &shData, nullptr, 0x1000, 0x2c, -2);
|
||||||
threadCreate(&homeButtonDetectorThread, impl::homeButtonDetector, &shData, nullptr, 0x1000, 0x2C, -2);
|
threadStart(&backgroundThread);
|
||||||
threadCreate(&powerButtonDetectorThread, impl::powerButtonDetector, &shData, nullptr, 0x1000, 0x2C, -2);
|
|
||||||
threadStart(&hidPollerThread);
|
|
||||||
threadStart(&homeButtonDetectorThread);
|
|
||||||
threadStart(&powerButtonDetectorThread);
|
|
||||||
|
|
||||||
eventCreate(&shData.comboEvent, false);
|
eventCreate(&shData.comboEvent, false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto& overlay = tsl::Overlay::s_overlayInstance;
|
auto& overlay = tsl::Overlay::s_overlayInstance;
|
||||||
overlay = new TOverlay();
|
overlay = new TOverlay();
|
||||||
overlay->m_closeOnExit = (u8(launchFlags) & u8(impl::LaunchFlags::CloseOnExit)) == u8(impl::LaunchFlags::CloseOnExit);
|
overlay->m_closeOnExit = (u8(launchFlags) & u8(impl::LaunchFlags::CloseOnExit)) == u8(impl::LaunchFlags::CloseOnExit);
|
||||||
@@ -3612,16 +3603,10 @@ namespace tsl {
|
|||||||
eventClear(&shData.comboEvent);
|
eventClear(&shData.comboEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
eventClose(&shData.homeButtonPressEvent);
|
|
||||||
eventClose(&shData.powerButtonPressEvent);
|
|
||||||
eventClose(&shData.comboEvent);
|
eventClose(&shData.comboEvent);
|
||||||
|
|
||||||
threadWaitForExit(&hidPollerThread);
|
threadWaitForExit(&backgroundThread);
|
||||||
threadClose(&hidPollerThread);
|
threadClose(&backgroundThread);
|
||||||
threadWaitForExit(&homeButtonDetectorThread);
|
|
||||||
threadClose(&homeButtonDetectorThread);
|
|
||||||
threadWaitForExit(&powerButtonDetectorThread);
|
|
||||||
threadClose(&powerButtonDetectorThread);
|
|
||||||
|
|
||||||
overlay->exitScreen();
|
overlay->exitScreen();
|
||||||
overlay->exitServices();
|
overlay->exitServices();
|
||||||
|
|||||||
Reference in New Issue
Block a user