1.5.1
This commit is contained in:
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019-2020 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "about_tab.h"
|
||||
|
||||
#include "logo.h"
|
||||
#include "ipc/ipc.h"
|
||||
#include "ipc/client.h"
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
AboutTab::AboutTab()
|
||||
{
|
||||
this->addView(new Logo(LogoStyle::ABOUT));
|
||||
|
||||
// Subtitle
|
||||
brls::Label *subTitle = new brls::Label(
|
||||
brls::LabelStyle::REGULAR,
|
||||
"This is a modified version of official sys-clk, which is not associated with any author below.\n" \
|
||||
"Nintendo Switch overclocking / underclocking system module and frontend app by the RetroNX Team.\n",
|
||||
true
|
||||
);
|
||||
subTitle->setHorizontalAlign(NVG_ALIGN_CENTER);
|
||||
this->addView(subTitle);
|
||||
|
||||
// Copyright
|
||||
brls::Label *copyright = new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"System module licensed under the Beerware license\n" \
|
||||
"Frontend app licensed under GPL-3.0\n" \
|
||||
"\u00A9 2019 - 2020 natinusala, p-sam, m4xw",
|
||||
true
|
||||
);
|
||||
copyright->setHorizontalAlign(NVG_ALIGN_CENTER);
|
||||
this->addView(copyright);
|
||||
|
||||
// Links
|
||||
this->addView(new brls::Header("Links and Resources"));
|
||||
brls::Label *links = new brls::Label(
|
||||
brls::LabelStyle::SMALL,
|
||||
"\uE016 User guide and code source can be found on our GitHub repository\n" \
|
||||
"\uE016 The sys-clk manager is powered by Borealis, an hardware accelerated UI library\n" \
|
||||
"\uE016 Join the RetroNX Discord server for support, to request features or just hang out!",
|
||||
true
|
||||
);
|
||||
this->addView(links);
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019-2020 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
class AboutTab : public brls::List
|
||||
{
|
||||
public:
|
||||
AboutTab();
|
||||
|
||||
View* getDefaultFocus() override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
@@ -1,192 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "advanced_settings_tab.h"
|
||||
|
||||
#include "app_profile_frame.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <sysclk/clocks.h>
|
||||
|
||||
AdvancedSettingsTab::AdvancedSettingsTab()
|
||||
{
|
||||
// Get context
|
||||
SysClkContext context;
|
||||
Result rc = sysclkIpcGetCurrentContext(&context);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
brls::Logger::error("Unable to get context");
|
||||
errorResult("sysclkIpcGetCurrentContext", rc);
|
||||
brls::Application::crash("Could not get the current sys-clk context, please check that it is correctly installed and enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create UI
|
||||
|
||||
// Disclaimer
|
||||
this->addView(new brls::Label(brls::LabelStyle::REGULAR, "\uE140 Please only alter these settings if you know what you are doing.", true));
|
||||
|
||||
// Temporary overrides
|
||||
this->addView(new brls::Header("Temporary overrides"));
|
||||
|
||||
// CPU
|
||||
brls::SelectListItem *cpuFreqListItem = createFreqListItem(SysClkModule_CPU, context.overrideFreqs[SysClkModule_CPU] / 1000000);
|
||||
cpuFreqListItem->getValueSelectedEvent()->subscribe([](int result){
|
||||
Result rc = result == 0 ?
|
||||
sysclkIpcRemoveOverride(SysClkModule_CPU) :
|
||||
sysclkIpcSetOverride(SysClkModule_CPU, g_freq_table_cpu_hz[result - 1]);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
brls::Logger::error("Unable to update CPU Override");
|
||||
errorResult(result == 0 ? "sysclkIpcRemoveOverride" : "sysclkIpcSetOverride", rc);
|
||||
// TODO: Reset selected value
|
||||
}
|
||||
});
|
||||
|
||||
// GPU
|
||||
brls::SelectListItem *gpuFreqListItem = createFreqListItem(SysClkModule_GPU, context.overrideFreqs[SysClkModule_GPU] / 1000000);
|
||||
gpuFreqListItem->getValueSelectedEvent()->subscribe([](int result){
|
||||
Result rc = result == 0 ?
|
||||
sysclkIpcRemoveOverride(SysClkModule_GPU) :
|
||||
sysclkIpcSetOverride(SysClkModule_GPU, g_freq_table_gpu_hz[result - 1]);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
brls::Logger::error("Unable to update GPU Override");
|
||||
errorResult(result == 0 ? "sysclkIpcRemoveOverride" : "sysclkIpcSetOverride", rc);
|
||||
// TODO: Reset selected value
|
||||
}
|
||||
});
|
||||
|
||||
// MEM
|
||||
brls::SelectListItem *memFreqListItem = createFreqListItem(SysClkModule_MEM, context.overrideFreqs[SysClkModule_MEM] / 1000000);
|
||||
memFreqListItem->getValueSelectedEvent()->subscribe([](int result)
|
||||
{
|
||||
Result rc = result == 0 ?
|
||||
sysclkIpcRemoveOverride(SysClkModule_MEM) :
|
||||
sysclkIpcSetOverride(SysClkModule_MEM, g_freq_table_mem_hz[result - 1]);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
brls::Logger::error("Unable to update MEM Override");
|
||||
errorResult(result == 0 ? "sysclkIpcRemoveOverride" : "sysclkIpcSetOverride", rc);
|
||||
// TODO: Reset selected value
|
||||
}
|
||||
});
|
||||
|
||||
this->addView(cpuFreqListItem);
|
||||
this->addView(gpuFreqListItem);
|
||||
this->addView(memFreqListItem);
|
||||
|
||||
// Global profile
|
||||
this->addView(new brls::Header("Global profile"));
|
||||
|
||||
// Add the ListItem to Global profile
|
||||
Title* globalTitle = (Title*) malloc(sizeof(Title));
|
||||
globalTitle->tid = SYSCLK_GLOBAL_PROFILE_TID;
|
||||
|
||||
brls::ListItem *globalList = new brls::ListItem(std::string("Set global profile"));
|
||||
globalList->getClickEvent()->subscribe([globalTitle](View* view) {
|
||||
AppProfileFrame* profileFrame = new AppProfileFrame(globalTitle);
|
||||
brls::Application::pushView(profileFrame, brls::ViewAnimation::SLIDE_LEFT);
|
||||
});
|
||||
this->addView(globalList);
|
||||
|
||||
// Config
|
||||
// Broken, only accepting single digit
|
||||
// this->addView(new brls::Header("Configuration"));
|
||||
|
||||
// Logging
|
||||
// TODO: add a logger view and put the button to enter it here
|
||||
|
||||
// Config entries
|
||||
// TODO: add constraints to the swkbd if possible (min / max)
|
||||
|
||||
// sysclkIpcGetConfigValues(&this->configValues);
|
||||
|
||||
// for (int i = 0; i < SysClkConfigValue_EnumMax; i++)
|
||||
// {
|
||||
// SysClkConfigValue config = (SysClkConfigValue) i;
|
||||
|
||||
// std::string label = std::string(sysclkFormatConfigValue(config, true));
|
||||
// std::string description = this->getDescriptionForConfig(config);
|
||||
// uint64_t defaultValue = configValues.values[config];
|
||||
|
||||
// brls::IntegerInputListItem* configItem = new brls::IntegerInputListItem(label, defaultValue, label, description);
|
||||
|
||||
// configItem->setReduceDescriptionSpacing(true);
|
||||
|
||||
// configItem->getClickEvent()->subscribe([this, configItem, config](View* view)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// int value = std::stoi(configItem->getValue());
|
||||
|
||||
// // Validate the value
|
||||
// if (value < 0)
|
||||
// {
|
||||
// brls::Application::notify("\uE5CD Couldn't save configuration: invalid value (is negative)");
|
||||
// configItem->setValue(std::to_string(this->configValues.values[config]));
|
||||
// return;
|
||||
// }
|
||||
|
||||
// uint64_t uvalue = (uint64_t) value;
|
||||
|
||||
// if (!sysclkValidConfigValue(config, uvalue))
|
||||
// {
|
||||
// brls::Application::notify("\uE5CD Couldn't save configuration: invalid value");
|
||||
// configItem->setValue(std::to_string(this->configValues.values[config]));
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // Save the config
|
||||
// this->configValues.values[config] = uvalue;
|
||||
// sysclkIpcSetConfigValues(&this->configValues);
|
||||
|
||||
// brls::Application::notify("\uE14B Configuration saved");
|
||||
// }
|
||||
// catch(const std::exception& e)
|
||||
// {
|
||||
// brls::Logger::error("Unable to parse config value %s: %s", configItem->getValue().c_str(), e.what());
|
||||
// }
|
||||
// });
|
||||
|
||||
// this->addView(configItem);
|
||||
// }
|
||||
}
|
||||
|
||||
std::string AdvancedSettingsTab::getDescriptionForConfig(SysClkConfigValue config)
|
||||
{
|
||||
switch (config)
|
||||
{
|
||||
case SysClkConfigValue_CsvWriteIntervalMs:
|
||||
return "How often to update /config/sys-clk/context.csv (in milliseconds)\n\uE016 Use 0 to disable";
|
||||
case SysClkConfigValue_TempLogIntervalMs:
|
||||
return "How often to log temperatures (in milliseconds)\n\uE016 Use 0 to disable";
|
||||
case SysClkConfigValue_PollingIntervalMs:
|
||||
return "How fast to check and apply profiles (in milliseconds)";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#include "ipc/client.h"
|
||||
|
||||
class AdvancedSettingsTab : public brls::List
|
||||
{
|
||||
public:
|
||||
AdvancedSettingsTab();
|
||||
|
||||
private:
|
||||
std::string getDescriptionForConfig(SysClkConfigValue config);
|
||||
|
||||
bool isLoggingEnabled();
|
||||
void setLoggingEnabled(bool value);
|
||||
|
||||
SysClkConfigValueList configValues;
|
||||
};
|
||||
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "app_profile_frame.h"
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "ipc/client.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AppProfileFrame::AppProfileFrame(Title* title) : ThumbnailFrame(), title(title)
|
||||
{
|
||||
bool isGlobal = (title->tid == SYSCLK_GLOBAL_PROFILE_TID);
|
||||
|
||||
this->setTitle(isGlobal ? "Edit global profile" : "Edit application profile");
|
||||
this->setIcon(new brls::MaterialIcon("\uE315"));
|
||||
|
||||
// Get the freqs
|
||||
Result rc = sysclkIpcGetProfiles(title->tid, &this->profiles);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
errorResult("sysclkIpcGetProfiles", rc);
|
||||
|
||||
// Setup the right sidebar
|
||||
if (!isGlobal)
|
||||
{
|
||||
this->getSidebar()->setThumbnail(title->icon, sizeof(title->icon));
|
||||
this->getSidebar()->setTitle(std::string(title->name));
|
||||
this->getSidebar()->setSubtitle(formatTid(title->tid));
|
||||
}
|
||||
this->getSidebar()->getButton()->setState(brls::ButtonState::DISABLED);
|
||||
|
||||
this->getSidebar()->getButton()->getClickEvent()->subscribe([this, title](brls::View* view)
|
||||
{
|
||||
SysClkTitleProfileList profiles;
|
||||
memcpy(&profiles, &this->profiles, sizeof(SysClkTitleProfileList));
|
||||
|
||||
for (int p = 0; p < SysClkProfile_EnumMax; p++)
|
||||
{
|
||||
for (int m = 0; m < SysClkModule_EnumMax; m++)
|
||||
profiles.mhzMap[p][m] /= 1000000;
|
||||
}
|
||||
|
||||
Result rc = sysclkIpcSetProfiles(title->tid, &profiles);
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
{
|
||||
// TODO: set the tick mark color to blue/green once borealis has rich text support
|
||||
brls::Application::notify("\uE14B Profile saved");
|
||||
brls::Application::popView(brls::ViewAnimation::SLIDE_RIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorResult("sysclkIpcSetProfiles", rc);
|
||||
brls::Application::notify("An error occured while saving the profile - see logs for more details");
|
||||
}
|
||||
});
|
||||
|
||||
// Setup the list
|
||||
brls::List* list = new brls::List();
|
||||
|
||||
this->addFreqs(list, SysClkProfile_Docked);
|
||||
this->addFreqs(list, SysClkProfile_Handheld);
|
||||
|
||||
this->addFreqs(list, SysClkProfile_HandheldCharging);
|
||||
this->addFreqs(list, SysClkProfile_HandheldChargingOfficial);
|
||||
this->addFreqs(list, SysClkProfile_HandheldChargingUSB);
|
||||
|
||||
this->setContentView(list);
|
||||
}
|
||||
|
||||
void AppProfileFrame::addFreqs(brls::List* list, SysClkProfile profile)
|
||||
{
|
||||
// Get the freqs
|
||||
list->addView(new brls::Header(std::string(sysclkFormatProfile(profile, true))));
|
||||
|
||||
// CPU
|
||||
brls::SelectListItem* cpuListItem = createFreqListItem(SysClkModule_CPU, this->profiles.mhzMap[profile][SysClkModule_CPU]);
|
||||
|
||||
this->profiles.mhzMap[profile][SysClkModule_CPU] *= 1000000;
|
||||
|
||||
cpuListItem->getValueSelectedEvent()->subscribe([this, profile](int result) {
|
||||
this->onProfileChanged();
|
||||
this->profiles.mhzMap[profile][SysClkModule_CPU] = result == 0 ? result : g_freq_table_cpu_hz[result - 1];
|
||||
|
||||
brls::Logger::debug("Caching freq for module %d and profile %d to %" PRIu32, SysClkModule_CPU, profile, this->profiles.mhzMap[profile][SysClkModule_CPU]);
|
||||
});
|
||||
list->addView(cpuListItem);
|
||||
|
||||
// GPU
|
||||
brls::SelectListItem* gpuListItem = createFreqListItem(SysClkModule_GPU, this->profiles.mhzMap[profile][SysClkModule_GPU]);
|
||||
|
||||
this->profiles.mhzMap[profile][SysClkModule_GPU] *= 1000000;
|
||||
|
||||
gpuListItem->getValueSelectedEvent()->subscribe([this, profile](int result) {
|
||||
this->onProfileChanged();
|
||||
this->profiles.mhzMap[profile][SysClkModule_GPU] = result == 0 ? result : g_freq_table_gpu_hz[result - 1];
|
||||
|
||||
brls::Logger::debug("Caching freq for module %d and profile %d to %" PRIu32, SysClkModule_GPU, profile, this->profiles.mhzMap[profile][SysClkModule_GPU]);
|
||||
});
|
||||
list->addView(gpuListItem);
|
||||
|
||||
// MEM
|
||||
brls::SelectListItem* memListItem = createFreqListItem(SysClkModule_MEM, this->profiles.mhzMap[profile][SysClkModule_MEM]);
|
||||
|
||||
this->profiles.mhzMap[profile][SysClkModule_MEM] *= 1000000;
|
||||
|
||||
memListItem->getValueSelectedEvent()->subscribe([this, profile](int result) {
|
||||
this->onProfileChanged();
|
||||
this->profiles.mhzMap[profile][SysClkModule_MEM] = result == 0 ? result : g_freq_table_mem_hz[result - 1];
|
||||
|
||||
brls::Logger::debug("Caching freq for module %d and profile %d to %" PRIu32, SysClkModule_MEM, profile, this->profiles.mhzMap[profile][SysClkModule_MEM]);
|
||||
});
|
||||
list->addView(memListItem);
|
||||
}
|
||||
|
||||
void AppProfileFrame::onProfileChanged()
|
||||
{
|
||||
this->getSidebar()->getButton()->setState(brls::ButtonState::ENABLED);
|
||||
this->updateActionHint(brls::Key::B, "Cancel");
|
||||
}
|
||||
|
||||
bool AppProfileFrame::onCancel()
|
||||
{
|
||||
if (this->hasProfileChanged())
|
||||
{
|
||||
brls::Dialog* dialog = new brls::Dialog("You have unsaved changes to this profile!\nAre you sure you want to discard them?");
|
||||
|
||||
dialog->addButton("No", [dialog](brls::View* view){
|
||||
dialog->close();
|
||||
});
|
||||
|
||||
dialog->addButton("Yes", [dialog](brls::View* view){
|
||||
dialog->close([](){
|
||||
brls::Application::popView(brls::ViewAnimation::SLIDE_RIGHT);
|
||||
});
|
||||
});
|
||||
|
||||
dialog->open();
|
||||
}
|
||||
else
|
||||
{
|
||||
brls::Application::popView(brls::ViewAnimation::SLIDE_RIGHT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AppProfileFrame::hasProfileChanged()
|
||||
{
|
||||
return this->getSidebar()->getButton()->getState() == brls::ButtonState::ENABLED;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#include <sysclk/clocks.h>
|
||||
|
||||
#include "app_profiles_tab.h"
|
||||
|
||||
class AppProfileFrame : public brls::ThumbnailFrame
|
||||
{
|
||||
public:
|
||||
AppProfileFrame(Title* title);
|
||||
|
||||
bool onCancel() override;
|
||||
|
||||
private:
|
||||
Title* title;
|
||||
|
||||
SysClkTitleProfileList profiles;
|
||||
|
||||
bool hasProfileChanged();
|
||||
|
||||
void addFreqs(brls::List* list, SysClkProfile profile);
|
||||
|
||||
void onProfileChanged();
|
||||
};
|
||||
@@ -1,244 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "app_profiles_tab.h"
|
||||
|
||||
#include "app_profile_frame.h"
|
||||
|
||||
#include "ipc/client.h"
|
||||
#include "ipc/ipc.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define PROFILE_BADGE "\uE3E0"
|
||||
|
||||
AppProfilesTab::AppProfilesTab()
|
||||
{
|
||||
// Filter toggle
|
||||
this->filterListItem = new brls::ToggleListItem("Show applications with no profile", this->showEmptyProfiles, "", "Yes", "No");
|
||||
filterListItem->getClickEvent()->subscribe([this](View* v)
|
||||
{
|
||||
this->refreshFilter();
|
||||
});
|
||||
this->addView(filterListItem);
|
||||
|
||||
// Spacing
|
||||
this->addView(new brls::ListItemGroupSpacing());
|
||||
|
||||
// Applications list
|
||||
NsApplicationRecord record;
|
||||
uint64_t tid;
|
||||
NsApplicationControlData controlData;
|
||||
NacpLanguageEntry* langEntry = NULL;
|
||||
|
||||
Result rc;
|
||||
size_t i = 0;
|
||||
int recordCount = 0;
|
||||
size_t controlSize = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Record
|
||||
rc = nsListApplicationRecord(&record, sizeof(record), i, &recordCount);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
errorResult("nsListApplicationRecord", rc);
|
||||
break;
|
||||
}
|
||||
|
||||
if(recordCount <= 0)
|
||||
break;
|
||||
|
||||
tid = record.application_id;
|
||||
|
||||
// Control data
|
||||
rc = nsGetApplicationControlData(NsApplicationControlSource_Storage, tid, &controlData, sizeof(controlData), &controlSize);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
errorResult("nsGetApplicationControlData", rc);
|
||||
break;
|
||||
}
|
||||
|
||||
// Language entry
|
||||
rc = nacpGetLanguageEntry(&controlData.nacp, &langEntry);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
errorResult("nacpGetLanguageEntry", rc);
|
||||
break;
|
||||
}
|
||||
|
||||
// Name
|
||||
if (!langEntry->name)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
Title* title = (Title*) malloc(sizeof(Title));
|
||||
title->tid = tid;
|
||||
|
||||
memset(title->name, 0, sizeof(title->name));
|
||||
strncpy(title->name, langEntry->name, sizeof(title->name)-1);
|
||||
|
||||
memcpy(title->icon, controlData.icon, sizeof(title->icon));
|
||||
|
||||
// Profile
|
||||
rc = sysclkIpcGetProfileCount(tid, &title->profileCount);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
errorResult("sysclkIpcGetProfileCount", rc);
|
||||
free(title);
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the ListItem
|
||||
brls::ListItem *listItem = new brls::ListItem(formatListItemTitle(std::string(title->name)), "", formatTid(title->tid));
|
||||
|
||||
title->listItem = listItem;
|
||||
|
||||
this->items.push_back(listItem);
|
||||
|
||||
if (title->profileCount > 0)
|
||||
{
|
||||
listItem->setValue(PROFILE_BADGE);
|
||||
this->profilesItems.push_back(listItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->emptyProfilesItems.push_back(listItem);
|
||||
|
||||
if (!this->showEmptyProfiles)
|
||||
listItem->collapse(false);
|
||||
}
|
||||
|
||||
listItem->setThumbnail(title->icon, sizeof(title->icon));
|
||||
|
||||
listItem->getClickEvent()->subscribe([this, title](View* view) {
|
||||
this->editingTitle = title;
|
||||
AppProfileFrame* profileFrame = new AppProfileFrame(title);
|
||||
brls::Application::pushView(profileFrame, brls::ViewAnimation::SLIDE_LEFT);
|
||||
});
|
||||
|
||||
this->addView(listItem);
|
||||
this->titles.push_back(title);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
// Empty list message
|
||||
this->emptyListLabel = new brls::Label(brls::LabelStyle::REGULAR, "", true);
|
||||
this->addView(emptyListLabel);
|
||||
this->updateEmptyListLabel(false);
|
||||
}
|
||||
|
||||
void AppProfilesTab::updateEmptyListLabel(bool animate)
|
||||
{
|
||||
if (this->items.empty())
|
||||
{
|
||||
this->emptyListLabel->setText("\uE140 You don't have any application installed on your Nintendo Switch.");
|
||||
this->emptyListLabel->show([](){}, animate);
|
||||
}
|
||||
else if (!this->showEmptyProfiles && this->profilesItems.empty())
|
||||
{
|
||||
this->emptyListLabel->setText("\uE140 You don't have any application with a defined profile at the moment.");
|
||||
this->emptyListLabel->show([](){}, animate);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->emptyListLabel->hide([](){}, animate);
|
||||
}
|
||||
}
|
||||
|
||||
AppProfilesTab::~AppProfilesTab()
|
||||
{
|
||||
for (Title* title : this->titles)
|
||||
free(title);
|
||||
|
||||
this->titles.clear();
|
||||
}
|
||||
|
||||
|
||||
void AppProfilesTab::willAppear(bool resetState)
|
||||
{
|
||||
if (this->editingTitle != nullptr)
|
||||
{
|
||||
bool hadProfiles = this->editingTitle->profileCount > 0;
|
||||
|
||||
Result rc = sysclkIpcGetProfileCount(this->editingTitle->tid, &this->editingTitle->profileCount);
|
||||
|
||||
bool hasProfiles = this->editingTitle->profileCount > 0;
|
||||
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
errorResult("sysclkIpcGetProfileCount", rc);
|
||||
this->editingTitle = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the profile badge
|
||||
if (hasProfiles)
|
||||
this->editingTitle->listItem->setValue(PROFILE_BADGE);
|
||||
else
|
||||
this->editingTitle->listItem->setValue("");
|
||||
|
||||
// Update lists
|
||||
|
||||
// Remove from emptyProfilesItems if it didn't have a profile
|
||||
// but has one now
|
||||
// Add to profilesItems
|
||||
if (!hadProfiles && hasProfiles)
|
||||
{
|
||||
this->emptyProfilesItems.erase(std::remove(this->emptyProfilesItems.begin(), this->emptyProfilesItems.end(), this->editingTitle->listItem), this->emptyProfilesItems.end());
|
||||
this->profilesItems.push_back(this->editingTitle->listItem);
|
||||
}
|
||||
|
||||
// Add to emptyProfilesItems if it had a profile but doesn't
|
||||
// has one now
|
||||
// Remove from profilesItems
|
||||
if (hadProfiles && !hasProfiles)
|
||||
{
|
||||
this->emptyProfilesItems.push_back(this->editingTitle->listItem);
|
||||
this->profilesItems.erase(std::remove(this->profilesItems.begin(), this->profilesItems.end(), this->editingTitle->listItem), this->profilesItems.end());
|
||||
}
|
||||
|
||||
// Refresh the filter
|
||||
this->refreshFilter();
|
||||
|
||||
// Cleanup
|
||||
this->editingTitle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AppProfilesTab::refreshFilter()
|
||||
{
|
||||
this->showEmptyProfiles = this->filterListItem->getToggleState();
|
||||
|
||||
for (brls::ListItem *listItem : this->emptyProfilesItems)
|
||||
{
|
||||
if (this->showEmptyProfiles)
|
||||
listItem->expand();
|
||||
else
|
||||
listItem->collapse();
|
||||
|
||||
this->updateEmptyListLabel();
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#include "ipc/ipc.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t tid;
|
||||
NsApplicationName name;
|
||||
NsApplicationIcon icon;
|
||||
uint8_t profileCount;
|
||||
|
||||
brls::ListItem* listItem;
|
||||
} Title;
|
||||
|
||||
class AppProfilesTab : public brls::List
|
||||
{
|
||||
private:
|
||||
bool showEmptyProfiles = true;
|
||||
|
||||
std::vector<Title*> titles;
|
||||
|
||||
std::vector<brls::ListItem*> items;
|
||||
std::vector<brls::ListItem*> emptyProfilesItems;
|
||||
std::vector<brls::ListItem*> profilesItems;
|
||||
|
||||
brls::Label *emptyListLabel;
|
||||
brls::ToggleListItem *filterListItem;
|
||||
|
||||
void updateEmptyListLabel(bool animate = true);
|
||||
|
||||
Title* editingTitle = nullptr;
|
||||
|
||||
void refreshFilter();
|
||||
|
||||
public:
|
||||
AppProfilesTab();
|
||||
~AppProfilesTab();
|
||||
|
||||
void willAppear(bool resetState) override;
|
||||
};
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019-2020 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "cheat_sheet_tab.h"
|
||||
#include "ipc/client.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
CheatSheetTab::CheatSheetTab()
|
||||
{
|
||||
// CPU
|
||||
this->addView(new brls::Header("CPU Clocks"));
|
||||
brls::Table *cpuTable = new brls::Table();
|
||||
|
||||
cpuTable->addRow(brls::TableRowType::BODY, "Tegra X1+ Official Max", "1963.5 MHz");
|
||||
cpuTable->addRow(brls::TableRowType::BODY, "Official Boost", "1785.0 MHz");
|
||||
cpuTable->addRow(brls::TableRowType::BODY, "Official Docked and Handheld", "1020.0 MHz");
|
||||
|
||||
this->addView(cpuTable);
|
||||
|
||||
// GPU
|
||||
this->addView(new brls::Header("GPU Clocks"));
|
||||
brls::Table *gpuTable = new brls::Table();
|
||||
|
||||
gpuTable->addRow(brls::TableRowType::BODY, "Tegra X1+ Official Max", "1267.2 MHz");
|
||||
gpuTable->addRow(brls::TableRowType::BODY, "Official Maximum", "921.6 MHz");
|
||||
gpuTable->addRow(brls::TableRowType::BODY, "Official Docked", "768.0 MHz");
|
||||
gpuTable->addRow(brls::TableRowType::BODY, "Official Handheld", "384.0/460.8 MHz");
|
||||
|
||||
this->addView(gpuTable);
|
||||
|
||||
// MEM
|
||||
this->addView(new brls::Header("MEM Clocks"));
|
||||
brls::Table *memTable = new brls::Table();
|
||||
|
||||
// Get context
|
||||
SysClkContext context;
|
||||
Result rc = sysclkIpcGetCurrentContext(&context);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
brls::Logger::error("Unable to get context");
|
||||
errorResult("sysclkIpcGetCurrentContext", rc);
|
||||
brls::Application::crash("Could not get the current sys-clk context, please check that it is correctly installed and enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
memTable->addRow(brls::TableRowType::BODY, "Tegra X1+ Official Max", "2131.2 MHz");
|
||||
memTable->addRow(brls::TableRowType::BODY, "Official", "1331.2/1600.0 MHz");
|
||||
|
||||
this->addView(memTable);
|
||||
}
|
||||
|
||||
void CheatSheetTab::customSpacing(brls::View* current, brls::View* next, int* spacing)
|
||||
{
|
||||
if (dynamic_cast<brls::Table*>(current))
|
||||
*spacing = 0;
|
||||
else
|
||||
List::customSpacing(current, next, spacing);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019-2020 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
class CheatSheetTab : public brls::List
|
||||
{
|
||||
public:
|
||||
bool isMariko = false;
|
||||
|
||||
CheatSheetTab();
|
||||
|
||||
void customSpacing(brls::View* current, brls::View* next, int* spacing) override;
|
||||
|
||||
View* getDefaultFocus() override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ipc.h"
|
||||
|
||||
#include <sysclk.h>
|
||||
#include <sysclk/client/ipc.h>
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __SWITCH__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <switch.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include "pc_shim/nacp.h"
|
||||
#include "pc_shim/ns.h"
|
||||
#include "pc_shim/types.h"
|
||||
|
||||
#endif
|
||||
@@ -1,313 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "client.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static SysClkShimServer* g_server = NULL;
|
||||
|
||||
bool sysclkIpcRunning()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Result sysclkIpcInitialize()
|
||||
{
|
||||
if(!g_server)
|
||||
{
|
||||
g_server = new SysClkShimServer();
|
||||
|
||||
g_server->SetContextApplicationId(0x0100000000001000ULL);
|
||||
g_server->SetContextHz(SysClkModule_CPU, 1020000000);
|
||||
g_server->SetContextHz(SysClkModule_GPU, 307200000);
|
||||
g_server->SetContextHz(SysClkModule_MEM, 1065600000);
|
||||
g_server->SetContextTemp(SysClkThermalSensor_PCB, 45700);
|
||||
g_server->SetContextTemp(SysClkThermalSensor_SOC, 48200);
|
||||
g_server->SetContextEnabled(true);
|
||||
|
||||
g_server->SetProfile(0x010000000000F002, SysClkModule_CPU, SysClkProfile_Docked, 1224);
|
||||
g_server->SetProfile(0x010000000000F002, SysClkModule_GPU, SysClkProfile_Docked, 921);
|
||||
g_server->SetProfile(0x010000000000F002, SysClkModule_MEM, SysClkProfile_Docked, 1600);
|
||||
|
||||
g_server->SetProfile(0x010000000000F002, SysClkModule_CPU, SysClkProfile_Handheld, 1224);
|
||||
g_server->SetProfile(0x010000000000F002, SysClkModule_MEM, SysClkProfile_Handheld, 1600);
|
||||
|
||||
g_server->SetConfigValue(SysClkConfigValue_CsvWriteIntervalMs, 5000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sysclkIpcExit()
|
||||
{
|
||||
if(g_server)
|
||||
delete g_server;
|
||||
}
|
||||
|
||||
Result sysclkIpcGetAPIVersion(u32* out_ver)
|
||||
{
|
||||
*out_ver = SYSCLK_IPC_API_VERSION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result sysclkIpcGetVersionString(char* out, size_t len)
|
||||
{
|
||||
strncpy(out, "- shim server -", len-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result sysclkIpcGetCurrentContext(SysClkContext* out_context)
|
||||
{
|
||||
g_server->CopyContext(out_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result sysclkIpcGetProfileCount(u64 tid, u8* out_count)
|
||||
{
|
||||
*out_count = g_server->CountProfiles(tid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result sysclkIpcGetProfiles(u64 tid, SysClkTitleProfileList* out_profiles)
|
||||
{
|
||||
g_server->GetProfiles(tid, out_profiles);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result sysclkIpcSetProfiles(u64 tid, SysClkTitleProfileList* profiles)
|
||||
{
|
||||
g_server->SetProfiles(tid, profiles);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result sysclkIpcSetEnabled(bool enabled)
|
||||
{
|
||||
g_server->SetContextEnabled(enabled);
|
||||
|
||||
if(enabled)
|
||||
{
|
||||
g_server->SetContextTemp(SysClkThermalSensor_PCB, 45700);
|
||||
g_server->SetContextTemp(SysClkThermalSensor_SOC, 48200);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_server->SetContextTemp(SysClkThermalSensor_PCB, 34200);
|
||||
g_server->SetContextTemp(SysClkThermalSensor_SOC, 42800);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result sysclkIpcExitCmd()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result sysclkIpcSetOverride(SysClkModule module, u32 hz)
|
||||
{
|
||||
g_server->SetContextOverride(module, hz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result sysclkIpcGetConfigValues(SysClkConfigValueList* out_configValues)
|
||||
{
|
||||
g_server->GetConfigValues(out_configValues);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues)
|
||||
{
|
||||
g_server->SetConfigValues(configValues);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SysClkShimServer::SysClkShimServer()
|
||||
{
|
||||
this->store = std::map<std::tuple<u64, SysClkModule, SysClkProfile>, u32>();
|
||||
this->SetContextApplicationId(0);
|
||||
this->SetContextHz(SysClkModule_CPU, 0);
|
||||
this->SetContextHz(SysClkModule_GPU, 0);
|
||||
this->SetContextHz(SysClkModule_MEM, 0);
|
||||
this->SetContextOverride(SysClkModule_CPU, 0);
|
||||
this->SetContextOverride(SysClkModule_GPU, 0);
|
||||
this->SetContextOverride(SysClkModule_MEM, 0);
|
||||
this->SetContextTemp(SysClkThermalSensor_PCB, 0);
|
||||
this->SetContextTemp(SysClkThermalSensor_SOC, 0);
|
||||
this->SetContextProfile(SysClkProfile_Handheld);
|
||||
this->SetContextEnabled(false);
|
||||
|
||||
for(int kval = 0; kval < SysClkConfigValue_EnumMax; kval++)
|
||||
{
|
||||
this->configValues[kval] = sysclkDefaultConfigValue((SysClkConfigValue)kval);
|
||||
}
|
||||
}
|
||||
|
||||
void SysClkShimServer::SetContextApplicationId(u64 tid)
|
||||
{
|
||||
this->context.applicationId = tid;
|
||||
}
|
||||
|
||||
void SysClkShimServer::SetContextHz(SysClkModule module, u32 hz)
|
||||
{
|
||||
if(module < SysClkModule_EnumMax)
|
||||
{
|
||||
this->context.freqs[module] = hz;
|
||||
}
|
||||
}
|
||||
|
||||
void SysClkShimServer::SetContextTemp(SysClkThermalSensor sensor, u32 temp)
|
||||
{
|
||||
if(sensor < SysClkThermalSensor_EnumMax)
|
||||
{
|
||||
this->context.temps[sensor] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
void SysClkShimServer::CopyContext(SysClkContext* out_context)
|
||||
{
|
||||
memcpy(out_context, &this->context, sizeof(SysClkContext));
|
||||
}
|
||||
|
||||
void SysClkShimServer::SetContextProfile(SysClkProfile profile)
|
||||
{
|
||||
if(profile < SysClkProfile_EnumMax)
|
||||
{
|
||||
this->context.profile = profile;
|
||||
}
|
||||
}
|
||||
|
||||
void SysClkShimServer::SetContextEnabled(bool enabled)
|
||||
{
|
||||
this->context.enabled = enabled;
|
||||
}
|
||||
|
||||
void SysClkShimServer::SetProfile(uint64_t applicationId, SysClkModule module, SysClkProfile profile, u32 mhz)
|
||||
{
|
||||
std::tuple<u64, SysClkModule, SysClkProfile> key = std::make_tuple(applicationId, module, profile);
|
||||
|
||||
if(mhz > 0)
|
||||
{
|
||||
this->store[key] = mhz;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->store.erase(key);
|
||||
}
|
||||
}
|
||||
|
||||
u32 SysClkShimServer::GetProfileMhz(uint64_t applicationId, SysClkModule module, SysClkProfile profile)
|
||||
{
|
||||
std::tuple<u64, SysClkModule, SysClkProfile> key = std::make_tuple(applicationId, module, profile);
|
||||
std::map<std::tuple<u64, SysClkModule, SysClkProfile>, u32>::iterator it = this->store.find(key);
|
||||
|
||||
if(it != this->store.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SysClkShimServer::GetProfiles(u64 applicationId, SysClkTitleProfileList* out_profiles)
|
||||
{
|
||||
for(unsigned int profile = 0; profile < SysClkProfile_EnumMax; profile++)
|
||||
{
|
||||
for(unsigned int module = 0; module < SysClkModule_EnumMax; module++)
|
||||
{
|
||||
out_profiles->mhzMap[profile][module] = this->GetProfileMhz(applicationId, (SysClkModule)module, (SysClkProfile)profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SysClkShimServer::SetProfiles(u64 applicationId, SysClkTitleProfileList* profiles)
|
||||
{
|
||||
for(unsigned int profile = 0; profile < SysClkProfile_EnumMax; profile++)
|
||||
{
|
||||
for(unsigned int module = 0; module < SysClkModule_EnumMax; module++)
|
||||
{
|
||||
this->SetProfile(applicationId, (SysClkModule)module, (SysClkProfile)profile, profiles->mhzMap[profile][module]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u8 SysClkShimServer::CountProfiles(u64 applicationId)
|
||||
{
|
||||
return std::accumulate(
|
||||
std::begin(this->store),
|
||||
std::end(this->store),
|
||||
0,
|
||||
[applicationId] (u8 value, const std::map<std::tuple<u64, SysClkModule, SysClkProfile>, u32>::value_type& p)
|
||||
{
|
||||
if(std::get<0>(p.first) == applicationId)
|
||||
{
|
||||
value++;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SysClkShimServer::SetContextOverride(SysClkModule module, u32 hz)
|
||||
{
|
||||
if(SYSCLK_ENUM_VALID(SysClkModule, module))
|
||||
{
|
||||
this->context.overrideFreqs[module] = hz;
|
||||
}
|
||||
}
|
||||
|
||||
u64 SysClkShimServer::GetConfigValue(SysClkConfigValue kval)
|
||||
{
|
||||
if(SYSCLK_ENUM_VALID(SysClkConfigValue, kval))
|
||||
{
|
||||
return this->configValues[kval];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SysClkShimServer::SetConfigValue(SysClkConfigValue kval, u64 val)
|
||||
{
|
||||
if(SYSCLK_ENUM_VALID(SysClkConfigValue, kval))
|
||||
{
|
||||
if(sysclkValidConfigValue(kval, this->configValues[kval]))
|
||||
{
|
||||
this->configValues[kval] = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->configValues[kval] = sysclkDefaultConfigValue(kval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SysClkShimServer::GetConfigValues(SysClkConfigValueList* out_configValues)
|
||||
{
|
||||
for(unsigned int kval = 0; kval < SysClkConfigValue_EnumMax; kval++)
|
||||
{
|
||||
out_configValues->values[kval] = this->GetConfigValue((SysClkConfigValue)kval);
|
||||
}
|
||||
}
|
||||
|
||||
void SysClkShimServer::SetConfigValues(SysClkConfigValueList* configValues)
|
||||
{
|
||||
for(unsigned int kval = 0; kval < SysClkConfigValue_EnumMax; kval++)
|
||||
{
|
||||
this->SetConfigValue((SysClkConfigValue)kval, configValues->values[kval]);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <numeric>
|
||||
#include "../client.h"
|
||||
|
||||
class SysClkShimServer
|
||||
{
|
||||
public:
|
||||
SysClkShimServer();
|
||||
void SetContextApplicationId(u64 tid);
|
||||
void SetContextHz(SysClkModule module, u32 hz);
|
||||
void SetContextTemp(SysClkThermalSensor sensor, u32 temp);
|
||||
void SetContextProfile(SysClkProfile profile);
|
||||
void SetContextEnabled(bool enabled);
|
||||
void SetContextOverride(SysClkModule module, u32 hz);
|
||||
void CopyContext(SysClkContext* out_context);
|
||||
void SetProfile(uint64_t applicationId, SysClkModule module, SysClkProfile profile, u32 mhz);
|
||||
u32 GetProfileMhz(uint64_t applicationId, SysClkModule module, SysClkProfile profile);
|
||||
void GetProfiles(u64 applicationId, SysClkTitleProfileList* out_profiles);
|
||||
void SetProfiles(u64 applicationId, SysClkTitleProfileList* profiles);
|
||||
u8 CountProfiles(u64 applicationId);
|
||||
u64 GetConfigValue(SysClkConfigValue kval);
|
||||
void SetConfigValue(SysClkConfigValue kval, u64 val);
|
||||
void GetConfigValues(SysClkConfigValueList* out_configValues);
|
||||
void SetConfigValues(SysClkConfigValueList* configValues);
|
||||
|
||||
protected:
|
||||
SysClkContext context;
|
||||
std::map<std::tuple<u64, SysClkModule, SysClkProfile>, u32> store;
|
||||
u64 configValues[SysClkConfigValue_EnumMax];
|
||||
};
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.5 KiB |
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[0x200];
|
||||
} NacpLanguageEntry;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NacpLanguageEntry entry;
|
||||
} NacpStruct;
|
||||
|
||||
static inline Result nacpGetLanguageEntry(NacpStruct* nacp, NacpLanguageEntry** langentry)
|
||||
{
|
||||
if(nacp && langentry)
|
||||
{
|
||||
*langentry = &nacp->entry;
|
||||
return 0;
|
||||
}
|
||||
return 0xBAD;
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ns.h"
|
||||
#include "types.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define GAME_ICON_PATH "src/ipc/pc_shim/game.jpg"
|
||||
|
||||
static NsShimStore* g_store = NULL;
|
||||
|
||||
Result nsInitialize()
|
||||
{
|
||||
if(!g_store)
|
||||
{
|
||||
g_store = new NsShimStore();
|
||||
g_store->AddRecord(0x010000000000F001ULL, "Secret Maryo Chronicles", GAME_ICON_PATH);
|
||||
g_store->AddRecord(0x010000000000F002ULL, "Zelda: Mystery of Solarus", GAME_ICON_PATH);
|
||||
g_store->AddRecord(0x010000000000F003ULL, "AM2R", GAME_ICON_PATH);
|
||||
g_store->AddRecord(0x010000000000F004ULL, "Mother 4", GAME_ICON_PATH);
|
||||
g_store->AddRecord(0x01007EF00011E000ULL, "Wrath of the Wild", GAME_ICON_PATH);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nsExit()
|
||||
{
|
||||
if(g_store)
|
||||
delete g_store;
|
||||
}
|
||||
|
||||
Result nsListApplicationRecord(NsApplicationRecord* out_records, s32 size, s32 offset, s32* out_count)
|
||||
{
|
||||
return g_store->ListRecord(out_records, size, offset, out_count) ? 0 : 0xBAD;
|
||||
}
|
||||
|
||||
Result nsGetApplicationControlData(NsApplicationControlSource flag, u64 titleID, NsApplicationControlData* out_data, size_t size, u64* out_size)
|
||||
{
|
||||
return g_store->GetControlData(out_data, size, titleID, out_size) ? 0 : 0xBAD;
|
||||
}
|
||||
|
||||
NsShimStore::NsShimStore()
|
||||
{
|
||||
this->store = std::map<u64, std::pair<std::string, std::string>>();
|
||||
}
|
||||
|
||||
void NsShimStore::AddRecord(u64 titleID, std::string name, std::string iconPath)
|
||||
{
|
||||
this->store[titleID] = std::make_pair(name, iconPath);
|
||||
}
|
||||
|
||||
bool NsShimStore::ListRecord(NsApplicationRecord* out_records, s32 size, s32 offset, s32* out_count)
|
||||
{
|
||||
if(!out_records || !out_count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t left = size;
|
||||
size_t count = 0;
|
||||
std::map<u64, std::pair<std::string, std::string>>::iterator it = this->store.begin();
|
||||
std::advance(it, offset);
|
||||
while(left >= sizeof(NsApplicationRecord) && it != this->store.end())
|
||||
{
|
||||
out_records->application_id = it->first;
|
||||
left -= sizeof(NsApplicationRecord);
|
||||
out_records++;
|
||||
count++;
|
||||
std::advance(it, 1);
|
||||
}
|
||||
|
||||
*out_count = count;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NsShimStore::GetControlData(NsApplicationControlData* out_data, size_t size, u64 tid, size_t* out_size)
|
||||
{
|
||||
if(!out_data || !out_size || size != sizeof(NsApplicationControlData))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<u64, std::pair<std::string, std::string>>::iterator it = this->store.find(tid);
|
||||
if(it == this->store.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(out_data, 0, size);
|
||||
strncpy(out_data->nacp.entry.name, it->second.first.c_str(), sizeof(out_data->nacp.entry.name)-1);
|
||||
FILE* f = fopen(it->second.second.c_str(), "rb");
|
||||
if(!f)
|
||||
{
|
||||
printf("[NsShimStore] Could not open file '%s'\n", it->second.second.c_str());
|
||||
return false;
|
||||
}
|
||||
*out_size = fread(out_data->icon, sizeof(out_data->icon), 1, f);
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "../types.h"
|
||||
#include "types.h"
|
||||
#include "nacp.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NsApplicationControlSource_Storage = 1
|
||||
} NsApplicationControlSource;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 application_id;
|
||||
} NsApplicationRecord;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NacpStruct nacp;
|
||||
NsApplicationIcon icon;
|
||||
} NsApplicationControlData;
|
||||
|
||||
Result nsInitialize();
|
||||
Result nsListApplicationRecord(NsApplicationRecord* out_records, s32 size, s32 offset, s32* out_count);
|
||||
Result nsGetApplicationControlData(NsApplicationControlSource flag, u64 titleID, NsApplicationControlData* out_data, size_t size, u64* out_size);
|
||||
void nsExit();
|
||||
|
||||
class NsShimStore
|
||||
{
|
||||
public:
|
||||
NsShimStore();
|
||||
void AddRecord(u64 titleID, std::string name, std::string iconPath);
|
||||
bool ListRecord(NsApplicationRecord* out_records, s32 size, s32 offset, s32* out_count);
|
||||
bool GetControlData(NsApplicationControlData* out_data, size_t size, u64 titleID, size_t* out_size);
|
||||
|
||||
protected:
|
||||
std::map<u64, std::pair<std::string, std::string>> store;
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#define R_FAILED(res) ((res) != 0)
|
||||
#define R_SUCCEEDED(res) ((res) == 0)
|
||||
|
||||
typedef std::uint32_t Result;
|
||||
typedef std::uint32_t u32;
|
||||
typedef std::int32_t s32;
|
||||
typedef std::uint64_t u64;
|
||||
typedef std::uint8_t u8;
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef char NsApplicationName[0x201];
|
||||
typedef uint8_t NsApplicationIcon[0x20000];
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019-2020 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "logo.h"
|
||||
|
||||
Logo::Logo(LogoStyle style) {
|
||||
this->logoLabel = new brls::Label(brls::LabelStyle::LIST_ITEM, "sys-clk-OC", style == LogoStyle::ABOUT);
|
||||
this->logoLabel->setParent(this);
|
||||
|
||||
int logoFont = brls::Application::findFont(LOGO_FONT_NAME);
|
||||
if (logoFont >= 0)
|
||||
{
|
||||
this->logoLabel->setFont(logoFont);
|
||||
}
|
||||
|
||||
if (style == LogoStyle::ABOUT)
|
||||
{
|
||||
this->logoLabel->setFontSize(LOGO_ABOUT_FONT_SIZE);
|
||||
this->logoLabel->setHorizontalAlign(NVG_ALIGN_CENTER);
|
||||
}
|
||||
|
||||
if (style == LogoStyle::HEADER)
|
||||
{
|
||||
this->logoLabel->setFontSize(LOGO_HEADER_FONT_SIZE);
|
||||
this->descLabel = new brls::Label(brls::LabelStyle::LIST_ITEM, "manager");
|
||||
this->descLabel->setParent(this);
|
||||
this->descLabel->setFontSize(LOGO_DESC_FONT_SIZE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Logo::~Logo() {
|
||||
delete this->logoLabel;
|
||||
|
||||
if (this->descLabel)
|
||||
delete this->descLabel;
|
||||
}
|
||||
|
||||
void Logo::draw(NVGcontext* vg, int x, int y, unsigned width, unsigned height, brls::Style* style, brls::FrameContext* ctx)
|
||||
{
|
||||
this->logoLabel->frame(ctx);
|
||||
|
||||
if (this->descLabel)
|
||||
this->descLabel->frame(ctx);
|
||||
}
|
||||
|
||||
void Logo::layout(NVGcontext* vg, brls::Style* style, brls::FontStash* stash)
|
||||
{
|
||||
this->logoLabel->setBoundaries(this->x, this->y + LOGO_OFFSET, this->width, this->height);
|
||||
this->logoLabel->layout(vg, style, stash);
|
||||
this->height = this->logoLabel->getHeight();
|
||||
|
||||
if (this->descLabel)
|
||||
{
|
||||
this->descLabel->layout(vg, style, stash);
|
||||
this->descLabel->setBoundaries(this->x + LOGO_HEADER_SPACING + this->logoLabel->getWidth(), this->y + style->AppletFrame.titleOffset - 1, this->descLabel->getWidth(), height);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019-2020 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
enum class LogoStyle
|
||||
{
|
||||
HEADER = 0,
|
||||
ABOUT
|
||||
};
|
||||
|
||||
#define LOGO_FONT_NAME "logo"
|
||||
#define LOGO_FONT_PATH APP_ASSET("fira/FiraSans-Medium-rnx.ttf")
|
||||
|
||||
#define LOGO_HEADER_FONT_SIZE 45
|
||||
#define LOGO_HEADER_SPACING 12
|
||||
#define LOGO_ABOUT_FONT_SIZE 55
|
||||
#define LOGO_DESC_FONT_SIZE 28
|
||||
#define LOGO_OFFSET 2
|
||||
|
||||
class Logo : public brls::View
|
||||
{
|
||||
protected:
|
||||
brls::Label* logoLabel = nullptr;
|
||||
brls::Label* descLabel = nullptr;
|
||||
void layout(NVGcontext* vg, brls::Style* style, brls::FontStash* stash);
|
||||
void draw(NVGcontext* vg, int x, int y, unsigned width, unsigned height, brls::Style* style, brls::FrameContext* ctx) override;
|
||||
public:
|
||||
Logo(LogoStyle style);
|
||||
virtual ~Logo();
|
||||
};
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#include "main_frame.h"
|
||||
#include "logo.h"
|
||||
|
||||
#include "ipc/client.h"
|
||||
#include "ipc/ipc.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// Init the app
|
||||
if (!brls::Application::init(APP_TITLE))
|
||||
{
|
||||
brls::Logger::error("Unable to init Borealis application");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Setup verbose logging on PC
|
||||
#ifndef __SWITCH__
|
||||
brls::Logger::setLogLevel(brls::LogLevel::DEBUG);
|
||||
#endif
|
||||
|
||||
if (brls::Application::loadFont(LOGO_FONT_NAME, LOGO_FONT_PATH) < 0)
|
||||
{
|
||||
brls::Logger::error("failed to load logo font");
|
||||
}
|
||||
|
||||
uint32_t apiVersion;
|
||||
|
||||
// Check that sys-clk is running
|
||||
if (!sysclkIpcRunning())
|
||||
{
|
||||
brls::Logger::error("sys-clk is not running");
|
||||
brls::Application::crash("sys-clk does not seem to be running, please check that it is correctly installed and enabled.");
|
||||
}
|
||||
// Initialize sys-clk IPC client
|
||||
else if (R_FAILED(sysclkIpcInitialize()) || R_FAILED(sysclkIpcGetAPIVersion(&apiVersion)))
|
||||
{
|
||||
brls::Logger::error("Unable to initialize sys-clk IPC client");
|
||||
brls::Application::crash("Could not connect to sys-clk, please check that it is correctly installed and enabled.");
|
||||
}
|
||||
else if (SYSCLK_IPC_API_VERSION != apiVersion) {
|
||||
brls::Logger::error("sys-clk IPC API version mismatch (expected: %u; actual: %u)", SYSCLK_IPC_API_VERSION, apiVersion);
|
||||
brls::Application::crash("The manager is not compatible with the currently running sysmodule of sys-clk, please check that you have correctly installed the latest version (reboot?).");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set version string
|
||||
char version[0x100] = {0};
|
||||
Result rc = sysclkIpcGetVersionString(version, sizeof(version));
|
||||
if (R_SUCCEEDED(rc))
|
||||
{
|
||||
brls::Application::setCommonFooter(std::string(version));
|
||||
}
|
||||
else
|
||||
{
|
||||
brls::Logger::error("Unable to get sys-clk version string");
|
||||
brls::Application::setCommonFooter("[unknown]");
|
||||
}
|
||||
|
||||
// Initialize services with a PC shim
|
||||
nsInitialize();
|
||||
|
||||
// Create root view
|
||||
MainFrame *mainFrame = new MainFrame();
|
||||
|
||||
// Add the root view to the stack
|
||||
brls::Application::pushView(mainFrame);
|
||||
}
|
||||
|
||||
// Run the app
|
||||
while (brls::Application::mainLoop());
|
||||
|
||||
// Exit
|
||||
nsExit();
|
||||
sysclkIpcExit();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019-2020 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "main_frame.h"
|
||||
|
||||
#include "status_tab.h"
|
||||
#include "advanced_settings_tab.h"
|
||||
#include "app_profiles_tab.h"
|
||||
// #include "cheat_sheet_tab.h"
|
||||
#include "about_tab.h"
|
||||
#include "logo.h"
|
||||
|
||||
#include "ipc/client.h"
|
||||
|
||||
MainFrame::MainFrame() : TabFrame()
|
||||
{
|
||||
// Start refresh task
|
||||
this->refreshTask = new RefreshTask();
|
||||
this->refreshTask->start();
|
||||
|
||||
// Load UI
|
||||
this->setIcon(new Logo(LogoStyle::HEADER));
|
||||
|
||||
AppProfilesTab *tab = new AppProfilesTab();
|
||||
|
||||
this->addTab("Status", new StatusTab(this->refreshTask));
|
||||
this->addTab("Application Profiles", tab);
|
||||
this->addTab("Advanced Settings", new AdvancedSettingsTab());
|
||||
|
||||
this->addSeparator();
|
||||
|
||||
// this->addTab("Cheat Sheet", new CheatSheetTab());
|
||||
this->addTab("About", new AboutTab());
|
||||
}
|
||||
|
||||
MainFrame::~MainFrame()
|
||||
{
|
||||
this->refreshTask->stop();
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#include "refresh_task.h"
|
||||
|
||||
class MainFrame : public brls::TabFrame
|
||||
{
|
||||
private:
|
||||
RefreshTask *refreshTask;
|
||||
|
||||
public:
|
||||
MainFrame();
|
||||
~MainFrame();
|
||||
};
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "refresh_task.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define REFRESH_INTERVAL 400
|
||||
|
||||
RefreshTask::RefreshTask() : RepeatingTask(REFRESH_INTERVAL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RefreshTask::onStart()
|
||||
{
|
||||
Result rc = sysclkIpcGetCurrentContext(&this->oldContext);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
brls::Logger::error("Unable to get context");
|
||||
errorResult("sysclkIpcGetCurrentContext", rc);
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshTask::run(retro_time_t currentTime)
|
||||
{
|
||||
RepeatingTask::run(currentTime);
|
||||
|
||||
// Get new context
|
||||
SysClkContext context;
|
||||
if (R_SUCCEEDED(sysclkIpcGetCurrentContext(&context)))
|
||||
{
|
||||
// CPU Freq
|
||||
if (context.freqs[SysClkModule_CPU] != this->oldContext.freqs[SysClkModule_CPU])
|
||||
this->freqUpdateEvent.fire(SysClkModule_CPU, context.freqs[SysClkModule_CPU]);
|
||||
|
||||
// GPU Freq
|
||||
if (context.freqs[SysClkModule_GPU] != this->oldContext.freqs[SysClkModule_GPU])
|
||||
this->freqUpdateEvent.fire(SysClkModule_GPU, context.freqs[SysClkModule_GPU]);
|
||||
|
||||
// MEM Freq
|
||||
if (context.freqs[SysClkModule_MEM] != this->oldContext.freqs[SysClkModule_MEM])
|
||||
this->freqUpdateEvent.fire(SysClkModule_MEM, context.freqs[SysClkModule_MEM]);
|
||||
|
||||
// Application ID
|
||||
if (context.applicationId != this->oldContext.applicationId)
|
||||
this->appIdUpdateEvent.fire(context.applicationId);
|
||||
|
||||
// Profile
|
||||
if (context.profile != this->oldContext.profile)
|
||||
this->profileUpdateEvent.fire(context.profile);
|
||||
|
||||
// Only notify temp changes every other tick
|
||||
if (this->shouldNotifyTempChange)
|
||||
{
|
||||
// PCB Temp
|
||||
if (context.temps[SysClkThermalSensor_PCB] != this->oldContext.temps[SysClkThermalSensor_PCB])
|
||||
this->tempUpdateEvent.fire(SysClkThermalSensor_PCB, context.temps[SysClkThermalSensor_PCB]);
|
||||
|
||||
//SoC Temp
|
||||
if (context.temps[SysClkThermalSensor_SOC] != this->oldContext.temps[SysClkThermalSensor_SOC])
|
||||
this->tempUpdateEvent.fire(SysClkThermalSensor_SOC, context.temps[SysClkThermalSensor_SOC]);
|
||||
|
||||
//Skin Temp
|
||||
if (context.temps[SysClkThermalSensor_Skin] != this->oldContext.temps[SysClkThermalSensor_Skin])
|
||||
this->tempUpdateEvent.fire(SysClkThermalSensor_Skin, context.temps[SysClkThermalSensor_Skin]);
|
||||
}
|
||||
|
||||
this->shouldNotifyTempChange = !this->shouldNotifyTempChange;
|
||||
this->oldContext = context;
|
||||
}
|
||||
else
|
||||
{
|
||||
brls::Logger::error("Unable to refresh context");
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#include "ipc/client.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
typedef brls::Event<SysClkModule, uint32_t> FreqUpdateEvent;
|
||||
typedef brls::Event<uint64_t> AppIdUpdateEvent;
|
||||
typedef brls::Event<SysClkProfile> ProfileUpdateEvent;
|
||||
typedef brls::Event<SysClkThermalSensor, uint32_t> TempUpdateEvent;
|
||||
|
||||
class RefreshTask : public brls::RepeatingTask
|
||||
{
|
||||
private:
|
||||
SysClkContext oldContext;
|
||||
|
||||
FreqUpdateEvent freqUpdateEvent;
|
||||
AppIdUpdateEvent appIdUpdateEvent;
|
||||
ProfileUpdateEvent profileUpdateEvent;
|
||||
TempUpdateEvent tempUpdateEvent;
|
||||
|
||||
bool shouldNotifyTempChange = true;
|
||||
|
||||
public:
|
||||
RefreshTask();
|
||||
~RefreshTask() {}
|
||||
|
||||
void onStart() override;
|
||||
void run(retro_time_t currentTime) override;
|
||||
|
||||
inline FreqUpdateEvent::Subscription registerFreqListener(FreqUpdateEvent::Callback cb) {
|
||||
return this->freqUpdateEvent.subscribe(cb);
|
||||
}
|
||||
inline void unregisterFreqListener(FreqUpdateEvent::Subscription subscription) {
|
||||
this->freqUpdateEvent.unsubscribe(subscription);
|
||||
}
|
||||
|
||||
inline AppIdUpdateEvent::Subscription registerAppIdListener(AppIdUpdateEvent::Callback cb) {
|
||||
return this->appIdUpdateEvent.subscribe(cb);
|
||||
}
|
||||
inline void unregisterAppIdListener(AppIdUpdateEvent::Subscription subscription) {
|
||||
this->appIdUpdateEvent.unsubscribe(subscription);
|
||||
}
|
||||
|
||||
inline ProfileUpdateEvent::Subscription registerProfileListener(ProfileUpdateEvent::Callback cb) {
|
||||
return this->profileUpdateEvent.subscribe(cb);
|
||||
}
|
||||
inline void unregisterProfileListener(ProfileUpdateEvent::Subscription subscription) {
|
||||
this->profileUpdateEvent.unsubscribe(subscription);
|
||||
}
|
||||
|
||||
inline TempUpdateEvent::Subscription registerTempListener(TempUpdateEvent::Callback cb) {
|
||||
return this->tempUpdateEvent.subscribe(cb);
|
||||
}
|
||||
inline void unregisterTempListener(TempUpdateEvent::Subscription subscription) {
|
||||
this->tempUpdateEvent.unsubscribe(subscription);
|
||||
}
|
||||
};
|
||||
@@ -1,314 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "status_tab.h"
|
||||
|
||||
#include "ipc/client.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define DANGEROUS_TEMP_THRESHOLD 84000
|
||||
#define DANGEROUS_TEMP_COLOR nvgRGB(255, 85, 0)
|
||||
|
||||
StatusTab::StatusTab(RefreshTask *refreshTask) :
|
||||
brls::List(),
|
||||
refreshTask(refreshTask)
|
||||
{
|
||||
// Get context
|
||||
SysClkContext context;
|
||||
Result rc = sysclkIpcGetCurrentContext(&context);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
brls::Logger::error("Unable to get context");
|
||||
errorResult("sysclkIpcGetCurrentContext", rc);
|
||||
brls::Application::crash("Could not get the current sys-clk context, please check that it is correctly installed and enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Customize list
|
||||
this->setSpacing(this->getSpacing() / 2);
|
||||
this->setMarginBottom(20);
|
||||
|
||||
// Enabled option
|
||||
brls::ToggleListItem *serviceEnabledListItem = new brls::ToggleListItem("Enable service", context.enabled, "", "Yes", "No");
|
||||
|
||||
serviceEnabledListItem->getClickEvent()->subscribe([this, serviceEnabledListItem](View* view)
|
||||
{
|
||||
bool enabled = serviceEnabledListItem->getToggleState();
|
||||
brls::Logger::info("New service state = %d", enabled);
|
||||
|
||||
Result rc = sysclkIpcSetEnabled(enabled);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
brls::Logger::error("Unable to set enabled state");
|
||||
errorResult("sysclkIpcSetEnabled", rc);
|
||||
// TODO: Put it back to on / off
|
||||
}
|
||||
|
||||
this->refreshTask->fireNow();
|
||||
});
|
||||
|
||||
this->addView(serviceEnabledListItem);
|
||||
|
||||
// Frequencies
|
||||
brls::Header *hardwareHeader = new brls::Header("Hardware");
|
||||
this->addView(hardwareHeader);
|
||||
|
||||
StatusGrid *frequenciesLayout = new StatusGrid();
|
||||
frequenciesLayout->setSpacing(22);
|
||||
frequenciesLayout->setHeight(40);
|
||||
|
||||
this->cpuFreqCell = new StatusCell("CPU", formatFreq(context.freqs[SysClkModule_CPU]));
|
||||
this->gpuFreqCell = new StatusCell("GPU", formatFreq(context.freqs[SysClkModule_GPU]));
|
||||
this->memFreqCell = new StatusCell("MEM", formatFreq(context.freqs[SysClkModule_MEM]));
|
||||
|
||||
frequenciesLayout->addView(this->cpuFreqCell);
|
||||
frequenciesLayout->addView(this->gpuFreqCell);
|
||||
frequenciesLayout->addView(this->memFreqCell);
|
||||
|
||||
this->addView(frequenciesLayout);
|
||||
|
||||
// Temperatures
|
||||
StatusGrid *tempsLayout = new StatusGrid();
|
||||
tempsLayout->setSpacing(22);
|
||||
tempsLayout->setHeight(40);
|
||||
|
||||
this->skinTempCell = new StatusCell("Skin", formatTemp(context.temps[SysClkThermalSensor_Skin]));
|
||||
this->socTempCell = new StatusCell("SOC", formatTemp(context.temps[SysClkThermalSensor_SOC]));
|
||||
this->pcbTempCell = new StatusCell("PCB", formatTemp(context.temps[SysClkThermalSensor_PCB]));
|
||||
|
||||
if (context.temps[SysClkThermalSensor_SOC] > DANGEROUS_TEMP_THRESHOLD)
|
||||
this->socTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
||||
|
||||
if (context.temps[SysClkThermalSensor_PCB] > DANGEROUS_TEMP_THRESHOLD)
|
||||
this->pcbTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
||||
|
||||
if (context.temps[SysClkThermalSensor_Skin] > DANGEROUS_TEMP_THRESHOLD)
|
||||
this->skinTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
||||
|
||||
tempsLayout->addView(this->socTempCell);
|
||||
tempsLayout->addView(this->pcbTempCell);
|
||||
tempsLayout->addView(this->skinTempCell);
|
||||
|
||||
this->addView(tempsLayout);
|
||||
|
||||
// Info
|
||||
brls::Header *systemHeader = new brls::Header("System");
|
||||
this->addView(systemHeader);
|
||||
|
||||
InfoGrid *infoLayout = new InfoGrid();
|
||||
infoLayout->setSpacing(22);
|
||||
infoLayout->setHeight(40);
|
||||
|
||||
this->profileCell = new StatusCell("Profile", formatProfile(context.profile));
|
||||
this->tidCell = new StatusCell("Application ID", formatTid(context.applicationId));
|
||||
|
||||
infoLayout->addView(this->profileCell);
|
||||
infoLayout->addView(this->tidCell);
|
||||
|
||||
this->addView(infoLayout);
|
||||
|
||||
// Warning label
|
||||
warningLabel = new brls::Label(brls::LabelStyle::SMALL, "");
|
||||
|
||||
warningLabel->setVerticalAlign(NVG_ALIGN_BOTTOM);
|
||||
warningLabel->setHorizontalAlign(NVG_ALIGN_RIGHT);
|
||||
|
||||
this->addView(warningLabel, true);
|
||||
|
||||
updateWarningForProfile(context.profile, false);
|
||||
|
||||
// Setup refresh task
|
||||
this->freqListenerSub = refreshTask->registerFreqListener([this](SysClkModule module, uint32_t freq) {
|
||||
switch(module)
|
||||
{
|
||||
case SysClkModule_CPU:
|
||||
this->cpuFreqCell->setValue(formatFreq(freq));
|
||||
break;
|
||||
case SysClkModule_GPU:
|
||||
this->gpuFreqCell->setValue(formatFreq(freq));
|
||||
break;
|
||||
case SysClkModule_MEM:
|
||||
this->memFreqCell->setValue(formatFreq(freq));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
this->appIdListenerSub = refreshTask->registerAppIdListener([this](uint64_t tid) {
|
||||
this->tidCell->setValue(formatTid(tid));
|
||||
});
|
||||
|
||||
this->profileListenerSub = refreshTask->registerProfileListener([this](SysClkProfile profile) {
|
||||
this->profileCell->setValue(formatProfile(profile));
|
||||
updateWarningForProfile(profile, true);
|
||||
});
|
||||
|
||||
this->tempListenerSub = refreshTask->registerTempListener([this](SysClkThermalSensor sensor, uint32_t temp) {
|
||||
switch (sensor)
|
||||
{
|
||||
case SysClkThermalSensor_PCB:
|
||||
this->pcbTempCell->setValue(formatTemp(temp));
|
||||
|
||||
if (temp > DANGEROUS_TEMP_THRESHOLD)
|
||||
this->pcbTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
||||
else
|
||||
this->pcbTempCell->resetValueColor();
|
||||
break;
|
||||
case SysClkThermalSensor_SOC:
|
||||
this->socTempCell->setValue(formatTemp(temp));
|
||||
|
||||
if (temp > DANGEROUS_TEMP_THRESHOLD)
|
||||
this->socTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
||||
else
|
||||
this->socTempCell->resetValueColor();
|
||||
|
||||
break;
|
||||
case SysClkThermalSensor_Skin:
|
||||
this->skinTempCell->setValue(formatTemp(temp));
|
||||
|
||||
if (temp > DANGEROUS_TEMP_THRESHOLD)
|
||||
this->skinTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
||||
else
|
||||
this->skinTempCell->resetValueColor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void StatusTab::updateWarningForProfile(SysClkProfile profile, bool animated)
|
||||
{
|
||||
// switch (profile)
|
||||
// {
|
||||
// case SysClkProfile_Handheld:
|
||||
// if (this->warningLabel->isHidden())
|
||||
// this->warningLabel->show([](){});
|
||||
// this->warningLabel->setText("\uE140 Handheld Mode: Max GPU freq: " + formatFreq(SYSCLK_GPU_HANDHELD_MAX_HZ));
|
||||
// break;
|
||||
// case SysClkProfile_HandheldChargingUSB:
|
||||
// if (this->warningLabel->isHidden())
|
||||
// this->warningLabel->show([](){});
|
||||
// this->warningLabel->setText("\uE140 USB Charging Mode: Max GPU freq: " + formatFreq(SYSCLK_GPU_CHARGING_USB_MAX_HZ));
|
||||
// break;
|
||||
// default:
|
||||
// if (!this->warningLabel->isHidden())
|
||||
// this->warningLabel->hide([](){}, animated);
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
StatusTab::~StatusTab()
|
||||
{
|
||||
refreshTask->unregisterFreqListener(this->freqListenerSub);
|
||||
refreshTask->unregisterAppIdListener(this->appIdListenerSub);
|
||||
refreshTask->unregisterProfileListener(this->profileListenerSub);
|
||||
refreshTask->unregisterTempListener(this->tempListenerSub);
|
||||
}
|
||||
|
||||
StatusGrid::StatusGrid()
|
||||
: BoxLayout(brls::BoxLayoutOrientation::HORIZONTAL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void StatusGrid::layout(NVGcontext* vg, brls::Style *style, brls::FontStash *stash)
|
||||
{
|
||||
// Distribute space equally between children
|
||||
if (!this->children.empty())
|
||||
{
|
||||
size_t size = this->children.size();
|
||||
unsigned width = (this->getWidth()- this->marginLeft - this->marginRight - this->getSpacing() * (size - 1)) / size;
|
||||
|
||||
for (brls::BoxLayoutChild *child : this->children)
|
||||
{
|
||||
if (!child->fill)
|
||||
child->view->setWidth(width);
|
||||
}
|
||||
}
|
||||
|
||||
// Layout normally
|
||||
BoxLayout::layout(vg, style, stash);
|
||||
}
|
||||
|
||||
InfoGrid::InfoGrid() : BoxLayout(brls::BoxLayoutOrientation::HORIZONTAL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void InfoGrid::layout(NVGcontext* vg, brls::Style *style, brls::FontStash *stash)
|
||||
{
|
||||
// Give first child one third of the view, give second child the rest
|
||||
if (this->children.size() >= 2)
|
||||
{
|
||||
size_t size = 3;
|
||||
unsigned firstWidth = (this->getWidth()- this->marginLeft - this->marginRight - this->getSpacing() * (size - 1)) / size;
|
||||
unsigned secondWidth = firstWidth * 2 + this->getSpacing();
|
||||
|
||||
this->children[0]->view->setWidth(firstWidth);
|
||||
this->children[1]->view->setWidth(secondWidth);
|
||||
}
|
||||
|
||||
// Layout normally
|
||||
BoxLayout::layout(vg, style, stash);
|
||||
}
|
||||
|
||||
StatusCell::StatusCell(std::string label, std::string value) : label(label), value(value)
|
||||
{
|
||||
this->resetValueColor();
|
||||
}
|
||||
|
||||
void StatusCell::setValue(std::string value)
|
||||
{
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
void StatusCell::draw(NVGcontext *vg, int x, int y, unsigned width, unsigned height, brls::Style *style, brls::FrameContext *ctx)
|
||||
{
|
||||
unsigned padding = 5;
|
||||
|
||||
// Label
|
||||
nvgBeginPath(vg);
|
||||
nvgFillColor(vg, a(ctx->theme->tableBodyTextColor));
|
||||
nvgFontSize(vg, 16);
|
||||
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE);
|
||||
nvgText(vg, x + padding, y + height / 2, this->label.c_str(), nullptr);
|
||||
|
||||
// Value
|
||||
nvgBeginPath(vg);
|
||||
nvgFillColor(vg, a(this->valueColor));
|
||||
nvgFontSize(vg, 20);
|
||||
nvgTextAlign(vg, NVG_ALIGN_RIGHT | NVG_ALIGN_BASELINE);
|
||||
nvgText(vg, x + width - padding, y + height / 2, this->value.c_str(), nullptr);
|
||||
}
|
||||
|
||||
void StatusCell::setValueColor(NVGcolor color)
|
||||
{
|
||||
this->valueColor = color;
|
||||
}
|
||||
|
||||
void StatusCell::resetValueColor()
|
||||
{
|
||||
this->valueColor = brls::Application::getThemeValues()->textColor;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#include "refresh_task.h"
|
||||
|
||||
class StatusCell : public brls::View
|
||||
{
|
||||
private:
|
||||
std::string label;
|
||||
std::string value;
|
||||
|
||||
NVGcolor valueColor;
|
||||
|
||||
public:
|
||||
StatusCell(std::string label, std::string value);
|
||||
|
||||
void draw(NVGcontext *vg, int x, int y, unsigned width, unsigned height, brls::Style *style, brls::FrameContext *ctx) override;
|
||||
|
||||
void setValue(std::string value);
|
||||
void setValueColor(NVGcolor color);
|
||||
void resetValueColor();
|
||||
};
|
||||
|
||||
class InfoGrid : public brls::BoxLayout
|
||||
{
|
||||
public:
|
||||
InfoGrid();
|
||||
|
||||
void layout(NVGcontext* vg, brls::Style *style, brls::FontStash *stash) override;
|
||||
};
|
||||
|
||||
class StatusGrid : public brls::BoxLayout
|
||||
{
|
||||
public:
|
||||
StatusGrid();
|
||||
|
||||
void layout(NVGcontext* vg, brls::Style *style, brls::FontStash *stash) override;
|
||||
};
|
||||
|
||||
class StatusTab : public brls::List
|
||||
{
|
||||
private:
|
||||
RefreshTask *refreshTask;
|
||||
|
||||
FreqUpdateEvent::Subscription freqListenerSub;
|
||||
AppIdUpdateEvent::Subscription appIdListenerSub;
|
||||
ProfileUpdateEvent::Subscription profileListenerSub;
|
||||
TempUpdateEvent::Subscription tempListenerSub;
|
||||
|
||||
StatusCell *cpuFreqCell;
|
||||
StatusCell *gpuFreqCell;
|
||||
StatusCell *memFreqCell;
|
||||
|
||||
StatusCell *socTempCell;
|
||||
StatusCell *pcbTempCell;
|
||||
StatusCell *skinTempCell;
|
||||
|
||||
StatusCell *profileCell;
|
||||
StatusCell *tidCell;
|
||||
|
||||
brls::Label *warningLabel;
|
||||
|
||||
void updateWarningForProfile(SysClkProfile profile, bool animated);
|
||||
|
||||
public:
|
||||
StatusTab(RefreshTask *refreshTask);
|
||||
~StatusTab();
|
||||
};
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
std::string formatFreq(uint32_t freq)
|
||||
{
|
||||
char str[16];
|
||||
snprintf(str, sizeof(str), "%.1f MHz", (float)freq / 1000000.0f);
|
||||
return std::string(str);
|
||||
}
|
||||
|
||||
std::string formatTid(uint64_t tid)
|
||||
{
|
||||
char str[17];
|
||||
snprintf(str, sizeof(str), "%016lX", tid);
|
||||
return std::string(str);
|
||||
}
|
||||
|
||||
std::string formatProfile(SysClkProfile profile)
|
||||
{
|
||||
return std::string(sysclkFormatProfile(profile, true));
|
||||
}
|
||||
|
||||
std::string formatTemp(uint32_t temp)
|
||||
{
|
||||
char str[16];
|
||||
snprintf(str, sizeof(str), "%.1f °C", (float)temp / 1000.0f);
|
||||
return std::string(str);
|
||||
}
|
||||
|
||||
void errorResult(std::string tag, Result rc)
|
||||
{
|
||||
#ifdef __SWITCH__
|
||||
brls::Logger::error("[0x%x] %s failed - %04d-%04d", rc, tag.c_str(), R_MODULE(rc), R_DESCRIPTION(rc));
|
||||
#else
|
||||
brls::Logger::error("[0x%x] %s failed - xxxx-xxxx", rc, tag.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: Merge ticker for single line labels in Borealis and remove usage of this
|
||||
std::string formatListItemTitle(const std::string str, size_t maxScore) {
|
||||
size_t score = 0;
|
||||
for (size_t i = 0; i < str.length(); i++)
|
||||
{
|
||||
score += std::isupper(str[i]) ? 4 : 3;
|
||||
if(score > maxScore)
|
||||
{
|
||||
return str.substr(0, i-1) + "\u2026";
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
brls::SelectListItem* createFreqListItem(SysClkModule module, uint32_t selectedFreqInMhz, std::string defaultString)
|
||||
{
|
||||
std::string name;
|
||||
uint32_t* table;
|
||||
|
||||
switch (module)
|
||||
{
|
||||
case SysClkModule_CPU:
|
||||
name = "CPU Frequency";
|
||||
table = g_freq_table_cpu_hz;
|
||||
break;
|
||||
case SysClkModule_GPU:
|
||||
name = "GPU Frequency";
|
||||
table = g_freq_table_gpu_hz;
|
||||
break;
|
||||
case SysClkModule_MEM:
|
||||
name = "MEM Frequency";
|
||||
table = g_freq_table_mem_hz;
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t selected = 0;
|
||||
size_t i = 0;
|
||||
|
||||
std::vector<std::string> clocks;
|
||||
|
||||
clocks.push_back(defaultString);
|
||||
|
||||
while (table[i] != 0)
|
||||
{
|
||||
uint32_t freq = table[i];
|
||||
|
||||
if (freq / 1000000 == selectedFreqInMhz)
|
||||
selected = i + 1;
|
||||
|
||||
char clock[16];
|
||||
if (freq == 1862400000)
|
||||
snprintf(clock, sizeof(clock), "Maximum");
|
||||
else
|
||||
snprintf(clock, sizeof(clock), "%d MHz", freq / 1000000);
|
||||
|
||||
clocks.push_back(std::string(clock));
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return new brls::SelectListItem(name, clocks, selected);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
sys-clk manager, a sys-clk frontend homebrew
|
||||
Copyright (C) 2019 natinusala
|
||||
Copyright (C) 2019 p-sam
|
||||
Copyright (C) 2019 m4xw
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <sysclk/clocks.h>
|
||||
#include "ipc/ipc.h"
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#define APP_ASSET(p) APP_RESOURCES p
|
||||
|
||||
std::string formatListItemTitle(const std::string str, size_t maxScore = 140);
|
||||
brls::SelectListItem* createFreqListItem(SysClkModule module, uint32_t selectedFreqInMhz, std::string defaultString = "Do not override");
|
||||
|
||||
std::string formatFreq(uint32_t freq);
|
||||
std::string formatTid(uint64_t tid);
|
||||
std::string formatProfile(SysClkProfile profile);
|
||||
std::string formatTemp(uint32_t temp);
|
||||
|
||||
void errorResult(std::string tag, Result rc);
|
||||
Reference in New Issue
Block a user