Mercurial > touhou
comparison src/th06/ecl_vm.rs @ 660:31fc0d881105
Make ecl_vm compile, and use it in eclrenderer (doesn’t render yet).
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sat, 10 Aug 2019 14:41:30 +0200 |
parents | 53786d834444 |
children | 598f3125cbac |
comparison
equal
deleted
inserted
replaced
659:53786d834444 | 660:31fc0d881105 |
---|---|
1 //! ECL runner. | 1 //! ECL runner. |
2 | 2 |
3 use crate::th06::anm0::{ | 3 use crate::th06::ecl::{Ecl, SubInstruction}; |
4 Script, | 4 use crate::th06::enemy::Enemy; |
5 Anm0, | |
6 Call, | |
7 Instruction, | |
8 }; | |
9 use crate::th06::interpolator::{Interpolator1, Interpolator2, Interpolator3, Formula}; | |
10 use crate::util::math::Mat4; | |
11 use crate::util::prng::Prng; | 5 use crate::util::prng::Prng; |
12 use std::cell::RefCell; | 6 use std::cell::RefCell; |
13 use std::rc::{Rc, Weak}; | 7 use std::rc::Rc; |
14 | 8 |
15 fn run_instruction(&mut self, instruction: Instruction) { | 9 type Variables = ([i32; 4], [f32; 4], [i32; 4]); |
16 let mut sprite = self.sprite.borrow_mut(); | 10 |
11 /// Interpreter for enemy scripts. | |
12 #[derive(Default)] | |
13 pub struct EclRunner { | |
14 enemy: Rc<RefCell<Enemy>>, | |
15 ecl: Option<Ecl>, | |
16 sub: u8, | |
17 running: bool, | |
18 /// XXX | |
19 pub frame: i32, | |
20 ip: i32, | |
21 variables: Variables, | |
22 comparison_reg: i8, | |
23 stack: Vec<Variables>, | |
24 } | |
25 | |
26 impl EclRunner { | |
27 /// Create a new ECL runner. | |
28 pub fn new(ecl: &Ecl, enemy: Rc<RefCell<Enemy>>, sub: u8) -> EclRunner { | |
29 EclRunner { | |
30 enemy, | |
31 // XXX: no clone. | |
32 ecl: Some(ecl.clone()), | |
33 sub, | |
34 ..Default::default() | |
35 } | |
36 } | |
37 | |
38 /// Advance the ECL of a single frame. | |
39 pub fn run_frame(&mut self) { | |
40 while self.running { | |
41 let ecl = self.ecl.clone().unwrap(); | |
42 let sub = &ecl.subs[self.sub as usize]; | |
43 let call = match sub.instructions.get(self.ip as usize) { | |
44 Some(call) => call, | |
45 None => { | |
46 self.running = false; | |
47 break; | |
48 } | |
49 }; | |
50 | |
51 if call.time > self.frame { | |
52 break; | |
53 } | |
54 self.ip += 1; | |
55 | |
56 let rank = self.enemy.borrow().get_rank(); | |
57 if call.rank_mask & (0x100 << rank) == 0 { | |
58 continue; | |
59 } | |
60 | |
61 if call.time == self.frame { | |
62 self.run_instruction(call.instr.clone()); | |
63 } | |
64 } | |
65 self.frame += 1; | |
66 } | |
67 | |
68 fn get_i32(&self, var: i32) -> i32 { | |
69 let enemy = self.enemy.borrow(); | |
70 match var { | |
71 -10001 => self.variables.0[0], | |
72 -10002 => self.variables.0[1], | |
73 -10003 => self.variables.0[2], | |
74 -10004 => self.variables.0[3], | |
75 -10005 => self.variables.1[0] as i32, | |
76 -10006 => self.variables.1[1] as i32, | |
77 -10007 => self.variables.1[2] as i32, | |
78 -10008 => self.variables.1[3] as i32, | |
79 -10009 => self.variables.2[0], | |
80 -10010 => self.variables.2[1], | |
81 -10011 => self.variables.2[2], | |
82 -10012 => self.variables.2[3], | |
83 -10013 => enemy.get_rank(), | |
84 -10014 => enemy.get_difficulty(), | |
85 -10015 => enemy.pos.x as i32, | |
86 -10016 => enemy.pos.y as i32, | |
87 -10017 => enemy.z as i32, | |
88 -10018 => unimplemented!(), | |
89 -10019 => unimplemented!(), | |
90 -10020 => unreachable!(), | |
91 -10021 => unimplemented!(), | |
92 -10022 => enemy.frame as i32, | |
93 -10023 => unreachable!(), | |
94 -10024 => enemy.life as i32, | |
95 -10025 => unimplemented!(), | |
96 _ => var | |
97 } | |
98 } | |
99 | |
100 fn get_f32(&self, var: f32) -> f32 { | |
101 let enemy = self.enemy.borrow(); | |
102 match var { | |
103 -10001.0 => self.variables.0[0] as f32, | |
104 -10002.0 => self.variables.0[1] as f32, | |
105 -10003.0 => self.variables.0[2] as f32, | |
106 -10004.0 => self.variables.0[3] as f32, | |
107 -10005.0 => self.variables.1[0], | |
108 -10006.0 => self.variables.1[1], | |
109 -10007.0 => self.variables.1[2], | |
110 -10008.0 => self.variables.1[3], | |
111 -10009.0 => self.variables.2[0] as f32, | |
112 -10010.0 => self.variables.2[1] as f32, | |
113 -10011.0 => self.variables.2[2] as f32, | |
114 -10012.0 => self.variables.2[3] as f32, | |
115 -10013.0 => enemy.get_rank() as f32, | |
116 -10014.0 => enemy.get_difficulty() as f32, | |
117 -10015.0 => enemy.pos.x, | |
118 -10016.0 => enemy.pos.y, | |
119 -10017.0 => enemy.z, | |
120 -10018.0 => unimplemented!(), | |
121 -10019.0 => unimplemented!(), | |
122 -10020.0 => unreachable!(), | |
123 -10021.0 => unimplemented!(), | |
124 -10022.0 => enemy.frame as f32, | |
125 -10023.0 => unreachable!(), | |
126 -10024.0 => enemy.life as f32, | |
127 -10025.0 => unimplemented!(), | |
128 _ => var | |
129 } | |
130 } | |
131 | |
132 fn set_i32(&mut self, var: i32, value: i32) { | |
133 unimplemented!() | |
134 } | |
135 | |
136 fn set_f32(&mut self, var: f32, value: f32) { | |
137 unimplemented!() | |
138 } | |
139 | |
140 fn get_prng(&mut self) -> Rc<RefCell<Prng>> { | |
141 let enemy = self.enemy.borrow(); | |
142 enemy.prng.upgrade().unwrap() | |
143 } | |
144 | |
145 fn run_instruction(&mut self, instruction: SubInstruction) { | |
17 match instruction { | 146 match instruction { |
18 Instruction::Noop() { | 147 SubInstruction::Noop() => { |
19 // really | 148 // really |
20 } | 149 } |
21 // 1 | 150 // 1 |
22 Instruction::Stop() { | 151 SubInstruction::Destroy(_unused) => { |
23 self._enemy.removed = true; | 152 let mut enemy = self.enemy.borrow_mut(); |
24 } | 153 enemy.removed = true; |
25 // 2 | 154 } |
26 Instruction::RelativeJump(frame, ip) { | 155 // 2 |
156 SubInstruction::RelativeJump(frame, ip) => { | |
27 self.frame = frame; | 157 self.frame = frame; |
28 // ip = ip + flag in th06 | 158 // ip = ip + flag in th06 |
29 self.ip = ip; | 159 self.ip = ip; |
30 // we jump back to the main of the interpreter | 160 // we jump back to the main of the interpreter |
31 } | 161 } |
32 // 3 | 162 // 3 |
33 // GHIDRA SAYS THERE IS A COMPARISON_REG BUFFER BUT THERE IS NOT!!! | 163 // GHIDRA SAYS THERE IS A COMPARISON_REG BUFFER BUT THERE IS NOT!!! |
34 // | 164 // |
35 // MOV ECX,dword ptr [EBP + 0x8] jumptable 00407544 case 31 | 165 // MOV ECX,dword ptr [EBP + 0x8] jumptable 00407544 case 31 |
36 // CMP dword ptr [0x9d4 + ECX],0x0 | 166 // CMP dword ptr [0x9d4 + ECX],0x0 |
37 // JLE LAB_00407abb | 167 // JLE LAB_00407abb |
38 // aka ECX = enemy pointer | 168 // aka ECX = enemy pointer |
39 // ECX->9d4 (aka enemy_pointer_copy->comparison_reg) == 0 | 169 // ECX->9d4 (aka enemy_pointer_copy->comparison_reg) == 0 |
40 // only the pointer is copied, not the value, thus we are safe | 170 // only the pointer is copied, not the value, thus we are safe |
41 Instruction::RelativeJumpEx(frame, ip, var_id) { | 171 SubInstruction::RelativeJumpEx(frame, ip, var_id) => { |
42 // TODO: counter_value is a field of "enemy" in th06, to check | 172 // TODO: counter_value is a field of "enemy" in th06, to check |
43 counter_value = self._getval(var_id) - 1 | 173 let counter_value = self.get_i32(var_id) - 1; |
44 if counter_value > 0 { | 174 if counter_value > 0 { |
45 Instruction::RelativeJump(frame, ip); | 175 SubInstruction::RelativeJump(frame, ip); |
46 } | 176 } |
47 } | 177 } |
48 | 178 // 4 |
49 //4, 5 | 179 SubInstruction::SetInt(var_id, value) => { |
50 Instruction::SetVariable(var_id, value) { | 180 self.set_i32(var_id, value); |
51 self._setval(var_id, value); | 181 } |
182 // 5 | |
183 SubInstruction::SetFloat(var_id, value) => { | |
184 self.set_f32(var_id as f32, value); | |
52 } | 185 } |
53 // 6 | 186 // 6 |
54 Instruction::SetRandomInt(var_id, maxval) { | 187 SubInstruction::SetRandomInt(var_id, maxval) => { |
55 self._setval(var_id, self._game.prng.rand_32()%self._getval(maxval)); | 188 let random = self.get_prng().borrow_mut().get_u32() as i32; |
189 self.set_i32(var_id, random % self.get_i32(maxval)); | |
56 } | 190 } |
57 // 7 | 191 // 7 |
58 Instruction::SetRandomIntMin(var_id, maxval, minval) { | 192 /* |
59 self._setval(var_id, (self._game.prng.rand_32()%self._getval(maxval))+self._getval(minval)); | 193 SubInstruction::SetRandomIntMin(var_id, maxval, minval) => { |
60 } | 194 self.set_i32(var_id, (self.get_prng().borrow_mut().get_u32() % self.get_i32(maxval)) + self.get_i32(minval)); |
195 } | |
196 */ | |
61 // 8 | 197 // 8 |
62 Instruction::SetRandomFloat(var_id, maxval) { | 198 SubInstruction::SetRandomFloat(var_id, maxval) => { |
63 self._setval(var_id, self._getval(maxval) * self._game.prng.rand_double()) | 199 let random = self.get_prng().borrow_mut().get_f64() as f32; |
200 self.set_f32(var_id as f32, self.get_f32(maxval) * random) | |
64 } | 201 } |
65 // 9 | 202 // 9 |
66 Instruction::SetRandomFloatMin(var_id, maxval, minval) { | 203 SubInstruction::SetRandomFloatMin(var_id, maxval, minval) => { |
67 self._setval(var_id, (self._getval(maxval) * self._game.prng.rand_double())+self._getval(minval)) | 204 let random = self.get_prng().borrow_mut().get_f64() as f32; |
205 self.set_f32(var_id as f32, self.get_f32(maxval) * random + self.get_f32(minval)) | |
68 } | 206 } |
69 // 10 | 207 // 10 |
70 Instruction::StoreX(var_id) { | 208 SubInstruction::StoreX(var_id) => { |
71 self._setval(var_id, self._enemy.x); | 209 let x = { |
210 let enemy = self.enemy.borrow(); | |
211 enemy.pos.x | |
212 }; | |
213 // TODO: is this really an i32? | |
214 self.set_i32(var_id, x as i32); | |
72 } | 215 } |
73 // 11 | 216 // 11 |
74 Instruction::StoreY(var_id) { | 217 /* |
75 self._setval(var_id, self._enemy.y); | 218 SubInstruction::StoreY(var_id) => { |
76 } | 219 let enemy = self.enemy.borrow(); |
220 self.set_i32(var_id, enemy.pos.y); | |
221 } | |
222 */ | |
77 // 12 | 223 // 12 |
78 Instruction::StoreZ(var_id) { | 224 /* |
79 self._setval(var_id, self._enemy.z); | 225 SubInstruction::StoreZ(var_id) => { |
80 } | 226 let enemy = self.enemy.borrow(); |
227 self.set_i32(var_id, enemy.z); | |
228 } | |
229 */ | |
81 // 13(int), 20(float), same impl in th06 | 230 // 13(int), 20(float), same impl in th06 |
82 Instruction::Add(var_id, a, b) { | 231 SubInstruction::AddInt(var_id, a, b) => { |
83 self._setval(var_id, self._getval(a) + self._getval(b)); | 232 self.set_i32(var_id, self.get_i32(a) + self.get_i32(b)); |
233 } | |
234 SubInstruction::AddFloat(var_id, a, b) => { | |
235 self.set_f32(var_id as f32, self.get_f32(a) + self.get_f32(b)); | |
84 } | 236 } |
85 // 14(int), 21(float), same impl in th06 | 237 // 14(int), 21(float), same impl in th06 |
86 Instruction::Substract(var_id, a, b) { | 238 SubInstruction::SubstractInt(var_id, a, b) => { |
87 self._setval(var_id, self._getval(a) - self._getval(b)); | 239 self.set_i32(var_id, self.get_i32(a) - self.get_i32(b)); |
240 } | |
241 SubInstruction::SubstractFloat(var_id, a, b) => { | |
242 self.set_f32(var_id as f32, self.get_f32(a) - self.get_f32(b)); | |
88 } | 243 } |
89 // 15(int), 22(unused) | 244 // 15(int), 22(unused) |
90 Instruction::Multiply(var_id, a, b) { | 245 SubInstruction::MultiplyInt(var_id, a, b) => { |
91 self._setval(var_id, self._getval(a) * self._getval(b)); | 246 self.set_i32(var_id, self.get_i32(a) * self.get_i32(b)); |
92 } | 247 } |
248 /* | |
249 SubInstruction::MultiplyFloat(var_id, a, b) => { | |
250 self.set_f32(var_id as f32, self.get_f32(a) * self.get_f32(b)); | |
251 } | |
252 */ | |
93 // 16(int), 23(unused) | 253 // 16(int), 23(unused) |
94 Instruction::Divide(var_id, a, b) { | 254 SubInstruction::DivideInt(var_id, a, b) => { |
95 self._setval(var_id, self._getval(a) / self._getval(b)); | 255 self.set_i32(var_id, self.get_i32(a) / self.get_i32(b)); |
96 } | 256 } |
257 /* | |
258 SubInstruction::Divide(var_id, a, b) => { | |
259 self.set_f32(var_id as f32, self.get_f32(a) / self.get_f32(b)); | |
260 } | |
261 */ | |
97 // 17(int) 24(unused) | 262 // 17(int) 24(unused) |
98 Instruction::Divide(var_id, a, b) { | 263 SubInstruction::ModuloInt(var_id, a, b) => { |
99 self._setval(var_id, self._getval(a) % self._getval(b)); | 264 self.set_i32(var_id, self.get_i32(a) % self.get_i32(b)); |
100 } | 265 } |
266 /* | |
267 SubInstruction::ModuloFloat(var_id, a, b) => { | |
268 self.set_f32(var_id as f32, self.get_f32(a) % self.get_f32(b)); | |
269 } | |
270 */ | |
101 // 18 | 271 // 18 |
102 // setval used by pytouhou, but not in game(???) | 272 // setval used by pytouhou, but not in game(???) |
103 Instruction::Increment(var_id) { | 273 SubInstruction::Increment(var_id) => { |
104 var_id = self._getval(var_id) + 1 | 274 self.set_i32(var_id, self.get_i32(var_id) + 1); |
105 } | 275 } |
106 // 19 | 276 // 19 |
107 Instruction::Decrement(var_id) { | 277 /* |
108 var_id = self._getval(var_id) - 1 | 278 SubInstruction::Decrement(var_id) => { |
109 } | 279 self.set_i32(var_id, self.get_i32(var_id) - 1); |
280 } | |
281 */ | |
110 //25 | 282 //25 |
111 Instruction::GetDirection(var_id, x1, y1, x2, y2) { | 283 SubInstruction::GetDirection(var_id, x1, y1, x2, y2) => { |
112 //__ctrandisp2 in ghidra, let's assume from pytouhou it's atan2 | 284 //__ctrandisp2 in ghidra, let's assume from pytouhou it's atan2 |
113 self._setval(var_id, atan2(self._getval(y2) - self._getval(y1), self._getval(x2) - self._getval(x1))); | 285 self.set_f32(var_id as f32, (self.get_f32(y2) - self.get_f32(y1)).atan2(self.get_f32(x2) - self.get_f32(x1))); |
114 } | 286 } |
115 | 287 |
116 // 26 | 288 // 26 |
117 Instruction::FloatToUnitCircle(var_id) { | 289 SubInstruction::FloatToUnitCircle(var_id) => { |
118 // TODO: atan2(var_id, ??) is used by th06, maybe ?? is pi? | 290 // TODO: atan2(var_id, ??) is used by th06, maybe ?? is pi? |
119 // we suck at trigonometry so let's use pytouhou for now | 291 // we suck at trigonometry so let's use pytouhou for now |
120 self._setval(var_id, (self._getval(var_id) + pi) % (2*pi) - pi); | 292 self.set_f32(var_id as f32, (self.get_f32(var_id as f32) + std::f32::consts::PI) % (2. * std::f32::consts::PI) - std::f32::consts::PI); |
121 } | 293 } |
122 | 294 |
123 // 27(int), 28(float) | 295 // 27(int), 28(float) |
124 Instruction::Compare(a, b) { | 296 SubInstruction::CompareInts(a, b) => { |
125 a = self._getval(a); | 297 let a = self.get_i32(a); |
126 b = self._getval(b); | 298 let b = self.get_i32(b); |
127 if a < b { | 299 if a < b { |
128 self.comparison_reg = -1 | 300 self.comparison_reg = -1; |
129 } | 301 } |
130 else if a == b { | 302 else if a == b { |
131 self.comparison_reg = 0 | 303 self.comparison_reg = 0; |
132 } | 304 } |
133 else { | 305 else { |
134 self.comparison_reg = 1 | 306 self.comparison_reg = 1; |
135 } | 307 } |
136 } | 308 } |
137 // 29 | 309 SubInstruction::CompareFloats(a, b) => { |
138 Instruction::RelativeJumpIfLowerThan(frame, ip) { | 310 let a = self.get_f32(a); |
311 let b = self.get_f32(b); | |
312 if a < b { | |
313 self.comparison_reg = -1; | |
314 } | |
315 else if a == b { | |
316 self.comparison_reg = 0; | |
317 } | |
318 else { | |
319 self.comparison_reg = 1; | |
320 } | |
321 } | |
322 // 29 | |
323 SubInstruction::RelativeJumpIfLowerThan(frame, ip) => { | |
139 if self.comparison_reg == -1 { | 324 if self.comparison_reg == -1 { |
140 Instruction::RelativeJump(); | 325 SubInstruction::RelativeJump(frame, ip); |
141 } | 326 } |
142 } | 327 } |
143 // 30 | 328 // 30 |
144 Instruction::RelativeJumpIfLowerOrEqual(frame, ip) { | 329 SubInstruction::RelativeJumpIfLowerOrEqual(frame, ip) => { |
145 if self.comparison_reg != 1 { | 330 if self.comparison_reg != 1 { |
146 Instruction::RelativeJump(); | 331 SubInstruction::RelativeJump(frame, ip); |
147 } | 332 } |
148 } | 333 } |
149 // 31 | 334 // 31 |
150 Instruction::RelativeJumpIfEqual(frame, ip) { | 335 SubInstruction::RelativeJumpIfEqual(frame, ip) => { |
151 if self.comparison_reg == 0 { | 336 if self.comparison_reg == 0 { |
152 Instruction::RelativeJump(); | 337 SubInstruction::RelativeJump(frame, ip); |
153 } | 338 } |
154 } | 339 } |
155 // 32 | 340 // 32 |
156 Instruction::RelativeJumpIfGreaterThan(frame, ip) { | 341 SubInstruction::RelativeJumpIfGreaterThan(frame, ip) => { |
157 if self.comparison_reg == 1 { | 342 if self.comparison_reg == 1 { |
158 Instruction::RelativeJump(); | 343 SubInstruction::RelativeJump(frame, ip); |
159 } | 344 } |
160 } | 345 } |
161 // 33 | 346 // 33 |
162 Instruction::RelativeJumpIfGreaterOrEqual(frame, ip) { | 347 SubInstruction::RelativeJumpIfGreaterOrEqual(frame, ip) => { |
163 if self.comparison_reg != -1 | 348 if self.comparison_reg != -1 { |
164 Instruction::RelativeJump(); | 349 SubInstruction::RelativeJump(frame, ip); |
350 } | |
165 } | 351 } |
166 // 34 | 352 // 34 |
167 Instruction::RelativeJumpIfNotEqual(frame, ip) { | 353 SubInstruction::RelativeJumpIfNotEqual(frame, ip) => { |
168 if self.comparison_reg != 0 | 354 if self.comparison_reg != 0 { |
169 Instruction::RelativeJump(); | 355 SubInstruction::RelativeJump(frame, ip); |
356 } | |
170 } | 357 } |
171 // 35 | 358 // 35 |
172 Instruction::Call(sub, param1, param2) { | 359 SubInstruction::Call(sub, param1, param2) => { |
173 // does insane stuff with the stack, not implemented | 360 // does insane stuff with the stack, not implemented |
174 } | 361 unimplemented!() |
175 | 362 } |
363 | |
176 // 36 | 364 // 36 |
177 Instruction::Ret(frame, ip) { | 365 SubInstruction::Return() => { |
178 // does insane stuff with the stack, not implemented | 366 // does insane stuff with the stack, not implemented |
367 unimplemented!() | |
179 } | 368 } |
180 // 37 | 369 // 37 |
181 Instruction::CallIfSuperior(sub, param1, param2, a, b) { | 370 /* |
182 if(self._getval(b) <= self._getval(a)) { | 371 SubInstruction::CallIfSuperior(sub, param1, param2, a, b) => { |
183 Instruction::Call(sub, param1, param2); | 372 if self.get_i32(b) <= self.get_i32(a) { |
184 } | 373 SubInstruction::Call(sub, param1, param2); |
185 } | 374 } |
375 } | |
376 */ | |
186 // 38 | 377 // 38 |
187 Instruction::CallIfSuperiorOrEqual(sub, param1, param2, a, b) { | 378 /* |
188 if(self._getval(b) <= self._getval(a)) { | 379 SubInstruction::CallIfSuperiorOrEqual(sub, param1, param2, a, b) => { |
189 Instruction::Call(sub, param1, param2); | 380 if self.get_i32(b) <= self.get_i32(a) { |
190 } | 381 SubInstruction::Call(sub, param1, param2); |
191 } | 382 } |
383 } | |
384 */ | |
192 // 39 | 385 // 39 |
193 Instruction::CallIfEqual(sub, param1, param2, a, b) { | 386 SubInstruction::CallIfEqual(sub, param1, param2, a, b) => { |
194 if(self._getval(b) == self._getval(a)) { | 387 if self.get_i32(b) == self.get_i32(a) { |
195 Instruction::Call(sub, param1, param2); | 388 SubInstruction::Call(sub, param1, param2); |
196 } | 389 } |
197 } | 390 } |
198 // 40 | 391 // 40 |
199 Instruction::CallIfEqual(sub, param1, param2, a, b) { | 392 /* |
200 if(self._getval(b) == self._getval(a)) { | 393 SubInstruction::CallIfEqual(sub, param1, param2, a, b) => { |
201 Instruction::Call(sub, param1, param2); | 394 if self.get_i32(b) == self.get_i32(a) { |
202 } | 395 SubInstruction::Call(sub, param1, param2); |
203 } | 396 } |
204 //41 | 397 } |
205 Instruction::CallIfInferior(sub, param1, param2, a, b) { | 398 */ |
206 if(self._getval(a) < self._getval(b)) { | 399 //41 |
207 Instruction::Call(sub, param1, param2); | 400 /* |
208 } | 401 SubInstruction::CallIfInferior(sub, param1, param2, a, b) => { |
209 } | 402 if self.get_i32(a) < self.get_i32(b) { |
210 //42 | 403 SubInstruction::Call(sub, param1, param2); |
211 Instruction::CallIfInferiorOrEqual(sub, param1, param2, a, b) { | 404 } |
212 if(self._getval(a) <= self._getval(b)) { | 405 } |
213 Instruction::Call(sub, param1, param2); | 406 */ |
214 } | 407 //42 |
215 } | 408 /* |
216 // 43 | 409 SubInstruction::CallIfInferiorOrEqual(sub, param1, param2, a, b) => { |
217 Instruction::SetPos(x, y, z) { | 410 if self.get_i32(a) <= self.get_i32(b) { |
218 self._enemy.set_pos(self._getval(x), self._getval(y), self._getval(z)); | 411 SubInstruction::Call(sub, param1, param2); |
219 } | 412 } |
220 // 44 | 413 } |
221 Instruction::SetPosInterlacing(x, y, z) { | 414 */ |
415 // 43 | |
416 SubInstruction::SetPosition(x, y, z) => { | |
417 let mut enemy = self.enemy.borrow_mut(); | |
418 enemy.set_pos(self.get_f32(x), self.get_f32(y), self.get_f32(z)); | |
419 } | |
420 // 44 | |
421 /* | |
422 SubInstruction::SetPositionInterlacing(x, y, z) => { | |
222 //TODO: almost the same as setpos, except with 3 different values and sets the | 423 //TODO: almost the same as setpos, except with 3 different values and sets the |
223 //interlacing, should double check | 424 //interlacing, should double check |
224 self._enemy.set_pos(self._getval(x), self._getval(y), self._getval(z)); | 425 let mut enemy = self.enemy.borrow_mut(); |
225 } | 426 enemy.set_pos(self.get_f32(x), self.get_f32(y), self.get_f32(z)); |
427 } | |
428 */ | |
226 // 45 | 429 // 45 |
227 Instruction::SetAngleSpeed(angle, speed) { | 430 SubInstruction::SetAngleAndSpeed(angle, speed) => { |
228 self._enemy.update_mode = 0; | 431 let mut enemy = self.enemy.borrow_mut(); |
229 self._enemy.angle, self._enemy.speed = self._getval(angle), self._getval(speed); | 432 enemy.update_mode = 0; |
230 } | 433 enemy.angle = self.get_f32(angle); |
231 // 46 | 434 enemy.speed = self.get_f32(speed); |
232 Instruction::SetRotationSpeed(speed) { | 435 } |
233 self._enemy.update_mode = 0 | 436 // 46 |
234 self._enemy.rotation_speed = self._getval(speed) | 437 SubInstruction::SetRotationSpeed(speed) => { |
235 } | 438 let mut enemy = self.enemy.borrow_mut(); |
236 // 47 | 439 enemy.update_mode = 0; |
237 Instruction::SetSpeed(speed) { | 440 enemy.rotation_speed = self.get_f32(speed); |
238 self._enemy.update_mode = 0 | 441 } |
239 self._enemy.speed = self._getval(speed) | 442 // 47 |
240 } | 443 SubInstruction::SetSpeed(speed) => { |
241 // 48 | 444 let mut enemy = self.enemy.borrow_mut(); |
242 Instruction::SetAcceleration(acceleration) { | 445 enemy.update_mode = 0; |
243 self._enemy.update_mode = 0 | 446 enemy.speed = self.get_f32(speed); |
244 self._enemy.acceleration = self._getval(acceleration) | 447 } |
448 // 48 | |
449 SubInstruction::SetAcceleration(acceleration) => { | |
450 let mut enemy = self.enemy.borrow_mut(); | |
451 enemy.update_mode = 0; | |
452 enemy.acceleration = self.get_f32(acceleration); | |
245 } | 453 } |
246 // 49 | 454 // 49 |
247 Instruction::SetRandomAngle(min_angle, max_angle) { | 455 SubInstruction::SetRandomAngle(min_angle, max_angle) => { |
248 angle = self._game.prng.rand_double() * (max_angle - min_angle) + min_angle | 456 let angle = self.get_prng().borrow_mut().get_f64() as f32 * (max_angle - min_angle) + min_angle; |
249 self._enemy.angle = angle | 457 let mut enemy = self.enemy.borrow_mut(); |
458 enemy.angle = angle; | |
250 } | 459 } |
251 | 460 |
252 // 83 -> star items >>> life items | 461 // 83 -> star items >>> life items |
253 | 462 |
254 | 463 _ => unimplemented!() |
255 | 464 } |
256 | 465 } |
257 | 466 } |
258 | |
259 | |
260 | |
261 | |
262 |