Skip to content

Commit

Permalink
Some fixes, add emuiibo code, add custom exception handling...
Browse files Browse the repository at this point in the history
  • Loading branch information
XorTroll committed Dec 16, 2019
1 parent 80c2b0d commit 5792a86
Show file tree
Hide file tree
Showing 12 changed files with 358 additions and 88 deletions.
3 changes: 2 additions & 1 deletion Goldleaf/Include/Types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,5 @@ bool HasKeyFile();
bool IsAtmosphere();
u64 GetCurrentApplicationId();
u32 RandomFromRange(u32 Min, u32 Max);
void EnsureDirectories();
void EnsureDirectories();
void Close();
53 changes: 51 additions & 2 deletions Goldleaf/Include/nfp/nfp_Emuiibo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,61 @@

namespace nfp::emu
{
constexpr SmServiceName EmuServiceName = smEncodeName("nfp:emu");
#define NFP_EMU_SERVICE "nfp:emu"

bool IsEmuiiboPresent();
constexpr SmServiceName ServiceName = smEncodeName(NFP_EMU_SERVICE);

bool IsEmuiiboAccessible();

Result Initialize();
void Exit();

namespace result
{
constexpr u32 Module = 352;

constexpr Result ResultNoAmiiboLoaded = MAKERESULT(Module, 1);
constexpr Result ResultUnableToMove = MAKERESULT(Module, 2);
constexpr Result ResultStatusOff = MAKERESULT(Module, 3);
}

enum class EmulationStatus : u32
{
OnForever,
OnOnce,
Off
};

NX_CONSTEXPR bool StatusIsOn(EmulationStatus status)
{
return status != EmulationStatus::Off;
}

struct Version
{
u8 major;
u8 minor;
u8 micro;
bool dev_build;
};

static_assert(sizeof(Version) == sizeof(u32), "Invalid nfp:emu Version!");

Result GetCurrentAmiibo(char *out, size_t out_len);
Result SetCustomAmiibo(const char *path);
Result HasCustomAmiibo(bool *out_has);
Result ResetCustomAmiibo();
Result SetEmulationOnForever();
Result SetEmulationOnOnce();
Result SetEmulationOff();
Result MoveToNextAmiibo();
Result GetStatus(EmulationStatus *out);
Result Refresh();
Result GetVersion(Version *out_ver);

String SaveAmiiboImageById(String id);

String GetAmiiboIdFromPath(String amiibo);

// TODO: implement emuiibo 0.4.0's commands
}
2 changes: 1 addition & 1 deletion Goldleaf/Include/ui/ui_ClickableImage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace ui
bool IsImageValid();
void SetOnClick(std::function<void()> Callback);
void OnRender(pu::ui::render::Renderer::Ref &Drawer, s32 X, s32 Y);
void OnInput(u64 Down, u64 Up, u64 Held, pu::ui::Touch Pos);
void OnInput(u64 down, u64 up, u64 held, pu::ui::Touch Pos);
protected:
String img;
pu::ui::render::NativeTexture ntex;
Expand Down
28 changes: 14 additions & 14 deletions Goldleaf/Include/ui/ui_MainApplication.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,23 @@ namespace ui
void LoadMenuData(String Name, std::string ImageName, String TempHead, bool CommonIcon = true);
void LoadMenuHead(String Head);
void UnloadMenuData();
void browser_Input(u64 Down, u64 Up, u64 Held);
void exploreMenu_Input(u64 Down, u64 Up, u64 Held);
void pcExplore_Input(u64 Down, u64 Up, u64 Held);
void fileContent_Input(u64 Down, u64 Up, u64 Held);
void contentInformation_Input(u64 Down, u64 Up, u64 Held);
void storageContents_Input(u64 Down, u64 Up, u64 Held);
void contentManager_Input(u64 Down, u64 Up, u64 Held);
void unusedTickets_Input(u64 Down, u64 Up, u64 Held);
void account_Input(u64 Down, u64 Up, u64 Held);
void amiibo_Input(u64 Down, u64 Up, u64 Held);
void settings_Input(u64 Down, u64 Up, u64 Held);
void memory_Input(u64 Down, u64 Up, u64 Held);
void about_Input(u64 Down, u64 Up, u64 Held);
void browser_Input(u64 down, u64 up, u64 held);
void exploreMenu_Input(u64 down, u64 up, u64 held);
void pcExplore_Input(u64 down, u64 up, u64 held);
void fileContent_Input(u64 down, u64 up, u64 held);
void contentInformation_Input(u64 down, u64 up, u64 held);
void storageContents_Input(u64 down, u64 up, u64 held);
void contentManager_Input(u64 down, u64 up, u64 held);
void unusedTickets_Input(u64 down, u64 up, u64 held);
void account_Input(u64 down, u64 up, u64 held);
void amiibo_Input(u64 down, u64 up, u64 held);
void settings_Input(u64 down, u64 up, u64 held);
void memory_Input(u64 down, u64 up, u64 held);
void about_Input(u64 down, u64 up, u64 held);
void userImage_OnClick();
void helpImage_OnClick();
void ReloadUser(AccountUid User);
void OnInput(u64 Down, u64 Up, u64 Held);
void OnInput(u64 down, u64 up, u64 held);
MainMenuLayout::Ref &GetMainMenuLayout();
PartitionBrowserLayout::Ref &GetBrowserLayout();
FileContentLayout::Ref &GetFileContentLayout();
Expand Down
2 changes: 2 additions & 0 deletions Goldleaf/Include/ui/ui_MainMenuLayout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace ui
void webMenuItem_Click();
void accountMenuItem_Click();
void amiiboMenuItem_Click();
void emuiiboMenuItem_Click();
void settingsMenuItem_Click();
void updateMenuItem_Click();
void aboutMenuItem_Click();
Expand All @@ -46,6 +47,7 @@ namespace ui
pu::ui::elm::MenuItem::Ref webMenuItem;
pu::ui::elm::MenuItem::Ref accountMenuItem;
pu::ui::elm::MenuItem::Ref amiiboMenuItem;
pu::ui::elm::MenuItem::Ref emuiiboMenuItem;
pu::ui::elm::MenuItem::Ref settingsMenuItem;
pu::ui::elm::MenuItem::Ref updateMenuItem;
pu::ui::elm::MenuItem::Ref aboutMenuItem;
Expand Down
81 changes: 67 additions & 14 deletions Goldleaf/Source/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,74 @@
*/

#include <ui/ui_MainApplication.hpp>
#include <sys/stat.h>
#include <cstdlib>
#include <ctime>
#include <iostream>

extern char *fake_heap_end;
void *new_heap_addr = NULL;
extern char** __system_argv;

ui::MainApplication::Ref mainapp;
set::Settings gsets;
bool gupdated = false;

static constexpr u64 HeapSize = 0x10000000;
alignas(16) u8 __nx_exception_stack[0x1000];
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);

u64 GetBaseAddress()
{
u32 p;
MemoryInfo info;

// Find the memory region in which the function itself is stored.
// The start of it will be the base address the homebrew was mapped to.
svcQueryMemory(&info, &p, (u64) &GetBaseAddress);

return info.addr;
}

struct StackFrame
{
u64 fp; // Frame Pointer (Pointer to previous stack frame)
u64 lr; // Link Register (Return address)
};

void UnwindStack(u64 *outStackTrace, s32 *outStackTraceSize, size_t maxStackTraceSize, u64 currFp)
{
for (size_t i = 0; i < maxStackTraceSize; i++) {
if (currFp == 0 || currFp % sizeof(u64) != 0)
break;

auto currTrace = reinterpret_cast<StackFrame*>(currFp);
outStackTrace[(*outStackTraceSize)++] = currTrace->lr;
currFp = currTrace->fp;
}
}

void Exit();

extern "C"
{
void __libnx_exception_handler(ThreadExceptionDump *context)
{
u64 stackTrace[0x20] = {0};
s32 stackTraceSize = 0;
UnwindStack(stackTrace, &stackTraceSize, 0x20, context->fp.x);
auto baseaddr = GetBaseAddress();
auto pcstr = hos::FormatHex(context->pc.x - baseaddr);

auto fname = "report_" + std::to_string(rand()) + ".log";
String crashtxt = "\nGoldleaf crash report\n\n";
crashtxt += String(" - Goldleaf version: ") + GOLDLEAF_VERSION + "\n - Current time: " + hos::GetCurrentTime() + "\n - Crash address: " + pcstr;
std::ofstream ofs("sdmc:/" + consts::Root + "/crash/" + fname);
if(ofs.good())
{
ofs << crashtxt.AsUTF8();
ofs.close();
}

Exit();
}
}

void Panic(std::string msg)
{
// TODO: non-console panic!
Expand Down Expand Up @@ -81,6 +133,14 @@ void Initialize()

void Exit()
{
// If Goldleaf updated itself in this session...
if(gupdated)
{
romfsExit();
fs::DeleteFile(__system_argv[0]);
fs::RenameFile(consts::TempUpdatePath, __system_argv[0]);
}

auto fsopsbuf = fs::GetFileSystemOperationsBuffer();
operator delete[](fsopsbuf, std::align_val_t(0x1000));
auto nsys = fs::GetNANDSystemExplorer();
Expand All @@ -106,9 +166,10 @@ void Exit()
ncmExit();
nifmExit();
pdmqryExit();
Close();
}

int main(int argc, char **argv)
int main()
{
Initialize();

Expand All @@ -117,14 +178,6 @@ int main(int argc, char **argv)

mainapp->Prepare();
mainapp->ShowWithFadeIn();

// If Goldleaf updated itself in this session...
if(gupdated)
{
romfsExit();
fs::DeleteFile(argv[0]);
fs::RenameFile(consts::TempUpdatePath, argv[0]);
}

Exit();
return 0;
Expand Down
9 changes: 9 additions & 0 deletions Goldleaf/Source/Types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace consts
{
std::string Root = "switch/Goldleaf";
std::string Log = Root + "/Goldleaf.log";
std::string CrashesDir = Root + "/crash";
std::string TempUpdatePath = Root + "/UpdateTemp.nro";
}

Expand Down Expand Up @@ -145,8 +146,16 @@ void EnsureDirectories()
sd->CreateDirectory(consts::Root + "/meta");
sd->CreateDirectory(consts::Root + "/title");
sd->CreateDirectory(consts::Root + "/dump");
sd->CreateDirectory(consts::Root + "/crash");
sd->CreateDirectory(consts::Root + "/amiibocache");
sd->CreateDirectory(consts::Root + "/userdata");
sd->CreateDirectory(consts::Root + "/dump/temp");
sd->CreateDirectory(consts::Root + "/dump/update");
sd->CreateDirectory(consts::Root + "/dump/title");
}

void Close()
{
if(GetLaunchMode() == LaunchMode::Application) libappletRequestHomeMenu();
else exit(0);
}
Loading

0 comments on commit 5792a86

Please sign in to comment.