diff --git a/Build/PTM.exe b/Build/PTM.exe index 9493ad64..ead6df47 100644 Binary files a/Build/PTM.exe and b/Build/PTM.exe differ diff --git a/Build/test.ptml b/Build/test.ptml index f83e52fa..d63b329e 100644 --- a/Build/test.ptml +++ b/Build/test.ptml @@ -1,4 +1,5 @@ O35bIFRFU1QgUFJPR1JBTSBdfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+ +a2V5LmVzYy5vbg== Q0FMTCBpbml0X2Nocg== Q0FMTCBpbml0X3BhbA== diff --git a/PTM/t_command.cpp b/PTM/t_command.cpp index 5cbcc06d..80092ced 100644 --- a/PTM/t_command.cpp +++ b/PTM/t_command.cpp @@ -42,7 +42,8 @@ bool t_command::execute(string& cmd, t_params& args) { else if (cmd == "TILE.STORE") store_cur_tile(args); else if (cmd == "TILE.PSTORE") parse_and_store_tile(args); else if (cmd == "TILE.LOAD") load_cur_tile(args); - else if (cmd == "TILE.TRA") set_tile_transparency(args); + else if (cmd == "TILE.TRA.ON") set_tile_transparency(args, true); + else if (cmd == "TILE.TRA.OFF") set_tile_transparency(args, false); // Tile buffer cursor else if (cmd == "CSR.LAYER") select_layer(args); else if (cmd == "CSR.SET") set_cursor_pos(args); @@ -72,6 +73,8 @@ bool t_command::execute(string& cmd, t_params& args) { else if (cmd == "KEY.GET") get_key_pressed(args); else if (cmd == "KEY.CALL") call_if_key_pressed(args); else if (cmd == "KEY.GOTO") goto_if_key_pressed(args); + else if (cmd == "KEY.ESC.ON") allow_exit_on_escape_key(args, true); + else if (cmd == "KEY.ESC.OFF") allow_exit_on_escape_key(args, false); // Debug else if (cmd == "DBG.FILE") save_debug_file(args); // Conditionals @@ -398,10 +401,9 @@ void t_command::set_wnd_bgcolor(t_params& arg) { ARGC(1); machine->wnd->SetBackColor(machine->pal->GetColorRGB(intp->require_number(arg[0]))); } -void t_command::set_tile_transparency(t_params& arg) { - ARGC(1); - int value = intp->require_number(arg[0]); - machine->tile_transparency = value > 0; +void t_command::set_tile_transparency(t_params& arg, bool transparent) { + ARGC(0); + machine->tile_transparency = transparent; } void t_command::select_layer(t_params& arg) { ARGC(1); @@ -727,3 +729,8 @@ void t_command::increment_variable(t_params& arg) { auto& var = machine->vars[arr_id]; machine->vars[arr_id] = String::ToString(String::ToInt(var.value) + 1); } + +void t_command::allow_exit_on_escape_key(t_params& arg, bool allow) { + ARGC(0); + machine->exit_key = allow ? SDLK_ESCAPE : 0; +} diff --git a/PTM/t_command.h b/PTM/t_command.h index 2a046ff3..8e38ee56 100644 --- a/PTM/t_command.h +++ b/PTM/t_command.h @@ -40,7 +40,7 @@ struct t_command { void clear_layer(t_params& arg); void clear_rect(t_params& arg); void set_wnd_bgcolor(t_params& arg); - void set_tile_transparency(t_params& arg); + void set_tile_transparency(t_params& arg, bool transparent); void select_layer(t_params& arg); void define_char(t_params& arg); void define_color(t_params& arg); @@ -79,4 +79,5 @@ struct t_command { void clear_array(t_params& arg); void copy_array(t_params& arg); void increment_variable(t_params& arg); + void allow_exit_on_escape_key(t_params& arg, bool allow); }; diff --git a/PTM/t_compiler.cpp b/PTM/t_compiler.cpp index 368ba295..0b4ede8e 100644 --- a/PTM/t_compiler.cpp +++ b/PTM/t_compiler.cpp @@ -7,9 +7,9 @@ void t_compiler::run(t_program* prg) { prg->lines.clear(); prg->labels.clear(); int src_line_nr = 1; - for (auto& srcline : prg->src_lines) { + for (auto& src_line : prg->src_lines) { t_program_line new_line; - bool must_add_line = compile(prg, &new_line, srcline, src_line_nr); + bool must_add_line = compile(prg, &new_line, src_line, src_line_nr); if (must_add_line) { prg->lines.push_back(new_line); } @@ -17,14 +17,21 @@ void t_compiler::run(t_program* prg) { } } bool t_compiler::compile(t_program* prg, t_program_line* new_line, string src_line, int src_line_nr) { - int line_ix = prg->lines.size(); + if (String::StartsWith(src_line, ' ')) { + add_error(src_line_nr, src_line, "Leading whitespace is not allowed"); + return false; + } src_line = String::Trim(src_line); if (String::StartsWith(src_line, ';')) { return false; } if (String::StartsWith(src_line, ":")) { string label = String::Trim(String::Skip(src_line, 1)); - prg->labels[label] = line_ix; + prg->labels[label] = prg->lines.size(); + return false; + } + if (!src_line.empty() && !String::StartsWithLetter(src_line)) { + add_error(src_line_nr, src_line, "Syntax error"); return false; } new_line->src = src_line; @@ -118,6 +125,6 @@ bool t_compiler::compile(t_program* prg, t_program_line* new_line, string src_li return true; } void t_compiler::add_error(int line, string src, string msg) { - errors.push_back(String::Format("At line %i:\n%s\n\n%s", + errors.push_back(String::Format("COMPILATION ERROR\nAt line %i:\n%s\n\n%s", line, msg.c_str(), src.c_str())); } diff --git a/PTM/t_interpreter.cpp b/PTM/t_interpreter.cpp index 9d143ae5..5bf42d8a 100644 --- a/PTM/t_interpreter.cpp +++ b/PTM/t_interpreter.cpp @@ -71,6 +71,8 @@ void t_interpreter::execute_current_line() { void t_interpreter::on_keydown(SDL_Keycode key, bool ctrl, bool shift, bool alt) { if (key == SDLK_RETURN && TKey::Alt()) { wnd->ToggleFullscreen(); + } else if (machine->exit_key != 0 && key == machine->exit_key) { + running = false; } else { machine->last_key_pressed = key; } @@ -78,7 +80,7 @@ void t_interpreter::on_keydown(SDL_Keycode key, bool ctrl, bool shift, bool alt) void t_interpreter::abort(string error) { running = false; if (cur_line) { - errors.push_back(String::Format("At line %i:\n%s\n\n%s", + errors.push_back(String::Format("RUNTIME ERROR\nAt line %i:\n%s\n\n%s", cur_line->src_line_nr, error.c_str(), cur_line->src.c_str())); } else { errors.push_back(error); diff --git a/PTM/t_machine.h b/PTM/t_machine.h index 5025df49..344aabdf 100644 --- a/PTM/t_machine.h +++ b/PTM/t_machine.h @@ -25,6 +25,7 @@ struct t_machine { } text_color; // Input SDL_Keycode last_key_pressed = 0; + SDL_Keycode exit_key = 0; // Sound TSound* snd = nullptr; // Comparisons diff --git a/PTM/t_program_editor.cpp b/PTM/t_program_editor.cpp index e0d8d818..1ff079db 100644 --- a/PTM/t_program_editor.cpp +++ b/PTM/t_program_editor.cpp @@ -390,9 +390,9 @@ void t_program_editor::compile_and_run() { void t_program_editor::print_errors(std::vector& errors) { snd->Beep(2500, 100); string error = errors[0]; - while (running) { + while (running || !cfg->autorun.empty()) { draw_screen_base(); - print_border_top("RUNTIME ERROR", 0); + print_border_top("PTM", 0); if (cfg->autorun.empty()) { print_border_bottom("Press ENTER to continue...", 0); } else {