Mercurial > touhou
annotate python/src/lib.rs @ 783:ec1e06402a97
Replace SDL2_mixer with the kira crate
| author | Link Mauve <linkmauve@linkmauve.fr> |
|---|---|
| date | Fri, 21 Nov 2025 10:21:59 +0100 |
| parents | a30ce01b9154 |
| children | 1f152ca95658 |
| rev | line source |
|---|---|
|
779
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
1 use pyo3::exceptions::{PyIOError, PyKeyError}; |
|
770
f6c287745a67
Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
2 use pyo3::prelude::*; |
|
779
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
3 use pyo3::types::{PyBytes, PyTuple}; |
|
783
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
4 use touhou_formats::th06::pos::LoopPoints; |
|
770
f6c287745a67
Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
5 use touhou_formats::th06::pbg3; |
|
779
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
6 use touhou_formats::th06::std as stage; |
|
782
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
7 use touhou_formats::th06::msg; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
8 use std::collections::{BTreeMap, HashMap}; |
|
770
f6c287745a67
Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
9 use std::fs::File; |
|
f6c287745a67
Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
10 use std::io::BufReader; |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
11 use std::path::PathBuf; |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
12 use std::sync::{Arc, Mutex}; |
|
770
f6c287745a67
Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
13 |
|
772
7492d384d122
Rust: Add a Glide renderer (2D only for now)
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
770
diff
changeset
|
14 #[cfg(feature = "glide")] |
|
7492d384d122
Rust: Add a Glide renderer (2D only for now)
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
770
diff
changeset
|
15 mod glide; |
|
7492d384d122
Rust: Add a Glide renderer (2D only for now)
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
770
diff
changeset
|
16 |
|
783
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
17 mod audio; |
|
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
18 |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
19 #[pyclass(module = "libtouhou")] |
|
779
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
20 struct PyModel { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
21 inner: stage::Model, |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
22 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
23 |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
24 #[pymethods] |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
25 impl PyModel { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
26 #[getter] |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
27 fn quads(&self) -> Vec<(u16, f32, f32, f32, f32, f32)> { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
28 self.inner.quads.iter().map(|quad| (quad.anm_script, quad.pos.x, quad.pos.y, quad.pos.z, quad.size_override.width, quad.size_override.height)).collect() |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
29 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
30 |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
31 #[getter] |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
32 fn bounding_box(&self) -> [f32; 6] { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
33 self.inner.bounding_box |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
34 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
35 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
36 |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
37 #[pyclass(module = "libtouhou")] |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
38 struct PyStage { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
39 inner: stage::Stage, |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
40 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
41 |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
42 #[pymethods] |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
43 impl PyStage { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
44 #[getter] |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
45 fn models(&self) -> Vec<PyModel> { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
46 self.inner.models.clone().into_iter().map(|inner| PyModel { inner }).collect() |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
47 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
48 |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
49 #[getter] |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
50 fn object_instances(&self) -> Vec<(u16, f32, f32, f32)> { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
51 self.inner.instances.iter().map(|instance| (instance.id, instance.pos.x, instance.pos.y, instance.pos.z)).collect() |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
52 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
53 |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
54 #[getter] |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
55 fn name(&self) -> &str { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
56 &self.inner.name |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
57 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
58 |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
59 #[getter] |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
60 fn bgms(&self) -> Vec<Option<(String, String)>> { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
61 self.inner.musics.clone() |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
62 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
63 |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
64 #[getter] |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
65 fn script(&self, py: Python) -> Vec<(u32, u16, Py<PyTuple>)> { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
66 fn call_to_python(py: Python, call: &stage::Call) -> PyResult<(u32, u16, Py<PyTuple>)> { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
67 let (opcode, args) = match call.instr { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
68 stage::Instruction::SetViewpos(x, y, z) => (0, (x, y, z).into_pyobject(py)?.unbind()), |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
69 stage::Instruction::SetFog(r, g, b, _a, near, far) => (1, (r, g, b, near, far).into_pyobject(py)?.unbind()), |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
70 stage::Instruction::SetViewpos2(x, y, z) => (2, (x, y, z).into_pyobject(py)?.unbind()), |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
71 stage::Instruction::StartInterpolatingViewpos2(frame, _unused1, _unused2) => (3, (frame,).into_pyobject(py)?.unbind()), |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
72 stage::Instruction::StartInterpolatingFog(frame, _unused1, _unused2) => (4, (frame,).into_pyobject(py)?.unbind()), |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
73 stage::Instruction::Unknown(unused1, unused2, unused3) => (5, (unused1, unused2, unused3).into_pyobject(py)?.unbind()), |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
74 }; |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
75 Ok((call.time, opcode, args)) |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
76 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
77 |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
78 self.inner.script.iter().map(|call| call_to_python(py, call).unwrap()).collect() |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
79 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
80 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
81 |
|
782
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
82 #[pyclass(module = "libtouhou")] |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
83 struct PyMsg { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
84 inner: msg::Msg, |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
85 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
86 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
87 #[pymethods] |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
88 impl PyMsg { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
89 #[getter] |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
90 fn msgs(&self, py: Python) -> BTreeMap<u8, Vec<(u16, u8, Py<PyTuple>)>> { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
91 fn call_to_python(py: Python, call: &msg::Call) -> PyResult<(u16, u8, Py<PyTuple>)> { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
92 let (opcode, args) = match &call.instr { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
93 msg::Instruction::Unk1() => (0, ().into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
94 msg::Instruction::Enter(side, effect) => (1, (side, effect).into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
95 msg::Instruction::ChangeFace(side, index) => (2, (side, index).into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
96 msg::Instruction::DisplayText(side, index, text) => (3, (side, index, text).into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
97 msg::Instruction::Pause(duration) => (4, (duration,).into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
98 msg::Instruction::Animate(side, effect) => (5, (side, effect).into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
99 msg::Instruction::SpawnEnemySprite() => (6, ().into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
100 msg::Instruction::ChangeMusic(track) => (7, (track,).into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
101 msg::Instruction::DisplayDescription(side, index, text) => (8, (side, index, text).into_pyobject(py)?), |
|
783
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
102 msg::Instruction::ShowScores(unk1) => (9, (unk1,).into_pyobject(py)?), |
|
782
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
103 msg::Instruction::Freeze() => (10, ().into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
104 msg::Instruction::NextStage() => (11, ().into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
105 msg::Instruction::Unk2() => (12, ().into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
106 msg::Instruction::SetAllowSkip(boolean) => (13, (boolean,).into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
107 msg::Instruction::Unk3() => (14, ().into_pyobject(py)?), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
108 }; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
109 Ok((call.time, opcode, args.unbind())) |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
110 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
111 self.inner.scripts.iter().map(|(index, script)| ( |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
112 *index, |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
113 script.into_iter().map(|call| call_to_python(py, call).unwrap()).collect(), |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
114 )).collect() |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
115 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
116 } |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
117 |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
118 /// A loader for Touhou files. |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
119 #[pyclass(module = "libtouhou", subclass)] |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
120 #[derive(Default)] |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
121 struct Loader { |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
122 /// The file names to the possible executable. |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
123 #[pyo3(get)] |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
124 exe_files: Vec<PathBuf>, |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
125 |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
126 /// The path to the game directory. |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
127 #[pyo3(get)] |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
128 game_dir: Option<PathBuf>, |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
129 |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
130 /// A map from inner filenames to the archive containing them. |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
131 known_files: HashMap<String, Arc<Mutex<pbg3::PBG3<BufReader<File>>>>>, |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
132 } |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
133 |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
134 #[pymethods] |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
135 impl Loader { |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
136 /// Create a new Loader for the given game_dir. |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
137 #[new] |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
138 fn new(game_dir: Option<PathBuf>) -> Loader { |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
139 Loader { |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
140 exe_files: Vec::new(), |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
141 game_dir, |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
142 known_files: HashMap::new(), |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
143 } |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
144 } |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
145 |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
146 /// Scan the game_dir for archives. |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
147 /// |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
148 /// paths_lists is a list of ':'-separated glob patterns, the first matching file will be used |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
149 /// and the other ones ignored. |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
150 fn scan_archives(&mut self, paths_lists: Vec<String>) -> PyResult<()> { |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
151 for paths in paths_lists.iter() { |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
152 let found_paths: Vec<_> = paths.split(':').map(|path| { |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
153 glob::glob(if let Some(game_dir) = self.game_dir.as_ref() { |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
154 game_dir.join(path) |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
155 } else { |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
156 PathBuf::from(path) |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
157 }.to_str().unwrap()).unwrap() |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
158 }).flatten().map(Result::unwrap).map(PathBuf::from).collect(); |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
159 if found_paths.is_empty() { |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
160 return Err(PyIOError::new_err(format!("No path found for {paths:?}"))); |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
161 } |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
162 let path = &found_paths[0]; |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
163 if let Some(extension) = path.extension() && extension == "exe" { |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
164 self.exe_files.extend(found_paths); |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
165 } else { |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
166 let pbg3 = pbg3::from_path_buffered(path)?; |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
167 let filenames: Vec<_> = pbg3.list_files().cloned().collect(); |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
168 let pbg3 = Arc::new(Mutex::new(pbg3)); |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
169 for name in filenames { |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
170 self.known_files.insert(name.clone(), Arc::clone(&pbg3)); |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
171 } |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
172 } |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
173 } |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
174 Ok(()) |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
175 } |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
176 |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
177 /// Return the given file as a Vec<u8>. |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
178 fn get_file_internal(&self, name: &str) -> PyResult<Vec<u8>> { |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
179 if let Some(archive) = self.known_files.get(name) { |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
180 let mut archive = archive.lock().unwrap(); |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
181 let bytes = archive.get_file(name, true)?; |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
182 Ok(bytes) |
|
779
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
183 } else { |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
184 Err(PyKeyError::new_err(format!("Unknown file {name:?}"))) |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
185 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
186 } |
|
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
187 |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
188 /// Return the given file as an io.BytesIO object. |
|
782
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
189 fn get_file(&self, py: Python, name: &str) -> PyResult<Py<PyAny>> { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
190 let vec = self.get_file_internal(name)?; |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
191 let bytes = PyBytes::new(py, &vec); |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
192 let io = py.import("io")?; |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
193 let bytesio_class = io.dict().get_item("BytesIO")?.unwrap(); |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
194 let file = bytesio_class.call1((bytes,))?; |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
195 Ok(file.unbind()) |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
196 } |
|
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
197 |
|
782
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
198 fn get_stage(&self, py: Python, name: &str) -> PyResult<Py<PyStage>> { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
199 let vec = self.get_file_internal(name)?; |
|
781
5b43c42fa680
Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents:
779
diff
changeset
|
200 let (_, inner) = stage::Stage::from_slice(&vec).unwrap(); |
|
779
ee09657d3789
Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
778
diff
changeset
|
201 Ok(Py::new(py, PyStage { inner })?) |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
202 } |
|
782
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
203 |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
204 fn get_msg(&self, py: Python, name: &str) -> PyResult<Py<PyMsg>> { |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
205 let vec = self.get_file_internal(name)?; |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
206 let (_, inner) = msg::Msg::from_slice(&vec).unwrap(); |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
207 Ok(Py::new(py, PyMsg { inner })?) |
|
a30ce01b9154
formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents:
781
diff
changeset
|
208 } |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
209 } |
|
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
210 |
|
783
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
211 impl Loader { |
|
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
212 fn get_loop_points(&self, name: &str) -> Result<LoopPoints, ()> { |
|
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
213 let vec = self.get_file_internal(name).unwrap(); |
|
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
214 let (_, inner) = LoopPoints::from_slice(&vec).unwrap(); |
|
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
215 Ok(inner) |
|
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
216 } |
|
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
217 } |
|
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
218 |
|
770
f6c287745a67
Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
219 #[pymodule] |
|
775
28d8b892fd06
Python: Upgrade pyo3 from 0.17 to 0.26
Link Mauve <linkmauve@linkmauve.fr>
parents:
772
diff
changeset
|
220 mod libtouhou { |
|
28d8b892fd06
Python: Upgrade pyo3 from 0.17 to 0.26
Link Mauve <linkmauve@linkmauve.fr>
parents:
772
diff
changeset
|
221 #[pymodule_export] |
|
778
816e1f01d650
Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents:
775
diff
changeset
|
222 use super::Loader; |
|
775
28d8b892fd06
Python: Upgrade pyo3 from 0.17 to 0.26
Link Mauve <linkmauve@linkmauve.fr>
parents:
772
diff
changeset
|
223 |
|
783
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
224 #[pymodule_export] |
|
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
225 use crate::audio::Audio; |
|
ec1e06402a97
Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents:
782
diff
changeset
|
226 |
|
772
7492d384d122
Rust: Add a Glide renderer (2D only for now)
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
770
diff
changeset
|
227 #[cfg(feature = "glide")] |
|
775
28d8b892fd06
Python: Upgrade pyo3 from 0.17 to 0.26
Link Mauve <linkmauve@linkmauve.fr>
parents:
772
diff
changeset
|
228 #[pymodule_export] |
|
28d8b892fd06
Python: Upgrade pyo3 from 0.17 to 0.26
Link Mauve <linkmauve@linkmauve.fr>
parents:
772
diff
changeset
|
229 use super::glide::module; |
|
770
f6c287745a67
Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
230 } |
