refactor(global): headers & arc module (#86)

This commit is contained in:
Xenxo Espasandín 2023-03-02 16:41:32 +01:00 committed by GitHub
parent 1bca247808
commit f6ae955f34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
214 changed files with 201183 additions and 906 deletions

View File

@ -6,4 +6,5 @@ clean:
gsc: parser.ypp
bison parser.ypp -Wcounterexamples
mv parser.hpp parser.cpp ../../src/gsc/
mv parser.hpp ../../include/xsk/gsc/
mv parser.cpp ../../src/gsc/

View File

@ -39,9 +39,9 @@ namespace xsk::gsc { class preprocessor; }
%code top
{
#include "stdinc.hpp"
#include "parser.hpp"
#include "preprocessor.hpp"
#include "xsk/stdinc.hpp"
#include "xsk/gsc/parser.hpp"
#include "xsk/gsc/preprocessor.hpp"
using namespace xsk::gsc;
namespace xsk::gsc
{

View File

@ -6,4 +6,5 @@ clean:
t6: parser.ypp
bison parser.ypp -Wcounterexamples
mv parser.hpp parser.cpp ../../src/t6/
mv parser.hpp ../../include/xsk/t6/
mv parser.cpp ../../src/t6/

View File

@ -36,9 +36,9 @@ namespace xsk::arc::t6 { class lexer; }
%code top
{
#include "stdinc.hpp"
#include "parser.hpp"
#include "lexer.hpp"
#include "xsk/stdinc.hpp"
#include "xsk/t6/parser.hpp"
#include "xsk/t6/lexer.hpp"
using namespace xsk::arc;
xsk::arc::t6::parser::symbol_type T6lex(xsk::arc::t6::lexer& lexer);
}

View File

@ -0,0 +1,208 @@
// Copyright 2023 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::arc
{
constexpr usize opcode_count = 143;
enum class opcode : u8
{
OP_Invalid,
OP_End,
OP_Return,
OP_GetUndefined,
OP_GetZero,
OP_GetByte,
OP_GetNegByte,
OP_GetUnsignedShort,
OP_GetNegUnsignedShort,
OP_GetInteger,
OP_GetFloat,
OP_GetString,
OP_GetIString,
OP_GetVector,
OP_GetLevelObject,
OP_GetAnimObject,
OP_GetSelf,
OP_GetLevel,
OP_GetGame,
OP_GetAnim,
OP_GetAnimation,
OP_GetGameRef,
OP_GetFunction,
OP_CreateLocalVariable,
OP_SafeCreateLocalVariables,
OP_RemoveLocalVariables,
OP_EvalLocalVariableCached,
OP_EvalArray,
OP_EvalLocalArrayRefCached,
OP_EvalArrayRef,
OP_ClearArray,
OP_EmptyArray,
OP_GetSelfObject,
OP_EvalFieldVariable,
OP_EvalFieldVariableRef,
OP_ClearFieldVariable,
OP_SafeSetVariableFieldCached,
OP_SafeSetWaittillVariableFieldCached,
OP_ClearParams,
OP_CheckClearParams,
OP_EvalLocalVariableRefCached,
OP_SetVariableField,
OP_CallBuiltin,
OP_CallBuiltinMethod,
OP_Wait,
OP_WaitTillFrameEnd,
OP_PreScriptCall,
OP_ScriptFunctionCall,
OP_ScriptFunctionCallPointer,
OP_ScriptMethodCall,
OP_ScriptMethodCallPointer,
OP_ScriptThreadCall,
OP_ScriptThreadCallPointer,
OP_ScriptMethodThreadCall,
OP_ScriptMethodThreadCallPointer,
OP_DecTop,
OP_CastFieldObject,
OP_CastBool,
OP_BoolNot,
OP_BoolComplement,
OP_JumpOnFalse,
OP_JumpOnTrue,
OP_JumpOnFalseExpr,
OP_JumpOnTrueExpr,
OP_Jump,
OP_JumpBack,
OP_Inc,
OP_Dec,
OP_Bit_Or,
OP_Bit_Xor,
OP_Bit_And,
OP_Equal,
OP_NotEqual,
OP_LessThan,
OP_GreaterThan,
OP_LessThanOrEqualTo,
OP_GreaterThanOrEqualTo,
OP_ShiftLeft,
OP_ShiftRight,
OP_Plus,
OP_Minus,
OP_Multiply,
OP_Divide,
OP_Modulus,
OP_SizeOf,
OP_WaitTillMatch,
OP_WaitTill,
OP_Notify,
OP_EndOn,
OP_VoidCodePos,
OP_Switch,
OP_EndSwitch,
OP_Vector,
OP_GetHash,
OP_RealWait,
OP_VectorConstant,
OP_IsDefined,
OP_VectorScale,
OP_AnglesToUp,
OP_AnglesToRight,
OP_AnglesToForward,
OP_AngleClamp180,
OP_VectorToAngles,
OP_Abs,
OP_GetTime,
OP_GetDvar,
OP_GetDvarInt,
OP_GetDvarFloat,
OP_GetDvarVector,
OP_GetDvarColorRed,
OP_GetDvarColorGreen,
OP_GetDvarColorBlue,
OP_GetDvarColorAlpha,
OP_FirstArrayKey,
OP_NextArrayKey,
OP_ProfileStart,
OP_ProfileStop,
OP_SafeDecTop,
OP_Nop,
OP_Abort,
OP_Object,
OP_ThreadObject,
OP_EvalLocalVariable,
OP_EvalLocalVariableRef,
OP_DevblockBegin,
OP_DevblockEnd,
OP_EvalLocalVariableCachedDebug,
OP_EvalLocalVariableRefCachedDebug,
OP_LevelEvalFieldVariable,
OP_LevelEvalFieldVariableRef,
OP_SelfEvalFieldVariable,
OP_SelfEvalFieldVariableRef,
OP_GetWorld,
OP_GetWorldObject,
OP_GetClasses,
OP_GetClassesObject,
OP_New,
OP_ScriptFunctionCallClass,
OP_ScriptThreadCallClass,
OP_GetUintptr,
OP_SuperEqual,
OP_SuperNotEqual,
OP_GetAPIFunction,
OP_Count,
};
struct instruction
{
using ptr = std::unique_ptr<instruction>;
u32 index;
u32 size;
opcode opcode;
std::vector<std::string> data;
};
struct function
{
using ptr = std::unique_ptr<function>;
u32 index;
u32 size;
u8 params;
u8 flags;
std::string name;
std::string space;
std::vector<instruction::ptr> instructions;
std::unordered_map<u32, std::string> labels;
};
struct assembly
{
using ptr = std::unique_ptr<assembly>;
std::vector<std::string> includes;
std::vector<function::ptr> functions;
};
inline auto make_instruction() -> std::unique_ptr<instruction>
{
return std::unique_ptr<instruction>(new instruction);
}
inline auto make_function() -> std::unique_ptr<function>
{
return std::unique_ptr<function>(new function);
}
inline auto make_assembly() -> std::unique_ptr<assembly>
{
return std::unique_ptr<assembly>(new assembly);
}
} // namespace xsk::arc

View File

@ -0,0 +1,119 @@
// Copyright 2023 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::arc
{
constexpr usize header_size_32 = 64;
constexpr usize header_size_64 = 72;
struct header
{
u64 magic;
u32 source_crc;
u32 include_offset;
u32 animtree_offset;
u32 cseg_offset;
u32 stringtablefixup_offset;
u32 devblock_stringtablefixup_offset;
u32 exports_offset;
u32 imports_offset;
u32 fixup_offset;
u32 profile_offset;
u32 cseg_size;
u32 name;
u16 stringtablefixup_count;
u16 exports_count;
u16 imports_count;
u16 fixup_count;
u16 profile_count;
u16 devblock_stringtablefixup_count;
u8 include_count;
u8 animtree_count;
u8 flags;
};
enum class import_flags : u8
{
none = 0,
func_reference = 1,
func_call = 2,
func_call_thread = 3,
meth_call = 4,
meth_call_thread = 5,
developer = 0x10,
unk = 0x20, // T7, T8, T9
};
struct import_ref
{
using ptr = std::shared_ptr<import_ref>;
std::string space;
std::string name;
u8 params;
u8 flags;
std::vector<u32> refs;
};
enum class export_flags : u8
{
export_none = 0x00,
export_public = 0x01,
export_autoexec = 0x02,
export_private = 0x04,
export_codecall = 0x08,
export_private2 = 0x10,
export_varargs = 0x20,
};
struct export_ref
{
using ptr = std::shared_ptr<export_ref>;
std::string space;
std::string name;
u32 checksum;
u32 offset;
u32 size;
u8 params;
u8 flags;
};
enum class string_type : u8
{
literal = 0,
canonical = 1,
};
struct string_ref
{
using ptr = std::shared_ptr<string_ref>;
std::string name;
u8 type;
std::vector<u32> refs;
};
struct animation_ref
{
using ptr = std::shared_ptr<animation_ref>;
std::string name;
u32 ref;
};
struct animtree_ref
{
using ptr = std::shared_ptr<animtree_ref>;
std::string name;
std::vector<u32> refs;
std::vector<animation_ref> anims;
};
} // namespace xsk::arc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
// Copyright 2023 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::arc
{
struct buffer
{
u8 const* data;
usize const size;
buffer() : data{ nullptr }, size{ 0 } {}
buffer(u8 const* data, usize size) : data{ data }, size{ size } {}
};
} // namespace xsk::arc

View File

@ -0,0 +1,47 @@
// Copyright 2023 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::arc
{
class error : public std::runtime_error
{
public:
error(std::string const& what);
};
class asm_error : public std::runtime_error
{
public:
asm_error(std::string const& what);
};
class disasm_error : public std::runtime_error
{
public:
disasm_error(std::string const& what);
};
class ppr_error : public std::runtime_error
{
public:
ppr_error(location const& loc, std::string const& what);
};
class comp_error : public std::runtime_error
{
public:
comp_error(location const& loc, std::string const& what);
};
class decomp_error : public std::runtime_error
{
public:
decomp_error(std::string const& what);
};
} // namespace xsk::arc

View File

@ -0,0 +1,177 @@
// Copyright 2023 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::arc
{
class position
{
public:
typedef const std::string filename_type;
typedef int counter_type;
filename_type *filename;
counter_type line;
counter_type column;
explicit position(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
: filename(f), line(l), column(c) {}
void initialize(filename_type *fn = nullptr, counter_type l = 1, counter_type c = 1)
{
filename = fn;
line = l;
column = c;
}
void lines(counter_type count = 1)
{
if (count)
{
column = 1;
line = add_(line, count, 1);
}
}
void columns(counter_type count = 1)
{
column = add_(column, count, 1);
}
private:
static counter_type add_(counter_type lhs, counter_type rhs, counter_type min)
{
return lhs + rhs < min ? min : lhs + rhs;
}
};
inline position& operator+=(position &res, position::counter_type width)
{
res.columns(width);
return res;
}
inline position operator+(position res, position::counter_type width)
{
return res += width;
}
inline position& operator-=(position &res, position::counter_type width)
{
return res += -width;
}
inline position operator-(position res, position::counter_type width)
{
return res -= width;
}
template <typename T>
std::basic_ostream<T>& operator<<(std::basic_ostream<T> &ostr, const position &pos)
{
if (pos.filename)
ostr << *pos.filename << ':';
return ostr << pos.line << '.' << pos.column;
}
class location
{
public:
typedef position::filename_type filename_type;
typedef position::counter_type counter_type;
position begin;
position end;
location(const position &b, const position &e)
: begin(b), end(e) {}
explicit location(const position &p = position())
: begin(p), end(p) {}
explicit location(filename_type *f, counter_type l = 1, counter_type c = 1)
: begin(f, l, c), end(f, l, c) {}
void initialize(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
{
begin.initialize(f, l, c);
end = begin;
}
void step()
{
begin = end;
}
void columns(counter_type count = 1)
{
end += count;
}
void lines(counter_type count = 1)
{
end.lines(count);
}
auto print() const -> std::string
{
return fmt::format("{}:{}:{}", *begin.filename, begin.line, begin.column);
}
auto label() const -> std::string
{
return fmt::format("loc_{:X}", begin.line);
}
};
inline location& operator+=(location &res, const location &end)
{
res.end = end.end;
return res;
}
inline location operator+(location res, const location &end)
{
return res += end;
}
inline location& operator+=(location &res, location::counter_type width)
{
res.columns(width);
return res;
}
inline location operator+(location res, location::counter_type width)
{
return res += width;
}
inline location& operator-=(location &res, location::counter_type width)
{
return res += -width;
}
inline location operator-(location res, location::counter_type width)
{
return res -= width;
}
template <typename T>
std::basic_ostream<T>& operator<<(std::basic_ostream<T> &ostr, const location &loc)
{
location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
ostr << loc.begin;
if (loc.end.filename && (!loc.begin.filename || *loc.begin.filename != *loc.end.filename))
ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
else if (loc.begin.line < loc.end.line)
ostr << '-' << loc.end.line << '.' << end_col;
else if (loc.begin.column < end_col)
ostr << '-' << end_col;
return ostr;
}
} // namespace xsk::arc

View File

@ -0,0 +1,97 @@
// Copyright 2023 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
#include "asset.hpp"
#include "assembly.hpp"
#include "buffer.hpp"
#include "location.hpp"
#include "exception.hpp"
#include "ast.hpp"
namespace xsk::arc
{
enum class instance : u8
{
server,
client,
};
enum class build : u8
{
dev,
prod,
};
enum class endian : u8
{
little,
big,
};
enum class system : u8
{
pc,
ps3,
xb2,
};
enum class engine : u8
{
t6,
t7,
t8,
t9,
};
struct props
{
enum values : u32
{
none = 0 << 0,
version2 = 1 << 0,
};
props(values value) : value_(value) {}
operator values() { return value_; }
operator bool() { return value_ != values::none; }
props::values operator|(props::values rhs) const { return static_cast<props::values>(value_ | rhs); }
props::values operator&(props::values rhs) const { return static_cast<props::values>(value_ & rhs); }
friend props::values operator|(props::values lhs, props::values rhs)
{
return static_cast<props::values>(static_cast<std::underlying_type<props::values>::type>(lhs) | static_cast<std::underlying_type<props::values>::type>(rhs));
}
friend props::values operator&(props::values lhs, props::values rhs)
{
return static_cast<props::values>(static_cast<std::underlying_type<props::values>::type>(lhs) & static_cast<std::underlying_type<props::values>::type>(rhs));
}
private:
values value_;
};
enum class switch_type
{
none,
integer,
string,
};
struct locjmp
{
std::string end;
std::string cnt;
std::string brk;
bool is_dev;
};
// fordward decl for modules ref
class context;
} // namespace xsk::arc

View File

@ -0,0 +1,69 @@
// Copyright 2023 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
#include "common/types.hpp"
#include "source.hpp"
#include "disassembler.hpp"
#include "decompiler.hpp"
namespace xsk::arc
{
class context
{
public:
using fs_callback = std::function<std::vector<u8>(std::string const&)>;
context(props props, engine engine, endian endian, system system, u64 magic);
auto props() const -> props { return props_; }
auto build() const -> build { return build_; }
auto engine() const -> engine { return engine_; }
auto endian() const -> endian { return endian_; }
auto system() const -> system { return system_; }
auto instance() const -> instance { return instance_; }
auto magic() const -> u64 { return magic_; }
auto source() -> source& { return source_; }
auto disassembler() -> disassembler& { return disassembler_; }
auto decompiler() -> decompiler& { return decompiler_; }
auto init(arc::build build, fs_callback callback) -> void;
auto cleanup() -> void;
auto engine_name() const -> std::string_view;
auto opcode_size(opcode op) const -> u32;
auto opcode_id(opcode op) const -> u8;
auto opcode_name(opcode op) const -> std::string;
auto opcode_enum(std::string const& name) const -> opcode;
auto opcode_enum(u16 id) const -> opcode;
auto dvar_id(std::string const& name) const -> u32;
auto dvar_name(u32 id) const -> std::string;
auto hash_id(std::string const& name) const -> u32;
auto hash_name(u32 id) const -> std::string;
protected:
arc::props props_;
arc::build build_;
arc::engine engine_;
arc::endian endian_;
arc::system system_;
arc::instance instance_;
u64 magic_;
arc::source source_;
arc::disassembler disassembler_;
arc::decompiler decompiler_;
fs_callback fs_callback_;
std::unordered_map<opcode, std::string_view> opcode_map_;
std::unordered_map<std::string_view, opcode> opcode_map_rev_;
std::unordered_map<u16, opcode> code_map_;
std::unordered_map<opcode, u8> code_map_rev_;
std::unordered_map<u32, std::string_view> dvar_map_;
std::unordered_map<u32, std::string_view> hash_map_;
};
} // namespace xsk::arc

View File

@ -0,0 +1,107 @@
// Copyright 2023 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
#include "common/types.hpp"
namespace xsk::arc
{
class decompiler
{
context const* ctx_;
program::ptr program_;
decl_function::ptr func_;
std::unordered_set<std::string> vars_;
std::unordered_map<u32, std::string> labels_;
std::vector<std::string> expr_labels_;
std::vector<std::string> tern_labels_;
std::vector<std::string> locals_;
std::stack<node::ptr> stack_;
locjmp locs_;
bool in_waittill_;
bool retbool_;
public:
decompiler(context const* ctx);
auto decompile(assembly const& data) -> program::ptr;
private:
auto decompile_function(function const& func) -> void;
auto decompile_instruction(instruction const& inst, bool last) -> void;
auto decompile_expressions(instruction const& inst) -> void;
auto decompile_statements(stmt_list& stm) -> void;
auto decompile_infinites(stmt_list& stm) -> void;
auto decompile_loops(stmt_list& stm) -> void;
auto decompile_switches(stmt_list& stm) -> void;
auto decompile_ifelses(stmt_list& stm) -> void;
auto decompile_aborts(stmt_list& stm) -> void;
auto decompile_devblocks(stmt_list& stm) -> void;
auto decompile_if(stmt_list& stm, usize begin, usize end) -> void;
auto decompile_ifelse(stmt_list& stm, usize begin, usize end) -> void;
auto decompile_inf(stmt_list& stm, usize begin, usize end) -> void;
auto decompile_loop(stmt_list& stm, usize begin, usize end) -> void;
auto decompile_while(stmt_list& stm, usize begin, usize end) -> void;
auto decompile_dowhile(stmt_list& stm, usize begin, usize end) -> void;
auto decompile_for(stmt_list& stm, usize begin, usize end) -> void;
auto decompile_foreach(stmt_list& stm, usize begin, usize end) -> void;
auto decompile_switch(stmt_list& stm, usize begin, usize end) -> void;
auto find_location_reference(stmt_list const& stm, usize begin, usize end, std::string const& loc) -> bool;
auto find_location_index(stmt_list const& stm, std::string const& loc) -> usize;
auto last_location_index(stmt_list const& stm, usize index) -> bool;
auto lvalues_match(stmt_assign const& stm1, stmt_assign const& stm2) -> bool;
auto resolve_label(std::string const& name) -> u32;
auto process_function(decl_function& func) -> void;
auto process_stmt(stmt& stm) -> void;
auto process_stmt_list(stmt_list& stm) -> void;
auto process_stmt_comp(stmt_comp& stm) -> void;
auto process_stmt_dev(stmt_dev& stm) -> void;
auto process_stmt_expr(stmt_expr& stm) -> void;
auto process_stmt_call(stmt_call& stm) -> void;
auto process_stmt_assign(stmt_assign& stm) -> void;
auto process_stmt_endon(stmt_endon& stm) -> void;
auto process_stmt_notify(stmt_notify& stm) -> void;
auto process_stmt_realwait(stmt_realwait& stm) -> void;
auto process_stmt_wait(stmt_wait& stm) -> void;
auto process_stmt_waittill(stmt_waittill& stm) -> void;
auto process_stmt_waittillmatch(stmt_waittillmatch& stm) -> void;
auto process_stmt_if(stmt_if& stm) -> void;
auto process_stmt_ifelse(stmt_ifelse& stm) -> void;
auto process_stmt_while(stmt_while& stm) -> void;
auto process_stmt_dowhile(stmt_dowhile& stm) -> void;
auto process_stmt_for(stmt_for& stm) -> void;
auto process_stmt_foreach(stmt_foreach& stm) -> void;
auto process_stmt_switch(stmt_switch& stm) -> void;
auto process_stmt_break(stmt_break& stm) -> void;
auto process_stmt_continue(stmt_continue& stm) -> void;
auto process_stmt_return(stmt_return& stm) -> void;
auto process_expr(expr& exp) -> void;
auto process_expr_assign(expr_assign::ptr& exp) -> void;
auto process_expr_increment(expr_increment& exp) -> void;
auto process_expr_decrement(expr_decrement& exp) -> void;
auto process_expr_ternary(expr_ternary& exp) -> void;
auto process_expr_binary(expr_binary& exp) -> void;
auto process_expr_and(expr_and& exp) -> void;
auto process_expr_or(expr_or& exp) -> void;
auto process_expr_complement(expr_complement& exp) -> void;
auto process_expr_not(expr_not& exp) -> void;
auto process_expr_call(expr_call& exp) -> void;
auto process_expr_method(expr_method& exp) -> void;
auto process_expr_call_member(expr_member& exp) -> void;
auto process_expr_call_pointer(expr_pointer& exp) -> void;
auto process_expr_call_function(expr_function& exp) -> void;
auto process_expr_method_pointer(expr_pointer& exp, expr& obj) -> void;
auto process_expr_method_function(expr_function& exp, expr& obj) -> void;
auto process_expr_parameters(expr_parameters& exp) -> void;
auto process_expr_arguments(expr_arguments& exp) -> void;
auto process_expr_size(expr_size& exp) -> void;
auto process_expr_array(expr_array& exp) -> void;
auto process_expr_field(expr_field& exp) -> void;
auto process_expr_vector(expr_vector& exp) -> void;
auto process_expr_identifier(expr_identifier& exp) -> void;
};
} // namespace xsk::arc

View File

@ -0,0 +1,44 @@
// Copyright 2023 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
#include "common/types.hpp"
#include "xsk/utils/reader.hpp"
namespace xsk::arc
{
class disassembler
{
context const* ctx_;
function::ptr func_;
assembly::ptr assembly_;
utils::reader script_;
std::map<u32, import_ref::ptr> import_refs_;
std::map<u32, string_ref::ptr> string_refs_;
std::map<u32, animtree_ref::ptr> anim_refs_;
public:
disassembler(context const* ctx);
auto disassemble(buffer const& data) -> assembly::ptr;
auto disassemble(std::vector<u8> const& data) -> assembly::ptr;
auto disassemble(u8 const* data, usize data_size) -> assembly::ptr;
private:
auto disassemble_function(function& func) -> void;
auto disassemble_instruction(instruction& inst) -> void;
auto disassemble_name(instruction& inst) -> void;
auto disassemble_params(instruction& inst) -> void;
auto disassemble_import(instruction& inst) -> void;
auto disassemble_string(instruction& inst) -> void;
auto disassemble_animtree(instruction& inst) -> void;
auto disassemble_animation(instruction& inst) -> void;
auto disassemble_jump(instruction& inst) -> void;
auto disassemble_switch(instruction& inst) -> void;
auto disassemble_end_switch(instruction& inst) -> void;
};
} // namespace xsk::arc

View File

@ -0,0 +1,24 @@
// Copyright 2023 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
#include "xsk/stdinc.hpp"
#include "xsk/arc/context.hpp"
namespace xsk::arc::t6
{
constexpr usize code_count = 125;
constexpr usize dvar_count = 3326;
constexpr u64 header_magic = 0x06000A0D43534780;
class context : public arc::context
{
public:
context();
};
} // namespace xsk::gsc::t6

View File

@ -0,0 +1,25 @@
// Copyright 2023 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
#include "xsk/stdinc.hpp"
#include "xsk/arc/context.hpp"
namespace xsk::arc::t7
{
constexpr usize code_count = 8192;
constexpr usize dvar_count = 0;
constexpr usize hash_count = 178717;
constexpr u64 header_magic = 0x1C000A0D43534780;
class context : public arc::context
{
public:
context();
};
} // namespace xsk::arc::t7

View File

@ -0,0 +1,25 @@
// Copyright 2023 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
#include "xsk/stdinc.hpp"
#include "xsk/arc/context.hpp"
namespace xsk::arc::t8
{
constexpr usize code_count = 0;
constexpr usize dvar_count = 0;
constexpr usize hash_count = 0;
constexpr u64 header_magic = 0;
class context : public arc::context
{
public:
context();
};
} // namespace xsk::arc::t8

View File

@ -0,0 +1,25 @@
// Copyright 2023 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
#include "xsk/stdinc.hpp"
#include "xsk/arc/context.hpp"
namespace xsk::arc::t9
{
constexpr usize code_count = 0;
constexpr usize dvar_count = 0;
constexpr usize hash_count = 0;
constexpr u64 header_magic = 0;
class context : public arc::context
{
public:
context();
};
} // namespace xsk::arc::t9

170
include/xsk/arc/source.hpp Normal file
View File

@ -0,0 +1,170 @@
// Copyright 2023 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
#include "common/types.hpp"
namespace xsk::arc
{
class source
{
context* ctx_;
std::vector<u8> buf_;
u32 indent_;
public:
source(context* ctx);
auto dump(assembly const& data) -> std::vector<u8>;
auto dump(program const& data) -> std::vector<u8>;
private:
auto dump_assembly(assembly const& data) -> void;
auto dump_function(function const& func) -> void;
auto dump_instruction(instruction const& inst) -> void;
auto dump_program(program const& data) -> void;
auto dump_include(include const& inc) -> void;
auto dump_decl(decl const& dec) -> void;
auto dump_decl_dev_begin(decl_dev_begin const& dec) -> void;
auto dump_decl_dev_end(decl_dev_end const& dec) -> void;
auto dump_decl_namespace(decl_namespace const& dec) -> void;
auto dump_decl_usingtree(decl_usingtree const& dec) -> void;
auto dump_decl_function(decl_function const& dec) -> void;
auto dump_stmt(stmt const& stm) -> void;
auto dump_stmt_list(stmt_list const& stm) -> void;
auto dump_stmt_comp(stmt_comp const& stm) -> void;
auto dump_stmt_dev(stmt_dev const& stm) -> void;
auto dump_stmt_expr(stmt_expr const& stm) -> void;
auto dump_stmt_call(stmt_call const& stm) -> void;
auto dump_stmt_const(stmt_const const& stm) -> void;
auto dump_stmt_assign(stmt_assign const& stm) -> void;
auto dump_stmt_endon(stmt_endon const& stm) -> void;
auto dump_stmt_notify(stmt_notify const& stm) -> void;
auto dump_stmt_realwait(stmt_realwait const& stm) -> void;
auto dump_stmt_wait(stmt_wait const& stm) -> void;
auto dump_stmt_waittill(stmt_waittill const& stm) -> void;
auto dump_stmt_waittillmatch(stmt_waittillmatch const& stm) -> void;
auto dump_stmt_waittillframeend(stmt_waittillframeend const& stm) -> void;
auto dump_stmt_if(stmt_if const& stm) -> void;
auto dump_stmt_ifelse(stmt_ifelse const& stm) -> void;
auto dump_stmt_while(stmt_while const& stm) -> void;
auto dump_stmt_dowhile(stmt_dowhile const& stm) -> void;
auto dump_stmt_for(stmt_for const& stm) -> void;
auto dump_stmt_foreach(stmt_foreach const& stm) -> void;
auto dump_stmt_switch(stmt_switch const& stm) -> void;
auto dump_stmt_case(stmt_case const& stm) -> void;
auto dump_stmt_default(stmt_default const& stm) -> void;
auto dump_stmt_break(stmt_break const& stm) -> void;
auto dump_stmt_continue(stmt_continue const& stm) -> void;
auto dump_stmt_return(stmt_return const& stm) -> void;
auto dump_stmt_breakpoint(stmt_breakpoint const& stm) -> void;
auto dump_stmt_prof_begin(stmt_prof_begin const& stm) -> void;
auto dump_stmt_prof_end(stmt_prof_end const& stm) -> void;
auto dump_expr(expr const& exp) -> void;
auto dump_expr_increment(expr_increment const& exp) -> void;
auto dump_expr_decrement(expr_decrement const& exp) -> void;
auto dump_expr_assign_equal(expr_assign_equal const& exp) -> void;
auto dump_expr_assign_add(expr_assign_add const& exp) -> void;
auto dump_expr_assign_sub(expr_assign_sub const& exp) -> void;
auto dump_expr_assign_mul(expr_assign_mul const& exp) -> void;
auto dump_expr_assign_div(expr_assign_div const& exp) -> void;
auto dump_expr_assign_mod(expr_assign_mod const& exp) -> void;
auto dump_expr_assign_shift_left(expr_assign_shift_left const& exp) -> void;
auto dump_expr_assign_shift_right(expr_assign_shift_right const& exp) -> void;
auto dump_expr_assign_bitwise_or(expr_assign_bitwise_or const& exp) -> void;
auto dump_expr_assign_bitwise_and(expr_assign_bitwise_and const& exp) -> void;
auto dump_expr_assign_bitwise_exor(expr_assign_bitwise_exor const& exp) -> void;
auto dump_expr_ternary(expr_ternary const& exp) -> void;
auto dump_expr_or(expr_or const& exp) -> void;
auto dump_expr_and(expr_and const& exp) -> void;
auto dump_expr_super_equal(expr_super_equal const& exp) -> void;
auto dump_expr_super_not_equal(expr_super_not_equal const& exp) -> void;
auto dump_expr_equality(expr_equality const& exp) -> void;
auto dump_expr_inequality(expr_inequality const& exp) -> void;
auto dump_expr_less_equal(expr_less_equal const& exp) -> void;
auto dump_expr_greater_equal(expr_greater_equal const& exp) -> void;
auto dump_expr_less(expr_less const& exp) -> void;
auto dump_expr_greater(expr_greater const& exp) -> void;
auto dump_expr_add(expr_add const& exp) -> void;
auto dump_expr_sub(expr_sub const& exp) -> void;
auto dump_expr_mul(expr_mul const& exp) -> void;
auto dump_expr_div(expr_div const& exp) -> void;
auto dump_expr_mod(expr_mod const& exp) -> void;
auto dump_expr_shift_left(expr_shift_left const& exp) -> void;
auto dump_expr_shift_right(expr_shift_right const& exp) -> void;
auto dump_expr_bitwise_or(expr_bitwise_or const& exp) -> void;
auto dump_expr_bitwise_and(expr_bitwise_and const& exp) -> void;
auto dump_expr_bitwise_exor(expr_bitwise_exor const& exp) -> void;
auto dump_expr_not(expr_not const& exp) -> void;
auto dump_expr_negate(expr_negate const& exp) -> void;
auto dump_expr_complement(expr_complement const& exp) -> void;
auto dump_expr_new(expr_new const& exp) -> void;
auto dump_expr_call(expr_call const& exp) -> void;
auto dump_expr_method(expr_method const& exp) -> void;
auto dump_call(call const& exp) -> void;
auto dump_expr_function(expr_function const& exp) -> void;
auto dump_expr_pointer(expr_pointer const& exp) -> void;
auto dump_expr_member(expr_member const& exp) -> void;
auto dump_expr_parameters(expr_parameters const& exp) -> void;
auto dump_expr_arguments(expr_arguments const& exp) -> void;
auto dump_expr_isdefined(expr_isdefined const& exp) -> void;
auto dump_expr_vectorscale(expr_vectorscale const& exp) -> void;
auto dump_expr_anglestoup(expr_anglestoup const& exp) -> void;
auto dump_expr_anglestoright(expr_anglestoright const& exp) -> void;
auto dump_expr_anglestoforward(expr_anglestoforward const& exp) -> void;
auto dump_expr_angleclamp180(expr_angleclamp180 const& exp) -> void;
auto dump_expr_vectortoangles(expr_vectortoangles const& exp) -> void;
auto dump_expr_abs(expr_abs const& exp) -> void;
auto dump_expr_gettime(expr_gettime const& exp) -> void;
auto dump_expr_getdvar(expr_getdvar const& exp) -> void;
auto dump_expr_getdvarint(expr_getdvarint const& exp) -> void;
auto dump_expr_getdvarfloat(expr_getdvarfloat const& exp) -> void;
auto dump_expr_getdvarvector(expr_getdvarvector const& exp) -> void;
auto dump_expr_getdvarcolorred(expr_getdvarcolorred const& exp) -> void;
auto dump_expr_getdvarcolorgreen(expr_getdvarcolorgreen const& exp) -> void;
auto dump_expr_getdvarcolorblue(expr_getdvarcolorblue const& exp) -> void;
auto dump_expr_getdvarcoloralpha(expr_getdvarcoloralpha const& exp) -> void;
auto dump_expr_getfirstarraykey(expr_getfirstarraykey const& exp) -> void;
auto dump_expr_getnextarraykey(expr_getnextarraykey const& exp) -> void;
auto dump_expr_reference(expr_reference const& exp) -> void;
auto dump_expr_array(expr_array const& exp) -> void;
auto dump_expr_field(expr_field const& exp) -> void;
auto dump_expr_size(expr_size const& exp) -> void;
auto dump_expr_paren(expr_paren const& exp) -> void;
auto dump_expr_empty_array(expr_empty_array const& exp) -> void;
auto dump_expr_undefined(expr_undefined const& exp) -> void;
auto dump_expr_game(expr_game const& exp) -> void;
auto dump_expr_self(expr_self const& exp) -> void;
auto dump_expr_anim(expr_anim const& exp) -> void;
auto dump_expr_level(expr_level const& exp) -> void;
auto dump_expr_world(expr_world const& exp) -> void;
auto dump_expr_classes(expr_classes const& exp) -> void;
auto dump_expr_animation(expr_animation const& exp) -> void;
auto dump_expr_animtree(expr_animtree const& exp) -> void;
auto dump_expr_identifier(expr_identifier const& exp) -> void;
auto dump_expr_path(expr_path const& exp) -> void;
auto dump_expr_istring(expr_istring const& exp) -> void;
auto dump_expr_string(expr_string const& exp) -> void;
auto dump_expr_hash(expr_hash const& exp) -> void;
auto dump_expr_vector(expr_vector const& exp) -> void;
auto dump_expr_float(expr_float const& exp) -> void;
auto dump_expr_integer(expr_integer const& exp) -> void;
auto dump_expr_false(expr_false const& exp) -> void;
auto dump_expr_true(expr_true const& exp) -> void;
auto dump_asm_loc(asm_loc const& exp) -> void;
auto dump_asm_jmp(asm_jmp const& exp) -> void;
auto dump_asm_jmp_back(asm_jmp_back const& exp) -> void;
auto dump_asm_jmp_cond(asm_jmp_cond const& exp) -> void;
auto dump_asm_jmp_true(asm_jmp_true const& exp) -> void;
auto dump_asm_jmp_false(asm_jmp_false const& exp) -> void;
auto dump_asm_switch(asm_switch const& exp) -> void;
auto dump_asm_endswitch(asm_endswitch const& exp) -> void;
auto dump_asm_prescriptcall(asm_prescriptcall const& exp) -> void;
auto dump_asm_voidcodepos(asm_voidcodepos const& exp) -> void;
auto dump_asm_dev(asm_dev const& exp) -> void;
};
} // namespace xsk::arc

View File

@ -5,8 +5,8 @@
#pragma once
#include "misc/types.hpp"
#include <utils/writer.hpp>
#include "xsk/utils/writer.hpp"
#include "common/types.hpp"
namespace xsk::gsc
{

View File

@ -5,7 +5,7 @@
#pragma once
#include "misc/types.hpp"
#include "common/types.hpp"
namespace xsk::gsc
{

View File

@ -5,7 +5,7 @@
#pragma once
#include "misc/types.hpp"
#include "common/types.hpp"
#include "source.hpp"
#include "assembler.hpp"
#include "disassembler.hpp"

View File

@ -5,7 +5,7 @@
#pragma once
#include "misc/types.hpp"
#include "common/types.hpp"
namespace xsk::gsc
{

View File

@ -5,8 +5,8 @@
#pragma once
#include "misc/types.hpp"
#include <utils/reader.hpp>
#include "xsk/utils/reader.hpp"
#include "common/types.hpp"
namespace xsk::gsc
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::h1
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::h2
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::iw5_pc
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::iw5_ps
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::iw5_xb
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::iw6_pc
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::iw6_ps
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::iw6_xb
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::iw7
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::iw8
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::iw9
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::s1_pc
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::s1_ps
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::s1_xb
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::s2
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::s4
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::t4
{

View File

@ -5,8 +5,8 @@
#pragma once
#include <stdinc.hpp>
#include <gsc/context.hpp>
#include "xsk/stdinc.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc::t5
{

View File

@ -5,7 +5,7 @@
#pragma once
#include "misc/types.hpp"
#include "common/types.hpp"
namespace xsk::gsc
{

View File

@ -5,7 +5,7 @@
#pragma once
#include "misc/types.hpp"
#include "common/types.hpp"
#include "lexer.hpp"
namespace xsk::gsc

View File

@ -5,7 +5,7 @@
#pragma once
#include "misc/types.hpp"
#include "common/types.hpp"
namespace xsk::gsc
{

View File

@ -5,11 +5,11 @@
#pragma once
#include <stdinc.hpp>
#include "utils/string.hpp"
#include "utils/reader.hpp"
#include "utils/writer.hpp"
#include "misc/arc.hpp"
#include "xsk/stdinc.hpp"
#include "xsk/utils/string.hpp"
#include "xsk/utils/reader.hpp"
#include "xsk/utils/writer.hpp"
#include "common/arc.hpp"
#include "assembler.hpp"
#include "disassembler.hpp"
#include "compiler.hpp"

View File

@ -83,23 +83,8 @@ project "xsk-tool"
targetname "gsc-tool"
dependson "xsk-utils"
-- dependson "xsk-arc"
dependson "xsk-gsc"
dependson "xsk-iw5_pc"
dependson "xsk-iw5_ps"
dependson "xsk-iw5_xb"
dependson "xsk-iw6_pc"
dependson "xsk-iw6_ps"
dependson "xsk-iw6_xb"
dependson "xsk-s1_pc"
dependson "xsk-s1_ps"
dependson "xsk-s1_xb"
dependson "xsk-iw7"
dependson "xsk-iw8"
dependson "xsk-iw9"
dependson "xsk-h1"
dependson "xsk-h2"
dependson "xsk-s2"
dependson "xsk-s4"
dependson "xsk-t6"
files {
@ -110,28 +95,13 @@ project "xsk-tool"
links {
"xsk-utils",
-- "xsk-arc",
"xsk-gsc",
"xsk-iw5_pc",
"xsk-iw5_ps",
"xsk-iw5_xb",
"xsk-iw6_pc",
"xsk-iw6_ps",
"xsk-iw6_xb",
"xsk-s1_pc",
"xsk-s1_ps",
"xsk-s1_xb",
"xsk-iw7",
"xsk-iw8",
"xsk-iw9",
"xsk-h1",
"xsk-h2",
"xsk-s2",
"xsk-s4",
"xsk-t6",
}
includedirs {
"./src"
"./include",
}
fmt:link()
@ -148,12 +118,28 @@ project "xsk-utils"
}
includedirs {
"./src"
"./include",
}
fmt:include()
zlib:include()
-- project "xsk-arc"
-- kind "StaticLib"
-- language "C++"
-- files {
-- "./src/arc/**.h",
-- "./src/arc/**.hpp",
-- "./src/arc/**.cpp"
-- }
-- includedirs {
-- "./include",
-- }
-- fmt:include()
project "xsk-gsc"
kind "StaticLib"
language "C++"
@ -165,290 +151,7 @@ project "xsk-gsc"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-iw5_pc"
kind "StaticLib"
language "C++"
files {
"./src/iw5/iw5_pc.hpp",
"./src/iw5/iw5_pc.cpp",
"./src/iw5/iw5_pc_code.cpp",
"./src/iw5/iw5_pc_func.cpp",
"./src/iw5/iw5_pc_meth.cpp",
"./src/iw5/iw5_pc_token.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-iw5_ps"
kind "StaticLib"
language "C++"
files {
"./src/iw5/iw5_ps.hpp",
"./src/iw5/iw5_ps.cpp",
"./src/iw5/iw5_ps_code.cpp",
"./src/iw5/iw5_ps_func.cpp",
"./src/iw5/iw5_ps_meth.cpp",
"./src/iw5/iw5_ps_token.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-iw5_xb"
kind "StaticLib"
language "C++"
files {
"./src/iw5/iw5_xb.hpp",
"./src/iw5/iw5_xb.cpp",
"./src/iw5/iw5_xb_code.cpp",
"./src/iw5/iw5_xb_func.cpp",
"./src/iw5/iw5_xb_meth.cpp",
"./src/iw5/iw5_xb_token.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-iw6_pc"
kind "StaticLib"
language "C++"
files {
"./src/iw6/iw6_pc.hpp",
"./src/iw6/iw6_pc.cpp",
"./src/iw6/iw6_pc_code.cpp",
"./src/iw6/iw6_pc_func.cpp",
"./src/iw6/iw6_pc_meth.cpp",
"./src/iw6/iw6_pc_token.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-iw6_ps"
kind "StaticLib"
language "C++"
files {
"./src/iw6/iw6_ps.hpp",
"./src/iw6/iw6_ps.cpp",
"./src/iw6/iw6_ps_code.cpp",
"./src/iw6/iw6_ps_func.cpp",
"./src/iw6/iw6_ps_meth.cpp",
"./src/iw6/iw6_ps_token.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-iw6_xb"
kind "StaticLib"
language "C++"
files {
"./src/iw6/iw6_xb.hpp",
"./src/iw6/iw6_xb.cpp",
"./src/iw6/iw6_xb_code.cpp",
"./src/iw6/iw6_xb_func.cpp",
"./src/iw6/iw6_xb_meth.cpp",
"./src/iw6/iw6_xb_token.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-s1_pc"
kind "StaticLib"
language "C++"
files {
"./src/s1/s1_pc.hpp",
"./src/s1/s1_pc.cpp",
"./src/s1/s1_pc_code.cpp",
"./src/s1/s1_pc_func.cpp",
"./src/s1/s1_pc_meth.cpp",
"./src/s1/s1_pc_token.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-s1_ps"
kind "StaticLib"
language "C++"
files {
"./src/s1/s1_ps.hpp",
"./src/s1/s1_ps.cpp",
"./src/s1/s1_ps_code.cpp",
"./src/s1/s1_ps_func.cpp",
"./src/s1/s1_ps_meth.cpp",
"./src/s1/s1_ps_token.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-s1_xb"
kind "StaticLib"
language "C++"
files {
"./src/s1/s1_xb.hpp",
"./src/s1/s1_xb.cpp",
"./src/s1/s1_xb_code.cpp",
"./src/s1/s1_xb_func.cpp",
"./src/s1/s1_xb_meth.cpp",
"./src/s1/s1_xb_token.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-iw7"
kind "StaticLib"
language "C++"
files {
"./src/iw7/**.h",
"./src/iw7/**.hpp",
"./src/iw7/**.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-iw8"
kind "StaticLib"
language "C++"
files {
"./src/iw8/**.h",
"./src/iw8/**.hpp",
"./src/iw8/**.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-iw9"
kind "StaticLib"
language "C++"
files {
"./src/iw9/**.h",
"./src/iw9/**.hpp",
"./src/iw9/**.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-h1"
kind "StaticLib"
language "C++"
files {
"./src/h1/**.h",
"./src/h1/**.hpp",
"./src/h1/**.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-h2"
kind "StaticLib"
language "C++"
files {
"./src/h2/**.h",
"./src/h2/**.hpp",
"./src/h2/**.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-s2"
kind "StaticLib"
language "C++"
files {
"./src/s2/**.h",
"./src/s2/**.hpp",
"./src/s2/**.cpp"
}
includedirs {
"./src"
}
fmt:include()
project "xsk-s4"
kind "StaticLib"
language "C++"
files {
"./src/s4/**.h",
"./src/s4/**.hpp",
"./src/s4/**.cpp"
}
includedirs {
"./src"
"./include",
}
fmt:include()
@ -464,7 +167,7 @@ project "xsk-t6"
}
includedirs {
"./src"
"./include",
}
fmt:include()

1225
src/arc/common/ast.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
// Copyright 2023 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 "xsk/stdinc.hpp"
#include "xsk/arc/common/location.hpp"
#include "xsk/arc/common/exception.hpp"
namespace xsk::arc
{
error::error(std::string const& what) : std::runtime_error(fmt::format("[ERROR]: {}", what))
{
}
asm_error::asm_error(std::string const& what) : std::runtime_error(fmt::format("[ERROR]:assembler: {}", what))
{
}
disasm_error::disasm_error(std::string const& what) : std::runtime_error(fmt::format("[ERROR]:disassembler: {}", what))
{
}
ppr_error::ppr_error(location const& loc, std::string const& what) : std::runtime_error(fmt::format("[ERROR]:preprocessor:{}: {}", loc.print(), what))
{
}
comp_error::comp_error(location const& loc, std::string const& what) : std::runtime_error(fmt::format("[ERROR]:compiler:{}: {}", loc.print(), what))
{
}
decomp_error::decomp_error(std::string const& what) : std::runtime_error(fmt::format("[ERROR]:decompiler: {}", what))
{
}
} // namespace xsk::arc

445
src/arc/context.cpp Normal file
View File

@ -0,0 +1,445 @@
// Copyright 2023 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 "xsk/stdinc.hpp"
#include "xsk/arc/context.hpp"
namespace xsk::arc
{
extern std::array<std::pair<opcode, std::string_view>, opcode_count> const opcode_list;
context::context(arc::props props, arc::engine engine, arc::endian endian, arc::system system, u64 magic)
: props_{ props }, engine_{ engine }, endian_{ endian }, system_{ system }, instance_{ arc::instance::server }, magic_{ magic },
source_{ this },/* assembler_{ this },*/ disassembler_{ this }/*, compiler_{ this }*/, decompiler_{ this }
{
opcode_map_.reserve(opcode_list.size());
opcode_map_rev_.reserve(opcode_list.size());
for (auto const& entry : opcode_list)
{
opcode_map_.insert({ entry.first, entry.second });
opcode_map_rev_.insert({ entry.second, entry.first });
}
}
auto context::init(arc::build build, fs_callback callback) -> void
{
build_ = build;
fs_callback_ = callback;
}
auto context::cleanup() -> void
{
}
auto context::engine_name() const -> std::string_view
{
switch (engine_)
{
case engine::t6: return "T6";
case engine::t7: return "T7";
case engine::t8: return "T8";
case engine::t9: return "T9";
default: return "";
}
}
auto context::opcode_size(opcode op) const -> u32
{
switch (op)
{
case opcode::OP_End:
case opcode::OP_Return:
case opcode::OP_GetUndefined:
case opcode::OP_GetZero:
case opcode::OP_GetLevelObject:
case opcode::OP_GetAnimObject:
case opcode::OP_GetSelf:
case opcode::OP_GetLevel:
case opcode::OP_GetGame:
case opcode::OP_GetAnim:
case opcode::OP_GetGameRef:
case opcode::OP_CreateLocalVariable:
case opcode::OP_EvalArray:
case opcode::OP_EvalArrayRef:
case opcode::OP_ClearArray:
case opcode::OP_EmptyArray:
case opcode::OP_GetSelfObject:
case opcode::OP_ClearParams:
case opcode::OP_CheckClearParams:
case opcode::OP_SetVariableField:
case opcode::OP_Wait:
case opcode::OP_WaitTillFrameEnd:
case opcode::OP_PreScriptCall:
case opcode::OP_DecTop:
case opcode::OP_CastFieldObject:
case opcode::OP_CastBool:
case opcode::OP_BoolNot:
case opcode::OP_BoolComplement:
case opcode::OP_Inc:
case opcode::OP_Dec:
case opcode::OP_Bit_Or:
case opcode::OP_Bit_Xor:
case opcode::OP_Bit_And:
case opcode::OP_Equal:
case opcode::OP_NotEqual:
case opcode::OP_LessThan:
case opcode::OP_GreaterThan:
case opcode::OP_LessThanOrEqualTo:
case opcode::OP_GreaterThanOrEqualTo:
case opcode::OP_ShiftLeft:
case opcode::OP_ShiftRight:
case opcode::OP_Plus:
case opcode::OP_Minus:
case opcode::OP_Multiply:
case opcode::OP_Divide:
case opcode::OP_Modulus:
case opcode::OP_SizeOf:
case opcode::OP_WaitTill:
case opcode::OP_Notify:
case opcode::OP_EndOn:
case opcode::OP_VoidCodePos:
case opcode::OP_Vector:
case opcode::OP_RealWait:
case opcode::OP_IsDefined:
case opcode::OP_VectorScale:
case opcode::OP_AnglesToUp:
case opcode::OP_AnglesToRight:
case opcode::OP_AnglesToForward:
case opcode::OP_AngleClamp180:
case opcode::OP_VectorToAngles:
case opcode::OP_Abs:
case opcode::OP_GetTime:
case opcode::OP_GetDvar:
case opcode::OP_GetDvarInt:
case opcode::OP_GetDvarFloat:
case opcode::OP_GetDvarVector:
case opcode::OP_GetDvarColorRed:
case opcode::OP_GetDvarColorGreen:
case opcode::OP_GetDvarColorBlue:
case opcode::OP_GetDvarColorAlpha:
case opcode::OP_FirstArrayKey:
case opcode::OP_NextArrayKey:
case opcode::OP_ProfileStop:
case opcode::OP_SafeDecTop:
case opcode::OP_Nop:
case opcode::OP_Abort:
case opcode::OP_Object:
case opcode::OP_ThreadObject:
case opcode::OP_EvalLocalVariable:
case opcode::OP_EvalLocalVariableRef:
case opcode::OP_GetWorldObject:
case opcode::OP_GetWorld:
case opcode::OP_GetClassesObject:
case opcode::OP_GetClasses:
case opcode::OP_SuperEqual:
case opcode::OP_SuperNotEqual:
return (props_ & props::version2) ? 2 : 1;
case opcode::OP_SafeSetVariableFieldCached:
return (props_ & props::version2) ? 3 : 1;
case opcode::OP_GetByte:
case opcode::OP_GetNegByte:
case opcode::OP_SafeCreateLocalVariables:
case opcode::OP_RemoveLocalVariables:
case opcode::OP_EvalLocalVariableCached:
case opcode::OP_EvalLocalArrayRefCached:
case opcode::OP_SafeSetWaittillVariableFieldCached:
case opcode::OP_EvalLocalVariableRefCached:
case opcode::OP_ScriptFunctionCallPointer:
case opcode::OP_ScriptMethodCallPointer:
case opcode::OP_ScriptThreadCallPointer:
case opcode::OP_ScriptMethodThreadCallPointer:
case opcode::OP_WaitTillMatch:
case opcode::OP_VectorConstant:
return (props_ & props::version2) ? 3 : 2;
case opcode::OP_GetUnsignedShort:
case opcode::OP_GetNegUnsignedShort:
case opcode::OP_JumpOnFalse:
case opcode::OP_JumpOnTrue:
case opcode::OP_JumpOnFalseExpr:
case opcode::OP_JumpOnTrueExpr:
case opcode::OP_Jump:
case opcode::OP_JumpBack:
case opcode::OP_DevblockBegin:
case opcode::OP_DevblockEnd:
return (props_ & props::version2) ? 4 : 3;
case opcode::OP_GetString:
case opcode::OP_GetIString:
case opcode::OP_EvalFieldVariable:
case opcode::OP_EvalFieldVariableRef:
case opcode::OP_ClearFieldVariable:
return (props_ & props::version2) ? 6 : 3;
case opcode::OP_EvalLocalVariableCachedDebug:
case opcode::OP_EvalLocalVariableRefCachedDebug:
case opcode::OP_LevelEvalFieldVariableRef:
case opcode::OP_LevelEvalFieldVariable:
case opcode::OP_New:
case opcode::OP_SelfEvalFieldVariableRef:
case opcode::OP_SelfEvalFieldVariable:
return 6;
case opcode::OP_GetInteger:
case opcode::OP_GetFloat:
case opcode::OP_Switch:
case opcode::OP_EndSwitch:
case opcode::OP_GetHash:
return (props_ & props::version2) ? 6 : 5;
case opcode::OP_ScriptFunctionCallClass:
case opcode::OP_ScriptThreadCallClass:
return 7;
case opcode::OP_GetAPIFunction:
return 10;
case opcode::OP_ProfileStart:
return (props_ & props::version2) ? 10 : 1;
case opcode::OP_GetAnimation:
case opcode::OP_GetFunction:
return (props_ & props::version2) ? 10 : 5;
case opcode::OP_CallBuiltin:
case opcode::OP_CallBuiltinMethod:
case opcode::OP_ScriptFunctionCall:
case opcode::OP_ScriptMethodCall:
case opcode::OP_ScriptThreadCall:
case opcode::OP_ScriptMethodThreadCall:
return (props_ & props::version2) ? 11 : 6;
case opcode::OP_GetVector:
return (props_ & props::version2) ? 14 : 13;
default:
throw error(fmt::format("couldn't resolve instruction size for '{}'", opcode_name(op)));
}
}
auto context::opcode_id(opcode op) const -> u8
{
auto const itr = code_map_rev_.find(op);
if (itr != code_map_rev_.end())
{
return itr->second;
}
throw error(fmt::format("couldn't resolve opcode id for '{}'", opcode_name(op)));
}
auto context::opcode_name(opcode op) const -> std::string
{
auto const itr = opcode_map_.find(op);
if (itr != opcode_map_.end())
{
return std::string{ itr->second };
}
throw std::runtime_error(fmt::format("couldn't resolve opcode string for enum '{}'", static_cast<std::underlying_type_t<opcode>>(op)));
}
auto context::opcode_enum(std::string const& name) const -> opcode
{
auto const itr = opcode_map_rev_.find(name);
if (itr != opcode_map_rev_.end())
{
return itr->second;
}
throw std::runtime_error(fmt::format("couldn't resolve opcode enum for name '{}'", name));
}
auto context::opcode_enum(u16 id) const -> opcode
{
auto const itr = code_map_.find(id);
if (itr != code_map_.end())
{
return itr->second;
}
return opcode::OP_Invalid;
//throw error(fmt::format("couldn't resolve opcode enum for '{:02X}'", id));
}
auto context::dvar_id(std::string const& /*name*/) const -> u32
{
// todo hash func
return 0;
}
auto context::dvar_name(u32 id) const -> std::string
{
auto const itr = dvar_map_.find(id);
if (itr != dvar_map_.end())
{
return std::string(itr->second);
}
return fmt::format("_hash_{:08X}", id);
}
auto context::hash_id(std::string const& /*name*/) const -> u32
{
// todo hash func
return 0;
}
auto context::hash_name(u32 id) const -> std::string
{
auto const itr = hash_map_.find(id);
if (itr != hash_map_.end())
{
return std::string(itr->second);
}
return fmt::format("_id_{:08X}", id);
}
extern std::array<std::pair<opcode, std::string_view>, opcode_count> const opcode_list
{{
{ opcode::OP_Invalid, "OP_Invalid" },
{ opcode::OP_End, "OP_End" },
{ opcode::OP_Return, "OP_Return" },
{ opcode::OP_GetUndefined, "OP_GetUndefined" },
{ opcode::OP_GetZero, "OP_GetZero" },
{ opcode::OP_GetByte, "OP_GetByte" },
{ opcode::OP_GetNegByte, "OP_GetNegByte" },
{ opcode::OP_GetUnsignedShort, "OP_GetUnsignedShort" },
{ opcode::OP_GetNegUnsignedShort, "OP_GetNegUnsignedShort" },
{ opcode::OP_GetInteger, "OP_GetInteger" },
{ opcode::OP_GetFloat, "OP_GetFloat" },
{ opcode::OP_GetString, "OP_GetString" },
{ opcode::OP_GetIString, "OP_GetIString" },
{ opcode::OP_GetVector, "OP_GetVector" },
{ opcode::OP_GetLevelObject, "OP_GetLevelObject" },
{ opcode::OP_GetAnimObject, "OP_GetAnimObject" },
{ opcode::OP_GetSelf, "OP_GetSelf" },
{ opcode::OP_GetLevel, "OP_GetLevel" },
{ opcode::OP_GetGame, "OP_GetGame" },
{ opcode::OP_GetAnim, "OP_GetAnim" },
{ opcode::OP_GetAnimation, "OP_GetAnimation" },
{ opcode::OP_GetGameRef, "OP_GetGameRef" },
{ opcode::OP_GetFunction, "OP_GetFunction" },
{ opcode::OP_CreateLocalVariable, "OP_CreateLocalVariable" },
{ opcode::OP_SafeCreateLocalVariables, "OP_SafeCreateLocalVariables" },
{ opcode::OP_RemoveLocalVariables, "OP_RemoveLocalVariables" },
{ opcode::OP_EvalLocalVariableCached, "OP_EvalLocalVariableCached" },
{ opcode::OP_EvalArray, "OP_EvalArray" },
{ opcode::OP_EvalLocalArrayRefCached, "OP_EvalLocalArrayRefCached" },
{ opcode::OP_EvalArrayRef, "OP_EvalArrayRef" },
{ opcode::OP_ClearArray, "OP_ClearArray" },
{ opcode::OP_EmptyArray, "OP_EmptyArray" },
{ opcode::OP_GetSelfObject, "OP_GetSelfObject" },
{ opcode::OP_EvalFieldVariable, "OP_EvalFieldVariable" },
{ opcode::OP_EvalFieldVariableRef, "OP_EvalFieldVariableRef" },
{ opcode::OP_ClearFieldVariable, "OP_ClearFieldVariable" },
{ opcode::OP_SafeSetVariableFieldCached, "OP_SafeSetVariableFieldCached" },
{ opcode::OP_SafeSetWaittillVariableFieldCached, "OP_SafeSetWaittillVariableFieldCached" },
{ opcode::OP_ClearParams, "OP_ClearParams" },
{ opcode::OP_CheckClearParams, "OP_CheckClearParams" },
{ opcode::OP_EvalLocalVariableRefCached, "OP_EvalLocalVariableRefCached" },
{ opcode::OP_SetVariableField, "OP_SetVariableField" },
{ opcode::OP_CallBuiltin, "OP_CallBuiltin" },
{ opcode::OP_CallBuiltinMethod, "OP_CallBuiltinMethod" },
{ opcode::OP_Wait, "OP_Wait" },
{ opcode::OP_WaitTillFrameEnd, "OP_WaitTillFrameEnd" },
{ opcode::OP_PreScriptCall, "OP_PreScriptCall" },
{ opcode::OP_ScriptFunctionCall, "OP_ScriptFunctionCall" },
{ opcode::OP_ScriptFunctionCallPointer, "OP_ScriptFunctionCallPointer" },
{ opcode::OP_ScriptMethodCall, "OP_ScriptMethodCall" },
{ opcode::OP_ScriptMethodCallPointer, "OP_ScriptMethodCallPointer" },
{ opcode::OP_ScriptThreadCall, "OP_ScriptThreadCall" },
{ opcode::OP_ScriptThreadCallPointer, "OP_ScriptThreadCallPointer" },
{ opcode::OP_ScriptMethodThreadCall, "OP_ScriptMethodThreadCall" },
{ opcode::OP_ScriptMethodThreadCallPointer, "OP_ScriptMethodThreadCallPointer" },
{ opcode::OP_DecTop, "OP_DecTop" },
{ opcode::OP_CastFieldObject, "OP_CastFieldObject" },
{ opcode::OP_CastBool, "OP_CastBool" },
{ opcode::OP_BoolNot, "OP_BoolNot" },
{ opcode::OP_BoolComplement, "OP_BoolComplement" },
{ opcode::OP_JumpOnFalse, "OP_JumpOnFalse" },
{ opcode::OP_JumpOnTrue, "OP_JumpOnTrue" },
{ opcode::OP_JumpOnFalseExpr, "OP_JumpOnFalseExpr" },
{ opcode::OP_JumpOnTrueExpr, "OP_JumpOnTrueExpr" },
{ opcode::OP_Jump, "OP_Jump" },
{ opcode::OP_JumpBack, "OP_JumpBack" },
{ opcode::OP_Inc, "OP_Inc" },
{ opcode::OP_Dec, "OP_Dec" },
{ opcode::OP_Bit_Or, "OP_Bit_Or" },
{ opcode::OP_Bit_Xor, "OP_Bit_Xor" },
{ opcode::OP_Bit_And, "OP_Bit_And" },
{ opcode::OP_Equal, "OP_Equal" },
{ opcode::OP_NotEqual, "OP_NotEqual" },
{ opcode::OP_LessThan, "OP_LessThan" },
{ opcode::OP_GreaterThan, "OP_GreaterThan" },
{ opcode::OP_LessThanOrEqualTo, "OP_LessThanOrEqualTo" },
{ opcode::OP_GreaterThanOrEqualTo, "OP_GreaterThanOrEqualTo" },
{ opcode::OP_ShiftLeft, "OP_ShiftLeft" },
{ opcode::OP_ShiftRight, "OP_ShiftRight" },
{ opcode::OP_Plus, "OP_Plus" },
{ opcode::OP_Minus, "OP_Minus" },
{ opcode::OP_Multiply, "OP_Multiply" },
{ opcode::OP_Divide, "OP_Divide" },
{ opcode::OP_Modulus, "OP_Modulus" },
{ opcode::OP_SizeOf, "OP_SizeOf" },
{ opcode::OP_WaitTillMatch, "OP_WaitTillMatch" },
{ opcode::OP_WaitTill, "OP_WaitTill" },
{ opcode::OP_Notify, "OP_Notify" },
{ opcode::OP_EndOn, "OP_EndOn" },
{ opcode::OP_VoidCodePos, "OP_VoidCodePos" },
{ opcode::OP_Switch, "OP_Switch" },
{ opcode::OP_EndSwitch, "OP_EndSwitch" },
{ opcode::OP_Vector, "OP_Vector" },
{ opcode::OP_GetHash, "OP_GetHash" },
{ opcode::OP_RealWait, "OP_RealWait" },
{ opcode::OP_VectorConstant, "OP_VectorConstant" },
{ opcode::OP_IsDefined, "OP_IsDefined" },
{ opcode::OP_VectorScale, "OP_VectorScale" },
{ opcode::OP_AnglesToUp, "OP_AnglesToUp" },
{ opcode::OP_AnglesToRight, "OP_AnglesToRight" },
{ opcode::OP_AnglesToForward, "OP_AnglesToForward" },
{ opcode::OP_AngleClamp180, "OP_AngleClamp180" },
{ opcode::OP_VectorToAngles, "OP_VectorToAngles" },
{ opcode::OP_Abs, "OP_Abs" },
{ opcode::OP_GetTime, "OP_GetTime" },
{ opcode::OP_GetDvar, "OP_GetDvar" },
{ opcode::OP_GetDvarInt, "OP_GetDvarInt" },
{ opcode::OP_GetDvarFloat, "OP_GetDvarFloat" },
{ opcode::OP_GetDvarVector, "OP_GetDvarVector" },
{ opcode::OP_GetDvarColorRed, "OP_GetDvarColorRed" },
{ opcode::OP_GetDvarColorGreen, "OP_GetDvarColorGreen" },
{ opcode::OP_GetDvarColorBlue, "OP_GetDvarColorBlue" },
{ opcode::OP_GetDvarColorAlpha, "OP_GetDvarColorAlpha" },
{ opcode::OP_FirstArrayKey, "OP_FirstArrayKey" },
{ opcode::OP_NextArrayKey, "OP_NextArrayKey" },
{ opcode::OP_ProfileStart, "OP_ProfileStart" },
{ opcode::OP_ProfileStop, "OP_ProfileStop" },
{ opcode::OP_SafeDecTop, "OP_SafeDecTop" },
{ opcode::OP_Nop, "OP_Nop" },
{ opcode::OP_Abort, "OP_Abort" },
{ opcode::OP_Object, "OP_Object" },
{ opcode::OP_ThreadObject, "OP_ThreadObject" },
{ opcode::OP_EvalLocalVariable, "OP_EvalLocalVariable" },
{ opcode::OP_EvalLocalVariableRef, "OP_EvalLocalVariableRef" },
{ opcode::OP_DevblockBegin, "OP_DevblockBegin" },
{ opcode::OP_DevblockEnd, "OP_DevblockEnd" },
{ opcode::OP_EvalLocalVariableCachedDebug, "OP_EvalLocalVariableCachedDebug" },
{ opcode::OP_EvalLocalVariableRefCachedDebug, "OP_EvalLocalVariableRefCachedDebug" },
{ opcode::OP_LevelEvalFieldVariable, "OP_LevelEvalFieldVariable" },
{ opcode::OP_LevelEvalFieldVariableRef, "OP_LevelEvalFieldVariableRef" },
{ opcode::OP_SelfEvalFieldVariable, "OP_SelfEvalFieldVariable" },
{ opcode::OP_SelfEvalFieldVariableRef, "OP_SelfEvalFieldVariableRef" },
{ opcode::OP_GetWorld, "OP_GetWorld" },
{ opcode::OP_GetWorldObject, "OP_GetWorldObject" },
{ opcode::OP_GetClasses, "OP_GetClasses" },
{ opcode::OP_GetClassesObject, "OP_GetClassesObject" },
{ opcode::OP_New, "OP_New" },
{ opcode::OP_ScriptFunctionCallClass, "OP_ScriptFunctionCallClass" },
{ opcode::OP_ScriptThreadCallClass, "OP_ScriptThreadCallClass" },
{ opcode::OP_GetUintptr, "OP_GetUintptr" },
{ opcode::OP_SuperEqual, "OP_SuperEqual" },
{ opcode::OP_SuperNotEqual, "OP_SuperNotEqual" },
{ opcode::OP_GetAPIFunction, "OP_GetAPIFunction" },
}};
} // namespace xsk::arc

2725
src/arc/decompiler.cpp Normal file

File diff suppressed because it is too large Load Diff

755
src/arc/disassembler.cpp Normal file
View File

@ -0,0 +1,755 @@
// Copyright 2023 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 "xsk/stdinc.hpp"
#include "xsk/arc/disassembler.hpp"
#include "xsk/arc/context.hpp"
#include "xsk/utils/string.hpp"
namespace xsk::arc
{
disassembler::disassembler(context const* ctx) : ctx_{ ctx }
{
}
auto disassembler::disassemble(buffer const& data) -> assembly::ptr
{
return disassemble(data.data, data.size);
}
auto disassembler::disassemble(std::vector<u8> const& data) -> assembly::ptr
{
return disassemble(data.data(), data.size());
}
auto disassembler::disassemble(u8 const* data, usize data_size) -> assembly::ptr
{
script_ = utils::reader{ data, static_cast<u32>(data_size), ctx_->endian() == endian::big };
assembly_ = make_assembly();
import_refs_.clear();
string_refs_.clear();
anim_refs_.clear();
auto header_ = header{};
header_.magic = script_.read<u64>();
if (header_.magic != ctx_->magic())
throw disasm_error("invalid binary script file!");
header_.source_crc = script_.read<u32>();
header_.include_offset = script_.read<u32>();
header_.animtree_offset = script_.read<u32>();
header_.cseg_offset = script_.read<u32>();
header_.stringtablefixup_offset = script_.read<u32>();
if (ctx_->props() & props::version2)
header_.devblock_stringtablefixup_offset = script_.read<u32>();
header_.exports_offset = script_.read<u32>();
header_.imports_offset = script_.read<u32>();
header_.fixup_offset = script_.read<u32>();
header_.profile_offset = script_.read<u32>();
header_.cseg_size = script_.read<u32>();
if (ctx_->props() & props::version2)
header_.name = script_.read<u32>();
else
header_.name = script_.read<u16>();
header_.stringtablefixup_count = script_.read<u16>();
header_.exports_count = script_.read<u16>();
header_.imports_count = script_.read<u16>();
header_.fixup_count = script_.read<u16>();
header_.profile_count = script_.read<u16>();
if (ctx_->props() & props::version2)
header_.devblock_stringtablefixup_count = script_.read<u16>();
header_.include_count = script_.read<u8>();
header_.animtree_count = script_.read<u8>();
header_.flags = script_.read<u8>();
auto string_pool = std::map<u32, std::string>{};
script_.pos((ctx_->props() & props::version2) ? 72 : 64);
while (script_.pos() < header_.include_offset)
{
auto pos = script_.pos();
string_pool.insert({ pos, script_.read_cstr() });
}
script_.pos(header_.include_offset);
for (auto i = 0u; i < header_.include_count; i++)
{
assembly_->includes.push_back(string_pool.at(script_.read<u32>()));
}
script_.pos(header_.animtree_offset);
for (auto i = 0u; i < header_.animtree_count; i++)
{
auto entry = std::make_shared<animtree_ref>();
entry->name = string_pool.at(script_.read<u16>());
auto ref_count = script_.read<u16>();
auto anim_count = script_.read<u16>();
script_.seek(2);
for (auto j = 0u; j < ref_count; j++)
{
auto ref = script_.read<u32>();
entry->refs.push_back(ref);
anim_refs_.insert({ ref, entry });
}
for (auto j = 0u; j < anim_count; j++)
{
auto name = ctx_->hash_name(script_.read<u32>());
if (ctx_->props() & props::version2)
script_.seek(4);
auto ref = script_.read<u32>();
if (ctx_->props() & props::version2)
script_.seek(4);
entry->anims.push_back({ name, ref });
anim_refs_.insert({ ref, entry });
}
}
script_.pos(header_.stringtablefixup_offset);
for (auto i = 0u; i < header_.stringtablefixup_count; i++)
{
auto entry = std::make_shared<string_ref>();
entry->name = string_pool.at((ctx_->props() & props::version2) ? script_.read<u32>() : script_.read<u16>());
auto count = script_.read<u8>();
entry->type = script_.read<u8>();
if (ctx_->props() & props::version2)
script_.seek(2);
for (auto j = 0u; j < count; j++)
{
auto ref = script_.read<u32>();
string_refs_.insert({ ref, entry });
}
}
if (ctx_->props() & props::version2)
{
script_.pos(header_.devblock_stringtablefixup_offset);
for (auto i = 0u; i < header_.devblock_stringtablefixup_count; i++)
{
auto entry = std::make_shared<string_ref>();
entry->name = "DEVSTR";
script_.seek(4);
auto count = script_.read<u8>();
entry->type = script_.read<u8>();
script_.seek(2);
for (auto j = 0; j < count; j++)
{
auto ref = script_.read<u32>();
string_refs_.insert({ ref, entry });
}
}
}
script_.pos(header_.imports_offset);
for (auto i = 0u; i < header_.imports_count; i++)
{
auto entry = std::make_shared<import_ref>();
if (ctx_->props() & props::version2)
{
entry->name = ctx_->hash_name(script_.read<u32>());
entry->space = ctx_->hash_name(script_.read<u32>());
}
else
{
entry->name = string_pool.at(script_.read<u16>());
entry->space = string_pool.at(script_.read<u16>());
}
auto count = script_.read<u16>();
entry->params = script_.read<u8>();
entry->flags = script_.read<u8>();
for (auto j = 0; j < count; j++)
{
import_refs_.insert({ script_.read<u32>(), entry });
}
}
auto exports_ = std::vector<export_ref::ptr>{};
script_.pos(header_.exports_offset);
for (auto i = 0u; i < header_.exports_count; i++)
{
auto entry = std::make_shared<export_ref>();
entry->checksum = script_.read<u32>();
entry->offset = script_.read<u32>();
if (ctx_->props() & props::version2)
{
entry->name = ctx_->hash_name(script_.read<u32>());
entry->space = ctx_->hash_name(script_.read<u32>());
}
else
{
entry->name = string_pool.at(script_.read<u16>());
entry->space = "";
}
entry->params = script_.read<u8>();
entry->flags = script_.read<u8>();
if (ctx_->props() & props::version2)
script_.seek(2);
exports_.push_back(entry);
}
for (auto i = 0u; i < exports_.size(); i++)
{
auto& entry = exports_[i];
if (i < exports_.size() - 1)
{
entry->size = (exports_[i + 1]->offset - entry->offset);
auto pad_size = (ctx_->props() & props::version2) ? 8 : 4;
auto end_pos = entry->offset + entry->size - pad_size;
script_.pos(end_pos);
if ((ctx_->props() & props::version2) && script_.read<u64>() == 0)
entry->size -= pad_size;
else if (script_.read<u32>() == 0)
entry->size -= pad_size;
}
else
{
entry->size = (header_.cseg_offset + header_.cseg_size) - entry->offset;
}
script_.pos(entry->offset);
func_ = make_function();
func_->index = entry->offset;
func_->size = entry->size;
func_->params = entry->params;
func_->flags = entry->flags;
func_->name = entry->name;
func_->space = entry->space;
disassemble_function(*func_);
assembly_->functions.push_back(std::move(func_));
}
return std::move(assembly_);
}
auto disassembler::disassemble_function(function& func) -> void
{
auto size = static_cast<i32>(func.size);
while (size > 0)
{
auto inst = make_instruction();
inst->index = script_.pos();
if (ctx_->props() & props::version2)
{
auto index = script_.read<u16>();
if (size < 8 && (index >= 0x2000 || ctx_->opcode_enum(index) == opcode::OP_Invalid))
break;
if ((index & 0x2000) == 0)
inst->opcode = ctx_->opcode_enum(index);
else
throw disasm_error(utils::string::va("invalid opcode index 0x%X at pos '%04X'!", index, inst->index));
}
else
{
auto index = script_.read<u8>();
if (size < 4 && ctx_->opcode_enum(index) == opcode::OP_Invalid)
break;
inst->opcode = ctx_->opcode_enum(index);
}
inst->size = ctx_->opcode_size(inst->opcode);
disassemble_instruction(*inst);
if (ctx_->props() & props::version2)
inst->size += script_.align(2);
size -= inst->size;
func.instructions.push_back(std::move(inst));
}
for (auto i = func.instructions.size() - 1; i >= 1; i--)
{
auto& inst = func.instructions.at(i);
auto& last = func.instructions.at(i-1);
if (func.labels.contains(inst->index))
break;
if ((inst->opcode == opcode::OP_End || inst->opcode == opcode::OP_Return)
&& (last->opcode != opcode::OP_End && last->opcode != opcode::OP_Return))
break;
func.instructions.pop_back();
}
}
auto disassembler::disassemble_instruction(instruction& inst) -> void
{
switch (inst.opcode)
{
case opcode::OP_End:
case opcode::OP_Return:
case opcode::OP_GetUndefined:
case opcode::OP_GetZero:
case opcode::OP_GetLevelObject:
case opcode::OP_GetAnimObject:
case opcode::OP_GetSelf:
case opcode::OP_GetLevel:
case opcode::OP_GetGame:
case opcode::OP_GetAnim:
case opcode::OP_GetGameRef:
case opcode::OP_CreateLocalVariable:
case opcode::OP_EvalArray:
case opcode::OP_EvalArrayRef:
case opcode::OP_ClearArray:
case opcode::OP_EmptyArray:
case opcode::OP_GetSelfObject:
case opcode::OP_SafeSetVariableFieldCached:
case opcode::OP_ClearParams:
case opcode::OP_CheckClearParams:
case opcode::OP_SetVariableField:
case opcode::OP_Wait:
case opcode::OP_WaitTillFrameEnd:
case opcode::OP_PreScriptCall:
case opcode::OP_DecTop:
case opcode::OP_CastFieldObject:
case opcode::OP_CastBool:
case opcode::OP_BoolNot:
case opcode::OP_BoolComplement:
case opcode::OP_Inc:
case opcode::OP_Dec:
case opcode::OP_Bit_Or:
case opcode::OP_Bit_Xor:
case opcode::OP_Bit_And:
case opcode::OP_Equal:
case opcode::OP_NotEqual:
case opcode::OP_LessThan:
case opcode::OP_GreaterThan:
case opcode::OP_LessThanOrEqualTo:
case opcode::OP_GreaterThanOrEqualTo:
case opcode::OP_ShiftLeft:
case opcode::OP_ShiftRight:
case opcode::OP_Plus:
case opcode::OP_Minus:
case opcode::OP_Multiply:
case opcode::OP_Divide:
case opcode::OP_Modulus:
case opcode::OP_SizeOf:
case opcode::OP_WaitTill:
case opcode::OP_Notify:
case opcode::OP_EndOn:
case opcode::OP_VoidCodePos:
case opcode::OP_Vector:
case opcode::OP_RealWait:
case opcode::OP_IsDefined:
case opcode::OP_VectorScale:
case opcode::OP_AnglesToUp:
case opcode::OP_AnglesToRight:
case opcode::OP_AnglesToForward:
case opcode::OP_AngleClamp180:
case opcode::OP_VectorToAngles:
case opcode::OP_Abs:
case opcode::OP_GetTime:
case opcode::OP_GetDvar:
case opcode::OP_GetDvarInt:
case opcode::OP_GetDvarFloat:
case opcode::OP_GetDvarVector:
case opcode::OP_GetDvarColorRed:
case opcode::OP_GetDvarColorGreen:
case opcode::OP_GetDvarColorBlue:
case opcode::OP_GetDvarColorAlpha:
case opcode::OP_FirstArrayKey:
case opcode::OP_NextArrayKey:
//case opcode::OP_ProfileStart:
case opcode::OP_ProfileStop:
case opcode::OP_SafeDecTop:
case opcode::OP_Nop:
case opcode::OP_Abort:
case opcode::OP_Object:
case opcode::OP_ThreadObject:
case opcode::OP_EvalLocalVariable:
case opcode::OP_EvalLocalVariableRef:
case opcode::OP_GetClassesObject:
case opcode::OP_GetClasses:
case opcode::OP_GetWorldObject:
case opcode::OP_GetWorld:
case opcode::OP_SuperEqual:
case opcode::OP_SuperNotEqual:
break;
case opcode::OP_GetByte:
case opcode::OP_GetNegByte:
inst.data.push_back(fmt::format("{}", script_.read<u8>()));
break;
case opcode::OP_GetUnsignedShort:
case opcode::OP_GetNegUnsignedShort:
inst.size += script_.align(2);
inst.data.push_back(fmt::format("{}", script_.read<u16>()));
break;
case opcode::OP_GetInteger:
inst.size += script_.align(4);
disassemble_animtree(inst);
inst.data.push_back(fmt::format("{}", script_.read<i32>()));
break;
case opcode::OP_GetFloat:
inst.size += script_.align(4);
inst.data.push_back(utils::string::float_string(script_.read<f32>()));
break;
case opcode::OP_GetUintptr:
//case opcode::OP_ProfileStart:
case opcode::OP_GetAPIFunction:
inst.size += script_.align(8);
inst.data.push_back(fmt::format("0x{:016X}", script_.read<u64>()));
break;
case opcode::OP_GetVector:
inst.size += script_.align(4);
inst.data.push_back(utils::string::float_string(script_.read<f32>()));
inst.data.push_back(utils::string::float_string(script_.read<f32>()));
inst.data.push_back(utils::string::float_string(script_.read<f32>()));
break;
case opcode::OP_GetString:
case opcode::OP_GetIString:
disassemble_string(inst);
break;
case opcode::OP_GetAnimation:
disassemble_animation(inst);
break;
case opcode::OP_WaitTillMatch:
inst.data.push_back(fmt::format("{}", script_.read<u8>()));
break;
case opcode::OP_VectorConstant:
inst.data.push_back(fmt::format("{}", script_.read<u8>()));
break;
case opcode::OP_GetHash:
inst.size += script_.align(4);
inst.data.push_back(ctx_->dvar_name(script_.read<u32>()));
break;
case opcode::OP_ScriptFunctionCallClass:
case opcode::OP_ScriptThreadCallClass:
script_.seek(1);
inst.size += script_.align(4);
inst.data.push_back(ctx_->hash_name(script_.read<u32>()));
break;
case opcode::OP_SafeCreateLocalVariables:
disassemble_params(inst);
break;
case opcode::OP_RemoveLocalVariables:
case opcode::OP_EvalLocalVariableCached:
case opcode::OP_EvalLocalArrayRefCached:
case opcode::OP_SafeSetWaittillVariableFieldCached:
case opcode::OP_EvalLocalVariableRefCached:
inst.data.push_back(fmt::format("{}", script_.read<u8>()));
break;
case opcode::OP_EvalFieldVariable:
case opcode::OP_EvalFieldVariableRef:
case opcode::OP_ClearFieldVariable:
case opcode::OP_EvalLocalVariableCachedDebug:
case opcode::OP_EvalLocalVariableRefCachedDebug:
case opcode::OP_LevelEvalFieldVariableRef:
case opcode::OP_LevelEvalFieldVariable:
case opcode::OP_SelfEvalFieldVariableRef:
case opcode::OP_SelfEvalFieldVariable:
case opcode::OP_New:
disassemble_name(inst);
break;
case opcode::OP_ScriptFunctionCallPointer:
case opcode::OP_ScriptMethodCallPointer:
case opcode::OP_ScriptThreadCallPointer:
case opcode::OP_ScriptMethodThreadCallPointer:
inst.data.push_back(fmt::format("{}", script_.read<u8>()));
break;
case opcode::OP_GetFunction:
disassemble_import(inst);
break;
case opcode::OP_CallBuiltin:
case opcode::OP_CallBuiltinMethod:
case opcode::OP_ScriptFunctionCall:
case opcode::OP_ScriptMethodCall:
case opcode::OP_ScriptThreadCall:
case opcode::OP_ScriptMethodThreadCall:
script_.seek(1);
disassemble_import(inst);
break;
case opcode::OP_JumpOnFalse:
case opcode::OP_JumpOnTrue:
case opcode::OP_JumpOnFalseExpr:
case opcode::OP_JumpOnTrueExpr:
case opcode::OP_Jump:
case opcode::OP_JumpBack:
case opcode::OP_DevblockBegin:
disassemble_jump(inst);
break;
case opcode::OP_Switch:
disassemble_switch(inst);
break;
case opcode::OP_EndSwitch:
disassemble_end_switch(inst);
break;
default:
throw disasm_error(fmt::format("unhandled opcode {} at index {:04X}", ctx_->opcode_name(inst.opcode), inst.index));
}
}
auto disassembler::disassemble_name(instruction& inst) -> void
{
inst.size += script_.align((ctx_->props() & props::version2) ? 4 : 2);
if (ctx_->props() & props::version2)
{
inst.data.push_back(ctx_->hash_name(script_.read<u32>()));
}
else
{
auto const itr = string_refs_.find(script_.pos());
if (itr != string_refs_.end())
{
inst.data.push_back(itr->second->name);
script_.seek(2);
return;
}
throw disasm_error(fmt::format("string reference not found at index {:04X}", inst.index));
}
}
auto disassembler::disassemble_params(instruction& inst) -> void
{
auto const count = script_.read<u8>();
for (auto i = 0u; i < count; i++)
{
if (ctx_->props() & props::version2)
{
inst.size += script_.align(4) + 5;
inst.data.push_back(ctx_->hash_name(script_.read<u32>()));
script_.seek(1);
}
else
{
disassemble_string(inst);
inst.size += 2;
}
}
}
auto disassembler::disassemble_import(instruction& inst) -> void
{
inst.size += script_.align((ctx_->props() & props::version2) ? 8 : 4);
script_.seek((ctx_->props() & props::version2) ? 8 : 4);
auto const itr = import_refs_.find(inst.index);
if (itr != import_refs_.end())
{
inst.data.push_back(itr->second->space);
inst.data.push_back(itr->second->name);
return;
}
throw disasm_error(fmt::format("import reference not found at index {:04X}", inst.index));
}
auto disassembler::disassemble_string(instruction& inst) -> void
{
inst.size += script_.align((ctx_->props() & props::version2) ? 4 : 2);
auto const itr = string_refs_.find(script_.pos());
if (itr != string_refs_.end())
{
inst.data.push_back(itr->second->name);
script_.seek((ctx_->props() & props::version2) ? 4 : 2);
return;
}
throw disasm_error(fmt::format("string reference not found at index {:04X}", inst.index));
}
auto disassembler::disassemble_animtree(instruction& inst) -> void
{
auto const itr = anim_refs_.find(script_.pos());
if (itr != anim_refs_.end())
{
inst.data.push_back(itr->second->name);
}
}
auto disassembler::disassemble_animation(instruction& inst) -> void
{
inst.size += script_.align((ctx_->props() & props::version2) ? 8 : 4);
auto const ref = script_.pos();
auto const itr = anim_refs_.find(ref);
if (itr != anim_refs_.end())
{
inst.data.push_back(itr->second->name);
for (auto const& anim : itr->second->anims)
{
if (anim.ref == ref)
{
inst.data.push_back(anim.name);
script_.seek((ctx_->props() & props::version2) ? 8 : 4);
return;
}
}
}
throw disasm_error(fmt::format("animation reference not found at index {:04X}", inst.index));
}
auto disassembler::disassemble_jump(instruction& inst) -> void
{
inst.size += script_.align(2);
auto addr = u32{};
if (ctx_->props() & props::version2)
addr = ((script_.read<i16>() + 1) & ~(1)) + script_.pos();
else
addr = script_.read<i16>() + script_.pos();
auto const label = fmt::format("loc_{:X}", addr);
inst.data.push_back(label);
func_->labels.insert({ addr, label });
}
auto disassembler::disassemble_switch(instruction& inst) -> void
{
inst.size += script_.align(4);
auto const addr = script_.read<i32>() + script_.pos();
auto const label = fmt::format("loc_{:X}", addr);
inst.data.push_back(label);
func_->labels.insert({ addr, label });
}
auto disassembler::disassemble_end_switch(instruction& inst) -> void
{
inst.size += script_.align(4);
auto const itr = func_->labels.find(script_.pos());
if (itr != func_->labels.end())
{
for (auto const& entry : func_->instructions)
{
if (entry->opcode == opcode::OP_Switch && entry->data[0] == itr->second)
{
auto const label = fmt::format("loc_{:X}", inst.index);
entry->data[0] = label;
func_->labels.erase(script_.pos());
if (!func_->labels.contains(inst.index))
{
func_->labels.insert({ inst.index, label });
}
break;
}
}
}
auto type = switch_type::none;
auto const count = script_.read<u32>();
inst.data.push_back(fmt::format("{}", count));
for (auto i = 0u; i < count; i++)
{
if (ctx_->props() & props::version2)
{
const auto value = script_.read<u32>();
const auto itr = string_refs_.find(script_.pos() - 4);
if (itr != string_refs_.end())
{
type = switch_type::string;
inst.data.push_back("case");
inst.data.push_back(itr->second->name);
}
else if (value == 0 && i == count - 1)
{
inst.data.push_back("default");
}
else
{
type = switch_type::integer;
inst.data.push_back("case");
inst.data.push_back(fmt::format("{}", value));
}
}
else
{
auto const value = script_.read<u32>();
if (value == 0)
{
inst.data.push_back("default");
}
else if (value < 0x40000)
{
type = switch_type::string;
inst.data.push_back("case");
inst.data.push_back(string_refs_.at(script_.pos() - 2)->name);
}
else
{
type = switch_type::integer;
inst.data.push_back("case");
inst.data.push_back(fmt::format("{}", (value - 0x800000) & 0xFFFFFF));
}
}
auto const addr = script_.read<i32>() + script_.pos();
auto const label = fmt::format("loc_{:X}", addr);
inst.data.push_back(label);
func_->labels.insert({ addr, label });
inst.size += 8;
}
inst.data.push_back(fmt::format("{}", static_cast<std::underlying_type_t<switch_type>>(type)));
}
} // namespace xsk::arc

32
src/arc/engine/t6.cpp Normal file
View File

@ -0,0 +1,32 @@
// Copyright 2023 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 "xsk/arc/engine/t6.hpp"
namespace xsk::arc::t6
{
extern std::array<std::pair<u8, opcode>, code_count> const code_list;
extern std::array<std::pair<u32, char const*>, dvar_count> const dvar_list;
context::context() : arc::context(props::none, engine::t6, endian::little, system::pc, header_magic)
{
code_map_.reserve(code_list.size());
code_map_rev_.reserve(code_list.size());
dvar_map_.reserve(dvar_list.size());
for (auto const& entry : code_list)
{
code_map_.insert({ entry.first, entry.second });
code_map_rev_.insert({ entry.second, entry.first });
}
for (auto const& entry : dvar_list)
{
dvar_map_.insert({ entry.first, entry.second });
}
}
} // namespace xsk::arc::t6

140
src/arc/engine/t6_code.cpp Normal file
View File

@ -0,0 +1,140 @@
// Copyright 2023 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 "xsk/arc/engine/t6.hpp"
namespace xsk::arc::t6
{
extern std::array<std::pair<u8, opcode>, code_count> const code_list
{{
{ 0x00, opcode::OP_End },
{ 0x01, opcode::OP_Return },
{ 0x02, opcode::OP_GetUndefined },
{ 0x03, opcode::OP_GetZero },
{ 0x04, opcode::OP_GetByte },
{ 0x05, opcode::OP_GetNegByte },
{ 0x06, opcode::OP_GetUnsignedShort },
{ 0x07, opcode::OP_GetNegUnsignedShort },
{ 0x08, opcode::OP_GetInteger },
{ 0x09, opcode::OP_GetFloat },
{ 0x0A, opcode::OP_GetString },
{ 0x0B, opcode::OP_GetIString },
{ 0x0C, opcode::OP_GetVector },
{ 0x0D, opcode::OP_GetLevelObject },
{ 0x0E, opcode::OP_GetAnimObject },
{ 0x0F, opcode::OP_GetSelf },
{ 0x10, opcode::OP_GetLevel },
{ 0x11, opcode::OP_GetGame },
{ 0x12, opcode::OP_GetAnim },
{ 0x13, opcode::OP_GetAnimation },
{ 0x14, opcode::OP_GetGameRef },
{ 0x15, opcode::OP_GetFunction },
{ 0x16, opcode::OP_CreateLocalVariable },
{ 0x17, opcode::OP_SafeCreateLocalVariables },
{ 0x18, opcode::OP_RemoveLocalVariables },
{ 0x19, opcode::OP_EvalLocalVariableCached },
{ 0x1A, opcode::OP_EvalArray },
{ 0x1B, opcode::OP_EvalLocalArrayRefCached },
{ 0x1C, opcode::OP_EvalArrayRef },
{ 0x1D, opcode::OP_ClearArray },
{ 0x1E, opcode::OP_EmptyArray },
{ 0x1F, opcode::OP_GetSelfObject },
{ 0x20, opcode::OP_EvalFieldVariable },
{ 0x21, opcode::OP_EvalFieldVariableRef },
{ 0x22, opcode::OP_ClearFieldVariable },
{ 0x23, opcode::OP_SafeSetVariableFieldCached },
{ 0x24, opcode::OP_SafeSetWaittillVariableFieldCached },
{ 0x25, opcode::OP_ClearParams },
{ 0x26, opcode::OP_CheckClearParams },
{ 0x27, opcode::OP_EvalLocalVariableRefCached },
{ 0x28, opcode::OP_SetVariableField },
{ 0x29, opcode::OP_CallBuiltin },
{ 0x2A, opcode::OP_CallBuiltinMethod },
{ 0x2B, opcode::OP_Wait },
{ 0x2C, opcode::OP_WaitTillFrameEnd },
{ 0x2D, opcode::OP_PreScriptCall },
{ 0x2E, opcode::OP_ScriptFunctionCall },
{ 0x2F, opcode::OP_ScriptFunctionCallPointer },
{ 0x30, opcode::OP_ScriptMethodCall },
{ 0x31, opcode::OP_ScriptMethodCallPointer },
{ 0x32, opcode::OP_ScriptThreadCall },
{ 0x33, opcode::OP_ScriptThreadCallPointer },
{ 0x34, opcode::OP_ScriptMethodThreadCall },
{ 0x35, opcode::OP_ScriptMethodThreadCallPointer },
{ 0x36, opcode::OP_DecTop },
{ 0x37, opcode::OP_CastFieldObject },
{ 0x38, opcode::OP_CastBool },
{ 0x39, opcode::OP_BoolNot },
{ 0x3A, opcode::OP_BoolComplement },
{ 0x3B, opcode::OP_JumpOnFalse },
{ 0x3C, opcode::OP_JumpOnTrue },
{ 0x3D, opcode::OP_JumpOnFalseExpr },
{ 0x3E, opcode::OP_JumpOnTrueExpr },
{ 0x3F, opcode::OP_Jump },
{ 0x40, opcode::OP_JumpBack },
{ 0x41, opcode::OP_Inc },
{ 0x42, opcode::OP_Dec },
{ 0x43, opcode::OP_Bit_Or },
{ 0x44, opcode::OP_Bit_Xor },
{ 0x45, opcode::OP_Bit_And },
{ 0x46, opcode::OP_Equal },
{ 0x47, opcode::OP_NotEqual },
{ 0x48, opcode::OP_LessThan },
{ 0x49, opcode::OP_GreaterThan },
{ 0x4A, opcode::OP_LessThanOrEqualTo },
{ 0x4B, opcode::OP_GreaterThanOrEqualTo },
{ 0x4C, opcode::OP_ShiftLeft },
{ 0x4D, opcode::OP_ShiftRight },
{ 0x4E, opcode::OP_Plus },
{ 0x4F, opcode::OP_Minus },
{ 0x50, opcode::OP_Multiply },
{ 0x51, opcode::OP_Divide },
{ 0x52, opcode::OP_Modulus },
{ 0x53, opcode::OP_SizeOf },
{ 0x54, opcode::OP_WaitTillMatch },
{ 0x55, opcode::OP_WaitTill },
{ 0x56, opcode::OP_Notify },
{ 0x57, opcode::OP_EndOn },
{ 0x58, opcode::OP_VoidCodePos },
{ 0x59, opcode::OP_Switch },
{ 0x5A, opcode::OP_EndSwitch },
{ 0x5B, opcode::OP_Vector },
{ 0x5C, opcode::OP_GetHash },
{ 0x5D, opcode::OP_RealWait },
{ 0x5E, opcode::OP_VectorConstant },
{ 0x5F, opcode::OP_IsDefined },
{ 0x60, opcode::OP_VectorScale },
{ 0x61, opcode::OP_AnglesToUp },
{ 0x62, opcode::OP_AnglesToRight },
{ 0x63, opcode::OP_AnglesToForward },
{ 0x64, opcode::OP_AngleClamp180 },
{ 0x65, opcode::OP_VectorToAngles },
{ 0x66, opcode::OP_Abs },
{ 0x67, opcode::OP_GetTime },
{ 0x68, opcode::OP_GetDvar },
{ 0x69, opcode::OP_GetDvarInt },
{ 0x6A, opcode::OP_GetDvarFloat },
{ 0x6B, opcode::OP_GetDvarVector },
{ 0x6C, opcode::OP_GetDvarColorRed },
{ 0x6D, opcode::OP_GetDvarColorGreen },
{ 0x6E, opcode::OP_GetDvarColorBlue },
{ 0x6F, opcode::OP_GetDvarColorAlpha },
{ 0x70, opcode::OP_FirstArrayKey },
{ 0x71, opcode::OP_NextArrayKey },
{ 0x72, opcode::OP_ProfileStart },
{ 0x73, opcode::OP_ProfileStop },
{ 0x74, opcode::OP_SafeDecTop },
{ 0x75, opcode::OP_Nop },
{ 0x76, opcode::OP_Abort },
{ 0x77, opcode::OP_Object },
{ 0x78, opcode::OP_ThreadObject },
{ 0x79, opcode::OP_EvalLocalVariable },
{ 0x7A, opcode::OP_EvalLocalVariableRef },
{ 0x7B, opcode::OP_DevblockBegin },
{ 0x7C, opcode::OP_DevblockEnd },
}};
} // namespace xsk::arc::t6

3341
src/arc/engine/t6_dvar.cpp Normal file

File diff suppressed because it is too large Load Diff

39
src/arc/engine/t7.cpp Normal file
View File

@ -0,0 +1,39 @@
// Copyright 2023 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 "xsk/arc/engine/t7.hpp"
namespace xsk::arc::t7
{
extern std::array<std::pair<u16, opcode>, code_count> const code_list;
extern std::array<std::pair<u32, char const*>, dvar_count> const dvar_list;
extern std::array<std::pair<u32, char const*>, hash_count> const hash_list;
context::context() : arc::context(props::version2, engine::t7, endian::little, system::pc, header_magic)
{
code_map_.reserve(code_list.size());
code_map_rev_.reserve(code_list.size());
dvar_map_.reserve(dvar_list.size());
hash_map_.reserve(dvar_list.size());
for (auto const& entry : code_list)
{
code_map_.insert({ entry.first, entry.second });
code_map_rev_.insert({ entry.second, entry.first });
}
for (auto const& entry : dvar_list)
{
dvar_map_.insert({ entry.first, entry.second });
}
for (auto const& entry : hash_list)
{
hash_map_.insert({ entry.first, entry.second });
}
}
} // namespace xsk::arc::t7

8207
src/arc/engine/t7_code.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
// Copyright 2023 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 "xsk/arc/engine/t7.hpp"
namespace xsk::arc::t7
{
extern std::array<std::pair<u32, char const*>, dvar_count> const dvar_list
{{
}};
} // namespace xsk::arc::t7

178732
src/arc/engine/t7_hash.cpp Normal file

File diff suppressed because it is too large Load Diff

1771
src/arc/source.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,9 @@
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.
#include <stdinc.hpp>
#include "assembler.hpp"
#include "context.hpp"
#include "xsk/stdinc.hpp"
#include "xsk/gsc/assembler.hpp"
#include "xsk/gsc/context.hpp"
namespace xsk::gsc
{

Some files were not shown because too many files have changed in this diff Show More