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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }