Pokebot
Pokemon FireRed bot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
VM.hh
Go to the documentation of this file.
1 #ifndef __VM_HH__
2 #define __VM_HH__
3 
4 #include <list>
5 #include <stack>
6 #include <cstring>
7 #include <functional>
8 #include "Script.hh"
9 #include "Action/AAction.hh"
10 
11 #define VM_FLAGS 0x900
12 #define VM_VARS 0x100
13 #define VM_TEMP 0x1F
14 #define VM_BANKS 0x04
15 #define VM_BUFF 0x03
16 #define VM_VAR_OFFSET 0x4000
17 #define VM_TEMP_OFFSET 0x8000
18 
19 #define VM_LASTRESULT 0x800D
20 
21 #define VM_IS_FLAG(x) ((x) < VM_FLAGS)
22 #define VM_IS_BANK(x) ((x) < VM_BANKS)
23 #define VM_IS_VAR(x) ((x) >= VM_VAR_OFFSET && (x) < VM_VAR_OFFSET + VM_VARS)
24 #define VM_IS_TEMP(x) ((x) >= VM_TEMP_OFFSET && (x) < VM_TEMP_OFFSET + VM_TEMP)
25 
26 #define VM_BOUNDS_ERR(x) ("Warning: " x " 0x%x out of bounds\n")
27 
28 class VM
29 {
30 public:
31  struct ChoicePts
32  {
33  std::vector<uint8_t> choices;
34  uint8_t pts;
35  };
36 
37 private:
38  class Context
39  {
40  public:
41  Context();
42  Context(const Context &ctx);
43  Context &operator=(const Context &ctx);
44 
45  public:
46  void update();
47  bool getFlag(uint16_t flag) const;
48  uint16_t getVar(uint16_t var) const;
49  uint32_t getBank(uint8_t bank) const;
50  void setFlag(uint16_t flag, bool val);
51  void setVar(uint16_t var, uint16_t val);
52  void setBank(uint8_t bank, uint32_t val);
53  void compare(uint32_t a, uint32_t b) { cmp1 = a; cmp2 = b; }
54  void pushStack(uint32_t addr) { stack.push(addr); }
55  uint32_t popStack() { uint32_t addr = stack.top(); stack.pop(); return (addr); }
56  void clearStack() { while (stack.size()) stack.pop(); }
57 
58  private:
59  uint8_t _flags[VM_FLAGS >> 3];
60  uint16_t _vars[VM_VARS];
61  uint16_t _temp[VM_TEMP];
62  uint32_t _banks[VM_BANKS];
63 
64  public:
65  std::stack<uint32_t> stack;
66  uint32_t pc;
67  uint32_t cmp1;
68  uint32_t cmp2;
69  ChoicePts cpts;
70  };
71 
72 public:
73  typedef void (VM::*Executer)(Script::Instruction *);
74 
75 public:
76  VM();
77  ~VM();
78 
79 public:
80  void exec(Script &script);
81  std::vector<ChoicePts> *execCountNewVisits(Script &script);
82 
83 public:
84  bool getFlag(uint16_t flag) const { return (_ctx.getFlag(flag)); }
85  uint16_t getVar(uint16_t var) const { return (_ctx.getVar(var)); }
86  uint32_t getBank(uint8_t bank) const { return (_ctx.getBank(bank)); }
87  void setFlag(uint16_t flag, bool val) { _ctx.setFlag(flag, val); }
88  void setVar(uint16_t var, uint16_t val) { _ctx.setVar(var, val); }
89  void setBank(uint8_t bank, uint32_t val) { _ctx.setBank(bank, val); }
90 
91 private:
92  void _compare(uint32_t a, uint32_t b) { _ctx.compare(a, b); }
93  void _compare8(uint8_t a, uint8_t b) { _ctx.compare(a, b); }
94  Context *_saveContext() { _states.push(new Context(_ctx)); return (_states.back()); }
95  bool _restoreContext();
96 
97 private:
98  void _return(Script::Instruction *instr);
99  void _call(Script::Instruction *instr);
100  void _goto(Script::Instruction *instr);
101  void _if1(Script::Instruction *instr);
102  void _if2(Script::Instruction *instr);
103  void _callstd(Script::Instruction *instr);
104  void _yesnobox(Script::Instruction *instr);
105  void _multichoice(Script::Instruction *instr);
106 
107  void _loadpointer(Script::Instruction *instr)
108  { setBank(instr->args[0], instr->args[1]); }
109  void _setbyte2(Script::Instruction *instr)
110  { setBank(instr->args[0], instr->args[1]); }
111  void _loadbytefrompointer(Script::Instruction *instr)
112  { setBank(instr->args[0], *(uint8_t *) gbaMem(instr->args[1])); }
113  void _copyscriptbanks(Script::Instruction *instr)
114  { setBank(instr->args[0], getBank(instr->args[1])); }
115  void _setvar(Script::Instruction *instr)
116  { setVar(instr->args[0], instr->args[1]); }
117  void _addvar(Script::Instruction *instr)
118  { setVar(instr->args[0], getVar(instr->args[0]) + instr->args[1]); }
119  void _subvar(Script::Instruction *instr)
120  { setVar(instr->args[0], getVar(instr->args[0]) - instr->args[1]); }
121  void _copyvar(Script::Instruction *instr)
122  { setVar(instr->args[0], getVar(instr->args[1])); }
123  void _copyvarifnotzero(Script::Instruction *instr)
124  { setVar(instr->args[0], VM_IS_VAR(instr->args[1]) ? getVar(instr->args[1]) : instr->args[1]); }
125  void _comparebanks(Script::Instruction *instr)
126  { _compare8(getBank(instr->args[0]), getBank(instr->args[1])); }
127  void _comparebanktobyte(Script::Instruction *instr)
128  { _compare8(getBank(instr->args[0]), instr->args[1]); }
129  void _comparebanktofarbyte(Script::Instruction *instr)
130  { _compare8(getBank(instr->args[0]), (*(uint8_t *) gbaMem(instr->args[1]))); }
131  void _comparefarbytetobank(Script::Instruction *instr)
132  { _compare8((*(uint8_t *) gbaMem(instr->args[0])), getBank(instr->args[1])); }
133  void _comparefarbytetobyte(Script::Instruction *instr)
134  { _compare8((*(uint8_t *) gbaMem(instr->args[0])), instr->args[1]); }
135  void _comparefarbytes(Script::Instruction *instr)
136  { _compare8((*(uint8_t *) gbaMem(instr->args[0])), (*(uint8_t *) gbaMem(instr->args[1]))); }
137  void _compare(Script::Instruction *instr)
138  { _compare(getVar(instr->args[0]), instr->args[1]); }
139  void _comparevars(Script::Instruction *instr)
140  { _compare(getVar(instr->args[0]), getVar(instr->args[1])); }
141  void _setflag(Script::Instruction *instr)
142  { setFlag(instr->args[0], 1); }
143  void _clearflag(Script::Instruction *instr)
144  { setFlag(instr->args[0], 0); }
145  void _checkflag(Script::Instruction *instr)
146  { _compare(getFlag(instr->args[0]), 1); }
147  void _resetvars(Script::Instruction *instr)
148  { for (int i = 0x8000; i <= 0x8002; i++) setVar(i, 0); }
149 
150 private:
151  Context _ctx;
152  std::queue<Context *> _states;
153 
154  static Executer _executers[0xD6];
155  static std::function<bool(uint32_t, uint32_t)> _cmpOp[6];
156 };
157 
158 #endif
uint16_t getVar(uint16_t var) const
Definition: VM.hh:85
bool getFlag(uint16_t flag) const
Definition: VM.hh:84
Args args
Definition: Script.hh:45
#define VM_TEMP
Definition: VM.hh:13
void setBank(uint8_t bank, uint32_t val)
Definition: VM.hh:89
#define VM_VARS
Definition: VM.hh:12
~VM()
Definition: VM.cpp:8
#define VM_IS_VAR(x)
Definition: VM.hh:23
std::vector< ChoicePts > * execCountNewVisits(Script &script)
Definition: VM.cpp:37
void(VM::* Executer)(Script::Instruction *)
Definition: VM.hh:73
uint32_t getBank(uint8_t bank) const
Definition: VM.hh:86
Definition: Script.hh:37
uint8_t pts
Definition: VM.hh:34
std::vector< uint8_t > choices
Definition: VM.hh:33
Definition: Script.hh:21
#define VM_FLAGS
Definition: VM.hh:11
Definition: VM.hh:31
void * gbaMem(uint32_t ptr)
Definition: PokemonUtils.cpp:57
void exec(Script &script)
Definition: VM.cpp:73
VM()
Definition: VM.cpp:3
void setVar(uint16_t var, uint16_t val)
Definition: VM.hh:88
#define VM_BANKS
Definition: VM.hh:14
Definition: VM.hh:28
void setFlag(uint16_t flag, bool val)
Definition: VM.hh:87