annotate python/src/lib.rs @ 796:d876ac2ccfe1 default tip

Pass audio only once to GameRunner This prevents it being recreated every stage change, and playing music over the previous stages’ music.
author Link Mauve <linkmauve@linkmauve.fr>
date Sun, 28 Jun 2026 14:27:03 +0200
parents 2d60a14f4816
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
792
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
1 use png::{BitDepth, ColorType, Transformations};
779
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
2 use pyo3::exceptions::{PyIOError, PyKeyError};
770
f6c287745a67 Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
3 use pyo3::prelude::*;
779
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
4 use pyo3::types::{PyBytes, PyTuple};
783
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
5 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
6 use touhou_formats::th06::pbg3;
779
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
7 use touhou_formats::th06::std as stage;
782
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
8 use touhou_formats::th06::msg;
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
9 use std::collections::{BTreeMap, HashMap};
770
f6c287745a67 Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
10 use std::fs::File;
f6c287745a67 Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
11 use std::io::BufReader;
778
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
12 use std::path::PathBuf;
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
13 use std::sync::{Arc, Mutex};
770
f6c287745a67 Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
14
772
7492d384d122 Rust: Add a Glide renderer (2D only for now)
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 770
diff changeset
15 #[cfg(feature = "glide")]
7492d384d122 Rust: Add a Glide renderer (2D only for now)
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 770
diff changeset
16 mod glide;
7492d384d122 Rust: Add a Glide renderer (2D only for now)
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 770
diff changeset
17
783
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
18 mod audio;
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
19
778
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
20 #[pyclass(module = "libtouhou")]
779
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
21 struct PyModel {
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
22 inner: stage::Model,
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
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
25 #[pymethods]
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
26 impl PyModel {
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
27 #[getter]
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
28 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
29 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
30 }
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
31
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
32 #[getter]
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
33 fn bounding_box(&self) -> [f32; 6] {
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
34 self.inner.bounding_box
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
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
38 #[pyclass(module = "libtouhou")]
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
39 struct PyStage {
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
40 inner: stage::Stage,
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
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
43 #[pymethods]
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
44 impl PyStage {
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
45 #[getter]
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
46 fn models(&self) -> Vec<PyModel> {
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
47 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
48 }
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
49
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
50 #[getter]
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
51 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
52 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
53 }
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
54
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
55 #[getter]
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
56 fn name(&self) -> &str {
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
57 &self.inner.name
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
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
60 #[getter]
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
61 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
62 self.inner.musics.clone()
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
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
65 #[getter]
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
66 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
67 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
68 let (opcode, args) = match call.instr {
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
69 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
70 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
71 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
72 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
73 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
74 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
75 };
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
76 Ok((call.time, opcode, args))
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
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
79 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
80 }
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
81 }
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
82
782
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
83 #[pyclass(module = "libtouhou")]
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
84 struct PyMsg {
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
85 inner: msg::Msg,
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
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
88 #[pymethods]
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
89 impl PyMsg {
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
90 #[getter]
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
91 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
92 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
93 let (opcode, args) = match &call.instr {
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
94 msg::Instruction::Unk1() => (0, ().into_pyobject(py)?),
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
95 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
96 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
97 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
98 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
99 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
100 msg::Instruction::SpawnEnemySprite() => (6, ().into_pyobject(py)?),
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
101 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
102 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
103 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
104 msg::Instruction::Freeze() => (10, ().into_pyobject(py)?),
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
105 msg::Instruction::NextStage() => (11, ().into_pyobject(py)?),
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
106 msg::Instruction::Unk2() => (12, ().into_pyobject(py)?),
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
107 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
108 msg::Instruction::Unk3() => (14, ().into_pyobject(py)?),
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
109 };
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
110 Ok((call.time, opcode, args.unbind()))
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
111 }
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
112 self.inner.scripts.iter().map(|(index, script)| (
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
113 *index,
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
114 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
115 )).collect()
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 }
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
118
778
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
119 /// A loader for Touhou files.
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
120 #[pyclass(module = "libtouhou", subclass)]
778
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
121 #[derive(Default)]
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
122 struct Loader {
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
123 /// The file names to the possible executable.
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
124 #[pyo3(get)]
778
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
125 exe_files: Vec<PathBuf>,
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
126
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
127 /// The path to the game directory.
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
128 #[pyo3(get)]
778
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
129 game_dir: Option<PathBuf>,
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
130
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
131 /// 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
132 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
133 }
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
134
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
135 #[pymethods]
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
136 impl Loader {
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
137 /// 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
138 #[new]
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
139 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
140 Loader {
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
141 exe_files: Vec::new(),
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
142 game_dir,
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
143 known_files: HashMap::new(),
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
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
147 /// Scan the game_dir for archives.
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
148 ///
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
149 /// 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
150 /// and the other ones ignored.
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
151 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
152 for paths in paths_lists.iter() {
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
153 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
154 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
155 game_dir.join(path)
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
156 } else {
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
157 PathBuf::from(path)
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
158 }.to_str().unwrap()).unwrap()
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
159 }).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
160 if found_paths.is_empty() {
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
161 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
162 }
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
163 let path = &found_paths[0];
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
164 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
165 self.exe_files.extend(found_paths);
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
166 } else {
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
167 let pbg3 = pbg3::from_path_buffered(path)?;
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
168 let filenames: Vec<_> = pbg3.list_files().cloned().collect();
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
169 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
170 for name in filenames {
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
171 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
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 }
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
175 Ok(())
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
176 }
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
177
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
178 /// Return the given file as a Vec<u8>.
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
179 fn get_file_internal(&self, name: &str) -> PyResult<Vec<u8>> {
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
180 let name = if let Some((_, name)) = name.rsplit_once('/') {
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
181 name
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
182 } else {
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
183 name
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
184 };
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
185 if let Some(archive) = self.known_files.get(name) {
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
186 let mut archive = archive.lock().unwrap();
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
187 let bytes = archive.get_file(name, true)?;
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
188 Ok(bytes)
779
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
189 } else {
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
190 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
191 }
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
192 }
ee09657d3789 Replace the stage parser with the Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 778
diff changeset
193
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
194 /// 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
195 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
196 let vec = self.get_file_internal(name)?;
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
197 let bytes = PyBytes::new(py, &vec);
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
198 let io = py.import("io")?;
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
199 let bytesio_class = io.dict().get_item("BytesIO")?.unwrap();
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
200 let file = bytesio_class.call1((bytes,))?;
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
201 Ok(file.unbind())
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
202 }
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
203
782
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
204 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
205 let vec = self.get_file_internal(name)?;
781
5b43c42fa680 Stop exposing PBG3 to Python
Link Mauve <linkmauve@linkmauve.fr>
parents: 779
diff changeset
206 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
207 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
208 }
782
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
209
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
210 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
211 let vec = self.get_file_internal(name)?;
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
212 let (_, inner) = msg::Msg::from_slice(&vec).unwrap();
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
213 Ok(Py::new(py, PyMsg { inner })?)
a30ce01b9154 formats: Rewrite msg parsing in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 781
diff changeset
214 }
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
215
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
216 fn get_image(&self, py: Python, name: &str) -> PyResult<Py<Image>> {
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
217 let vec = self.get_file_internal(name)?;
792
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
218 let image = Image::from_rgb_png(&vec);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
219 Py::new(py, image)
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
220 }
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
221
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
222 fn get_image_with_alpha(&self, py: Python, name: &str, alpha: &str) -> PyResult<Py<Image>> {
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
223 let rgb = self.get_file_internal(name)?;
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
224 let alpha = self.get_file_internal(alpha)?;
792
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
225 let image = Image::from_rgb_and_alpha_png(&rgb, &alpha);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
226 Py::new(py, image)
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
227 }
778
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
228 }
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
229
783
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
230 impl Loader {
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
231 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
232 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
233 let (_, inner) = LoopPoints::from_slice(&vec).unwrap();
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
234 Ok(inner)
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
235 }
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
236 }
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
237
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
238 #[pyclass(module = "libtouhou")]
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
239 #[derive(Debug)]
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
240 struct Image {
792
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
241 width: u32,
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
242 height: u32,
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
243 data: Vec<u8>,
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
244 }
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
245
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
246 #[pymethods]
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
247 impl Image {
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
248 #[getter]
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
249 fn dimensions(&self) -> (u32, u32) {
792
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
250 (self.width, self.height)
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
251 }
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
252
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
253 #[getter]
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
254 fn pixels(&self) -> &[u8] {
792
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
255 &self.data
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
256 }
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
257 }
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
258
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
259 impl Image {
792
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
260 fn load_png(data: &[u8], add_alpha: bool) -> (u32, u32, ColorType, Vec<u8>) {
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
261 let cursor = std::io::Cursor::new(data);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
262 let mut decoder = png::Decoder::new(cursor);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
263 // Request either rgb8 or rgba8 data.
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
264 decoder.set_transformations(if add_alpha {
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
265 Transformations::ALPHA
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
266 } else {
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
267 Transformations::EXPAND
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
268 });
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
269 let mut reader = decoder.read_info().unwrap();
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
270 let mut buf = vec![0; reader.output_buffer_size().unwrap()];
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
271 let info = reader.next_frame(&mut buf).unwrap();
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
272 assert_eq!(buf.capacity(), info.buffer_size());
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
273 assert_eq!(info.bit_depth, BitDepth::Eight);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
274 (info.width, info.height, info.color_type, buf)
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
275 }
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
276
792
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
277 fn from_rgb_png(rgb: &[u8]) -> Self {
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
278 let (width, height, color_type, data) = Self::load_png(rgb, true);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
279 assert_eq!(color_type, ColorType::Rgba);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
280 Self { width, height, data }
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
281 }
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
282
792
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
283 fn from_rgb_and_alpha_png(rgb: &[u8], alpha: &[u8]) -> Self {
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
284 let (width, height, color_type, data) = Self::load_png(rgb, false);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
285 if color_type == ColorType::Rgba {
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
286 // TODO: Check which should be used, the alpha channel in the primary PNG, or the alpha
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
287 // mask in the secondary PNG, in case both are present (such as for Patchouli’s face).
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
288 return Self { width, height, data };
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
289 }
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
290
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
291 let (alpha_width, alpha_height, color_type, alpha) = Self::load_png(alpha, false);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
292 assert_eq!(color_type, ColorType::Rgb);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
293 assert_eq!(width, alpha_width);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
294 assert_eq!(height, alpha_height);
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
295
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
296 let data = data
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
297 .as_chunks::<3>().0
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
298 .into_iter()
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
299 .zip(alpha.as_chunks::<3>().0)
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
300 .flat_map(|([r, g, b], [luma, _, _])| [*r, *g, *b, *luma])
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
301 .collect();
11bc22bad1bf python: Replace the image crate with png
Link Mauve <linkmauve@linkmauve.fr>
parents: 786
diff changeset
302 Self { width, height, data }
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
303 }
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
304 }
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
305
784
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
306 /// A loader for Touhou files.
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
307 #[pyclass(module = "libtouhou")]
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
308 struct Prng {
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
309 inner: touhou_utils::prng::Prng,
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
310 }
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
311
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
312 #[pymethods]
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
313 impl Prng {
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
314 #[pyo3(signature = (seed=None))]
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
315 #[new]
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
316 fn new(seed: Option<u16>) -> Prng {
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
317 let inner = touhou_utils::prng::Prng::new(seed);
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
318 Prng { inner }
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
319 }
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
320
795
2d60a14f4816 python: Rewrite the main entrypoint in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 792
diff changeset
321 #[getter]
2d60a14f4816 python: Rewrite the main entrypoint in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 792
diff changeset
322 fn seed(&self) -> u16 {
2d60a14f4816 python: Rewrite the main entrypoint in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 792
diff changeset
323 self.inner.get_seed()
2d60a14f4816 python: Rewrite the main entrypoint in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 792
diff changeset
324 }
2d60a14f4816 python: Rewrite the main entrypoint in Rust
Link Mauve <linkmauve@linkmauve.fr>
parents: 792
diff changeset
325
784
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
326 fn rand_uint16(&mut self) -> u16 {
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
327 self.inner.get_u16()
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
328 }
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
329
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
330 fn rand_uint32(&mut self) -> u32 {
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
331 self.inner.get_u32()
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
332 }
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
333
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
334 fn rand_double(&mut self) -> f64 {
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
335 self.inner.get_f64()
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
336 }
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
337 }
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
338
796
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
339 #[pyclass(module = "libtouhou")]
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
340 pub struct DummyAudio;
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
341
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
342 #[pymethods]
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
343 impl DummyAudio {
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
344 #[new]
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
345 fn new() -> DummyAudio {
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
346 DummyAudio
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
347 }
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
348
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
349 fn load_bgms(&mut self, _bgms: [Option<(String, String)>; 4]) {}
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
350
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
351 fn play_bgm(&mut self, _number: usize) {}
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
352
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
353 fn play(&mut self, _name: &str) {}
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
354 }
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
355
770
f6c287745a67 Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
356 #[pymodule]
775
28d8b892fd06 Python: Upgrade pyo3 from 0.17 to 0.26
Link Mauve <linkmauve@linkmauve.fr>
parents: 772
diff changeset
357 mod libtouhou {
28d8b892fd06 Python: Upgrade pyo3 from 0.17 to 0.26
Link Mauve <linkmauve@linkmauve.fr>
parents: 772
diff changeset
358 #[pymodule_export]
778
816e1f01d650 Partially replace the Loader with a Rust one
Link Mauve <linkmauve@linkmauve.fr>
parents: 775
diff changeset
359 use super::Loader;
775
28d8b892fd06 Python: Upgrade pyo3 from 0.17 to 0.26
Link Mauve <linkmauve@linkmauve.fr>
parents: 772
diff changeset
360
783
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
361 #[pymodule_export]
786
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
362 use super::Image;
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
363
7e940ebeb5fd Replace SDL2_image with the image crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 784
diff changeset
364 #[pymodule_export]
784
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
365 use super::Prng;
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
366
1f152ca95658 Replace pytouhou.utils.random.Random with a Rust version
Link Mauve <linkmauve@linkmauve.fr>
parents: 783
diff changeset
367 #[pymodule_export]
796
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
368 use crate::DummyAudio;
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
369
d876ac2ccfe1 Pass audio only once to GameRunner
Link Mauve <linkmauve@linkmauve.fr>
parents: 795
diff changeset
370 #[pymodule_export]
783
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
371 use crate::audio::Audio;
ec1e06402a97 Replace SDL2_mixer with the kira crate
Link Mauve <linkmauve@linkmauve.fr>
parents: 782
diff changeset
372
772
7492d384d122 Rust: Add a Glide renderer (2D only for now)
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 770
diff changeset
373 #[cfg(feature = "glide")]
775
28d8b892fd06 Python: Upgrade pyo3 from 0.17 to 0.26
Link Mauve <linkmauve@linkmauve.fr>
parents: 772
diff changeset
374 #[pymodule_export]
28d8b892fd06 Python: Upgrade pyo3 from 0.17 to 0.26
Link Mauve <linkmauve@linkmauve.fr>
parents: 772
diff changeset
375 use super::glide::module;
770
f6c287745a67 Rust: Add a libtouhou Python wrapper using pyo3
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
376 }