Mercurial > touhou
comparison src/th06/ecl_vm.rs @ 685:11d7e4d6947a
ecl_vm: nearing the complete list
author | Gauvain "GovanifY" Roussel-Tarbouriech <gauvain@govanify.com> |
---|---|
date | Fri, 16 Aug 2019 23:27:09 +0200 |
parents | c8bb28961d31 |
children | aefe5b5f481e |
comparison
equal
deleted
inserted
replaced
684:c8bb28961d31 | 685:11d7e4d6947a |
---|---|
246 SubInstruction::SetRandomInt(var_id, maxval) => { | 246 SubInstruction::SetRandomInt(var_id, maxval) => { |
247 let random = self.get_prng().borrow_mut().get_u32() as i32; | 247 let random = self.get_prng().borrow_mut().get_u32() as i32; |
248 self.set_i32(var_id, random % self.get_i32(maxval)); | 248 self.set_i32(var_id, random % self.get_i32(maxval)); |
249 } | 249 } |
250 // 7 | 250 // 7 |
251 /* | |
252 SubInstruction::SetRandomIntMin(var_id, maxval, minval) => { | 251 SubInstruction::SetRandomIntMin(var_id, maxval, minval) => { |
253 self.set_i32(var_id, (self.get_prng().borrow_mut().get_u32() % self.get_i32(maxval)) + self.get_i32(minval)); | 252 let random = self.get_prng().borrow_mut().get_u32() as i32; |
254 } | 253 self.set_i32(var_id, (random % self.get_i32(maxval)) + self.get_i32(minval)); |
255 */ | 254 } |
256 // 8 | 255 // 8 |
257 SubInstruction::SetRandomFloat(var_id, maxval) => { | 256 SubInstruction::SetRandomFloat(var_id, maxval) => { |
258 let random = self.get_prng().borrow_mut().get_f64() as f32; | 257 let random = self.get_prng().borrow_mut().get_f64() as f32; |
259 self.set_f32(var_id as f32, self.get_f32(maxval) * random) | 258 self.set_f32(var_id as f32, self.get_f32(maxval) * random) |
260 } | 259 } |
271 }; | 270 }; |
272 // TODO: is this really an i32? | 271 // TODO: is this really an i32? |
273 self.set_i32(var_id, x as i32); | 272 self.set_i32(var_id, x as i32); |
274 } | 273 } |
275 // 11 | 274 // 11 |
276 /* | |
277 SubInstruction::StoreY(var_id) => { | 275 SubInstruction::StoreY(var_id) => { |
278 let enemy = self.enemy.borrow(); | 276 let y = { |
279 self.set_i32(var_id, enemy.pos.y); | 277 let enemy = self.enemy.borrow(); |
280 } | 278 enemy.pos.y |
281 */ | 279 }; |
280 self.set_i32(var_id, y as i32); | |
281 } | |
282 // 12 | 282 // 12 |
283 /* | |
284 SubInstruction::StoreZ(var_id) => { | 283 SubInstruction::StoreZ(var_id) => { |
285 let enemy = self.enemy.borrow(); | 284 let z = { |
286 self.set_i32(var_id, enemy.z); | 285 let enemy = self.enemy.borrow(); |
287 } | 286 enemy.z |
288 */ | 287 }; |
288 self.set_i32(var_id, z as i32); | |
289 } | |
289 // 13(int), 20(float), same impl in th06 | 290 // 13(int), 20(float), same impl in th06 |
290 SubInstruction::AddInt(var_id, a, b) => { | 291 SubInstruction::AddInt(var_id, a, b) => { |
291 self.set_i32(var_id, self.get_i32(a) + self.get_i32(b)); | 292 self.set_i32(var_id, self.get_i32(a) + self.get_i32(b)); |
292 } | 293 } |
293 SubInstruction::AddFloat(var_id, a, b) => { | 294 SubInstruction::AddFloat(var_id, a, b) => { |
311 */ | 312 */ |
312 // 16(int), 23(unused) | 313 // 16(int), 23(unused) |
313 SubInstruction::DivideInt(var_id, a, b) => { | 314 SubInstruction::DivideInt(var_id, a, b) => { |
314 self.set_i32(var_id, self.get_i32(a) / self.get_i32(b)); | 315 self.set_i32(var_id, self.get_i32(a) / self.get_i32(b)); |
315 } | 316 } |
316 /* | 317 |
317 SubInstruction::Divide(var_id, a, b) => { | 318 SubInstruction::DivideFloat(var_id, a, b) => { |
318 self.set_f32(var_id as f32, self.get_f32(a) / self.get_f32(b)); | 319 self.set_f32(var_id as f32, self.get_f32(a) / self.get_f32(b)); |
319 } | 320 } |
320 */ | 321 |
321 // 17(int) 24(unused) | 322 // 17(int) 24(unused) |
322 SubInstruction::ModuloInt(var_id, a, b) => { | 323 SubInstruction::ModuloInt(var_id, a, b) => { |
323 self.set_i32(var_id, self.get_i32(a) % self.get_i32(b)); | 324 self.set_i32(var_id, self.get_i32(a) % self.get_i32(b)); |
324 } | 325 } |
325 /* | 326 |
326 SubInstruction::ModuloFloat(var_id, a, b) => { | 327 SubInstruction::ModuloFloat(var_id, a, b) => { |
327 self.set_f32(var_id as f32, self.get_f32(a) % self.get_f32(b)); | 328 self.set_f32(var_id as f32, self.get_f32(a) % self.get_f32(b)); |
328 } | 329 } |
329 */ | 330 |
330 // 18 | 331 // 18 |
331 // setval used by pytouhou, but not in game(???) | 332 // setval used by pytouhou, but not in game(???) |
332 SubInstruction::Increment(var_id) => { | 333 SubInstruction::Increment(var_id) => { |
333 self.set_i32(var_id, self.get_i32(var_id) + 1); | 334 self.set_i32(var_id, self.get_i32(var_id) + 1); |
334 } | 335 } |
336 | |
335 // 19 | 337 // 19 |
336 /* | |
337 SubInstruction::Decrement(var_id) => { | 338 SubInstruction::Decrement(var_id) => { |
338 self.set_i32(var_id, self.get_i32(var_id) - 1); | 339 self.set_i32(var_id, self.get_i32(var_id) - 1); |
339 } | 340 } |
340 */ | 341 |
341 //25 | 342 //25 |
342 SubInstruction::GetDirection(var_id, x1, y1, x2, y2) => { | 343 SubInstruction::GetDirection(var_id, x1, y1, x2, y2) => { |
343 //__ctrandisp2 in ghidra, let's assume from pytouhou it's atan2 | 344 //__ctrandisp2 in ghidra, let's assume from pytouhou it's atan2 |
344 self.set_f32(var_id as f32, (self.get_f32(y2) - self.get_f32(y1)).atan2(self.get_f32(x2) - self.get_f32(x1))); | 345 self.set_f32(var_id as f32, (self.get_f32(y2) - self.get_f32(y1)).atan2(self.get_f32(x2) - self.get_f32(x1))); |
345 } | 346 } |
424 SubInstruction::Return() => { | 425 SubInstruction::Return() => { |
425 // does insane stuff with the stack, not implemented | 426 // does insane stuff with the stack, not implemented |
426 unimplemented!() | 427 unimplemented!() |
427 } | 428 } |
428 // 37 | 429 // 37 |
429 /* | |
430 SubInstruction::CallIfSuperior(sub, param1, param2, a, b) => { | 430 SubInstruction::CallIfSuperior(sub, param1, param2, a, b) => { |
431 if self.get_i32(a) < self.get_i32(b) { | |
432 SubInstruction::Call(sub, param1, param2); | |
433 } | |
434 } | |
435 // 38 | |
436 SubInstruction::CallIfSuperiorOrEqual(sub, param1, param2, a, b) => { | |
437 if self.get_i32(a) <= self.get_i32(b) { | |
438 SubInstruction::Call(sub, param1, param2); | |
439 } | |
440 } | |
441 // 39 | |
442 SubInstruction::CallIfEqual(sub, param1, param2, a, b) => { | |
443 if self.get_i32(a) == self.get_i32(b) { | |
444 SubInstruction::Call(sub, param1, param2); | |
445 } | |
446 } | |
447 // 40 | |
448 SubInstruction::CallIfInferior(sub, param1, param2, a, b) => { | |
449 if self.get_i32(b) < self.get_i32(a) { | |
450 SubInstruction::Call(sub, param1, param2); | |
451 } | |
452 } | |
453 | |
454 // 41 | |
455 SubInstruction::CallIfInferiorOrEqual(sub, param1, param2, a, b) => { | |
431 if self.get_i32(b) <= self.get_i32(a) { | 456 if self.get_i32(b) <= self.get_i32(a) { |
432 SubInstruction::Call(sub, param1, param2); | 457 SubInstruction::Call(sub, param1, param2); |
433 } | 458 } |
434 } | 459 } |
435 */ | 460 //42 |
436 // 38 | 461 SubInstruction::CallIfNotEqual(sub, param1, param2, a, b) => { |
437 /* | 462 if self.get_i32(a) != self.get_i32(b) { |
438 SubInstruction::CallIfSuperiorOrEqual(sub, param1, param2, a, b) => { | |
439 if self.get_i32(b) <= self.get_i32(a) { | |
440 SubInstruction::Call(sub, param1, param2); | 463 SubInstruction::Call(sub, param1, param2); |
441 } | 464 } |
442 } | 465 } |
443 */ | 466 |
444 // 39 | |
445 SubInstruction::CallIfEqual(sub, param1, param2, a, b) => { | |
446 if self.get_i32(b) == self.get_i32(a) { | |
447 SubInstruction::Call(sub, param1, param2); | |
448 } | |
449 } | |
450 // 40 | |
451 /* | |
452 SubInstruction::CallIfEqual(sub, param1, param2, a, b) => { | |
453 if self.get_i32(b) == self.get_i32(a) { | |
454 SubInstruction::Call(sub, param1, param2); | |
455 } | |
456 } | |
457 */ | |
458 //41 | |
459 /* | |
460 SubInstruction::CallIfInferior(sub, param1, param2, a, b) => { | |
461 if self.get_i32(a) < self.get_i32(b) { | |
462 SubInstruction::Call(sub, param1, param2); | |
463 } | |
464 } | |
465 */ | |
466 //42 | |
467 /* | |
468 SubInstruction::CallIfInferiorOrEqual(sub, param1, param2, a, b) => { | |
469 if self.get_i32(a) <= self.get_i32(b) { | |
470 SubInstruction::Call(sub, param1, param2); | |
471 } | |
472 } | |
473 */ | |
474 // 43 | 467 // 43 |
475 SubInstruction::SetPosition(x, y, z) => { | 468 SubInstruction::SetPosition(x, y, z) => { |
476 let mut enemy = self.enemy.borrow_mut(); | 469 let mut enemy = self.enemy.borrow_mut(); |
477 enemy.set_pos(self.get_f32(x), self.get_f32(y), self.get_f32(z)); | 470 enemy.set_pos(self.get_f32(x), self.get_f32(y), self.get_f32(z)); |
478 } | 471 } |
669 let mut laser = enemy.laser_by_id.get(laser_id); | 662 let mut laser = enemy.laser_by_id.get(laser_id); |
670 laser.cancel(); | 663 laser.cancel(); |
671 } | 664 } |
672 } | 665 } |
673 */ | 666 */ |
674 | 667 // 93 |
675 | 668 // TODO: actually implement that hell |
676 | 669 SubInstruction::SetSpellcard(face, number, name) => { |
670 unimplemented!("spellcard start"); | |
671 | |
672 } | |
673 // 94 | |
674 SubInstruction::EndSpellcard() => { | |
675 unimplemented!("spellcard end"); | |
676 | |
677 } | |
678 | |
679 // 95 | |
680 /* | |
681 SubInstruction::PopEnemy(sub, x, y, z, life, bonus_dropped, die_score) => { | |
682 self._pop_enemy(sub, 0, self.get_f32(x), | |
683 self.get_f32(y), | |
684 self.get_f32(z), | |
685 life, bonus_dropped, die_score) | |
686 | |
687 } | |
688 */ | |
689 | |
690 | |
691 // 96 | |
692 /* | |
693 SubInstruction::KillEnemies() => { | |
694 let mut game = self.game.borrow_mut(); | |
695 game.kill_enemies(); | |
696 } | |
697 */ | |
677 | 698 |
678 | 699 |
679 | 700 |
680 // 97 | 701 // 97 |
681 SubInstruction::SetAnim(index) => { | 702 SubInstruction::SetAnim(index) => { |
695 } else { | 716 } else { |
696 enemy.set_anim(default as u8); | 717 enemy.set_anim(default as u8); |
697 Some((end_left as u8, end_right as u8, left as u8, right as u8)) | 718 Some((end_left as u8, end_right as u8, left as u8, right as u8)) |
698 }; | 719 }; |
699 } | 720 } |
721 /* | |
722 // 99 | |
723 SubInstruction::SetAuxAnims(number, script) => { | |
724 assert!(7 < number); | |
725 let mut enemy = self.enemy.borrow_mut(); | |
726 enemy.set_aux_anm(number, script) | |
727 } | |
728 */ | |
700 | 729 |
701 // 100 | 730 // 100 |
702 SubInstruction::SetDeathAnim(index) => { | 731 SubInstruction::SetDeathAnim(index) => { |
703 // TODO: takes 3 parameters in game as u8 unlike our single u32. | 732 // TODO: takes 3 parameters in game as u8 unlike our single u32. |
704 // To reverse! | 733 // To reverse! |
705 let mut enemy = self.enemy.borrow_mut(); | 734 let mut enemy = self.enemy.borrow_mut(); |
706 enemy.death_anim = index; | 735 enemy.death_anim = index; |
707 } | 736 } |
737 // 101 | |
738 /* | |
739 SubInstruction::SetBossMode(value) => { | |
740 let mut enemy = self.enemy.borrow_mut(); | |
741 if value < 0 { | |
742 enemy.set_boss(false); | |
743 } | |
744 else { | |
745 // the boss pointer is written somewhere in memory and overwrote by a 0 when | |
746 // the boss mode is false, might want to look into that | |
747 enemy.set_boss(true); | |
748 } | |
749 } | |
750 */ | |
751 | |
752 // 102 | |
753 // TODO: title says it all | |
754 /* | |
755 SubInstruction::ParticlesVoodooMagic(unk1, unk2, unk3, unk4, unk5) => { | |
756 } | |
757 */ | |
708 | 758 |
709 // 103 | 759 // 103 |
710 SubInstruction::SetHitbox(width, height, depth) => { | 760 SubInstruction::SetHitbox(width, height, depth) => { |
711 let mut enemy = self.enemy.borrow_mut(); | 761 let mut enemy = self.enemy.borrow_mut(); |
712 enemy.set_hitbox(width, height); | 762 enemy.set_hitbox(width, height); |
740 // 107 | 790 // 107 |
741 SubInstruction::SetDeathFlags(death_flags) => { | 791 SubInstruction::SetDeathFlags(death_flags) => { |
742 let mut enemy = self.enemy.borrow_mut(); | 792 let mut enemy = self.enemy.borrow_mut(); |
743 enemy.death_flags = death_flags; | 793 enemy.death_flags = death_flags; |
744 } | 794 } |
795 // 108 | |
796 /* | |
797 SubInstruction::SetDeathCallback(sub) => { | |
798 let mut enemy = self.enemy.borrow_mut(); | |
799 enemy.death_callback.enable(self.switch_to_sub, (sub,)); | |
800 } | |
801 */ | |
745 | 802 |
746 // 109 | 803 // 109 |
747 SubInstruction::MemoryWriteInt(value, index) => { | 804 SubInstruction::MemoryWriteInt(value, index) => { |
748 unimplemented!("not again that damn foe corrupted my ret\\x41\\x41\\x41\\x41"); | 805 unimplemented!("not again that damn foe corrupted my ret\\x41\\x41\\x41\\x41"); |
749 } | 806 } |
807 | |
808 // 110 | |
809 /* | |
810 SubInstruction::KillEnemy(enemy) => { | |
811 let mut game = self.game.borrow_mut(); | |
812 game.kill_enemy(enemy); | |
813 } | |
814 */ | |
815 | |
816 // 111 | |
817 /* | |
818 SubInstruction::SetLife(value) => { | |
819 let mut enemy = self.enemy.borrow_mut(); | |
820 let mut game = self.game.borrow_mut(); | |
821 enemy.life = value; | |
822 game.interface.set_boss_life(); | |
823 } | |
824 */ | |
825 // 112 | |
826 SubInstruction::SetElapsedTime(value) => { | |
827 let mut enemy = self.enemy.borrow_mut(); | |
828 enemy.frame = value as u32; | |
829 } | |
830 // 113 | |
831 /* | |
832 SubInstruction::SetLowLifeTrigger(value) => { | |
833 let mut enemy = self.enemy.borrow_mut(); | |
834 let mut game = self.game.borrow_mut(); | |
835 enemy.low_life_trigger = value; | |
836 game.interface.set_spell_life(); | |
837 } | |
838 */ | |
839 // 114 | |
840 /* | |
841 SubInstruction::SetLowLifeCallback(sub) => { | |
842 let mut enemy = self.enemy.borrow_mut(); | |
843 enemy.low_life_callback.enable(self.switch_to_sub, (sub,)); | |
844 } | |
845 */ | |
846 // 115 | |
847 /* | |
848 SubInstruction::SetTimeout(timeout) => { | |
849 let mut enemy = self.enemy.borrow_mut(); | |
850 enemy.frame = value; | |
851 enemy.timeout = timeout; | |
852 } | |
853 */ | |
854 // 116 | |
855 /* | |
856 SubInstruction::SetTimeoutCallback(sub) => { | |
857 let mut enemy = self.enemy.borrow_mut(); | |
858 enemy.timeout_callback.enable(self.switch_to_sub, (sub,)); | |
859 } | |
860 */ | |
750 | 861 |
751 | 862 |
752 // 117 | 863 // 117 |
753 SubInstruction::SetTouchable(touchable) => { | 864 SubInstruction::SetTouchable(touchable) => { |
754 let mut enemy = self.enemy.borrow_mut(); | 865 let mut enemy = self.enemy.borrow_mut(); |