From eaaa6fda8520bbc56ffb5297883f30d088233033 Mon Sep 17 00:00:00 2001 From: user4520 Date: Sun, 31 Oct 2021 13:01:26 +0100 Subject: [PATCH] Undo CRLF conversions by vscode --- gen/iw5/Makefile | 24 +- src/iw5/stdafx.hpp | 78 +-- src/iw5/xsk/compiler.hpp | 326 +++++----- src/tool/xsk/main.cpp | 1256 +++++++++++++++++++------------------- src/utils/xsk/utils.hpp | 56 +- 5 files changed, 870 insertions(+), 870 deletions(-) diff --git a/gen/iw5/Makefile b/gen/iw5/Makefile index a8863424..86e83f69 100644 --- a/gen/iw5/Makefile +++ b/gen/iw5/Makefile @@ -1,12 +1,12 @@ -generate: IW5 - -clean: - rm -rf ./parser.hpp - rm -rf ./parser.cpp - rm -rf ./lexer.hpp - rm -rf ./lexer.cpp - -IW5: lexer.lpp parser.ypp - flex lexer.lpp - bison parser.ypp -Wcounterexamples - mv lexer.hpp lexer.cpp parser.hpp parser.cpp ../../src/iw5/xsk/ +generate: IW5 + +clean: + rm -rf ./parser.hpp + rm -rf ./parser.cpp + rm -rf ./lexer.hpp + rm -rf ./lexer.cpp + +IW5: lexer.lpp parser.ypp + flex lexer.lpp + bison parser.ypp -Wcounterexamples + mv lexer.hpp lexer.cpp parser.hpp parser.cpp ../../src/iw5/xsk/ diff --git a/src/iw5/stdafx.hpp b/src/iw5/stdafx.hpp index e196373e..f9802079 100644 --- a/src/iw5/stdafx.hpp +++ b/src/iw5/stdafx.hpp @@ -1,39 +1,39 @@ -// Copyright 2021 xensik. All rights reserved. -// -// Use of this source code is governed by a GNU GPLv3 license -// that can be found in the LICENSE file. - -#pragma once - -// Warnings -#ifdef _WIN32 -#pragma warning(disable:4244) -#pragma warning(disable:4267) -#pragma warning(disable:4005) -#pragma warning(disable:4065) -#define _CRT_SECURE_NO_WARNINGS -#endif - -// C/C++ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Ext -using namespace std::literals; - -#include "xsk/iw5.hpp" +// Copyright 2021 xensik. All rights reserved. +// +// Use of this source code is governed by a GNU GPLv3 license +// that can be found in the LICENSE file. + +#pragma once + +// Warnings +#ifdef _WIN32 +#pragma warning(disable:4244) +#pragma warning(disable:4267) +#pragma warning(disable:4005) +#pragma warning(disable:4065) +#define _CRT_SECURE_NO_WARNINGS +#endif + +// C/C++ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Ext +using namespace std::literals; + +#include "xsk/iw5.hpp" diff --git a/src/iw5/xsk/compiler.hpp b/src/iw5/xsk/compiler.hpp index 9a5142e1..1396786b 100644 --- a/src/iw5/xsk/compiler.hpp +++ b/src/iw5/xsk/compiler.hpp @@ -1,163 +1,163 @@ -// Copyright 2021 xensik. All rights reserved. -// -// Use of this source code is governed by a GNU GPLv3 license -// that can be found in the LICENSE file. - -#pragma once - -namespace xsk::gsc::iw5 -{ - -enum class opcode : std::uint8_t; - -class compiler : public gsc::compiler -{ - std::string filename_; - std::vector assembly_; - gsc::function_ptr function_; - std::uint32_t index_; - std::uint32_t label_idx_; - std::uint8_t stack_idx_; - std::vector local_stack_; - std::vector local_functions_; - std::vector includes_; - std::vector animtrees_; - std::unordered_map constants_; - std::function(const std::string&)> callback_readf_; - std::vector break_ctxs_; - std::vector continue_ctxs_; - bool can_break_; - bool can_continue_; - -public: - compiler(gsc::compilation_mode mode) : m_mode(mode) {} - - auto output() -> std::vector; - void compile(const std::string& file, std::vector& data); - void set_readf_callback(std::function(const std::string&)> func); - -private: - auto parse_buffer(const std::string& file, std::vector& data) -> gsc::program_ptr; - auto parse_file(const std::string& file) -> gsc::program_ptr; - void compile_program(const gsc::program_ptr& program); - void emit_include(const gsc::include_ptr& include); - void emit_define(const gsc::define_ptr& define); - void emit_usingtree(const gsc::usingtree_ptr& animtree); - void emit_constant(const gsc::constant_ptr& constant); - void emit_thread(const gsc::thread_ptr& thread); - void emit_parameters(const gsc::context_ptr& ctx, const gsc::parameters_ptr& params); - void emit_stmt(const gsc::context_ptr& ctx, const gsc::stmt_ptr& stmt, bool last); - void emit_stmt_list(const gsc::context_ptr& ctx, const gsc::stmt_list_ptr& stmt, bool last); - void emit_stmt_call(const gsc::context_ptr& ctx, const gsc::stmt_call_ptr& stmt); - void emit_stmt_assign(const gsc::context_ptr& ctx, const gsc::stmt_assign_ptr& stmt); - void emit_stmt_endon(const gsc::context_ptr& ctx, const gsc::stmt_endon_ptr& stmt); - void emit_stmt_notify(const gsc::context_ptr& ctx, const gsc::stmt_notify_ptr& stmt); - void emit_stmt_wait(const gsc::context_ptr& ctx, const gsc::stmt_wait_ptr& stmt); - void emit_stmt_waittill(const gsc::context_ptr& ctx, const gsc::stmt_waittill_ptr& stmt); - void emit_stmt_waittillmatch(const gsc::context_ptr& ctx, const gsc::stmt_waittillmatch_ptr& stmt); - void emit_stmt_waittillframeend(const gsc::context_ptr& ctx, const gsc::stmt_waittillframeend_ptr& stmt); - void emit_stmt_if(const gsc::context_ptr& ctx, const gsc::stmt_if_ptr& stmt, bool last); - void emit_stmt_ifelse(const gsc::context_ptr& ctx, const gsc::stmt_ifelse_ptr& stmt, bool last); - void emit_stmt_while(const gsc::context_ptr& ctx, const gsc::stmt_while_ptr& stmt); - void emit_stmt_for(const gsc::context_ptr& ctx, const gsc::stmt_for_ptr& stmt); - void emit_stmt_foreach(const gsc::context_ptr& ctx, const gsc::stmt_foreach_ptr& stmt); - void emit_stmt_switch(const gsc::context_ptr& ctx, const gsc::stmt_switch_ptr& stmt); - void emit_stmt_case(const gsc::context_ptr& ctx, const gsc::stmt_case_ptr& stmt); - void emit_stmt_default(const gsc::context_ptr& ctx, const gsc::stmt_default_ptr& stmt); - void emit_stmt_break(const gsc::context_ptr& ctx, const gsc::stmt_break_ptr& stmt); - void emit_stmt_continue(const gsc::context_ptr& ctx, const gsc::stmt_continue_ptr& stmt); - void emit_stmt_return(const gsc::context_ptr& ctx, const gsc::stmt_return_ptr& stmt); - void emit_expr(const gsc::context_ptr& ctx, const gsc::expr_ptr& expr); - void emit_expr_assign(const gsc::context_ptr& ctx, const gsc::expr_assign_ptr& expr); - void emit_expr_ternary(const gsc::context_ptr& ctx, const gsc::expr_ternary_ptr& expr); - void emit_expr_binary(const gsc::context_ptr& ctx, const gsc::expr_binary_ptr& expr); - void emit_expr_and(const gsc::context_ptr& ctx, const gsc::expr_and_ptr& expr); - void emit_expr_or(const gsc::context_ptr& ctx, const gsc::expr_or_ptr& expr); - void emit_expr_complement(const gsc::context_ptr& ctx, const gsc::expr_complement_ptr& expr); - void emit_expr_not(const gsc::context_ptr& ctx, const gsc::expr_not_ptr& expr); - void emit_expr_call(const gsc::context_ptr& ctx, const gsc::expr_call_ptr& expr); - void emit_expr_call_pointer(const gsc::context_ptr& ctx, const gsc::expr_call_ptr& expr); - void emit_expr_call_pointer_type(const gsc::context_ptr& ctx, int args, bool builtin, bool method, bool thread, bool child); - void emit_expr_call_function(const gsc::context_ptr& ctx, const gsc::expr_call_ptr& expr); - void emit_expr_call_function_builtin(const gsc::context_ptr& ctx, const std::string& func, int args, bool method); - void emit_expr_call_function_local(const gsc::context_ptr& ctx, const std::string& func, int args, bool method, bool thread, bool child); - void emit_expr_call_function_far(const gsc::context_ptr& ctx, const std::string& file, const std::string& func, int args, bool method, bool thread, bool child); - void emit_expr_arguments(const gsc::context_ptr& ctx, const gsc::expr_arguments_ptr& arg_list); - void emit_expr_function(const gsc::context_ptr& ctx, const gsc::expr_function_ptr& node); - void emit_expr_clear_variable(const gsc::context_ptr& ctx, const gsc::expr_ptr& lvalue); - void emit_expr_add_array(const gsc::context_ptr& ctx, const gsc::expr_add_array_ptr& expr); - void emit_expr_size(const gsc::context_ptr& ctx, const gsc::expr_size_ptr& expr); - void emit_variable_ref(const gsc::context_ptr& ctx, const gsc::expr_ptr& expr, bool set); - void emit_array_variable_ref(const gsc::context_ptr& ctx, const gsc::expr_array_ptr& expr, bool set); - void emit_field_variable_ref(const gsc::context_ptr& ctx, const gsc::expr_field_ptr& expr, bool set); - void emit_local_variable_ref(const gsc::context_ptr& ctx, const gsc::name_ptr& expr, bool set); - void emit_variable(const gsc::context_ptr& ctx, const gsc::expr_ptr& expr); - void emit_array_variable(const gsc::context_ptr& ctx, const gsc::expr_array_ptr& expr); - void emit_field_variable(const gsc::context_ptr& ctx, const gsc::expr_field_ptr& expr); - void emit_local_variable(const gsc::context_ptr& ctx, const gsc::name_ptr& expr); - void emit_clear_local_variable(const gsc::context_ptr& ctx, const gsc::name_ptr& expr); - void emit_create_local_vars(const gsc::context_ptr& ctx); - void emit_remove_local_vars(const gsc::context_ptr& ctx); - void emit_object(const gsc::context_ptr& ctx, const gsc::expr_ptr& expr); - void emit_animtree(const gsc::context_ptr& ctx, const gsc::animtree_ptr& animtree); - void emit_animation(const gsc::context_ptr& ctx, const gsc::animation_ptr& animation); - void emit_istring(const gsc::context_ptr& ctx, const gsc::istring_ptr& str); - void emit_string(const gsc::context_ptr& ctx, const gsc::string_ptr& str); - void emit_color(const gsc::context_ptr& ctx, const gsc::color_ptr& color); - void emit_vector(const gsc::context_ptr& ctx, const gsc::vector_ptr& vec); - void emit_float(const gsc::context_ptr& ctx, const gsc::float_ptr& num); - void emit_integer(const gsc::context_ptr& ctx, const gsc::integer_ptr& num); - void emit_false(const gsc::context_ptr& ctx, const gsc::false_ptr& expr); - void emit_true(const gsc::context_ptr& ctx, const gsc::true_ptr& expr); - void emit_opcode(const gsc::context_ptr& ctx, opcode op); - void emit_opcode(const gsc::context_ptr& ctx, opcode op, const std::string& data); - void emit_opcode(const gsc::context_ptr& ctx, opcode op, const std::vector& data); - void process_thread(const gsc::context_ptr& ctx, const gsc::thread_ptr& thread); - void process_parameters(const gsc::context_ptr& ctx, const gsc::parameters_ptr& params); - void process_stmt(const gsc::context_ptr& ctx, const gsc::stmt_ptr& stmt); - void process_stmt_list(const gsc::context_ptr& ctx, const gsc::stmt_list_ptr& stmt); - void process_expr(const gsc::context_ptr& ctx, const gsc::expr_ptr& expr); - void process_stmt_waittill(const gsc::context_ptr& ctx, const gsc::stmt_waittill_ptr& stmt); - void process_stmt_if(const gsc::context_ptr& ctx, const gsc::stmt_if_ptr& stmt); - void process_stmt_ifelse(const gsc::context_ptr& ctx, const gsc::stmt_ifelse_ptr& stmt); - void process_stmt_while(const gsc::context_ptr& ctx, const gsc::stmt_while_ptr& stmt); - void process_stmt_for(const gsc::context_ptr& ctx, const gsc::stmt_for_ptr& stmt); - void process_stmt_foreach(const gsc::context_ptr& ctx, const gsc::stmt_foreach_ptr& stmt); - void process_stmt_switch(const gsc::context_ptr& ctx, const gsc::stmt_switch_ptr& stmt); - void process_stmt_break(const gsc::context_ptr& ctx, const gsc::stmt_break_ptr& stmt); - void process_stmt_continue(const gsc::context_ptr& ctx, const gsc::stmt_continue_ptr& stmt); - void process_stmt_return(const gsc::context_ptr& ctx, const gsc::stmt_return_ptr& stmt); - void register_variable(const gsc::context_ptr& ctx, const std::string& name); - void initialize_variable(const gsc::context_ptr& ctx, const gsc::name_ptr& name); - void create_variable(const gsc::context_ptr& ctx, const gsc::name_ptr& name); - auto variable_stack_index(const gsc::context_ptr& ctx, const gsc::name_ptr& name) -> std::uint8_t; - auto variable_create_index(const gsc::context_ptr& ctx, const gsc::name_ptr& name) -> std::string; - auto variable_access_index(const gsc::context_ptr& ctx, const gsc::name_ptr& name) -> std::string; - auto variable_initialized(const gsc::context_ptr& ctx, const gsc::name_ptr& name) -> bool; - auto is_include_call(const std::string& name, std::string& file) -> bool; - auto is_local_call(const std::string& name) -> bool; - auto is_builtin_call(const std::string& name) -> bool; - auto is_builtin_func(const std::string& name) -> bool; - auto is_builtin_method(const std::string& name) -> bool; - auto is_constant_condition(const gsc::expr_ptr& expr) -> bool; - auto create_label() -> std::string; - auto insert_label() -> std::string; - void insert_label(const std::string& label); - - static gsc::include_t include_maps_mp_utility_; - static gsc::include_t include_common_scripts_utility_; - static gsc::include_t include_common_scripts_createfx_; - static gsc::include_t include_maps_mp_gametypes_hud_util_; - auto map_known_includes(const std::string& include) -> bool; - - // debug - void print_debug_info(); - void print_opcodes(std::uint32_t index, std::uint32_t size); - void print_function(const gsc::function_ptr& func); - void print_instruction(const gsc::instruction_ptr& inst); - void print_label(const std::string& label); - - gsc::compilation_mode m_mode; -}; - -} // namespace xsk::gsc::iw5 +// Copyright 2021 xensik. All rights reserved. +// +// Use of this source code is governed by a GNU GPLv3 license +// that can be found in the LICENSE file. + +#pragma once + +namespace xsk::gsc::iw5 +{ + +enum class opcode : std::uint8_t; + +class compiler : public gsc::compiler +{ + std::string filename_; + std::vector assembly_; + gsc::function_ptr function_; + std::uint32_t index_; + std::uint32_t label_idx_; + std::uint8_t stack_idx_; + std::vector local_stack_; + std::vector local_functions_; + std::vector includes_; + std::vector animtrees_; + std::unordered_map constants_; + std::function(const std::string&)> callback_readf_; + std::vector break_ctxs_; + std::vector continue_ctxs_; + bool can_break_; + bool can_continue_; + +public: + compiler(gsc::compilation_mode mode) : m_mode(mode) {} + + auto output() -> std::vector; + void compile(const std::string& file, std::vector& data); + void set_readf_callback(std::function(const std::string&)> func); + +private: + auto parse_buffer(const std::string& file, std::vector& data) -> gsc::program_ptr; + auto parse_file(const std::string& file) -> gsc::program_ptr; + void compile_program(const gsc::program_ptr& program); + void emit_include(const gsc::include_ptr& include); + void emit_define(const gsc::define_ptr& define); + void emit_usingtree(const gsc::usingtree_ptr& animtree); + void emit_constant(const gsc::constant_ptr& constant); + void emit_thread(const gsc::thread_ptr& thread); + void emit_parameters(const gsc::context_ptr& ctx, const gsc::parameters_ptr& params); + void emit_stmt(const gsc::context_ptr& ctx, const gsc::stmt_ptr& stmt, bool last); + void emit_stmt_list(const gsc::context_ptr& ctx, const gsc::stmt_list_ptr& stmt, bool last); + void emit_stmt_call(const gsc::context_ptr& ctx, const gsc::stmt_call_ptr& stmt); + void emit_stmt_assign(const gsc::context_ptr& ctx, const gsc::stmt_assign_ptr& stmt); + void emit_stmt_endon(const gsc::context_ptr& ctx, const gsc::stmt_endon_ptr& stmt); + void emit_stmt_notify(const gsc::context_ptr& ctx, const gsc::stmt_notify_ptr& stmt); + void emit_stmt_wait(const gsc::context_ptr& ctx, const gsc::stmt_wait_ptr& stmt); + void emit_stmt_waittill(const gsc::context_ptr& ctx, const gsc::stmt_waittill_ptr& stmt); + void emit_stmt_waittillmatch(const gsc::context_ptr& ctx, const gsc::stmt_waittillmatch_ptr& stmt); + void emit_stmt_waittillframeend(const gsc::context_ptr& ctx, const gsc::stmt_waittillframeend_ptr& stmt); + void emit_stmt_if(const gsc::context_ptr& ctx, const gsc::stmt_if_ptr& stmt, bool last); + void emit_stmt_ifelse(const gsc::context_ptr& ctx, const gsc::stmt_ifelse_ptr& stmt, bool last); + void emit_stmt_while(const gsc::context_ptr& ctx, const gsc::stmt_while_ptr& stmt); + void emit_stmt_for(const gsc::context_ptr& ctx, const gsc::stmt_for_ptr& stmt); + void emit_stmt_foreach(const gsc::context_ptr& ctx, const gsc::stmt_foreach_ptr& stmt); + void emit_stmt_switch(const gsc::context_ptr& ctx, const gsc::stmt_switch_ptr& stmt); + void emit_stmt_case(const gsc::context_ptr& ctx, const gsc::stmt_case_ptr& stmt); + void emit_stmt_default(const gsc::context_ptr& ctx, const gsc::stmt_default_ptr& stmt); + void emit_stmt_break(const gsc::context_ptr& ctx, const gsc::stmt_break_ptr& stmt); + void emit_stmt_continue(const gsc::context_ptr& ctx, const gsc::stmt_continue_ptr& stmt); + void emit_stmt_return(const gsc::context_ptr& ctx, const gsc::stmt_return_ptr& stmt); + void emit_expr(const gsc::context_ptr& ctx, const gsc::expr_ptr& expr); + void emit_expr_assign(const gsc::context_ptr& ctx, const gsc::expr_assign_ptr& expr); + void emit_expr_ternary(const gsc::context_ptr& ctx, const gsc::expr_ternary_ptr& expr); + void emit_expr_binary(const gsc::context_ptr& ctx, const gsc::expr_binary_ptr& expr); + void emit_expr_and(const gsc::context_ptr& ctx, const gsc::expr_and_ptr& expr); + void emit_expr_or(const gsc::context_ptr& ctx, const gsc::expr_or_ptr& expr); + void emit_expr_complement(const gsc::context_ptr& ctx, const gsc::expr_complement_ptr& expr); + void emit_expr_not(const gsc::context_ptr& ctx, const gsc::expr_not_ptr& expr); + void emit_expr_call(const gsc::context_ptr& ctx, const gsc::expr_call_ptr& expr); + void emit_expr_call_pointer(const gsc::context_ptr& ctx, const gsc::expr_call_ptr& expr); + void emit_expr_call_pointer_type(const gsc::context_ptr& ctx, int args, bool builtin, bool method, bool thread, bool child); + void emit_expr_call_function(const gsc::context_ptr& ctx, const gsc::expr_call_ptr& expr); + void emit_expr_call_function_builtin(const gsc::context_ptr& ctx, const std::string& func, int args, bool method); + void emit_expr_call_function_local(const gsc::context_ptr& ctx, const std::string& func, int args, bool method, bool thread, bool child); + void emit_expr_call_function_far(const gsc::context_ptr& ctx, const std::string& file, const std::string& func, int args, bool method, bool thread, bool child); + void emit_expr_arguments(const gsc::context_ptr& ctx, const gsc::expr_arguments_ptr& arg_list); + void emit_expr_function(const gsc::context_ptr& ctx, const gsc::expr_function_ptr& node); + void emit_expr_clear_variable(const gsc::context_ptr& ctx, const gsc::expr_ptr& lvalue); + void emit_expr_add_array(const gsc::context_ptr& ctx, const gsc::expr_add_array_ptr& expr); + void emit_expr_size(const gsc::context_ptr& ctx, const gsc::expr_size_ptr& expr); + void emit_variable_ref(const gsc::context_ptr& ctx, const gsc::expr_ptr& expr, bool set); + void emit_array_variable_ref(const gsc::context_ptr& ctx, const gsc::expr_array_ptr& expr, bool set); + void emit_field_variable_ref(const gsc::context_ptr& ctx, const gsc::expr_field_ptr& expr, bool set); + void emit_local_variable_ref(const gsc::context_ptr& ctx, const gsc::name_ptr& expr, bool set); + void emit_variable(const gsc::context_ptr& ctx, const gsc::expr_ptr& expr); + void emit_array_variable(const gsc::context_ptr& ctx, const gsc::expr_array_ptr& expr); + void emit_field_variable(const gsc::context_ptr& ctx, const gsc::expr_field_ptr& expr); + void emit_local_variable(const gsc::context_ptr& ctx, const gsc::name_ptr& expr); + void emit_clear_local_variable(const gsc::context_ptr& ctx, const gsc::name_ptr& expr); + void emit_create_local_vars(const gsc::context_ptr& ctx); + void emit_remove_local_vars(const gsc::context_ptr& ctx); + void emit_object(const gsc::context_ptr& ctx, const gsc::expr_ptr& expr); + void emit_animtree(const gsc::context_ptr& ctx, const gsc::animtree_ptr& animtree); + void emit_animation(const gsc::context_ptr& ctx, const gsc::animation_ptr& animation); + void emit_istring(const gsc::context_ptr& ctx, const gsc::istring_ptr& str); + void emit_string(const gsc::context_ptr& ctx, const gsc::string_ptr& str); + void emit_color(const gsc::context_ptr& ctx, const gsc::color_ptr& color); + void emit_vector(const gsc::context_ptr& ctx, const gsc::vector_ptr& vec); + void emit_float(const gsc::context_ptr& ctx, const gsc::float_ptr& num); + void emit_integer(const gsc::context_ptr& ctx, const gsc::integer_ptr& num); + void emit_false(const gsc::context_ptr& ctx, const gsc::false_ptr& expr); + void emit_true(const gsc::context_ptr& ctx, const gsc::true_ptr& expr); + void emit_opcode(const gsc::context_ptr& ctx, opcode op); + void emit_opcode(const gsc::context_ptr& ctx, opcode op, const std::string& data); + void emit_opcode(const gsc::context_ptr& ctx, opcode op, const std::vector& data); + void process_thread(const gsc::context_ptr& ctx, const gsc::thread_ptr& thread); + void process_parameters(const gsc::context_ptr& ctx, const gsc::parameters_ptr& params); + void process_stmt(const gsc::context_ptr& ctx, const gsc::stmt_ptr& stmt); + void process_stmt_list(const gsc::context_ptr& ctx, const gsc::stmt_list_ptr& stmt); + void process_expr(const gsc::context_ptr& ctx, const gsc::expr_ptr& expr); + void process_stmt_waittill(const gsc::context_ptr& ctx, const gsc::stmt_waittill_ptr& stmt); + void process_stmt_if(const gsc::context_ptr& ctx, const gsc::stmt_if_ptr& stmt); + void process_stmt_ifelse(const gsc::context_ptr& ctx, const gsc::stmt_ifelse_ptr& stmt); + void process_stmt_while(const gsc::context_ptr& ctx, const gsc::stmt_while_ptr& stmt); + void process_stmt_for(const gsc::context_ptr& ctx, const gsc::stmt_for_ptr& stmt); + void process_stmt_foreach(const gsc::context_ptr& ctx, const gsc::stmt_foreach_ptr& stmt); + void process_stmt_switch(const gsc::context_ptr& ctx, const gsc::stmt_switch_ptr& stmt); + void process_stmt_break(const gsc::context_ptr& ctx, const gsc::stmt_break_ptr& stmt); + void process_stmt_continue(const gsc::context_ptr& ctx, const gsc::stmt_continue_ptr& stmt); + void process_stmt_return(const gsc::context_ptr& ctx, const gsc::stmt_return_ptr& stmt); + void register_variable(const gsc::context_ptr& ctx, const std::string& name); + void initialize_variable(const gsc::context_ptr& ctx, const gsc::name_ptr& name); + void create_variable(const gsc::context_ptr& ctx, const gsc::name_ptr& name); + auto variable_stack_index(const gsc::context_ptr& ctx, const gsc::name_ptr& name) -> std::uint8_t; + auto variable_create_index(const gsc::context_ptr& ctx, const gsc::name_ptr& name) -> std::string; + auto variable_access_index(const gsc::context_ptr& ctx, const gsc::name_ptr& name) -> std::string; + auto variable_initialized(const gsc::context_ptr& ctx, const gsc::name_ptr& name) -> bool; + auto is_include_call(const std::string& name, std::string& file) -> bool; + auto is_local_call(const std::string& name) -> bool; + auto is_builtin_call(const std::string& name) -> bool; + auto is_builtin_func(const std::string& name) -> bool; + auto is_builtin_method(const std::string& name) -> bool; + auto is_constant_condition(const gsc::expr_ptr& expr) -> bool; + auto create_label() -> std::string; + auto insert_label() -> std::string; + void insert_label(const std::string& label); + + static gsc::include_t include_maps_mp_utility_; + static gsc::include_t include_common_scripts_utility_; + static gsc::include_t include_common_scripts_createfx_; + static gsc::include_t include_maps_mp_gametypes_hud_util_; + auto map_known_includes(const std::string& include) -> bool; + + // debug + void print_debug_info(); + void print_opcodes(std::uint32_t index, std::uint32_t size); + void print_function(const gsc::function_ptr& func); + void print_instruction(const gsc::instruction_ptr& inst); + void print_label(const std::string& label); + + gsc::compilation_mode m_mode; +}; + +} // namespace xsk::gsc::iw5 diff --git a/src/tool/xsk/main.cpp b/src/tool/xsk/main.cpp index 27453362..167d7495 100644 --- a/src/tool/xsk/main.cpp +++ b/src/tool/xsk/main.cpp @@ -1,628 +1,628 @@ -// Copyright 2021 xensik. All rights reserved. -// -// Use of this source code is governed by a GNU GPLv3 license -// that can be found in the LICENSE file. - -#include "stdafx.hpp" - -#include "iw5/xsk/iw5.hpp" -#include "iw6/xsk/iw6.hpp" -#include "iw7/xsk/iw7.hpp" -#include "iw8/xsk/iw8.hpp" -#include "s1/xsk/s1.hpp" -#include "s2/xsk/s2.hpp" -#include "s4/xsk/s4.hpp" -#include "h1/xsk/h1.hpp" -#include "h2/xsk/h2.hpp" - -namespace xsk::gsc -{ - -enum class mode { __, ASM, DISASM, COMP, DECOMP }; -enum class game { __, IW5, IW6, IW7, IW8, S1, S2, S4, H1, H2 }; - -std::map modes = -{ - { "-asm", mode::ASM }, - { "-disasm", mode::DISASM }, - { "-comp", mode::COMP }, - { "-decomp", mode::DECOMP }, -}; - -std::map games = -{ - { "-iw5", game::IW5 }, - { "-iw6", game::IW6 }, - { "-iw7", game::IW7 }, - { "-iw8", game::IW8 }, - { "-s1", game::S1 }, - { "-s2", game::S2 }, - { "-s4", game::S4 }, - { "-h1", game::H1 }, - { "-h2", game::H2 }, -}; - -auto overwrite_prompt(const std::string& file) -> bool -{ - auto overwrite = true; - - if (utils::file::exists(file)) - { - do - { - std::cout << "File \"" << file << "\" already exists, overwrite? [Y/n]: "; - auto result = std::getchar(); - - if (result == '\n' || result == 'Y' || result == 'y') - { - break; - } - else if (result == 'N' || result == 'n') - { - overwrite = false; - break; - } - } while (true); - } - - return overwrite; -} - -auto choose_resolver_file_name(uint32_t id, game& game) -> std::string -{ - switch (game) - { - case game::IW5: return iw5::resolver::file_name(static_cast(id)); - case game::IW6: return iw6::resolver::file_name(static_cast(id)); - case game::IW7: return iw7::resolver::file_name(id); - case game::IW8: return iw8::resolver::file_name(id); - case game::S1: return s1::resolver::file_name(static_cast(id)); - case game::S2: return s2::resolver::file_name(static_cast(id)); - case game::S4: return s4::resolver::file_name(id); - case game::H1: return h1::resolver::file_name(static_cast(id)); - case game::H2: return h2::resolver::file_name(static_cast(id)); - default: return ""; - } -} - -void assemble_file(gsc::assembler& assembler, std::string file, bool zonetool) -{ - try - { - const auto ext = std::string(".gscasm"); - const auto extpos = file.find(ext); - - if (extpos != std::string::npos) - { - file.replace(extpos, ext.length(), ""); - } - - auto data = utils::file::read(file + ext); - - assembler.assemble(file, data); - - if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin"))) - { - if(zonetool) - { - utils::file::save(file + ".cgsc", assembler.output_script()); - utils::file::save(file + ".cgsc.stack", assembler.output_stack()); - std::cout << "assembled " << file << ".cgsc\n"; - } - else - { - gsc::asset script; - - auto uncompressed = assembler.output_stack(); - auto compressed = utils::zlib::compress(uncompressed); - - script.name = file; - script.bytecode = assembler.output_script(); - script.buffer = std::move(compressed); - script.len = uncompressed.size(); - script.compressedLen = script.buffer.size(); - script.bytecodeLen = script.bytecode.size(); - - auto output = script.serialize(); - utils::file::save(file + ".gscbin", output); - std::cout << "assembled " << file << ".gscbin\n"; - } - } - } - catch(const std::exception& e) - { - std::cerr << e.what() << '\n'; - } -} - -void disassemble_file(gsc::disassembler& disassembler, std::string file, game& game, bool zonetool) -{ - try - { - if(zonetool) - { - if (file.find(".stack") != std::string::npos) - { - std::cerr << "Cannot disassemble stack files\n"; - return; - } - - const auto ext = std::string(".cgsc"); - const auto extpos = file.find(ext); - - if (extpos != std::string::npos) - { - file.replace(extpos, ext.length(), ""); - } - - auto script = utils::file::read(file + ".cgsc"); - auto stack = utils::file::read(file + ".cgsc.stack"); - - disassembler.disassemble(file, script, stack); - } - else - { - const auto ext = std::string(".gscbin"); - const auto extpos = file.find(ext); - - if (extpos != std::string::npos) - { - file.replace(extpos, ext.length(), ""); - } - - auto data = utils::file::read(file + ext); - - gsc::asset script; - - script.deserialize(data); - - auto stack = utils::zlib::decompress(script.buffer, script.len); - - disassembler.disassemble(file, script.bytecode, stack); - } - - auto scriptid = std::filesystem::path(file).filename().string(); - - if (!isdigit(scriptid.data()[0])) - { - utils::file::save(file + ".gscasm", disassembler.output_data()); - std::cout << "disassembled " << file << ".gscasm\n"; - } - else - { - auto filename = choose_resolver_file_name(std::atoi(scriptid.data()), game); - auto count = file.find(scriptid); - - if (count != std::string::npos) - { - if (!filename.empty()) - { - file.erase(count, scriptid.length()); - } - } - - utils::file::save(file + filename + ".gscasm", disassembler.output_data()); - std::cout << "disassembled " << file << filename << ".gscasm\n"; - } - } - catch(const std::exception& e) - { - std::cerr << e.what() << '\n'; - } -} - -void compile_file(gsc::assembler& assembler, gsc::compiler& compiler, std::string file, bool zonetool) -{ - try - { - const auto ext = std::string(".gsc"); - const auto extpos = file.find(ext); - - if (extpos != std::string::npos) - { - file.replace(extpos, ext.length(), ""); - } - - auto data = utils::file::read(file + ext); - compiler.set_readf_callback(utils::file::read); - compiler.compile(file, data); - - auto assembly = compiler.output(); - - assembler.assemble(file, assembly); - - if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin"))) - { - if(zonetool) - { - utils::file::save(file + ".cgsc", assembler.output_script()); - utils::file::save(file + ".cgsc.stack", assembler.output_stack()); - std::cout << "compiled " << file << ".cgsc\n"; - } - else - { - gsc::asset script; - - auto uncompressed = assembler.output_stack(); - auto compressed = utils::zlib::compress(uncompressed); - - script.name = file; - script.bytecode = assembler.output_script(); - script.buffer = std::move(compressed); - script.len = uncompressed.size(); - script.compressedLen = script.buffer.size(); - script.bytecodeLen = script.bytecode.size(); - - auto output = script.serialize(); - utils::file::save(file + ".gscbin", output); - std::cout << "compiled " << file << ".gscbin\n"; - } - } - } - catch(const std::exception& e) - { - std::cerr << e.what() << '\n'; - } -} - -void decompile_file(gsc::disassembler& disassembler, gsc::decompiler& decompiler, std::string file, game& game, bool zonetool) -{ - try - { - if(zonetool) - { - if (file.find(".stack") != std::string::npos) - { - std::cerr << "Cannot disassemble stack files\n"; - return; - } - - const auto ext = std::string(".cgsc"); - const auto extpos = file.find(ext); - - if (extpos != std::string::npos) - { - file.replace(extpos, ext.length(), ""); - } - - auto script = utils::file::read(file + ".cgsc"); - auto stack = utils::file::read(file + ".cgsc.stack"); - - disassembler.disassemble(file, script, stack); - } - else - { - const auto ext = std::string(".gscbin"); - const auto extpos = file.find(ext); - - if (extpos != std::string::npos) - { - file.replace(extpos, ext.length(), ""); - } - - auto data = utils::file::read(file + ext); - - gsc::asset script; - - script.deserialize(data); - - auto stack = utils::zlib::decompress(script.buffer, script.len); - - disassembler.disassemble(file, script.bytecode, stack); - } - - auto output = disassembler.output(); - - decompiler.decompile(file, output); - - auto scriptid = std::filesystem::path(file).filename().string(); - - if (!isdigit(scriptid.data()[0])) - { - utils::file::save(file + ".gsc", decompiler.output()); - std::cout << "decompiled " << file << ".gsc\n"; - } - else - { - auto filename = choose_resolver_file_name(std::atoi(scriptid.data()), game); - auto count = file.find(scriptid); - - if (count != std::string::npos) - { - if (!filename.empty()) - { - file.erase(count, scriptid.length()); - } - } - - utils::file::save(file + filename + ".gsc", decompiler.output()); - std::cout << "decompiled " << file << filename << ".gsc\n"; - } - } - catch(const std::exception& e) - { - std::cerr << e.what() << '\n'; - } -} - -int parse_flags(int argc, char** argv, game& game, mode& mode, bool& zonetool) -{ - if (argc != 4) return 1; - - std::string arg = utils::string::to_lower(argv[1]); - - const auto it1 = games.find(arg); - - if (it1 != games.end()) - { - game = it1->second; - } - else - { - std::cout << "Unknown game '" << argv[1] << "'.\n\n"; - return 1; - } - - arg = utils::string::to_lower(argv[2]); - - if(arg.at(1) == 'z') - { - arg.erase(arg.begin() + 1); - zonetool = true; - } - - const auto it2 = modes.find(arg); - - if (it2 != modes.end()) - { - mode = it2->second; - } - else - { - std::cout << "Unknown mode '" << argv[2] << "'.\n\n"; - return 1; - } - - return 0; -} - -void print_usage() -{ - std::cout << "usage: gsc-tool.exe \n"; - std::cout << " * games: -iw5, -iw6, -iw7, -iw8, -s1, -s2, -s4, -h1, -h2\n"; - std::cout << " * modes: -asm, -disasm, -comp, -decomp\n"; -} - -std::uint32_t main(std::uint32_t argc, char** argv) -{ - std::string file = utils::string::fordslash(argv[argc - 1]); - mode mode = mode::__; - game game = game::__; - bool zonetool = false; - - if (parse_flags(argc, argv, game, mode, zonetool)) - { - print_usage(); - return 0; - } - - if (mode == mode::ASM) - { - if( game == game::IW5) - { - gsc::iw5::assembler assembler; - assemble_file(assembler, file, zonetool); - } - else if (game == game::IW6) - { - iw6::assembler assembler; - assemble_file(assembler, file, zonetool); - } - else if (game == game::IW7) - { - iw7::assembler assembler; - assemble_file(assembler, file, zonetool); - } - else if (game == game::IW8) - { - iw8::assembler assembler; - assemble_file(assembler, file, zonetool); - } - else if (game == game::S1) - { - s1::assembler assembler; - assemble_file(assembler, file, zonetool); - } - else if (game == game::S2) - { - s2::assembler assembler; - assemble_file(assembler, file, zonetool); - } - else if (game == game::S4) - { - s4::assembler assembler; - assemble_file(assembler, file, zonetool); - } - else if (game == game::H1) - { - h1::assembler assembler; - assemble_file(assembler, file, zonetool); - } - else if (game == game::H2) - { - h2::assembler assembler; - assemble_file(assembler, file, zonetool); - } - } - else if (mode == mode::DISASM) - { - if (game == game::IW5) - { - gsc::iw5::disassembler disassembler; - disassemble_file(disassembler, file, game, zonetool); - } - else if (game == game::IW6) - { - iw6::disassembler disassembler; - disassemble_file(disassembler, file, game, zonetool); - } - else if (game == game::IW7) - { - iw7::disassembler disassembler; - disassemble_file(disassembler, file, game, zonetool); - } - else if (game == game::IW8) - { - iw8::disassembler disassembler; - disassemble_file(disassembler, file, game, zonetool); - } - else if (game == game::S1) - { - s1::disassembler disassembler; - disassemble_file(disassembler, file, game, zonetool); - } - else if (game == game::S2) - { - s2::disassembler disassembler; - disassemble_file(disassembler, file, game, zonetool); - } - else if (game == game::S4) - { - s4::disassembler disassembler; - disassemble_file(disassembler, file, game, zonetool); - } - else if (game == game::H1) - { - h1::disassembler disassembler; - disassemble_file(disassembler, file, game, zonetool); - } - else if (game == game::H2) - { - h2::disassembler disassembler; - disassemble_file(disassembler, file, game, zonetool); - } - } - else if (mode == mode::COMP) - { - if (game == game::IW5) - { - gsc::iw5::assembler assembler; - gsc::iw5::compiler compiler(gsc::compilation_mode::release); - compile_file(assembler, compiler, file ,zonetool); - } - else if (game == game::IW6) - { - iw6::assembler assembler; - iw6::compiler compiler; - compile_file(assembler, compiler, file ,zonetool); - } - else if (game == game::IW7) - { - iw7::assembler assembler; - iw7::compiler compiler; - compile_file(assembler, compiler, file ,zonetool); - } - else if (game == game::IW8) - { - iw8::assembler assembler; - iw8::compiler compiler; - compile_file(assembler, compiler, file ,zonetool); - } - else if (game == game::S1) - { - s1::assembler assembler; - s1::compiler compiler; - compile_file(assembler, compiler, file ,zonetool); - } - else if (game == game::S2) - { - s2::assembler assembler; - s2::compiler compiler; - compile_file(assembler, compiler, file ,zonetool); - } - else if (game == game::S4) - { - s4::assembler assembler; - s4::compiler compiler; - compile_file(assembler, compiler, file ,zonetool); - } - else if (game == game::H1) - { - h1::assembler assembler; - h1::compiler compiler; - compile_file(assembler, compiler, file ,zonetool); - } - else if (game == game::H2) - { - h2::assembler assembler; - h2::compiler compiler; - compile_file(assembler, compiler, file ,zonetool); - } - } - else if (mode == mode::DECOMP) - { - if (game == game::IW5) - { - iw5::disassembler disassembler; - iw5::decompiler decompiler; - decompile_file(disassembler, decompiler, file, game, zonetool); - } - else if (game == game::IW6) - { - iw6::disassembler disassembler; - iw6::decompiler decompiler; - decompile_file(disassembler, decompiler, file, game, zonetool); - } - else if (game == game::IW7) - { - iw7::disassembler disassembler; - iw7::decompiler decompiler; - decompile_file(disassembler, decompiler, file, game, zonetool); - } - else if (game == game::IW8) - { - iw8::disassembler disassembler; - iw8::decompiler decompiler; - decompile_file(disassembler, decompiler, file, game, zonetool); - } - else if (game == game::S1) - { - s1::disassembler disassembler; - s1::decompiler decompiler; - decompile_file(disassembler, decompiler, file, game, zonetool); - } - else if (game == game::S2) - { - s2::disassembler disassembler; - s2::decompiler decompiler; - decompile_file(disassembler, decompiler, file, game, zonetool); - } - else if (game == game::S4) - { - s4::disassembler disassembler; - s4::decompiler decompiler; - decompile_file(disassembler, decompiler, file, game, zonetool); - } - else if (game == game::H1) - { - h1::disassembler disassembler; - h1::decompiler decompiler; - decompile_file(disassembler, decompiler, file, game, zonetool); - } - else if (game == game::H2) - { - h2::disassembler disassembler; - h2::decompiler decompiler; - decompile_file(disassembler, decompiler, file, game, zonetool); - } - } - - return 0; -} - -} // namespace xsk::gsc - -int main(int argc, char** argv) -{ - xsk::gsc::main(argc, argv); -} +// Copyright 2021 xensik. All rights reserved. +// +// Use of this source code is governed by a GNU GPLv3 license +// that can be found in the LICENSE file. + +#include "stdafx.hpp" + +#include "iw5/xsk/iw5.hpp" +#include "iw6/xsk/iw6.hpp" +#include "iw7/xsk/iw7.hpp" +#include "iw8/xsk/iw8.hpp" +#include "s1/xsk/s1.hpp" +#include "s2/xsk/s2.hpp" +#include "s4/xsk/s4.hpp" +#include "h1/xsk/h1.hpp" +#include "h2/xsk/h2.hpp" + +namespace xsk::gsc +{ + +enum class mode { __, ASM, DISASM, COMP, DECOMP }; +enum class game { __, IW5, IW6, IW7, IW8, S1, S2, S4, H1, H2 }; + +std::map modes = +{ + { "-asm", mode::ASM }, + { "-disasm", mode::DISASM }, + { "-comp", mode::COMP }, + { "-decomp", mode::DECOMP }, +}; + +std::map games = +{ + { "-iw5", game::IW5 }, + { "-iw6", game::IW6 }, + { "-iw7", game::IW7 }, + { "-iw8", game::IW8 }, + { "-s1", game::S1 }, + { "-s2", game::S2 }, + { "-s4", game::S4 }, + { "-h1", game::H1 }, + { "-h2", game::H2 }, +}; + +auto overwrite_prompt(const std::string& file) -> bool +{ + auto overwrite = true; + + if (utils::file::exists(file)) + { + do + { + std::cout << "File \"" << file << "\" already exists, overwrite? [Y/n]: "; + auto result = std::getchar(); + + if (result == '\n' || result == 'Y' || result == 'y') + { + break; + } + else if (result == 'N' || result == 'n') + { + overwrite = false; + break; + } + } while (true); + } + + return overwrite; +} + +auto choose_resolver_file_name(uint32_t id, game& game) -> std::string +{ + switch (game) + { + case game::IW5: return iw5::resolver::file_name(static_cast(id)); + case game::IW6: return iw6::resolver::file_name(static_cast(id)); + case game::IW7: return iw7::resolver::file_name(id); + case game::IW8: return iw8::resolver::file_name(id); + case game::S1: return s1::resolver::file_name(static_cast(id)); + case game::S2: return s2::resolver::file_name(static_cast(id)); + case game::S4: return s4::resolver::file_name(id); + case game::H1: return h1::resolver::file_name(static_cast(id)); + case game::H2: return h2::resolver::file_name(static_cast(id)); + default: return ""; + } +} + +void assemble_file(gsc::assembler& assembler, std::string file, bool zonetool) +{ + try + { + const auto ext = std::string(".gscasm"); + const auto extpos = file.find(ext); + + if (extpos != std::string::npos) + { + file.replace(extpos, ext.length(), ""); + } + + auto data = utils::file::read(file + ext); + + assembler.assemble(file, data); + + if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin"))) + { + if(zonetool) + { + utils::file::save(file + ".cgsc", assembler.output_script()); + utils::file::save(file + ".cgsc.stack", assembler.output_stack()); + std::cout << "assembled " << file << ".cgsc\n"; + } + else + { + gsc::asset script; + + auto uncompressed = assembler.output_stack(); + auto compressed = utils::zlib::compress(uncompressed); + + script.name = file; + script.bytecode = assembler.output_script(); + script.buffer = std::move(compressed); + script.len = uncompressed.size(); + script.compressedLen = script.buffer.size(); + script.bytecodeLen = script.bytecode.size(); + + auto output = script.serialize(); + utils::file::save(file + ".gscbin", output); + std::cout << "assembled " << file << ".gscbin\n"; + } + } + } + catch(const std::exception& e) + { + std::cerr << e.what() << '\n'; + } +} + +void disassemble_file(gsc::disassembler& disassembler, std::string file, game& game, bool zonetool) +{ + try + { + if(zonetool) + { + if (file.find(".stack") != std::string::npos) + { + std::cerr << "Cannot disassemble stack files\n"; + return; + } + + const auto ext = std::string(".cgsc"); + const auto extpos = file.find(ext); + + if (extpos != std::string::npos) + { + file.replace(extpos, ext.length(), ""); + } + + auto script = utils::file::read(file + ".cgsc"); + auto stack = utils::file::read(file + ".cgsc.stack"); + + disassembler.disassemble(file, script, stack); + } + else + { + const auto ext = std::string(".gscbin"); + const auto extpos = file.find(ext); + + if (extpos != std::string::npos) + { + file.replace(extpos, ext.length(), ""); + } + + auto data = utils::file::read(file + ext); + + gsc::asset script; + + script.deserialize(data); + + auto stack = utils::zlib::decompress(script.buffer, script.len); + + disassembler.disassemble(file, script.bytecode, stack); + } + + auto scriptid = std::filesystem::path(file).filename().string(); + + if (!isdigit(scriptid.data()[0])) + { + utils::file::save(file + ".gscasm", disassembler.output_data()); + std::cout << "disassembled " << file << ".gscasm\n"; + } + else + { + auto filename = choose_resolver_file_name(std::atoi(scriptid.data()), game); + auto count = file.find(scriptid); + + if (count != std::string::npos) + { + if (!filename.empty()) + { + file.erase(count, scriptid.length()); + } + } + + utils::file::save(file + filename + ".gscasm", disassembler.output_data()); + std::cout << "disassembled " << file << filename << ".gscasm\n"; + } + } + catch(const std::exception& e) + { + std::cerr << e.what() << '\n'; + } +} + +void compile_file(gsc::assembler& assembler, gsc::compiler& compiler, std::string file, bool zonetool) +{ + try + { + const auto ext = std::string(".gsc"); + const auto extpos = file.find(ext); + + if (extpos != std::string::npos) + { + file.replace(extpos, ext.length(), ""); + } + + auto data = utils::file::read(file + ext); + compiler.set_readf_callback(utils::file::read); + compiler.compile(file, data); + + auto assembly = compiler.output(); + + assembler.assemble(file, assembly); + + if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin"))) + { + if(zonetool) + { + utils::file::save(file + ".cgsc", assembler.output_script()); + utils::file::save(file + ".cgsc.stack", assembler.output_stack()); + std::cout << "compiled " << file << ".cgsc\n"; + } + else + { + gsc::asset script; + + auto uncompressed = assembler.output_stack(); + auto compressed = utils::zlib::compress(uncompressed); + + script.name = file; + script.bytecode = assembler.output_script(); + script.buffer = std::move(compressed); + script.len = uncompressed.size(); + script.compressedLen = script.buffer.size(); + script.bytecodeLen = script.bytecode.size(); + + auto output = script.serialize(); + utils::file::save(file + ".gscbin", output); + std::cout << "compiled " << file << ".gscbin\n"; + } + } + } + catch(const std::exception& e) + { + std::cerr << e.what() << '\n'; + } +} + +void decompile_file(gsc::disassembler& disassembler, gsc::decompiler& decompiler, std::string file, game& game, bool zonetool) +{ + try + { + if(zonetool) + { + if (file.find(".stack") != std::string::npos) + { + std::cerr << "Cannot disassemble stack files\n"; + return; + } + + const auto ext = std::string(".cgsc"); + const auto extpos = file.find(ext); + + if (extpos != std::string::npos) + { + file.replace(extpos, ext.length(), ""); + } + + auto script = utils::file::read(file + ".cgsc"); + auto stack = utils::file::read(file + ".cgsc.stack"); + + disassembler.disassemble(file, script, stack); + } + else + { + const auto ext = std::string(".gscbin"); + const auto extpos = file.find(ext); + + if (extpos != std::string::npos) + { + file.replace(extpos, ext.length(), ""); + } + + auto data = utils::file::read(file + ext); + + gsc::asset script; + + script.deserialize(data); + + auto stack = utils::zlib::decompress(script.buffer, script.len); + + disassembler.disassemble(file, script.bytecode, stack); + } + + auto output = disassembler.output(); + + decompiler.decompile(file, output); + + auto scriptid = std::filesystem::path(file).filename().string(); + + if (!isdigit(scriptid.data()[0])) + { + utils::file::save(file + ".gsc", decompiler.output()); + std::cout << "decompiled " << file << ".gsc\n"; + } + else + { + auto filename = choose_resolver_file_name(std::atoi(scriptid.data()), game); + auto count = file.find(scriptid); + + if (count != std::string::npos) + { + if (!filename.empty()) + { + file.erase(count, scriptid.length()); + } + } + + utils::file::save(file + filename + ".gsc", decompiler.output()); + std::cout << "decompiled " << file << filename << ".gsc\n"; + } + } + catch(const std::exception& e) + { + std::cerr << e.what() << '\n'; + } +} + +int parse_flags(int argc, char** argv, game& game, mode& mode, bool& zonetool) +{ + if (argc != 4) return 1; + + std::string arg = utils::string::to_lower(argv[1]); + + const auto it1 = games.find(arg); + + if (it1 != games.end()) + { + game = it1->second; + } + else + { + std::cout << "Unknown game '" << argv[1] << "'.\n\n"; + return 1; + } + + arg = utils::string::to_lower(argv[2]); + + if(arg.at(1) == 'z') + { + arg.erase(arg.begin() + 1); + zonetool = true; + } + + const auto it2 = modes.find(arg); + + if (it2 != modes.end()) + { + mode = it2->second; + } + else + { + std::cout << "Unknown mode '" << argv[2] << "'.\n\n"; + return 1; + } + + return 0; +} + +void print_usage() +{ + std::cout << "usage: gsc-tool.exe \n"; + std::cout << " * games: -iw5, -iw6, -iw7, -iw8, -s1, -s2, -s4, -h1, -h2\n"; + std::cout << " * modes: -asm, -disasm, -comp, -decomp\n"; +} + +std::uint32_t main(std::uint32_t argc, char** argv) +{ + std::string file = utils::string::fordslash(argv[argc - 1]); + mode mode = mode::__; + game game = game::__; + bool zonetool = false; + + if (parse_flags(argc, argv, game, mode, zonetool)) + { + print_usage(); + return 0; + } + + if (mode == mode::ASM) + { + if( game == game::IW5) + { + gsc::iw5::assembler assembler; + assemble_file(assembler, file, zonetool); + } + else if (game == game::IW6) + { + iw6::assembler assembler; + assemble_file(assembler, file, zonetool); + } + else if (game == game::IW7) + { + iw7::assembler assembler; + assemble_file(assembler, file, zonetool); + } + else if (game == game::IW8) + { + iw8::assembler assembler; + assemble_file(assembler, file, zonetool); + } + else if (game == game::S1) + { + s1::assembler assembler; + assemble_file(assembler, file, zonetool); + } + else if (game == game::S2) + { + s2::assembler assembler; + assemble_file(assembler, file, zonetool); + } + else if (game == game::S4) + { + s4::assembler assembler; + assemble_file(assembler, file, zonetool); + } + else if (game == game::H1) + { + h1::assembler assembler; + assemble_file(assembler, file, zonetool); + } + else if (game == game::H2) + { + h2::assembler assembler; + assemble_file(assembler, file, zonetool); + } + } + else if (mode == mode::DISASM) + { + if (game == game::IW5) + { + gsc::iw5::disassembler disassembler; + disassemble_file(disassembler, file, game, zonetool); + } + else if (game == game::IW6) + { + iw6::disassembler disassembler; + disassemble_file(disassembler, file, game, zonetool); + } + else if (game == game::IW7) + { + iw7::disassembler disassembler; + disassemble_file(disassembler, file, game, zonetool); + } + else if (game == game::IW8) + { + iw8::disassembler disassembler; + disassemble_file(disassembler, file, game, zonetool); + } + else if (game == game::S1) + { + s1::disassembler disassembler; + disassemble_file(disassembler, file, game, zonetool); + } + else if (game == game::S2) + { + s2::disassembler disassembler; + disassemble_file(disassembler, file, game, zonetool); + } + else if (game == game::S4) + { + s4::disassembler disassembler; + disassemble_file(disassembler, file, game, zonetool); + } + else if (game == game::H1) + { + h1::disassembler disassembler; + disassemble_file(disassembler, file, game, zonetool); + } + else if (game == game::H2) + { + h2::disassembler disassembler; + disassemble_file(disassembler, file, game, zonetool); + } + } + else if (mode == mode::COMP) + { + if (game == game::IW5) + { + gsc::iw5::assembler assembler; + gsc::iw5::compiler compiler(gsc::compilation_mode::release); + compile_file(assembler, compiler, file ,zonetool); + } + else if (game == game::IW6) + { + iw6::assembler assembler; + iw6::compiler compiler; + compile_file(assembler, compiler, file ,zonetool); + } + else if (game == game::IW7) + { + iw7::assembler assembler; + iw7::compiler compiler; + compile_file(assembler, compiler, file ,zonetool); + } + else if (game == game::IW8) + { + iw8::assembler assembler; + iw8::compiler compiler; + compile_file(assembler, compiler, file ,zonetool); + } + else if (game == game::S1) + { + s1::assembler assembler; + s1::compiler compiler; + compile_file(assembler, compiler, file ,zonetool); + } + else if (game == game::S2) + { + s2::assembler assembler; + s2::compiler compiler; + compile_file(assembler, compiler, file ,zonetool); + } + else if (game == game::S4) + { + s4::assembler assembler; + s4::compiler compiler; + compile_file(assembler, compiler, file ,zonetool); + } + else if (game == game::H1) + { + h1::assembler assembler; + h1::compiler compiler; + compile_file(assembler, compiler, file ,zonetool); + } + else if (game == game::H2) + { + h2::assembler assembler; + h2::compiler compiler; + compile_file(assembler, compiler, file ,zonetool); + } + } + else if (mode == mode::DECOMP) + { + if (game == game::IW5) + { + iw5::disassembler disassembler; + iw5::decompiler decompiler; + decompile_file(disassembler, decompiler, file, game, zonetool); + } + else if (game == game::IW6) + { + iw6::disassembler disassembler; + iw6::decompiler decompiler; + decompile_file(disassembler, decompiler, file, game, zonetool); + } + else if (game == game::IW7) + { + iw7::disassembler disassembler; + iw7::decompiler decompiler; + decompile_file(disassembler, decompiler, file, game, zonetool); + } + else if (game == game::IW8) + { + iw8::disassembler disassembler; + iw8::decompiler decompiler; + decompile_file(disassembler, decompiler, file, game, zonetool); + } + else if (game == game::S1) + { + s1::disassembler disassembler; + s1::decompiler decompiler; + decompile_file(disassembler, decompiler, file, game, zonetool); + } + else if (game == game::S2) + { + s2::disassembler disassembler; + s2::decompiler decompiler; + decompile_file(disassembler, decompiler, file, game, zonetool); + } + else if (game == game::S4) + { + s4::disassembler disassembler; + s4::decompiler decompiler; + decompile_file(disassembler, decompiler, file, game, zonetool); + } + else if (game == game::H1) + { + h1::disassembler disassembler; + h1::decompiler decompiler; + decompile_file(disassembler, decompiler, file, game, zonetool); + } + else if (game == game::H2) + { + h2::disassembler disassembler; + h2::decompiler decompiler; + decompile_file(disassembler, decompiler, file, game, zonetool); + } + } + + return 0; +} + +} // namespace xsk::gsc + +int main(int argc, char** argv) +{ + xsk::gsc::main(argc, argv); +} diff --git a/src/utils/xsk/utils.hpp b/src/utils/xsk/utils.hpp index 48b3c383..81ba6db2 100644 --- a/src/utils/xsk/utils.hpp +++ b/src/utils/xsk/utils.hpp @@ -1,28 +1,28 @@ -// Copyright 2021 xensik. All rights reserved. -// -// Use of this source code is governed by a GNU GPLv3 license -// that can be found in the LICENSE file. - -#pragma once - -// Utility -#include "file.hpp" -#include "string.hpp" -#include "byte_buffer.hpp" -#include "compression.hpp" - -// GSC Types -#include "gsc/compilation_mode.hpp" -#include "gsc/pair.hpp" -#include "gsc/asset.hpp" -#include "gsc/assembly.hpp" -#include "gsc/context.hpp" -#include "gsc/location.hpp" -#include "gsc/nodetree.hpp" - -// GSC Interfaces -#include "gsc/interfaces/exception.hpp" -#include "gsc/interfaces/assembler.hpp" -#include "gsc/interfaces/disassembler.hpp" -#include "gsc/interfaces/compiler.hpp" -#include "gsc/interfaces/decompiler.hpp" +// Copyright 2021 xensik. All rights reserved. +// +// Use of this source code is governed by a GNU GPLv3 license +// that can be found in the LICENSE file. + +#pragma once + +// Utility +#include "file.hpp" +#include "string.hpp" +#include "byte_buffer.hpp" +#include "compression.hpp" + +// GSC Types +#include "gsc/compilation_mode.hpp" +#include "gsc/pair.hpp" +#include "gsc/asset.hpp" +#include "gsc/assembly.hpp" +#include "gsc/context.hpp" +#include "gsc/location.hpp" +#include "gsc/nodetree.hpp" + +// GSC Interfaces +#include "gsc/interfaces/exception.hpp" +#include "gsc/interfaces/assembler.hpp" +#include "gsc/interfaces/disassembler.hpp" +#include "gsc/interfaces/compiler.hpp" +#include "gsc/interfaces/decompiler.hpp"