Compare commits

..

21 Commits
2.9.9 ... 3.0.1

Author SHA1 Message Date
suchmememanyskill
f730f4a08e bump version to 3.0.1 2021-01-11 22:14:38 +01:00
suchmememanyskill
ec64658a6a reee copy printing 2021-01-11 21:37:09 +01:00
suchmememanyskill
86db030bda small fixes
- On a switch lite, the home and cap buttons do weird things, so we should disable m
- File deletions should wait a bit
2021-01-11 21:22:24 +01:00
suchmememanyskill
d27832effb [script] Fix <= and >= 2021-01-10 23:19:51 +01:00
suchmememanyskill
5057bb2863 [script] menu now allows for hidden & skip entries 2021-01-10 16:58:40 +01:00
suchmememanyskill
963987d639 [script] add operators, add reboot to payload
- Add a function to reboot to payload
- Add an "Empty array" variable type that is created when you try to assign []. This will get filled with a valid entry upon first addition
- Adds operator string array plus string
2021-01-10 16:32:50 +01:00
suchmememanyskill
3f80693d9e Save bytes, add screenshots into main and more
- Also run script on bootup if a script called startup.te is found on the root of the sd
- Saved bytes by just disabling making exfat partitions, lol
2021-01-10 00:10:28 +01:00
suchmememanyskill
5485f5ca06 Add screenshot taking as debug arg 2021-01-09 17:12:45 +01:00
suchmememanyskill
981e5435ea Add charging icon 2021-01-08 19:32:06 +01:00
suchmememanyskill
99c2abeaf3 not all gpt entries are all caps 2021-01-05 19:42:15 +01:00
suchmememanyskill
cf2c116240 Complete rewrite of TE
Merge pull request #32 from suchmememanyskill/rewrite
2021-01-05 17:00:00 +01:00
suchmememanyskill
502a246949 add timerMs function, unmounting emu does not unmount sd 2021-01-05 15:55:11 +01:00
suchmememanyskill
e98a3bba68 don't pause script on exit except on error 2021-01-04 23:42:26 +01:00
suchmememanyskill
9447256934 Remove beta signature 2021-01-04 18:30:09 +01:00
suchmememanyskill
7e2a672753 [script] fix == not working 2021-01-04 18:27:17 +01:00
suchmememanyskill
12136d9289 [Script] add last bits
Fixed: Scripts should free at the end
Added: ncaGetType, saveSign
Modified: pathCombine can now take 2+ args to combine
2021-01-04 16:57:47 +01:00
suchmememanyskill
c9fdb650c3 [script] Make equivalent to tsV1
Fixed: functions in functions
Added functions: version, menu, pathCombine, pathEscFolder, fileMove, fileCopy, fileDel, mmcConnect, mmcMount, mkdir, dirRead, dirCopy, dirDel, mmcDump, mmcRestore
2021-01-04 01:55:58 +01:00
suchmememanyskill
e1491da4ad [script] add some util functions
functions added: return, exit, printPos, clearscreen, drawBox, color, pause, exit
2021-01-02 12:43:15 +01:00
suchmememanyskill
e0c62cbec4 [script] add bitshifting 2021-01-02 11:39:14 +01:00
suchmememanyskill
e1f292fe0d [script] vector slicing, basic file functions
new operators:
vector(int, byte) - int -> works like py's list[0:-int]
vector(int, byte) : int -> works like py's list[int:]

new functions:
fileRead, fileWrite, fileExists, bytesToStr
2021-01-01 18:30:51 +01:00
suchmememanyskill
b5c11a56c9 build on all branches & all prs 2020-12-29 13:10:21 +01:00
32 changed files with 799 additions and 92 deletions

View File

@@ -1,10 +1,6 @@
name: TegraExplorer builder name: TegraExplorer builder
on: on: [push, pull_request]
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs: jobs:
build: build:

View File

@@ -11,7 +11,7 @@ include $(DEVKITARM)/base_rules
IPL_LOAD_ADDR := 0x40003000 IPL_LOAD_ADDR := 0x40003000
LPVERSION_MAJOR := 3 LPVERSION_MAJOR := 3
LPVERSION_MINOR := 0 LPVERSION_MINOR := 0
LPVERSION_BUGFX := 0 LPVERSION_BUGFX := 1
################################################################################ ################################################################################
@@ -46,7 +46,7 @@ CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
#CUSTOMDEFINES += -DDEBUG #CUSTOMDEFINES += -DDEBUG
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
CFLAGS = $(ARCH) -Os -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall $(CUSTOMDEFINES) CFLAGS = $(ARCH) -Os -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall -Wno-missing-braces $(CUSTOMDEFINES)
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR) LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
################################################################################ ################################################################################

View File

@@ -5929,6 +5929,7 @@ FRESULT f_mkfs (
#if FF_FS_EXFAT #if FF_FS_EXFAT
if (fmt == FS_EXFAT) { /* Create an exFAT volume */ if (fmt == FS_EXFAT) { /* Create an exFAT volume */
LEAVE_MKFS(FR_NO_FILESYSTEM); // Muh frii bytes
DWORD szb_bit, szb_case, sum, nb, cl; DWORD szb_bit, szb_case, sum, nb, cl;
WCHAR ch, si; WCHAR ch, si;
UINT j, st; UINT j, st;

View File

@@ -37,9 +37,8 @@ ErrCode_t FileCopy(const char *locin, const char *locout, u8 options){
} }
if (options & COPY_MODE_PRINT){ if (options & COPY_MODE_PRINT){
gfx_printf("[ ]"); gfx_printf("[ 0%%]");
x += 16; x += 16;
gfx_con_setpos(x, y);
} }
buff = malloc(TConf.FSBuffSize); buff = malloc(TConf.FSBuffSize);
@@ -62,8 +61,8 @@ ErrCode_t FileCopy(const char *locin, const char *locout, u8 options){
sizeRemaining -= toCopy; sizeRemaining -= toCopy;
if (options & COPY_MODE_PRINT){ if (options & COPY_MODE_PRINT){
gfx_printf("%3d%%", (u32)(((totalsize - sizeRemaining) * 100) / totalsize));
gfx_con_setpos(x, y); gfx_con_setpos(x, y);
gfx_printf("%3d%%", (u32)(((totalsize - sizeRemaining) * 100) / totalsize));
} }
if (options & COPY_MODE_CANCEL && btn_read() & (BTN_VOL_DOWN | BTN_VOL_UP)){ if (options & COPY_MODE_CANCEL && btn_read() & (BTN_VOL_DOWN | BTN_VOL_UP)){
@@ -78,6 +77,10 @@ ErrCode_t FileCopy(const char *locin, const char *locout, u8 options){
f_chmod(locout, in_info.fattrib, 0x3A); f_chmod(locout, in_info.fattrib, 0x3A);
if (options & COPY_MODE_PRINT){
gfx_con_setpos(x - 16, y);
}
//f_stat(locin, &in_info); //somehow stops fatfs from being weird //f_stat(locin, &in_info); //somehow stops fatfs from being weird
return err; return err;
} }
@@ -89,6 +92,15 @@ void BoxRestOfScreen(){
} }
ErrCode_t FolderCopy(const char *locin, const char *locout){ ErrCode_t FolderCopy(const char *locin, const char *locout){
if (TConf.explorerCopyMode >= CMODE_CopyFolder){
if (strstr(locout, locin) != NULL)
return newErrCode(TE_ERR_PATH_IN_PATH);
}
if (!strcmp(locin, locout)){
return newErrCode(TE_ERR_SAME_LOC);
}
char *dstPath = CombinePaths(locout, strrchr(locin, '/') + 1); char *dstPath = CombinePaths(locout, strrchr(locin, '/') + 1);
int res = 0; int res = 0;
ErrCode_t ret = newErrCode(0); ErrCode_t ret = newErrCode(0);

View File

@@ -23,3 +23,5 @@ typedef struct {
u16 sizeUnion; u16 sizeUnion;
}; };
} FSEntry_t; } FSEntry_t;
#define newFSEntry(filename) (FSEntry_t) {.name = filename}

View File

@@ -15,6 +15,7 @@
#include "../../script/parser.h" #include "../../script/parser.h"
#include "../../script/variables.h" #include "../../script/variables.h"
#include <storage/nx_sd.h> #include <storage/nx_sd.h>
#include "../../storage/emummc.h"
MenuEntry_t FileMenuEntries[] = { MenuEntry_t FileMenuEntries[] = {
{.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "-- File menu --"}, {.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "-- File menu --"},
@@ -59,6 +60,7 @@ void DeleteFile(char *path, FSEntry_t entry){
SETCOLOR(COLOR_RED, COLOR_DARKGREY); SETCOLOR(COLOR_RED, COLOR_DARKGREY);
gfx_printf("Are you sure? "); gfx_printf("Are you sure? ");
WaitFor(500);
if (!MakeYesNoHorzMenu(3, COLOR_DARKGREY)) if (!MakeYesNoHorzMenu(3, COLOR_DARKGREY))
return; return;
@@ -77,17 +79,21 @@ void RunScript(char *path, FSEntry_t entry){
if (!script) if (!script)
return; return;
if (((entry.size >= 64 && entry.sizeDef == 1) || entry.sizeDef >= 2) && !TConf.minervaEnabled)
return;
gfx_clearscreen(); gfx_clearscreen();
scriptCtx_t ctx = createScriptCtx(); scriptCtx_t ctx = createScriptCtx();
ctx.script = runLexar(script, size); ctx.script = runLexer(script, size);
free(script); free(script);
dictVectorAdd(&ctx.varDict, newDict(CpyStr("_CWD"), (newVar(StringType, 0, .stringType = path))));
dictVectorAdd(&ctx.varDict, newDict(CpyStr("_EMU"), (newVar(IntType, 0, emu_cfg.enabled))));
printError(mainLoop(&ctx)); printError(mainLoop(&ctx));
freeVariableVector(&ctx.varDict); freeDictVector(&ctx.varDict);
lexarVectorClear(&ctx.script); lexarVectorClear(&ctx.script);
gfx_printf("\nend of script");
hidWait();
} }
void RenameFile(char *path, FSEntry_t entry){ void RenameFile(char *path, FSEntry_t entry){

View File

@@ -4,3 +4,4 @@
typedef void (*fileMenuPath)(char *path, FSEntry_t entry); typedef void (*fileMenuPath)(char *path, FSEntry_t entry);
void FileMenu(char *path, FSEntry_t entry); void FileMenu(char *path, FSEntry_t entry);
void RunScript(char *path, FSEntry_t entry);

View File

@@ -121,6 +121,7 @@ static const u8 _gfx_font[] = {
0x00, 0x00, 0x00, 0x4C, 0x32, 0x00, 0x00, 0x00, // Char 126 (~) 0x00, 0x00, 0x00, 0x4C, 0x32, 0x00, 0x00, 0x00, // Char 126 (~)
0x00, 0x0C, 0x12, 0x7E, 0x42, 0x42, 0x7E, 0x00, // Char 127 (folder) 0x00, 0x0C, 0x12, 0x7E, 0x42, 0x42, 0x7E, 0x00, // Char 127 (folder)
0x00, 0x0E, 0x12, 0x22, 0x22, 0x22, 0x3E, 0x00, // Char 128 (file) 0x00, 0x0E, 0x12, 0x22, 0x22, 0x22, 0x3E, 0x00, // Char 128 (file)
0x00, 0x08, 0x0C, 0x0E, 0x7E, 0x70, 0x30, 0x10, // Char 129 (Charging)
}; };
u32 YLeftConfig = YLEFT; u32 YLeftConfig = YLEFT;
@@ -188,7 +189,7 @@ void gfx_putc(char c)
switch (gfx_con.fntsz) switch (gfx_con.fntsz)
{ {
case 16: case 16:
if (c >= 32 && c <= 128) if (c >= 32 && c <= 129)
{ {
u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)]; u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];
u32 *fb = gfx_ctxt.fb + gfx_con.x + gfx_con.y * gfx_ctxt.stride; u32 *fb = gfx_ctxt.fb + gfx_con.x + gfx_con.y * gfx_ctxt.stride;
@@ -265,7 +266,7 @@ void gfx_putc(char c)
break; break;
case 8: case 8:
default: default:
if (c >= 30 && c <= 126) if (c >= 30 && c <= 129)
{ {
u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)]; u8 *cbuf = (u8 *)&_gfx_font[8 * (c - 32)];
u32 *fb = gfx_ctxt.fb + gfx_con.x + gfx_con.y * gfx_ctxt.stride; u32 *fb = gfx_ctxt.fb + gfx_con.x + gfx_con.y * gfx_ctxt.stride;

View File

@@ -1,22 +1,30 @@
#include "gfx.h" #include "gfx.h"
#include "gfxutils.h" #include "gfxutils.h"
#include <power/max17050.h> #include <power/max17050.h>
#include <power/max17050.h>
#include <power/bq24193.h>
#include "../hid/hid.h" #include "../hid/hid.h"
void gfx_clearscreen(){ void gfx_printTopInfo() {
int battery = 0; int battery = 0;
max17050_get_property(MAX17050_RepSOC, &battery); max17050_get_property(MAX17050_RepSOC, &battery);
//gfx_clear_grey(0x1B); int current_charge_status = 0;
gfx_boxGrey(0, 16, 1279, 703, 0x1b); bq24193_get_property(BQ24193_ChargeStatus, &current_charge_status);
SETCOLOR(COLOR_DEFAULT, COLOR_WHITE); SETCOLOR(COLOR_DEFAULT, COLOR_WHITE);
gfx_con_setpos(0, 0);
gfx_printf("Tegraexplorer %d.%d.%d | Battery: %d%% %c\n", LP_VER_MJ, LP_VER_MN, LP_VER_BF, battery >> 8, ((current_charge_status) ? 129 : 32));
RESETCOLOR;
}
void gfx_clearscreen(){
gfx_boxGrey(0, 16, 1279, 703, 0x1b);
gfx_boxGrey(0, 703, 1279, 719, 0xFF); gfx_boxGrey(0, 703, 1279, 719, 0xFF);
gfx_boxGrey(0, 0, 1279, 15, 0xFF); gfx_boxGrey(0, 0, 1279, 15, 0xFF);
gfx_con_setpos(0, 0);
gfx_printf("Tegraexplorer b%d.%d.%d | Battery: %3d%%\n", LP_VER_MJ, LP_VER_MN, LP_VER_BF, battery >> 8);
RESETCOLOR;
gfx_printTopInfo();
} }
MenuEntry_t YesNoEntries[] = { MenuEntry_t YesNoEntries[] = {

View File

@@ -16,3 +16,4 @@
void gfx_clearscreen(); void gfx_clearscreen();
int MakeHorizontalMenu(MenuEntry_t *entries, int len, int spacesBetween, u32 bg, int startPos); int MakeHorizontalMenu(MenuEntry_t *entries, int len, int spacesBetween, u32 bg, int startPos);
int MakeYesNoHorzMenu(int spacesBetween, u32 bg); int MakeYesNoHorzMenu(int spacesBetween, u32 bg);
void gfx_printTopInfo();

View File

@@ -160,8 +160,10 @@ int newMenu(Vector_t* vec, int startIndex, int screenLenX, int screenLenY, u8 op
break; break;
} }
} }
else else {
holdTimer = 300; holdTimer = 300;
gfx_printTopInfo();
}
} }
lastPress = get_tmr_ms(); lastPress = get_tmr_ms();

View File

@@ -5,6 +5,9 @@
#include <utils/types.h> #include <utils/types.h>
#include <utils/util.h> #include <utils/util.h>
#include "../utils/utils.h" #include "../utils/utils.h"
#include "../tegraexplorer/tools.h"
#include <gfx/di.h>
#include "../config.h"
static Input_t inputs = {0}; static Input_t inputs = {0};
u16 LbaseX = 0, LbaseY = 0, RbaseX = 0, RbaseY = 0; u16 LbaseX = 0, LbaseY = 0, RbaseX = 0, RbaseY = 0;
@@ -13,15 +16,22 @@ void hidInit(){
jc_init_hw(); jc_init_hw();
} }
extern hekate_config h_cfg;
Input_t *hidRead(){ Input_t *hidRead(){
jc_gamepad_rpt_t *controller = joycon_poll(); jc_gamepad_rpt_t *controller = joycon_poll();
//if (controller->cap) if (h_cfg.t210b01){ // Disable home and capture buttons on mariko to avoid weird behaviour
// utils_takeScreenshot(); controller->home = 0;
controller->cap = 0;
}
if (controller->home) if (controller->home)
RebootToPayloadOrRcm(); RebootToPayloadOrRcm();
if (controller->cap)
TakeScreenshot();
inputs.buttons = controller->buttons; inputs.buttons = controller->buttons;
u8 btn = btn_read(); u8 btn = btn_read();

51
source/keys/save.c Normal file
View File

@@ -0,0 +1,51 @@
#include "save.h"
#include <utils/types.h>
#include <libs/fatfs/ff.h>
#include <sec/se.h>
#include <mem/heap.h>
#include "../err.h"
ErrCode_t saveCommit(const char *path){
FIL file;
int res;
u8 *buf, hash[0x20], *cmac_data, cmac[0x10];
const u32 hashed_data_size = 0x3D00, cmac_data_size = 0x200;
buf = malloc(hashed_data_size);
cmac_data = malloc(cmac_data_size);
if ((res = f_open(&file, path, FA_OPEN_EXISTING | FA_READ | FA_WRITE))){
goto out_free;
}
f_lseek(&file, 0x300);
if ((res = f_read(&file, buf, hashed_data_size, NULL))){
goto out_free;
}
se_calc_sha256_oneshot(hash, buf, hashed_data_size);
f_lseek(&file, 0x108);
if ((res = f_write(&file, hash, sizeof(hash), NULL))){
goto out_free;
}
f_lseek(&file, 0x100);
if ((res = f_read(&file, cmac_data, cmac_data_size, NULL))){
goto out_free;
}
se_aes_cmac(8, cmac, 0x10, cmac_data, cmac_data_size);
f_lseek(&file, 0);
if ((res = f_write(&file, cmac, sizeof(cmac), NULL))){
goto out_free;
}
out_free:;
free(buf);
free(cmac_data);
f_close(&file);
return newErrCode(res);
}

4
source/keys/save.h Normal file
View File

@@ -0,0 +1,4 @@
#pragma once
#include "../err.h"
ErrCode_t saveCommit(const char *path);

View File

@@ -52,6 +52,9 @@
#include "keys/keys.h" #include "keys/keys.h"
#include "keys/keyfile.h" #include "keys/keyfile.h"
#include "storage/mountmanager.h" #include "storage/mountmanager.h"
#include "fs/fsutils.h"
#include "fs/fstypes.h"
#include "fs/menus/filemenu.h"
hekate_config h_cfg; hekate_config h_cfg;
@@ -304,6 +307,10 @@ void ipl_main()
if (res == 0) if (res == 0)
hidWait(); hidWait();
if (FileExists("sd:/startup.te"))
RunScript("sd:/", newFSEntry("startup.te"));
EnterMainMenu(); EnterMainMenu();
// Halt BPMP if we managed to get out of execution. // Halt BPMP if we managed to get out of execution.

View File

@@ -42,6 +42,10 @@ Vector_t extractVars(scriptCtx_t* ctx, lexarToken_t* tokens, u32 len) {
int distance = distanceBetweenTokens(&tokens[i + 1], len - i - 1, LSBracket, RSBracket); int distance = distanceBetweenTokens(&tokens[i + 1], len - i - 1, LSBracket, RSBracket);
i += distance + 1; i += distance + 1;
} }
if (tokens[i].token == LBracket){
int distance = distanceBetweenTokens(&tokens[i + 1], len - i - 1, LBracket, RBracket);
i += distance + 1;
}
if (tokens[i].token == Seperator) { if (tokens[i].token == Seperator) {
Variable_t res = solveEquation(ctx, &tokens[lastLoc], i - lastLoc, 0); Variable_t res = solveEquation(ctx, &tokens[lastLoc], i - lastLoc, 0);
lastLoc = i + 1; lastLoc = i + 1;
@@ -128,17 +132,18 @@ Variable_t getVarFromToken(scriptCtx_t* ctx, lexarToken_t* tokens, int* index, u
val = executeFunction(ctx, tokens[i - 2].text, &tokens[i], argCount); val = executeFunction(ctx, tokens[i - 2].text, &tokens[i], argCount);
//val = IntValue(1);
i += argCount; i += argCount;
} }
ELIFTX(LSBracket) { ELIFTX(LSBracket) {
i++; i++;
int argCount = distanceBetweenTokens(&tokens[i], maxLen - 1, LSBracket, RSBracket); int argCount = distanceBetweenTokens(&tokens[i], maxLen - 1, LSBracket, RSBracket);
if (argCount <= 0) if (argCount < 0)
return ErrValue(ERRSYNTAX); return ErrValue(ERRSYNTAX);
// ArrayVars should be a Vector_t containing Variable_t's. Not implemented yet! val.varType = EmptyArrayType;
if (argCount > 0){
Vector_t arrayVars = extractVars(ctx, &tokens[i], argCount); Vector_t arrayVars = extractVars(ctx, &tokens[i], argCount);
Variable_t* variables = vecGetArray(Variable_t*, arrayVars); Variable_t* variables = vecGetArray(Variable_t*, arrayVars);
int type = variables[0].varType; int type = variables[0].varType;
@@ -149,22 +154,23 @@ Variable_t getVarFromToken(scriptCtx_t* ctx, lexarToken_t* tokens, int* index, u
val.free = 1; val.free = 1;
val.vectorType = newVec((type == IntType) ? sizeof(int) : sizeof(char*), arrayVars.count); val.vectorType = newVec((type == IntType) ? sizeof(int) : sizeof(char*), arrayVars.count);
for (int i = 0; i < arrayVars.count; i++) { for (int j = 0; j < arrayVars.count; j++) {
if (variables[i].varType != type) if (variables[j].varType != type)
return ErrValue(ERRINVALIDTYPE); // Free-ing issue!! return ErrValue(ERRINVALIDTYPE); // Free-ing issue!!
if (type == StringType) { if (type == StringType) {
char* temp = CpyStr(variables[i].stringType); char* temp = CpyStr(variables[j].stringType);
vecAddElement(&val.vectorType, temp); vecAddElement(&val.vectorType, temp);
} }
else { else {
vecAddElement(&val.vectorType, variables[i].integerType); vecAddElement(&val.vectorType, variables[j].integerType);
} }
} }
i += argCount; i += argCount;
freeVariableVector(&arrayVars); freeVariableVector(&arrayVars);
} }
}
ELIFTX(LBracket) { ELIFTX(LBracket) {
i++; i++;
int argCount = distanceBetweenTokens(&tokens[i], maxLen - 1, LBracket, RBracket); int argCount = distanceBetweenTokens(&tokens[i], maxLen - 1, LBracket, RBracket);
@@ -263,6 +269,10 @@ Variable_t solveEquation(scriptCtx_t* ctx, lexarToken_t* tokens, u32 len, u8 sho
res.integerType = res.integerType & val.integerType; res.integerType = res.integerType & val.integerType;
ELIFT(OR) ELIFT(OR)
res.integerType = res.integerType | val.integerType; res.integerType = res.integerType | val.integerType;
ELIFT(BitShiftLeft)
res.integerType = res.integerType << val.integerType;
ELIFT(BitShiftRight)
res.integerType = res.integerType >> val.integerType;
else else
return ErrValue(ERRBADOPERATOR); return ErrValue(ERRBADOPERATOR);
} }
@@ -343,6 +353,25 @@ Variable_t solveEquation(scriptCtx_t* ctx, lexarToken_t* tokens, u32 len, u8 sho
vecAddElement(&res.vectorType, in); vecAddElement(&res.vectorType, in);
} }
} }
ELIFT(Minus){
if (val.integerType >= res.vectorType.count)
return ErrValue(ERRSYNTAX);
res.vectorType.count -= val.integerType;
Vector_t newV = vecCopy(&res.vectorType);
freeVariable(res);
res.vectorType = newV;
res.free = 1;
}
ELIFT(Selector){
if (val.integerType >= res.vectorType.count)
return ErrValue(ERRSYNTAX);
Vector_t newV = vecCopyOffset(&res.vectorType, val.integerType);
freeVariable(res);
res.vectorType = newV;
res.free = 1;
}
} }
else if (res.varType == StringType && val.varType == IntType){ else if (res.varType == StringType && val.varType == IntType){
if (localOpToken == Minus){ if (localOpToken == Minus){
@@ -370,6 +399,43 @@ Variable_t solveEquation(scriptCtx_t* ctx, lexarToken_t* tokens, u32 len, u8 sho
else else
return ErrValue(ERRBADOPERATOR); return ErrValue(ERRBADOPERATOR);
} }
else if (res.varType == EmptyArrayType && localOpToken == Plus){
res.free = 1;
res.varType = val.varType + 2;
if (val.varType == IntType){
res.vectorType = newVec(sizeof(int), 4);
vecAddElem(&res.vectorType, val.integerType);
}
else if (val.varType == StringType) {
res.vectorType = newVec(sizeof(char*), 4);
char *temp = CpyStr(val.stringType);
vecAddElem(&res.vectorType, temp);
}
else
return ErrValue(ERRBADOPERATOR);
freeVariable(val);
}
else if (res.varType == StringArrayType && val.varType == StringType){
if (localOpToken == Plus){
Vector_t new = vecCopy(&res.vectorType);
vecDefArray(char **, strings, new);
for (int j = 0; j < new.count; j++){
strings[j] = CpyStr(strings[j]);
}
freeVariable(res);
char *temp = CpyStr(val.stringType);
vecAddElem(&new, temp);
res.free = 1;
res.vectorType = new;
}
else
return ErrValue(ERRBADOPERATOR);
}
else else
return ErrValue(ERRBADOPERATOR); return ErrValue(ERRBADOPERATOR);
} }
@@ -377,7 +443,7 @@ Variable_t solveEquation(scriptCtx_t* ctx, lexarToken_t* tokens, u32 len, u8 sho
res = val; res = val;
} }
} }
else if (tokens[i].token >= Plus && tokens[i].token <= Selector) { else if (tokens[i].token >= Plus && tokens[i].token <= BitShiftRight) {
lastToken = tokens[i].token; lastToken = tokens[i].token;
} }
} }

View File

@@ -6,8 +6,27 @@
#include <mem/heap.h> #include <mem/heap.h>
#include "lexer.h" #include "lexer.h"
#include <storage/nx_sd.h>
#include "../fs/fsutils.h"
#include "../gfx/gfxutils.h"
#include "../hid/hid.h"
#include <utils/util.h>
#include "../fs/fscopy.h"
#include "../storage/mountmanager.h"
#include "../storage/emummc.h"
#include "../fs/readers/folderReader.h"
#include "../utils/utils.h"
#include "../keys/keys.h"
#include "../storage/emmcfile.h"
#include "../keys/nca.h"
#include "../keys/save.h"
#include "../tegraexplorer/tconf.h"
#define scriptFunction(name) Variable_t name(scriptCtx_t *ctx, Variable_t *vars, u32 varLen) #define scriptFunction(name) Variable_t name(scriptCtx_t *ctx, Variable_t *vars, u32 varLen)
#define varInt(i) newVar(IntType, 0, i)
#define varStr(s) newVar(StringType, 1, .stringType = s)
scriptFunction(funcIf) { scriptFunction(funcIf) {
setCurIndentInstruction(ctx, (vars[0].integerType == 0), 0, -1); setCurIndentInstruction(ctx, (vars[0].integerType == 0), 0, -1);
return NullVar; return NullVar;
@@ -76,10 +95,343 @@ scriptFunction(funcSetPixel){
return NullVar; return NullVar;
} }
scriptFunction(funcFileExists){
return newVar(IntType, 0, FileExists(vars[0].stringType));
}
// Args: Str (Path)
scriptFunction(funcReadFile){
u32 fSize = 0;
u8 *buff = sd_file_read(vars[0].stringType, &fSize);
if (buff == NULL)
return ErrVar(ERRFATALFUNCFAIL);
Vector_t vec = vecFromArray(buff, fSize, sizeof(u8));
return newVar(ByteArrayType, 1, .vectorType = vec);
}
// Args: Str (Path), vector(Byte) (toWrite)
scriptFunction(funcWriteFile){
return newVar(IntType, 0, sd_save_to_file(vars[1].vectorType.data, vars[1].vectorType.count, vars[0].stringType));
}
// Args: vector(Byte)
scriptFunction(funcByteToStr){
char *str = calloc(vars[0].vectorType.count + 1, 1);
memcpy(str, vars[0].vectorType.data, vars[0].vectorType.count);
return newVar(StringType, 1, .stringType = str);
}
scriptFunction(funcReturn){
if (ctx->indentIndex > 0){
vecDefArray(indentInstructor_t*, instructors, ctx->indentInstructors);
for (int i = ctx->indentIndex - 1; i >= 0; i--){
indentInstructor_t ins = instructors[i];
if (ins.active && ins.jump && ins.function){
ctx->curPos = ins.jumpLoc - 1;
ins.active = 0;
ctx->indentIndex = i;
break;
}
}
}
return NullVar;
}
scriptFunction(funcExit){
return ErrVar(ERRESCSCRIPT);
}
/*
scriptFunction(funcContinue){
if (ctx->indentIndex > 0){
vecDefArray(indentInstructor_t*, instructors, ctx->indentInstructors);
for (int i = ctx->indentIndex - 1; i >= 0; i--){
indentInstructor_t ins = instructors[i];
if (ins.active && ins.jump && !ins.function){
ctx->curPos = ins.jumpLoc - 1;
ins.active = 0;
ctx->indentIndex = i;
break;
}
}
}
return NullVar;
}
*/
// Args: Int, Int
scriptFunction(funcSetPrintPos){
if (vars[0].integerType > 78 || vars[0].integerType < 0 || vars[1].integerType > 42 || vars[1].integerType < 0)
return ErrVar(ERRFATALFUNCFAIL);
gfx_con_setpos(vars[0].integerType * 16, vars[1].integerType * 16);
return NullVar;
}
scriptFunction(funcClearScreen){
gfx_clearscreen();
return NullVar;
}
int validRanges[] = {
1279,
719,
1279,
719
};
// Args: Int, Int, Int, Int, Int
scriptFunction(funcDrawBox){
for (int i = 0; i < ARR_LEN(validRanges); i++){
if (vars[i].integerType > validRanges[i] || vars[i].integerType < 0)
return ErrVar(ERRFATALFUNCFAIL);
}
gfx_box(vars[0].integerType, vars[1].integerType, vars[2].integerType, vars[3].integerType, vars[4].integerType);
return NullVar;
}
typedef struct {
char *name;
u32 color;
} ColorCombo_t;
ColorCombo_t combos[] = {
{"RED", COLOR_RED},
{"ORANGE", COLOR_ORANGE},
{"YELLOW", COLOR_YELLOW},
{"GREEN", COLOR_GREEN},
{"BLUE", COLOR_BLUE},
{"VIOLET", COLOR_VIOLET},
{"GREY", COLOR_GREY},
};
u32 GetColor(char *color){
for (int i = 0; i < ARR_LEN(combos); i++){
if (!strcmp(combos[i].name, color)){
return combos[i].color;
}
}
return COLOR_WHITE;
}
// Args: Str
scriptFunction(funcSetColor){
SETCOLOR(GetColor(vars[0].stringType), COLOR_DEFAULT);
return NullVar;
}
scriptFunction(funcPause){
return newVar(IntType, 0, hidWait()->buttons);
}
// Args: Int
scriptFunction(funcWait){
u32 timer = get_tmr_ms();
while (timer + vars[0].integerType > get_tmr_ms()){
gfx_printf("<Wait %d seconds> \r", (vars[0].integerType - (get_tmr_ms() - timer)) / 1000);
hidRead();
}
return NullVar;
}
scriptFunction(funcGetVer){
int *arr = malloc(3 * sizeof(int));
arr[0] = LP_VER_MJ;
arr[1] = LP_VER_MN;
arr[2] = LP_VER_BF;
Vector_t res = vecFromArray(arr, 3, sizeof(int));
return newVar(IntArrayType, 1, .vectorType = res);
}
// Args: vec(str), int, (optional) vec(str)
scriptFunction(funcMakeMenu){
if (varLen == 3 && vars[2].vectorType.count != vars[0].vectorType.count)
return ErrVar(ERRSYNTAX);
Vector_t menuEntries = newVec(sizeof(MenuEntry_t), vars[0].vectorType.count);
vecDefArray(char**, names, vars[0].vectorType);
char **colors;
if (varLen >= 3)
colors = vecGetArray(char**, vars[2].vectorType);
int *options;
if (varLen == 4)
options = vecGetArray(int*, vars[3].vectorType);
for (int i = 0; i < vars[0].vectorType.count; i++){
u32 color = COLORTORGB(((varLen >= 3) ? GetColor(colors[i]) : COLOR_WHITE));
MenuEntry_t a = {.optionUnion = color, .name = names[i]};
if (varLen == 4){
a.skip = (options[i] & 1) ? 1 : 0;
a.hide = (options[i] & 2) ? 1 : 0;
}
vecAddElem(&menuEntries, a);
}
int res = newMenu(&menuEntries, vars[1].integerType, 78, 10, ENABLEB | ALWAYSREDRAW, menuEntries.count);
vecFree(menuEntries);
return varInt(res);
}
// Args: Str, Str
scriptFunction(funcCombinePath){
if (varLen <= 1)
return NullVar;
for (int i = 0; i < varLen; i++){
if (vars[i].varType != StringType)
return ErrVar(ERRINVALIDTYPE);
}
char *res = CpyStr(vars[0].stringType);
for (int i = 1; i < varLen; i++){
char *temp = CombinePaths(res, vars[i].stringType);
free(res);
res = temp;
}
return varStr(res);
}
// Args: Str
scriptFunction(funcEscFolder){
return newVar(StringType, 1, .stringType = EscapeFolder(vars[0].stringType));
}
// Args: Str, Str
scriptFunction(funcFileMove){
return varInt(f_rename(vars[0].stringType, vars[1].stringType));
}
// Args: Str, Str
scriptFunction(funcFileCopy){
return varInt(FileCopy(vars[0].stringType, vars[1].stringType, COPY_MODE_PRINT).err);
}
// Args: Str
scriptFunction(funcMmcConnect){
int res = 0;
if (!strcmp(vars[0].stringType, "SYSMMC"))
res = connectMMC(MMC_CONN_EMMC);
else if (!strcmp(vars[0].stringType, "EMUMMC") && emu_cfg.enabled)
res = connectMMC(MMC_CONN_EMUMMC);
else
return ErrVar(ERRFATALFUNCFAIL);
return varInt(res);
}
// Args: Str
scriptFunction(funcMmcMount){
if (!TConf.keysDumped)
return ErrVar(ERRFATALFUNCFAIL);
return varInt((mountMMCPart(vars[0].stringType).err));
}
// Args: Str
scriptFunction(funcMkdir){
return varInt((f_mkdir(vars[0].stringType)));
}
// Args: Str
scriptFunction(funcReadDir){
int res = 0;
Vector_t files = ReadFolder(vars[0].stringType, &res);
if (res){
clearFileVector(&files);
return ErrVar(ERRFATALFUNCFAIL);
}
vecDefArray(FSEntry_t*, fsEntries, files);
Vector_t fileNames = newVec(sizeof(char*), files.count);
Vector_t fileProperties = newVec(sizeof(int), files.count);
for (int i = 0; i < files.count; i++){
vecAddElem(&fileNames, fsEntries[i].name);
int isFolder = fsEntries[i].isDir;
vecAddElem(&fileProperties, isFolder);
}
vecFree(files);
dictVectorAdd(&ctx->varDict, newDict(CpyStr("fileProperties"), (newVar(IntArrayType, 1, .vectorType = fileProperties))));
return newVar(StringArrayType, 1, .vectorType = fileNames);
}
// Args: Str, Str
scriptFunction(funcCopyDir){
return varInt((FolderCopy(vars[0].stringType, vars[1].stringType).err));
}
// Args: Str
scriptFunction(funcDelDir){
return varInt((FolderDelete(vars[0].stringType).err));
}
// Args: Str
scriptFunction(funcDelFile){
return varInt((f_unlink(vars[0].stringType)));
}
// Args: Str, Str
scriptFunction(funcMmcDump){
return varInt((DumpOrWriteEmmcPart(vars[0].stringType, vars[1].stringType, 0, 1).err));
}
// Args: Str, Str, Int
scriptFunction(funcMmcRestore){
return varInt((DumpOrWriteEmmcPart(vars[0].stringType, vars[1].stringType, 1, vars[2].integerType).err));
}
// Args: Str
scriptFunction(funcGetNcaType){
if (!TConf.keysDumped)
return ErrVar(ERRFATALFUNCFAIL);
return varInt((GetNcaType(vars[0].stringType)));
}
// Args: Str
scriptFunction(funcSignSave){
if (!TConf.keysDumped)
return ErrVar(ERRFATALFUNCFAIL);
return varInt((saveCommit(vars[0].stringType).err));
}
scriptFunction(funcGetMs){
return varInt(get_tmr_ms());
}
extern int launch_payload(char *path);
// Args: Str
scriptFunction(funcLaunchPayload){
return varInt(launch_payload(vars[0].stringType));
}
u8 fiveInts[] = {IntType, IntType, IntType, IntType, IntType}; u8 fiveInts[] = {IntType, IntType, IntType, IntType, IntType};
u8 singleIntArray[] = { IntArrayType }; u8 singleIntArray[] = { IntArrayType };
u8 singleInt[] = { IntType }; u8 singleInt[] = { IntType };
u8 singleAny[] = { varArgs }; u8 singleAny[] = { varArgs };
u8 singleStr[] = { StringType };
u8 singleByteArr[] = { ByteArrayType };
u8 StrByteVec[] = { StringType, ByteArrayType};
u8 MenuArgs[] = { StringArrayType, IntType, StringArrayType, IntArrayType};
u8 twoStrings[] = { StringType, StringType };
u8 mmcReadWrite[] = { StringType, StringType, IntType};
functionStruct_t scriptFunctions[] = { functionStruct_t scriptFunctions[] = {
{"if", funcIf, 1, singleInt}, {"if", funcIf, 1, singleInt},
@@ -90,6 +442,41 @@ functionStruct_t scriptFunctions[] = {
{"len", funcLen, 1, singleAny}, {"len", funcLen, 1, singleAny},
{"byte", funcMakeByteArray, 1, singleIntArray}, {"byte", funcMakeByteArray, 1, singleIntArray},
{"setPixel", funcSetPixel, 5, fiveInts}, {"setPixel", funcSetPixel, 5, fiveInts},
{"fileRead", funcReadFile, 1, singleStr},
{"fileWrite", funcWriteFile, 2, StrByteVec},
{"fileExists", funcFileExists, 1, singleStr},
{"bytesToStr", funcByteToStr, 1, singleByteArr},
{"return", funcReturn, 0, NULL},
{"exit", funcExit, 0, NULL},
//{"continue", funcContinue, 0, NULL},
{"printPos", funcSetPrintPos, 2, fiveInts},
{"clearscreen", funcClearScreen, 0, NULL},
{"drawBox", funcDrawBox, 5, fiveInts},
{"color", funcSetColor, 1, singleStr},
{"pause", funcPause, 0, NULL},
{"wait", funcWait, 1, singleInt},
{"version", funcGetVer, 0, NULL},
{"menu", funcMakeMenu, 2, MenuArgs}, // for the optional arg
{"menu", funcMakeMenu, 3, MenuArgs},
{"menu", funcMakeMenu, 4, MenuArgs},
{"pathCombine", funcCombinePath, varArgs, NULL},
{"pathEscFolder", funcEscFolder, 1, singleStr},
{"fileMove", funcFileMove, 2, twoStrings},
{"fileCopy", funcFileCopy, 2, twoStrings},
{"fileDel", funcDelFile, 1, singleStr},
{"mmcConnect", funcMmcConnect, 1, singleStr},
{"mmcMount", funcMmcMount, 1, singleStr},
{"mkdir", funcMkdir, 1, singleStr},
{"dirRead", funcReadDir, 1, singleStr},
{"dirCopy", funcCopyDir, 2, twoStrings},
{"dirDel", funcDelDir, 1, singleStr},
{"mmcDump", funcMmcDump, 2, mmcReadWrite},
{"mmcRestore", funcMmcRestore, 3, mmcReadWrite},
{"ncaGetType", funcGetNcaType, 1, singleStr},
{"saveSign", funcSignSave, 1, singleStr},
{"timerMs", funcGetMs, 0, NULL},
{"launchPayload", funcLaunchPayload, 1, singleStr},
// Left from old: keyboard(?)
}; };
Variable_t executeFunction(scriptCtx_t* ctx, char* func_name, lexarToken_t *start, u32 len) { Variable_t executeFunction(scriptCtx_t* ctx, char* func_name, lexarToken_t *start, u32 len) {

View File

@@ -36,8 +36,6 @@ lexarTranslation_t lexarTranslations[] = {
{'*', Multiply}, {'*', Multiply},
{'/', Division}, {'/', Division},
{'%', Mod}, {'%', Mod},
{'<', Smaller},
{'>', Bigger},
{'!', Not}, {'!', Not},
{':', Selector}, {':', Selector},
{')', RBracket}, {')', RBracket},
@@ -46,6 +44,8 @@ lexarTranslation_t lexarTranslations[] = {
{'{', LCBracket}, {'{', LCBracket},
{'=', Equal}, {'=', Equal},
{'[', LSBracket}, {'[', LSBracket},
{'<', Smaller},
{'>', Bigger},
{'\0', 0}, {'\0', 0},
}; };
@@ -92,7 +92,7 @@ void lexarVectorClear(Vector_t *v){
#define ELIFC(c) else if (*in == c) #define ELIFC(c) else if (*in == c)
Vector_t runLexar(const char* in, u32 len) { Vector_t runLexer(const char* in, u32 len) {
const char *start = in; const char *start = in;
Vector_t vec = newVec(sizeof(lexarToken_t), 16); Vector_t vec = newVec(sizeof(lexarToken_t), 16);
// store last var for re-assignment // store last var for re-assignment
@@ -102,16 +102,20 @@ Vector_t runLexar(const char* in, u32 len) {
// maybe measure len between ( ) and [ ], so this doesn't have to be done during runtime? // maybe measure len between ( ) and [ ], so this doesn't have to be done during runtime?
// We also have to support (()). maybe if '(' set indent level, then if ')' minus indent level, set len. indent level contains {u8 level, u16 token, u16 startoffset} // We also have to support (()). maybe if '(' set indent level, then if ')' minus indent level, set len. indent level contains {u8 level, u16 token, u16 startoffset}
u32 lastAssignment = 0;
while ((in - start) < len) { while ((in - start) < len) {
lexarToken_t* lx = vecGetArray(lexarToken_t*, vec); lexarToken_t* lx = vecGetArray(lexarToken_t*, vec);
if ((lx[vec.count - 2].token == StrLit || lx[vec.count - 2].token == IntLit || lx[vec.count - 2].token == Variable || lx[vec.count - 2].token == RSBracket || lx[vec.count - 2].token == RBracket) if ((lx[vec.count - 2].token == StrLit || lx[vec.count - 2].token == IntLit || lx[vec.count - 2].token == Variable || lx[vec.count - 2].token == RSBracket || lx[vec.count - 2].token == RBracket)
&& (lx[vec.count - 1].token == Variable || lx[vec.count - 1].token == LCBracket || lx[vec.count - 1].token == RCBracket)) { && (lx[vec.count - 1].token == Variable || lx[vec.count - 1].token == LCBracket || lx[vec.count - 1].token == RCBracket)) {
if (!(lx[lastAssignment].token == ArrayVariableAssignment && lx[vec.count - 1].token == Variable && lx[vec.count - 2].token == RSBracket)) {
lexarToken_t holder = lx[vec.count - 1]; lexarToken_t holder = lx[vec.count - 1];
lx[vec.count - 1] = makeLexarToken(EquationSeperator, 0); lx[vec.count - 1] = makeLexarToken(EquationSeperator, 0);
vecAddElement(&vec, holder); vecAddElement(&vec, holder);
lx = vecGetArray(lexarToken_t*, vec); lx = vecGetArray(lexarToken_t*, vec);
} }
}
if (isValidWord(*in)) { if (isValidWord(*in)) {
char* startWord = in; char* startWord = in;
@@ -158,6 +162,12 @@ Vector_t runLexar(const char* in, u32 len) {
vecAddElement(&vec, makeLexarToken(LSBracket, 0)); vecAddElement(&vec, makeLexarToken(LSBracket, 0));
} }
ELIFC('=') { // Do we need to keep = if the vars are assignments anyway? ELIFC('=') { // Do we need to keep = if the vars are assignments anyway?
if (in[1] == '='){
vecAddElement(&vec, makeLexarToken(EqualEqual, 0));
in++;
continue;
}
if (lx[vec.count - 1].token == Variable) if (lx[vec.count - 1].token == Variable)
lx[vec.count - 1].token = VariableAssignment; lx[vec.count - 1].token = VariableAssignment;
@@ -170,8 +180,12 @@ Vector_t runLexar(const char* in, u32 len) {
} }
if (lx[vec.count - back].token == ArrayVariable) { if (lx[vec.count - back].token == ArrayVariable) {
lx[vec.count - back].token = ArrayVariableAssignment; lx[vec.count - back].token = ArrayVariableAssignment;
lastAssignment = vec.count - back;
in++;
continue;
} }
} }
lastAssignment = 0;
} }
ELIFC('{') { ELIFC('{') {
if (lx[vec.count - 1].token == VariableAssignment) { if (lx[vec.count - 1].token == VariableAssignment) {
@@ -232,6 +246,30 @@ Vector_t runLexar(const char* in, u32 len) {
vecAddElement(&vec, makeLexarToken(OR, 0)); vecAddElement(&vec, makeLexarToken(OR, 0));
} }
} }
ELIFC('>'){
if (in[1] == '>'){
vecAddElement(&vec, makeLexarToken(BitShiftRight, 0));
in++;
}
else {
int a = (in[1] == '=') ? 1 : 0;
vecAddElement(&vec, makeLexarToken(Bigger, 0));
in += a;
}
}
ELIFC('<'){
if (in[1] == '<'){
vecAddElement(&vec, makeLexarToken(BitShiftLeft, 0));
in++;
}
else {
int a = (in[1] == '=') ? 1 : 0;
vecAddElement(&vec, makeLexarToken(Smaller + a, 0));
in += a;
}
}
else { else {
int val = 0; int val = 0;

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include "types.h" #include "types.h"
Vector_t runLexar(const char* in, u32 len); Vector_t runLexer(const char* in, u32 len);
char lexarDebugGetTokenC(u8 tokenN); char lexarDebugGetTokenC(u8 tokenN);
void lexarVectorClear(Vector_t *v); void lexarVectorClear(Vector_t *v);

View File

@@ -5,6 +5,7 @@
#include "../gfx/gfx.h" #include "../gfx/gfx.h"
#include "../utils/utils.h" #include "../utils/utils.h"
#include <mem/heap.h> #include <mem/heap.h>
#include "../hid/hid.h"
#define scriptResultCreate(resCode, nearToken) (scriptResult_t) {resCode, nearToken, 1} #define scriptResultCreate(resCode, nearToken) (scriptResult_t) {resCode, nearToken, 1}
#define scriptResultCreateLen(resCode, nearToken, len) (scriptResult_t) {resCode, nearToken, len} #define scriptResultCreateLen(resCode, nearToken, len) (scriptResult_t) {resCode, nearToken, len}
@@ -77,13 +78,15 @@ scriptResult_t mainLoop(scriptCtx_t* ctx) {
void printToken(lexarToken_t* token) { void printToken(lexarToken_t* token) {
switch (token->token) { switch (token->token) {
case Variable: case Variable:
case VariableAssignment:
case Function:
case FunctionAssignment:
case ArrayVariable: case ArrayVariable:
case ArrayVariableAssignment: case Function:
gfx_printf("%s", token->text); gfx_printf("%s", token->text);
break; break;
case FunctionAssignment:
case VariableAssignment:
case ArrayVariableAssignment:
gfx_printf("%s=", token->text);
break;
case StrLit: case StrLit:
//printf("%d: '%s'\n", vec.tokens[i].token, vec.tokens[i].text); //printf("%d: '%s'\n", vec.tokens[i].token, vec.tokens[i].text);
gfx_printf("\"%s\"", token->text); gfx_printf("\"%s\"", token->text);
@@ -99,11 +102,29 @@ void printToken(lexarToken_t* token) {
} }
} }
char *ErrorText[] = {
"Bad operator",
"Double not",
"Syntax err",
"Invalid type",
"No var",
"No func",
"Inactive indent",
"Div by 0",
"Func fail"
};
void printError(scriptResult_t res) { void printError(scriptResult_t res) {
if (res.resCode) { if (res.resCode) {
gfx_printf("Error %d found!\nNear: ", res.resCode); if (res.resCode == ERRESCSCRIPT)
return;
gfx_printf("Error found! %s\nNear: ", ErrorText[res.resCode - 1]);
for (int i = 0; i < res.len; i++) { for (int i = 0; i < res.len; i++) {
printToken(&res.nearToken[i]); printToken(&res.nearToken[i]);
} }
gfx_printf("\nPress any key to exit");
hidWait();
} }
} }

View File

@@ -38,6 +38,8 @@ enum Tokens {
AND, AND,
OR, OR,
Selector, Selector,
BitShiftLeft,
BitShiftRight,
EquationSeperator, EquationSeperator,
}; };
@@ -57,7 +59,9 @@ enum Errors {
ERRNOVAR, ERRNOVAR,
ERRNOFUNC, ERRNOFUNC,
ERRINACTIVEINDENT, ERRINACTIVEINDENT,
ERRDIVBYZERO ERRDIVBYZERO,
ERRFATALFUNCFAIL,
ERRESCSCRIPT,
}; };
enum Variables { enum Variables {
@@ -70,6 +74,7 @@ enum Variables {
DictType, DictType,
NullType, NullType,
ErrType, ErrType,
EmptyArrayType,
}; };
typedef struct { // this is to keep track of how many {} we passed. Keep an internal var with the "indentation level", +1 for {, -1 for }. have an array with the following def on what to do (on func: enter, set indentation & jump back, on while, jump to while, use while as if, on if simply set true or false) typedef struct { // this is to keep track of how many {} we passed. Keep an internal var with the "indentation level", +1 for {, -1 for }. have an array with the following def on what to do (on func: enter, set indentation & jump back, on while, jump to while, use while as if, on if simply set true or false)
@@ -130,7 +135,6 @@ typedef struct {
} scriptResult_t; } scriptResult_t;
#define newDict(strName, var) (dict_t) {strName, var} #define newDict(strName, var) (dict_t) {strName, var}
#define newVar(var, frii, value) (Variable_t) {.varType = var, .free = frii, value} #define newVar(var, frii, value) (Variable_t) {.varType = var, .free = frii, value}

View File

@@ -15,7 +15,7 @@ void freeVariable(Variable_t dv) {
case StringArrayType:; case StringArrayType:;
char** strArray = vecGetArray(char**, dv.vectorType); char** strArray = vecGetArray(char**, dv.vectorType);
for (u32 i = 0; i < dv.vectorType.count; i++){ for (u32 i = 0; i < dv.vectorType.count; i++){
FREE(strArray[i]); free(strArray[i]);
} }
case IntArrayType: case IntArrayType:

View File

@@ -125,6 +125,9 @@ ErrCode_t DumpOrWriteEmmcPart(const char *path, const char *part, u8 write, u8 f
if (!sd_mount()) if (!sd_mount())
return newErrCode(TE_ERR_NO_SD); return newErrCode(TE_ERR_NO_SD);
if (TConf.currentMMCConnected == MMC_CONN_None)
return newErrCode(TE_ERR_PARTITION_NOT_FOUND);
if (!memcmp(part, "BOOT0", 5)){ if (!memcmp(part, "BOOT0", 5)){
emummc_storage_set_mmc_partition(&emmc_storage, 1); emummc_storage_set_mmc_partition(&emmc_storage, 1);
lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1; lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;

View File

@@ -175,10 +175,7 @@ out:
int emummc_storage_end(sdmmc_storage_t *storage) int emummc_storage_end(sdmmc_storage_t *storage)
{ {
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
sdmmc_storage_end(storage); sdmmc_storage_end(storage);
else
sd_end();
return 1; return 1;
} }

View File

@@ -84,11 +84,6 @@ void GptMenu(u8 MMCType){
gfx_clearscreen(); gfx_clearscreen();
char *fileName = CpyStr(strrchr(TConf.srcCopy, '/') + 1); char *fileName = CpyStr(strrchr(TConf.srcCopy, '/') + 1);
for (int i = 0; i < strlen(fileName); i++){
if (fileName[i] >= 'a' && fileName[i] <= 'z')
fileName[i] &= ~BIT(5);
}
gfx_printf("Are you sure you want to flash %s? ", fileName); gfx_printf("Are you sure you want to flash %s? ", fileName);
if (MakeYesNoHorzMenu(3, COLOR_DEFAULT)){ if (MakeYesNoHorzMenu(3, COLOR_DEFAULT)){
RESETCOLOR; RESETCOLOR;
@@ -118,6 +113,7 @@ void GptMenu(u8 MMCType){
DrawError(err); DrawError(err);
} }
else { else {
if (TConf.keysDumped){
if (TConf.curExplorerLoc > LOC_SD) if (TConf.curExplorerLoc > LOC_SD)
ResetCopyParams(); ResetCopyParams();
@@ -125,6 +121,7 @@ void GptMenu(u8 MMCType){
FileExplorer("bis:/"); FileExplorer("bis:/");
} }
} }
}
else { else {
if (!sd_mount()) if (!sd_mount())
continue; continue;

View File

@@ -22,6 +22,7 @@ void SetKeySlots(){
// Not for bis but whatever // Not for bis but whatever
se_aes_key_set(6, dumpedKeys.header_key + 0x00, 0x10); se_aes_key_set(6, dumpedKeys.header_key + 0x00, 0x10);
se_aes_key_set(7, dumpedKeys.header_key + 0x10, 0x10); se_aes_key_set(7, dumpedKeys.header_key + 0x10, 0x10);
se_aes_key_set(8, dumpedKeys.save_mac_key, 0x10);
} }
} }
@@ -61,6 +62,9 @@ int connectMMC(u8 mmcType){
} }
ErrCode_t mountMMCPart(const char *partition){ ErrCode_t mountMMCPart(const char *partition){
if (TConf.currentMMCConnected == MMC_CONN_None)
return newErrCode(TE_ERR_PARTITION_NOT_FOUND);
unmountMMCPart(); unmountMMCPart();
emummc_storage_set_mmc_partition(&emmc_storage, 0); // why i have to do this twice beats me emummc_storage_set_mmc_partition(&emmc_storage, 0); // why i have to do this twice beats me

View File

@@ -141,8 +141,7 @@ void EnterMainMenu(){
// -- Explore -- // -- Explore --
mainMenuEntries[MainBrowseSd].hide = !sd_mounted; mainMenuEntries[MainBrowseSd].hide = !sd_mounted;
mainMenuEntries[MainMountSd].name = (sd_mounted) ? "Unmount SD" : "Mount SD"; mainMenuEntries[MainMountSd].name = (sd_mounted) ? "Unmount SD" : "Mount SD";
mainMenuEntries[MainBrowseEmmc].hide = !TConf.keysDumped; mainMenuEntries[MainBrowseEmummc].hide = (!emu_cfg.enabled || !sd_mounted);
mainMenuEntries[MainBrowseEmummc].hide = (!TConf.keysDumped || !emu_cfg.enabled || !sd_mounted);
// -- Tools -- // -- Tools --
mainMenuEntries[MainPartitionSd].hide = (!is_sd_inited || sd_get_card_removed()); mainMenuEntries[MainPartitionSd].hide = (!is_sd_inited || sd_get_card_removed());

View File

@@ -197,3 +197,65 @@ void FormatSD(){
free(work); free(work);
hidWait(); 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);
sprintf(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);
}

View File

@@ -1,4 +1,24 @@
#pragma once #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 DumpSysFw();
void FormatSD(); void FormatSD();
void TakeScreenshot();

View File

@@ -64,7 +64,7 @@ char *ShowKeyboard(const char *toEdit, u8 alwaysRet){
int posOnWord = 0; int posOnWord = 0;
bool shift = 0; bool shift = 0;
gfx_printf("* = exit | ~ = backspace | ^(left) = shift | _ = Space | + = add char\n\n"); gfx_printf("* = exit | ~ = backspace | ^(left) = shift | + = add char\n\n");
u32 x, y; u32 x, y;
gfx_con_getpos(&x, &y); gfx_con_getpos(&x, &y);
@@ -142,6 +142,7 @@ char *ShowKeyboard(const char *toEdit, u8 alwaysRet){
} }
int val = (input->up || input->down) ? 11 : 1; int val = (input->up || input->down) ? 11 : 1;
// Btn buttons do not work lol
if (input->buttons & (JoyLLeft | JoyLUp | BtnVolM)){ if (input->buttons & (JoyLLeft | JoyLUp | BtnVolM)){
if (pos > -1 + val) if (pos > -1 + val)
pos -= val; pos -= val;

View File

@@ -47,9 +47,14 @@ bool vecAdd(Vector_t* v, void* elem, u32 sz)
return true; return true;
} }
Vector_t vecCopy(Vector_t* orig) { Vector_t vecCopyOffset(Vector_t* orig, u32 offset) {
Vector_t dst = newVec(orig->elemSz, orig->count); Vector_t dst = newVec(orig->elemSz, orig->count - offset);
memcpy(dst.data, orig->data, orig->count * orig->elemSz); memcpy(dst.data, ((u8*)orig->data + orig->elemSz * offset), (orig->count - offset) * orig->elemSz);
dst.count = orig->count; dst.count = orig->count - offset;
return dst; return dst;
} }
Vector_t vecCopy(Vector_t* orig) {
return vecCopyOffset(orig, 0);
}

View File

@@ -27,3 +27,4 @@ Vector_t newVec(u32 typesz, u32 preallocate);
Vector_t vecFromArray(void* array, u32 count, u32 typesz); Vector_t vecFromArray(void* array, u32 count, u32 typesz);
bool vecAdd(Vector_t* v, void* elem, u32 sz); bool vecAdd(Vector_t* v, void* elem, u32 sz);
Vector_t vecCopy(Vector_t* orig); Vector_t vecCopy(Vector_t* orig);
Vector_t vecCopyOffset(Vector_t* orig, u32 offset);