Compare commits

..

9 commits

Author SHA1 Message Date
Gered 1f564253e3 Merge branch 'master' into 3dmath 2024-09-07 23:11:15 -04:00
Gered 16eb66b219 address a number of cargo warnings and clippy lints
while also ignored some bullshit clippy lints
2024-09-07 21:21:49 -04:00
Gered 040e480dd0 fix events::adding_and_removing_listeners test failure in release mode
best guess is that release mode optimizations collapsed these two
functions into one, because in release mode the assertion that would
fail was:

    assert!(listeners.add(other_dummy_listener));

which would mean that `listeners.add()` thought it was trying to add
a duplicate listener function.

adding dummy println's is a simple way to ensure that the compiler
won't try to collapse these thinking that they are the same function.
2024-09-07 17:12:34 -04:00
Gered d9e26556e6 fix simd imports 2024-09-07 16:51:36 -04:00
Gered ed95332699 update toolchain 2024-09-07 16:51:24 -04:00
Gered c7d6bd8aef revert app_root_dir usages in examples. re-org example asset files
ultimately, cargo workspaces are kind of weird. you can do things like
`cargo run` from the top-level cargo.toml file and run an individual
sub-module via `--bin`, or you can go to that sub-module's directory
where it's own cargo.toml is, and `cargo run` directly from there.

the current working directory will be different in each case, and this
difference can be very annoying when you want to do seemingly-logical
things like organize sub-module "asset" files (e.g. images, and other
types of data files that aren't code) within that sub-module's
directory. in this case, how do you write code in that sub-module that
can load those asset files in a way that will work in BOTH of the
aforementioned scenarios for `cargo run`?

you can't really! some people use the `CARGO_MANIFEST_DIR` environment
variable that cargo sets when running any given cargo module, but this
is only a valid method for obtaining the module's root directory when
running from a cargo command ... which you won't be doing when running
within a debugger! likely you or your IDE invoked the debugger process
against the already built executable directly, so `CARGO_MANIFEST_DIR`
will not be set and you're back to square one!

super annoying!

as such, i am now giving up and am just doing what it seems like most
other cargo projects that utilize workspaces do ... place all the
assets for all sub-modules together in the same directory, relative
to the workspace root.

why go with this approach?

because it works under the most common scenarios (but NOT all!):
- running via `cargo run --bin` from the workspace root
- debugging via gdb/lldb etc using the workspace root as the cwd

these seem to be the most common ways to do each type of task from
any rust-equipped editor/IDE that i've seen so far.
2024-09-05 22:35:20 -04:00
Gered 4d359f3e3c update all explicit Path instance allocation and use
previously, there were a ton of places that were allocating new Path
instances via `Path::new` for the purpose of creating a path to be
passed into a function as a Path argument

this has now been simplified everywhere by updating all functions
and methods that previously took Path arguments to instead take
AsRef<Path> arguments, allowing much more flexibility in the types
of path arguments passed in
2024-09-04 00:31:30 -04:00
Gered a18aee300d ignore some clippy warnings 2024-09-03 00:06:52 -04:00
Gered 0cbd5366fd add app_root_dir helper function. integrate with all examples 2024-09-03 00:00:07 -04:00
92 changed files with 1054 additions and 766 deletions

View file

@ -11,15 +11,15 @@ struct AudioChannelStatus {
playing: bool, playing: bool,
} }
fn load_and_convert_wav(path: &Path, target_spec: &AudioSpec) -> Result<AudioBuffer> { fn load_and_convert_wav(path: impl AsRef<Path>, target_spec: &AudioSpec) -> Result<AudioBuffer> {
let sound = AudioBuffer::load_wav_file(path)?; let sound = AudioBuffer::load_wav_file(&path)?;
let original_spec = *sound.spec(); let original_spec = *sound.spec();
let sound = sound.convert(target_spec)?; let sound = sound.convert(target_spec)?;
let final_spec = *sound.spec(); let final_spec = *sound.spec();
if original_spec != final_spec { if original_spec != final_spec {
println!("{:?} was converted from {:?} to {:?}", path, original_spec, final_spec); println!("{:?} was converted from {:?} to {:?}", path.as_ref(), original_spec, final_spec);
} else { } else {
println!("{:?} did not need to be converted from {:?}", path, original_spec); println!("{:?} did not need to be converted from {:?}", path.as_ref(), original_spec);
} }
Ok(sound) Ok(sound)
} }
@ -28,6 +28,7 @@ pub struct SineWaveGenerator {
t: usize, t: usize,
} }
#[allow(clippy::new_without_default)]
impl SineWaveGenerator { impl SineWaveGenerator {
pub fn new() -> Self { pub fn new() -> Self {
SineWaveGenerator { t: 0 } SineWaveGenerator { t: 0 }
@ -58,11 +59,11 @@ fn main() -> Result<()> {
let mut volume = 1.0; let mut volume = 1.0;
let sounds = [ let sounds = [
load_and_convert_wav(Path::new("./assets/pickup-coin.wav"), system.res.audio.spec())?, load_and_convert_wav("./assets/pickup-coin.wav", system.res.audio.spec())?,
load_and_convert_wav(Path::new("./assets/powerup.wav"), system.res.audio.spec())?, load_and_convert_wav("./assets/powerup.wav", system.res.audio.spec())?,
load_and_convert_wav(Path::new("./assets/explosion.wav"), system.res.audio.spec())?, load_and_convert_wav("./assets/explosion.wav", system.res.audio.spec())?,
load_and_convert_wav(Path::new("./assets/jump.wav"), system.res.audio.spec())?, load_and_convert_wav("./assets/jump.wav", system.res.audio.spec())?,
load_and_convert_wav(Path::new("./assets/laser-shoot.wav"), system.res.audio.spec())?, load_and_convert_wav("./assets/laser-shoot.wav", system.res.audio.spec())?,
]; ];
let mut statuses = [AudioChannelStatus { size: 0, position: 0, playing: false }; NUM_CHANNELS]; let mut statuses = [AudioChannelStatus { size: 0, position: 0, playing: false }; NUM_CHANNELS];
@ -154,7 +155,7 @@ fn main() -> Result<()> {
for index in 0..NUM_CHANNELS { for index in 0..NUM_CHANNELS {
let channel = &audio_device[index]; let channel = &audio_device[index];
let mut status = &mut statuses[index]; let status = &mut statuses[index];
status.playing = channel.playing; status.playing = channel.playing;
status.position = channel.position; status.position = channel.position;
status.size = channel.data.len(); status.size = channel.data.len();
@ -183,8 +184,7 @@ fn main() -> Result<()> {
system.res.video.print_string("Audio Channels", 16, 32, FontRenderOpts::Color(14), &system.res.font); system.res.video.print_string("Audio Channels", 16, 32, FontRenderOpts::Color(14), &system.res.font);
let mut y = 48; let mut y = 48;
for index in 0..NUM_CHANNELS { for (index, status) in statuses.iter().enumerate() {
let status = &statuses[index];
system.res.video.print_string( system.res.video.print_string(
&format!( &format!(
"channel {} - {} {}", "channel {} - {} {}",

View file

@ -1,5 +1,3 @@
use std::path::Path;
use anyhow::Result; use anyhow::Result;
use ggdt::prelude::*; use ggdt::prelude::*;
@ -26,7 +24,7 @@ fn main() -> Result<()> {
let font = BitmaskFont::new_vga_font()?; let font = BitmaskFont::new_vga_font()?;
let (balls_bmp, balls_palette) = IndexedBitmap::load_pcx_file(Path::new("./assets/balls.pcx"))?; let (balls_bmp, balls_palette) = IndexedBitmap::load_pcx_file("./assets/balls.pcx")?;
system.res.palette = balls_palette.clone(); system.res.palette = balls_palette.clone();
let mut sprites = Vec::<IndexedBitmap>::new(); let mut sprites = Vec::<IndexedBitmap>::new();
@ -62,8 +60,7 @@ fn main() -> Result<()> {
} }
if system.res.keyboard.is_key_up(Scancode::S) { if system.res.keyboard.is_key_up(Scancode::S) {
for i in 0..NUM_BALLS { for ball in balls.iter_mut() {
let ball = &mut balls[i];
ball.x += ball.dir_x; ball.x += ball.dir_x;
ball.y += ball.dir_y; ball.y += ball.dir_y;
@ -72,26 +69,22 @@ fn main() -> Result<()> {
ball.dir_x = -ball.dir_x; ball.dir_x = -ball.dir_x;
ball.x = 0; ball.x = 0;
} }
} else { } else if ball.x >= (system.res.video.width() - BALL_WIDTH) as i32 {
if ball.x >= (system.res.video.width() - BALL_WIDTH) as i32 {
ball.dir_x = -ball.dir_x; ball.dir_x = -ball.dir_x;
ball.x = (system.res.video.width() - BALL_WIDTH) as i32; ball.x = (system.res.video.width() - BALL_WIDTH) as i32;
} }
}
if ball.dir_y < 0 { if ball.dir_y < 0 {
if ball.y <= 0 { if ball.y <= 0 {
ball.dir_y = -ball.dir_y; ball.dir_y = -ball.dir_y;
ball.y = 0; ball.y = 0;
} }
} else { } else if ball.y >= (system.res.video.height() - BALL_HEIGHT) as i32 {
if ball.y >= (system.res.video.height() - BALL_HEIGHT) as i32 {
ball.dir_y = -ball.dir_y; ball.dir_y = -ball.dir_y;
ball.y = (system.res.video.height() - BALL_HEIGHT) as i32; ball.y = (system.res.video.height() - BALL_HEIGHT) as i32;
} }
} }
} }
}
system.update()?; system.update()?;
system.res.video.clear(2); system.res.video.clear(2);

Binary file not shown.

View file

@ -114,8 +114,8 @@ fn update_system_collision(context: &mut Context) {
let mut velocities = context.entities.components_mut::<Velocity>(); let mut velocities = context.entities.components_mut::<Velocity>();
for (entity, _) in bounceables.iter() { for (entity, _) in bounceables.iter() {
let mut position = positions.get_mut(entity).unwrap(); let position = positions.get_mut(entity).unwrap();
let mut velocity = velocities.get_mut(entity).unwrap(); let velocity = velocities.get_mut(entity).unwrap();
let mut bounced = false; let mut bounced = false;
if position.0.x as i32 <= 0 || position.0.x as i32 + BALL_SIZE >= context.system.res.video.right() as i32 { if position.0.x as i32 <= 0 || position.0.x as i32 + BALL_SIZE >= context.system.res.video.right() as i32 {

View file

@ -1,5 +1,3 @@
use std::path::Path;
use anyhow::Result; use anyhow::Result;
use ggdt::prelude::*; use ggdt::prelude::*;

View file

@ -25,7 +25,7 @@ impl Game {
pub fn new(mut system: System<DosLike>) -> Result<Self> { pub fn new(mut system: System<DosLike>) -> Result<Self> {
let font = BitmaskFont::new_vga_font()?; let font = BitmaskFont::new_vga_font()?;
let (balls_bmp, balls_palette) = IndexedBitmap::load_pcx_file(Path::new("./assets/balls.pcx"))?; let (balls_bmp, balls_palette) = IndexedBitmap::load_pcx_file("./assets/balls.pcx")?;
system.res.palette = balls_palette.clone(); system.res.palette = balls_palette.clone();
let mut sprites = Vec::new(); let mut sprites = Vec::new();

View file

@ -1,5 +1,4 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::path::Path;
use std::rc::Rc; use std::rc::Rc;
use anyhow::Result; use anyhow::Result;
@ -91,17 +90,17 @@ impl AppContext<Standard> for GameContext {
impl GameContext { impl GameContext {
pub fn new(system: System<Standard>) -> Result<Self> { pub fn new(system: System<Standard>) -> Result<Self> {
let palette = load_palette(Path::new("./assets/db16.pal"))?; let palette = load_palette("./assets/db16.pal")?;
let font = load_font(Path::new("./assets/dp.fnt"))?; let font = load_font("./assets/dp.fnt")?;
let small_font = load_font(Path::new("./assets/small.fnt"))?; let small_font = load_font("./assets/small.fnt")?;
let tiles = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/tiles.pcx"))?); let tiles = Rc::new(load_bitmap_atlas_autogrid("./assets/tiles.pcx")?);
let green_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/green_slime.pcx"))?); let green_slime = Rc::new(load_bitmap_atlas_autogrid("./assets/green_slime.pcx")?);
let blue_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/blue_slime.pcx"))?); let blue_slime = Rc::new(load_bitmap_atlas_autogrid("./assets/blue_slime.pcx")?);
let orange_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/orange_slime.pcx"))?); let orange_slime = Rc::new(load_bitmap_atlas_autogrid("./assets/orange_slime.pcx")?);
let tilemap = TileMap::load_from(Path::new("./assets/arena.map.json"))?; let tilemap = TileMap::load_from("./assets/arena.map.json")?;
let entities = Entities::new(); let entities = Entities::new();
let component_systems = ComponentSystems::new(); let component_systems = ComponentSystems::new();

View file

@ -369,7 +369,7 @@ pub fn remove_entity(entities: &mut Entities, entity: EntityId) {
pub fn set_entity_activity(entities: &mut Entities, entity: EntityId, new_activity: EntityActivity) { pub fn set_entity_activity(entities: &mut Entities, entity: EntityId, new_activity: EntityActivity) {
let mut activities = entities.components_mut::<Activity>(); let mut activities = entities.components_mut::<Activity>();
let mut activity = activities.get_mut(&entity).unwrap(); let activity = activities.get_mut(&entity).unwrap();
// only change the activity, and more importantly, the animation if we are actually applying // only change the activity, and more importantly, the animation if we are actually applying
// an actual activity change from what it was before // an actual activity change from what it was before

View file

@ -85,12 +85,13 @@ impl AppState<GameContext> for DemoState {
} }
}); });
if !ui.is_any_hovered() && !ui.is_any_focused() { if !ui.is_any_hovered()
if context.core.system.res.mouse.is_button_down(MouseButton::Right) { && !ui.is_any_focused()
&& context.core.system.res.mouse.is_button_down(MouseButton::Right)
{
context.core.camera_x -= context.core.system.res.mouse.x_delta() * 2; context.core.camera_x -= context.core.system.res.mouse.x_delta() * 2;
context.core.camera_y -= context.core.system.res.mouse.y_delta() * 2; context.core.camera_y -= context.core.system.res.mouse.y_delta() * 2;
} }
}
context.support.do_events(&mut context.core); context.support.do_events(&mut context.core);
context.support.component_systems.update(&mut context.core); context.support.component_systems.update(&mut context.core);

View file

@ -1,17 +1,19 @@
use std::path::Path;
use crate::tilemap::{TILE_HEIGHT, TILE_WIDTH}; use crate::tilemap::{TILE_HEIGHT, TILE_WIDTH};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use ggdt::prelude::*; use ggdt::prelude::*;
pub fn load_palette(path: &std::path::Path) -> Result<Palette> { pub fn load_palette(path: impl AsRef<Path>) -> Result<Palette> {
Palette::load_from_file(path, PaletteFormat::Vga).context(format!("Loading palette: {:?}", path)) Palette::load_from_file(&path, PaletteFormat::Vga).context(format!("Loading palette: {:?}", path.as_ref()))
} }
pub fn load_font(path: &std::path::Path) -> Result<BitmaskFont> { pub fn load_font(path: impl AsRef<Path>) -> Result<BitmaskFont> {
BitmaskFont::load_from_file(path).context(format!("Loading font: {:?}", path)) BitmaskFont::load_from_file(&path).context(format!("Loading font: {:?}", path.as_ref()))
} }
pub fn load_bitmap_atlas_autogrid(path: &std::path::Path) -> Result<BitmapAtlas<RgbaBitmap>> { pub fn load_bitmap_atlas_autogrid(path: impl AsRef<Path>) -> Result<BitmapAtlas<RgbaBitmap>> {
let (bmp, _) = RgbaBitmap::load_file(path).context(format!("Loading bitmap atlas: {:?}", path))?; let (bmp, _) = RgbaBitmap::load_file(&path).context(format!("Loading bitmap atlas: {:?}", path.as_ref()))?;
let mut atlas = BitmapAtlas::new(bmp); let mut atlas = BitmapAtlas::new(bmp);
atlas.add_grid(TILE_WIDTH, TILE_HEIGHT)?; atlas.add_grid(TILE_WIDTH, TILE_HEIGHT)?;
Ok(atlas) Ok(atlas)

View file

@ -1,3 +1,5 @@
use std::path::Path;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use ggdt::prelude::*; use ggdt::prelude::*;
@ -16,10 +18,10 @@ pub struct TileMap {
} }
impl TileMap { impl TileMap {
pub fn load_from(path: &std::path::Path) -> Result<Self> { pub fn load_from(path: impl AsRef<Path>) -> Result<Self> {
let f = std::fs::File::open(path)?; let f = std::fs::File::open(&path)?;
let reader = std::io::BufReader::new(f); let reader = std::io::BufReader::new(f);
serde_json::from_reader(reader).context(format!("Loading json tilemap: {:?}", path)) serde_json::from_reader(reader).context(format!("Loading json tilemap: {:?}", path.as_ref()))
} }
#[inline] #[inline]

View file

@ -1,9 +0,0 @@
{
"width":40,
"height":30,
"layers":[
[96,96,96,96,96,96,96,96,96,96,96,96,16,17,16,16,16,16,16,17,17,32,16,16,16,16,16,32,16,16,16,16,16,16,16,16,16,33,16,16,96,96,96,96,96,96,96,96,96,96,96,16,17,17,17,32,17,32,16,16,32,16,16,32,16,16,16,16,16,16,32,16,33,16,16,16,16,16,16,16,96,96,96,96,96,96,96,96,96,96,181,178,178,178,178,183,32,16,17,181,178,178,178,178,178,178,178,178,178,178,178,183,16,16,16,16,16,16,16,32,96,96,96,96,96,96,96,96,96,181,195,16,32,17,17,193,178,178,178,195,16,16,16,16,16,16,32,16,16,16,16,193,178,183,16,32,16,16,16,16,96,96,96,96,96,96,96,181,178,195,16,16,16,32,17,17,17,17,32,16,16,16,33,16,16,16,16,16,16,16,16,16,16,193,183,16,16,16,33,16,96,96,96,96,96,96,181,195,32,16,16,16,16,16,16,16,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,32,16,193,183,16,16,16,16,16,17,16,16,96,181,195,16,16,33,16,16,16,16,16,32,16,16,16,16,16,32,16,16,16,16,48,48,48,48,16,16,16,16,16,196,16,16,16,16,32,16,17,16,181,195,16,16,16,16,16,32,16,16,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,16,16,32,193,183,16,32,16,8,8,8,181,195,16,16,16,16,17,32,16,16,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,196,16,16,16,7,7,7,196,16,32,16,32,17,17,17,16,16,16,16,33,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,48,48,16,16,193,183,16,32,7,7,181,195,16,16,16,16,16,32,16,16,16,16,16,16,16,16,16,32,16,16,16,48,48,48,48,48,48,48,48,48,48,48,48,32,16,196,32,16,7,7,196,16,16,32,16,16,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,48,48,16,16,16,196,16,16,7,7,196,8,8,16,16,16,16,16,16,32,16,16,16,16,32,16,16,16,16,16,16,16,16,48,48,48,48,48,48,48,48,16,16,16,16,196,17,16,7,7,196,7,7,16,16,16,16,16,16,16,16,16,33,16,16,16,16,16,16,16,16,16,32,16,16,48,48,48,48,48,16,16,16,16,16,196,17,16,7,7,196,7,7,16,16,16,16,16,33,16,16,16,16,16,16,16,16,16,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,196,17,16,16,16,196,16,33,16,16,16,16,16,16,16,16,16,16,16,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,196,32,16,16,16,196,16,16,16,16,16,32,16,16,16,16,32,16,16,16,32,16,16,16,16,16,16,16,16,32,16,16,16,16,16,16,16,16,16,16,196,16,16,16,16,196,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,32,16,16,16,16,16,16,16,33,16,16,16,16,16,32,16,196,16,33,32,16,196,16,16,16,16,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,33,16,16,16,16,16,16,16,16,16,16,16,16,16,196,32,16,16,16,196,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,32,16,16,16,16,16,196,16,16,16,16,193,183,16,16,48,48,48,48,48,16,16,16,16,16,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,196,32,16,32,16,33,196,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,196,16,16,16,16,16,193,183,48,48,48,48,48,48,48,48,16,16,32,16,16,16,16,16,16,16,16,33,16,16,16,16,16,16,16,16,16,16,16,16,196,16,16,16,32,16,16,196,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,32,16,196,16,16,16,16,16,16,193,183,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,181,195,16,16,16,16,16,16,16,193,183,48,48,48,48,48,48,48,48,48,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,196,16,16,16,16,16,16,16,16,16,193,178,178,183,48,48,48,48,48,48,48,48,16,16,16,16,16,32,16,16,16,16,32,16,16,16,16,16,16,181,195,16,16,16,32,16,16,33,16,32,16,16,16,193,178,178,178,178,178,178,178,178,183,16,32,16,16,16,16,16,33,16,16,16,16,16,16,181,178,195,32,16,16,16,16,16,16,16,16,16,16,32,16,16,16,16,16,16,16,33,32,17,193,178,178,178,178,178,178,178,178,178,178,178,178,178,178,195,16,16,16,16,16,48,16,16,32,16,16,16,16,16,16,16,16,16,16,32,16,16,16,16,32,16,16,32,16,16,16,32,16,16,16,33,16,16,32,16,16,16,16,16,48,48],
[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,87,-1,104,108,108,108,105,-1,-1,-1,-1,-1,80,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,98,105,-1,-1,-1,26,-1,26,80,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,27,-1,-1,-1,80,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,80,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,80,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,266,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,80,-1,266,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,26,-1,-1,80,108,108,108,97,-1,-1,-1,-1,266,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,49,51,-1,-1,-1,-1,52,50,-1,-1,-1,-1,-1,-1,-1,-1,46,46,46,102,-1,-1,27,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,49,51,-1,-1,-1,-1,-1,-1,27,-1,52,50,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,51,-1,-1,26,-1,-1,-1,-1,-1,-1,27,52,50,-1,-1,-1,-1,-1,-1,-1,-1,-1,266,-1,-1,-1,-1,-1,-1,-1,-1,80,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,278,-1,-1,-1,-1,52,-1,-1,-1,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,26,-1,-1,-1,-1,67,-1,-1,27,279,-1,-1,294,-1,-1,-1,-1,-1,-1,-1,-1,-1,83,-1,-1,-1,46,46,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,65,67,-1,-1,-1,-1,-1,-1,26,-1,-1,266,68,-1,-1,-1,-1,86,-1,-1,-1,-1,-1,29,-1,-1,-1,-1,-1,-1,26,-1,-1,-1,-1,-1,-1,-1,-1,27,-1,65,67,-1,-1,-1,-1,-1,-1,-1,-1,68,66,-1,-1,-1,-1,86,-1,-1,-1,-1,-1,29,-1,27,-1,80,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,65,67,-1,-1,-1,-1,-1,68,66,-1,-1,26,-1,-1,86,-1,-1,-1,-1,-1,29,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,86,14,14,-1,14,14,-1,80,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,86,-1,282,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,80,-1,-1,-1,-1,104,-1,282,-1,-1,-1,259,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,26,-1,80,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,80,-1,281,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,49,51,-1,-1,-1,-1,-1,52,-1,-1,-1,-1,-1,-1,-1,80,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,80,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,52,-1,-1,-1,-1,-1,-1,-1,-1,-1,278,-1,-1,278,-1,-1,266,27,-1,278,-1,-1,-1,-1,26,-1,-1,-1,-1,-1,-1,-1,-1,26,-1,-1,-1,-1,-1,27,-1,50,-1,-1,-1,-1,-1,-1,-1,-1,294,-1,-1,294,-1,27,279,-1,-1,294,-1,-1,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,52,50,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,278,-1,-1,-1,-1,266,-1,-1,-1,-1,-1,-1,-1,-1,52,50,-1,-1,-1,-1,-1,-1,-1,-1,278,-1,-1,278,-1,-1,278,-1,-1,80,-1,-1,-1,-1,26,-1,294,-1,-1,-1,-1,-1,27,-1,-1,-1,-1,-1,-1,-1,-1,266,52,-1,-1,-1,27,279,-1,-1,294,-1,-1,294,-1,-1,294,-1,266,-1,-1,-1,26,-1,-1,-1,-1,-1,260,-1,-1,-1,-1,-1,-1,27,-1,-1,-1,26,-1,-1,-1,50,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,27,-1,-1,27,-1,49,-1,278,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,266,-1,-1,-1,-1,-1,-1,-1,27,-1,-1,-1,-1,-1,49,51,-1,294,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,27,-1,49,51,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,49,51,27,-1],
[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,-1,-1,-1,-1,-1,-1,-1,-1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,-1,-1,-1,-1,-1,-1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,-1,-1,-1,-1,-1,-1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,-1,-1,-1,-1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1,0,1,1,0,1,1,1,1,1,1,1,0,-1,-1,-1,-1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,-1,-1,-1,-1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,-1,-1,-1,-1,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,-1,-1,-1,-1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,-1,-1,-1,-1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,-1,-1,-1,-1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,-1,-1,-1,-1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,-1,-1,-1,-1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,-1,-1,-1,-1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,-1,-1,-1,-1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,-1,-1,-1,-1,-1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,-1,-1,-1,-1,-1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,-1,-1,-1,-1,-1,-1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,-1,-1,-1,-1,-1,-1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,0,1,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -381,7 +381,7 @@ pub struct Pickuper;
pub fn init_everything( pub fn init_everything(
context: &mut Game, context: &mut Game,
map_file: &Path, map_file: impl AsRef<Path>,
min_spawn_time: f32, min_spawn_time: f32,
max_spawn_time: f32, max_spawn_time: f32,
max_slimes: usize, max_slimes: usize,

View file

@ -105,7 +105,7 @@ fn move_entity_with_collision(
pub fn set_entity_activity(entities: &mut Entities, entity: EntityId, new_activity: EntityActivity) { pub fn set_entity_activity(entities: &mut Entities, entity: EntityId, new_activity: EntityActivity) {
let mut activities = entities.components_mut::<Activity>(); let mut activities = entities.components_mut::<Activity>();
let mut activity = activities.get_mut(&entity).unwrap(); let activity = activities.get_mut(&entity).unwrap();
// only change the activity, and more importantly, the animation if we are actually applying // only change the activity, and more importantly, the animation if we are actually applying
// an actual activity change from what it was before // an actual activity change from what it was before
@ -215,7 +215,7 @@ pub fn attack(context: &mut Core, entity: EntityId) {
} }
} }
pub fn hit_entity(context: &mut Core, target: EntityId, source: EntityId, damage: i32, damage_position: Vector2) { pub fn hit_entity(context: &mut Core, target: EntityId, _source: EntityId, damage: i32, damage_position: Vector2) {
let position; let position;
{ {
let positions = context.entities.components::<Position>(); let positions = context.entities.components::<Position>();
@ -248,15 +248,15 @@ pub fn stop_attack(context: &mut Core, entity: EntityId) {
remove_entity_attachment(&mut context.entities, entity); remove_entity_attachment(&mut context.entities, entity);
} }
pub fn pickup(context: &mut Core, picked_up_by: EntityId, picked_up: EntityId) { pub fn pickup(context: &mut Core, _picked_up_by: EntityId, picked_up: EntityId) {
let kind; let _kind;
let position; let position;
{ {
let positions = context.entities.components::<Position>(); let positions = context.entities.components::<Position>();
position = positions.get(&picked_up).unwrap().0; position = positions.get(&picked_up).unwrap().0;
let pickupables = context.entities.components::<Pickupable>(); let pickupables = context.entities.components::<Pickupable>();
kind = pickupables.get(&picked_up).unwrap().kind; _kind = pickupables.get(&picked_up).unwrap().kind;
} }
// TODO: tally up the kinds // TODO: tally up the kinds
@ -332,7 +332,7 @@ fn update_system_pushing(context: &mut Core) {
let pusher_bounds = bounds.get(pusher_entity).unwrap(); let pusher_bounds = bounds.get(pusher_entity).unwrap();
let pusher_circle = Circle::new(pusher_position.0.x as i32, pusher_position.0.y as i32, pusher_bounds.radius); let pusher_circle = Circle::new(pusher_position.0.x as i32, pusher_position.0.y as i32, pusher_bounds.radius);
for (pushable_entity, pushable) in pushable.iter() { for (pushable_entity, _pushable) in pushable.iter() {
// don't push ourself ... // don't push ourself ...
if *pushable_entity == *pusher_entity { if *pushable_entity == *pusher_entity {
continue; continue;
@ -535,7 +535,7 @@ fn update_system_randomly_spawn_slimes(context: &mut Core) {
fn update_system_camera_follows_player(context: &mut Core) { fn update_system_camera_follows_player(context: &mut Core) {
if let Some((player_entity, _)) = context.entities.components::<Player>().single() { if let Some((player_entity, _)) = context.entities.components::<Player>().single() {
if let Some((_, mut camera)) = context.entities.components_mut::<Camera>().single_mut() { if let Some((_, camera)) = context.entities.components_mut::<Camera>().single_mut() {
let positions = context.entities.components::<Position>().unwrap(); let positions = context.entities.components::<Position>().unwrap();
let position = positions.get(player_entity).unwrap(); let position = positions.get(player_entity).unwrap();
@ -569,7 +569,7 @@ fn update_system_turn_attached_entities(context: &mut Core) {
// change the direction of the attachment (child) to match the parent ... if the // change the direction of the attachment (child) to match the parent ... if the
// attachment even has a direction itself ... // attachment even has a direction itself ...
if let Some(mut facing_direction) = facing_directions.get_mut(&attachment.0) { if let Some(facing_direction) = facing_directions.get_mut(&attachment.0) {
facing_direction.0 = parent_facing_direction; facing_direction.0 = parent_facing_direction;
} }
} }
@ -593,7 +593,7 @@ fn update_system_position_attached_entities(context: &mut Core) {
} }
let attached_entity = attachment.0; let attached_entity = attachment.0;
if let Some(mut attachment_position) = positions.get_mut(&attached_entity) { if let Some(attachment_position) = positions.get_mut(&attached_entity) {
// start off the attachment by placing it directly at the parent // start off the attachment by placing it directly at the parent
attachment_position.0 = parent_position; attachment_position.0 = parent_position;

View file

@ -1,7 +1,6 @@
extern crate core; extern crate core;
use std::collections::HashMap; use std::collections::HashMap;
use std::path::Path;
use std::rc::Rc; use std::rc::Rc;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
@ -108,30 +107,30 @@ impl AppContext<DosLike> for Game {
impl Game { impl Game {
pub fn new(mut system: System<DosLike>) -> Result<Self> { pub fn new(mut system: System<DosLike>) -> Result<Self> {
let palette = load_palette(Path::new("./assets/db16.pal"))?; let palette = load_palette("./assets/db16.pal")?;
system.res.palette = palette.clone(); system.res.palette = palette.clone();
let font = load_font(Path::new("./assets/dp.fnt"))?; let font = load_font("./assets/dp.fnt")?;
let tiles = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/tiles.pcx"))?); let tiles = Rc::new(load_bitmap_atlas_autogrid("./assets/tiles.pcx")?);
let hero_male = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/hero_male.pcx"))?); let hero_male = Rc::new(load_bitmap_atlas_autogrid("./assets/hero_male.pcx")?);
let hero_female = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/hero_female.pcx"))?); let hero_female = Rc::new(load_bitmap_atlas_autogrid("./assets/hero_female.pcx")?);
let green_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/green_slime.pcx"))?); let green_slime = Rc::new(load_bitmap_atlas_autogrid("./assets/green_slime.pcx")?);
let blue_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/blue_slime.pcx"))?); let blue_slime = Rc::new(load_bitmap_atlas_autogrid("./assets/blue_slime.pcx")?);
let orange_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/orange_slime.pcx"))?); let orange_slime = Rc::new(load_bitmap_atlas_autogrid("./assets/orange_slime.pcx")?);
let fist = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/fist.pcx"))?); let fist = Rc::new(load_bitmap_atlas_autogrid("./assets/fist.pcx")?);
let sword = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/sword.pcx"))?); let sword = Rc::new(load_bitmap_atlas_autogrid("./assets/sword.pcx")?);
let particles = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/particles.pcx"))?); let particles = Rc::new(load_bitmap_atlas_autogrid("./assets/particles.pcx")?);
let items = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/items.pcx"))?); let items = Rc::new(load_bitmap_atlas_autogrid("./assets/items.pcx")?);
let mut ui = load_bitmap_atlas(Path::new("./assets/ui.pcx"))?; let mut ui = load_bitmap_atlas("./assets/ui.pcx")?;
ui.add(Rect::new(0, 0, 16, 16))?; ui.add(Rect::new(0, 0, 16, 16))?;
ui.add(Rect::new(16, 0, 16, 16))?; ui.add(Rect::new(16, 0, 16, 16))?;
for i in 0..8 { for i in 0..8 {
ui.add(Rect::new(i * 8, 16, 8, 8))?; ui.add(Rect::new(i * 8, 16, 8, 8))?;
} }
let tilemap = TileMap::load_from(Path::new("./assets/title_screen.map.json"))?; let tilemap = TileMap::load_from("./assets/title_screen.map.json")?;
let entities = Entities::new(); let entities = Entities::new();
let component_systems = ComponentSystems::new(); let component_systems = ComponentSystems::new();

View file

@ -1,5 +1,3 @@
use std::path::Path;
use ggdt::prelude::*; use ggdt::prelude::*;
use crate::entities::*; use crate::entities::*;
@ -45,7 +43,7 @@ impl AppState<Game> for MainMenuState {
None None
} }
fn render(&mut self, state: State, context: &mut Game) { fn render(&mut self, _state: State, context: &mut Game) {
context.core.tilemap.draw(&mut context.core.system.res.video, &context.core.tiles, 0, 0); context.core.tilemap.draw(&mut context.core.system.res.video, &context.core.tiles, 0, 0);
context.support.component_systems.render(&mut context.core); context.support.component_systems.render(&mut context.core);
@ -85,10 +83,10 @@ impl AppState<Game> for MainMenuState {
update_fade_transition(state, &mut self.fade, context.core.delta * 3.0, context) update_fade_transition(state, &mut self.fade, context.core.delta * 3.0, context)
} }
fn state_change(&mut self, new_state: State, old_state: State, context: &mut Game) { fn state_change(&mut self, new_state: State, _old_state: State, context: &mut Game) {
match new_state { match new_state {
State::Pending | State::Resume => { State::Pending | State::Resume => {
init_everything(context, Path::new("./assets/title_screen.map.json"), 0.2, 1.0, 32); init_everything(context, "./assets/title_screen.map.json", 0.2, 1.0, 32);
} }
State::TransitionIn => { State::TransitionIn => {
self.fade = 0.0; self.fade = 0.0;
@ -172,7 +170,7 @@ impl AppState<Game> for GamePlayState {
None None
} }
fn render(&mut self, state: State, context: &mut Game) { fn render(&mut self, _state: State, context: &mut Game) {
if let Some((_, camera)) = context.core.entities.components::<Camera>().single() { if let Some((_, camera)) = context.core.entities.components::<Camera>().single() {
context.core.tilemap.draw(&mut context.core.system.res.video, &context.core.tiles, camera.x, camera.y); context.core.tilemap.draw(&mut context.core.system.res.video, &context.core.tiles, camera.x, camera.y);
} }
@ -216,10 +214,10 @@ impl AppState<Game> for GamePlayState {
update_fade_transition(state, &mut self.fade, context.core.delta * 3.0, context) update_fade_transition(state, &mut self.fade, context.core.delta * 3.0, context)
} }
fn state_change(&mut self, new_state: State, old_state: State, context: &mut Game) { fn state_change(&mut self, new_state: State, _old_state: State, context: &mut Game) {
match new_state { match new_state {
State::Pending => { State::Pending => {
init_everything(context, Path::new("./assets/arena.map.json"), 0.5, 2.0, 100); init_everything(context, "./assets/arena.map.json", 0.5, 2.0, 100);
spawn_player_randomly(&mut context.core); spawn_player_randomly(&mut context.core);
} }
State::TransitionIn => { State::TransitionIn => {

View file

@ -6,23 +6,23 @@ use ggdt::prelude::*;
use crate::{Game, TILE_HEIGHT, TILE_WIDTH}; use crate::{Game, TILE_HEIGHT, TILE_WIDTH};
pub fn load_palette(path: &Path) -> Result<Palette> { pub fn load_palette(path: impl AsRef<Path>) -> Result<Palette> {
Palette::load_from_file(path, PaletteFormat::Vga).context(format!("Loading palette: {:?}", path)) Palette::load_from_file(&path, PaletteFormat::Vga).context(format!("Loading palette: {:?}", path.as_ref()))
} }
pub fn load_font(path: &Path) -> Result<BitmaskFont> { pub fn load_font(path: impl AsRef<Path>) -> Result<BitmaskFont> {
BitmaskFont::load_from_file(path).context(format!("Loading font: {:?}", path)) BitmaskFont::load_from_file(&path).context(format!("Loading font: {:?}", path.as_ref()))
} }
pub fn load_bitmap_atlas_autogrid(path: &Path) -> Result<BitmapAtlas<IndexedBitmap>> { pub fn load_bitmap_atlas_autogrid(path: impl AsRef<Path>) -> Result<BitmapAtlas<IndexedBitmap>> {
let (bmp, _) = IndexedBitmap::load_file(path).context(format!("Loading bitmap atlas: {:?}", path))?; let (bmp, _) = IndexedBitmap::load_file(&path).context(format!("Loading bitmap atlas: {:?}", path.as_ref()))?;
let mut atlas = BitmapAtlas::new(bmp); let mut atlas = BitmapAtlas::new(bmp);
atlas.add_grid(TILE_WIDTH, TILE_HEIGHT)?; atlas.add_grid(TILE_WIDTH, TILE_HEIGHT)?;
Ok(atlas) Ok(atlas)
} }
pub fn load_bitmap_atlas(path: &Path) -> Result<BitmapAtlas<IndexedBitmap>> { pub fn load_bitmap_atlas(path: impl AsRef<Path>) -> Result<BitmapAtlas<IndexedBitmap>> {
let (bmp, _) = IndexedBitmap::load_file(path).context(format!("Loading bitmap atlas: {:?}", path))?; let (bmp, _) = IndexedBitmap::load_file(&path).context(format!("Loading bitmap atlas: {:?}", path.as_ref()))?;
let atlas = BitmapAtlas::new(bmp); let atlas = BitmapAtlas::new(bmp);
Ok(atlas) Ok(atlas)
} }

View file

@ -21,10 +21,10 @@ pub struct TileMap {
} }
impl TileMap { impl TileMap {
pub fn load_from(path: &Path) -> Result<Self> { pub fn load_from(path: impl AsRef<Path>) -> Result<Self> {
let f = File::open(path)?; let f = File::open(&path)?;
let reader = BufReader::new(f); let reader = BufReader::new(f);
serde_json::from_reader(reader).context(format!("Loading json tilemap: {:?}", path)) serde_json::from_reader(reader).context(format!("Loading json tilemap: {:?}", path.as_ref()))
} }
#[inline] #[inline]

View file

@ -108,16 +108,16 @@ impl AppState<App> for DemoState {
None None
} }
fn render(&mut self, state: State, context: &mut App) { fn render(&mut self, _state: State, context: &mut App) {
context.core.system.res.video.clear(0); context.core.system.res.video.clear(0);
context.support.component_systems.render(&mut context.core); context.support.component_systems.render(&mut context.core);
} }
fn transition(&mut self, state: State, context: &mut App) -> bool { fn transition(&mut self, _state: State, _context: &mut App) -> bool {
true true
} }
fn state_change(&mut self, new_state: State, old_state: State, context: &mut App) { fn state_change(&mut self, new_state: State, _old_state: State, context: &mut App) {
match new_state { match new_state {
State::Pending => { State::Pending => {
self.init(context); self.init(context);

View file

@ -50,3 +50,12 @@ harness = false
[[bench]] [[bench]]
name = "triangles" name = "triangles"
harness = false harness = false
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(recreate_ref_test_images)'] }
[lints.clippy]
too_long_first_doc_paragraph = "allow"
tabs_in_doc_comments = "allow" # fuck off
too_many_arguments = "allow"

View file

@ -1,12 +1,10 @@
use std::path::Path;
use criterion::{black_box, criterion_group, criterion_main, Criterion}; use criterion::{black_box, criterion_group, criterion_main, Criterion};
use ggdt::prelude::*; use ggdt::prelude::*;
pub fn criterion_benchmark(c: &mut Criterion) { pub fn criterion_benchmark(c: &mut Criterion) {
let mut framebuffer = IndexedBitmap::new(320, 240).unwrap(); let mut framebuffer = IndexedBitmap::new(320, 240).unwrap();
let (bmp, _) = IndexedBitmap::load_iff_file(Path::new("./test-assets/test-tiles.lbm")).unwrap(); let (bmp, _) = IndexedBitmap::load_iff_file("./test-assets/test-tiles.lbm").unwrap();
let mut solid_bmp = IndexedBitmap::new(16, 16).unwrap(); let mut solid_bmp = IndexedBitmap::new(16, 16).unwrap();
solid_bmp.blit_region(IndexedBlitMethod::Solid, &bmp, &Rect::new(16, 16, 16, 16), 0, 0); solid_bmp.blit_region(IndexedBlitMethod::Solid, &bmp, &Rect::new(16, 16, 16, 16), 0, 0);

View file

@ -7,7 +7,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let height = 240; let height = 240;
let mut dest = RgbaBitmap::new(width, height).unwrap(); let mut dest = RgbaBitmap::new(width, height).unwrap();
let (texture, _) = RgbaBitmap::load_gif_file(std::path::Path::new("./test-assets/gif/small.gif")).unwrap(); let (texture, _) = RgbaBitmap::load_gif_file("./test-assets/gif/small.gif").unwrap();
let big_v1 = Vector2::new(47.0, 23.0); let big_v1 = Vector2::new(47.0, 23.0);
let big_v2 = Vector2::new(60.0, 192.0); let big_v2 = Vector2::new(60.0, 192.0);

View file

@ -270,7 +270,7 @@ impl AudioBuffer {
/// Loads a WAV file into an [`AudioBuffer`]. The returned buffer will be in its original /// Loads a WAV file into an [`AudioBuffer`]. The returned buffer will be in its original
/// format and may need to be converted before it can be played. /// format and may need to be converted before it can be played.
pub fn load_wav_file(path: &Path) -> Result<AudioBuffer, WavError> { pub fn load_wav_file(path: impl AsRef<Path>) -> Result<AudioBuffer, WavError> {
let f = File::open(path)?; let f = File::open(path)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
Self::load_wav_bytes(&mut reader) Self::load_wav_bytes(&mut reader)
@ -287,31 +287,31 @@ mod tests {
const BASE_PATH: &str = "./test-assets/wav/"; const BASE_PATH: &str = "./test-assets/wav/";
fn test_file(file: &Path) -> PathBuf { fn test_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(BASE_PATH).join(file) PathBuf::from(BASE_PATH).join(file)
} }
#[test] #[test]
pub fn load_wav_file() -> Result<(), WavError> { pub fn load_wav_file() -> Result<(), WavError> {
let wav_buffer = AudioBuffer::load_wav_file(test_file(Path::new("22khz_8bit_1ch.wav")).as_path())?; let wav_buffer = AudioBuffer::load_wav_file(test_file("22khz_8bit_1ch.wav").as_path())?;
assert_eq!(AUDIO_FREQUENCY_22KHZ, wav_buffer.spec().frequency()); assert_eq!(AUDIO_FREQUENCY_22KHZ, wav_buffer.spec().frequency());
assert_eq!(1, wav_buffer.spec().channels()); assert_eq!(1, wav_buffer.spec().channels());
assert_eq!(AudioFormat::U8, wav_buffer.spec.format); assert_eq!(AudioFormat::U8, wav_buffer.spec.format);
assert_eq!(11248, wav_buffer.data.len()); assert_eq!(11248, wav_buffer.data.len());
let wav_buffer = AudioBuffer::load_wav_file(test_file(Path::new("44khz_8bit_1ch.wav")).as_path())?; let wav_buffer = AudioBuffer::load_wav_file(test_file("44khz_8bit_1ch.wav").as_path())?;
assert_eq!(AUDIO_FREQUENCY_44KHZ, wav_buffer.spec().frequency()); assert_eq!(AUDIO_FREQUENCY_44KHZ, wav_buffer.spec().frequency());
assert_eq!(1, wav_buffer.spec().channels()); assert_eq!(1, wav_buffer.spec().channels());
assert_eq!(AudioFormat::U8, wav_buffer.spec.format); assert_eq!(AudioFormat::U8, wav_buffer.spec.format);
assert_eq!(22496, wav_buffer.data.len()); assert_eq!(22496, wav_buffer.data.len());
let wav_buffer = AudioBuffer::load_wav_file(test_file(Path::new("22khz_16bit_1ch.wav")).as_path())?; let wav_buffer = AudioBuffer::load_wav_file(test_file("22khz_16bit_1ch.wav").as_path())?;
assert_eq!(AUDIO_FREQUENCY_22KHZ, wav_buffer.spec().frequency()); assert_eq!(AUDIO_FREQUENCY_22KHZ, wav_buffer.spec().frequency());
assert_eq!(1, wav_buffer.spec().channels()); assert_eq!(1, wav_buffer.spec().channels());
assert_eq!(AudioFormat::S16LSB, wav_buffer.spec.format); assert_eq!(AudioFormat::S16LSB, wav_buffer.spec.format);
assert_eq!(22496, wav_buffer.data.len()); assert_eq!(22496, wav_buffer.data.len());
let wav_buffer = AudioBuffer::load_wav_file(test_file(Path::new("44khz_16bit_1ch.wav")).as_path())?; let wav_buffer = AudioBuffer::load_wav_file(test_file("44khz_16bit_1ch.wav").as_path())?;
assert_eq!(AUDIO_FREQUENCY_44KHZ, wav_buffer.spec().frequency()); assert_eq!(AUDIO_FREQUENCY_44KHZ, wav_buffer.spec().frequency());
assert_eq!(1, wav_buffer.spec().channels()); assert_eq!(1, wav_buffer.spec().channels());
assert_eq!(AudioFormat::S16LSB, wav_buffer.spec.format); assert_eq!(AudioFormat::S16LSB, wav_buffer.spec.format);

View file

@ -174,6 +174,12 @@ impl AudioChannel {
} }
} }
impl Default for AudioChannel {
fn default() -> Self {
Self::new()
}
}
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Debug, Error)] #[derive(Debug, Error)]

View file

@ -1,133 +1,135 @@
//! Optional, extra types and helpers that can be used to get game's main loop boilerplate up and /*!
//! running quicker. Optional, extra types and helpers that can be used to get game's main loop boilerplate up and
//! running quicker.
//! This is all of somewhat dubious quality and value at the moment. And it may continue to be this
//! way for a long while yet. And, truthfully, I suspect I may rip this out eventually. Maybe. This is all of somewhat dubious quality and value at the moment. And it may continue to be this
//! way for a long while yet. And, truthfully, I suspect I may rip this out eventually. Maybe.
//! The very-long-winded rationale here is that as I've started building more and more things with
//! ggdt, I started implementing games/apps using a particular pattern which I was largely The very-long-winded rationale here is that as I've started building more and more things with
//! pushed towards due to the Rust borrow-checker (as is often the case with Rust). My games/apps ggdt, I started implementing games/apps using a particular pattern which I was largely
//! needed to keep their state (for clarity, the word 'state' here is being used very broadly to pushed towards due to the Rust borrow-checker (as is often the case with Rust). My games/apps
//! refer to all game/app state, and not just referring to the stuff inside `ggdt::states`) needed to keep their state (for clarity, the word 'state' here is being used very broadly to
//! somewhere and my needs were a bit complicated since my game/app state often included things refer to all game/app state, and not just referring to the stuff inside `ggdt::states`)
//! which needed to get passed other things from inside that same "bag" of state. somewhere and my needs were a bit complicated since my game/app state often included things
//! which needed to get passed other things from inside that same "bag" of state.
//! I originally wanted to do something like this, where this `App` struct is our overall "game/app
//! context" grab bag: I originally wanted to do something like this, where this `App` struct is our overall "game/app
//! context" grab bag:
//! ```
//! use ggdt::prelude::*; ```
//! use ggdt::prelude::*;
//! pub enum Event { /* .. various events here .. */ }
//! pub enum Event { /* .. various events here .. */ }
//! struct App {
//! pub delta: f32, struct App {
//! pub system: System<DosLike>, pub delta: f32,
//! pub entities: Entities, pub system: System<DosLike>,
//! pub component_systems: ComponentSystems<App, App>, // oh no! :'( pub entities: Entities,
//! pub event_publisher: EventPublisher<Event>, pub component_systems: ComponentSystems<App, App>, // oh no! :'(
//! pub event_listeners: EventListeners<Event, App>, // oh no again! :'( pub event_publisher: EventPublisher<Event>,
//! } pub event_listeners: EventListeners<Event, App>, // oh no again! :'(
//! ``` }
//! ```
//! Of course, we cannot do this, because then we end up trying to get additional mutable borrows
//! of `App` when we eventually try to call certain methods on either the `component_systems` or Of course, we cannot do this, because then we end up trying to get additional mutable borrows
//! `event_listeners` instances. Boooo! :-( of `App` when we eventually try to call certain methods on either the `component_systems` or
//! `event_listeners` instances. Boooo! :-(
//! That of course lead me to split this structure up. I didn't and still don't like this because
//! I really don't know what to call these two things. They're both "context" and they're literally That of course lead me to split this structure up. I didn't and still don't like this because
//! only split up because of borrow-checker issues. But splitting them up did work for me. I I really don't know what to call these two things. They're both "context" and they're literally
//! initially went with a parent-child split, which seemed logical to me at the time: only split up because of borrow-checker issues. But splitting them up did work for me. I
//! initially went with a parent-child split, which seemed logical to me at the time:
//! ```
//! use ggdt::prelude::*; ```
//! use ggdt::prelude::*;
//! pub enum Event { /* .. various events here .. */ }
//! pub enum Event { /* .. various events here .. */ }
//! // "core" because what the heck else do i call this? "InnerContext"? "InnerApp"? ...
//! struct Core { // "core" because what the heck else do i call this? "InnerContext"? "InnerApp"? ...
//! pub delta: f32, struct Core {
//! pub system: System<DosLike>, pub delta: f32,
//! pub entities: Entities, pub system: System<DosLike>,
//! pub event_publisher: EventPublisher<Event>, pub entities: Entities,
//! } pub event_publisher: EventPublisher<Event>,
//! }
//! // i guess this is a bit more obvious what to call it, but still ... doesn't sit right with me
//! struct App { // i guess this is a bit more obvious what to call it, but still ... doesn't sit right with me
//! pub core: Core, struct App {
//! pub component_systems: ComponentSystems<Core, Core>, pub core: Core,
//! pub event_listeners: EventListeners<Event, Core>, pub component_systems: ComponentSystems<Core, Core>,
//! } pub event_listeners: EventListeners<Event, Core>,
//! ``` }
//! ```
//! This structure seemed to work generally well and I've gotten pretty far with it. Keeping the
//! main `ggdt::states::States` instance _separate_ was also key, and never really a problem This structure seemed to work generally well and I've gotten pretty far with it. Keeping the
//! since that can (and should) just live at the top in your main loop. Easy. main `ggdt::states::States` instance _separate_ was also key, and never really a problem
//! since that can (and should) just live at the top in your main loop. Easy.
//! I ended up with some common bits of code that I'd always add to projects using this structure,
//! such as a very simple copy+pasted main loop, as well as a very simple function that calculates I ended up with some common bits of code that I'd always add to projects using this structure,
//! the new frame `delta` each iteration of the main loop. As well as event processing via the such as a very simple copy+pasted main loop, as well as a very simple function that calculates
//! `event_publisher` and `event_listener` instances. I also expect this set of common bits of code the new frame `delta` each iteration of the main loop. As well as event processing via the
//! to grow over time. And I, ideally, want a single place to put it all. `event_publisher` and `event_listener` instances. I also expect this set of common bits of code
//! to grow over time. And I, ideally, want a single place to put it all.
//! So, this module here is my attempt at trying to formalize this a bit more and do a bit of
//! refactoring where I can keep this common copy+pasted bits somewhere. As well, I decided to So, this module here is my attempt at trying to formalize this a bit more and do a bit of
//! move away from my "context" struct having a parent-child relation for the split of the data refactoring where I can keep this common copy+pasted bits somewhere. As well, I decided to
//! kept in these, and instead just "flatten" it out a bit (sort of) as this seems much more move away from my "context" struct having a parent-child relation for the split of the data
//! future-proof if/when I encounter more borrow-checker issues down the road with other additions kept in these, and instead just "flatten" it out a bit (sort of) as this seems much more
//! to these structures. future-proof if/when I encounter more borrow-checker issues down the road with other additions
//! to these structures.
//! But again, better naming still eludes me here!
//! But again, better naming still eludes me here!
//! ```
//! use ggdt::prelude::*; ```
//! use ggdt::prelude::*;
//! pub enum Event { /* .. various events here .. */ }
//! pub enum Event { /* .. various events here .. */ }
//! // "Core" because it contains the things that probably 90% of game/app code will need to work
//! // with. you'd probably want to put your game/app resources/assets on this struct too. // "Core" because it contains the things that probably 90% of game/app code will need to work
//! struct Core { // with. you'd probably want to put your game/app resources/assets on this struct too.
//! pub delta: f32, struct Core {
//! pub system: System<DosLike>, pub delta: f32,
//! pub entities: Entities, pub system: System<DosLike>,
//! pub event_publisher: EventPublisher<Event>, pub entities: Entities,
//! } pub event_publisher: EventPublisher<Event>,
//! }
//! // "Support" because it contains things that support the main/core game state?
//! // kinda grasping at straws here maybe ... // "Support" because it contains things that support the main/core game state?
//! struct Support { // kinda grasping at straws here maybe ...
//! pub component_systems: ComponentSystems<Core, Core>, struct Support {
//! pub event_listeners: EventListeners<Event, Core>, pub component_systems: ComponentSystems<Core, Core>,
//! } pub event_listeners: EventListeners<Event, Core>,
//! }
//! // better, maybe?
//! struct App { // better, maybe?
//! pub core: Core, struct App {
//! pub support: Support, pub core: Core,
//! } pub support: Support,
//! ``` }
//! ```
//! Even though it's another struct being added, I do like this more, despite the naming
//! uncertainty. Even though it's another struct being added, I do like this more, despite the naming
//! uncertainty.
//! So, with this being my current preferred way to architect a ggdt-using project, I created
//! some traits here in this module to formalize this all a bit more. `CoreState` and (optionally) So, with this being my current preferred way to architect a ggdt-using project, I created
//! `CoreStateWithEvents` are what you'd make your project's `Core` struct (as shown in the above some traits here in this module to formalize this all a bit more. `CoreState` and (optionally)
//! example code) implement, while `SupportSystems` and (optionally) `SupportSystemsWithEvents` `CoreStateWithEvents` are what you'd make your project's `Core` struct (as shown in the above
//! are what you'd make your project's `Support` struct (again, as shown in the above example code) example code) implement, while `SupportSystems` and (optionally) `SupportSystemsWithEvents`
//! implement. Finally, `AppContext` is for your `App` struct that contains the two. are what you'd make your project's `Support` struct (again, as shown in the above example code)
//! implement. Finally, `AppContext` is for your `App` struct that contains the two.
//! Once you have all this (which ironically ends up being _more_ code than if you'd not used these
//! traits ... heh), you can now optionally use the `main_loop` function to get a ready-to-use Once you have all this (which ironically ends up being _more_ code than if you'd not used these
//! main loop which is set up to use a `ggdt::states::State` state manager. traits ... heh), you can now optionally use the `main_loop` function to get a ready-to-use
//! main loop which is set up to use a `ggdt::states::State` state manager.
//! Having said all of this ... again, I will reiterate that I don't believe any of this has reached
//! anything resembling a "good design" ... yet. There may be a good design hidden somewhere in Having said all of this ... again, I will reiterate that I don't believe any of this has reached
//! here that I've yet to fully discover, but I definitely don't think I've arrived at quite it yet. anything resembling a "good design" ... yet. There may be a good design hidden somewhere in
//! here that I've yet to fully discover, but I definitely don't think I've arrived at quite it yet.
//! So, basically, I expect this to evolve over time (probably a _long_ time). And this is all
//! totally optional anyway. So, basically, I expect this to evolve over time (probably a _long_ time). And this is all
//! totally optional anyway.
*/
use thiserror::Error; use thiserror::Error;

View file

@ -230,6 +230,12 @@ impl Entities {
} }
} }
impl Default for Entities {
fn default() -> Self {
Self::new()
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: is there some fancy way to get rid of the impl duplication here ... ? // TODO: is there some fancy way to get rid of the impl duplication here ... ?
@ -470,6 +476,12 @@ impl<U, R> ComponentSystems<U, R> {
} }
} }
impl<U, R> Default for ComponentSystems<U, R> {
fn default() -> Self {
Self::new()
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
#[cfg(test)] #[cfg(test)]
@ -667,7 +679,7 @@ mod tests {
// modify position components // modify position components
{ {
let mut positions = em.components_mut::<Position>().unwrap(); let mut positions = em.components_mut::<Position>().unwrap();
for mut component in positions.values_mut() { for component in positions.values_mut() {
component.0 += 5; component.0 += 5;
} }
@ -678,7 +690,7 @@ mod tests {
// modify health components // modify health components
{ {
let mut healths = em.components_mut::<Health>().unwrap(); let mut healths = em.components_mut::<Health>().unwrap();
for mut component in healths.values_mut() { for component in healths.values_mut() {
component.0 += 5; component.0 += 5;
} }
assert_eq!(Health(25), *healths.get(&a).unwrap()); assert_eq!(Health(25), *healths.get(&a).unwrap());
@ -722,10 +734,10 @@ mod tests {
println!("entity {}, health: {:?}, position: {:?}", name.0, health, position); println!("entity {}, health: {:?}, position: {:?}", name.0, health, position);
if let Some(mut health) = health { if let Some(health) = health {
health.0 += 5; health.0 += 5;
} }
if let Some(mut position) = position { if let Some(position) = position {
position.0 += 5; position.0 += 5;
} }
} }

View file

@ -55,6 +55,12 @@ impl<EventType> EventPublisher<EventType> {
} }
} }
impl<EventType> Default for EventPublisher<EventType> {
fn default() -> Self {
Self::new()
}
}
/// A manager for application event listeners/handlers that can dispatch events queued up by a /// A manager for application event listeners/handlers that can dispatch events queued up by a
/// [`EventPublisher`] to each of the event listeners/handlers registered with this manager. /// [`EventPublisher`] to each of the event listeners/handlers registered with this manager.
/// ///
@ -150,6 +156,12 @@ impl<EventType, ContextType> EventListeners<EventType, ContextType> {
} }
} }
impl<EventType, ContextType> Default for EventListeners<EventType, ContextType> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -175,10 +187,12 @@ mod tests {
} }
fn dummy_listener(_event: &TestEvent, _context: &mut DummyContext) -> bool { fn dummy_listener(_event: &TestEvent, _context: &mut DummyContext) -> bool {
println!("dummy_listener event fired");
false false
} }
fn other_dummy_listener(_event: &TestEvent, _context: &mut DummyContext) -> bool { fn other_dummy_listener(_event: &TestEvent, _context: &mut DummyContext) -> bool {
println!("other_dummy_listener event fired");
false false
} }

View file

@ -127,6 +127,10 @@ fn get_flipped_blit_properties<PixelType: Pixel>(
(x_inc, src_start_x, src_start_y, src_next_row_inc) (x_inc, src_start_x, src_start_y, src_next_row_inc)
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
#[inline] #[inline]
pub unsafe fn per_pixel_blit<PixelType: Pixel>( pub unsafe fn per_pixel_blit<PixelType: Pixel>(
dest: &mut Bitmap<PixelType>, dest: &mut Bitmap<PixelType>,
@ -153,6 +157,10 @@ pub unsafe fn per_pixel_blit<PixelType: Pixel>(
} }
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
#[inline] #[inline]
pub unsafe fn per_pixel_flipped_blit<PixelType: Pixel>( pub unsafe fn per_pixel_flipped_blit<PixelType: Pixel>(
dest: &mut Bitmap<PixelType>, dest: &mut Bitmap<PixelType>,
@ -183,6 +191,10 @@ pub unsafe fn per_pixel_flipped_blit<PixelType: Pixel>(
} }
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
#[inline] #[inline]
pub unsafe fn per_pixel_rotozoom_blit<PixelType: Pixel>( pub unsafe fn per_pixel_rotozoom_blit<PixelType: Pixel>(
dest: &mut Bitmap<PixelType>, dest: &mut Bitmap<PixelType>,
@ -280,6 +292,10 @@ pub unsafe fn per_pixel_rotozoom_blit<PixelType: Pixel>(
} }
impl<PixelType: Pixel> Bitmap<PixelType> { impl<PixelType: Pixel> Bitmap<PixelType> {
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn solid_blit(&mut self, src: &Self, src_region: &Rect, dest_x: i32, dest_y: i32) { pub unsafe fn solid_blit(&mut self, src: &Self, src_region: &Rect, dest_x: i32, dest_y: i32) {
let src_row_length = src_region.width as usize; let src_row_length = src_region.width as usize;
let src_pitch = src.width as usize; let src_pitch = src.width as usize;
@ -294,6 +310,10 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
} }
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn solid_flipped_blit( pub unsafe fn solid_flipped_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -317,6 +337,10 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_blit( pub unsafe fn transparent_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -339,6 +363,10 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_flipped_blit( pub unsafe fn transparent_flipped_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -365,6 +393,10 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_single_color_blit( pub unsafe fn transparent_single_color_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -388,6 +420,10 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_flipped_single_color_blit( pub unsafe fn transparent_flipped_single_color_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -415,6 +451,10 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn rotozoom_blit( pub unsafe fn rotozoom_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -440,6 +480,10 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn rotozoom_transparent_blit( pub unsafe fn rotozoom_transparent_blit(
&mut self, &mut self,
src: &Self, src: &Self,

View file

@ -468,7 +468,7 @@ impl IndexedBitmap {
Ok((bitmap.unwrap(), palette.unwrap())) Ok((bitmap.unwrap(), palette.unwrap()))
} }
pub fn load_gif_file(path: &Path) -> Result<(IndexedBitmap, Palette), GifError> { pub fn load_gif_file(path: impl AsRef<Path>) -> Result<(IndexedBitmap, Palette), GifError> {
let f = File::open(path)?; let f = File::open(path)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
Self::load_gif_bytes(&mut reader) Self::load_gif_bytes(&mut reader)
@ -520,7 +520,12 @@ impl IndexedBitmap {
Ok(()) Ok(())
} }
pub fn to_gif_file(&self, path: &Path, palette: &Palette, settings: GifSettings) -> Result<(), GifError> { pub fn to_gif_file(
&self,
path: impl AsRef<Path>,
palette: &Palette,
settings: GifSettings,
) -> Result<(), GifError> {
let f = File::create(path)?; let f = File::create(path)?;
let mut writer = BufWriter::new(f); let mut writer = BufWriter::new(f);
self.to_gif_bytes(&mut writer, palette, settings) self.to_gif_bytes(&mut writer, palette, settings)
@ -537,7 +542,7 @@ impl RgbaBitmap {
Ok((output, palette)) Ok((output, palette))
} }
pub fn load_gif_file(path: &Path) -> Result<(RgbaBitmap, Palette), GifError> { pub fn load_gif_file(path: impl AsRef<Path>) -> Result<(RgbaBitmap, Palette), GifError> {
let (temp_bitmap, palette) = IndexedBitmap::load_gif_file(path)?; let (temp_bitmap, palette) = IndexedBitmap::load_gif_file(path)?;
let output = temp_bitmap.to_rgba(&palette); let output = temp_bitmap.to_rgba(&palette);
Ok((output, palette)) Ok((output, palette))
@ -556,7 +561,7 @@ mod tests {
const BASE_PATH: &str = "./test-assets/gif/"; const BASE_PATH: &str = "./test-assets/gif/";
fn test_file(file: &Path) -> PathBuf { fn test_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(BASE_PATH).join(file) PathBuf::from(BASE_PATH).join(file)
} }
@ -564,14 +569,14 @@ mod tests {
fn load_and_save() -> Result<(), GifError> { fn load_and_save() -> Result<(), GifError> {
let tmp_dir = TempDir::new()?; let tmp_dir = TempDir::new()?;
let ref_pixels = load_raw_indexed(test_file(Path::new("small.bin")).as_path())?; let ref_pixels = load_raw_indexed(test_file("small.bin"))?;
let dp2_palette = Palette::load_from_file( let dp2_palette = Palette::load_from_file(
test_assets_file(Path::new("dp2.pal")).as_path(), // test_assets_file("dp2.pal"), //
PaletteFormat::Normal, PaletteFormat::Normal,
) )
.unwrap(); .unwrap();
let (bmp, palette) = IndexedBitmap::load_gif_file(test_file(Path::new("small.gif")).as_path())?; let (bmp, palette) = IndexedBitmap::load_gif_file(test_file("small.gif"))?;
assert_eq!(16, bmp.width()); assert_eq!(16, bmp.width());
assert_eq!(16, bmp.height()); assert_eq!(16, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -597,9 +602,9 @@ mod tests {
// first image // first image
let ref_pixels = load_raw_indexed(test_file(Path::new("large_1.bin")).as_path())?; let ref_pixels = load_raw_indexed(test_file("large_1.bin"))?;
let (bmp, palette) = IndexedBitmap::load_gif_file(test_file(Path::new("large_1.gif")).as_path())?; let (bmp, palette) = IndexedBitmap::load_gif_file(test_file("large_1.gif"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -613,9 +618,9 @@ mod tests {
// second image // second image
let ref_pixels = load_raw_indexed(test_file(Path::new("large_2.bin")).as_path())?; let ref_pixels = load_raw_indexed(test_file("large_2.bin"))?;
let (bmp, palette) = IndexedBitmap::load_gif_file(test_file(Path::new("large_2.gif")).as_path())?; let (bmp, palette) = IndexedBitmap::load_gif_file(test_file("large_2.gif"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());

View file

@ -213,7 +213,7 @@ fn merge_bitplane(plane: u32, src: &[u8], dest: &mut [u8], row_size: usize) {
fn extract_bitplane(plane: u32, src: &[u8], dest: &mut [u8], row_size: usize) { fn extract_bitplane(plane: u32, src: &[u8], dest: &mut [u8], row_size: usize) {
let bitmask = 1 << plane; let bitmask = 1 << plane;
let mut src_base_index = 0; let mut src_base_index = 0;
for x in 0..row_size { for dest_pixel in dest.iter_mut().take(row_size) {
let mut data = 0; let mut data = 0;
if src[src_base_index] & bitmask != 0 { if src[src_base_index] & bitmask != 0 {
data |= 128; data |= 128;
@ -241,7 +241,7 @@ fn extract_bitplane(plane: u32, src: &[u8], dest: &mut [u8], row_size: usize) {
} }
src_base_index += 8; src_base_index += 8;
dest[x] = data; *dest_pixel = data;
} }
} }
@ -430,7 +430,7 @@ impl IndexedBitmap {
Ok((bitmap.unwrap(), palette.unwrap())) Ok((bitmap.unwrap(), palette.unwrap()))
} }
pub fn load_iff_file(path: &Path) -> Result<(IndexedBitmap, Palette), IffError> { pub fn load_iff_file(path: impl AsRef<Path>) -> Result<(IndexedBitmap, Palette), IffError> {
let f = File::open(path)?; let f = File::open(path)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
Self::load_iff_bytes(&mut reader) Self::load_iff_bytes(&mut reader)
@ -522,7 +522,7 @@ impl IndexedBitmap {
Ok(()) Ok(())
} }
pub fn to_iff_file(&self, path: &Path, palette: &Palette, format: IffFormat) -> Result<(), IffError> { pub fn to_iff_file(&self, path: impl AsRef<Path>, palette: &Palette, format: IffFormat) -> Result<(), IffError> {
let f = File::create(path)?; let f = File::create(path)?;
let mut writer = BufWriter::new(f); let mut writer = BufWriter::new(f);
self.to_iff_bytes(&mut writer, palette, format) self.to_iff_bytes(&mut writer, palette, format)
@ -539,7 +539,7 @@ impl RgbaBitmap {
Ok((output, palette)) Ok((output, palette))
} }
pub fn load_iff_file(path: &Path) -> Result<(RgbaBitmap, Palette), IffError> { pub fn load_iff_file(path: impl AsRef<Path>) -> Result<(RgbaBitmap, Palette), IffError> {
let (temp_bitmap, palette) = IndexedBitmap::load_iff_file(path)?; let (temp_bitmap, palette) = IndexedBitmap::load_iff_file(path)?;
let output = temp_bitmap.to_rgba(&palette); let output = temp_bitmap.to_rgba(&palette);
Ok((output, palette)) Ok((output, palette))
@ -558,7 +558,7 @@ mod tests {
const BASE_PATH: &str = "./test-assets/iff/"; const BASE_PATH: &str = "./test-assets/iff/";
fn test_file(file: &Path) -> PathBuf { fn test_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(BASE_PATH).join(file) PathBuf::from(BASE_PATH).join(file)
} }
@ -566,16 +566,16 @@ mod tests {
pub fn load_and_save() -> Result<(), IffError> { pub fn load_and_save() -> Result<(), IffError> {
let tmp_dir = TempDir::new()?; let tmp_dir = TempDir::new()?;
let ref_pixels = load_raw_indexed(test_file(Path::new("small.bin")).as_path())?; let ref_pixels = load_raw_indexed(test_file("small.bin"))?;
let dp2_palette = Palette::load_from_file( let dp2_palette = Palette::load_from_file(
test_assets_file(Path::new("dp2.pal")).as_path(), // test_assets_file("dp2.pal"), //
PaletteFormat::Normal, PaletteFormat::Normal,
) )
.unwrap(); .unwrap();
// ILBM format // ILBM format
let (bmp, palette) = IndexedBitmap::load_iff_file(test_file(Path::new("small.lbm")).as_path())?; let (bmp, palette) = IndexedBitmap::load_iff_file(test_file("small.lbm"))?;
assert_eq!(16, bmp.width()); assert_eq!(16, bmp.width());
assert_eq!(16, bmp.height()); assert_eq!(16, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -591,7 +591,7 @@ mod tests {
// PBM format // PBM format
let (bmp, palette) = IndexedBitmap::load_iff_file(test_file(Path::new("small.pbm")).as_path())?; let (bmp, palette) = IndexedBitmap::load_iff_file(test_file("small.pbm"))?;
assert_eq!(16, bmp.width()); assert_eq!(16, bmp.width());
assert_eq!(16, bmp.height()); assert_eq!(16, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -614,9 +614,9 @@ mod tests {
// first image, PBM format // first image, PBM format
let ref_pixels = load_raw_indexed(test_file(Path::new("large_1.bin")).as_path())?; let ref_pixels = load_raw_indexed(test_file("large_1.bin"))?;
let (bmp, palette) = IndexedBitmap::load_iff_file(test_file(Path::new("large_1.pbm")).as_path())?; let (bmp, palette) = IndexedBitmap::load_iff_file(test_file("large_1.pbm"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -630,7 +630,7 @@ mod tests {
// first image, ILBM format // first image, ILBM format
let (bmp, palette) = IndexedBitmap::load_iff_file(test_file(Path::new("large_1.lbm")).as_path())?; let (bmp, palette) = IndexedBitmap::load_iff_file(test_file("large_1.lbm"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -644,9 +644,9 @@ mod tests {
// second image, PBM format // second image, PBM format
let ref_pixels = load_raw_indexed(test_file(Path::new("large_2.bin")).as_path())?; let ref_pixels = load_raw_indexed(test_file("large_2.bin"))?;
let (bmp, palette) = IndexedBitmap::load_iff_file(test_file(Path::new("large_2.lbm")).as_path())?; let (bmp, palette) = IndexedBitmap::load_iff_file(test_file("large_2.lbm"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -660,7 +660,7 @@ mod tests {
// second image, ILBM format // second image, ILBM format
let (bmp, palette) = IndexedBitmap::load_iff_file(test_file(Path::new("large_2.lbm")).as_path())?; let (bmp, palette) = IndexedBitmap::load_iff_file(test_file("large_2.lbm"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());

View file

@ -126,6 +126,10 @@ pub enum IndexedBlitMethod {
} }
impl IndexedBitmap { impl IndexedBitmap {
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn solid_blended_blit( pub unsafe fn solid_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -150,6 +154,10 @@ impl IndexedBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn solid_flipped_blended_blit( pub unsafe fn solid_flipped_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -178,6 +186,10 @@ impl IndexedBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn solid_palette_offset_blit( pub unsafe fn solid_palette_offset_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -198,6 +210,10 @@ impl IndexedBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn solid_flipped_palette_offset_blit( pub unsafe fn solid_flipped_palette_offset_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -222,6 +238,10 @@ impl IndexedBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_blended_blit( pub unsafe fn transparent_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -249,6 +269,10 @@ impl IndexedBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_flipped_blended_blit( pub unsafe fn transparent_flipped_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -280,6 +304,10 @@ impl IndexedBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_palette_offset_blit( pub unsafe fn transparent_palette_offset_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -303,6 +331,10 @@ impl IndexedBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_flipped_palette_offset_blit( pub unsafe fn transparent_flipped_palette_offset_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -330,6 +362,10 @@ impl IndexedBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn rotozoom_blended_blit( pub unsafe fn rotozoom_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -363,6 +399,10 @@ impl IndexedBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn rotozoom_transparent_blended_blit( pub unsafe fn rotozoom_transparent_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -399,6 +439,10 @@ impl IndexedBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn rotozoom_palette_offset_blit( pub unsafe fn rotozoom_palette_offset_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -426,6 +470,10 @@ impl IndexedBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn rotozoom_transparent_palette_offset_blit( pub unsafe fn rotozoom_transparent_palette_offset_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -522,6 +570,10 @@ impl IndexedBitmap {
}; };
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
#[inline] #[inline]
#[rustfmt::skip] #[rustfmt::skip]
pub unsafe fn blit_region_unchecked( pub unsafe fn blit_region_unchecked(
@ -606,12 +658,20 @@ impl IndexedBitmap {
} }
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
#[inline] #[inline]
pub unsafe fn blit_unchecked(&mut self, method: IndexedBlitMethod, src: &Self, x: i32, y: i32) { pub unsafe fn blit_unchecked(&mut self, method: IndexedBlitMethod, src: &Self, x: i32, y: i32) {
let src_region = Rect::new(0, 0, src.width, src.height); let src_region = Rect::new(0, 0, src.width, src.height);
self.blit_region_unchecked(method, src, &src_region, x, y); self.blit_region_unchecked(method, src, &src_region, x, y);
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
#[inline] #[inline]
pub unsafe fn blit_atlas_unchecked( pub unsafe fn blit_atlas_unchecked(
&mut self, &mut self,

View file

@ -25,8 +25,8 @@ impl IndexedBitmap {
Self::internal_new(width, height, 0) Self::internal_new(width, height, 0)
} }
pub fn load_file(path: &Path) -> Result<(Self, Palette), BitmapError> { pub fn load_file(path: impl AsRef<Path>) -> Result<(Self, Palette), BitmapError> {
if let Some(extension) = path.extension() { if let Some(extension) = path.as_ref().extension() {
let extension = extension.to_ascii_lowercase(); let extension = extension.to_ascii_lowercase();
match extension.to_str() { match extension.to_str() {
Some("png") => { Some("png") => {

View file

@ -20,8 +20,11 @@ impl IndexedBitmap {
} }
/// Sets the pixel at the given coordinates using a blended color via the specified blend map, /// Sets the pixel at the given coordinates using a blended color via the specified blend map,
/// or using the color specified if the blend map does not include the given color. The /// or using the color specified if the blend map does not include the given color.
/// coordinates are not checked for validity, so it is up to you to ensure they lie within the ///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap. /// bounds of the bitmap.
#[inline] #[inline]
pub unsafe fn set_blended_pixel_unchecked(&mut self, x: i32, y: i32, color: u8, blend_map: &BlendMap) { pub unsafe fn set_blended_pixel_unchecked(&mut self, x: i32, y: i32, color: u8, blend_map: &BlendMap) {

View file

@ -89,7 +89,7 @@ impl IndexedBitmap {
use IndexedTriangle2d::*; use IndexedTriangle2d::*;
match triangle { match triangle {
Solid { position, color } => self.solid_triangle_2d(position, *color), Solid { position, color } => self.solid_triangle_2d(position, *color),
SolidBlended { position, color, blendmap } => self.solid_blended_triangle_2d(position, *color, *blendmap), SolidBlended { position, color, blendmap } => self.solid_blended_triangle_2d(position, *color, blendmap),
SolidTextured { position, texcoord, bitmap } => self.solid_textured_triangle_2d(position, texcoord, bitmap), SolidTextured { position, texcoord, bitmap } => self.solid_textured_triangle_2d(position, texcoord, bitmap),
SolidTexturedBlended { position, texcoord, bitmap, blendmap } => { SolidTexturedBlended { position, texcoord, bitmap, blendmap } => {
self.solid_textured_blended_triangle_2d(position, texcoord, bitmap, blendmap) self.solid_textured_blended_triangle_2d(position, texcoord, bitmap, blendmap)

View file

@ -212,8 +212,12 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
} }
/// Returns an unsafe reference to the subset of the raw pixels in this bitmap beginning at the /// Returns an unsafe reference to the subset of the raw pixels in this bitmap beginning at the
/// given coordinates and extending to the end of the bitmap. The coordinates are not checked /// given coordinates and extending to the end of the bitmap.
/// for validity, so it is up to you to ensure they lie within the bounds of the bitmap. ///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline] #[inline]
pub unsafe fn pixels_at_unchecked(&self, x: i32, y: i32) -> &[PixelType] { pub unsafe fn pixels_at_unchecked(&self, x: i32, y: i32) -> &[PixelType] {
let offset = self.get_offset_to_xy(x, y); let offset = self.get_offset_to_xy(x, y);
@ -221,8 +225,12 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
} }
/// Returns a mutable unsafe reference to the subset of the raw pixels in this bitmap beginning /// Returns a mutable unsafe reference to the subset of the raw pixels in this bitmap beginning
/// at the given coordinates and extending to the end of the bitmap. The coordinates are not /// at the given coordinates and extending to the end of the bitmap.
/// checked for validity, so it is up to you to ensure they lie within the bounds of the bitmap. ///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline] #[inline]
pub unsafe fn pixels_at_mut_unchecked(&mut self, x: i32, y: i32) -> &mut [PixelType] { pub unsafe fn pixels_at_mut_unchecked(&mut self, x: i32, y: i32) -> &mut [PixelType] {
let offset = self.get_offset_to_xy(x, y); let offset = self.get_offset_to_xy(x, y);
@ -236,10 +244,10 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
/// coordinates. If the coordinates given are outside the bitmap's current clipping region, /// coordinates. If the coordinates given are outside the bitmap's current clipping region,
/// None is returned. /// None is returned.
#[inline] #[inline]
pub unsafe fn pixels_at_ptr(&self, x: i32, y: i32) -> Option<*const PixelType> { pub fn pixels_at_ptr(&self, x: i32, y: i32) -> Option<*const PixelType> {
if self.is_xy_visible(x, y) { if self.is_xy_visible(x, y) {
let offset = self.get_offset_to_xy(x, y); let offset = self.get_offset_to_xy(x, y);
Some(self.pixels.as_ptr().add(offset)) Some(unsafe { self.pixels.as_ptr().add(offset) })
} else { } else {
None None
} }
@ -249,18 +257,22 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
/// given coordinates. If the coordinates given are outside the bitmap's current clipping /// given coordinates. If the coordinates given are outside the bitmap's current clipping
/// region, None is returned. /// region, None is returned.
#[inline] #[inline]
pub unsafe fn pixels_at_mut_ptr(&mut self, x: i32, y: i32) -> Option<*mut PixelType> { pub fn pixels_at_mut_ptr(&mut self, x: i32, y: i32) -> Option<*mut PixelType> {
if self.is_xy_visible(x, y) { if self.is_xy_visible(x, y) {
let offset = self.get_offset_to_xy(x, y); let offset = self.get_offset_to_xy(x, y);
Some(self.pixels.as_mut_ptr().add(offset)) Some(unsafe { self.pixels.as_mut_ptr().add(offset) })
} else { } else {
None None
} }
} }
/// Returns an unsafe pointer to the subset of the raw pixels in this bitmap beginning at the /// Returns an unsafe pointer to the subset of the raw pixels in this bitmap beginning at the
/// given coordinates. The coordinates are not checked for validity, so it is up to you to /// given coordinates.
/// ensure they lie within the bounds of the bitmap. ///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline] #[inline]
pub unsafe fn pixels_at_ptr_unchecked(&self, x: i32, y: i32) -> *const PixelType { pub unsafe fn pixels_at_ptr_unchecked(&self, x: i32, y: i32) -> *const PixelType {
let offset = self.get_offset_to_xy(x, y); let offset = self.get_offset_to_xy(x, y);
@ -268,8 +280,12 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
} }
/// Returns a mutable unsafe pointer to the subset of the raw pixels in this bitmap beginning /// Returns a mutable unsafe pointer to the subset of the raw pixels in this bitmap beginning
/// at the given coordinates. The coordinates are not checked for validity, so it is up to you /// at the given coordinates.
/// to ensure they lie within the bounds of the bitmap. ///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline] #[inline]
pub unsafe fn pixels_at_mut_ptr_unchecked(&mut self, x: i32, y: i32) -> *mut PixelType { pub unsafe fn pixels_at_mut_ptr_unchecked(&mut self, x: i32, y: i32) -> *mut PixelType {
let offset = self.get_offset_to_xy(x, y); let offset = self.get_offset_to_xy(x, y);
@ -482,15 +498,15 @@ mod tests {
let mut bmp = Bitmap::<u8>::new(8, 8).unwrap(); let mut bmp = Bitmap::<u8>::new(8, 8).unwrap();
bmp.pixels_mut().copy_from_slice(RAW_BMP_PIXELS); bmp.pixels_mut().copy_from_slice(RAW_BMP_PIXELS);
assert_eq!(None, unsafe { bmp.pixels_at_ptr(-1, -1) }); assert_eq!(None, bmp.pixels_at_ptr(-1, -1));
let offset = bmp.get_offset_to_xy(1, 1); let offset = bmp.get_offset_to_xy(1, 1);
let pixels = unsafe { bmp.pixels_at_ptr(0, 0).unwrap() }; let pixels = bmp.pixels_at_ptr(0, 0).unwrap();
assert_eq!(0, unsafe { *pixels }); assert_eq!(0, unsafe { *pixels });
assert_eq!(1, unsafe { *(pixels.add(offset)) }); assert_eq!(1, unsafe { *(pixels.add(offset)) });
assert_eq!(2, unsafe { *(pixels.add(63)) }); assert_eq!(2, unsafe { *(pixels.add(63)) });
let pixels = unsafe { bmp.pixels_at_ptr(1, 1).unwrap() }; let pixels = bmp.pixels_at_ptr(1, 1).unwrap();
assert_eq!(1, unsafe { *pixels }); assert_eq!(1, unsafe { *pixels });
assert_eq!(2, unsafe { *(pixels.add(54)) }); assert_eq!(2, unsafe { *(pixels.add(54)) });
} }
@ -500,15 +516,15 @@ mod tests {
let mut bmp = Bitmap::<u8>::new(8, 8).unwrap(); let mut bmp = Bitmap::<u8>::new(8, 8).unwrap();
bmp.pixels_mut().copy_from_slice(RAW_BMP_PIXELS); bmp.pixels_mut().copy_from_slice(RAW_BMP_PIXELS);
assert_eq!(None, unsafe { bmp.pixels_at_mut_ptr(-1, -1) }); assert_eq!(None, bmp.pixels_at_mut_ptr(-1, -1));
let offset = bmp.get_offset_to_xy(1, 1); let offset = bmp.get_offset_to_xy(1, 1);
let pixels = unsafe { bmp.pixels_at_mut_ptr(0, 0).unwrap() }; let pixels = bmp.pixels_at_mut_ptr(0, 0).unwrap();
assert_eq!(0, unsafe { *pixels }); assert_eq!(0, unsafe { *pixels });
assert_eq!(1, unsafe { *(pixels.add(offset)) }); assert_eq!(1, unsafe { *(pixels.add(offset)) });
assert_eq!(2, unsafe { *(pixels.add(63)) }); assert_eq!(2, unsafe { *(pixels.add(63)) });
let pixels = unsafe { bmp.pixels_at_mut_ptr(1, 1).unwrap() }; let pixels = bmp.pixels_at_mut_ptr(1, 1).unwrap();
assert_eq!(1, unsafe { *pixels }); assert_eq!(1, unsafe { *pixels });
assert_eq!(2, unsafe { *(pixels.add(54)) }); assert_eq!(2, unsafe { *(pixels.add(54)) });
} }

View file

@ -178,7 +178,7 @@ impl IndexedBitmap {
Ok((bmp, palette)) Ok((bmp, palette))
} }
pub fn load_pcx_file(path: &Path) -> Result<(IndexedBitmap, Palette), PcxError> { pub fn load_pcx_file(path: impl AsRef<Path>) -> Result<(IndexedBitmap, Palette), PcxError> {
let f = File::open(path)?; let f = File::open(path)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
Self::load_pcx_bytes(&mut reader) Self::load_pcx_bytes(&mut reader)
@ -250,7 +250,7 @@ impl IndexedBitmap {
Ok(()) Ok(())
} }
pub fn to_pcx_file(&self, path: &Path, palette: &Palette) -> Result<(), PcxError> { pub fn to_pcx_file(&self, path: impl AsRef<Path>, palette: &Palette) -> Result<(), PcxError> {
let f = File::create(path)?; let f = File::create(path)?;
let mut writer = BufWriter::new(f); let mut writer = BufWriter::new(f);
self.to_pcx_bytes(&mut writer, palette) self.to_pcx_bytes(&mut writer, palette)
@ -267,7 +267,7 @@ impl RgbaBitmap {
Ok((output, palette)) Ok((output, palette))
} }
pub fn load_pcx_file(path: &Path) -> Result<(RgbaBitmap, Palette), PcxError> { pub fn load_pcx_file(path: impl AsRef<Path>) -> Result<(RgbaBitmap, Palette), PcxError> {
let (temp_bitmap, palette) = IndexedBitmap::load_pcx_file(path)?; let (temp_bitmap, palette) = IndexedBitmap::load_pcx_file(path)?;
let output = temp_bitmap.to_rgba(&palette); let output = temp_bitmap.to_rgba(&palette);
Ok((output, palette)) Ok((output, palette))
@ -286,7 +286,7 @@ mod tests {
const BASE_PATH: &str = "./test-assets/pcx/"; const BASE_PATH: &str = "./test-assets/pcx/";
fn test_file(file: &Path) -> PathBuf { fn test_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(BASE_PATH).join(file) PathBuf::from(BASE_PATH).join(file)
} }
@ -294,14 +294,14 @@ mod tests {
pub fn load_and_save() -> Result<(), PcxError> { pub fn load_and_save() -> Result<(), PcxError> {
let tmp_dir = TempDir::new()?; let tmp_dir = TempDir::new()?;
let ref_pixels = load_raw_indexed(test_file(Path::new("small.bin")).as_path())?; let ref_pixels = load_raw_indexed(test_file("small.bin"))?;
let dp2_palette = Palette::load_from_file( let dp2_palette = Palette::load_from_file(
test_assets_file(Path::new("dp2.pal")).as_path(), // test_assets_file("dp2.pal"), //
PaletteFormat::Normal, PaletteFormat::Normal,
) )
.unwrap(); .unwrap();
let (bmp, palette) = IndexedBitmap::load_pcx_file(test_file(Path::new("small.pcx")).as_path())?; let (bmp, palette) = IndexedBitmap::load_pcx_file(test_file("small.pcx"))?;
assert_eq!(16, bmp.width()); assert_eq!(16, bmp.width());
assert_eq!(16, bmp.height()); assert_eq!(16, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -324,9 +324,9 @@ mod tests {
// first image // first image
let ref_pixels = load_raw_indexed(test_file(Path::new("large_1.bin")).as_path())?; let ref_pixels = load_raw_indexed(test_file("large_1.bin"))?;
let (bmp, palette) = IndexedBitmap::load_pcx_file(test_file(Path::new("large_1.pcx")).as_path())?; let (bmp, palette) = IndexedBitmap::load_pcx_file(test_file("large_1.pcx"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -340,9 +340,9 @@ mod tests {
// second image // second image
let ref_pixels = load_raw_indexed(test_file(Path::new("large_2.bin")).as_path())?; let ref_pixels = load_raw_indexed(test_file("large_2.bin"))?;
let (bmp, palette) = IndexedBitmap::load_pcx_file(test_file(Path::new("large_2.pcx")).as_path())?; let (bmp, palette) = IndexedBitmap::load_pcx_file(test_file("large_2.pcx"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref()); assert_eq!(bmp.pixels(), ref_pixels.as_ref());

View file

@ -42,10 +42,10 @@ pub enum PngFormat {
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
enum ColorFormat { enum ColorFormat {
Grayscale = 0, Grayscale = 0,
RGB = 2, Rgb = 2,
IndexedColor = 3, IndexedColor = 3,
GrayscaleAlpha = 4, GrayscaleAlpha = 4,
RGBA = 6, Rgba = 6,
} }
impl ColorFormat { impl ColorFormat {
@ -53,10 +53,10 @@ impl ColorFormat {
use ColorFormat::*; use ColorFormat::*;
match value { match value {
0 => Ok(Grayscale), 0 => Ok(Grayscale),
2 => Ok(RGB), 2 => Ok(Rgb),
3 => Ok(IndexedColor), 3 => Ok(IndexedColor),
4 => Ok(GrayscaleAlpha), 4 => Ok(GrayscaleAlpha),
6 => Ok(RGBA), 6 => Ok(Rgba),
_ => Err(PngError::UnsupportedColorType(value)), _ => Err(PngError::UnsupportedColorType(value)),
} }
} }
@ -202,8 +202,8 @@ impl ScanlineBuffer {
pub fn new(ihdr: &ImageHeaderChunk) -> Result<Self, PngError> { pub fn new(ihdr: &ImageHeaderChunk) -> Result<Self, PngError> {
let bpp = match ihdr.format { let bpp = match ihdr.format {
ColorFormat::IndexedColor => 1, ColorFormat::IndexedColor => 1,
ColorFormat::RGB => 3, ColorFormat::Rgb => 3,
ColorFormat::RGBA => 4, ColorFormat::Rgba => 4,
_ => return Err(PngError::BadFile(format!("Unsupported color format: {:?}", ihdr.format))), _ => return Err(PngError::BadFile(format!("Unsupported color format: {:?}", ihdr.format))),
}; };
let stride = ihdr.width as usize * bpp; let stride = ihdr.width as usize * bpp;
@ -333,13 +333,13 @@ impl ScanlinePixelConverter<RGBA> for ScanlineBuffer {
))) )))
} }
} }
ColorFormat::RGB => { ColorFormat::Rgb => {
let r = self.current[offset]; let r = self.current[offset];
let g = self.current[offset + 1]; let g = self.current[offset + 1];
let b = self.current[offset + 2]; let b = self.current[offset + 2];
Ok(RGBA::from_rgb([r, g, b])) Ok(RGBA::from_rgb([r, g, b]))
} }
ColorFormat::RGBA => { ColorFormat::Rgba => {
let r = self.current[offset]; let r = self.current[offset];
let g = self.current[offset + 1]; let g = self.current[offset + 1];
let b = self.current[offset + 2]; let b = self.current[offset + 2];
@ -353,13 +353,13 @@ impl ScanlinePixelConverter<RGBA> for ScanlineBuffer {
fn write_pixel(&mut self, x: usize, pixel: RGBA) -> Result<(), PngError> { fn write_pixel(&mut self, x: usize, pixel: RGBA) -> Result<(), PngError> {
let offset = x * self.bpp; let offset = x * self.bpp;
match self.format { match self.format {
ColorFormat::RGB => { ColorFormat::Rgb => {
self.current[offset] = pixel.r(); self.current[offset] = pixel.r();
self.current[offset + 1] = pixel.g(); self.current[offset + 1] = pixel.g();
self.current[offset + 2] = pixel.b(); self.current[offset + 2] = pixel.b();
Ok(()) Ok(())
} }
ColorFormat::RGBA => { ColorFormat::Rgba => {
self.current[offset] = pixel.r(); self.current[offset] = pixel.r();
self.current[offset + 1] = pixel.g(); self.current[offset + 1] = pixel.g();
self.current[offset + 2] = pixel.b(); self.current[offset + 2] = pixel.b();
@ -400,8 +400,8 @@ where
return Err(PngError::BadFile(String::from("Unsupported color bit depth."))); return Err(PngError::BadFile(String::from("Unsupported color bit depth.")));
} }
if ihdr.format != ColorFormat::IndexedColor // . if ihdr.format != ColorFormat::IndexedColor // .
&& ihdr.format != ColorFormat::RGB && ihdr.format != ColorFormat::Rgb
&& ihdr.format != ColorFormat::RGBA && ihdr.format != ColorFormat::Rgba
{ {
return Err(PngError::BadFile(String::from("Unsupported pixel color format."))); return Err(PngError::BadFile(String::from("Unsupported pixel color format.")));
} }
@ -560,7 +560,7 @@ impl IndexedBitmap {
load_png_bytes(reader) load_png_bytes(reader)
} }
pub fn load_png_file(path: &Path) -> Result<(IndexedBitmap, Option<Palette>), PngError> { pub fn load_png_file(path: impl AsRef<Path>) -> Result<(IndexedBitmap, Option<Palette>), PngError> {
let f = File::open(path)?; let f = File::open(path)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
Self::load_png_bytes(&mut reader) Self::load_png_bytes(&mut reader)
@ -570,7 +570,7 @@ impl IndexedBitmap {
write_png_bytes(writer, self, ColorFormat::IndexedColor, Some(palette)) write_png_bytes(writer, self, ColorFormat::IndexedColor, Some(palette))
} }
pub fn to_png_file(&self, path: &Path, palette: &Palette) -> Result<(), PngError> { pub fn to_png_file(&self, path: impl AsRef<Path>, palette: &Palette) -> Result<(), PngError> {
let f = File::create(path)?; let f = File::create(path)?;
let mut writer = BufWriter::new(f); let mut writer = BufWriter::new(f);
self.to_png_bytes(&mut writer, palette) self.to_png_bytes(&mut writer, palette)
@ -582,7 +582,7 @@ impl RgbaBitmap {
load_png_bytes(reader) load_png_bytes(reader)
} }
pub fn load_png_file(path: &Path) -> Result<(RgbaBitmap, Option<Palette>), PngError> { pub fn load_png_file(path: impl AsRef<Path>) -> Result<(RgbaBitmap, Option<Palette>), PngError> {
let f = File::open(path)?; let f = File::open(path)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
Self::load_png_bytes(&mut reader) Self::load_png_bytes(&mut reader)
@ -593,14 +593,14 @@ impl RgbaBitmap {
writer, writer,
self, self,
match format { match format {
PngFormat::RGB => ColorFormat::RGB, PngFormat::RGB => ColorFormat::Rgb,
PngFormat::RGBA => ColorFormat::RGBA, PngFormat::RGBA => ColorFormat::Rgba,
}, },
None, None,
) )
} }
pub fn to_png_file(&self, path: &Path, format: PngFormat) -> Result<(), PngError> { pub fn to_png_file(&self, path: impl AsRef<Path>, format: PngFormat) -> Result<(), PngError> {
let f = File::create(path)?; let f = File::create(path)?;
let mut writer = BufWriter::new(f); let mut writer = BufWriter::new(f);
self.to_png_bytes(&mut writer, format) self.to_png_bytes(&mut writer, format)
@ -620,14 +620,14 @@ mod tests {
const BASE_PATH: &str = "./test-assets/png/"; const BASE_PATH: &str = "./test-assets/png/";
fn test_file(file: &Path) -> PathBuf { fn test_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(BASE_PATH).join(file) PathBuf::from(BASE_PATH).join(file)
} }
#[test] #[test]
pub fn loads_indexed_256_color() -> Result<(), PngError> { pub fn loads_indexed_256_color() -> Result<(), PngError> {
let ref_bytes = load_raw_indexed(test_file(Path::new("indexed_8.bin")).as_path())?; let ref_bytes = load_raw_indexed(test_file("indexed_8.bin"))?;
let (bmp, palette) = IndexedBitmap::load_png_file(test_file(Path::new("indexed_8.png")).as_path())?; let (bmp, palette) = IndexedBitmap::load_png_file(test_file("indexed_8.png"))?;
assert!(palette.is_some()); assert!(palette.is_some());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
Ok(()) Ok(())
@ -635,8 +635,8 @@ mod tests {
#[test] #[test]
pub fn loads_indexed_256_color_to_rgba_destination() -> Result<(), PngError> { pub fn loads_indexed_256_color_to_rgba_destination() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("indexed_8_rgba.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("indexed_8_rgba.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("indexed_8.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("indexed_8.png"))?;
assert!(palette.is_some()); assert!(palette.is_some());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
Ok(()) Ok(())
@ -644,8 +644,8 @@ mod tests {
#[test] #[test]
pub fn loads_rgb_color() -> Result<(), PngError> { pub fn loads_rgb_color() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("rgb.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("rgb.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("rgb.png"))?;
assert!(palette.is_none()); assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
Ok(()) Ok(())
@ -653,8 +653,8 @@ mod tests {
#[test] #[test]
pub fn loads_rgba_color() -> Result<(), PngError> { pub fn loads_rgba_color() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("rgba.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("rgba.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("rgba.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("rgba.png"))?;
assert!(palette.is_none()); assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
Ok(()) Ok(())
@ -662,8 +662,8 @@ mod tests {
#[test] #[test]
pub fn loads_filter_0() -> Result<(), PngError> { pub fn loads_filter_0() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("filter_0_rgb.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("filter_0_rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("filter_0_rgb.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("filter_0_rgb.png"))?;
assert!(palette.is_none()); assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
Ok(()) Ok(())
@ -671,8 +671,8 @@ mod tests {
#[test] #[test]
pub fn loads_filter_1() -> Result<(), PngError> { pub fn loads_filter_1() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("filter_1_rgb.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("filter_1_rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("filter_1_rgb.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("filter_1_rgb.png"))?;
assert!(palette.is_none()); assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
Ok(()) Ok(())
@ -680,8 +680,8 @@ mod tests {
#[test] #[test]
pub fn loads_filter_2() -> Result<(), PngError> { pub fn loads_filter_2() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("filter_2_rgb.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("filter_2_rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("filter_2_rgb.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("filter_2_rgb.png"))?;
assert!(palette.is_none()); assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
Ok(()) Ok(())
@ -689,8 +689,8 @@ mod tests {
#[test] #[test]
pub fn loads_filter_3() -> Result<(), PngError> { pub fn loads_filter_3() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("filter_3_rgb.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("filter_3_rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("filter_3_rgb.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("filter_3_rgb.png"))?;
assert!(palette.is_none()); assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
Ok(()) Ok(())
@ -698,8 +698,8 @@ mod tests {
#[test] #[test]
pub fn loads_filter_4() -> Result<(), PngError> { pub fn loads_filter_4() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("filter_4_rgb.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("filter_4_rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("filter_4_rgb.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("filter_4_rgb.png"))?;
assert!(palette.is_none()); assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
Ok(()) Ok(())
@ -707,13 +707,13 @@ mod tests {
#[test] #[test]
pub fn loads_larger_indexed_256color_images() -> Result<(), PngError> { pub fn loads_larger_indexed_256color_images() -> Result<(), PngError> {
let ref_bytes = load_raw_indexed(test_file(Path::new("large_1_indexed.bin")).as_path())?; let ref_bytes = load_raw_indexed(test_file("large_1_indexed.bin"))?;
let (bmp, palette) = IndexedBitmap::load_png_file(test_file(Path::new("large_1_indexed.png")).as_path())?; let (bmp, palette) = IndexedBitmap::load_png_file(test_file("large_1_indexed.png"))?;
assert!(palette.is_some()); assert!(palette.is_some());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
let ref_bytes = load_raw_indexed(test_file(Path::new("large_2_indexed.bin")).as_path())?; let ref_bytes = load_raw_indexed(test_file("large_2_indexed.bin"))?;
let (bmp, palette) = IndexedBitmap::load_png_file(test_file(Path::new("large_2_indexed.png")).as_path())?; let (bmp, palette) = IndexedBitmap::load_png_file(test_file("large_2_indexed.png"))?;
assert!(palette.is_some()); assert!(palette.is_some());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
@ -722,13 +722,13 @@ mod tests {
#[test] #[test]
pub fn loads_larger_rgb_images() -> Result<(), PngError> { pub fn loads_larger_rgb_images() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("large_1_rgba.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("large_1_rgba.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("large_1_rgb.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("large_1_rgb.png"))?;
assert!(palette.is_none()); assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
let ref_bytes = load_raw_rgba(test_file(Path::new("large_2_rgba.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("large_2_rgba.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("large_2_rgb.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("large_2_rgb.png"))?;
assert!(palette.is_none()); assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels); assert_eq!(ref_bytes, bmp.pixels);
@ -739,9 +739,9 @@ mod tests {
pub fn load_and_save_indexed_256_color() -> Result<(), PngError> { pub fn load_and_save_indexed_256_color() -> Result<(), PngError> {
let tmp_dir = TempDir::new()?; let tmp_dir = TempDir::new()?;
let ref_bytes = load_raw_indexed(test_file(Path::new("indexed_8.bin")).as_path())?; let ref_bytes = load_raw_indexed(test_file("indexed_8.bin"))?;
let (bmp, palette) = IndexedBitmap::load_png_file(test_file(Path::new("indexed_8.png")).as_path())?; let (bmp, palette) = IndexedBitmap::load_png_file(test_file("indexed_8.png"))?;
assert_eq!(32, bmp.width()); assert_eq!(32, bmp.width());
assert_eq!(32, bmp.height()); assert_eq!(32, bmp.height());
assert_eq!(bmp.pixels, ref_bytes); assert_eq!(bmp.pixels, ref_bytes);
@ -764,9 +764,9 @@ mod tests {
// first image // first image
let ref_bytes = load_raw_indexed(test_file(Path::new("large_1_indexed.bin")).as_path())?; let ref_bytes = load_raw_indexed(test_file("large_1_indexed.bin"))?;
let (bmp, palette) = IndexedBitmap::load_png_file(test_file(Path::new("large_1_indexed.png")).as_path())?; let (bmp, palette) = IndexedBitmap::load_png_file(test_file("large_1_indexed.png"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels, ref_bytes); assert_eq!(bmp.pixels, ref_bytes);
@ -782,9 +782,9 @@ mod tests {
// second image // second image
let ref_bytes = load_raw_indexed(test_file(Path::new("large_2_indexed.bin")).as_path())?; let ref_bytes = load_raw_indexed(test_file("large_2_indexed.bin"))?;
let (bmp, palette) = IndexedBitmap::load_png_file(test_file(Path::new("large_2_indexed.png")).as_path())?; let (bmp, palette) = IndexedBitmap::load_png_file(test_file("large_2_indexed.png"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels, ref_bytes); assert_eq!(bmp.pixels, ref_bytes);
@ -805,9 +805,9 @@ mod tests {
pub fn load_and_save_rgb_color() -> Result<(), PngError> { pub fn load_and_save_rgb_color() -> Result<(), PngError> {
let tmp_dir = TempDir::new()?; let tmp_dir = TempDir::new()?;
let ref_bytes = load_raw_rgba(test_file(Path::new("rgb.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("rgb.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("rgb.png"))?;
assert_eq!(32, bmp.width()); assert_eq!(32, bmp.width());
assert_eq!(32, bmp.height()); assert_eq!(32, bmp.height());
assert_eq!(bmp.pixels, ref_bytes); assert_eq!(bmp.pixels, ref_bytes);
@ -830,9 +830,9 @@ mod tests {
// first image // first image
let ref_bytes = load_raw_rgba(test_file(Path::new("large_1_rgba.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("large_1_rgba.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("large_1_rgb.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("large_1_rgb.png"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels, ref_bytes); assert_eq!(bmp.pixels, ref_bytes);
@ -848,9 +848,9 @@ mod tests {
// second image // second image
let ref_bytes = load_raw_rgba(test_file(Path::new("large_2_rgba.bin")).as_path())?; let ref_bytes = load_raw_rgba(test_file("large_2_rgba.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("large_2_rgb.png")).as_path())?; let (bmp, palette) = RgbaBitmap::load_png_file(test_file("large_2_rgb.png"))?;
assert_eq!(320, bmp.width()); assert_eq!(320, bmp.width());
assert_eq!(200, bmp.height()); assert_eq!(200, bmp.height());
assert_eq!(bmp.pixels, ref_bytes); assert_eq!(bmp.pixels, ref_bytes);
@ -869,58 +869,43 @@ mod tests {
#[test] #[test]
pub fn load_fails_on_unsupported_formats() -> Result<(), PngError> { pub fn load_fails_on_unsupported_formats() -> Result<(), PngError> {
assert_matches!(RgbaBitmap::load_png_file(test_file("unsupported_alpha_8bit.png")), Err(PngError::BadFile(..)));
assert_matches!( assert_matches!(
RgbaBitmap::load_png_file(test_file(Path::new("unsupported_alpha_8bit.png")).as_path()), RgbaBitmap::load_png_file(test_file("unsupported_greyscale_8bit.png")),
Err(PngError::BadFile(..)) Err(PngError::BadFile(..))
); );
assert_matches!( assert_matches!(
RgbaBitmap::load_png_file(test_file(Path::new("unsupported_greyscale_8bit.png")).as_path()), RgbaBitmap::load_png_file(test_file("unsupported_indexed_16col.png")),
Err(PngError::BadFile(..))
);
assert_matches!(
RgbaBitmap::load_png_file(test_file(Path::new("unsupported_indexed_16col.png")).as_path()),
Err(PngError::BadFile(..))
);
assert_matches!(
RgbaBitmap::load_png_file(test_file(Path::new("unsupported_rgb_16bit.png")).as_path()),
Err(PngError::BadFile(..))
);
assert_matches!(
RgbaBitmap::load_png_file(test_file(Path::new("unsupported_rgba_16bit.png")).as_path()),
Err(PngError::BadFile(..)) Err(PngError::BadFile(..))
); );
assert_matches!(RgbaBitmap::load_png_file(test_file("unsupported_rgb_16bit.png")), Err(PngError::BadFile(..)));
assert_matches!(RgbaBitmap::load_png_file(test_file("unsupported_rgba_16bit.png")), Err(PngError::BadFile(..)));
assert_matches!( assert_matches!(
IndexedBitmap::load_png_file(test_file(Path::new("unsupported_alpha_8bit.png")).as_path()), IndexedBitmap::load_png_file(test_file("unsupported_alpha_8bit.png")),
Err(PngError::BadFile(..)) Err(PngError::BadFile(..))
); );
assert_matches!( assert_matches!(
IndexedBitmap::load_png_file(test_file(Path::new("unsupported_greyscale_8bit.png")).as_path()), IndexedBitmap::load_png_file(test_file("unsupported_greyscale_8bit.png")),
Err(PngError::BadFile(..)) Err(PngError::BadFile(..))
); );
assert_matches!( assert_matches!(
IndexedBitmap::load_png_file(test_file(Path::new("unsupported_indexed_16col.png")).as_path()), IndexedBitmap::load_png_file(test_file("unsupported_indexed_16col.png")),
Err(PngError::BadFile(..)) Err(PngError::BadFile(..))
); );
assert_matches!( assert_matches!(
IndexedBitmap::load_png_file(test_file(Path::new("unsupported_rgb_16bit.png")).as_path()), IndexedBitmap::load_png_file(test_file("unsupported_rgb_16bit.png")),
Err(PngError::BadFile(..)) Err(PngError::BadFile(..))
); );
assert_matches!( assert_matches!(
IndexedBitmap::load_png_file(test_file(Path::new("unsupported_rgba_16bit.png")).as_path()), IndexedBitmap::load_png_file(test_file("unsupported_rgba_16bit.png")),
Err(PngError::BadFile(..)) Err(PngError::BadFile(..))
); );
// also test the extra formats that IndexedBitmap does not support which RgbaBitmap does // also test the extra formats that IndexedBitmap does not support which RgbaBitmap does
// (anything not 256-color indexed basically ...) // (anything not 256-color indexed basically ...)
assert_matches!( assert_matches!(IndexedBitmap::load_png_file(test_file("rgb.png")), Err(PngError::BadFile(..)));
IndexedBitmap::load_png_file(test_file(Path::new("rgb.png")).as_path()), assert_matches!(IndexedBitmap::load_png_file(test_file("rgba.png")), Err(PngError::BadFile(..)));
Err(PngError::BadFile(..))
);
assert_matches!(
IndexedBitmap::load_png_file(test_file(Path::new("rgba.png")).as_path()),
Err(PngError::BadFile(..))
);
Ok(()) Ok(())
} }

View file

@ -31,9 +31,12 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
} }
} }
/// Sets the pixel at the given coordinates to the color specified. The coordinates are not /// Sets the pixel at the given coordinates to the color specified.
/// checked for validity, so it is up to you to ensure they lie within the bounds of the ///
/// bitmap. /// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline] #[inline]
pub unsafe fn set_pixel_unchecked(&mut self, x: i32, y: i32, color: PixelType) { pub unsafe fn set_pixel_unchecked(&mut self, x: i32, y: i32, color: PixelType) {
let p = self.pixels_at_mut_ptr_unchecked(x, y); let p = self.pixels_at_mut_ptr_unchecked(x, y);
@ -42,8 +45,12 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
/// Sets the pixel at the given coordinates to the color returned by the given function. The /// Sets the pixel at the given coordinates to the color returned by the given function. The
/// given function is one that accepts a color value that corresponds to the current pixel at /// given function is one that accepts a color value that corresponds to the current pixel at
/// the given coordinates. The coordinates are not checked for validity, so it is up to you to /// the given coordinates.
/// ensure they lie within the bounds of the bitmap. ///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline] #[inline]
pub unsafe fn set_custom_pixel_unchecked(&mut self, x: i32, y: i32, pixel_fn: impl Fn(PixelType) -> PixelType) { pub unsafe fn set_custom_pixel_unchecked(&mut self, x: i32, y: i32, pixel_fn: impl Fn(PixelType) -> PixelType) {
let p = self.pixels_at_mut_ptr_unchecked(x, y); let p = self.pixels_at_mut_ptr_unchecked(x, y);
@ -57,8 +64,12 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
self.pixels_at(x, y).map(|pixels| pixels[0]) self.pixels_at(x, y).map(|pixels| pixels[0])
} }
/// Gets the pixel at the given coordinates. The coordinates are not checked for validity, so /// Gets the pixel at the given coordinates.
/// it is up to you to ensure they lie within the bounds of the bitmap. ///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline] #[inline]
pub unsafe fn get_pixel_unchecked(&self, x: i32, y: i32) -> PixelType { pub unsafe fn get_pixel_unchecked(&self, x: i32, y: i32) -> PixelType {
*(self.pixels_at_ptr_unchecked(x, y)) *(self.pixels_at_ptr_unchecked(x, y))

View file

@ -111,6 +111,10 @@ pub enum RgbaBlitMethod {
} }
impl RgbaBitmap { impl RgbaBitmap {
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn solid_tinted_blit( pub unsafe fn solid_tinted_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -131,6 +135,10 @@ impl RgbaBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn solid_blended_blit( pub unsafe fn solid_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -151,6 +159,10 @@ impl RgbaBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn solid_flipped_blended_blit( pub unsafe fn solid_flipped_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -175,6 +187,10 @@ impl RgbaBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn solid_flipped_tinted_blit( pub unsafe fn solid_flipped_tinted_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -199,6 +215,10 @@ impl RgbaBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_tinted_blit( pub unsafe fn transparent_tinted_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -222,6 +242,10 @@ impl RgbaBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_blended_blit( pub unsafe fn transparent_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -245,6 +269,10 @@ impl RgbaBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_flipped_tinted_blit( pub unsafe fn transparent_flipped_tinted_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -272,6 +300,10 @@ impl RgbaBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn transparent_flipped_blended_blit( pub unsafe fn transparent_flipped_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -299,6 +331,10 @@ impl RgbaBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn rotozoom_tinted_blit( pub unsafe fn rotozoom_tinted_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -325,6 +361,10 @@ impl RgbaBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn rotozoom_blended_blit( pub unsafe fn rotozoom_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -353,6 +393,10 @@ impl RgbaBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn rotozoom_transparent_tinted_blit( pub unsafe fn rotozoom_transparent_tinted_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -382,6 +426,10 @@ impl RgbaBitmap {
); );
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
pub unsafe fn rotozoom_transparent_blended_blit( pub unsafe fn rotozoom_transparent_blended_blit(
&mut self, &mut self,
src: &Self, src: &Self,
@ -479,6 +527,10 @@ impl RgbaBitmap {
}; };
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
#[inline] #[inline]
#[rustfmt::skip] #[rustfmt::skip]
pub unsafe fn blit_region_unchecked( pub unsafe fn blit_region_unchecked(
@ -561,12 +613,20 @@ impl RgbaBitmap {
} }
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
#[inline] #[inline]
pub unsafe fn blit_unchecked(&mut self, method: RgbaBlitMethod, src: &Self, x: i32, y: i32) { pub unsafe fn blit_unchecked(&mut self, method: RgbaBlitMethod, src: &Self, x: i32, y: i32) {
let src_region = Rect::new(0, 0, src.width, src.height); let src_region = Rect::new(0, 0, src.width, src.height);
self.blit_region_unchecked(method, src, &src_region, x, y); self.blit_region_unchecked(method, src, &src_region, x, y);
} }
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the source and destination bitmaps.
#[inline] #[inline]
pub unsafe fn blit_atlas_unchecked( pub unsafe fn blit_atlas_unchecked(
&mut self, &mut self,

View file

@ -60,8 +60,8 @@ impl RgbaBitmap {
Ok(bitmap) Ok(bitmap)
} }
pub fn load_file(path: &Path) -> Result<(Self, Option<Palette>), BitmapError> { pub fn load_file(path: impl AsRef<Path>) -> Result<(Self, Option<Palette>), BitmapError> {
if let Some(extension) = path.extension() { if let Some(extension) = path.as_ref().extension() {
let extension = extension.to_ascii_lowercase(); let extension = extension.to_ascii_lowercase();
match extension.to_str() { match extension.to_str() {
Some("png") => Ok(Self::load_png_file(path)?), Some("png") => Ok(Self::load_png_file(path)?),

View file

@ -12,8 +12,11 @@ impl RgbaBitmap {
); );
} }
/// Sets the pixel at the given coordinates using a blended color via the specified blend function, /// Sets the pixel at the given coordinates using a blended color via the specified blend function.
/// The coordinates are not checked for validity, so it is up to you to ensure they lie within the ///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap. /// bounds of the bitmap.
#[inline] #[inline]
pub unsafe fn set_blended_pixel_unchecked(&mut self, x: i32, y: i32, color: RGBA, blend: BlendFunction) { pub unsafe fn set_blended_pixel_unchecked(&mut self, x: i32, y: i32, color: RGBA, blend: BlendFunction) {

View file

@ -1,5 +1,5 @@
use std::simd; use std::simd;
use std::simd::{SimdFloat, SimdUint}; use std::simd::prelude::{SimdFloat, SimdUint};
use crate::graphics::{edge_function, per_pixel_triangle_2d, BlendFunction, RgbaBitmap, RGBA}; use crate::graphics::{edge_function, per_pixel_triangle_2d, BlendFunction, RgbaBitmap, RGBA};
use crate::math::Vector2; use crate::math::Vector2;

View file

@ -232,7 +232,7 @@ pub struct BitmapAtlasDescriptor {
} }
impl BitmapAtlasDescriptor { impl BitmapAtlasDescriptor {
pub fn load_from_file(path: &Path) -> Result<Self, BitmapAtlasDescriptorError> { pub fn load_from_file(path: impl AsRef<Path>) -> Result<Self, BitmapAtlasDescriptorError> {
let f = File::open(path)?; let f = File::open(path)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
Self::load_from_bytes(&mut reader) Self::load_from_bytes(&mut reader)
@ -245,7 +245,7 @@ impl BitmapAtlasDescriptor {
} }
} }
pub fn to_file(&self, path: &Path) -> Result<(), BitmapAtlasDescriptorError> { pub fn to_file(&self, path: impl AsRef<Path>) -> Result<(), BitmapAtlasDescriptorError> {
let f = File::create(path)?; let f = File::create(path)?;
let mut writer = BufWriter::new(f); let mut writer = BufWriter::new(f);
self.to_bytes(&mut writer) self.to_bytes(&mut writer)

View file

@ -239,7 +239,7 @@ impl BlendMap {
self.get_mapping(source_color).map(|mapping| mapping[dest_color as usize]) self.get_mapping(source_color).map(|mapping| mapping[dest_color as usize])
} }
pub fn load_from_file(path: &Path) -> Result<Self, BlendMapError> { pub fn load_from_file(path: impl AsRef<Path>) -> Result<Self, BlendMapError> {
let f = File::open(path)?; let f = File::open(path)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
Self::load_from_bytes(&mut reader) Self::load_from_bytes(&mut reader)
@ -268,7 +268,7 @@ impl BlendMap {
}) })
} }
pub fn to_file(&self, path: &Path) -> Result<(), BlendMapError> { pub fn to_file(&self, path: impl AsRef<Path>) -> Result<(), BlendMapError> {
let f = File::create(path)?; let f = File::create(path)?;
let mut writer = BufWriter::new(f); let mut writer = BufWriter::new(f);
self.to_bytes(&mut writer) self.to_bytes(&mut writer)

View file

@ -1,6 +1,6 @@
use std::ops::{Mul, MulAssign}; use std::ops::{Mul, MulAssign};
use std::simd; use std::simd;
use std::simd::{SimdFloat, SimdUint}; use std::simd::prelude::{SimdFloat, SimdUint};
use byteorder::{ReadBytesExt, WriteBytesExt}; use byteorder::{ReadBytesExt, WriteBytesExt};

View file

@ -209,7 +209,7 @@ impl BitmaskFont {
Ok(font) Ok(font)
} }
pub fn load_from_file(path: &Path) -> Result<BitmaskFont, FontError> { pub fn load_from_file(path: impl AsRef<Path>) -> Result<BitmaskFont, FontError> {
let f = File::open(path)?; let f = File::open(path)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
@ -232,8 +232,8 @@ impl BitmaskFont {
} }
// read character widths (used for rendering) // read character widths (used for rendering)
for i in 0..NUM_CHARS { for character in characters.iter_mut().take(NUM_CHARS) {
characters[i].bounds.width = reader.read_u8()? as u32; character.bounds.width = reader.read_u8()? as u32;
} }
// read global font height (used for rendering) // read global font height (used for rendering)
@ -242,7 +242,7 @@ impl BitmaskFont {
Self::new(&characters, line_height as usize) Self::new(&characters, line_height as usize)
} }
pub fn to_file(&self, path: &Path) -> Result<(), FontError> { pub fn to_file(&self, path: impl AsRef<Path>) -> Result<(), FontError> {
let f = File::create(path)?; let f = File::create(path)?;
let mut writer = BufWriter::new(f); let mut writer = BufWriter::new(f);
self.to_bytes(&mut writer) self.to_bytes(&mut writer)
@ -327,13 +327,13 @@ mod tests {
const BASE_PATH: &str = "./test-assets/font/"; const BASE_PATH: &str = "./test-assets/font/";
fn test_file(file: &Path) -> PathBuf { fn test_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(BASE_PATH).join(file) PathBuf::from(BASE_PATH).join(file)
} }
#[test] #[test]
pub fn load_font() -> Result<(), FontError> { pub fn load_font() -> Result<(), FontError> {
let font = BitmaskFont::load_from_file(test_file(Path::new("vga.fnt")).as_path())?; let font = BitmaskFont::load_from_file(test_file("vga.fnt"))?;
assert_eq!(256, font.characters.len()); assert_eq!(256, font.characters.len());
assert_eq!(CHAR_FIXED_WIDTH as u8, font.space_width); assert_eq!(CHAR_FIXED_WIDTH as u8, font.space_width);
for character in font.characters.iter() { for character in font.characters.iter() {
@ -347,7 +347,7 @@ mod tests {
#[test] #[test]
pub fn measure_text() -> Result<(), FontError> { pub fn measure_text() -> Result<(), FontError> {
{ {
let font = BitmaskFont::load_from_file(test_file(Path::new("vga.fnt")).as_path())?; let font = BitmaskFont::load_from_file(test_file("vga.fnt"))?;
assert_eq!((40, 8), font.measure("Hello", FontRenderOpts::<u8>::None)); assert_eq!((40, 8), font.measure("Hello", FontRenderOpts::<u8>::None));
assert_eq!((40, 16), font.measure("Hello\nthere", FontRenderOpts::<u8>::None)); assert_eq!((40, 16), font.measure("Hello\nthere", FontRenderOpts::<u8>::None));
@ -361,7 +361,7 @@ mod tests {
} }
{ {
let font = BitmaskFont::load_from_file(test_file(Path::new("small.fnt")).as_path())?; let font = BitmaskFont::load_from_file(test_file("small.fnt"))?;
assert_eq!((22, 7), font.measure("Hello", FontRenderOpts::<u8>::None)); assert_eq!((22, 7), font.measure("Hello", FontRenderOpts::<u8>::None));
assert_eq!((24, 14), font.measure("Hello\nthere", FontRenderOpts::<u8>::None)); assert_eq!((24, 14), font.measure("Hello\nthere", FontRenderOpts::<u8>::None));

View file

@ -34,12 +34,11 @@ fn read_palette_6bit<T: ReadBytesExt>(reader: &mut T, num_colors: usize) -> Resu
return Err(PaletteError::OutOfRange(num_colors)); return Err(PaletteError::OutOfRange(num_colors));
} }
let mut colors = [RGBA::from_rgba([0, 0, 0, 255]); NUM_COLORS]; let mut colors = [RGBA::from_rgba([0, 0, 0, 255]); NUM_COLORS];
for i in 0..num_colors { for color in colors.iter_mut().take(num_colors) {
let r = reader.read_u8()?; let r = reader.read_u8()?;
let g = reader.read_u8()?; let g = reader.read_u8()?;
let b = reader.read_u8()?; let b = reader.read_u8()?;
let color = RGBA::from_rgb([from_6bit(r), from_6bit(g), from_6bit(b)]); *color = RGBA::from_rgb([from_6bit(r), from_6bit(g), from_6bit(b)]);
colors[i] = color;
} }
Ok(colors) Ok(colors)
} }
@ -52,10 +51,10 @@ fn write_palette_6bit<T: WriteBytesExt>(
if num_colors > NUM_COLORS { if num_colors > NUM_COLORS {
return Err(PaletteError::OutOfRange(num_colors)); return Err(PaletteError::OutOfRange(num_colors));
} }
for i in 0..num_colors { for color in colors.iter().take(num_colors) {
writer.write_u8(to_6bit(colors[i].r()))?; writer.write_u8(to_6bit(color.r()))?;
writer.write_u8(to_6bit(colors[i].g()))?; writer.write_u8(to_6bit(color.g()))?;
writer.write_u8(to_6bit(colors[i].b()))?; writer.write_u8(to_6bit(color.b()))?;
} }
Ok(()) Ok(())
} }
@ -66,12 +65,11 @@ fn read_palette_8bit<T: ReadBytesExt>(reader: &mut T, num_colors: usize) -> Resu
return Err(PaletteError::OutOfRange(num_colors)); return Err(PaletteError::OutOfRange(num_colors));
} }
let mut colors = [RGBA::from_rgba([0, 0, 0, 255]); NUM_COLORS]; let mut colors = [RGBA::from_rgba([0, 0, 0, 255]); NUM_COLORS];
for i in 0..num_colors { for color in colors.iter_mut().take(num_colors) {
let r = reader.read_u8()?; let r = reader.read_u8()?;
let g = reader.read_u8()?; let g = reader.read_u8()?;
let b = reader.read_u8()?; let b = reader.read_u8()?;
let color = RGBA::from_rgb([r, g, b]); *color = RGBA::from_rgb([r, g, b]);
colors[i] = color;
} }
Ok(colors) Ok(colors)
} }
@ -84,10 +82,10 @@ fn write_palette_8bit<T: WriteBytesExt>(
if num_colors > NUM_COLORS { if num_colors > NUM_COLORS {
return Err(PaletteError::OutOfRange(num_colors)); return Err(PaletteError::OutOfRange(num_colors));
} }
for i in 0..num_colors { for color in colors.iter().take(num_colors) {
writer.write_u8(colors[i].r())?; writer.write_u8(color.r())?;
writer.write_u8(colors[i].g())?; writer.write_u8(color.g())?;
writer.write_u8(colors[i].b())?; writer.write_u8(color.b())?;
} }
Ok(()) Ok(())
} }
@ -137,7 +135,7 @@ impl Palette {
/// ///
/// * `path`: the path of the palette file to be loaded /// * `path`: the path of the palette file to be loaded
/// * `format`: the format that the palette data is expected to be in /// * `format`: the format that the palette data is expected to be in
pub fn load_from_file(path: &Path, format: PaletteFormat) -> Result<Palette, PaletteError> { pub fn load_from_file(path: impl AsRef<Path>, format: PaletteFormat) -> Result<Palette, PaletteError> {
let f = File::open(path)?; let f = File::open(path)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
Self::load_from_bytes(&mut reader, format) Self::load_from_bytes(&mut reader, format)
@ -168,7 +166,7 @@ impl Palette {
/// * `format`: the format that the palette data is expected to be in /// * `format`: the format that the palette data is expected to be in
/// * `num_colors`: the expected number of colors in the palette to be loaded (<= 256) /// * `num_colors`: the expected number of colors in the palette to be loaded (<= 256)
pub fn load_num_colors_from_file( pub fn load_num_colors_from_file(
path: &Path, path: impl AsRef<Path>,
format: PaletteFormat, format: PaletteFormat,
num_colors: usize, num_colors: usize,
) -> Result<Palette, PaletteError> { ) -> Result<Palette, PaletteError> {
@ -208,7 +206,7 @@ impl Palette {
/// ///
/// * `path`: the path of the file to save the palette to /// * `path`: the path of the file to save the palette to
/// * `format`: the format to write the palette data in /// * `format`: the format to write the palette data in
pub fn to_file(&self, path: &Path, format: PaletteFormat) -> Result<(), PaletteError> { pub fn to_file(&self, path: impl AsRef<Path>, format: PaletteFormat) -> Result<(), PaletteError> {
let f = File::create(path)?; let f = File::create(path)?;
let mut writer = BufWriter::new(f); let mut writer = BufWriter::new(f);
self.to_bytes(&mut writer, format) self.to_bytes(&mut writer, format)
@ -239,7 +237,7 @@ impl Palette {
/// * `num_colors`: the number of colors from this palette to write out to the file (<= 256) /// * `num_colors`: the number of colors from this palette to write out to the file (<= 256)
pub fn num_colors_to_file( pub fn num_colors_to_file(
&self, &self,
path: &Path, path: impl AsRef<Path>,
format: PaletteFormat, format: PaletteFormat,
num_colors: usize, num_colors: usize,
) -> Result<(), PaletteError> { ) -> Result<(), PaletteError> {
@ -471,6 +469,12 @@ impl Palette {
} }
} }
impl Default for Palette {
fn default() -> Self {
Self::new()
}
}
impl Index<u8> for Palette { impl Index<u8> for Palette {
type Output = RGBA; type Output = RGBA;
@ -499,7 +503,7 @@ mod tests {
const BASE_PATH: &str = "./test-assets/palette/"; const BASE_PATH: &str = "./test-assets/palette/";
fn test_file(file: &Path) -> PathBuf { fn test_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(BASE_PATH).join(file) PathBuf::from(BASE_PATH).join(file)
} }
@ -538,7 +542,7 @@ mod tests {
// vga rgb format (6-bit) // vga rgb format (6-bit)
let palette = Palette::load_from_file(test_file(Path::new("vga.pal")).as_path(), PaletteFormat::Vga)?; let palette = Palette::load_from_file(test_file("vga.pal"), PaletteFormat::Vga)?;
assert_ega_colors(&palette); assert_ega_colors(&palette);
let save_path = tmp_dir.path().join("test_save_vga_format.pal"); let save_path = tmp_dir.path().join("test_save_vga_format.pal");
@ -548,7 +552,7 @@ mod tests {
// normal rgb format (8-bit) // normal rgb format (8-bit)
let palette = Palette::load_from_file(test_file(Path::new("dp2.pal")).as_path(), PaletteFormat::Normal)?; let palette = Palette::load_from_file(test_file("dp2.pal"), PaletteFormat::Normal)?;
let save_path = tmp_dir.path().join("test_save_normal_format.pal"); let save_path = tmp_dir.path().join("test_save_normal_format.pal");
palette.to_file(&save_path, PaletteFormat::Normal)?; palette.to_file(&save_path, PaletteFormat::Normal)?;
@ -564,8 +568,7 @@ mod tests {
// vga rgb format (6-bit) // vga rgb format (6-bit)
let palette = let palette = Palette::load_num_colors_from_file(test_file("ega_6bit.pal"), PaletteFormat::Vga, 16)?;
Palette::load_num_colors_from_file(test_file(Path::new("ega_6bit.pal")).as_path(), PaletteFormat::Vga, 16)?;
assert_ega_colors(&palette); assert_ega_colors(&palette);
let save_path = tmp_dir.path().join("test_save_vga_format_16_colors.pal"); let save_path = tmp_dir.path().join("test_save_vga_format_16_colors.pal");
@ -575,11 +578,7 @@ mod tests {
// normal rgb format (8-bit) // normal rgb format (8-bit)
let palette = Palette::load_num_colors_from_file( let palette = Palette::load_num_colors_from_file(test_file("ega_8bit.pal"), PaletteFormat::Normal, 16)?;
test_file(Path::new("ega_8bit.pal")).as_path(),
PaletteFormat::Normal,
16,
)?;
let save_path = tmp_dir.path().join("test_save_normal_format_16_colors.pal"); let save_path = tmp_dir.path().join("test_save_normal_format_16_colors.pal");
palette.to_file(&save_path, PaletteFormat::Normal)?; palette.to_file(&save_path, PaletteFormat::Normal)?;

View file

@ -30,15 +30,15 @@ mod tests {
const TEST_ASSETS_PATH: &str = "./test-assets/"; const TEST_ASSETS_PATH: &str = "./test-assets/";
#[allow(dead_code)] #[allow(dead_code)]
pub fn assets_file(file: &Path) -> PathBuf { pub fn assets_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(ASSETS_PATH).join(file) PathBuf::from(ASSETS_PATH).join(file)
} }
pub fn test_assets_file(file: &Path) -> PathBuf { pub fn test_assets_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(TEST_ASSETS_PATH).join(file) PathBuf::from(TEST_ASSETS_PATH).join(file)
} }
pub fn load_raw_indexed(bin_file: &Path) -> Result<Box<[u8]>, io::Error> { pub fn load_raw_indexed(bin_file: impl AsRef<Path>) -> Result<Box<[u8]>, io::Error> {
let f = File::open(bin_file)?; let f = File::open(bin_file)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
let mut buffer = Vec::new(); let mut buffer = Vec::new();
@ -46,7 +46,7 @@ mod tests {
Ok(buffer.into_boxed_slice()) Ok(buffer.into_boxed_slice())
} }
pub fn load_raw_rgba(bin_file: &Path) -> Result<Box<[RGBA]>, io::Error> { pub fn load_raw_rgba(bin_file: impl AsRef<Path>) -> Result<Box<[RGBA]>, io::Error> {
let f = File::open(bin_file)?; let f = File::open(bin_file)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
let mut buffer = Vec::new(); let mut buffer = Vec::new();

View file

@ -24,8 +24,7 @@ impl Circle {
let mut max_x = min_x; let mut max_x = min_x;
let mut max_y = min_y; let mut max_y = min_y;
for i in 0..points.len() { for point in points.iter() {
let point = &points[i];
min_x = point.x.min(min_x); min_x = point.x.min(min_x);
min_y = point.y.min(min_y); min_y = point.y.min(min_y);
max_x = point.x.max(max_x); max_x = point.x.max(max_x);

View file

@ -1,6 +1,6 @@
use std::ops::{Add, Div, Mul, Sub}; use std::ops::{Add, Div, Mul, Sub};
use std::simd; use std::simd;
use std::simd::{SimdFloat, SimdPartialOrd}; use std::simd::prelude::{SimdFloat, SimdPartialOrd};
mod circle; mod circle;
mod matrix3x3; mod matrix3x3;
@ -272,6 +272,7 @@ mod tests {
assert!(nearly_equal(0.0, angle, 0.0001)); assert!(nearly_equal(0.0, angle, 0.0001));
} }
#[allow(clippy::approx_constant)]
#[test] #[test]
pub fn test_angle_to_direction() { pub fn test_angle_to_direction() {
let (x, y) = angle_to_direction(RADIANS_0); let (x, y) = angle_to_direction(RADIANS_0);

View file

@ -435,6 +435,7 @@ mod tests {
assert!(nearly_equal(crate::math::RIGHT, Vector2::RIGHT.angle(), 0.0001)); assert!(nearly_equal(crate::math::RIGHT, Vector2::RIGHT.angle(), 0.0001));
} }
#[allow(clippy::approx_constant)]
#[test] #[test]
pub fn test_from_angle() { pub fn test_from_angle() {
let v = Vector2::from_angle(RADIANS_0); let v = Vector2::from_angle(RADIANS_0);

View file

@ -445,6 +445,12 @@ impl<ContextType> States<ContextType> {
} }
} }
impl<ContextType> Default for States<ContextType> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use claim::*; use claim::*;

View file

@ -55,6 +55,12 @@ impl Keyboard {
} }
} }
impl Default for Keyboard {
fn default() -> Self {
Self::new()
}
}
impl InputDevice for Keyboard { impl InputDevice for Keyboard {
fn update(&mut self) { fn update(&mut self) {
for state in self.keyboard.iter_mut() { for state in self.keyboard.iter_mut() {

View file

@ -202,6 +202,16 @@ where
} }
} }
impl<BitmapType> Default for CustomMouseCursor<BitmapType>
where
Self: DefaultMouseCursorBitmaps<BitmapType>,
BitmapType: GeneralBitmap,
{
fn default() -> Self {
Self::new()
}
}
impl DefaultMouseCursorBitmaps<IndexedBitmap> for CustomMouseCursor<IndexedBitmap> { impl DefaultMouseCursorBitmaps<IndexedBitmap> for CustomMouseCursor<IndexedBitmap> {
fn get_default() -> MouseCursorBitmap<IndexedBitmap> { fn get_default() -> MouseCursorBitmap<IndexedBitmap> {
#[rustfmt::skip] #[rustfmt::skip]

View file

@ -103,6 +103,12 @@ impl Mouse {
} }
} }
impl Default for Mouse {
fn default() -> Self {
Self::new()
}
}
impl InputDevice for Mouse { impl InputDevice for Mouse {
fn update(&mut self) { fn update(&mut self) {
self.x_delta = 0; self.x_delta = 0;

View file

@ -1,6 +1,7 @@
use thiserror::Error; use thiserror::Error;
use crate::audio::AudioError; use crate::audio::AudioError;
use crate::utils::app_root_dir;
mod event; mod event;
mod framebuffer; mod framebuffer;
@ -51,6 +52,9 @@ pub enum SystemError {
#[error("SystemResources error: {0}")] #[error("SystemResources error: {0}")]
SystemResourcesError(#[from] SystemResourcesError), SystemResourcesError(#[from] SystemResourcesError),
#[error("System I/O error")]
IOError(#[from] std::io::Error),
} }
/// Builder for configuring and constructing an instance of [`System`]. /// Builder for configuring and constructing an instance of [`System`].
@ -195,6 +199,8 @@ impl SystemBuilder {
let event_pump = SystemEventPump::from(sdl_event_pump); let event_pump = SystemEventPump::from(sdl_event_pump);
let app_root_dir = app_root_dir()?;
Ok(System { Ok(System {
sdl_context, sdl_context,
sdl_audio_subsystem, sdl_audio_subsystem,
@ -202,6 +208,7 @@ impl SystemBuilder {
sdl_timer_subsystem, sdl_timer_subsystem,
res: system_resources, res: system_resources,
event_pump, event_pump,
app_root_dir,
vsync: self.vsync, vsync: self.vsync,
target_framerate: self.target_framerate, target_framerate: self.target_framerate,
target_framerate_delta: None, target_framerate_delta: None,
@ -210,6 +217,12 @@ impl SystemBuilder {
} }
} }
impl Default for SystemBuilder {
fn default() -> Self {
Self::new()
}
}
/// Holds all primary structures necessary for interacting with the operating system and for /// Holds all primary structures necessary for interacting with the operating system and for
/// applications to render to the display, react to input device events, etc. through the /// applications to render to the display, react to input device events, etc. through the
/// "virtual machine" exposed by this library. /// "virtual machine" exposed by this library.
@ -231,6 +244,8 @@ where
pub res: SystemResType, pub res: SystemResType,
pub event_pump: SystemEventPump, pub event_pump: SystemEventPump,
pub app_root_dir: std::path::PathBuf,
} }
impl<SystemResType> std::fmt::Debug for System<SystemResType> impl<SystemResType> std::fmt::Debug for System<SystemResType>

View file

@ -1,5 +1,8 @@
use byteorder::{ReadBytesExt, WriteBytesExt}; use byteorder::{ReadBytesExt, WriteBytesExt};
use std::io::{Error, SeekFrom}; use std::{
io::{Error, SeekFrom},
path::PathBuf,
};
/// Provides a convenience method for determining the total size of a stream. This is provided /// Provides a convenience method for determining the total size of a stream. This is provided
/// as a temporary alternative to [std::io::Seek::stream_len] which is currently marked unstable. /// as a temporary alternative to [std::io::Seek::stream_len] which is currently marked unstable.
@ -34,3 +37,28 @@ pub trait WriteType {
fn write<T: WriteBytesExt>(&self, writer: &mut T) -> Result<(), Self::ErrorType>; fn write<T: WriteBytesExt>(&self, writer: &mut T) -> Result<(), Self::ErrorType>;
} }
/// Returns the application root directory (the directory that the application executable is
/// located in).
///
/// First tries to automatically detect this from the `CARGO_MANIFEST_DIR` environment variable,
/// if present, to catch scenarios where the application is running from a Cargo workspace as a
/// sub-project/binary within that workspace. In such a case, the application root directory is
/// the same as that sub-project/binary's `Cargo.toml`.
///
/// If `CARGO_MANIFEST_DIR` is not present, then an attempt is made to determine the application
/// root directory from the running executable's location.
///
/// If this fails for some reason, then this returns the current working directory.
pub fn app_root_dir() -> Result<PathBuf, Error> {
if let Some(manifest_path) = std::env::var_os("CARGO_MANIFEST_DIR") {
return Ok(PathBuf::from(manifest_path));
}
let mut exe_path = std::env::current_exe()?.canonicalize()?;
if exe_path.pop() {
return Ok(exe_path);
}
std::env::current_dir()
}

View file

@ -537,8 +537,8 @@ where
// this does mean that the size of the table is always 2 less than the number of created codes. // this does mean that the size of the table is always 2 less than the number of created codes.
let mut table = vec![None; 1usize.wrapping_shl(MAX_BITS as u32)]; let mut table = vec![None; 1usize.wrapping_shl(MAX_BITS as u32)];
for i in 0..initial_table_size { for (i, item) in table.iter_mut().enumerate().take(initial_table_size) {
table[i] = Some(vec![i as u8]); *item = Some(vec![i as u8]);
} }
let mut max_code_value_for_bit_size = get_max_code_value_for_bits(current_bit_size); let mut max_code_value_for_bit_size = get_max_code_value_for_bits(current_bit_size);
let mut next_code = initial_table_size as LzwCode + 2; let mut next_code = initial_table_size as LzwCode + 2;

View file

@ -11,7 +11,7 @@ const SCREEN_HEIGHT: u32 = 240;
const BASE_PATH: &str = "./tests/ref/indexed/"; const BASE_PATH: &str = "./tests/ref/indexed/";
fn reference_file(file: &Path) -> PathBuf { fn reference_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(BASE_PATH).join(file) PathBuf::from(BASE_PATH).join(file)
} }
@ -22,8 +22,8 @@ fn setup() -> (IndexedBitmap, Palette) {
} }
fn setup_for_blending() -> (IndexedBitmap, Palette, BlendMap) { fn setup_for_blending() -> (IndexedBitmap, Palette, BlendMap) {
let (texture, palette) = IndexedBitmap::load_file(test_assets_file(Path::new("texture.lbm")).as_path()).unwrap(); let (texture, palette) = IndexedBitmap::load_file(test_assets_file("texture.lbm")).unwrap();
let blend_map = BlendMap::load_from_file(test_assets_file(Path::new("test.blendmap")).as_path()).unwrap(); let blend_map = BlendMap::load_from_file(test_assets_file("test.blendmap")).unwrap();
let mut screen = IndexedBitmap::new(SCREEN_WIDTH, SCREEN_HEIGHT).unwrap(); let mut screen = IndexedBitmap::new(SCREEN_WIDTH, SCREEN_HEIGHT).unwrap();
for y in 0..(SCREEN_HEIGHT as f32 / texture.height() as f32).ceil() as i32 { for y in 0..(SCREEN_HEIGHT as f32 / texture.height() as f32).ceil() as i32 {
for x in 0..(SCREEN_WIDTH as f32 / texture.width() as f32).ceil() as i32 { for x in 0..(SCREEN_WIDTH as f32 / texture.width() as f32).ceil() as i32 {
@ -33,7 +33,7 @@ fn setup_for_blending() -> (IndexedBitmap, Palette, BlendMap) {
(screen, palette, blend_map) (screen, palette, blend_map)
} }
fn verify_visual(screen: &IndexedBitmap, palette: &Palette, source: &Path) -> bool { fn verify_visual(screen: &IndexedBitmap, palette: &Palette, source: impl AsRef<Path>) -> bool {
let (source_bmp, source_pal) = IndexedBitmap::load_file(source).unwrap(); let (source_bmp, source_pal) = IndexedBitmap::load_file(source).unwrap();
*screen == source_bmp && *palette == source_pal *screen == source_bmp && *palette == source_pal
} }
@ -79,11 +79,11 @@ fn pixel_addressing() {
} }
} }
let path = reference_file(Path::new("pixel_addressing.png")); let path = &reference_file("pixel_addressing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -133,11 +133,11 @@ fn pixel_drawing() {
screen.set_pixel(160, i + 234, 15); screen.set_pixel(160, i + 234, 15);
} }
let path = reference_file(Path::new("pixel_drawing.png")); let path = &reference_file("pixel_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -169,11 +169,11 @@ fn blended_pixel_drawing() {
screen.set_blended_pixel(160, i + 234, 15, &blend_map); screen.set_blended_pixel(160, i + 234, 15, &blend_map);
} }
let path = reference_file(Path::new("blended_pixel_drawing.png")); let path = &reference_file("blended_pixel_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -191,11 +191,11 @@ fn horiz_line_drawing() {
screen.horiz_line(100, 200, -10, 6); screen.horiz_line(100, 200, -10, 6);
screen.horiz_line(20, 80, 250, 7); screen.horiz_line(20, 80, 250, 7);
let path = reference_file(Path::new("horiz_line_drawing.png")); let path = &reference_file("horiz_line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -213,11 +213,11 @@ fn blended_horiz_line_drawing() {
screen.blended_horiz_line(100, 200, -10, 6, &blend_map); screen.blended_horiz_line(100, 200, -10, 6, &blend_map);
screen.blended_horiz_line(20, 80, 250, 7, &blend_map); screen.blended_horiz_line(20, 80, 250, 7, &blend_map);
let path = reference_file(Path::new("blended_horiz_line_drawing.png")); let path = &reference_file("blended_horiz_line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -235,11 +235,11 @@ fn vert_line_drawing() {
screen.vert_line(-17, 10, 20, 6); screen.vert_line(-17, 10, 20, 6);
screen.vert_line(400, 100, 300, 7); screen.vert_line(400, 100, 300, 7);
let path = reference_file(Path::new("vert_line_drawing.png")); let path = &reference_file("vert_line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -257,11 +257,11 @@ fn blended_vert_line_drawing() {
screen.blended_vert_line(-17, 10, 20, 6, &blend_map); screen.blended_vert_line(-17, 10, 20, 6, &blend_map);
screen.blended_vert_line(400, 100, 300, 7, &blend_map); screen.blended_vert_line(400, 100, 300, 7, &blend_map);
let path = reference_file(Path::new("blended_vert_line_drawing.png")); let path = &reference_file("blended_vert_line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -296,11 +296,11 @@ fn line_drawing() {
screen.line(-100, 120, -100, 239, 3); screen.line(-100, 120, -100, 239, 3);
screen.line(320, 99, 320, 199, 5); screen.line(320, 99, 320, 199, 5);
let path = reference_file(Path::new("line_drawing.png")); let path = &reference_file("line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -335,11 +335,11 @@ fn blended_line_drawing() {
screen.blended_line(-100, 120, -100, 239, 3, &blend_map); screen.blended_line(-100, 120, -100, 239, 3, &blend_map);
screen.blended_line(320, 99, 320, 199, 5, &blend_map); screen.blended_line(320, 99, 320, 199, 5, &blend_map);
let path = reference_file(Path::new("blended_line_drawing.png")); let path = &reference_file("blended_line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -365,11 +365,11 @@ fn rect_drawing() {
screen.rect(300, 20, 340, -20, 13); screen.rect(300, 20, 340, -20, 13);
screen.rect(20, 220, -20, 260, 14); screen.rect(20, 220, -20, 260, 14);
let path = reference_file(Path::new("rect_drawing.png")); let path = &reference_file("rect_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -395,11 +395,11 @@ fn blended_rect_drawing() {
screen.blended_rect(300, 20, 340, -20, 13, &blend_map); screen.blended_rect(300, 20, 340, -20, 13, &blend_map);
screen.blended_rect(20, 220, -20, 260, 14, &blend_map); screen.blended_rect(20, 220, -20, 260, 14, &blend_map);
let path = reference_file(Path::new("blended_rect_drawing.png")); let path = &reference_file("blended_rect_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -425,11 +425,11 @@ fn filled_rect_drawing() {
screen.filled_rect(300, 20, 340, -20, 13); screen.filled_rect(300, 20, 340, -20, 13);
screen.filled_rect(20, 220, -20, 260, 14); screen.filled_rect(20, 220, -20, 260, 14);
let path = reference_file(Path::new("filled_rect_drawing.png")); let path = &reference_file("filled_rect_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -455,11 +455,11 @@ fn blended_filled_rect_drawing() {
screen.blended_filled_rect(300, 20, 340, -20, 13, &blend_map); screen.blended_filled_rect(300, 20, 340, -20, 13, &blend_map);
screen.blended_filled_rect(20, 220, -20, 260, 14, &blend_map); screen.blended_filled_rect(20, 220, -20, 260, 14, &blend_map);
let path = reference_file(Path::new("blended_filled_rect_drawing.png")); let path = &reference_file("blended_filled_rect_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -480,11 +480,11 @@ fn circle_drawing() {
screen.circle(319, 1, 22, 9); screen.circle(319, 1, 22, 9);
screen.circle(2, 242, 19, 10); screen.circle(2, 242, 19, 10);
let path = reference_file(Path::new("circle_drawing.png")); let path = &reference_file("circle_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -505,11 +505,11 @@ fn filled_circle_drawing() {
screen.filled_circle(319, 1, 22, 9); screen.filled_circle(319, 1, 22, 9);
screen.filled_circle(2, 242, 19, 10); screen.filled_circle(2, 242, 19, 10);
let path = reference_file(Path::new("filled_circle_drawing.png")); let path = &reference_file("filled_circle_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -517,8 +517,8 @@ fn text_drawing() {
let (mut screen, palette) = setup(); let (mut screen, palette) = setup();
let font = BitmaskFont::new_vga_font().unwrap(); let font = BitmaskFont::new_vga_font().unwrap();
let small_font = BitmaskFont::load_from_file(test_assets_file(Path::new("small.fnt")).as_path()).unwrap(); let small_font = BitmaskFont::load_from_file(test_assets_file("small.fnt")).unwrap();
let chunky_font = BitmaskFont::load_from_file(test_assets_file(Path::new("chunky.fnt")).as_path()).unwrap(); let chunky_font = BitmaskFont::load_from_file(test_assets_file("chunky.fnt")).unwrap();
let message = "Hello, world! HELLO, WORLD!\nTesting 123"; let message = "Hello, world! HELLO, WORLD!\nTesting 123";
@ -558,11 +558,11 @@ fn text_drawing() {
screen.print_string(message, 360, 120, FontRenderOpts::Color(7), &font); screen.print_string(message, 360, 120, FontRenderOpts::Color(7), &font);
screen.print_string(message, 200, 250, FontRenderOpts::Color(8), &font); screen.print_string(message, 200, 250, FontRenderOpts::Color(8), &font);
let path = reference_file(Path::new("text_drawing.png")); let path = &reference_file("text_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
fn generate_bitmap(width: i32, height: i32) -> IndexedBitmap { fn generate_bitmap(width: i32, height: i32) -> IndexedBitmap {
@ -645,11 +645,11 @@ fn solid_blits() {
screen.blit(method.clone(), &bmp16, 196, 238); screen.blit(method.clone(), &bmp16, 196, 238);
screen.blit(method.clone(), &bmp16, 226, 240); screen.blit(method.clone(), &bmp16, 226, 240);
let path = reference_file(Path::new("solid_blits.png")); let path = &reference_file("solid_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -716,11 +716,11 @@ fn blended_solid_blits() {
screen.blit(method.clone(), &bmp16, 196, 238); screen.blit(method.clone(), &bmp16, 196, 238);
screen.blit(method.clone(), &bmp16, 226, 240); screen.blit(method.clone(), &bmp16, 226, 240);
let path = reference_file(Path::new("blended_solid_blits.png")); let path = &reference_file("blended_solid_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -782,11 +782,11 @@ fn solid_flipped_blits() {
screen.blit(SolidFlipped { horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238); screen.blit(SolidFlipped { horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238);
screen.blit(SolidFlipped { horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240); screen.blit(SolidFlipped { horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240);
let path = reference_file(Path::new("solid_flipped_blits.png")); let path = &reference_file("solid_flipped_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -849,11 +849,11 @@ fn blended_solid_flipped_blits() {
screen.blit(SolidFlippedBlended { horizontal_flip: true, vertical_flip: false, blend_map: blend_map.clone() }, &bmp, 196, 238); screen.blit(SolidFlippedBlended { horizontal_flip: true, vertical_flip: false, blend_map: blend_map.clone() }, &bmp, 196, 238);
screen.blit(SolidFlippedBlended { horizontal_flip: false, vertical_flip: true, blend_map: blend_map.clone() }, &bmp, 226, 240); screen.blit(SolidFlippedBlended { horizontal_flip: false, vertical_flip: true, blend_map: blend_map.clone() }, &bmp, 226, 240);
let path = reference_file(Path::new("blended_solid_flipped_blits.png")); let path = &reference_file("blended_solid_flipped_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -919,11 +919,11 @@ fn solid_offset_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("solid_offset_blits.png")); let path = &reference_file("solid_offset_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -990,11 +990,11 @@ fn solid_flipped_offset_blits() {
screen.blit(SolidFlippedOffset { offset, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238); screen.blit(SolidFlippedOffset { offset, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238);
screen.blit(SolidFlippedOffset { offset, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240); screen.blit(SolidFlippedOffset { offset, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240);
let path = reference_file(Path::new("solid_flipped_offset_blits.png")); let path = &reference_file("solid_flipped_offset_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -1061,11 +1061,11 @@ fn transparent_blits() {
screen.blit(method.clone(), &bmp16, 196, 238); screen.blit(method.clone(), &bmp16, 196, 238);
screen.blit(method.clone(), &bmp16, 226, 240); screen.blit(method.clone(), &bmp16, 226, 240);
let path = reference_file(Path::new("transparent_blits.png")); let path = &reference_file("transparent_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -1132,11 +1132,11 @@ fn blended_transparent_blits() {
screen.blit(method.clone(), &bmp16, 196, 238); screen.blit(method.clone(), &bmp16, 196, 238);
screen.blit(method.clone(), &bmp16, 226, 240); screen.blit(method.clone(), &bmp16, 226, 240);
let path = reference_file(Path::new("blended_transparent_blits.png")); let path = &reference_file("blended_transparent_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1201,11 +1201,11 @@ fn transparent_flipped_blits() {
screen.blit(TransparentFlipped { transparent_color, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238); screen.blit(TransparentFlipped { transparent_color, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238);
screen.blit(TransparentFlipped { transparent_color, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240); screen.blit(TransparentFlipped { transparent_color, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240);
let path = reference_file(Path::new("transparent_flipped_blits.png")); let path = &reference_file("transparent_flipped_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1270,11 +1270,11 @@ fn blended_transparent_flipped_blits() {
screen.blit(TransparentFlippedBlended { transparent_color, horizontal_flip: true, vertical_flip: false, blend_map: blend_map.clone() }, &bmp, 196, 238); screen.blit(TransparentFlippedBlended { transparent_color, horizontal_flip: true, vertical_flip: false, blend_map: blend_map.clone() }, &bmp, 196, 238);
screen.blit(TransparentFlippedBlended { transparent_color, horizontal_flip: false, vertical_flip: true, blend_map: blend_map.clone() }, &bmp, 226, 240); screen.blit(TransparentFlippedBlended { transparent_color, horizontal_flip: false, vertical_flip: true, blend_map: blend_map.clone() }, &bmp, 226, 240);
let path = reference_file(Path::new("blended_transparent_flipped_blits.png")); let path = &reference_file("blended_transparent_flipped_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -1342,11 +1342,11 @@ fn transparent_offset_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("transparent_offset_blits.png")); let path = &reference_file("transparent_offset_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1415,11 +1415,11 @@ fn transparent_flipped_offset_blits() {
screen.blit(TransparentFlippedOffset { transparent_color, offset, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238); screen.blit(TransparentFlippedOffset { transparent_color, offset, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238);
screen.blit(TransparentFlippedOffset { transparent_color, offset, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240); screen.blit(TransparentFlippedOffset { transparent_color, offset, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240);
let path = reference_file(Path::new("transparent_flipped_offset_blits.png")); let path = &reference_file("transparent_flipped_offset_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -1487,11 +1487,11 @@ fn transparent_single_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("transparent_single_blits.png")); let path = &reference_file("transparent_single_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1560,11 +1560,11 @@ fn transparent_flipped_single_blits() {
screen.blit(TransparentFlippedSingle { transparent_color, draw_color, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238); screen.blit(TransparentFlippedSingle { transparent_color, draw_color, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238);
screen.blit(TransparentFlippedSingle { transparent_color, draw_color, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240); screen.blit(TransparentFlippedSingle { transparent_color, draw_color, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240);
let path = reference_file(Path::new("transparent_flipped_single_blits.png")); let path = &reference_file("transparent_flipped_single_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -1628,11 +1628,11 @@ fn rotozoom_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("rotozoom_blits.png")); let path = &reference_file("rotozoom_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1697,11 +1697,11 @@ fn blended_rotozoom_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("blended_rotozoom_blits.png")); let path = &reference_file("blended_rotozoom_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1768,11 +1768,11 @@ fn rotozoom_offset_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("rotozoom_offset_blits.png")); let path = &reference_file("rotozoom_offset_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1839,11 +1839,11 @@ fn rotozoom_transparent_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("rotozoom_transparent_blits.png")); let path = &reference_file("rotozoom_transparent_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1916,11 +1916,11 @@ fn blended_rotozoom_transparent_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("blended_rotozoom_transparent_blits.png")); let path = &reference_file("blended_rotozoom_transparent_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1989,11 +1989,11 @@ fn rotozoom_transparent_offset_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("rotozoom_transparent_offset_blits.png")); let path = &reference_file("rotozoom_transparent_offset_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2203,11 +2203,11 @@ fn triangle_2d() {
color, color,
}); });
let path = reference_file(Path::new("triangle_2d.png")); let path = &reference_file("triangle_2d.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -2378,11 +2378,11 @@ fn triangle_2d_solid_textured() {
draw_triangles(&mut screen, TriangleType::SolidTextured, Some(&texture), None); draw_triangles(&mut screen, TriangleType::SolidTextured, Some(&texture), None);
let path = reference_file(Path::new("triangle_2d_solid_textured.png")); let path = &reference_file("triangle_2d_solid_textured.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2391,11 +2391,11 @@ fn triangle_2d_solid_blended() {
draw_triangles(&mut screen, TriangleType::SolidBlended, None, Some(&blend_map)); draw_triangles(&mut screen, TriangleType::SolidBlended, None, Some(&blend_map));
let path = reference_file(Path::new("triangle_2d_solid_blended.png")); let path = &reference_file("triangle_2d_solid_blended.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2406,9 +2406,9 @@ fn triangle_2d_solid_textured_blended() {
draw_triangles(&mut screen, TriangleType::SolidTexturedBlended, Some(&texture), Some(&blend_map)); draw_triangles(&mut screen, TriangleType::SolidTexturedBlended, Some(&texture), Some(&blend_map));
let path = reference_file(Path::new("triangle_2d_solid_textured_blended.png")); let path = &reference_file("triangle_2d_solid_textured_blended.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), &palette).unwrap(); screen.to_png_file(path, &palette).unwrap();
} }
assert!(verify_visual(&screen, &palette, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, &palette, path), "bitmap differs from source image: {:?}", path);
} }

View file

@ -29,7 +29,7 @@ const SCREEN_HEIGHT: u32 = 240;
const BASE_PATH: &str = "./tests/ref/rgba/"; const BASE_PATH: &str = "./tests/ref/rgba/";
fn reference_file(file: &Path) -> PathBuf { fn reference_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(BASE_PATH).join(file) PathBuf::from(BASE_PATH).join(file)
} }
@ -38,7 +38,7 @@ fn setup() -> RgbaBitmap {
} }
fn setup_for_blending() -> RgbaBitmap { fn setup_for_blending() -> RgbaBitmap {
let (texture, _) = RgbaBitmap::load_file(test_assets_file(Path::new("texture.lbm")).as_path()).unwrap(); let (texture, _) = RgbaBitmap::load_file(test_assets_file("texture.lbm")).unwrap();
let mut screen = RgbaBitmap::new(SCREEN_WIDTH, SCREEN_HEIGHT).unwrap(); let mut screen = RgbaBitmap::new(SCREEN_WIDTH, SCREEN_HEIGHT).unwrap();
for y in 0..(SCREEN_HEIGHT as f32 / texture.height() as f32).ceil() as i32 { for y in 0..(SCREEN_HEIGHT as f32 / texture.height() as f32).ceil() as i32 {
for x in 0..(SCREEN_WIDTH as f32 / texture.width() as f32).ceil() as i32 { for x in 0..(SCREEN_WIDTH as f32 / texture.width() as f32).ceil() as i32 {
@ -49,7 +49,7 @@ fn setup_for_blending() -> RgbaBitmap {
} }
fn setup_for_blending_half_solid_half_semi_transparent() -> RgbaBitmap { fn setup_for_blending_half_solid_half_semi_transparent() -> RgbaBitmap {
let (texture, _) = RgbaBitmap::load_file(test_assets_file(Path::new("texture.lbm")).as_path()).unwrap(); let (texture, _) = RgbaBitmap::load_file(test_assets_file("texture.lbm")).unwrap();
let mut screen = RgbaBitmap::new(SCREEN_WIDTH, SCREEN_HEIGHT).unwrap(); let mut screen = RgbaBitmap::new(SCREEN_WIDTH, SCREEN_HEIGHT).unwrap();
for y in 0..(screen.height() as f32 / texture.height() as f32).ceil() as i32 { for y in 0..(screen.height() as f32 / texture.height() as f32).ceil() as i32 {
for x in 0..(screen.width() as f32 / texture.width() as f32).ceil() as i32 { for x in 0..(screen.width() as f32 / texture.width() as f32).ceil() as i32 {
@ -69,7 +69,7 @@ fn setup_for_blending_half_solid_half_semi_transparent() -> RgbaBitmap {
screen screen
} }
fn verify_visual(screen: &RgbaBitmap, source: &Path) -> bool { fn verify_visual(screen: &RgbaBitmap, source: impl AsRef<Path>) -> bool {
let (source_bmp, _) = RgbaBitmap::load_file(source).unwrap(); let (source_bmp, _) = RgbaBitmap::load_file(source).unwrap();
*screen == source_bmp *screen == source_bmp
} }
@ -115,11 +115,11 @@ fn pixel_addressing() {
} }
} }
let path = reference_file(Path::new("pixel_addressing.png")); let path = &reference_file("pixel_addressing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -169,11 +169,11 @@ fn pixel_drawing() {
screen.set_pixel(160, i + 234, COLOR_BRIGHT_WHITE); screen.set_pixel(160, i + 234, COLOR_BRIGHT_WHITE);
} }
let path = reference_file(Path::new("pixel_drawing.png")); let path = &reference_file("pixel_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -207,11 +207,11 @@ fn blended_pixel_drawing() {
screen.set_blended_pixel(160, i + 234, COLOR_BRIGHT_WHITE_HALF_ALPHA, blend); screen.set_blended_pixel(160, i + 234, COLOR_BRIGHT_WHITE_HALF_ALPHA, blend);
} }
let path = reference_file(Path::new("blended_pixel_drawing.png")); let path = &reference_file("blended_pixel_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -229,11 +229,11 @@ fn horiz_line_drawing() {
screen.horiz_line(100, 200, -10, COLOR_BROWN); screen.horiz_line(100, 200, -10, COLOR_BROWN);
screen.horiz_line(20, 80, 250, COLOR_DARK_GRAY); screen.horiz_line(20, 80, 250, COLOR_DARK_GRAY);
let path = reference_file(Path::new("horiz_line_drawing.png")); let path = &reference_file("horiz_line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -253,11 +253,11 @@ fn blended_horiz_line_drawing() {
screen.blended_horiz_line(100, 200, -10, COLOR_BROWN_HALF_ALPHA, blend); screen.blended_horiz_line(100, 200, -10, COLOR_BROWN_HALF_ALPHA, blend);
screen.blended_horiz_line(20, 80, 250, COLOR_LIGHT_GRAY_HALF_ALPHA, blend); screen.blended_horiz_line(20, 80, 250, COLOR_LIGHT_GRAY_HALF_ALPHA, blend);
let path = reference_file(Path::new("blended_horiz_line_drawing.png")); let path = &reference_file("blended_horiz_line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -275,11 +275,11 @@ fn vert_line_drawing() {
screen.vert_line(-17, 10, 20, COLOR_BROWN); screen.vert_line(-17, 10, 20, COLOR_BROWN);
screen.vert_line(400, 100, 300, COLOR_LIGHT_GRAY); screen.vert_line(400, 100, 300, COLOR_LIGHT_GRAY);
let path = reference_file(Path::new("vert_line_drawing.png")); let path = &reference_file("vert_line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -299,11 +299,11 @@ fn blended_vert_line_drawing() {
screen.blended_vert_line(-17, 10, 20, COLOR_BROWN_HALF_ALPHA, blend); screen.blended_vert_line(-17, 10, 20, COLOR_BROWN_HALF_ALPHA, blend);
screen.blended_vert_line(400, 100, 300, COLOR_LIGHT_GRAY_HALF_ALPHA, blend); screen.blended_vert_line(400, 100, 300, COLOR_LIGHT_GRAY_HALF_ALPHA, blend);
let path = reference_file(Path::new("blended_vert_line_drawing.png")); let path = &reference_file("blended_vert_line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -338,11 +338,11 @@ fn line_drawing() {
screen.line(-100, 120, -100, 239, COLOR_CYAN); screen.line(-100, 120, -100, 239, COLOR_CYAN);
screen.line(320, 99, 320, 199, COLOR_MAGENTA); screen.line(320, 99, 320, 199, COLOR_MAGENTA);
let path = reference_file(Path::new("line_drawing.png")); let path = &reference_file("line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -379,11 +379,11 @@ fn blended_line_drawing() {
screen.blended_line(-100, 120, -100, 239, COLOR_CYAN_HALF_ALPHA, blend); screen.blended_line(-100, 120, -100, 239, COLOR_CYAN_HALF_ALPHA, blend);
screen.blended_line(320, 99, 320, 199, COLOR_MAGENTA_HALF_ALPHA, blend); screen.blended_line(320, 99, 320, 199, COLOR_MAGENTA_HALF_ALPHA, blend);
let path = reference_file(Path::new("blended_line_drawing.png")); let path = &reference_file("blended_line_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -409,11 +409,11 @@ fn rect_drawing() {
screen.rect(300, 20, 340, -20, COLOR_BRIGHT_MAGENTA); screen.rect(300, 20, 340, -20, COLOR_BRIGHT_MAGENTA);
screen.rect(20, 220, -20, 260, COLOR_BRIGHT_YELLOW); screen.rect(20, 220, -20, 260, COLOR_BRIGHT_YELLOW);
let path = reference_file(Path::new("rect_drawing.png")); let path = &reference_file("rect_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -441,11 +441,11 @@ fn blended_rect_drawing() {
screen.blended_rect(300, 20, 340, -20, COLOR_BRIGHT_MAGENTA_HALF_ALPHA, blend); screen.blended_rect(300, 20, 340, -20, COLOR_BRIGHT_MAGENTA_HALF_ALPHA, blend);
screen.blended_rect(20, 220, -20, 260, COLOR_BRIGHT_YELLOW_HALF_ALPHA, blend); screen.blended_rect(20, 220, -20, 260, COLOR_BRIGHT_YELLOW_HALF_ALPHA, blend);
let path = reference_file(Path::new("blended_rect_drawing.png")); let path = &reference_file("blended_rect_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -471,11 +471,11 @@ fn filled_rect_drawing() {
screen.filled_rect(300, 20, 340, -20, COLOR_BRIGHT_MAGENTA); screen.filled_rect(300, 20, 340, -20, COLOR_BRIGHT_MAGENTA);
screen.filled_rect(20, 220, -20, 260, COLOR_BRIGHT_YELLOW); screen.filled_rect(20, 220, -20, 260, COLOR_BRIGHT_YELLOW);
let path = reference_file(Path::new("filled_rect_drawing.png")); let path = &reference_file("filled_rect_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -503,11 +503,11 @@ fn blended_filled_rect_drawing() {
screen.blended_filled_rect(300, 20, 340, -20, COLOR_BRIGHT_MAGENTA_HALF_ALPHA, blend); screen.blended_filled_rect(300, 20, 340, -20, COLOR_BRIGHT_MAGENTA_HALF_ALPHA, blend);
screen.blended_filled_rect(20, 220, -20, 260, COLOR_BRIGHT_YELLOW_HALF_ALPHA, blend); screen.blended_filled_rect(20, 220, -20, 260, COLOR_BRIGHT_YELLOW_HALF_ALPHA, blend);
let path = reference_file(Path::new("blended_filled_rect_drawing.png")); let path = &reference_file("blended_filled_rect_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -528,11 +528,11 @@ fn circle_drawing() {
screen.circle(319, 1, 22, COLOR_BRIGHT_BLUE); screen.circle(319, 1, 22, COLOR_BRIGHT_BLUE);
screen.circle(2, 242, 19, COLOR_BRIGHT_GREEN); screen.circle(2, 242, 19, COLOR_BRIGHT_GREEN);
let path = reference_file(Path::new("circle_drawing.png")); let path = &reference_file("circle_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -553,11 +553,11 @@ fn filled_circle_drawing() {
screen.filled_circle(319, 1, 22, COLOR_BRIGHT_BLUE); screen.filled_circle(319, 1, 22, COLOR_BRIGHT_BLUE);
screen.filled_circle(2, 242, 19, COLOR_BRIGHT_GREEN); screen.filled_circle(2, 242, 19, COLOR_BRIGHT_GREEN);
let path = reference_file(Path::new("filled_circle_drawing.png")); let path = &reference_file("filled_circle_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -565,8 +565,8 @@ fn text_drawing() {
let mut screen = setup(); let mut screen = setup();
let font = BitmaskFont::new_vga_font().unwrap(); let font = BitmaskFont::new_vga_font().unwrap();
let small_font = BitmaskFont::load_from_file(test_assets_file(Path::new("small.fnt")).as_path()).unwrap(); let small_font = BitmaskFont::load_from_file(test_assets_file("small.fnt")).unwrap();
let chunky_font = BitmaskFont::load_from_file(test_assets_file(Path::new("chunky.fnt")).as_path()).unwrap(); let chunky_font = BitmaskFont::load_from_file(test_assets_file("chunky.fnt")).unwrap();
let message = "Hello, world! HELLO, WORLD!\nTesting 123"; let message = "Hello, world! HELLO, WORLD!\nTesting 123";
@ -606,11 +606,11 @@ fn text_drawing() {
screen.print_string(message, 360, 120, FontRenderOpts::Color(COLOR_LIGHT_GRAY), &font); screen.print_string(message, 360, 120, FontRenderOpts::Color(COLOR_LIGHT_GRAY), &font);
screen.print_string(message, 200, 250, FontRenderOpts::Color(COLOR_DARK_GRAY), &font); screen.print_string(message, 200, 250, FontRenderOpts::Color(COLOR_DARK_GRAY), &font);
let path = reference_file(Path::new("text_drawing.png")); let path = &reference_file("text_drawing.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
fn generate_bitmap(width: i32, height: i32) -> RgbaBitmap { fn generate_bitmap(width: i32, height: i32) -> RgbaBitmap {
@ -737,11 +737,11 @@ fn solid_blits() {
screen.blit(method.clone(), &bmp16, 196, 238); screen.blit(method.clone(), &bmp16, 196, 238);
screen.blit(method.clone(), &bmp16, 226, 240); screen.blit(method.clone(), &bmp16, 226, 240);
let path = reference_file(Path::new("solid_blits.png")); let path = &reference_file("solid_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -808,11 +808,11 @@ fn solid_tinted_blits() {
screen.blit(method.clone(), &bmp16, 196, 238); screen.blit(method.clone(), &bmp16, 196, 238);
screen.blit(method.clone(), &bmp16, 226, 240); screen.blit(method.clone(), &bmp16, 226, 240);
let path = reference_file(Path::new("solid_tinted_blits.png")); let path = &reference_file("solid_tinted_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -878,11 +878,11 @@ fn blended_solid_blits() {
screen.blit(method.clone(), &bmp16, 196, 238); screen.blit(method.clone(), &bmp16, 196, 238);
screen.blit(method.clone(), &bmp16, 226, 240); screen.blit(method.clone(), &bmp16, 226, 240);
let path = reference_file(Path::new("blended_solid_blits.png")); let path = &reference_file("blended_solid_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -944,11 +944,11 @@ fn solid_flipped_blits() {
screen.blit(SolidFlipped { horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238); screen.blit(SolidFlipped { horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238);
screen.blit(SolidFlipped { horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240); screen.blit(SolidFlipped { horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240);
let path = reference_file(Path::new("solid_flipped_blits.png")); let path = &reference_file("solid_flipped_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1013,11 +1013,11 @@ fn solid_flipped_tinted_blits() {
screen.blit(SolidFlippedTinted { tint_color, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238); screen.blit(SolidFlippedTinted { tint_color, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238);
screen.blit(SolidFlippedTinted { tint_color, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240); screen.blit(SolidFlippedTinted { tint_color, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240);
let path = reference_file(Path::new("solid_flipped_tinted_blits.png")); let path = &reference_file("solid_flipped_tinted_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1081,11 +1081,11 @@ fn blended_solid_flipped_blits() {
screen.blit(SolidFlippedBlended { horizontal_flip: true, vertical_flip: false, blend }, &bmp, 196, 238); screen.blit(SolidFlippedBlended { horizontal_flip: true, vertical_flip: false, blend }, &bmp, 196, 238);
screen.blit(SolidFlippedBlended { horizontal_flip: false, vertical_flip: true, blend }, &bmp, 226, 240); screen.blit(SolidFlippedBlended { horizontal_flip: false, vertical_flip: true, blend }, &bmp, 226, 240);
let path = reference_file(Path::new("blended_solid_flipped_blits.png")); let path = &reference_file("blended_solid_flipped_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -1152,11 +1152,11 @@ fn transparent_blits() {
screen.blit(method.clone(), &bmp16, 196, 238); screen.blit(method.clone(), &bmp16, 196, 238);
screen.blit(method.clone(), &bmp16, 226, 240); screen.blit(method.clone(), &bmp16, 226, 240);
let path = reference_file(Path::new("transparent_blits.png")); let path = &reference_file("transparent_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -1226,11 +1226,11 @@ fn transparent_tinted_blits() {
screen.blit(method.clone(), &bmp16, 196, 238); screen.blit(method.clone(), &bmp16, 196, 238);
screen.blit(method.clone(), &bmp16, 226, 240); screen.blit(method.clone(), &bmp16, 226, 240);
let path = reference_file(Path::new("transparent_tinted_blits.png")); let path = &reference_file("transparent_tinted_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -1296,11 +1296,11 @@ fn blended_transparent_blits() {
screen.blit(method.clone(), &bmp16, 196, 238); screen.blit(method.clone(), &bmp16, 196, 238);
screen.blit(method.clone(), &bmp16, 226, 240); screen.blit(method.clone(), &bmp16, 226, 240);
let path = reference_file(Path::new("blended_transparent_blits.png")); let path = &reference_file("blended_transparent_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1365,11 +1365,11 @@ fn transparent_flipped_blits() {
screen.blit(TransparentFlipped { transparent_color, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238); screen.blit(TransparentFlipped { transparent_color, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238);
screen.blit(TransparentFlipped { transparent_color, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240); screen.blit(TransparentFlipped { transparent_color, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240);
let path = reference_file(Path::new("transparent_flipped_blits.png")); let path = &reference_file("transparent_flipped_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1435,11 +1435,11 @@ fn transparent_flipped_tinted_blits() {
screen.blit(TransparentFlippedTinted { transparent_color, tint_color, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238); screen.blit(TransparentFlippedTinted { transparent_color, tint_color, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238);
screen.blit(TransparentFlippedTinted { transparent_color, tint_color, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240); screen.blit(TransparentFlippedTinted { transparent_color, tint_color, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240);
let path = reference_file(Path::new("transparent_flipped_tinted_blits.png")); let path = &reference_file("transparent_flipped_tinted_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1504,11 +1504,11 @@ fn blended_transparent_flipped_blits() {
screen.blit(TransparentFlippedBlended { transparent_color, horizontal_flip: true, vertical_flip: false, blend }, &bmp, 196, 238); screen.blit(TransparentFlippedBlended { transparent_color, horizontal_flip: true, vertical_flip: false, blend }, &bmp, 196, 238);
screen.blit(TransparentFlippedBlended { transparent_color, horizontal_flip: false, vertical_flip: true, blend }, &bmp, 226, 240); screen.blit(TransparentFlippedBlended { transparent_color, horizontal_flip: false, vertical_flip: true, blend }, &bmp, 226, 240);
let path = reference_file(Path::new("blended_transparent_flipped_blits.png")); let path = &reference_file("blended_transparent_flipped_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1577,11 +1577,11 @@ fn transparent_single_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("transparent_single_blits.png")); let path = &reference_file("transparent_single_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1646,11 +1646,11 @@ fn transparent_flipped_single_blits() {
screen.blit(TransparentFlippedSingle { transparent_color, draw_color: COLOR_BRIGHT_GREEN, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238); screen.blit(TransparentFlippedSingle { transparent_color, draw_color: COLOR_BRIGHT_GREEN, horizontal_flip: true, vertical_flip: false }, &bmp, 196, 238);
screen.blit(TransparentFlippedSingle { transparent_color, draw_color: COLOR_BRIGHT_GREEN, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240); screen.blit(TransparentFlippedSingle { transparent_color, draw_color: COLOR_BRIGHT_GREEN, horizontal_flip: false, vertical_flip: true }, &bmp, 226, 240);
let path = reference_file(Path::new("transparent_flipped_single_blits.png")); let path = &reference_file("transparent_flipped_single_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -1714,11 +1714,11 @@ fn rotozoom_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("rotozoom_blits.png")); let path = &reference_file("rotozoom_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1785,11 +1785,11 @@ fn rotozoom_tinted_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("rotozoom_tinted_blits.png")); let path = &reference_file("rotozoom_tinted_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -1854,11 +1854,11 @@ fn blended_rotozoom_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("blended_rotozoom_blits.png")); let path = &reference_file("blended_rotozoom_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1925,11 +1925,11 @@ fn rotozoom_transparent_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("rotozoom_transparent_blits.png")); let path = &reference_file("rotozoom_transparent_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -1997,11 +1997,11 @@ fn rotozoom_transparent_tinted_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("rotozoom_transparent_tinted_blits.png")); let path = &reference_file("rotozoom_transparent_tinted_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[rustfmt::skip] #[rustfmt::skip]
@ -2068,11 +2068,11 @@ fn blended_rotozoom_transparent_blits() {
screen.blit(method.clone(), &bmp, 196, 238); screen.blit(method.clone(), &bmp, 196, 238);
screen.blit(method.clone(), &bmp, 226, 240); screen.blit(method.clone(), &bmp, 226, 240);
let path = reference_file(Path::new("blended_rotozoom_transparent_blits.png")); let path = &reference_file("blended_rotozoom_transparent_blits.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2095,11 +2095,11 @@ fn blend_function_blend() {
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 130); screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 130);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 130); screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 130);
let path = reference_file(Path::new("blend_function_blend.png")); let path = &reference_file("blend_function_blend.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2142,11 +2142,11 @@ fn blend_function_tinted_blend() {
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 195); screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 195);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 195); screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 195);
let path = reference_file(Path::new("blend_function_tinted_blend.png")); let path = &reference_file("blend_function_tinted_blend.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2189,11 +2189,11 @@ fn blend_function_blend_source_with_alpha() {
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 195); screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 195);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 195); screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 195);
let path = reference_file(Path::new("blend_function_blend_source_with_alpha.png")); let path = &reference_file("blend_function_blend_source_with_alpha.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2236,11 +2236,11 @@ fn blend_function_multiplied_blend() {
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 195); screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 195);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 195); screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 195);
let path = reference_file(Path::new("blend_function_multiplied_blend.png")); let path = &reference_file("blend_function_multiplied_blend.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2450,11 +2450,11 @@ fn triangle_2d() {
color, color,
}); });
let path = reference_file(Path::new("triangle_2d.png")); let path = &reference_file("triangle_2d.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -2517,21 +2517,21 @@ fn get_quad(
}, },
], ],
TriangleType::SolidTextured => [ TriangleType::SolidTextured => [
RgbaTriangle2d::SolidTextured { position: positions_1, texcoord: texcoords_1, bitmap: &texture.unwrap() }, RgbaTriangle2d::SolidTextured { position: positions_1, texcoord: texcoords_1, bitmap: texture.unwrap() },
RgbaTriangle2d::SolidTextured { position: positions_2, texcoord: texcoords_2, bitmap: &texture.unwrap() }, RgbaTriangle2d::SolidTextured { position: positions_2, texcoord: texcoords_2, bitmap: texture.unwrap() },
], ],
TriangleType::SolidTexturedColored => [ TriangleType::SolidTexturedColored => [
RgbaTriangle2d::SolidTexturedColored { RgbaTriangle2d::SolidTexturedColored {
position: positions_1, position: positions_1,
texcoord: texcoords_1, texcoord: texcoords_1,
color: single_color, color: single_color,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
}, },
RgbaTriangle2d::SolidTexturedColored { RgbaTriangle2d::SolidTexturedColored {
position: positions_2, position: positions_2,
texcoord: texcoords_2, texcoord: texcoords_2,
color: single_color, color: single_color,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
}, },
], ],
TriangleType::SolidTexturedColoredBlended => [ TriangleType::SolidTexturedColoredBlended => [
@ -2539,14 +2539,14 @@ fn get_quad(
position: positions_1, position: positions_1,
texcoord: texcoords_1, texcoord: texcoords_1,
color: single_color, color: single_color,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(128), blend: BlendFunction::BlendSourceWithAlpha(128),
}, },
RgbaTriangle2d::SolidTexturedColoredBlended { RgbaTriangle2d::SolidTexturedColoredBlended {
position: positions_2, position: positions_2,
texcoord: texcoords_2, texcoord: texcoords_2,
color: single_color, color: single_color,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(128), blend: BlendFunction::BlendSourceWithAlpha(128),
}, },
], ],
@ -2555,13 +2555,13 @@ fn get_quad(
position: positions_1, position: positions_1,
texcoord: texcoords_1, texcoord: texcoords_1,
color: colors_1, color: colors_1,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
}, },
RgbaTriangle2d::SolidTexturedMultiColored { RgbaTriangle2d::SolidTexturedMultiColored {
position: positions_2, position: positions_2,
texcoord: texcoords_2, texcoord: texcoords_2,
color: colors_2, color: colors_2,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
}, },
], ],
TriangleType::SolidTexturedMultiColoredBlended => [ TriangleType::SolidTexturedMultiColoredBlended => [
@ -2569,14 +2569,14 @@ fn get_quad(
position: positions_1, position: positions_1,
texcoord: texcoords_1, texcoord: texcoords_1,
color: colors_1, color: colors_1,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(192), blend: BlendFunction::BlendSourceWithAlpha(192),
}, },
RgbaTriangle2d::SolidTexturedMultiColoredBlended { RgbaTriangle2d::SolidTexturedMultiColoredBlended {
position: positions_2, position: positions_2,
texcoord: texcoords_2, texcoord: texcoords_2,
color: colors_2, color: colors_2,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(192), blend: BlendFunction::BlendSourceWithAlpha(192),
}, },
], ],
@ -2584,13 +2584,13 @@ fn get_quad(
RgbaTriangle2d::SolidTexturedTinted { RgbaTriangle2d::SolidTexturedTinted {
position: positions_1, position: positions_1,
texcoord: texcoords_1, texcoord: texcoords_1,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
tint: tint_color, tint: tint_color,
}, },
RgbaTriangle2d::SolidTexturedTinted { RgbaTriangle2d::SolidTexturedTinted {
position: positions_2, position: positions_2,
texcoord: texcoords_2, texcoord: texcoords_2,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
tint: tint_color, tint: tint_color,
}, },
], ],
@ -2598,13 +2598,13 @@ fn get_quad(
RgbaTriangle2d::SolidTexturedBlended { RgbaTriangle2d::SolidTexturedBlended {
position: positions_1, position: positions_1,
texcoord: texcoords_1, texcoord: texcoords_1,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(128), blend: BlendFunction::BlendSourceWithAlpha(128),
}, },
RgbaTriangle2d::SolidTexturedBlended { RgbaTriangle2d::SolidTexturedBlended {
position: positions_2, position: positions_2,
texcoord: texcoords_2, texcoord: texcoords_2,
bitmap: &texture.unwrap(), bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(128), blend: BlendFunction::BlendSourceWithAlpha(128),
}, },
], ],
@ -2716,11 +2716,11 @@ fn triangle_2d_solid_blended() {
draw_triangles(&mut screen, TriangleType::SolidBlended, None); draw_triangles(&mut screen, TriangleType::SolidBlended, None);
let path = reference_file(Path::new("triangle_2d_solid_blended.png")); let path = &reference_file("triangle_2d_solid_blended.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2729,11 +2729,11 @@ fn triangle_2d_solid_multicolor_blended() {
draw_triangles(&mut screen, TriangleType::SolidMultiColorBlended, None); draw_triangles(&mut screen, TriangleType::SolidMultiColorBlended, None);
let path = reference_file(Path::new("triangle_2d_solid_multicolor_blended.png")); let path = &reference_file("triangle_2d_solid_multicolor_blended.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2745,11 +2745,11 @@ fn triangle_2d_solid_textured() {
draw_triangles(&mut screen, TriangleType::SolidTextured, Some(&texture)); draw_triangles(&mut screen, TriangleType::SolidTextured, Some(&texture));
let path = reference_file(Path::new("triangle_2d_solid_textured.png")); let path = &reference_file("triangle_2d_solid_textured.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2761,11 +2761,11 @@ fn triangle_2d_solid_textured_colored() {
draw_triangles(&mut screen, TriangleType::SolidTexturedColored, Some(&texture)); draw_triangles(&mut screen, TriangleType::SolidTexturedColored, Some(&texture));
let path = reference_file(Path::new("triangle_2d_solid_textured_colored.png")); let path = &reference_file("triangle_2d_solid_textured_colored.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2776,11 +2776,11 @@ fn triangle_2d_solid_textured_colored_blended() {
draw_triangles(&mut screen, TriangleType::SolidTexturedColoredBlended, Some(&texture)); draw_triangles(&mut screen, TriangleType::SolidTexturedColoredBlended, Some(&texture));
let path = reference_file(Path::new("triangle_2d_solid_textured_colored_blended.png")); let path = &reference_file("triangle_2d_solid_textured_colored_blended.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2792,11 +2792,11 @@ fn triangle_2d_solid_textured_multicolored() {
draw_triangles(&mut screen, TriangleType::SolidTexturedMultiColored, Some(&texture)); draw_triangles(&mut screen, TriangleType::SolidTexturedMultiColored, Some(&texture));
let path = reference_file(Path::new("triangle_2d_solid_textured_multicolored.png")); let path = &reference_file("triangle_2d_solid_textured_multicolored.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2807,11 +2807,11 @@ fn triangle_2d_solid_textured_multicolored_blended() {
draw_triangles(&mut screen, TriangleType::SolidTexturedMultiColoredBlended, Some(&texture)); draw_triangles(&mut screen, TriangleType::SolidTexturedMultiColoredBlended, Some(&texture));
let path = reference_file(Path::new("triangle_2d_solid_textured_multicolored_blended.png")); let path = &reference_file("triangle_2d_solid_textured_multicolored_blended.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2823,11 +2823,11 @@ fn triangle_2d_solid_textured_tinted() {
draw_triangles(&mut screen, TriangleType::SolidTexturedTinted, Some(&texture)); draw_triangles(&mut screen, TriangleType::SolidTexturedTinted, Some(&texture));
let path = reference_file(Path::new("triangle_2d_solid_textured_tinted.png")); let path = &reference_file("triangle_2d_solid_textured_tinted.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }
#[test] #[test]
@ -2838,9 +2838,9 @@ fn triangle_2d_solid_textured_blended() {
draw_triangles(&mut screen, TriangleType::SolidTexturedBlended, Some(&texture)); draw_triangles(&mut screen, TriangleType::SolidTexturedBlended, Some(&texture));
let path = reference_file(Path::new("triangle_2d_solid_textured_blended.png")); let path = &reference_file("triangle_2d_solid_textured_blended.png");
if cfg!(recreate_ref_test_images) { if cfg!(recreate_ref_test_images) {
screen.to_png_file(path.as_path(), PngFormat::RGBA).unwrap(); screen.to_png_file(path, PngFormat::RGBA).unwrap();
} }
assert!(verify_visual(&screen, &path), "bitmap differs from source image: {:?}", path); assert!(verify_visual(&screen, path), "bitmap differs from source image: {:?}", path);
} }

View file

@ -8,15 +8,15 @@ use byteorder::{LittleEndian, ReadBytesExt};
const ASSETS_PATH: &str = "./assets/"; const ASSETS_PATH: &str = "./assets/";
const TEST_ASSETS_PATH: &str = "./test-assets/"; const TEST_ASSETS_PATH: &str = "./test-assets/";
pub fn assets_file(file: &Path) -> PathBuf { pub fn assets_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(ASSETS_PATH).join(file) PathBuf::from(ASSETS_PATH).join(file)
} }
pub fn test_assets_file(file: &Path) -> PathBuf { pub fn test_assets_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(TEST_ASSETS_PATH).join(file) PathBuf::from(TEST_ASSETS_PATH).join(file)
} }
pub fn load_raw_indexed(bin_file: &Path) -> Result<Box<[u8]>, io::Error> { pub fn load_raw_indexed(bin_file: impl AsRef<Path>) -> Result<Box<[u8]>, io::Error> {
let f = File::open(bin_file)?; let f = File::open(bin_file)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
let mut buffer = Vec::new(); let mut buffer = Vec::new();
@ -24,7 +24,7 @@ pub fn load_raw_indexed(bin_file: &Path) -> Result<Box<[u8]>, io::Error> {
Ok(buffer.into_boxed_slice()) Ok(buffer.into_boxed_slice())
} }
pub fn load_raw_rgba(bin_file: &Path) -> Result<Box<[u32]>, io::Error> { pub fn load_raw_rgba(bin_file: impl AsRef<Path>) -> Result<Box<[u32]>, io::Error> {
let f = File::open(bin_file)?; let f = File::open(bin_file)?;
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
let mut buffer = Vec::new(); let mut buffer = Vec::new();

View file

@ -61,6 +61,12 @@ impl ImGui {
} }
} }
impl Default for ImGui {
fn default() -> Self {
Self::new()
}
}
impl SystemEventHandler for ImGui { impl SystemEventHandler for ImGui {
fn handle_event(&mut self, event: &SystemEvent) -> bool { fn handle_event(&mut self, event: &SystemEvent) -> bool {
self.platform.handle_event(&mut self.context, event) self.platform.handle_event(&mut self.context, event)

View file

@ -7,7 +7,7 @@ fn create_default_texture_map(context: &mut imgui::Context) -> imgui::Textures<R
// set up a bitmap with the imgui font atlas texture pixels and register a bitmap->texture mapping for it // set up a bitmap with the imgui font atlas texture pixels and register a bitmap->texture mapping for it
// with imgui // with imgui
let mut font = context.fonts(); let font = context.fonts();
let mut font_atlas_texture = font.build_rgba32_texture(); let mut font_atlas_texture = font.build_rgba32_texture();
font.tex_id = texture_map.insert( font.tex_id = texture_map.insert(
RgbaBitmap::from_bytes( RgbaBitmap::from_bytes(

View file

@ -4,4 +4,4 @@
# necessarily see a reason to keep using whatever nightly version is the latest, and would # necessarily see a reason to keep using whatever nightly version is the latest, and would
# prefer stick with versions that appear to be stable and just periodically do manual updates # prefer stick with versions that appear to be stable and just periodically do manual updates
# here to get *some* peace of mind in terms of build stability. # here to get *some* peace of mind in terms of build stability.
channel = "nightly-2023-11-10" channel = "nightly-2024-09-05"