Skip to content

Commit

Permalink
implemented fastCFWswitch overlay
Browse files Browse the repository at this point in the history
  • Loading branch information
Hartie95 committed Apr 14, 2020
1 parent 62aba15 commit 41fc264
Show file tree
Hide file tree
Showing 16 changed files with 491 additions and 17 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "libs/libtesla"]
path = libs/libtesla
url = https://github.com/WerWolv/libtesla
[submodule "libs/inih"]
path = libs/inih
url = https://github.com/benhoyt/inih.git
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ include $(DEVKITPRO)/libnx/switch_rules
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
# NACP building is skipped as well.
#---------------------------------------------------------------------------------
APP_TITLE := Tesla Overlay Template
APP_TITLE := fastCFWswitch
APP_VERSION := 1.0.0

TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
SOURCES := source libs/inih
DATA := data
INCLUDES := include libs/libtesla/include
INCLUDES := include libs/libtesla/include libs/inih

NO_ICON := 1

Expand All @@ -56,7 +56,7 @@ ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
CFLAGS := -g -Wall -O2 -ffunction-sections \
$(ARCH) $(DEFINES)

CFLAGS += $(INCLUDE) -D__SWITCH__
CFLAGS += $(INCLUDE) -I -D__SWITCH__

CXXFLAGS := $(CFLAGS) -fno-exceptions -std=c++17

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Tesla-Template
A template repository for Tesla Overlay Homebrews
# fastCFWswitch
A tesla based overlay to boot into different payloads on the Nintendo Switch.
1 change: 1 addition & 0 deletions libs/inih
Submodule inih added at 351217
2 changes: 1 addition & 1 deletion libs/libtesla
18 changes: 18 additions & 0 deletions out/config/fastCFWSwitch/config.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[CFWS]
type=section
name=cfws

[ATMOSPHERE]
name=atmosphere
path=/atmosphere/reboot_payload.bin

[SXOS]
name=SxOS
path=/sxos/reboot_payload.bin

[TOOLS]
name=Tools

[HEKATE]
name=Hekate
path=/hekate_ctcaer_4.9.1.bin
161 changes: 161 additions & 0 deletions source/configParser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#include "configParser.h"
#include "ini.h"
#include <map>
#include <list>
#include <sstream>

#include "section.h"
#include "payload.h"

using namespace fastCFWSwitcher;

namespace fastCFWSwitcher {
class ConfigEntry{
public:
ConfigEntry(std::string section, int pos) : section(section), pos(pos){
this->type.assign("payload");
}
void setType(const char * type){
this->type.assign(type);
}
void setName(const char * name){
this->name.assign(name);
}
void setPath(const char * path){
this->path.assign(path);
}

Element* toElement(){
if(type == "section" || path.empty()){
return (Element*) new Section(name);
} else if(type == "payload"){
return (Element*) new Payload(name, path);
}
return nullptr;
}

static bool comparePos(const ConfigEntry* first, const ConfigEntry* second)
{
return (first->pos < second->pos);
}

std::string section;
int pos;
std::string type;
std::string name;
std::string path;
private:
};
}

int handler(void *user, const char *section, const char *name, const char *value)

{
std::map<std::string, fastCFWSwitcher::ConfigEntry*>* elementsMap = (std::map<std::string, fastCFWSwitcher::ConfigEntry*>*) user;

std::string sectionString(section);
fastCFWSwitcher::ConfigEntry* configEntry ;

std::map<std::string, fastCFWSwitcher::ConfigEntry*>::iterator it = elementsMap->find(sectionString);
if( it != elementsMap->end() ){
configEntry = it->second;
} else {
configEntry = new fastCFWSwitcher::ConfigEntry(sectionString, elementsMap->size());
elementsMap->insert(std::pair<std::string, fastCFWSwitcher::ConfigEntry*>(sectionString, configEntry));
}

if (!strcmp("type", name) ) {
configEntry->setType(value);
} else if (!strcmp("name", name) ) {
configEntry->setName(value);
} else if (!strcmp("path", name)) {
configEntry->setPath(value);
}
return 1;
}

void ConfigParser::setError(std::string errorString){
this->list->addItem(new tsl::elm::CategoryHeader(errorString));
}

std::list<Element*>* ConfigParser::getElements(){

// Read settings file

FsFileSystem fsSdmc;

if(R_FAILED(fsOpenSdCardFileSystem(&fsSdmc))){
setError("open sd failed\n");
return nullptr;
}

/* Open config file. */
FsFile fileConfig;
if (R_FAILED(fsFsOpenFile(&fsSdmc, this->filePath, FsOpenMode_Read, &fileConfig))){
setError("open config file failed ");
fsFsClose(&fsSdmc);
return nullptr;
}


/* Get config file size. */
s64 configFileSize;
if (R_FAILED(fsFileGetSize(&fileConfig, &configFileSize))){
setError("get file size failed\n");
fsFileClose(&fileConfig);
fsFsClose(&fsSdmc);
return nullptr;
}

std::vector<char> fileString(configFileSize+1);
fileString[configFileSize] = 0;

u64 readSize;
Result rc = fsFileRead(&fileConfig, 0, &fileString[0], configFileSize, FsReadOption_None, &readSize);
if (R_FAILED(rc) || readSize != static_cast<u64>(configFileSize)){
setError("read file failed\n");
fsFileClose(&fileConfig);
fsFsClose(&fsSdmc);
return nullptr;
}

fsFileClose(&fileConfig);
fsFsClose(&fsSdmc);


//parse ini file
std::map<std::string, fastCFWSwitcher::ConfigEntry*> elementsMap;

int config_err = ini_parse_string(&fileString[0], handler, &elementsMap);
if(config_err<0){
setError("An error occured.");
return nullptr;
} else if(config_err>0){
std::stringstream ss;
ss<< std::hex << config_err; // int decimal_value
std::string res ( ss.str() );
setError("Bad config file, first error on line "+res);
return nullptr;
}
std::list<fastCFWSwitcher::ConfigEntry*>* elementsList = new std::list<fastCFWSwitcher::ConfigEntry*>();
for (auto const& x : elementsMap)
{
elementsList->push_back(x.second);
}

elementsList->sort(fastCFWSwitcher::ConfigEntry::comparePos);

std::list<fastCFWSwitcher::Element*>* payloadList = new std::list<fastCFWSwitcher::Element*>();

for (fastCFWSwitcher::ConfigEntry* entry : *elementsList)
{
fastCFWSwitcher::Element* element = entry->toElement();
if(element!=nullptr){
payloadList->push_back(element);
//setError(x.second->path);
} else {
setError("error "+entry->section);
}
}
return payloadList;
}
22 changes: 22 additions & 0 deletions source/configParser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once
#include <tesla.hpp>
#include "element.h"
#include <list>

#define CONFIG_FILE_PATH "/config/fastCFWSwitch/config.ini"

namespace fastCFWSwitcher{
class ConfigParser{
public:
ConfigParser(const char* filePath, tsl::elm::List* list) : filePath(filePath), list(list){
};
~ConfigParser(){
}
std::list<fastCFWSwitcher::Element*>* getElements();
void setError(std::string errorString);

private:
const char* filePath;
tsl::elm::List* list;
};
}
10 changes: 10 additions & 0 deletions source/element.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once
#include <tesla.hpp>
namespace fastCFWSwitcher{
class PayloadHandler;

class Element{
public:
virtual tsl::elm::ListItem* toListItem(fastCFWSwitcher::PayloadHandler* payloadHandler) = 0;
};
}
45 changes: 35 additions & 10 deletions source/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#define TESLA_INIT_IMPL // If you have more than one file using the tesla header, only define this in the main one
#include <tesla.hpp> // The Tesla Header
#include "payloadHandler.h"
#include "payload.h"
#include "section.h"
#include "configParser.h"


class GuiTest : public tsl::Gui {
Expand All @@ -9,15 +13,35 @@ class GuiTest : public tsl::Gui {
// Called when this Gui gets loaded to create the UI
// Allocate all elements on the heap. libtesla will make sure to clean them up when not needed anymore
virtual tsl::elm::Element* createUI() override {
// A OverlayFrame is the base element every overlay consists of. This will draw the default Title and Subtitle.
// If you need more information in the header or want to change it's look, use a HeaderOverlayFrame.
auto frame = new tsl::elm::OverlayFrame("Tesla Example", "v1.3.1");

// A list that can contain sub elements and handles scrolling
auto frame = new tsl::elm::OverlayFrame("Switch CFW", "v1.0.0");
auto list = new tsl::elm::List();

// Create and add a new list item to the list
list->addItem(new tsl::elm::ListItem("Default List Item"));
fastCFWSwitcher::ConfigParser* configParser = new fastCFWSwitcher::ConfigParser(CONFIG_FILE_PATH, list);
fastCFWSwitcher::PayloadHandler* payloadHandler = new fastCFWSwitcher::PayloadHandler(frame);


std::list<fastCFWSwitcher::Element*>* payloadList = configParser->getElements();

/*fastCFWSwitcher::Element* payload = (fastCFWSwitcher::Element*) new fastCFWSwitcher::Payload("atmosphere", "/atmosphere/reboot_payload.bin");
payloadList.push_back(payload);
payload = (fastCFWSwitcher::Element*) new fastCFWSwitcher::Payload("SXOS", "/sxos/reboot_payload.bin");
payloadList.push_back(payload);
payload = (fastCFWSwitcher::Element*) new fastCFWSwitcher::Section("Tools");
payloadList.push_back(payload);
payload = (fastCFWSwitcher::Element*) new fastCFWSwitcher::Payload("Hekate", "/bootloader/reboot_payload.bin");
payloadList.push_back(payload);
*/

if(payloadList!=nullptr){
for(fastCFWSwitcher::Element* curPayload : *payloadList){
auto item = curPayload->toListItem(payloadHandler);
list->addItem(item);
}
} else {
list->addItem(new tsl::elm::CategoryHeader("list is null"));
}

// Add the list to the frame for it to be drawn
frame->setContent(list);
Expand All @@ -35,9 +59,10 @@ class GuiTest : public tsl::Gui {
virtual bool handleInput(u64 keysDown, u64 keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
return false; // Return true here to singal the inputs have been consumed
}

};

class OverlayTest : public tsl::Overlay {
class FastCFWSwitchOverlay : public tsl::Overlay {
public:
// libtesla already initialized fs, hid, pl, pmdmnt, hid:sys and set:sys
virtual void initServices() override {} // Called at the start to initialize all services necessary for this Overlay
Expand All @@ -52,5 +77,5 @@ class OverlayTest : public tsl::Overlay {
};

int main(int argc, char **argv) {
return tsl::loop<OverlayTest>(argc, argv);
}
return tsl::loop<FastCFWSwitchOverlay>(argc, argv);
}
23 changes: 23 additions & 0 deletions source/payload.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "payload.h"
#include "payloadHandler.h"
#include "element.h"

using namespace fastCFWSwitcher;
using namespace tsl::elm;




ListItem* Payload::toListItem(PayloadHandler* payloadHandler){
auto item = new ListItem(this->name);
std::function<bool(u64)> onClick = [item, payloadHandler, this](u64 keys) {
if(keys & KEY_A){
item->setText("rebooting");
payloadHandler->rebootToPayload(this);
return true;
}
return false;
};
item->setClickListener(onClick);
return item;
}
21 changes: 21 additions & 0 deletions source/payload.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once
#include <tesla.hpp>
#include "element.h"

namespace fastCFWSwitcher {
class Payload : Element {

public:
Payload(std::string name, std::string path) : name(name), path(path){
}
~Payload(){};
tsl::elm::ListItem* toListItem(fastCFWSwitcher::PayloadHandler* payloadHandler);
std::string getPath(){
return path;
}

private:
std::string name;
std::string path;
};
}
Loading

0 comments on commit 41fc264

Please sign in to comment.