annotate interpreters/src/th06/std.rs @ 791:a29122662cde

utils: Simplify translate_2d and align Mat4 to 16 bytes This lowers the amount of instructions from 61 to 32 on PowerPC with AltiVec, and from 25 to 14 on amd64 with AVX2.
author Link Mauve <linkmauve@linkmauve.fr>
date Sat, 17 Jan 2026 14:19:58 +0100
parents 7f9b3f5001c2
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
679
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
1 //! Interpreter of STD files.
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
2
757
21b186be2590 Split the Rust version into multiple crates.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 716
diff changeset
3 use touhou_formats::th06::std::{Stage, Call, Instruction};
787
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
4 use crate::th06::interpolator::{Interpolator, Formula};
757
21b186be2590 Split the Rust version into multiple crates.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 716
diff changeset
5 use touhou_utils::math::{Mat4, setup_camera};
679
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
6 use std::cell::RefCell;
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
7 use std::rc::Rc;
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
8
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
9 /// Interpreter for Stage.
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
10 pub struct StageRunner {
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
11 /// XXX: no pub.
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
12 pub stage: Rc<RefCell<Stage>>,
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
13 frame: u32,
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
14
787
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
15 position: Interpolator<f32, 3>,
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
16 direction: Interpolator<f32, 3>,
679
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
17
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
18 /// XXX: no pub.
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
19 pub fog_color: [f32; 4],
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
20 /// XXX: no pub.
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
21 pub fog_near: f32,
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
22 /// XXX: no pub.
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
23 pub fog_far: f32,
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
24 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
25
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
26 impl StageRunner {
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
27 /// Create a new StageRunner attached to a Stage.
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
28 pub fn new(stage: Rc<RefCell<Stage>>) -> StageRunner {
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
29 StageRunner {
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
30 stage,
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
31 frame: 0,
787
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
32 position: Interpolator::new([0., 0., 0.], 0, [0., 0., 0.], 0, Formula::Linear),
7f9b3f5001c2 interpreters: Make Interpolator generic over N
Link Mauve <linkmauve@linkmauve.fr>
parents: 757
diff changeset
33 direction: Interpolator::new([0., 0., 0.], 0, [0., 0., 0.], 0, Formula::Linear),
679
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
34 fog_color: [1.; 4],
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
35 fog_near: 0.,
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
36 fog_far: 1000.,
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
37 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
38 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
39
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
40 /// Advance the simulation one frame.
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
41 pub fn run_frame(&mut self) {
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
42 let stage = self.stage.borrow();
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
43
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
44 for Call { time, instr } in stage.script.iter() {
710
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
45 let time = *time;
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
46 if time != self.frame {
679
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
47 continue;
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
48 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
49
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
50 println!("{} {:?}", time, instr);
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
51
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
52 match *instr {
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
53 Instruction::SetViewpos(x, y, z) => {
710
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
54 self.position.set_start(time, [x, y, z]);
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
55 for Call { time, instr } in stage.script.iter().cloned() {
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
56 if time <= self.frame {
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
57 continue;
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
58 }
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
59 if let Instruction::SetViewpos(x, y, z) = instr {
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
60 self.position.set_end(time, [x, y, z]);
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
61 break;
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
62 }
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
63 }
679
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
64 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
65 Instruction::SetFog(b, g, r, a, near, far) => {
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
66 self.fog_color = [r as f32 / 255., g as f32 / 255., b as f32 / 255., a as f32 / 255.];
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
67 self.fog_near = near;
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
68 self.fog_far = far;
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
69 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
70 Instruction::SetViewpos2(dx, dy, dz) => {
710
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
71 let direction = [dx, dy, dz];
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
72 self.direction.set_start(time, if time == 0 { direction } else { self.direction.values(time) });
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
73 self.direction.set_end_values(direction);
679
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
74 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
75 Instruction::StartInterpolatingViewpos2(frame, _, _) => {
710
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
76 self.direction.set_end_frame(time + frame);
679
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
77 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
78 Instruction::StartInterpolatingFog(frame, _, _) => {
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
79 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
80 Instruction::Unknown(_, _, _) => {
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
81 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
82 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
83 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
84
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
85 self.frame += 1;
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
86 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
87
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
88 /// Generate the model-view matrix for the current frame.
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
89 pub fn get_model_view(&self) -> Mat4 {
710
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
90 let [x, y, z] = self.position.values(self.frame);
679
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
91
710
377c241be559 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 679
diff changeset
92 let [dx, dy, dz] = self.direction.values(self.frame);
679
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
93
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
94 let view = setup_camera(dx, dy, dz);
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
95
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
96 let model = Mat4::new([[1., 0., 0., 0.],
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
97 [0., 1., 0., 0.],
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
98 [0., 0., 1., 0.],
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
99 [-x, -y, -z, 1.]]);
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
100 model * view
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
101 }
6020e33d4fc4 Implement a .std renderer, and its associated VM.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
102 }