From e0a0c4882f55bc15c832b1a70961c36a7da54e8d Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Mon, 21 Jul 2014 00:34:28 +0100 Subject: [PATCH] Refactor Script loading into engine --- rwengine/include/script/SCMFile.hpp | 79 ++++++++ rwengine/include/script/ScriptMachine.hpp | 87 ++++++++ rwengine/src/script/SCMFile.cpp | 43 ++++ rwengine/src/script/ScriptMachine.cpp | 0 scripttool/CMakeLists.txt | 2 + scripttool/main.cpp | 230 +++++----------------- 6 files changed, 255 insertions(+), 186 deletions(-) create mode 100644 rwengine/include/script/SCMFile.hpp create mode 100644 rwengine/include/script/ScriptMachine.hpp create mode 100644 rwengine/src/script/SCMFile.cpp create mode 100644 rwengine/src/script/ScriptMachine.cpp diff --git a/rwengine/include/script/SCMFile.hpp b/rwengine/include/script/SCMFile.hpp new file mode 100644 index 00000000..1fb53d71 --- /dev/null +++ b/rwengine/include/script/SCMFile.hpp @@ -0,0 +1,79 @@ +#pragma once +#ifndef _SCMFILE_HPP_ +#define _SCMFILE_HPP_ +#include +#include +#include + +typedef uint16_t SCMOpcode; +typedef char SCMByte; + +/** + * @brief Handles in-memory SCM file data including section offsets. + */ +class SCMFile { +public: + + typedef std::uint32_t uint32; + typedef std::uint16_t u16; + typedef std::uint8_t u8; + + enum SCMTarget { + NoTarget = 0, + GTAIII = 0xC6, + GTAVC = 0x6D, + GTASA = 0x73 + }; + + SCMFile() + : _data(nullptr), _target(NoTarget), mainOffset(0), + mainSize(0), missionLargestSize(0) + {} + + ~SCMFile() + { + delete[] _data; + } + + void loadFile(char* data, unsigned int size); + + SCMByte* data() const { return _data; } + + template T read(unsigned int offset) const + { + return *(T*)(_data+offset); + } + + uint32 getMainSize() const { return mainSize; } + uint32 getLargestMissionSize() const { return missionLargestSize; } + + const std::vector& getModels() const { return models; } + + const std::vector& getMissionOffsets() const { return missionOffsets; } + + std::uint32_t getGlobalSection() const { return globalSectionOffset; } + std::uint32_t getModelSection() const { return modelSectionOffset; } + std::uint32_t getMissionSection() const { return missionSectionOffset; } + std::uint32_t getCodeSection() const { return codeSectionOffset; } + +private: + + SCMByte* _data; + + SCMTarget _target; + + std::vector models; + + uint32 mainOffset; + std::vector missionOffsets; + + uint32 mainSize; + uint32 missionLargestSize; + + uint32 globalSectionOffset; + uint32 modelSectionOffset; + uint32 missionSectionOffset; + uint32 codeSectionOffset; +}; + +#endif diff --git a/rwengine/include/script/ScriptMachine.hpp b/rwengine/include/script/ScriptMachine.hpp new file mode 100644 index 00000000..53905746 --- /dev/null +++ b/rwengine/include/script/ScriptMachine.hpp @@ -0,0 +1,87 @@ +#pragma once +#ifndef _SCRIPTMACHINE_HPP_ +#define _SCRIPTMACHINE_HPP_ +#include +#include + +#define SCM_CONDITIONAL_MASK 0xF000 + +struct SCMException +{ + virtual ~SCMException() { } + virtual std::string what() const = 0; +}; + +struct IllegalInstruction : SCMException +{ + SCMOpcode opcode; + unsigned int offset; + + IllegalInstruction(SCMOpcode opcode, unsigned int offset) + : opcode(opcode), offset(offset) { } + + std::string what() const { + std::stringstream ss; + ss << "Illegal Instruction " << + std::setfill('0') << std::setw(4) << std::hex << opcode << + " encountered at offset " << + std::setfill('0') << std::setw(4) << std::hex << offset; + return ss.str(); + } +}; + +struct UnknownType : SCMException +{ + SCMByte type; + unsigned int offset; + + UnknownType(SCMByte type, unsigned int offset) + : type(type), offset(offset) {} + + std::string what() const { + std::stringstream ss; + ss << "Unkown data type " << + std::setfill('0') << std::hex << static_cast(type) << + " encountered at offset " << + std::setfill('0') << std::hex << offset; + return ss.str(); + } +}; + +struct SCMMicrocode { + std::string name; + int parameters; +}; + +typedef std::map SCMMicrocodeTable; + +SCMMicrocodeTable knownOps; + +enum SCMType { + EndOfArgList = 0x00, + TInt32 = 0x01, + TGlobal = 0x02, + TLocal = 0x03, + TInt8 = 0x04, + TInt16 = 0x05, + TFloat16 = 0x06, + TString = 0x09, +}; + +struct SCMTypeInfo { + uint8_t size; +}; + +typedef std::map SCMTypeInfoTable; + +SCMTypeInfoTable typeData = { + {TInt8, {1}}, + {TInt16, {2}}, + {TInt32, {4}}, + {TGlobal, {2}}, + {TLocal, {2}}, + {TFloat16,{2}}, + {EndOfArgList, {0}}, +}; + +#endif diff --git a/rwengine/src/script/SCMFile.cpp b/rwengine/src/script/SCMFile.cpp new file mode 100644 index 00000000..e806e3e4 --- /dev/null +++ b/rwengine/src/script/SCMFile.cpp @@ -0,0 +1,43 @@ +#include