mirror of
https://github.com/odiecay/chronicle-ps4.git
synced 2026-10-17 11:01:28 +02:00
359 lines
11 KiB
C++
359 lines
11 KiB
C++
#pragma once
|
|
|
|
#include "common.h"
|
|
|
|
/**
|
|
* Opcodes of the script virtual machine, as vmcode_t::op holds them.
|
|
*/
|
|
// clang-format off
|
|
enum RS_OPCODE {
|
|
RS_OP_LOAD = 1, /**< Push a variable. */
|
|
RS_OP_LOAD_ADDR = 2, /**< Push a variable's address. */
|
|
RS_OP_PUSH_CONST = 3, /**< Push a constant. */
|
|
RS_OP_POP = 4, /**< Pop. */
|
|
RS_OP_STORE = 5, /**< Store. */
|
|
RS_OP_ADD = 6, /**< Add. */
|
|
RS_OP_SUB = 7, /**< Subtract. */
|
|
RS_OP_MUL = 8, /**< Multiply. */
|
|
RS_OP_DIV = 9, /**< Divide. */
|
|
RS_OP_MOD = 10, /**< Remainder. */
|
|
RS_OP_NEG = 11, /**< Negate. */
|
|
RS_OP_ITOF = 12, /**< Integer to float. */
|
|
RS_OP_FTOI = 13, /**< Float to integer. */
|
|
RS_OP_CMP = 14, /**< Compare. */
|
|
RS_OP_RET = 15, /**< Return. */
|
|
RS_OP_JMP = 16, /**< Jump. */
|
|
RS_OP_JMP_FALSE = 17, /**< Jump if false. */
|
|
RS_OP_JMP_TRUE = 18, /**< Jump if true. */
|
|
RS_OP_CALL = 19, /**< Call. */
|
|
RS_OP_PRINT = 20, /**< Print. */
|
|
RS_OP_EXT = 21, /**< Call an external function. */
|
|
RS_OP_WAIT = 23, /**< Wait. */
|
|
RS_OP_AND = 24, /**< Logical and. */
|
|
RS_OP_OR = 25, /**< Logical or. */
|
|
RS_OP_NOT = 26, /**< Logical not. */
|
|
RS_OP_END = 27, /**< End. */
|
|
RS_OP_SKIP_END = 28, /**< Clear the skip wait. */
|
|
RS_OP_SIN = 29, /**< Sine. */
|
|
RS_OP_COS = 30, /**< Cosine. */
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
/**
|
|
* How a script load addresses its variable, as vmcode_t::arg2 holds it.
|
|
*/
|
|
// clang-format off
|
|
enum RS_ADDR_MODE {
|
|
RS_ADDR_LOCAL = 1, /**< Local slot. */
|
|
RS_ADDR_LOCAL_INDEX = 2, /**< Indexed local slot. */
|
|
RS_ADDR_POINTER_INDEX = 4, /**< Indexed through a pointer. */
|
|
RS_ADDR_LOCAL_FLOAT = 8, /**< Local slot, as a float. */
|
|
RS_ADDR_LOCAL_INDEX_FLOAT = 16, /**< Indexed local slot, as a float. */
|
|
RS_ADDR_POINTER_INDEX_FLOAT = 32, /**< Indexed through a pointer, as a float. */
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
/**
|
|
* Comparisons of the script compare opcode, as vmcode_t::arg1 holds them.
|
|
*/
|
|
// clang-format off
|
|
enum RS_COMPARE {
|
|
RS_CMP_EQ = 40, /**< Equal. */
|
|
RS_CMP_NE = 41, /**< Not equal. */
|
|
RS_CMP_LT = 42, /**< Less than. */
|
|
RS_CMP_LE = 43, /**< Less than or equal. */
|
|
RS_CMP_GT = 44, /**< Greater than. */
|
|
RS_CMP_GE = 45, /**< Greater than or equal. */
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
/**
|
|
* A tagged value stored on the script interpreter's operand stack.
|
|
*/
|
|
struct RS_STACKDATA {
|
|
int type; /**< Identifies the active value representation. */
|
|
|
|
union {
|
|
int i; /**< Value of an integer. */
|
|
float f; /**< Value of a float. */
|
|
char *s; /**< Value of a string. */
|
|
RS_STACKDATA *p; /**< Stack slot a reference points at. */
|
|
};
|
|
};
|
|
|
|
enum {
|
|
RS_INT = 0,
|
|
RS_FLOAT = 1,
|
|
RS_STR = 2,
|
|
RS_PTR = 3
|
|
};
|
|
|
|
/**
|
|
* A single virtual-machine instruction and its two opcode-specific operands.
|
|
*/
|
|
struct vmcode_t {
|
|
int op; /**< Selects the operation to execute. @see RS_OPCODE. */
|
|
int arg1; /**< Supplies the operation's first operand. */
|
|
int arg2; /**< Supplies the operation's second operand. */
|
|
};
|
|
|
|
/**
|
|
* Describes a script function's code position and stack-frame requirements.
|
|
*/
|
|
struct funcdata {
|
|
int addr; /**< Stores the function's offset in the code block. */
|
|
char *name; /**< Names the function for runtime diagnostics. */
|
|
int local; /**< Gives the total number of frame slots. */
|
|
int arg; /**< Gives the number of argument slots. */
|
|
};
|
|
|
|
/**
|
|
* Preserves interpreter state for a suspended script call.
|
|
*/
|
|
struct RS_CALLDATA {
|
|
vmcode_t *ret; /**< Points to the caller's return instruction. */
|
|
RS_STACKDATA *frame; /**< Points to the caller's stack frame. */
|
|
funcdata *func; /**< Describes the caller's function. */
|
|
};
|
|
|
|
/**
|
|
* Maps an external program number to its function description.
|
|
*/
|
|
struct RS_PROGDATA {
|
|
int no; /**< Identifies the externally selectable program. */
|
|
int func; /**< Stores the function-description offset. */
|
|
};
|
|
|
|
/**
|
|
* Describes the offset-based sections of a compiled script program.
|
|
*/
|
|
struct RS_PROG_HEADER {
|
|
int unk_0;
|
|
int main; /**< Stores the main function-description offset. */
|
|
int code; /**< Stores the bytecode-section offset. */
|
|
int prog; /**< Stores the program-table offset. */
|
|
int prog_num; /**< Gives the number of program-table entries. */
|
|
};
|
|
|
|
/**
|
|
* Runs one compiled script on a stack machine, suspending at its waits.
|
|
*/
|
|
class CRunScript {
|
|
public:
|
|
int ext_func_num; /**< Gives the number of registered external functions. */
|
|
int (**ext_func_table)(RS_STACKDATA *, int); /**< Points to the external function table. */
|
|
int stack_num; /**< Gives the operand stack capacity. */
|
|
RS_STACKDATA *stack; /**< Points to the operand stack storage. */
|
|
RS_STACKDATA *sp; /**< Points to the next operand stack slot. */
|
|
RS_STACKDATA *stack_end; /**< Points one past the operand stack storage. */
|
|
int call_num; /**< Gives the call stack capacity. */
|
|
RS_CALLDATA *call; /**< Points to the call stack storage. */
|
|
RS_CALLDATA *call_sp; /**< Points to the next call stack entry. */
|
|
RS_CALLDATA *call_end; /**< Points one past the call stack storage. */
|
|
RS_STACKDATA *frame; /**< Points to the active operand frame. */
|
|
funcdata *func; /**< Describes the active script function. */
|
|
vmcode_t *pc; /**< Points to the next instruction. */
|
|
int end; /**< Records whether execution has completed. */
|
|
int skip_wait; /**< Records whether wait operations should be skipped. */
|
|
RS_PROG_HEADER *prog; /**< Points to the loaded program header. */
|
|
char *code; /**< Points to the loaded bytecode section. */
|
|
int result; /**< Stores the script's return value. */
|
|
|
|
/**
|
|
* Nonzero once the script has run to its end.
|
|
*/
|
|
int IsEnd() { return end; }
|
|
|
|
/**
|
|
* Makes an interpreter with no program, stack or external functions.
|
|
*
|
|
* @mangled __ct__10CRunScriptFv
|
|
* @address 0x23D940
|
|
* @size 0x40
|
|
*/
|
|
CRunScript();
|
|
|
|
/**
|
|
* Stops the game when the operand stack is full.
|
|
*
|
|
* @mangled check_stack__10CRunScriptFv
|
|
* @address 0x23D980
|
|
* @size 0x34
|
|
* @unknownret
|
|
*/
|
|
void check_stack();
|
|
|
|
/**
|
|
* Pushes one value onto the operand stack.
|
|
*
|
|
* @mangled push__10CRunScriptF12RS_STACKDATA
|
|
* @address 0x23D9C0
|
|
* @size 0x50
|
|
* @unknownret
|
|
*/
|
|
void push(RS_STACKDATA value);
|
|
|
|
/**
|
|
* Pushes an integer onto the operand stack.
|
|
*
|
|
* @mangled push_int__10CRunScriptFi
|
|
* @address 0x23DA10
|
|
* @size 0x50
|
|
* @unknownret
|
|
*/
|
|
void push_int(int value);
|
|
|
|
/**
|
|
* Pushes a string onto the operand stack.
|
|
*
|
|
* @mangled push_str__10CRunScriptFPc
|
|
* @address 0x23DA60
|
|
* @size 0x54
|
|
* @unknownret
|
|
*/
|
|
void push_str(char *string);
|
|
|
|
/**
|
|
* Pushes a reference to a stack slot onto the operand stack.
|
|
*
|
|
* @mangled push_ptr__10CRunScriptFP12RS_STACKDATA
|
|
* @address 0x23DAC0
|
|
* @size 0x54
|
|
* @unknownret
|
|
*/
|
|
void push_ptr(RS_STACKDATA *pointer);
|
|
|
|
/**
|
|
* Pushes a float onto the operand stack.
|
|
*
|
|
* @mangled push_float__10CRunScriptFf
|
|
* @address 0x23DB20
|
|
* @size 0x54
|
|
* @unknownret
|
|
*/
|
|
void push_float(float value);
|
|
|
|
/**
|
|
* Pops the top value off the operand stack.
|
|
*
|
|
* @mangled pop__10CRunScriptFv
|
|
* @address 0x23DB80
|
|
* @size 0x24
|
|
* @unknownret
|
|
*/
|
|
RS_STACKDATA pop();
|
|
|
|
/**
|
|
* Enters a script function, and gives back its first instruction.
|
|
*
|
|
* @mangled call_func__10CRunScriptFP8funcdataP8vmcode_t
|
|
* @address 0x23DBB0
|
|
* @size 0x108
|
|
* @unknownret
|
|
*/
|
|
vmcode_t *call_func(funcdata *callee, vmcode_t *return_pc);
|
|
|
|
/**
|
|
* Leaves the current script function, and gives back the caller's instruction.
|
|
*
|
|
* @mangled ret_func__10CRunScriptFv
|
|
* @address 0x23DCC0
|
|
* @size 0x34
|
|
* @unknownret
|
|
*/
|
|
vmcode_t *ret_func();
|
|
|
|
/**
|
|
* Calls the external function the first argument names.
|
|
*
|
|
* @mangled ext__10CRunScriptFP12RS_STACKDATAi
|
|
* @address 0x23DD00
|
|
* @size 0xB4
|
|
* @unknownret
|
|
*/
|
|
void ext(RS_STACKDATA *args, int argc);
|
|
|
|
/**
|
|
* Gives the interpreter a program and the stacks to run it on.
|
|
*
|
|
* @mangled load__10CRunScriptFP14RS_PROG_HEADERP12RS_STACKDATAiP11RS_CALLDATAi
|
|
* @address 0x23DDC0
|
|
* @size 0x50
|
|
* @unknownret
|
|
*/
|
|
void load(RS_PROG_HEADER *prog, RS_STACKDATA *stack, int stack_num, RS_CALLDATA *call, int call_num);
|
|
|
|
/**
|
|
* Swaps in another program, keeping the stacks.
|
|
*
|
|
* @mangled reload__10CRunScriptFP14RS_PROG_HEADER
|
|
* @address 0x23DE10
|
|
* @size 0x18
|
|
* @unknownret
|
|
*/
|
|
void reload(RS_PROG_HEADER *prog);
|
|
|
|
/**
|
|
* Registers the table of external functions scripts can call.
|
|
*
|
|
* @mangled ext_func__10CRunScriptFPPFP12RS_STACKDATAi_ii
|
|
* @address 0x23DE30
|
|
* @size 0x10
|
|
* @unknownret
|
|
*/
|
|
void ext_func(int (**table)(RS_STACKDATA *, int), int count);
|
|
|
|
/**
|
|
* Continues a suspended script where it stopped.
|
|
*
|
|
* @mangled resume__10CRunScriptFv
|
|
* @address 0x23DE40
|
|
* @size 0x2C
|
|
* @unknownret
|
|
*/
|
|
void resume();
|
|
|
|
/**
|
|
* Starts a numbered program, or the main function for a negative number.
|
|
*
|
|
* @mangled run__10CRunScriptFi
|
|
* @address 0x23DE70
|
|
* @size 0x180
|
|
* @unknownret
|
|
*/
|
|
int run(int no);
|
|
|
|
/**
|
|
* Reports whether the program has a numbered entry.
|
|
*
|
|
* @mangled check_program__10CRunScriptFi
|
|
* @address 0x23DFF0
|
|
* @size 0x54
|
|
* @unknownret
|
|
*/
|
|
int check_program(int no);
|
|
|
|
/**
|
|
* Resumes the script, running through its waits.
|
|
*
|
|
* @mangled skip__10CRunScriptFv
|
|
* @address 0x23E050
|
|
* @size 0x28
|
|
* @unknownret
|
|
*/
|
|
void skip();
|
|
|
|
/**
|
|
* Runs instructions from one until the script ends or waits.
|
|
*
|
|
* @mangled exe__10CRunScriptFP8vmcode_t
|
|
* @address 0x23E080
|
|
* @size 0x1508
|
|
* @unknownret
|
|
*/
|
|
void exe(vmcode_t *entry);
|
|
};
|