Revert "hoc-clk: add live vdd2, live boost clock and basic pwm dimming"

This reverts commit 15b7df8ef1.
This commit is contained in:
souldbminersmwc
2025-11-09 16:14:52 -05:00
parent 22ec140738
commit 21a3f953d7
3804 changed files with 435 additions and 570162 deletions

View File

@@ -1,158 +0,0 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <switch.h>
#include <string.h>
#include "ams_su.h"
#include "service_guard.h"
static Service g_amssuSrv;
static TransferMemory g_tmem;
NX_GENERATE_SERVICE_GUARD(amssu);
Result _amssuInitialize(void) {
return smGetService(&g_amssuSrv, "ams:su");
}
void _amssuCleanup(void) {
serviceClose(&g_amssuSrv);
tmemClose(&g_tmem);
}
Service *amssuGetServiceSession(void) {
return &g_amssuSrv;
}
Result amssuGetUpdateInformation(AmsSuUpdateInformation *out, const char *path) {
char send_path[FS_MAX_PATH] = {0};
strncpy(send_path, path, FS_MAX_PATH-1);
send_path[FS_MAX_PATH-1] = 0;
return serviceDispatchOut(&g_amssuSrv, 0, *out,
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { send_path, FS_MAX_PATH } },
);
}
Result amssuValidateUpdate(AmsSuUpdateValidationInfo *out, const char *path) {
char send_path[FS_MAX_PATH] = {0};
strncpy(send_path, path, FS_MAX_PATH-1);
send_path[FS_MAX_PATH-1] = 0;
return serviceDispatchOut(&g_amssuSrv, 1, *out,
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { send_path, FS_MAX_PATH } },
);
}
Result amssuSetupUpdate(void *buffer, size_t size, const char *path, bool exfat) {
Result rc = 0;
if (buffer == NULL) {
rc = tmemCreate(&g_tmem, size, Perm_None);
} else {
rc = tmemCreateFromMemory(&g_tmem, buffer, size, Perm_None);
}
if (R_FAILED(rc)) return rc;
char send_path[FS_MAX_PATH] = {0};
strncpy(send_path, path, FS_MAX_PATH-1);
send_path[FS_MAX_PATH-1] = 0;
const struct {
u8 exfat;
u64 size;
} in = { exfat, g_tmem.size };
rc = serviceDispatchIn(&g_amssuSrv, 2, in,
.in_num_handles = 1,
.in_handles = { g_tmem.handle },
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { send_path, FS_MAX_PATH } },
);
if (R_FAILED((rc))) {
tmemClose(&g_tmem);
}
return rc;
}
Result amssuSetupUpdateWithVariation(void *buffer, size_t size, const char *path, bool exfat, u32 variation) {
Result rc = 0;
if (buffer == NULL) {
rc = tmemCreate(&g_tmem, size, Perm_None);
} else {
rc = tmemCreateFromMemory(&g_tmem, buffer, size, Perm_None);
}
if (R_FAILED(rc)) return rc;
char send_path[FS_MAX_PATH] = {0};
strncpy(send_path, path, FS_MAX_PATH-1);
send_path[FS_MAX_PATH-1] = 0;
const struct {
u8 exfat;
u32 variation;
u64 size;
} in = { exfat, variation, g_tmem.size };
rc = serviceDispatchIn(&g_amssuSrv, 3, in,
.in_num_handles = 1,
.in_handles = { g_tmem.handle },
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { send_path, FS_MAX_PATH } },
);
if (R_FAILED((rc))) {
tmemClose(&g_tmem);
}
return rc;
}
Result amssuRequestPrepareUpdate(AsyncResult *a) {
memset(a, 0, sizeof(*a));
Handle event = INVALID_HANDLE;
Result rc = serviceDispatch(&g_amssuSrv, 4,
.out_num_objects = 1,
.out_objects = &a->s,
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
.out_handles = &event,
);
if (R_SUCCEEDED(rc))
eventLoadRemote(&a->event, event, false);
return rc;
}
Result amssuGetPrepareUpdateProgress(NsSystemUpdateProgress *out) {
return serviceDispatchOut(&g_amssuSrv, 5, *out);
}
Result amssuHasPreparedUpdate(bool *out) {
u8 outval = 0;
Result rc = serviceDispatchOut(&g_amssuSrv, 6, outval);
if (R_SUCCEEDED(rc)) {
if (out) *out = outval & 1;
}
return rc;
}
Result amssuApplyPreparedUpdate() {
return serviceDispatch(&g_amssuSrv, 7);
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
u32 version;
bool exfat_supported;
u32 num_firmware_variations;
u32 firmware_variation_ids[16];
} AmsSuUpdateInformation;
typedef struct {
Result result;
Result exfat_result;
NcmContentMetaKey invalid_key;
NcmContentId invalid_content_id;
} AmsSuUpdateValidationInfo;
Result amssuInitialize();
void amssuExit();
Service *amssuGetServiceSession(void);
Result amssuGetUpdateInformation(AmsSuUpdateInformation *out, const char *path);
Result amssuValidateUpdate(AmsSuUpdateValidationInfo *out, const char *path);
Result amssuSetupUpdate(void *buffer, size_t size, const char *path, bool exfat);
Result amssuSetupUpdateWithVariation(void *buffer, size_t size, const char *path, bool exfat, u32 variation);
Result amssuRequestPrepareUpdate(AsyncResult *a);
Result amssuGetPrepareUpdateProgress(NsSystemUpdateProgress *out);
Result amssuHasPreparedUpdate(bool *out);
Result amssuApplyPreparedUpdate();
#ifdef __cplusplus
}
#endif

View File

@@ -1,23 +0,0 @@
/*
* Copyright (c) Adubbz
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstdlib>
#define DBK_ABORT_UNLESS(expr) \
if (!static_cast<bool>(expr)) { \
std::abort(); \
}

View File

@@ -1,272 +0,0 @@
/*
* Copyright (c) Adubbz
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <optional>
#include <switch.h>
#include <nanovg.h>
#include <nanovg_dk.h>
#include <nanovg/framework/CApplication.h>
#include "ui.hpp"
#include "ams_su.h"
extern "C" {
void userAppInit(void) {
Result rc = 0;
if (R_FAILED(rc = romfsInit())) {
fatalThrow(rc);
}
if (R_FAILED(rc = spsmInitialize())) {
fatalThrow(rc);
}
if (R_FAILED(rc = plInitialize(PlServiceType_User))) {
fatalThrow(rc);
}
if (R_FAILED(rc = splInitialize())) {
fatalThrow(rc);
}
if (R_FAILED(rc = nsInitialize())) {
fatalThrow(rc);
}
if (R_FAILED(rc = hiddbgInitialize())) {
fatalThrow(rc);
}
}
void userAppExit(void) {
hiddbgExit();
nsExit();
splExit();
plExit();
spsmExit();
romfsExit();
amssuExit();
}
}
namespace {
static constexpr u32 FramebufferWidth = 1280;
static constexpr u32 FramebufferHeight = 720;
}
class Daybreak : public CApplication {
private:
static constexpr unsigned NumFramebuffers = 2;
static constexpr unsigned StaticCmdSize = 0x1000;
dk::UniqueDevice m_device;
dk::UniqueQueue m_queue;
dk::UniqueSwapchain m_swapchain;
std::optional<CMemPool> m_pool_images;
std::optional<CMemPool> m_pool_code;
std::optional<CMemPool> m_pool_data;
dk::UniqueCmdBuf m_cmd_buf;
DkCmdList m_render_cmdlist;
dk::Image m_depth_buffer;
CMemPool::Handle m_depth_buffer_mem;
dk::Image m_framebuffers[NumFramebuffers];
CMemPool::Handle m_framebuffers_mem[NumFramebuffers];
DkCmdList m_framebuffer_cmdlists[NumFramebuffers];
std::optional<nvg::DkRenderer> m_renderer;
NVGcontext *m_vg;
int m_standard_font;
public:
Daybreak() {
Result rc = 0;
/* Create the deko3d device. */
m_device = dk::DeviceMaker{}.create();
/* Create the main queue. */
m_queue = dk::QueueMaker{m_device}.setFlags(DkQueueFlags_Graphics).create();
/* Create the memory pools. */
m_pool_images.emplace(m_device, DkMemBlockFlags_GpuCached | DkMemBlockFlags_Image, 16*1024*1024);
m_pool_code.emplace(m_device, DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached | DkMemBlockFlags_Code, 128*1024);
m_pool_data.emplace(m_device, DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached, 1*1024*1024);
/* Create the static command buffer and feed it freshly allocated memory. */
m_cmd_buf = dk::CmdBufMaker{m_device}.create();
CMemPool::Handle cmdmem = m_pool_data->allocate(StaticCmdSize);
m_cmd_buf.addMemory(cmdmem.getMemBlock(), cmdmem.getOffset(), cmdmem.getSize());
/* Create the framebuffer resources. */
this->CreateFramebufferResources();
m_renderer.emplace(FramebufferWidth, FramebufferHeight, m_device, m_queue, *m_pool_images, *m_pool_code, *m_pool_data);
m_vg = nvgCreateDk(&*m_renderer, NVG_ANTIALIAS | NVG_STENCIL_STROKES);
PlFontData font;
if (R_FAILED(rc = plGetSharedFontByType(&font, PlSharedFontType_Standard))) {
fatalThrow(rc);
}
m_standard_font = nvgCreateFontMem(m_vg, "switch-standard", static_cast<u8 *>(font.address), font.size, 0);
}
~Daybreak() {
/* Destroy the framebuffer resources. This should be done first. */
this->DestroyFramebufferResources();
/* Cleanup vg. */
nvgDeleteDk(m_vg);
/* Destroy the renderer. */
m_renderer.reset();
}
private:
void CreateFramebufferResources() {
/* Create layout for the depth buffer. */
dk::ImageLayout layout_depth_buffer;
dk::ImageLayoutMaker{m_device}
.setFlags(DkImageFlags_UsageRender | DkImageFlags_HwCompression)
.setFormat(DkImageFormat_S8)
.setDimensions(FramebufferWidth, FramebufferHeight)
.initialize(layout_depth_buffer);
/* Create the depth buffer. */
m_depth_buffer_mem = m_pool_images->allocate(layout_depth_buffer.getSize(), layout_depth_buffer.getAlignment());
m_depth_buffer.initialize(layout_depth_buffer, m_depth_buffer_mem.getMemBlock(), m_depth_buffer_mem.getOffset());
/* Create layout for the framebuffers. */
dk::ImageLayout layout_framebuffer;
dk::ImageLayoutMaker{m_device}
.setFlags(DkImageFlags_UsageRender | DkImageFlags_UsagePresent | DkImageFlags_HwCompression)
.setFormat(DkImageFormat_RGBA8_Unorm)
.setDimensions(FramebufferWidth, FramebufferHeight)
.initialize(layout_framebuffer);
/* Create the framebuffers. */
std::array<DkImage const*, NumFramebuffers> fb_array;
const u64 fb_size = layout_framebuffer.getSize();
const u32 fb_align = layout_framebuffer.getAlignment();
for (unsigned int i = 0; i < NumFramebuffers; i++) {
/* Allocate a framebuffer. */
m_framebuffers_mem[i] = m_pool_images->allocate(fb_size, fb_align);
m_framebuffers[i].initialize(layout_framebuffer, m_framebuffers_mem[i].getMemBlock(), m_framebuffers_mem[i].getOffset());
/* Generate a command list that binds it. */
dk::ImageView color_target{ m_framebuffers[i] }, depth_target{ m_depth_buffer };
m_cmd_buf.bindRenderTargets(&color_target, &depth_target);
m_framebuffer_cmdlists[i] = m_cmd_buf.finishList();
/* Fill in the array for use later by the swapchain creation code. */
fb_array[i] = &m_framebuffers[i];
}
/* Create the swapchain using the framebuffers. */
m_swapchain = dk::SwapchainMaker{m_device, nwindowGetDefault(), fb_array}.create();
/* Generate the main rendering cmdlist. */
this->RecordStaticCommands();
}
void DestroyFramebufferResources() {
/* Return early if we have nothing to destroy. */
if (!m_swapchain) return;
/* Make sure the queue is idle before destroying anything. */
m_queue.waitIdle();
/* Clear the static cmdbuf, destroying the static cmdlists in the process. */
m_cmd_buf.clear();
/* Destroy the swapchain. */
m_swapchain.destroy();
/* Destroy the framebuffers. */
for (unsigned int i = 0; i < NumFramebuffers; i ++) {
m_framebuffers_mem[i].destroy();
}
/* Destroy the depth buffer. */
m_depth_buffer_mem.destroy();
}
void RecordStaticCommands() {
/* Initialize state structs with deko3d defaults. */
dk::RasterizerState rasterizer_state;
dk::ColorState color_state;
dk::ColorWriteState color_write_state;
/* Configure the viewport and scissor. */
m_cmd_buf.setViewports(0, { { 0.0f, 0.0f, FramebufferWidth, FramebufferHeight, 0.0f, 1.0f } });
m_cmd_buf.setScissors(0, { { 0, 0, FramebufferWidth, FramebufferHeight } });
/* Clear the color and depth buffers. */
m_cmd_buf.clearColor(0, DkColorMask_RGBA, 0.f, 0.f, 0.f, 1.0f);
m_cmd_buf.clearDepthStencil(true, 1.0f, 0xFF, 0);
/* Bind required state. */
m_cmd_buf.bindRasterizerState(rasterizer_state);
m_cmd_buf.bindColorState(color_state);
m_cmd_buf.bindColorWriteState(color_write_state);
m_render_cmdlist = m_cmd_buf.finishList();
}
void Render(u64 ns) {
/* Acquire a framebuffer from the swapchain (and wait for it to be available). */
int slot = m_queue.acquireImage(m_swapchain);
/* Run the command list that attaches said framebuffer to the queue. */
m_queue.submitCommands(m_framebuffer_cmdlists[slot]);
/* Run the main rendering command list. */
m_queue.submitCommands(m_render_cmdlist);
nvgBeginFrame(m_vg, FramebufferWidth, FramebufferHeight, 1.0f);
dbk::RenderMenu(m_vg, ns);
nvgEndFrame(m_vg);
/* Now that we are done rendering, present it to the screen. */
m_queue.presentImage(m_swapchain, slot);
}
public:
bool onFrame(u64 ns) override {
dbk::UpdateMenu(ns);
this->Render(ns);
return !dbk::IsExitRequested();
}
};
int main(int argc, char **argv) {
/* Initialize the menu. */
if (argc > 1)
dbk::InitializeMenu(FramebufferWidth, FramebufferHeight, argv[1]);
else
dbk::InitializeMenu(FramebufferWidth, FramebufferHeight);
Daybreak daybreak;
daybreak.run();
return 0;
}

View File

@@ -1,56 +0,0 @@
#pragma once
#include <switch/types.h>
#include <switch/result.h>
#include <switch/kernel/mutex.h>
#include <switch/sf/service.h>
#include <switch/services/sm.h>
typedef struct ServiceGuard {
Mutex mutex;
u32 refCount;
} ServiceGuard;
NX_INLINE bool serviceGuardBeginInit(ServiceGuard* g)
{
mutexLock(&g->mutex);
return (g->refCount++) == 0;
}
NX_INLINE Result serviceGuardEndInit(ServiceGuard* g, Result rc, void (*cleanupFunc)(void))
{
if (R_FAILED(rc)) {
cleanupFunc();
--g->refCount;
}
mutexUnlock(&g->mutex);
return rc;
}
NX_INLINE void serviceGuardExit(ServiceGuard* g, void (*cleanupFunc)(void))
{
mutexLock(&g->mutex);
if (g->refCount && (--g->refCount) == 0)
cleanupFunc();
mutexUnlock(&g->mutex);
}
#define NX_GENERATE_SERVICE_GUARD_PARAMS(name, _paramdecl, _parampass) \
\
static ServiceGuard g_##name##Guard; \
NX_INLINE Result _##name##Initialize _paramdecl; \
static void _##name##Cleanup(void); \
\
Result name##Initialize _paramdecl \
{ \
Result rc = 0; \
if (serviceGuardBeginInit(&g_##name##Guard)) \
rc = _##name##Initialize _parampass; \
return serviceGuardEndInit(&g_##name##Guard, rc, _##name##Cleanup); \
} \
\
void name##Exit(void) \
{ \
serviceGuardExit(&g_##name##Guard, _##name##Cleanup); \
}
#define NX_GENERATE_SERVICE_GUARD(name) NX_GENERATE_SERVICE_GUARD_PARAMS(name, (void), ())

File diff suppressed because it is too large Load Diff

View File

@@ -1,272 +0,0 @@
/*
* Copyright (c) Adubbz
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <array>
#include <memory>
#include <vector>
#include <optional>
#include <nanovg.h>
#include <switch.h>
#include "ams_su.h"
namespace dbk {
struct Button {
static constexpr u32 InvalidButtonId = -1;
u32 id;
bool selected;
bool enabled;
char text[256];
float x;
float y;
float w;
float h;
inline bool IsPositionInBounds(float x, float y) {
return x >= this->x && y >= this->y && x < (this->x + this->w) && y < (this->y + this->h);
}
};
enum class Direction {
Up,
Down,
Left,
Right,
Invalid,
};
class Menu {
protected:
static constexpr size_t MaxButtons = 32;
static constexpr size_t LogBufferSize = 0x1000;
protected:
std::array<std::optional<Button>, MaxButtons> m_buttons;
const std::shared_ptr<Menu> m_prev_menu;
char m_log_buffer[LogBufferSize];
protected:
void AddButton(u32 id, const char *text, float x, float y, float w, float h);
void SetButtonSelected(u32 id, bool selected);
void DeselectAllButtons();
void SetButtonEnabled(u32 id, bool enabled);
Button *GetButton(u32 id);
Button *GetSelectedButton();
Button *GetClosestButtonToSelection(Direction direction);
Button *GetTouchedButton();
Button *GetActivatedButton();
void UpdateButtons();
void DrawButtons(NVGcontext *vg, u64 ns);
void LogText(const char *format, ...);
public:
Menu(std::shared_ptr<Menu> prev_menu) : m_buttons({}), m_prev_menu(prev_menu), m_log_buffer{} { /* ... */ }
std::shared_ptr<Menu> GetPrevMenu();
virtual void Update(u64 ns) = 0;
virtual void Draw(NVGcontext *vg, u64 ns) = 0;
};
class AlertMenu : public Menu {
protected:
static constexpr float WindowWidth = 600.0f;
static constexpr float WindowHeight = 214.0f;
static constexpr float TitleGap = 90.0f;
static constexpr float SubTextHeight = 24.0f;
protected:
char m_text[0x100];
char m_subtext[0x100];
char m_result_text[0x20];
Result m_rc;
public:
AlertMenu(std::shared_ptr<Menu> prev_menu, const char *text, const char *subtext, Result rc = 0);
virtual void Draw(NVGcontext *vg, u64 ns) override;
};
class ErrorMenu : public AlertMenu {
private:
static constexpr u32 ExitButtonId = 0;
public:
ErrorMenu(const char *text, const char *subtext, Result rc = 0);
virtual void Update(u64 ns) override;
};
class WarningMenu : public AlertMenu {
private:
static constexpr u32 BackButtonId = 0;
static constexpr u32 ContinueButtonId = 1;
private:
const std::shared_ptr<Menu> m_next_menu;
public:
WarningMenu(std::shared_ptr<Menu> prev_menu, std::shared_ptr<Menu> next_menu, const char *text, const char *subtext, Result rc = 0);
virtual void Update(u64 ns) override;
};
class MainMenu : public Menu {
private:
static constexpr u32 InstallButtonId = 0;
static constexpr u32 ExitButtonId = 1;
static constexpr float WindowWidth = 400.0f;
static constexpr float WindowHeight = 240.0f;
static constexpr float TitleGap = 90.0f;
public:
MainMenu();
virtual void Update(u64 ns) override;
virtual void Draw(NVGcontext *vg, u64 ns) override;
};
class FileMenu : public Menu {
private:
struct FileEntry {
char name[FS_MAX_PATH];
};
private:
static constexpr size_t MaxFileRows = 11;
static constexpr float WindowWidth = 1200.0f;
static constexpr float WindowHeight = 680.0f;
static constexpr float TitleGap = 90.0f;
static constexpr float TextBackgroundOffset = 20.0f;
static constexpr float FileRowHeight = 40.0f;
static constexpr float FileRowGap = 10.0f;
static constexpr float FileRowHorizontalInset = 10.0f;
static constexpr float FileListHeight = MaxFileRows * (FileRowHeight + FileRowGap);
private:
char m_root[FS_MAX_PATH];
std::vector<FileEntry> m_file_entries;
u32 m_current_index;
float m_scroll_offset;
float m_touch_start_scroll_offset;
bool m_touch_finalize_selection;
Result PopulateFileEntries();
bool IsSelectionVisible();
void ScrollToSelection();
bool IsEntryTouched(u32 i);
void UpdateTouches();
void FinalizeSelection();
public:
FileMenu(std::shared_ptr<Menu> prev_menu, const char *root);
virtual void Update(u64 ns) override;
virtual void Draw(NVGcontext *vg, u64 ns) override;
};
class ValidateUpdateMenu : public Menu {
private:
static constexpr u32 BackButtonId = 0;
static constexpr u32 ContinueButtonId = 1;
static constexpr float WindowWidth = 600.0f;
static constexpr float WindowHeight = 600.0f;
static constexpr float TitleGap = 90.0f;
static constexpr float TextAreaHeight = 410.0f;
private:
AmsSuUpdateInformation m_update_info;
AmsSuUpdateValidationInfo m_validation_info;
bool m_has_drawn;
bool m_has_info;
bool m_has_validated;
Result GetUpdateInformation();
void ValidateUpdate();
public:
ValidateUpdateMenu(std::shared_ptr<Menu> prev_menu);
virtual void Update(u64 ns) override;
virtual void Draw(NVGcontext *vg, u64 ns) override;
};
class ChooseResetMenu : public Menu {
private:
static constexpr u32 ResetToFactorySettingsButtonId = 0;
static constexpr u32 PreserveSettingsButtonId = 1;
static constexpr float WindowWidth = 600.0f;
static constexpr float WindowHeight = 170.0f;
static constexpr float TitleGap = 90.0f;
public:
ChooseResetMenu(std::shared_ptr<Menu> prev_menu);
virtual void Update(u64 ns) override;
virtual void Draw(NVGcontext *vg, u64 ns) override;
};
class ChooseExfatMenu : public Menu {
private:
static constexpr u32 Fat32ButtonId = 0;
static constexpr u32 ExFatButtonId = 1;
static constexpr float WindowWidth = 600.0f;
static constexpr float WindowHeight = 170.0f;
static constexpr float TitleGap = 90.0f;
public:
ChooseExfatMenu(std::shared_ptr<Menu> prev_menu);
virtual void Update(u64 ns) override;
virtual void Draw(NVGcontext *vg, u64 ns) override;
};
class InstallUpdateMenu : public Menu {
private:
enum class InstallState {
NeedsDraw,
NeedsSetup,
NeedsPrepare,
AwaitingPrepare,
NeedsApply,
AwaitingReboot,
};
private:
static constexpr u32 ShutdownButtonId = 0;
static constexpr u32 RebootButtonId = 1;
static constexpr float WindowWidth = 600.0f;
static constexpr float WindowHeight = 600.0f;
static constexpr float TitleGap = 120.0f;
static constexpr float ProgressTextHeight = 20.0f;
static constexpr float ProgressBarHeight = 30.0f;
static constexpr float TextAreaHeight = 320.0f;
static constexpr size_t UpdateTaskBufferSize = 0x100000;
private:
InstallState m_install_state;
AsyncResult m_prepare_result;
float m_progress_percent;
void MarkForReboot();
Result TransitionUpdateState();
public:
InstallUpdateMenu(std::shared_ptr<Menu> prev_menu);
virtual void Update(u64 ns) override;
virtual void Draw(NVGcontext *vg, u64 ns) override;
};
bool InitializeMenu(u32 screen_width, u32 screen_height);
bool InitializeMenu(u32 screen_width, u32 screen_height, const char *update_path);
void UpdateMenu(u64 ns);
void RenderMenu(NVGcontext *vg, u64 ns);
bool IsExitRequested();
}

View File

@@ -1,204 +0,0 @@
/*
* Copyright (c) Adubbz
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ui_util.hpp"
#include <cstdio>
#include <math.h>
#include <cstring>
namespace dbk {
namespace {
constexpr const char *SwitchStandardFont = "switch-standard";
constexpr float WindowCornerRadius = 20.0f;
constexpr float TextAreaCornerRadius = 10.0f;
constexpr float ButtonCornerRaidus = 3.0f;
NVGcolor GetSelectionRGB2(u64 ns) {
/* Calculate the rgb values for the breathing colour effect. */
const double t = static_cast<double>(ns) / 1'000'000'000.0d;
const float d = -0.5 * cos(3.0f*t) + 0.5f;
const int r2 = 83 + (float)(128 - 83) * (d * 0.7f + 0.3f);
const int g2 = 71 + (float)(126 - 71) * (d * 0.7f + 0.3f);
const int b2 = 185 + (float)(230 - 185) * (d * 0.7f + 0.3f);
return nvgRGB(r2, g2, b2);
}
}
void DrawStar(NVGcontext *vg, float x, float y, float width) {
nvgBeginPath(vg);
nvgEllipse(vg, x, y, width, width * 3.0f);
nvgEllipse(vg, x, y, width * 3.0f, width);
nvgFillColor(vg, nvgRGB(65, 71, 115));
nvgFill(vg);
}
void DrawBackground(NVGcontext *vg, float w, float h) {
/* Draw the background gradient. */
const NVGpaint bg_paint = nvgLinearGradient(vg, w / 2.0f, 0, w / 2.0f, h + 20.0f, nvgRGB(20, 24, 50), nvgRGB(46, 57, 127));
nvgBeginPath(vg);
nvgRect(vg, 0, 0, w, h);
nvgFillPaint(vg, bg_paint);
nvgFill(vg);
}
void DrawWindow(NVGcontext *vg, const char *title, float x, float y, float w, float h) {
/* Draw the window background. */
const NVGpaint window_bg_paint = nvgLinearGradient(vg, x + w / 2.0f, y, x + w / 2.0f, y + h + h / 4.0f, nvgRGB(255, 255, 255), nvgRGB(188, 214, 234));
nvgBeginPath(vg);
nvgRoundedRect(vg, x, y, w, h, WindowCornerRadius);
nvgFillPaint(vg, window_bg_paint);
nvgFill(vg);
/* Draw the shadow surrounding the window. */
NVGpaint shadowPaint = nvgBoxGradient(vg, x, y + 2, w, h, WindowCornerRadius * 2, 10, nvgRGBA(0, 0, 0, 128), nvgRGBA(0, 0, 0, 0));
nvgBeginPath(vg);
nvgRect(vg, x - 10, y - 10, w + 20, h + 30);
nvgRoundedRect(vg, x, y, w, h, WindowCornerRadius);
nvgPathWinding(vg, NVG_HOLE);
nvgFillPaint(vg, shadowPaint);
nvgFill(vg);
/* Setup the font. */
nvgFontSize(vg, std::min(32.0f, -(strlen(title)*0.5f) + 47.0f));
nvgFontFace(vg, SwitchStandardFont);
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
nvgFillColor(vg, nvgRGB(0, 0, 0));
/* Draw the title. */
const float tw = nvgTextBounds(vg, 0, 0, title, nullptr, nullptr);
nvgText(vg, x + w * 0.5f - tw * 0.5f, y + 40.0f, title, nullptr);
}
void DrawButton(NVGcontext *vg, const char *text, float x, float y, float w, float h, ButtonStyle style, u64 ns) {
/* Fill the background if selected. */
if (style == ButtonStyle::StandardSelected || style == ButtonStyle::FileSelectSelected) {
NVGpaint bg_paint = nvgLinearGradient(vg, x, y + h / 2.0f, x + w, y + h / 2.0f, nvgRGB(83, 71, 185), GetSelectionRGB2(ns));
nvgBeginPath(vg);
nvgRoundedRect(vg, x, y, w, h, ButtonCornerRaidus);
nvgFillPaint(vg, bg_paint);
nvgFill(vg);
}
/* Draw the shadow surrounding the button. */
if (style == ButtonStyle::Standard || style == ButtonStyle::StandardSelected || style == ButtonStyle::StandardDisabled || style == ButtonStyle::FileSelectSelected) {
const unsigned char shadow_color = style == ButtonStyle::Standard ? 128 : 64;
NVGpaint shadow_paint = nvgBoxGradient(vg, x, y, w, h, ButtonCornerRaidus, 5, nvgRGBA(0, 0, 0, shadow_color), nvgRGBA(0, 0, 0, 0));
nvgBeginPath(vg);
nvgRect(vg, x - 10, y - 10, w + 20, h + 30);
nvgRoundedRect(vg, x, y, w, h, ButtonCornerRaidus);
nvgPathWinding(vg, NVG_HOLE);
nvgFillPaint(vg, shadow_paint);
nvgFill(vg);
}
/* Setup the font. */
nvgFontSize(vg, 20.0f);
nvgFontFace(vg, SwitchStandardFont);
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
/* Set the text colour. */
if (style == ButtonStyle::StandardSelected || style == ButtonStyle::FileSelectSelected) {
nvgFillColor(vg, nvgRGB(255, 255, 255));
} else {
const unsigned char alpha = style == ButtonStyle::StandardDisabled ? 64 : 255;
nvgFillColor(vg, nvgRGBA(0, 0, 0, alpha));
}
/* Draw the button text. */
const float tw = nvgTextBounds(vg, 0, 0, text, nullptr, nullptr);
if (style == ButtonStyle::Standard || style == ButtonStyle::StandardSelected || style == ButtonStyle::StandardDisabled) {
nvgText(vg, x + w * 0.5f - tw * 0.5f, y + h * 0.5f, text, nullptr);
} else {
nvgText(vg, x + 10.0f, y + h * 0.5f, text, nullptr);
}
}
void DrawTextBackground(NVGcontext *vg, float x, float y, float w, float h) {
nvgBeginPath(vg);
nvgRoundedRect(vg, x, y, w, h, TextAreaCornerRadius);
nvgFillColor(vg, nvgRGBA(0, 0, 0, 16));
nvgFill(vg);
}
void DrawText(NVGcontext *vg, float x, float y, float w, const char *text) {
nvgFontSize(vg, 20.0f);
nvgFontFace(vg, SwitchStandardFont);
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
nvgFillColor(vg, nvgRGB(0, 0, 0));
const float tw = nvgTextBounds(vg, 0, 0, text, nullptr, nullptr);
nvgText(vg, x + w * 0.5f - tw * 0.5f, y, text, nullptr);
}
void DrawProgressText(NVGcontext *vg, float x, float y, float progress) {
char progress_text[32] = {};
snprintf(progress_text, sizeof(progress_text)-1, "%d%% complete", static_cast<int>(progress * 100.0f));
nvgFontSize(vg, 24.0f);
nvgFontFace(vg, SwitchStandardFont);
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
nvgFillColor(vg, nvgRGB(0, 0, 0));
nvgText(vg, x, y, progress_text, nullptr);
}
void DrawProgressBar(NVGcontext *vg, float x, float y, float w, float h, float progress) {
/* Draw the progress bar background. */
nvgBeginPath(vg);
nvgRoundedRect(vg, x, y, w, h, WindowCornerRadius);
nvgFillColor(vg, nvgRGBA(0, 0, 0, 128));
nvgFill(vg);
/* Draw the progress bar fill. */
if (progress > 0.0f) {
NVGpaint progress_fill_paint = nvgLinearGradient(vg, x, y + 0.5f * h, x + w, y + 0.5f * h, nvgRGB(83, 71, 185), nvgRGB(128, 126, 230));
nvgBeginPath(vg);
nvgRoundedRect(vg, x, y, WindowCornerRadius + (w - WindowCornerRadius) * progress, h, WindowCornerRadius);
nvgFillPaint(vg, progress_fill_paint);
nvgFill(vg);
}
}
void DrawTextBlock(NVGcontext *vg, const char *text, float x, float y, float w, float h) {
/* Save state and scissor. */
nvgSave(vg);
nvgScissor(vg, x, y, w, h);
/* Configure the text. */
nvgFontSize(vg, 18.0f);
nvgFontFace(vg, SwitchStandardFont);
nvgTextLineHeight(vg, 1.3f);
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
nvgFillColor(vg, nvgRGB(0, 0, 0));
/* Determine the bounds of the text box. */
float bounds[4];
nvgTextBoxBounds(vg, 0, 0, w, text, nullptr, bounds);
/* Adjust the y to only show the last part of the text that fits. */
float y_adjustment = 0.0f;
if (bounds[3] > h) {
y_adjustment = bounds[3] - h;
}
/* Draw the text box and restore state. */
nvgTextBox(vg, x, y - y_adjustment, w, text, nullptr);
nvgRestore(vg);
}
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright (c) Adubbz
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <nanovg.h>
#include <switch.h>
namespace dbk {
enum class ButtonStyle {
Standard,
StandardSelected,
StandardDisabled,
FileSelect,
FileSelectSelected,
};
void DrawStar(NVGcontext *vg, float x, float y, float width);
void DrawBackground(NVGcontext *vg, float w, float h);
void DrawWindow(NVGcontext *vg, const char *title, float x, float y, float w, float h);
void DrawButton(NVGcontext *vg, const char *text, float x, float y, float w, float h, ButtonStyle style, u64 ns);
void DrawTextBackground(NVGcontext *vg, float x, float y, float w, float h);
void DrawText(NVGcontext *vg, float x, float y, float w, const char *text);
void DrawProgressText(NVGcontext *vg, float x, float y, float progress);
void DrawProgressBar(NVGcontext *vg, float x, float y, float w, float h, float progress);
void DrawTextBlock(NVGcontext *vg, const char *text, float x, float y, float w, float h);
}