diff --git a/arm9/source/common/common.h b/arm9/source/common/common.h index de1c541..e64e09f 100644 --- a/arm9/source/common/common.h +++ b/arm9/source/common/common.h @@ -49,11 +49,8 @@ // used in several places #define STD_BUFFER_SIZE 0x100000 // must be a multiple of 0x200 -// buffer area defines (in use by scripting.c) -#define SCRIPT_BUFFER ((u8*)0x20300000) -#define SCRIPT_BUFFER_SIZE (0x100000) // buffer area defines (in use by vgame.c) -#define VGAME_BUFFER ((u8*)0x20400000) +#define VGAME_BUFFER ((u8*)0x20000000) #define VGAME_BUFFER_SIZE (0x200000) // 2MB, big RomFS // buffer area defines (in use by image.c, for RAMdrive) diff --git a/arm9/source/godmode.c b/arm9/source/godmode.c index 4b7e30f..20f314a 100644 --- a/arm9/source/godmode.c +++ b/arm9/source/godmode.c @@ -2437,16 +2437,9 @@ u32 ScriptRunner(int entrypoint) { while (HID_STATE); // wait until no buttons are pressed while (timer_msec( timer ) < 500); // show splash for at least 0.5 sec - // get script from VRAM0 TAR - u64 autorun_gm9_size = 0; - void* autorun_gm9 = FindVTarFileInfo(VRAM0_AUTORUN_GM9, &autorun_gm9_size); - - if (autorun_gm9 && autorun_gm9_size) { + if (PathExist("V:/" VRAM0_AUTORUN_GM9)) { ClearScreenF(true, true, COLOR_STD_BG); // clear splash - // copy script to script buffer and run it - memset(SCRIPT_BUFFER, 0, SCRIPT_BUFFER_SIZE); - memcpy(SCRIPT_BUFFER, autorun_gm9, autorun_gm9_size); - ExecuteGM9Script(NULL); + ExecuteGM9Script("V:/" VRAM0_AUTORUN_GM9); } else if (PathExist("V:/" VRAM0_SCRIPTS)) { char loadpath[256]; if (FileSelector(loadpath, FLAVOR " scripts menu.\nSelect script:", "V:/" VRAM0_SCRIPTS, "*.gm9", HIDE_EXT)) diff --git a/arm9/source/system/memmap.h b/arm9/source/system/memmap.h index 1a715cc..afbf0e9 100644 --- a/arm9/source/system/memmap.h +++ b/arm9/source/system/memmap.h @@ -24,5 +24,5 @@ #define __STACKABT_TOP (__STACK_TOP - __STACK_SIZE) #define __STACKABT_SIZE 0x10000 -#define __HEAP_ADDR (__FCRAM0_ADDR + 0x0700000) +#define __HEAP_ADDR (__FCRAM0_ADDR + 0x0200000) #define __HEAP_END (__STACKABT_TOP - __STACKABT_SIZE) diff --git a/arm9/source/utils/scripting.c b/arm9/source/utils/scripting.c index 2e81e38..9bd5fce 100644 --- a/arm9/source/utils/scripting.c +++ b/arm9/source/utils/scripting.c @@ -19,6 +19,7 @@ #define _ARG_MAX_LEN 512 #define _VAR_CNT_LEN 256 #define _VAR_NAME_LEN 32 +#define _VAR_MAX_BUFF 256 #define _ERR_STR_LEN 32 #define _CHOICE_STR_LEN 32 @@ -43,8 +44,6 @@ #define _MAX_FOR_DEPTH 16 -#define VAR_BUFFER (SCRIPT_BUFFER + SCRIPT_BUFFER_SIZE - VAR_BUFFER_SIZE) - // macros for textviewer #define TV_VPAD 1 // vertical padding per line (above / below) #define TV_HPAD 0 // horizontal padding per line (left) @@ -188,6 +187,10 @@ static char* for_ptr = NULL; // position of the active 'for' command static u32 skip_state = 0; // zero, _SKIP_BLOCK, _SKIP_TILL_END static u32 ifcnt = 0; // current # of 'if' nesting +// script / var buffers +static void* script_buffer = NULL; +static void* var_buffer = NULL; + static inline bool isntrboot(void) { // taken over from Luma 3DS: @@ -321,17 +324,16 @@ void set_preview(const char* name, const char* content) { } char* set_var(const char* name, const char* content) { - Gm9ScriptVar* vars = (Gm9ScriptVar*) VAR_BUFFER; - u32 max_vars = VAR_BUFFER_SIZE / sizeof(Gm9ScriptVar); + Gm9ScriptVar* vars = (Gm9ScriptVar*) var_buffer; if ((strnlen(name, _VAR_NAME_LEN) > (_VAR_NAME_LEN-1)) || (strnlen(content, _VAR_CNT_LEN) > (_VAR_CNT_LEN-1)) || (strchr(name, '[') || strchr(name, ']'))) return NULL; u32 n_var = 0; - for (Gm9ScriptVar* var = vars; n_var < max_vars; n_var++, var++) + for (Gm9ScriptVar* var = vars; n_var < _VAR_MAX_BUFF; n_var++, var++) if (!*(var->name) || (strncmp(var->name, name, _VAR_NAME_LEN) == 0)) break; - if (n_var >= max_vars) return NULL; + if (n_var >= _VAR_MAX_BUFF) return NULL; strncpy(vars[n_var].name, name, _VAR_NAME_LEN); strncpy(vars[n_var].content, content, _VAR_CNT_LEN); if (!n_var) *(vars[n_var].content) = '\0'; // NULL var @@ -392,8 +394,7 @@ void upd_var(const char* name) { } char* get_var(const char* name, char** endptr) { - Gm9ScriptVar* vars = (Gm9ScriptVar*) VAR_BUFFER; - u32 max_vars = VAR_BUFFER_SIZE / sizeof(Gm9ScriptVar); + Gm9ScriptVar* vars = (Gm9ScriptVar*) var_buffer; u32 name_len = 0; char* pname = NULL; @@ -414,18 +415,18 @@ char* get_var(const char* name, char** endptr) { upd_var(vname); // handle dynamic env vars u32 n_var = 0; - for (Gm9ScriptVar* var = vars; n_var < max_vars; n_var++, var++) { + for (Gm9ScriptVar* var = vars; n_var < _VAR_MAX_BUFF; n_var++, var++) { if (!*(var->name) || (strncmp(var->name, vname, _VAR_NAME_LEN) == 0)) break; } - if (n_var >= max_vars || !*(vars[n_var].name)) n_var = 0; + if (n_var >= _VAR_MAX_BUFF || !*(vars[n_var].name)) n_var = 0; return vars[n_var].content; } bool init_vars(const char* path_script) { // reset var buffer - memset(VAR_BUFFER, 0x00, VAR_BUFFER_SIZE); + memset(var_buffer, 0x00, sizeof(Gm9ScriptVar) * _VAR_MAX_BUFF); // current path char curr_dir[_VAR_CNT_LEN]; @@ -628,7 +629,7 @@ char* find_next(char* ptr) { } char* find_label(const char* label, const char* last_found) { - char* script = (char*) SCRIPT_BUFFER; // equals global, not a good solution + char* script = (char*) script_buffer; char* ptr = script; if (last_found) { @@ -1592,11 +1593,10 @@ bool FileTextViewer(const char* path, bool as_script) { } bool ExecuteGM9Script(const char* path_script) { - char* script = (char*) SCRIPT_BUFFER; - char* ptr = script; char path_str[32+1]; TruncateString(path_str, path_script, 32, 12); + // reset control flow global vars ifcnt = 0; jump_ptr = NULL; @@ -1604,10 +1604,28 @@ bool ExecuteGM9Script(const char* path_script) { skip_state = 0; syntax_error = false; - // fetch script - if no path is given, assume script already in script buffer - u32 script_size = (path_script) ? FileGetData(path_script, (u8*) script, SCRIPT_MAX_SIZE, 0) : strnlen(script, SCRIPT_BUFFER_SIZE); - if (!script_size || (script_size >= SCRIPT_BUFFER_SIZE)) + + // allocate && check memory + var_buffer = (void*) malloc(sizeof(Gm9ScriptVar) * _VAR_MAX_BUFF); + script_buffer = (void*) malloc(SCRIPT_MAX_SIZE); + char* script = (char*) script_buffer; + char* ptr = script; + + if (!var_buffer || !script_buffer) { + if (var_buffer) free(var_buffer); + if (script_buffer) free(script_buffer); + ShowPrompt(false, "Out of memory."); return false; + } + + // fetch script from path + u32 script_size = FileGetData(path_script, (u8*) script, SCRIPT_MAX_SIZE, 0); + if (!script_size || (script_size >= SCRIPT_MAX_SIZE)) { + free(var_buffer); + free(script_buffer); + return false; + } + char* end = script + script_size; *end = '\0'; @@ -1626,6 +1644,7 @@ bool ExecuteGM9Script(const char* path_script) { // script execute loop u32 lno = 1; + bool result = true; while (ptr < end) { u32 flags = 0; @@ -1734,7 +1753,11 @@ bool ExecuteGM9Script(const char* path_script) { ShowPrompt(false, "%s\nline %lu: %s\n%s", path_str, lno, err_str, line_str); } } - if (!(flags & _FLG('o'))) return false; // failed if not optional + if (!(flags & _FLG('o'))) { // failed if not optional + for_handler(NULL, NULL, NULL, false); // make sure we don't have an open 'for' + result = false; // we failed + break; + } } // reposition pointer @@ -1754,19 +1777,26 @@ bool ExecuteGM9Script(const char* path_script) { } } - // check for unresolved if here - if (ifcnt) { - ShowPrompt(false, "%s\nend of script: unresolved 'if'", path_str); - return false; - } else if (for_ptr) { - ShowPrompt(false, "%s\nend of script: unresolved 'for'", path_str); - for_handler(NULL, NULL, NULL, false); - return false; + + if (result) { // all fine(?) up to this point + if (ifcnt) { // check for unresolved 'if' + ShowPrompt(false, "%s\nend of script: unresolved 'if'", path_str); + result = false; + } + if (for_ptr) { // check for unresolved 'for' + ShowPrompt(false, "%s\nend of script: unresolved 'for'", path_str); + for_handler(NULL, NULL, NULL, false); + result = false; + } } - // success message if applicable - char* msg_okay = get_var("SUCCESSMSG", NULL); - if (msg_okay && *msg_okay) ShowPrompt(false, msg_okay); + if (result) { // success message if applicable + char* msg_okay = get_var("SUCCESSMSG", NULL); + if (msg_okay && *msg_okay) ShowPrompt(false, msg_okay); + } - return true; + + free(var_buffer); + free(script_buffer); + return result; } diff --git a/arm9/source/utils/scripting.h b/arm9/source/utils/scripting.h index 309a118..ad1aa52 100644 --- a/arm9/source/utils/scripting.h +++ b/arm9/source/utils/scripting.h @@ -2,10 +2,8 @@ #include "common.h" -#define VAR_BUFFER_SIZE (72 * 1024) // enough for exactly 256 vars - #define SCRIPT_EXT "gm9" -#define SCRIPT_MAX_SIZE (SCRIPT_BUFFER_SIZE-VAR_BUFFER_SIZE-1) +#define SCRIPT_MAX_SIZE STD_BUFFER_SIZE bool ValidateText(const char* text, u32 size); bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script);