Switch status icons
@ -209,7 +209,7 @@ $(BUILD)/%.rgba: $(GRAPHICS)/%.png | $(BUILD)
|
|||||||
@convert $< $@
|
@convert $< $@
|
||||||
|
|
||||||
$(ROMFS_GFX): $(ROMFS)/%.rgba.zst: $(BUILD)/%.rgba
|
$(ROMFS_GFX): $(ROMFS)/%.rgba.zst: $(BUILD)/%.rgba
|
||||||
@zstd $< -o $@ --ultra -22
|
@zstd -f $< -o $@ --ultra -22
|
||||||
|
|
||||||
$(ROMFS_SHADERS)/%_vsh.dksh: %_vsh.glsl
|
$(ROMFS_SHADERS)/%_vsh.dksh: %_vsh.glsl
|
||||||
@echo {vert} $(notdir $<)
|
@echo {vert} $(notdir $<)
|
||||||
|
@ -228,7 +228,8 @@ void drawStatus ()
|
|||||||
auto const uv2 = ImVec2 (battery->right, battery->bottom);
|
auto const uv2 = ImVec2 (battery->right, battery->bottom);
|
||||||
|
|
||||||
// draw battery icon
|
// draw battery icon
|
||||||
ImGui::GetForegroundDrawList ()->AddImage (&s_gfxTexture, p1, p2, uv1, uv2);
|
ImGui::GetForegroundDrawList ()->AddImage (
|
||||||
|
&s_gfxTexture, p1, p2, uv1, uv2, ImGui::GetColorU32 (ImGuiCol_Text));
|
||||||
|
|
||||||
// get wifi strength
|
// get wifi strength
|
||||||
auto const wifiStrength = osGetWifiStrength ();
|
auto const wifiStrength = osGetWifiStrength ();
|
||||||
@ -247,14 +248,15 @@ void drawStatus ()
|
|||||||
auto const uv4 = ImVec2 (wifi->right, wifi->bottom);
|
auto const uv4 = ImVec2 (wifi->right, wifi->bottom);
|
||||||
|
|
||||||
// draw wifi icon
|
// draw wifi icon
|
||||||
ImGui::GetForegroundDrawList ()->AddImage (&s_gfxTexture, p3, p4, uv3, uv4);
|
ImGui::GetForegroundDrawList ()->AddImage (
|
||||||
|
&s_gfxTexture, p3, p4, uv3, uv4, ImGui::GetColorU32 (ImGuiCol_Text));
|
||||||
|
|
||||||
// draw current timestamp
|
// draw current timestamp
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
auto const now = std::time (nullptr);
|
auto const now = std::time (nullptr);
|
||||||
std::strftime (buffer, sizeof (buffer), "%H:%M:%S", std::localtime (&now));
|
std::strftime (buffer, sizeof (buffer), "%H:%M:%S", std::localtime (&now));
|
||||||
ImGui::GetForegroundDrawList ()->AddText (
|
ImGui::GetForegroundDrawList ()->AddText (
|
||||||
ImVec2 (p3.x - 65.0f, style.FramePadding.y), 0xFFFFFFFF, buffer);
|
ImVec2 (p3.x - 65.0f, style.FramePadding.y), ImGui::GetColorU32 (ImGuiCol_Text), buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,12 +81,12 @@ void drawLog ()
|
|||||||
s_messages.erase (begin, end);
|
s_messages.erase (begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImVec4 const s_colors[] = {
|
ImVec4 const s_colors[] = {
|
||||||
[DEBUG] = ImVec4 (1.0f, 1.0f, 0.4f, 1.0f), // yellow
|
[DEBUG] = ImVec4 (1.0f, 1.0f, 0.4f, 1.0f), // yellow
|
||||||
[INFO] = ImVec4 (1.0f, 1.0f, 1.0f, 1.0f), // white
|
[INFO] = ImGui::GetStyleColorVec4 (ImGuiCol_Text), // normal
|
||||||
[ERROR] = ImVec4 (1.0f, 0.4f, 0.4f, 1.0f), // red
|
[ERROR] = ImVec4 (1.0f, 0.4f, 0.4f, 1.0f), // red
|
||||||
[COMMAND] = ImVec4 (0.4f, 1.0f, 0.4f, 1.0f), // green
|
[COMMAND] = ImVec4 (0.4f, 1.0f, 0.4f, 1.0f), // green
|
||||||
[RESPONSE] = ImVec4 (0.4f, 1.0f, 1.0f, 1.0f), // cyan
|
[RESPONSE] = ImVec4 (0.4f, 1.0f, 1.0f, 1.0f), // cyan
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto const &message : s_messages)
|
for (auto const &message : s_messages)
|
||||||
|
@ -56,6 +56,7 @@ void userAppInit ()
|
|||||||
|
|
||||||
romfsInit ();
|
romfsInit ();
|
||||||
plInitialize ();
|
plInitialize ();
|
||||||
|
psmInitialize ();
|
||||||
nifmInitialize (NifmServiceType_User);
|
nifmInitialize (NifmServiceType_User);
|
||||||
|
|
||||||
if (R_FAILED (socketInitialize (&s_socketInitConfig)))
|
if (R_FAILED (socketInitialize (&s_socketInitConfig)))
|
||||||
@ -78,6 +79,7 @@ void userAppExit ()
|
|||||||
|
|
||||||
socketExit ();
|
socketExit ();
|
||||||
nifmExit ();
|
nifmExit ();
|
||||||
|
psmExit ();
|
||||||
plExit ();
|
plExit ();
|
||||||
romfsExit ();
|
romfsExit ();
|
||||||
appletUnlockExit ();
|
appletUnlockExit ();
|
||||||
|
@ -38,19 +38,42 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <numeric>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
/// \brief Texture index
|
||||||
|
enum TextureIndex
|
||||||
|
{
|
||||||
|
DEKO3D_LOGO = 1,
|
||||||
|
BATTERY_ICON,
|
||||||
|
CHARGING_ICON,
|
||||||
|
ETH_NONE_ICON,
|
||||||
|
ETH_ICON,
|
||||||
|
AIRPLANE_ICON,
|
||||||
|
WIFI_NONE_ICON,
|
||||||
|
WIFI1_ICON,
|
||||||
|
WIFI2_ICON,
|
||||||
|
WIFI3_ICON,
|
||||||
|
|
||||||
|
MAX_TEXTURE,
|
||||||
|
};
|
||||||
|
|
||||||
/// \brief deko3d logo width
|
/// \brief deko3d logo width
|
||||||
constexpr auto LOGO_WIDTH = 500;
|
constexpr auto LOGO_WIDTH = 500;
|
||||||
/// \brief deko3d logo height
|
/// \brief deko3d logo height
|
||||||
constexpr auto LOGO_HEIGHT = 493;
|
constexpr auto LOGO_HEIGHT = 493;
|
||||||
|
|
||||||
|
/// \brief icon width
|
||||||
|
constexpr auto ICON_WIDTH = 24;
|
||||||
|
/// \brief icon height
|
||||||
|
constexpr auto ICON_HEIGHT = 24;
|
||||||
|
|
||||||
/// \brief Maximum number of samplers
|
/// \brief Maximum number of samplers
|
||||||
constexpr auto MAX_SAMPLERS = 2;
|
constexpr auto MAX_SAMPLERS = 2;
|
||||||
/// \brief Maximum number of images
|
/// \brief Maximum number of images
|
||||||
constexpr auto MAX_IMAGES = 2;
|
constexpr auto MAX_IMAGES = MAX_TEXTURE;
|
||||||
|
|
||||||
/// \brief Number of framebuffers
|
/// \brief Number of framebuffers
|
||||||
constexpr auto FB_NUM = 2u;
|
constexpr auto FB_NUM = 2u;
|
||||||
@ -163,6 +186,7 @@ void rebuildSwapchain (unsigned const width_, unsigned const height_)
|
|||||||
s_swapchain = dk::SwapchainMaker{s_device, nwindowGetDefault (), swapchainImages}.create ();
|
s_swapchain = dk::SwapchainMaker{s_device, nwindowGetDefault (), swapchainImages}.create ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Initialize deko3d
|
||||||
void deko3dInit ()
|
void deko3dInit ()
|
||||||
{
|
{
|
||||||
// create deko3d device
|
// create deko3d device
|
||||||
@ -217,97 +241,132 @@ void deko3dInit ()
|
|||||||
cmdBuf.clear ();
|
cmdBuf.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadLogo ()
|
/// \brief Load textures
|
||||||
|
void loadTextures ()
|
||||||
{
|
{
|
||||||
// read the deko3d logo
|
struct TextureInfo
|
||||||
auto const path = "romfs:/deko3d.rgba.zst";
|
|
||||||
|
|
||||||
struct stat st;
|
|
||||||
if (stat (path, &st) != 0)
|
|
||||||
{
|
{
|
||||||
std::fprintf (stderr, "stat(%s): %s\n", path, std::strerror (errno));
|
TextureInfo (char const *const path_, unsigned const width_, unsigned const height_)
|
||||||
std::abort ();
|
: path (path_), width (width_), height (height_)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
fs::File fp;
|
char const *const path;
|
||||||
if (!fp.open (path))
|
unsigned width;
|
||||||
{
|
unsigned height;
|
||||||
std::fprintf (stderr, "open(%s): %s\n", path, std::strerror (errno));
|
};
|
||||||
std::abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<char> buffer (st.st_size);
|
TextureInfo textureInfos[] = {TextureInfo ("romfs:/deko3d.rgba.zst", LOGO_WIDTH, LOGO_HEIGHT),
|
||||||
if (!fp.readAll (buffer.data (), st.st_size))
|
TextureInfo ("romfs:/battery_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT),
|
||||||
{
|
TextureInfo ("romfs:/charging_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT),
|
||||||
std::fprintf (stderr, "read(%s): %s\n", path, std::strerror (errno));
|
TextureInfo ("romfs:/eth_none_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT),
|
||||||
std::abort ();
|
TextureInfo ("romfs:/eth_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT),
|
||||||
}
|
TextureInfo ("romfs:/airplane_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT),
|
||||||
|
TextureInfo ("romfs:/wifi_none_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT),
|
||||||
|
TextureInfo ("romfs:/wifi1_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT),
|
||||||
|
TextureInfo ("romfs:/wifi2_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT),
|
||||||
|
TextureInfo ("romfs:/wifi3_icon.rgba.zst", ICON_WIDTH, ICON_HEIGHT)};
|
||||||
|
|
||||||
fp.close ();
|
// create memblock for transfer (large enough for the largest source file)
|
||||||
|
|
||||||
auto const size = ZSTD_getFrameContentSize (buffer.data (), st.st_size);
|
|
||||||
if (ZSTD_isError (size))
|
|
||||||
{
|
|
||||||
std::fprintf (stderr, "ZSTD_getFrameContentSize: %s\n", ZSTD_getErrorName (size));
|
|
||||||
std::abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// create memblock for transfer
|
|
||||||
dk::UniqueMemBlock memBlock =
|
dk::UniqueMemBlock memBlock =
|
||||||
dk::MemBlockMaker{s_device, imgui::deko3d::align (size, DK_MEMBLOCK_ALIGNMENT)}
|
dk::MemBlockMaker{s_device, imgui::deko3d::align (1048576, DK_MEMBLOCK_ALIGNMENT)}
|
||||||
.setFlags (DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached)
|
.setFlags (DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached)
|
||||||
.create ();
|
.create ();
|
||||||
|
|
||||||
// decompress into transfer memblock
|
// create image memblock (large enough to hold all the images)
|
||||||
auto const decoded = ZSTD_decompress (memBlock.getCpuAddr (), size, buffer.data (), st.st_size);
|
|
||||||
if (ZSTD_isError (decoded))
|
|
||||||
{
|
|
||||||
std::fprintf (stderr, "ZSTD_decompress: %s\n", ZSTD_getErrorName (decoded));
|
|
||||||
std::abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize deko3d logo texture image layout
|
|
||||||
dk::ImageLayout layout;
|
|
||||||
dk::ImageLayoutMaker{s_device}
|
|
||||||
.setFlags (0)
|
|
||||||
.setFormat (DkImageFormat_RGBA8_Unorm)
|
|
||||||
.setDimensions (LOGO_WIDTH, LOGO_HEIGHT)
|
|
||||||
.initialize (layout);
|
|
||||||
|
|
||||||
auto const logoAlign = layout.getAlignment ();
|
|
||||||
auto const logoSize = layout.getSize ();
|
|
||||||
|
|
||||||
// create image memblock
|
|
||||||
s_imageMemBlock = dk::MemBlockMaker{s_device,
|
s_imageMemBlock = dk::MemBlockMaker{s_device,
|
||||||
imgui::deko3d::align (logoSize, std::max<unsigned> (logoAlign, DK_MEMBLOCK_ALIGNMENT))}
|
imgui::deko3d::align (1048576 + (MAX_TEXTURE - 2) * 4096, DK_MEMBLOCK_ALIGNMENT)}
|
||||||
.setFlags (DkMemBlockFlags_GpuCached | DkMemBlockFlags_Image)
|
.setFlags (DkMemBlockFlags_GpuCached | DkMemBlockFlags_Image)
|
||||||
.create ();
|
.create ();
|
||||||
|
|
||||||
|
auto &cmdBuf = s_cmdBuf[0];
|
||||||
|
|
||||||
|
unsigned imageIndex = 1;
|
||||||
|
unsigned imageOffset = 0;
|
||||||
|
for (auto const &textureInfo : textureInfos)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (::stat (textureInfo.path, &st) != 0)
|
||||||
|
{
|
||||||
|
std::fprintf (stderr, "stat(%s): %s\n", textureInfo.path, std::strerror (errno));
|
||||||
|
std::abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::File fp;
|
||||||
|
if (!fp.open (textureInfo.path))
|
||||||
|
{
|
||||||
|
std::fprintf (stderr, "open(%s): %s\n", textureInfo.path, std::strerror (errno));
|
||||||
|
std::abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// read file into memory
|
||||||
|
std::vector<char> buffer (st.st_size);
|
||||||
|
if (!fp.readAll (buffer.data (), buffer.size ()))
|
||||||
|
{
|
||||||
|
std::fprintf (stderr, "read(%s): %s\n", textureInfo.path, std::strerror (errno));
|
||||||
|
std::abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get uncompressed size
|
||||||
|
auto const size = ZSTD_getFrameContentSize (buffer.data (), buffer.size ());
|
||||||
|
if (ZSTD_isError (size))
|
||||||
|
{
|
||||||
|
std::fprintf (stderr, "ZSTD_getFrameContentSize: %s\n", ZSTD_getErrorName (size));
|
||||||
|
std::abort ();
|
||||||
|
}
|
||||||
|
assert (size <= memBlock.getSize ());
|
||||||
|
|
||||||
|
// wait for previous transfer to complete
|
||||||
|
s_queue.waitIdle ();
|
||||||
|
|
||||||
|
// decompress into transfer memblock
|
||||||
|
auto const decoded =
|
||||||
|
ZSTD_decompress (memBlock.getCpuAddr (), size, buffer.data (), buffer.size ());
|
||||||
|
if (ZSTD_isError (decoded))
|
||||||
|
{
|
||||||
|
std::fprintf (stderr, "ZSTD_decompress: %s\n", ZSTD_getErrorName (decoded));
|
||||||
|
std::abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize texture image layout
|
||||||
|
dk::ImageLayout layout;
|
||||||
|
dk::ImageLayoutMaker{s_device}
|
||||||
|
.setFlags (0)
|
||||||
|
.setFormat (DkImageFormat_RGBA8_Unorm)
|
||||||
|
.setDimensions (textureInfo.width, textureInfo.height)
|
||||||
|
.initialize (layout);
|
||||||
|
|
||||||
|
// calculate image offset
|
||||||
|
imageOffset = imgui::deko3d::align (imageOffset, layout.getAlignment ());
|
||||||
|
assert (imageOffset < s_imageMemBlock.getSize ());
|
||||||
|
assert (s_imageMemBlock.getSize () - imageOffset >= layout.getSize ());
|
||||||
|
|
||||||
|
// initialize image descriptor
|
||||||
|
dk::Image image;
|
||||||
|
image.initialize (layout, s_imageMemBlock, imageOffset);
|
||||||
|
s_imageDescriptors[imageIndex++].initialize (image);
|
||||||
|
|
||||||
|
// copy texture to image
|
||||||
|
dk::ImageView imageView (image);
|
||||||
|
cmdBuf.copyBufferToImage ({memBlock.getGpuAddr ()},
|
||||||
|
imageView,
|
||||||
|
{0, 0, 0, textureInfo.width, textureInfo.height, 1});
|
||||||
|
s_queue.submitCommands (cmdBuf.finishList ());
|
||||||
|
|
||||||
|
imageOffset += imgui::deko3d::align (layout.getSize (), layout.getAlignment ());
|
||||||
|
}
|
||||||
|
|
||||||
// initialize sampler descriptor
|
// initialize sampler descriptor
|
||||||
s_samplerDescriptors[1].initialize (
|
s_samplerDescriptors[1].initialize (
|
||||||
dk::Sampler{}
|
dk::Sampler{}
|
||||||
.setFilter (DkFilter_Linear, DkFilter_Linear)
|
.setFilter (DkFilter_Linear, DkFilter_Linear)
|
||||||
.setWrapMode (DkWrapMode_ClampToEdge, DkWrapMode_ClampToEdge, DkWrapMode_ClampToEdge));
|
.setWrapMode (DkWrapMode_ClampToEdge, DkWrapMode_ClampToEdge, DkWrapMode_ClampToEdge));
|
||||||
|
|
||||||
// initialize deko3d logo texture image descriptor
|
|
||||||
dk::Image logoTexture;
|
|
||||||
logoTexture.initialize (layout, s_imageMemBlock, 0);
|
|
||||||
s_imageDescriptors[1].initialize (logoTexture);
|
|
||||||
|
|
||||||
auto &cmdBuf = s_cmdBuf[0];
|
|
||||||
|
|
||||||
// copy deko3d logo texture to image view
|
|
||||||
dk::ImageView imageView{logoTexture};
|
|
||||||
cmdBuf.copyBufferToImage (
|
|
||||||
{memBlock.getGpuAddr ()}, imageView, {0, 0, 0, LOGO_WIDTH, LOGO_HEIGHT, 1});
|
|
||||||
|
|
||||||
// submit commands to transfer deko3d logo texture
|
|
||||||
s_queue.submitCommands (cmdBuf.finishList ());
|
|
||||||
|
|
||||||
// wait for commands to complete before releasing memblocks
|
// wait for commands to complete before releasing memblocks
|
||||||
s_queue.waitIdle ();
|
s_queue.waitIdle ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Deinitialize deko3d
|
||||||
void deko3dExit ()
|
void deko3dExit ()
|
||||||
{
|
{
|
||||||
// clean up all of the deko3d objects
|
// clean up all of the deko3d objects
|
||||||
@ -326,6 +385,112 @@ void deko3dExit ()
|
|||||||
s_depthMemBlock = nullptr;
|
s_depthMemBlock = nullptr;
|
||||||
s_device = nullptr;
|
s_device = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Draw time status
|
||||||
|
void drawTimeStatus ()
|
||||||
|
{
|
||||||
|
auto const &io = ImGui::GetIO ();
|
||||||
|
auto const &style = ImGui::GetStyle ();
|
||||||
|
|
||||||
|
// draw current timestamp
|
||||||
|
char buffer[64];
|
||||||
|
auto const now = std::time (nullptr);
|
||||||
|
std::strftime (buffer, sizeof (buffer), "%H:%M:%S", std::localtime (&now));
|
||||||
|
ImGui::GetForegroundDrawList ()->AddText (
|
||||||
|
ImVec2 (io.DisplaySize.x - 240.0f, style.FramePadding.y),
|
||||||
|
ImGui::GetColorU32 (ImGuiCol_Text),
|
||||||
|
buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Draw network status
|
||||||
|
void drawNetworkStatus ()
|
||||||
|
{
|
||||||
|
TextureIndex netIcon = AIRPLANE_ICON;
|
||||||
|
|
||||||
|
NifmInternetConnectionType type;
|
||||||
|
std::uint32_t wifiStrength;
|
||||||
|
NifmInternetConnectionStatus status;
|
||||||
|
if (R_SUCCEEDED (nifmGetInternetConnectionStatus (&type, &wifiStrength, &status)))
|
||||||
|
{
|
||||||
|
if (type == NifmInternetConnectionType_Ethernet)
|
||||||
|
{
|
||||||
|
if (status == NifmInternetConnectionStatus_Connected)
|
||||||
|
netIcon = ETH_ICON;
|
||||||
|
else
|
||||||
|
netIcon = ETH_NONE_ICON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (wifiStrength >= 3)
|
||||||
|
netIcon = WIFI3_ICON;
|
||||||
|
else if (wifiStrength == 2)
|
||||||
|
netIcon = WIFI3_ICON;
|
||||||
|
else if (wifiStrength == 1)
|
||||||
|
netIcon = WIFI3_ICON;
|
||||||
|
else if (wifiStrength == 0)
|
||||||
|
netIcon = WIFI_NONE_ICON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const &io = ImGui::GetIO ();
|
||||||
|
auto const &style = ImGui::GetStyle ();
|
||||||
|
|
||||||
|
auto const x1 = io.DisplaySize.x - ICON_WIDTH - 100.0f;
|
||||||
|
auto const x2 = x1 + ICON_WIDTH;
|
||||||
|
auto const y1 = style.FramePadding.y;
|
||||||
|
auto const y2 = y1 + ICON_HEIGHT;
|
||||||
|
|
||||||
|
ImGui::GetForegroundDrawList ()->AddImage (
|
||||||
|
imgui::deko3d::makeTextureID (dkMakeTextureHandle (netIcon, 1)),
|
||||||
|
ImVec2 (x1, y1),
|
||||||
|
ImVec2 (x2, y2),
|
||||||
|
ImVec2 (0, 0),
|
||||||
|
ImVec2 (1, 1),
|
||||||
|
ImGui::GetColorU32 (ImGuiCol_Text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Draw power status
|
||||||
|
void drawPowerStatus ()
|
||||||
|
{
|
||||||
|
std::uint32_t batteryCharge = 0;
|
||||||
|
psmGetBatteryChargePercentage (&batteryCharge);
|
||||||
|
|
||||||
|
ChargerType charger = ChargerType_None;
|
||||||
|
psmGetChargerType (&charger);
|
||||||
|
|
||||||
|
TextureIndex powerIcon = BATTERY_ICON;
|
||||||
|
if (charger != ChargerType_None)
|
||||||
|
powerIcon = CHARGING_ICON;
|
||||||
|
|
||||||
|
auto const &io = ImGui::GetIO ();
|
||||||
|
auto const &style = ImGui::GetStyle ();
|
||||||
|
|
||||||
|
auto const x1 = io.DisplaySize.x - ICON_WIDTH - style.FramePadding.x;
|
||||||
|
auto const x2 = x1 + ICON_WIDTH;
|
||||||
|
auto const y1 = style.FramePadding.y;
|
||||||
|
auto const y2 = y1 + ICON_HEIGHT;
|
||||||
|
|
||||||
|
ImGui::GetForegroundDrawList ()->AddImage (
|
||||||
|
imgui::deko3d::makeTextureID (dkMakeTextureHandle (powerIcon, 1)),
|
||||||
|
ImVec2 (x1, y1),
|
||||||
|
ImVec2 (x2, y2),
|
||||||
|
ImVec2 (0, 0),
|
||||||
|
ImVec2 (1, 1),
|
||||||
|
ImGui::GetColorU32 (ImGuiCol_Text));
|
||||||
|
|
||||||
|
char buffer[16];
|
||||||
|
std::sprintf (buffer, "%u%%", batteryCharge);
|
||||||
|
ImGui::GetForegroundDrawList ()->AddText (
|
||||||
|
ImVec2 (x1 - 60.0f, y1), ImGui::GetColorU32 (ImGuiCol_Text), buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Draw status
|
||||||
|
void drawStatus ()
|
||||||
|
{
|
||||||
|
drawTimeStatus ();
|
||||||
|
drawNetworkStatus ();
|
||||||
|
drawPowerStatus ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool platform::init ()
|
bool platform::init ()
|
||||||
@ -338,7 +503,7 @@ bool platform::init ()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
deko3dInit ();
|
deko3dInit ();
|
||||||
loadLogo ();
|
loadTextures ();
|
||||||
imgui::deko3d::init (s_device,
|
imgui::deko3d::init (s_device,
|
||||||
s_queue,
|
s_queue,
|
||||||
s_cmdBuf[0],
|
s_cmdBuf[0],
|
||||||
@ -390,6 +555,8 @@ bool platform::loop ()
|
|||||||
ImVec2 (x1, y1),
|
ImVec2 (x1, y1),
|
||||||
ImVec2 (x2, y2));
|
ImVec2 (x2, y2));
|
||||||
|
|
||||||
|
drawStatus ();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
switch/gfx/airplane_icon.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
switch/gfx/battery_icon.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
switch/gfx/charging_icon.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
switch/gfx/eth_icon.png
Normal file
After Width: | Height: | Size: 520 B |
BIN
switch/gfx/eth_none_icon.png
Normal file
After Width: | Height: | Size: 570 B |
BIN
switch/gfx/wifi1_icon.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
switch/gfx/wifi2_icon.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
switch/gfx/wifi3_icon.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
switch/gfx/wifi_none_icon.png
Normal file
After Width: | Height: | Size: 5.6 KiB |