changeset 653:16aa9a636d35

Some starting point for ecl_vm.
author Gauvain "GovanifY" Roussel-Tarbouriech <gauvain@govanify.com>
date Thu, 08 Aug 2019 16:03:38 +0200
parents 93bdc7b9df15
children ec7e888e88f3
files .gitignore src/th06/ecl_vm.rs
diffstat 2 files changed, 141 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/.gitignore	Thu Aug 08 17:19:30 2019 +0200
+++ b/.gitignore	Thu Aug 08 16:03:38 2019 +0200
@@ -1,3 +1,13 @@
 /target
 **/*.rs.bk
 Cargo.lock
+# swap
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+# session
+Session.vim
+# temporary
+.netrwhist
+*~
+# auto-generated tag files
+tags
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/th06/ecl_vm.rs	Thu Aug 08 16:03:38 2019 +0200
@@ -0,0 +1,131 @@
+//! ECL runner.
+
+use crate::th06::anm0::{
+    Script,
+    Anm0,
+    Call,
+    Instruction,
+};
+use crate::th06::interpolator::{Interpolator1, Interpolator2, Interpolator3, Formula};
+use crate::util::math::Mat4;
+use crate::util::prng::Prng;
+use std::cell::RefCell;
+use std::rc::{Rc, Weak};
+
+    fn run_instruction(&mut self, instruction: Instruction) {
+        let mut sprite = self.sprite.borrow_mut();
+        match instruction {
+            Instruction::Noop() {
+                // really
+            }
+            // 1
+            Instruction::Stop() {
+                self._enemy.removed = true;
+            }
+            // 2 
+            Instruction::RelativeJump(frame, ip) {
+                self.frame = frame;
+                // ip = ip + flag in th06
+                self.ip = ip;
+                // we jump back to the main of the interpreter
+            }
+            // 3
+            // GHIDRA SAYS THERE IS A COMPARISON_REG BUFFER BUT THERE IS NOT!!!
+            // 
+            // MOV        ECX,dword ptr [EBP + 0x8]                     jumptable 00407544 case 31 
+            // CMP        dword ptr [0x9d4 + ECX],0x0
+            // JLE        LAB_00407abb
+            // aka ECX = enemy pointer
+            // ECX->9d4 (aka enemy_pointer_copy->comparison_reg) == 0
+            // only the pointer is copied, not the value, thus we are safe
+            Instruction::RelativeJumpEx(frame, ip, var_id) {
+                // TODO: counter_value is a field of "enemy" in th06, to check
+                counter_value = self._getval(var_id) - 1
+                    if counter_value > 0 {
+                        Instruction::RelativeJump(frame, ip);
+                    }
+            }
+
+            //4, 5
+            Instruction::SetVariable(var_id, value) {
+                self._setval(var_id, value);
+            }
+            // 6
+            Instruction::SetRandomInt(var_id, maxval) {
+                self._setval(var_id, self._game.prng.rand_32()%self._getval(maxval));
+            }
+            // 7
+            Instruction::SetRandomIntMin(var_id, maxval, minval) {
+                self._setval(var_id, (self._game.prng.rand_32()%self._getval(maxval))+self._getval(minval));
+            }
+            // 8
+            Instruction::SetRandomFloat(var_id, maxval) {
+                self._setval(var_id, self._getval(maxval) * self._game.prng.rand_double())
+            }
+            // 9
+            Instruction::SetRandomFloatMin(var_id, maxval, minval) {
+                self._setval(var_id, (self._getval(maxval) * self._game.prng.rand_double())+self._getval(minval))
+            }
+            // 10
+            Instruction::StoreX(var_id) {
+                self._setval(var_id, self._enemy.x);
+            }
+            // 11
+            Instruction::StoreY(var_id) {
+                self._setval(var_id, self._enemy.y);
+            }
+            // 12
+            Instruction::StoreZ(var_id) {
+                self._setval(var_id, self._enemy.z);
+            }
+            // 13(int), 20(float), same impl in th06
+            Instruction::Add(var_id, a, b) {
+                self._setval(var_id, self._getval(a) + self._getval(b));
+            }
+            // 14(int), 21(float), same impl in th06
+            Instruction::Substract(var_id, a, b) {
+                self._setval(var_id, self._getval(a) - self._getval(b));
+            }
+            // 15(int), 22(unused)
+            Instruction::Multiply(var_id, a, b) {
+                self._setval(var_id, self._getval(a) * self._getval(b));
+            }
+             // 16(int), 23(unused)
+            Instruction::Divide(var_id, a, b) {
+                self._setval(var_id, self._getval(a) / self._getval(b));
+            }
+            // 17(int) 24(unused)
+            Instruction::Divide(var_id, a, b) {
+                self._setval(var_id, self._getval(a) % self._getval(b));
+            }
+            // 18
+            // setval used by pytouhou, but not in game(???)
+            Instruction::Increment(var_id) {
+                var_id = self._getval(var_id) + 1
+            }
+            // 19
+            Instruction::Decrement(var_id) {
+                var_id = self._getval(var_id) - 1
+            }
+            //25
+
+
+
+
+
+            // 32
+            Instruction::RelativeJumpIfGreaterThan(frame, ip) {
+                if self.comparison_reg == 1
+                    Instruction::RelativeJump();
+            }
+            // 34
+            Instruction::RelativeJumpIfNotEqual(frame, ip) {
+                if self.comparison_reg != 0
+                    Instruction::RelativeJump();
+            }
+
+
+
+
+
+