emu_runner/contexts/
gens.rs1use camino::Utf8PathBuf;
2use crate::{EmulatorContext, Error};
3use crate::includes::copy_if_different;
4
5#[derive(Debug, Copy, Clone, PartialEq, Eq)]
6pub enum GensVersion {
7 Ver11A,
8 Ver11B,
9 GitA2425B5,
10}
11
12#[derive(Debug, Clone, PartialEq)]
13pub struct GensContext {
14 pub version: GensVersion,
15 pub start_paused: bool,
16 pub rom: Option<Utf8PathBuf>,
17 pub movie: Option<Utf8PathBuf>,
18 pub lua: Option<Utf8PathBuf>,
19 pub working_dir: Utf8PathBuf,
20}
21impl EmulatorContext for GensContext {
22 fn cmd_name(&self) -> String {
23 #[cfg(target_family = "unix")]
24 { "wine".into() }
25
26 #[cfg(target_family = "windows")]
27 { "Gens.exe".into() }
28 }
29
30 fn args(&self) -> Vec<String> {
31 let mut args = Vec::with_capacity(5);
32
33 #[cfg(target_family = "unix")]
34 {
35 let mut executable = self.working_dir.clone();
36 executable.push("Gens.exe");
37 args.push(executable.to_string());
38 }
39
40 use GensVersion::*;
41 match self.version {
42 Ver11A | Ver11B | GitA2425B5 => { if self.start_paused {
44 args.push("-pause".into());
45 args.push("0".into());
46 }
47 if let Some(rom) = self.rom.as_ref() {
48 args.push("-rom".into());
49 args.push(rom.to_string());
50 }
51 if let Some(movie) = self.movie.as_ref() {
52 args.push("-play".into());
53 args.push(movie.to_string());
54 }
55 if let Some(lua) = self.lua.as_ref() {
56 args.push("-lua".into());
57 args.push(lua.to_string());
58 }
59 },
60 }
61
62 args
63 }
64
65 fn env(&self) -> Vec<(String, String)> {
66 let mut vars = vec![];
67
68 #[cfg(target_family = "unix")]
69 {
70 let mut prefix = self.working_dir.clone();
71 prefix.push(".wine/");
72
73 vars.push(("WINEPREFIX".into(), prefix.to_string()));
74 }
75
76 vars
77 }
78
79 fn prepare(&mut self) -> Result<(), Error> {
80 if let Some(rom) = self.rom.as_ref() {
83 if !rom.is_file() {
84 return Err(Error::MissingRom(rom.clone()));
85 }
86 let mut dest = self.working_dir.clone();
87 dest.push(rom.file_name().unwrap());
88
89 copy_if_different(&std::fs::read(rom)?, dest)?;
90
91 self.rom = Some(rom.file_name().unwrap().into());
92 }
93 if let Some(movie) = self.movie.as_ref() {
94 if !movie.is_file() {
95 return Err(Error::MissingMovie(movie.clone()));
96 }
97
98 if !movie.is_absolute() {
100 let mut dest = self.working_dir.clone();
101 dest.push(movie.file_name().unwrap());
102
103 copy_if_different(&std::fs::read(movie)?, dest)?;
104
105 self.movie = Some(movie.file_name().unwrap().into());
106 }
107 }
108 if let Some(lua) = self.lua.as_ref() {
109 if !lua.is_file() {
110 return Err(Error::MissingLua(lua.clone()));
111 }
112
113 if !lua.is_absolute() {
115 let mut dest = self.working_dir.clone();
116 dest.push(lua.file_name().unwrap());
117
118 copy_if_different(&std::fs::read(lua)?, dest)?;
119
120 self.lua = Some(lua.file_name().unwrap().into());
121 }
122 }
123
124 Ok(())
125 }
126
127 fn working_dir(&self) -> Utf8PathBuf {
128 self.working_dir.clone()
129 }
130}
131impl GensContext {
132 pub fn new<P: Into<Utf8PathBuf>>(working_dir: P, version: GensVersion) -> Result<Self, Error> {
137 let mut working_dir = working_dir.into();
138 if working_dir.is_file() {
139 working_dir.pop();
140 }
141
142 working_dir = working_dir.canonicalize_utf8().unwrap_or(working_dir);
143
144 let mut detect_exe = working_dir.clone();
145 detect_exe.push("Gens.exe");
146 if working_dir.is_file() || !working_dir.exists() || !detect_exe.is_file() {
147 return Err(Error::MissingExecutable(detect_exe));
148 }
149
150 Ok(Self {
151 version,
152 start_paused: false,
153 rom: None,
154 movie: None,
155 lua: None,
156 working_dir,
157 })
158 }
159
160 pub fn with_pause(self, start_paused: bool) -> Self {
161 Self {
162 start_paused,
163 ..self
164 }
165 }
166
167 pub fn with_rom<P: Into<Utf8PathBuf>>(self, rom: P) -> Self {
168 Self {
169 rom: Some(rom.into()),
170 ..self
171 }
172 }
173
174 pub fn with_movie<P: Into<Utf8PathBuf>>(self, movie: P) -> Self {
175 Self {
176 movie: Some(movie.into()),
177 ..self
178 }
179 }
180
181 pub fn with_lua<P: Into<Utf8PathBuf>>(self, lua: P) -> Self {
182 Self {
183 lua: Some(lua.into()),
184 ..self
185 }
186 }
187}