Initial Commit
This commit is contained in:
270
TegraExplorer/source/tegraexplorer/mainmenu.c
Normal file
270
TegraExplorer/source/tegraexplorer/mainmenu.c
Normal file
@@ -0,0 +1,270 @@
|
||||
#include "mainmenu.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../gfx/menu.h"
|
||||
#include "tools.h"
|
||||
#include "../hid/hid.h"
|
||||
#include "../fs/menus/explorer.h"
|
||||
#include <utils/btn.h>
|
||||
#include <storage/nx_sd.h>
|
||||
#include "tconf.h"
|
||||
#include "../keys/keys.h"
|
||||
#include "../storage/mountmanager.h"
|
||||
#include "../storage/gptmenu.h"
|
||||
#include "../storage/emummc.h"
|
||||
#include <utils/util.h>
|
||||
#include "../fs/fsutils.h"
|
||||
#include <soc/fuse.h>
|
||||
#include "../utils/utils.h"
|
||||
#include "../config.h"
|
||||
#include "../fs/readers/folderReader.h"
|
||||
#include <string.h>
|
||||
#include <mem/heap.h>
|
||||
#include "../fs/menus/filemenu.h"
|
||||
|
||||
#define INCLUDE_BUILTIN_SCRIPTS 1
|
||||
//#define SCRIPT_ONLY 1
|
||||
|
||||
#ifdef INCLUDE_BUILTIN_SCRIPTS
|
||||
#include "../../build/TegraExplorer/script/builtin.h"
|
||||
#endif
|
||||
|
||||
extern hekate_config h_cfg;
|
||||
|
||||
enum {
|
||||
#ifndef SCRIPT_ONLY
|
||||
MainExplore = 0,
|
||||
MainBrowseSd,
|
||||
MainMountSd,
|
||||
MainBrowseEmmc,
|
||||
MainBrowseEmummc,
|
||||
MainTools,
|
||||
MainPartitionSd,
|
||||
MainViewKeys,
|
||||
MainViewCredits,
|
||||
MainExit,
|
||||
#else
|
||||
MainExit = 0,
|
||||
#endif
|
||||
MainPowerOff,
|
||||
MainRebootRCM,
|
||||
MainRebootNormal,
|
||||
MainRebootHekate,
|
||||
MainRebootAMS,
|
||||
MainScripts,
|
||||
};
|
||||
|
||||
MenuEntry_t mainMenuEntries[] = {
|
||||
#ifndef SCRIPT_ONLY
|
||||
[MainExplore] = {.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "-- Explore --"},
|
||||
[MainBrowseSd] = {.optionUnion = COLORTORGB(COLOR_GREEN), .name = "Browse SD"},
|
||||
[MainMountSd] = {.optionUnion = COLORTORGB(COLOR_YELLOW)}, // To mount/unmount the SD
|
||||
[MainBrowseEmmc] = {.optionUnion = COLORTORGB(COLOR_BLUE), .name = "Browse EMMC"},
|
||||
[MainBrowseEmummc] = {.optionUnion = COLORTORGB(COLOR_BLUE), .name = "Browse EMUMMC"},
|
||||
[MainTools] = {.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "\n-- Tools --"},
|
||||
[MainPartitionSd] = {.optionUnion = COLORTORGB(COLOR_ORANGE), .name = "Partition the sd"},
|
||||
[MainViewKeys] = {.optionUnion = COLORTORGB(COLOR_YELLOW), .name = "View dumped keys"},
|
||||
[MainViewCredits] = {.optionUnion = COLORTORGB(COLOR_YELLOW), .name = "Credits"},
|
||||
[MainExit] = {.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "\n-- Exit --"},
|
||||
#else
|
||||
[MainExit] = {.optionUnion = COLORTORGB(COLOR_WHITE), .name = "\n-- Exit --"},
|
||||
#endif
|
||||
[MainPowerOff] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Power off"},
|
||||
[MainRebootRCM] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot to RCM"},
|
||||
[MainRebootNormal] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot normally"},
|
||||
[MainRebootHekate] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot to bootloader/update.bin"},
|
||||
[MainRebootAMS] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot to atmosphere/reboot_payload.bin"},
|
||||
[MainScripts] = {.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "\n-- Scripts --"}
|
||||
};
|
||||
|
||||
void HandleSD(){
|
||||
gfx_clearscreen();
|
||||
TConf.curExplorerLoc = LOC_SD;
|
||||
if (!sd_mount() || sd_get_card_removed()){
|
||||
gfx_printf("Sd is not mounted!");
|
||||
hidWait();
|
||||
}
|
||||
else
|
||||
FileExplorer("sd:/");
|
||||
}
|
||||
|
||||
void HandleEMMC(){
|
||||
GptMenu(MMC_CONN_EMMC);
|
||||
}
|
||||
|
||||
void HandleEMUMMC(){
|
||||
GptMenu(MMC_CONN_EMUMMC);
|
||||
}
|
||||
|
||||
void ViewKeys(){
|
||||
gfx_clearscreen();
|
||||
for (int i = 0; i < 3; i++){
|
||||
gfx_printf("\nBis key 0%d: ", i);
|
||||
PrintKey(dumpedKeys.bis_key[i], AES_128_KEY_SIZE * 2);
|
||||
}
|
||||
|
||||
gfx_printf("\nMaster key 0: ");
|
||||
PrintKey(dumpedKeys.master_key, AES_128_KEY_SIZE);
|
||||
gfx_printf("\nHeader key: ");
|
||||
PrintKey(dumpedKeys.header_key, AES_128_KEY_SIZE * 2);
|
||||
gfx_printf("\nSave mac key: ");
|
||||
PrintKey(dumpedKeys.save_mac_key, AES_128_KEY_SIZE);
|
||||
|
||||
u8 fuseCount = 0;
|
||||
for (u32 i = 0; i < 32; i++){
|
||||
if ((fuse_read_odm(7) >> i) & 1)
|
||||
fuseCount++;
|
||||
}
|
||||
|
||||
gfx_printf("\n\nPkg1 ID: '%s'\nFuse count: %d", TConf.pkg1ID, fuseCount);
|
||||
|
||||
hidWait();
|
||||
}
|
||||
|
||||
void ViewCredits(){
|
||||
gfx_clearscreen();
|
||||
gfx_printf("\nTegraexplorer v%d.%d.%d\nBy SuchMemeManySkill\n\nBased on Lockpick_RCM & Hekate, from shchmue & CTCaer\n\n\n", LP_VER_MJ, LP_VER_MN, LP_VER_BF);
|
||||
|
||||
if (hidRead()->r)
|
||||
gfx_printf("%k\"I'm not even sure if it works\" - meme", COLOR_ORANGE);
|
||||
|
||||
hidWait();
|
||||
}
|
||||
|
||||
extern bool sd_mounted;
|
||||
extern bool is_sd_inited;
|
||||
extern int launch_payload(char *path);
|
||||
|
||||
void RebootToAMS(){
|
||||
launch_payload("sd:/atmosphere/reboot_payload.bin");
|
||||
}
|
||||
|
||||
void RebootToHekate(){
|
||||
launch_payload("sd:/bootloader/update.bin");
|
||||
}
|
||||
|
||||
void MountOrUnmountSD(){
|
||||
gfx_clearscreen();
|
||||
if (sd_mounted)
|
||||
sd_unmount();
|
||||
else if (!sd_mount())
|
||||
hidWait();
|
||||
}
|
||||
|
||||
menuPaths mainMenuPaths[] = {
|
||||
#ifndef SCRIPT_ONLY
|
||||
[MainBrowseSd] = HandleSD,
|
||||
[MainMountSd] = MountOrUnmountSD,
|
||||
[MainBrowseEmmc] = HandleEMMC,
|
||||
[MainBrowseEmummc] = HandleEMUMMC,
|
||||
[MainPartitionSd] = FormatSD,
|
||||
[MainViewKeys] = ViewKeys,
|
||||
[MainViewCredits] = ViewCredits,
|
||||
#endif
|
||||
[MainRebootAMS] = RebootToAMS,
|
||||
[MainRebootHekate] = RebootToHekate,
|
||||
[MainRebootRCM] = reboot_rcm,
|
||||
[MainPowerOff] = power_off,
|
||||
[MainRebootNormal] = reboot_normal,
|
||||
};
|
||||
|
||||
void EnterMainMenu(){
|
||||
int res = 0;
|
||||
while (1){
|
||||
if (sd_get_card_removed())
|
||||
sd_unmount();
|
||||
|
||||
#ifndef SCRIPT_ONLY
|
||||
// -- Explore --
|
||||
mainMenuEntries[MainBrowseSd].hide = !sd_mounted;
|
||||
mainMenuEntries[MainMountSd].name = (sd_mounted) ? "Unmount SD" : "Mount SD";
|
||||
mainMenuEntries[MainBrowseEmummc].hide = (!emu_cfg.enabled || !sd_mounted);
|
||||
|
||||
// -- Tools --
|
||||
mainMenuEntries[MainPartitionSd].hide = (!is_sd_inited || sd_get_card_removed());
|
||||
mainMenuEntries[MainViewKeys].hide = !TConf.keysDumped;
|
||||
|
||||
// -- Exit --
|
||||
mainMenuEntries[MainRebootAMS].hide = (!sd_mounted || !FileExists("sd:/atmosphere/reboot_payload.bin"));
|
||||
mainMenuEntries[MainRebootHekate].hide = (!sd_mounted || !FileExists("sd:/bootloader/update.bin"));
|
||||
mainMenuEntries[MainRebootRCM].hide = h_cfg.t210b01;
|
||||
#endif
|
||||
// -- Scripts --
|
||||
#ifndef INCLUDE_BUILTIN_SCRIPTS
|
||||
mainMenuEntries[MainScripts].hide = (!sd_mounted || !FileExists("sd:/tegraexplorer/scripts"));
|
||||
#else
|
||||
mainMenuEntries[MainScripts].hide = ((!sd_mounted || !FileExists("sd:/tegraexplorer/scripts")) && !EMBEDDED_SCRIPTS_LEN);
|
||||
#endif
|
||||
|
||||
Vector_t ent = newVec(sizeof(MenuEntry_t), ARRAY_SIZE(mainMenuEntries));
|
||||
ent.count = ARRAY_SIZE(mainMenuEntries);
|
||||
memcpy(ent.data, mainMenuEntries, sizeof(MenuEntry_t) * ARRAY_SIZE(mainMenuEntries));
|
||||
Vector_t scriptFiles = {0};
|
||||
u8 hasScripts = 0;
|
||||
|
||||
#ifdef INCLUDE_BUILTIN_SCRIPTS
|
||||
for (int i = 0; i < EMBEDDED_SCRIPTS_LEN; i++){
|
||||
MenuEntry_t m = {.name = embedded_scripts_g[i].name, .optionUnion = COLORTORGB(COLOR_BLUE), .icon = 128};
|
||||
vecAdd(&ent, m);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sd_mounted && FileExists("sd:/tegraexplorer/scripts")){
|
||||
scriptFiles = ReadFolder("sd:/tegraexplorer/scripts", &res);
|
||||
if (!res){
|
||||
if (!scriptFiles.count){
|
||||
FREE(scriptFiles.data);
|
||||
mainMenuEntries[MainScripts].hide = 1;
|
||||
}
|
||||
else {
|
||||
hasScripts = 1;
|
||||
vecForEach(FSEntry_t*, scriptFile, (&scriptFiles)){
|
||||
if (!scriptFile->isDir && StrEndsWith(scriptFile->name, ".te")){
|
||||
MenuEntry_t a = MakeMenuOutFSEntry(*scriptFile);
|
||||
vecAdd(&ent, a);
|
||||
}
|
||||
}
|
||||
|
||||
if (ent.count == ARRAY_SIZE(mainMenuEntries)){
|
||||
clearFileVector(&scriptFiles);
|
||||
hasScripts = 0;
|
||||
mainMenuEntries[MainScripts].hide = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gfx_clearscreen();
|
||||
gfx_putc('\n');
|
||||
|
||||
res = newMenu(&ent, res, 79, 30, (ent.count == ARRAY_SIZE(mainMenuEntries)) ? ALWAYSREDRAW : ALWAYSREDRAW | ENABLEPAGECOUNT, ent.count - ARRAY_SIZE(mainMenuEntries));
|
||||
if (res < MainScripts && mainMenuPaths[res] != NULL)
|
||||
mainMenuPaths[res]();
|
||||
#ifndef INCLUDE_BUILTIN_SCRIPTS
|
||||
else if (hasScripts){
|
||||
#else
|
||||
else {
|
||||
if (res - ARRAY_SIZE(mainMenuEntries) < EMBEDDED_SCRIPTS_LEN){
|
||||
char *script = embedded_scripts_g[res - ARRAY_SIZE(mainMenuEntries)].script;
|
||||
RunScriptString(script, strlen(script));
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
vecDefArray(MenuEntry_t*, entArray, ent);
|
||||
MenuEntry_t entry = entArray[res];
|
||||
FSEntry_t fsEntry = {.name = entry.name, .sizeUnion = entry.sizeUnion};
|
||||
RunScript("sd:/tegraexplorer/scripts", fsEntry);
|
||||
#ifdef INCLUDE_BUILTIN_SCRIPTS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (hasScripts){
|
||||
clearFileVector(&scriptFiles);
|
||||
}
|
||||
|
||||
free(ent.data);
|
||||
}
|
||||
}
|
||||
|
||||
3
TegraExplorer/source/tegraexplorer/mainmenu.h
Normal file
3
TegraExplorer/source/tegraexplorer/mainmenu.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void EnterMainMenu();
|
||||
17
TegraExplorer/source/tegraexplorer/tconf.c
Normal file
17
TegraExplorer/source/tegraexplorer/tconf.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "tconf.h"
|
||||
#include <mem/heap.h>
|
||||
#include "../utils/utils.h"
|
||||
TConf_t TConf = {0};
|
||||
|
||||
void ResetCopyParams(){
|
||||
TConf.heldExplorerCopyLoc = LOC_None;
|
||||
FREE(TConf.srcCopy);
|
||||
TConf.explorerCopyMode = CMODE_None;
|
||||
}
|
||||
|
||||
void SetCopyParams(const char *path, u8 mode){
|
||||
ResetCopyParams();
|
||||
TConf.heldExplorerCopyLoc = TConf.curExplorerLoc;
|
||||
TConf.explorerCopyMode = mode;
|
||||
TConf.srcCopy = CpyStr(path);
|
||||
}
|
||||
42
TegraExplorer/source/tegraexplorer/tconf.h
Normal file
42
TegraExplorer/source/tegraexplorer/tconf.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include <utils/types.h>
|
||||
#include "../keys/keys.h"
|
||||
|
||||
enum {
|
||||
LOC_None = 0,
|
||||
LOC_SD,
|
||||
LOC_EMMC,
|
||||
LOC_EMUMMC
|
||||
};
|
||||
|
||||
enum {
|
||||
CMODE_None = 0,
|
||||
CMODE_Copy,
|
||||
CMODE_Move,
|
||||
CMODE_CopyFolder,
|
||||
CMODE_MoveFolder
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
u32 FSBuffSize;
|
||||
char *srcCopy;
|
||||
union {
|
||||
struct {
|
||||
u16 minervaEnabled:1;
|
||||
u16 keysDumped:1;
|
||||
u16 curExplorerLoc:2;
|
||||
u16 heldExplorerCopyLoc:2;
|
||||
u16 explorerCopyMode:4;
|
||||
u16 currentMMCConnected:2;
|
||||
u16 connectedMMCMounted:1;
|
||||
};
|
||||
u16 optionUnion;
|
||||
};
|
||||
const char *pkg1ID;
|
||||
char *scriptCWD;
|
||||
} TConf_t;
|
||||
|
||||
extern TConf_t TConf;
|
||||
|
||||
void ResetCopyParams();
|
||||
void SetCopyParams(const char *path, u8 mode);
|
||||
164
TegraExplorer/source/tegraexplorer/tools.c
Normal file
164
TegraExplorer/source/tegraexplorer/tools.c
Normal file
@@ -0,0 +1,164 @@
|
||||
#include "tools.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../gfx/menu.h"
|
||||
#include "../hid/hid.h"
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include "../keys/keys.h"
|
||||
#include "../keys/nca.h"
|
||||
#include <storage/nx_sd.h>
|
||||
#include "../fs/fsutils.h"
|
||||
#include <utils/util.h>
|
||||
#include "../storage/mountmanager.h"
|
||||
#include "../err.h"
|
||||
#include <utils/sprintf.h>
|
||||
#include <mem/heap.h>
|
||||
#include "../tegraexplorer/tconf.h"
|
||||
#include "../fs/readers/folderReader.h"
|
||||
#include <string.h>
|
||||
#include "../fs/fscopy.h"
|
||||
#include "../utils/utils.h"
|
||||
#include <display/di.h>
|
||||
|
||||
extern sdmmc_storage_t sd_storage;
|
||||
extern bool is_sd_inited;
|
||||
|
||||
MenuEntry_t FatAndEmu[] = {
|
||||
{.optionUnion = COLORTORGB(COLOR_ORANGE), .name = "Back to main menu"},
|
||||
{.optionUnion = COLORTORGB(COLOR_GREEN), .name = "Fat32 + EmuMMC"},
|
||||
{.optionUnion = COLORTORGB(COLOR_BLUE), .name = "Only Fat32"}
|
||||
};
|
||||
|
||||
void FormatSD(){
|
||||
gfx_clearscreen();
|
||||
disconnectMMC();
|
||||
DWORD plist[] = {0,0,0,0};
|
||||
bool emummc = 0;
|
||||
int res;
|
||||
|
||||
if (!is_sd_inited || sd_get_card_removed())
|
||||
return;
|
||||
|
||||
gfx_printf("\nDo you want to partition for an emummc?\n");
|
||||
res = MakeHorizontalMenu(FatAndEmu, ARR_LEN(FatAndEmu), 3, COLOR_DEFAULT, 0);
|
||||
|
||||
if (!res)
|
||||
return;
|
||||
|
||||
emummc = !(res - 1);
|
||||
|
||||
SETCOLOR(COLOR_RED, COLOR_DEFAULT);
|
||||
|
||||
plist[0] = sd_storage.csd.capacity;
|
||||
if (emummc){
|
||||
if (plist[0] < 83886080){
|
||||
gfx_printf("\n\nYou seem to be running this on a 32GB or smaller SD\nNot enough free space for emummc!");
|
||||
hidWait();
|
||||
return;
|
||||
}
|
||||
plist[0] -= 61145088;
|
||||
u32 allignedSectors = plist[0] - plist[0] % 2048;
|
||||
plist[1] = 61145088 + plist[0] % 2048;
|
||||
plist[0] = allignedSectors;
|
||||
}
|
||||
|
||||
gfx_printf("\n\nAre you sure you want to format your sd?\nThis will delete everything on your SD card!\nThis action is irreversible!\n\n");
|
||||
WaitFor(1500);
|
||||
|
||||
gfx_printf("%kAre you sure? ", COLOR_WHITE);
|
||||
if (!MakeYesNoHorzMenu(3, COLOR_DEFAULT)){
|
||||
return;
|
||||
}
|
||||
|
||||
RESETCOLOR;
|
||||
|
||||
gfx_printf("\n\nStarting Partitioning & Formatting\n");
|
||||
|
||||
for (int i = 0; i < 2; i++){
|
||||
gfx_printf("Part %d: %dKiB\n", i + 1, plist[i] / 2);
|
||||
}
|
||||
|
||||
u8 *work = malloc(TConf.FSBuffSize);
|
||||
res = f_fdisk_mod(0, plist, work);
|
||||
|
||||
if (!res){
|
||||
res = f_mkfs("sd:", FM_FAT32, 32768, work, TConf.FSBuffSize);
|
||||
}
|
||||
|
||||
sd_unmount();
|
||||
|
||||
if (res){
|
||||
DrawError(newErrCode(res));
|
||||
gfx_clearscreen();
|
||||
gfx_printf("Something went wrong\nPress any key to exit");
|
||||
}
|
||||
else {
|
||||
sd_mount();
|
||||
gfx_printf("\nDone!\nPress any key to exit");
|
||||
}
|
||||
|
||||
free(work);
|
||||
hidWait();
|
||||
}
|
||||
|
||||
extern bool sd_mounted;
|
||||
|
||||
void TakeScreenshot(){
|
||||
static u32 timer = 0;
|
||||
|
||||
if (!TConf.minervaEnabled || !sd_mounted)
|
||||
return;
|
||||
|
||||
if (timer + 3 < get_tmr_s())
|
||||
timer = get_tmr_s();
|
||||
else
|
||||
return;
|
||||
|
||||
char *name, *path;
|
||||
const char basepath[] = "sd:/tegraexplorer/screenshots";
|
||||
name = malloc(40);
|
||||
s_printf(name, "Screenshot_%08X.bmp", get_tmr_us());
|
||||
|
||||
f_mkdir("sd:/tegraexplorer");
|
||||
f_mkdir(basepath);
|
||||
path = CombinePaths(basepath, name);
|
||||
free(name);
|
||||
|
||||
const u32 file_size = 0x384000 + 0x36;
|
||||
u8 *bitmap = malloc(file_size);
|
||||
u32 *fb = malloc(0x384000);
|
||||
u32 *fb_ptr = gfx_ctxt.fb;
|
||||
|
||||
for (int x = 1279; x >= 0; x--)
|
||||
{
|
||||
for (int y = 719; y >= 0; y--)
|
||||
fb[y * 1280 + x] = *fb_ptr++;
|
||||
}
|
||||
|
||||
memcpy(bitmap + 0x36, fb, 0x384000);
|
||||
bmp_t *bmp = (bmp_t *)bitmap;
|
||||
|
||||
bmp->magic = 0x4D42;
|
||||
bmp->size = file_size;
|
||||
bmp->rsvd = 0;
|
||||
bmp->data_off = 0x36;
|
||||
bmp->hdr_size = 40;
|
||||
bmp->width = 1280;
|
||||
bmp->height = 720;
|
||||
bmp->planes = 1;
|
||||
bmp->pxl_bits = 32;
|
||||
bmp->comp = 0;
|
||||
bmp->img_size = 0x384000;
|
||||
bmp->res_h = 2834;
|
||||
bmp->res_v = 2834;
|
||||
bmp->rsvd2 = 0;
|
||||
|
||||
sd_save_to_file(bitmap, file_size, path);
|
||||
free(bitmap);
|
||||
free(fb);
|
||||
free(path);
|
||||
|
||||
display_backlight_brightness(255, 1000);
|
||||
msleep(100);
|
||||
display_backlight_brightness(100, 1000);
|
||||
}
|
||||
24
TegraExplorer/source/tegraexplorer/tools.h
Normal file
24
TegraExplorer/source/tegraexplorer/tools.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include <utils/types.h>
|
||||
|
||||
typedef struct _bmp_t
|
||||
{
|
||||
u16 magic;
|
||||
u32 size;
|
||||
u32 rsvd;
|
||||
u32 data_off;
|
||||
u32 hdr_size;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u16 planes;
|
||||
u16 pxl_bits;
|
||||
u32 comp;
|
||||
u32 img_size;
|
||||
u32 res_h;
|
||||
u32 res_v;
|
||||
u64 rsvd2;
|
||||
} __attribute__((packed)) bmp_t;
|
||||
|
||||
void DumpSysFw();
|
||||
void FormatSD();
|
||||
void TakeScreenshot();
|
||||
Reference in New Issue
Block a user