1pub mod dialogs;
34mod integration;
35#[cfg(feature = "scenes")]
36pub mod scenes;
37pub mod ui;
38pub mod utilities;
39#[cfg(feature = "window_prefs")]
40pub mod window_prefs;
41
42use crate::prelude::{winit, Coord, ALL_KEYS};
43use crate::ui::styles::UiStyle;
44#[cfg(feature = "window_prefs")]
45use crate::window_prefs::WindowPreferences;
46pub use buffer_graphics_lib;
47use buffer_graphics_lib::Graphics;
48use rustc_hash::FxHashMap;
49#[cfg(feature = "serde")]
50use serde::{Deserialize, Serialize};
51use simple_game_utils::prelude::*;
52use thiserror::Error;
53use winit::event::MouseButton;
54pub use winit::event_loop::ControlFlow;
55use winit::keyboard::KeyCode;
56use winit::window::Window;
57
58pub mod prelude {
59 pub use crate::dialogs::*;
60 pub use crate::integration::softbuffer_winit::run;
61 #[cfg(feature = "scenes")]
62 pub use crate::scenes::*;
63 pub use crate::utilities::virtual_key_codes::*;
64 #[cfg(feature = "window_prefs")]
65 pub use crate::window_prefs::*;
66 pub use crate::GraphicsError;
67 pub use crate::MouseData;
68 pub use crate::Options;
69 pub use crate::System;
70 pub use crate::WindowScaling;
71 pub use buffer_graphics_lib::prelude::*;
72 pub use rustc_hash::FxHashSet;
73 pub use simple_game_utils::prelude::*;
74 pub use winit;
75 pub use winit::event::MouseButton;
76 pub use winit::keyboard::KeyCode;
77 pub use winit::window::Window;
78}
79
80#[derive(Error, Debug)]
81pub enum GraphicsError {
82 #[error("Creating a window: {0}")]
83 WindowInit(String),
84 #[error("Saving window pref: {0}")]
85 SavingWindowPref(String),
86 #[cfg(feature = "window_prefs")]
87 #[error("Loading window pref: {0}")]
88 LoadingWindowPref(String),
89 #[error("Invalid pixel array length, expected: {0}, found: {1}")]
90 ImageInitSize(usize, usize),
91 #[error("Both images must be the same size, expected: {0}x{1}, found: {2}x{3}")]
92 ImageBlendSize(usize, usize, usize, usize),
93 #[cfg(feature = "controller")]
94 #[error("Unable to init controller: {0}")]
95 ControllerInit(String),
96 #[error("Initialing Winit: {0}")]
97 WinitInit(#[source] winit::error::EventLoopError),
98}
99
100#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
101#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
102pub enum WindowScaling {
103 Native,
105 Double,
107 Quad,
109}
110
111#[allow(unused_variables)]
112pub trait System {
113 fn keys_used(&self) -> &[KeyCode] {
115 &ALL_KEYS
116 }
117 #[cfg(feature = "window_prefs")]
118 fn window_prefs(&mut self) -> Option<WindowPreferences> {
119 None
120 }
121 fn update(&mut self, timing: &Timing, window: &Window);
122 fn render(&mut self, graphics: &mut Graphics);
123 fn on_mouse_move(&mut self, mouse: &MouseData) {}
124 fn on_mouse_down(&mut self, mouse: &MouseData, button: MouseButton) {}
125 fn on_mouse_up(&mut self, mouse: &MouseData, button: MouseButton) {}
126 fn on_scroll(&mut self, mouse: &MouseData, x_diff: isize, y_diff: isize) {}
127 fn on_key_down(&mut self, keys: Vec<KeyCode>) {}
128 fn on_key_up(&mut self, keys: Vec<KeyCode>) {}
129 fn on_window_closed(&mut self) {}
130 fn on_visibility_changed(&mut self, visible: bool) {}
131 fn on_focus_changed(&mut self, focused: bool) {}
132 fn should_exit(&mut self) -> bool {
133 false
134 }
135}
136
137#[derive(Debug, PartialEq)]
139pub struct Options {
140 pub ups: usize,
143 pub scaling: WindowScaling,
146 pub vsync: bool,
149 pub hide_cursor: bool,
153 pub confine_cursor: bool,
156 pub style: UiStyle,
158 pub control_flow: ControlFlow,
160}
161
162impl Options {
163 pub fn new(
164 ups: usize,
165 scaling: WindowScaling,
166 vsync: bool,
167 hide_cursor: bool,
168 confine_cursor: bool,
169 style: UiStyle,
170 control_flow: ControlFlow,
171 ) -> Self {
172 Self {
173 ups,
174 scaling,
175 vsync,
176 hide_cursor,
177 confine_cursor,
178 style,
179 control_flow,
180 }
181 }
182}
183
184impl Default for Options {
185 fn default() -> Self {
186 Self {
187 ups: 240,
188 scaling: WindowScaling::Double,
189 vsync: true,
190 hide_cursor: false,
191 confine_cursor: false,
192 style: UiStyle::default(),
193 control_flow: ControlFlow::Poll,
194 }
195 }
196}
197
198#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
199#[derive(Debug, Clone, Eq, PartialEq, Default)]
200pub struct MouseData {
201 pub xy: Coord,
202 buttons: FxHashMap<MouseButton, Coord>,
203}
204
205impl MouseData {
206 pub fn any_held(&self) -> bool {
207 !self.buttons.is_empty()
208 }
209
210 pub fn is_down(&self, button: MouseButton) -> Option<Coord> {
212 self.buttons.get(&button).cloned()
213 }
214
215 pub(crate) fn add_up(&mut self, button: MouseButton) {
216 self.buttons.remove(&button);
217 }
218
219 pub(crate) fn add_down(&mut self, xy: Coord, button: MouseButton) {
220 self.buttons.insert(button, xy);
221 }
222}