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,
}
fn load_and_convert_wav(path: &Path, target_spec: &AudioSpec) -> Result<AudioBuffer> {
let sound = AudioBuffer::load_wav_file(path)?;
fn load_and_convert_wav(path: impl AsRef<Path>, target_spec: &AudioSpec) -> Result<AudioBuffer> {
let sound = AudioBuffer::load_wav_file(&path)?;
let original_spec = *sound.spec();
let sound = sound.convert(target_spec)?;
let final_spec = *sound.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 {
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)
}
@ -28,6 +28,7 @@ pub struct SineWaveGenerator {
t: usize,
}
#[allow(clippy::new_without_default)]
impl SineWaveGenerator {
pub fn new() -> Self {
SineWaveGenerator { t: 0 }
@ -58,11 +59,11 @@ fn main() -> Result<()> {
let mut volume = 1.0;
let sounds = [
load_and_convert_wav(Path::new("./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(Path::new("./assets/explosion.wav"), system.res.audio.spec())?,
load_and_convert_wav(Path::new("./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/pickup-coin.wav", system.res.audio.spec())?,
load_and_convert_wav("./assets/powerup.wav", system.res.audio.spec())?,
load_and_convert_wav("./assets/explosion.wav", system.res.audio.spec())?,
load_and_convert_wav("./assets/jump.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];
@ -154,7 +155,7 @@ fn main() -> Result<()> {
for index in 0..NUM_CHANNELS {
let channel = &audio_device[index];
let mut status = &mut statuses[index];
let status = &mut statuses[index];
status.playing = channel.playing;
status.position = channel.position;
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);
let mut y = 48;
for index in 0..NUM_CHANNELS {
let status = &statuses[index];
for (index, status) in statuses.iter().enumerate() {
system.res.video.print_string(
&format!(
"channel {} - {} {}",

View file

@ -1,5 +1,3 @@
use std::path::Path;
use anyhow::Result;
use ggdt::prelude::*;
@ -26,7 +24,7 @@ fn main() -> Result<()> {
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();
let mut sprites = Vec::<IndexedBitmap>::new();
@ -62,8 +60,7 @@ fn main() -> Result<()> {
}
if system.res.keyboard.is_key_up(Scancode::S) {
for i in 0..NUM_BALLS {
let ball = &mut balls[i];
for ball in balls.iter_mut() {
ball.x += ball.dir_x;
ball.y += ball.dir_y;
@ -72,11 +69,9 @@ fn main() -> Result<()> {
ball.dir_x = -ball.dir_x;
ball.x = 0;
}
} else {
if ball.x >= (system.res.video.width() - BALL_WIDTH) as i32 {
ball.dir_x = -ball.dir_x;
ball.x = (system.res.video.width() - BALL_WIDTH) as i32;
}
} else if ball.x >= (system.res.video.width() - BALL_WIDTH) as i32 {
ball.dir_x = -ball.dir_x;
ball.x = (system.res.video.width() - BALL_WIDTH) as i32;
}
if ball.dir_y < 0 {
@ -84,11 +79,9 @@ fn main() -> Result<()> {
ball.dir_y = -ball.dir_y;
ball.y = 0;
}
} else {
if ball.y >= (system.res.video.height() - BALL_HEIGHT) as i32 {
ball.dir_y = -ball.dir_y;
ball.y = (system.res.video.height() - BALL_HEIGHT) as i32;
}
} else if ball.y >= (system.res.video.height() - BALL_HEIGHT) as i32 {
ball.dir_y = -ball.dir_y;
ball.y = (system.res.video.height() - BALL_HEIGHT) as i32;
}
}
}

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>();
for (entity, _) in bounceables.iter() {
let mut position = positions.get_mut(entity).unwrap();
let mut velocity = velocities.get_mut(entity).unwrap();
let position = positions.get_mut(entity).unwrap();
let velocity = velocities.get_mut(entity).unwrap();
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 {

View file

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

View file

@ -25,7 +25,7 @@ impl Game {
pub fn new(mut system: System<DosLike>) -> Result<Self> {
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();
let mut sprites = Vec::new();

View file

@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::path::Path;
use std::rc::Rc;
use anyhow::Result;
@ -91,17 +90,17 @@ impl AppContext<Standard> for GameContext {
impl GameContext {
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 small_font = load_font(Path::new("./assets/small.fnt"))?;
let font = load_font("./assets/dp.fnt")?;
let small_font = load_font("./assets/small.fnt")?;
let tiles = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/tiles.pcx"))?);
let green_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/green_slime.pcx"))?);
let blue_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/blue_slime.pcx"))?);
let orange_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/orange_slime.pcx"))?);
let tiles = Rc::new(load_bitmap_atlas_autogrid("./assets/tiles.pcx")?);
let green_slime = Rc::new(load_bitmap_atlas_autogrid("./assets/green_slime.pcx")?);
let blue_slime = Rc::new(load_bitmap_atlas_autogrid("./assets/blue_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 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) {
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
// an actual activity change from what it was before

View file

@ -85,11 +85,12 @@ impl AppState<GameContext> for DemoState {
}
});
if !ui.is_any_hovered() && !ui.is_any_focused() {
if 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_y -= context.core.system.res.mouse.y_delta() * 2;
}
if !ui.is_any_hovered()
&& !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_y -= context.core.system.res.mouse.y_delta() * 2;
}
context.support.do_events(&mut context.core);

View file

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

View file

@ -1,3 +1,5 @@
use std::path::Path;
use anyhow::{Context, Result};
use ggdt::prelude::*;
@ -16,10 +18,10 @@ pub struct TileMap {
}
impl TileMap {
pub fn load_from(path: &std::path::Path) -> Result<Self> {
let f = std::fs::File::open(path)?;
pub fn load_from(path: impl AsRef<Path>) -> Result<Self> {
let f = std::fs::File::open(&path)?;
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]

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(
context: &mut Game,
map_file: &Path,
map_file: impl AsRef<Path>,
min_spawn_time: f32,
max_spawn_time: f32,
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) {
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
// 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 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);
}
pub fn pickup(context: &mut Core, picked_up_by: EntityId, picked_up: EntityId) {
let kind;
pub fn pickup(context: &mut Core, _picked_up_by: EntityId, picked_up: EntityId) {
let _kind;
let position;
{
let positions = context.entities.components::<Position>();
position = positions.get(&picked_up).unwrap().0;
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
@ -332,7 +332,7 @@ fn update_system_pushing(context: &mut Core) {
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);
for (pushable_entity, pushable) in pushable.iter() {
for (pushable_entity, _pushable) in pushable.iter() {
// don't push ourself ...
if *pushable_entity == *pusher_entity {
continue;
@ -535,7 +535,7 @@ fn update_system_randomly_spawn_slimes(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((_, 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 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
// 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;
}
}
@ -593,7 +593,7 @@ fn update_system_position_attached_entities(context: &mut Core) {
}
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
attachment_position.0 = parent_position;

View file

@ -1,7 +1,6 @@
extern crate core;
use std::collections::HashMap;
use std::path::Path;
use std::rc::Rc;
use anyhow::{Context, Result};
@ -108,30 +107,30 @@ impl AppContext<DosLike> for Game {
impl Game {
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();
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 hero_male = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/hero_male.pcx"))?);
let hero_female = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/hero_female.pcx"))?);
let green_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/green_slime.pcx"))?);
let blue_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/blue_slime.pcx"))?);
let orange_slime = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/orange_slime.pcx"))?);
let fist = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/fist.pcx"))?);
let sword = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/sword.pcx"))?);
let particles = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/particles.pcx"))?);
let items = Rc::new(load_bitmap_atlas_autogrid(Path::new("./assets/items.pcx"))?);
let tiles = Rc::new(load_bitmap_atlas_autogrid("./assets/tiles.pcx")?);
let hero_male = Rc::new(load_bitmap_atlas_autogrid("./assets/hero_male.pcx")?);
let hero_female = Rc::new(load_bitmap_atlas_autogrid("./assets/hero_female.pcx")?);
let green_slime = Rc::new(load_bitmap_atlas_autogrid("./assets/green_slime.pcx")?);
let blue_slime = Rc::new(load_bitmap_atlas_autogrid("./assets/blue_slime.pcx")?);
let orange_slime = Rc::new(load_bitmap_atlas_autogrid("./assets/orange_slime.pcx")?);
let fist = Rc::new(load_bitmap_atlas_autogrid("./assets/fist.pcx")?);
let sword = Rc::new(load_bitmap_atlas_autogrid("./assets/sword.pcx")?);
let particles = Rc::new(load_bitmap_atlas_autogrid("./assets/particles.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(16, 0, 16, 16))?;
for i in 0..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 component_systems = ComponentSystems::new();

View file

@ -1,5 +1,3 @@
use std::path::Path;
use ggdt::prelude::*;
use crate::entities::*;
@ -45,7 +43,7 @@ impl AppState<Game> for MainMenuState {
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.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)
}
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 {
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 => {
self.fade = 0.0;
@ -172,7 +170,7 @@ impl AppState<Game> for GamePlayState {
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() {
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)
}
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 {
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);
}
State::TransitionIn => {

View file

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

View file

@ -21,10 +21,10 @@ pub struct TileMap {
}
impl TileMap {
pub fn load_from(path: &Path) -> Result<Self> {
let f = File::open(path)?;
pub fn load_from(path: impl AsRef<Path>) -> Result<Self> {
let f = File::open(&path)?;
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]

View file

@ -108,16 +108,16 @@ impl AppState<App> for DemoState {
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.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
}
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 {
State::Pending => {
self.init(context);

View file

@ -50,3 +50,12 @@ harness = false
[[bench]]
name = "triangles"
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 ggdt::prelude::*;
pub fn criterion_benchmark(c: &mut Criterion) {
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();
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 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_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
/// 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 mut reader = BufReader::new(f);
Self::load_wav_bytes(&mut reader)
@ -287,31 +287,31 @@ mod tests {
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)
}
#[test]
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!(1, wav_buffer.spec().channels());
assert_eq!(AudioFormat::U8, wav_buffer.spec.format);
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!(1, wav_buffer.spec().channels());
assert_eq!(AudioFormat::U8, wav_buffer.spec.format);
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!(1, wav_buffer.spec().channels());
assert_eq!(AudioFormat::S16LSB, wav_buffer.spec.format);
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!(1, wav_buffer.spec().channels());
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)]

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.
//!
//! 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
//! pushed towards due to the Rust borrow-checker (as is often the case with Rust). My games/apps
//! needed to keep their state (for clarity, the word 'state' here is being used very broadly to
//! refer to all game/app state, and not just referring to the stuff inside `ggdt::states`)
//! 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:
//!
//! ```
//! use ggdt::prelude::*;
//!
//! pub enum Event { /* .. various events here .. */ }
//!
//! struct App {
//! pub delta: f32,
//! pub system: System<DosLike>,
//! pub entities: Entities,
//! pub component_systems: ComponentSystems<App, App>, // oh no! :'(
//! 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
//! `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
//! 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::*;
//!
//! pub enum Event { /* .. various events here .. */ }
//!
//! // "core" because what the heck else do i call this? "InnerContext"? "InnerApp"? ...
//! struct Core {
//! pub delta: f32,
//! pub system: System<DosLike>,
//! 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 {
//! pub core: 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
//! 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
//! the new frame `delta` each iteration of the main loop. As well as event processing via the
//! `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
//! move away from my "context" struct having a parent-child relation for the split of the data
//! kept in these, and instead just "flatten" it out a bit (sort of) as this seems much more
//! 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!
//!
//! ```
//! use ggdt::prelude::*;
//!
//! 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.
//! struct Core {
//! pub delta: f32,
//! pub system: System<DosLike>,
//! 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 ...
//! struct Support {
//! pub component_systems: ComponentSystems<Core, Core>,
//! pub event_listeners: EventListeners<Event, Core>,
//! }
//!
//! // better, maybe?
//! struct App {
//! pub core: Core,
//! pub support: Support,
//! }
//! ```
//!
//! 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)
//! `CoreStateWithEvents` are what you'd make your project's `Core` struct (as shown in the above
//! example code) implement, while `SupportSystems` and (optionally) `SupportSystemsWithEvents`
//! 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
//! 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
//! 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.
//!
/*!
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.
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
pushed towards due to the Rust borrow-checker (as is often the case with Rust). My games/apps
needed to keep their state (for clarity, the word 'state' here is being used very broadly to
refer to all game/app state, and not just referring to the stuff inside `ggdt::states`)
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:
```
use ggdt::prelude::*;
pub enum Event { /* .. various events here .. */ }
struct App {
pub delta: f32,
pub system: System<DosLike>,
pub entities: Entities,
pub component_systems: ComponentSystems<App, App>, // oh no! :'(
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
`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
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::*;
pub enum Event { /* .. various events here .. */ }
// "core" because what the heck else do i call this? "InnerContext"? "InnerApp"? ...
struct Core {
pub delta: f32,
pub system: System<DosLike>,
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 {
pub core: 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
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
the new frame `delta` each iteration of the main loop. As well as event processing via the
`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
move away from my "context" struct having a parent-child relation for the split of the data
kept in these, and instead just "flatten" it out a bit (sort of) as this seems much more
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!
```
use ggdt::prelude::*;
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.
struct Core {
pub delta: f32,
pub system: System<DosLike>,
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 ...
struct Support {
pub component_systems: ComponentSystems<Core, Core>,
pub event_listeners: EventListeners<Event, Core>,
}
// better, maybe?
struct App {
pub core: Core,
pub support: Support,
}
```
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)
`CoreStateWithEvents` are what you'd make your project's `Core` struct (as shown in the above
example code) implement, while `SupportSystems` and (optionally) `SupportSystemsWithEvents`
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
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
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.
*/
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 ... ?
@ -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)]
@ -667,7 +679,7 @@ mod tests {
// modify position components
{
let mut positions = em.components_mut::<Position>().unwrap();
for mut component in positions.values_mut() {
for component in positions.values_mut() {
component.0 += 5;
}
@ -678,7 +690,7 @@ mod tests {
// modify health components
{
let mut healths = em.components_mut::<Health>().unwrap();
for mut component in healths.values_mut() {
for component in healths.values_mut() {
component.0 += 5;
}
assert_eq!(Health(25), *healths.get(&a).unwrap());
@ -722,10 +734,10 @@ mod tests {
println!("entity {}, health: {:?}, position: {:?}", name.0, health, position);
if let Some(mut health) = health {
if let Some(health) = health {
health.0 += 5;
}
if let Some(mut position) = position {
if let Some(position) = position {
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
/// [`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)]
mod tests {
use super::*;
@ -175,10 +187,12 @@ mod tests {
}
fn dummy_listener(_event: &TestEvent, _context: &mut DummyContext) -> bool {
println!("dummy_listener event fired");
false
}
fn other_dummy_listener(_event: &TestEvent, _context: &mut DummyContext) -> bool {
println!("other_dummy_listener event fired");
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)
}
/// # 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]
pub unsafe fn per_pixel_blit<PixelType: Pixel>(
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]
pub unsafe fn per_pixel_flipped_blit<PixelType: Pixel>(
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]
pub unsafe fn per_pixel_rotozoom_blit<PixelType: Pixel>(
dest: &mut Bitmap<PixelType>,
@ -280,6 +292,10 @@ pub unsafe fn per_pixel_rotozoom_blit<PixelType: Pixel>(
}
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) {
let src_row_length = src_region.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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut self,
src: &Self,

View file

@ -468,7 +468,7 @@ impl IndexedBitmap {
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 mut reader = BufReader::new(f);
Self::load_gif_bytes(&mut reader)
@ -520,7 +520,12 @@ impl IndexedBitmap {
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 mut writer = BufWriter::new(f);
self.to_gif_bytes(&mut writer, palette, settings)
@ -537,7 +542,7 @@ impl RgbaBitmap {
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 output = temp_bitmap.to_rgba(&palette);
Ok((output, palette))
@ -556,7 +561,7 @@ mod tests {
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)
}
@ -564,14 +569,14 @@ mod tests {
fn load_and_save() -> Result<(), GifError> {
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(
test_assets_file(Path::new("dp2.pal")).as_path(), //
test_assets_file("dp2.pal"), //
PaletteFormat::Normal,
)
.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.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -597,9 +602,9 @@ mod tests {
// 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!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -613,9 +618,9 @@ mod tests {
// 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!(200, bmp.height());
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) {
let bitmask = 1 << plane;
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;
if src[src_base_index] & bitmask != 0 {
data |= 128;
@ -241,7 +241,7 @@ fn extract_bitplane(plane: u32, src: &[u8], dest: &mut [u8], row_size: usize) {
}
src_base_index += 8;
dest[x] = data;
*dest_pixel = data;
}
}
@ -430,7 +430,7 @@ impl IndexedBitmap {
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 mut reader = BufReader::new(f);
Self::load_iff_bytes(&mut reader)
@ -522,7 +522,7 @@ impl IndexedBitmap {
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 mut writer = BufWriter::new(f);
self.to_iff_bytes(&mut writer, palette, format)
@ -539,7 +539,7 @@ impl RgbaBitmap {
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 output = temp_bitmap.to_rgba(&palette);
Ok((output, palette))
@ -558,7 +558,7 @@ mod tests {
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)
}
@ -566,16 +566,16 @@ mod tests {
pub fn load_and_save() -> Result<(), IffError> {
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(
test_assets_file(Path::new("dp2.pal")).as_path(), //
test_assets_file("dp2.pal"), //
PaletteFormat::Normal,
)
.unwrap();
// 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.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -591,7 +591,7 @@ mod tests {
// 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.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -614,9 +614,9 @@ mod tests {
// 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!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -630,7 +630,7 @@ mod tests {
// 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!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -644,9 +644,9 @@ mod tests {
// 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!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -660,7 +660,7 @@ mod tests {
// 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!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref());

View file

@ -126,6 +126,10 @@ pub enum IndexedBlitMethod {
}
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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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]
#[rustfmt::skip]
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]
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);
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]
pub unsafe fn blit_atlas_unchecked(
&mut self,

View file

@ -25,8 +25,8 @@ impl IndexedBitmap {
Self::internal_new(width, height, 0)
}
pub fn load_file(path: &Path) -> Result<(Self, Palette), BitmapError> {
if let Some(extension) = path.extension() {
pub fn load_file(path: impl AsRef<Path>) -> Result<(Self, Palette), BitmapError> {
if let Some(extension) = path.as_ref().extension() {
let extension = extension.to_ascii_lowercase();
match extension.to_str() {
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,
/// or using the color specified if the blend map does not include the given color. The
/// coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// or using the color specified if the blend map does not include the given color.
///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline]
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::*;
match triangle {
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),
SolidTexturedBlended { 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
/// given coordinates and extending to the end of the bitmap. The coordinates are not checked
/// for validity, so it is up to you to ensure they lie within the bounds of the bitmap.
/// given coordinates and extending to the end 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]
pub unsafe fn pixels_at_unchecked(&self, x: i32, y: i32) -> &[PixelType] {
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
/// at the given coordinates and extending to the end of the bitmap. The coordinates are not
/// checked for validity, so it is up to you to ensure they lie within the bounds of the bitmap.
/// at the given coordinates and extending to the end 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]
pub unsafe fn pixels_at_mut_unchecked(&mut self, x: i32, y: i32) -> &mut [PixelType] {
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,
/// None is returned.
#[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) {
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 {
None
}
@ -249,18 +257,22 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
/// given coordinates. If the coordinates given are outside the bitmap's current clipping
/// region, None is returned.
#[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) {
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 {
None
}
}
/// 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
/// ensure they lie within the bounds of the bitmap.
/// given coordinates.
///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline]
pub unsafe fn pixels_at_ptr_unchecked(&self, x: i32, y: i32) -> *const PixelType {
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
/// at the given coordinates. The coordinates are not checked for validity, so it is up to you
/// to ensure they lie within the bounds of the bitmap.
/// at the given coordinates.
///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline]
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);
@ -482,15 +498,15 @@ mod tests {
let mut bmp = Bitmap::<u8>::new(8, 8).unwrap();
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 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!(1, unsafe { *(pixels.add(offset)) });
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!(2, unsafe { *(pixels.add(54)) });
}
@ -500,15 +516,15 @@ mod tests {
let mut bmp = Bitmap::<u8>::new(8, 8).unwrap();
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 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!(1, unsafe { *(pixels.add(offset)) });
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!(2, unsafe { *(pixels.add(54)) });
}

View file

@ -178,7 +178,7 @@ impl IndexedBitmap {
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 mut reader = BufReader::new(f);
Self::load_pcx_bytes(&mut reader)
@ -250,7 +250,7 @@ impl IndexedBitmap {
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 mut writer = BufWriter::new(f);
self.to_pcx_bytes(&mut writer, palette)
@ -267,7 +267,7 @@ impl RgbaBitmap {
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 output = temp_bitmap.to_rgba(&palette);
Ok((output, palette))
@ -286,7 +286,7 @@ mod tests {
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)
}
@ -294,14 +294,14 @@ mod tests {
pub fn load_and_save() -> Result<(), PcxError> {
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(
test_assets_file(Path::new("dp2.pal")).as_path(), //
test_assets_file("dp2.pal"), //
PaletteFormat::Normal,
)
.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.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -324,9 +324,9 @@ mod tests {
// 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!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref());
@ -340,9 +340,9 @@ mod tests {
// 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!(200, bmp.height());
assert_eq!(bmp.pixels(), ref_pixels.as_ref());

View file

@ -42,10 +42,10 @@ pub enum PngFormat {
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
enum ColorFormat {
Grayscale = 0,
RGB = 2,
Rgb = 2,
IndexedColor = 3,
GrayscaleAlpha = 4,
RGBA = 6,
Rgba = 6,
}
impl ColorFormat {
@ -53,10 +53,10 @@ impl ColorFormat {
use ColorFormat::*;
match value {
0 => Ok(Grayscale),
2 => Ok(RGB),
2 => Ok(Rgb),
3 => Ok(IndexedColor),
4 => Ok(GrayscaleAlpha),
6 => Ok(RGBA),
6 => Ok(Rgba),
_ => Err(PngError::UnsupportedColorType(value)),
}
}
@ -202,8 +202,8 @@ impl ScanlineBuffer {
pub fn new(ihdr: &ImageHeaderChunk) -> Result<Self, PngError> {
let bpp = match ihdr.format {
ColorFormat::IndexedColor => 1,
ColorFormat::RGB => 3,
ColorFormat::RGBA => 4,
ColorFormat::Rgb => 3,
ColorFormat::Rgba => 4,
_ => return Err(PngError::BadFile(format!("Unsupported color format: {:?}", ihdr.format))),
};
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 g = self.current[offset + 1];
let b = self.current[offset + 2];
Ok(RGBA::from_rgb([r, g, b]))
}
ColorFormat::RGBA => {
ColorFormat::Rgba => {
let r = self.current[offset];
let g = self.current[offset + 1];
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> {
let offset = x * self.bpp;
match self.format {
ColorFormat::RGB => {
ColorFormat::Rgb => {
self.current[offset] = pixel.r();
self.current[offset + 1] = pixel.g();
self.current[offset + 2] = pixel.b();
Ok(())
}
ColorFormat::RGBA => {
ColorFormat::Rgba => {
self.current[offset] = pixel.r();
self.current[offset + 1] = pixel.g();
self.current[offset + 2] = pixel.b();
@ -400,8 +400,8 @@ where
return Err(PngError::BadFile(String::from("Unsupported color bit depth.")));
}
if ihdr.format != ColorFormat::IndexedColor // .
&& ihdr.format != ColorFormat::RGB
&& ihdr.format != ColorFormat::RGBA
&& ihdr.format != ColorFormat::Rgb
&& ihdr.format != ColorFormat::Rgba
{
return Err(PngError::BadFile(String::from("Unsupported pixel color format.")));
}
@ -560,7 +560,7 @@ impl IndexedBitmap {
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 mut reader = BufReader::new(f);
Self::load_png_bytes(&mut reader)
@ -570,7 +570,7 @@ impl IndexedBitmap {
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 mut writer = BufWriter::new(f);
self.to_png_bytes(&mut writer, palette)
@ -582,7 +582,7 @@ impl RgbaBitmap {
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 mut reader = BufReader::new(f);
Self::load_png_bytes(&mut reader)
@ -593,14 +593,14 @@ impl RgbaBitmap {
writer,
self,
match format {
PngFormat::RGB => ColorFormat::RGB,
PngFormat::RGBA => ColorFormat::RGBA,
PngFormat::RGB => ColorFormat::Rgb,
PngFormat::RGBA => ColorFormat::Rgba,
},
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 mut writer = BufWriter::new(f);
self.to_png_bytes(&mut writer, format)
@ -620,14 +620,14 @@ mod tests {
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)
}
#[test]
pub fn loads_indexed_256_color() -> Result<(), PngError> {
let ref_bytes = load_raw_indexed(test_file(Path::new("indexed_8.bin")).as_path())?;
let (bmp, palette) = IndexedBitmap::load_png_file(test_file(Path::new("indexed_8.png")).as_path())?;
let ref_bytes = load_raw_indexed(test_file("indexed_8.bin"))?;
let (bmp, palette) = IndexedBitmap::load_png_file(test_file("indexed_8.png"))?;
assert!(palette.is_some());
assert_eq!(ref_bytes, bmp.pixels);
Ok(())
@ -635,8 +635,8 @@ mod tests {
#[test]
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 (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("indexed_8.png")).as_path())?;
let ref_bytes = load_raw_rgba(test_file("indexed_8_rgba.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file("indexed_8.png"))?;
assert!(palette.is_some());
assert_eq!(ref_bytes, bmp.pixels);
Ok(())
@ -644,8 +644,8 @@ mod tests {
#[test]
pub fn loads_rgb_color() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("rgb.bin")).as_path())?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("rgb.png")).as_path())?;
let ref_bytes = load_raw_rgba(test_file("rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file("rgb.png"))?;
assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels);
Ok(())
@ -653,8 +653,8 @@ mod tests {
#[test]
pub fn loads_rgba_color() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("rgba.bin")).as_path())?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("rgba.png")).as_path())?;
let ref_bytes = load_raw_rgba(test_file("rgba.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file("rgba.png"))?;
assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels);
Ok(())
@ -662,8 +662,8 @@ mod tests {
#[test]
pub fn loads_filter_0() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("filter_0_rgb.bin")).as_path())?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("filter_0_rgb.png")).as_path())?;
let ref_bytes = load_raw_rgba(test_file("filter_0_rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file("filter_0_rgb.png"))?;
assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels);
Ok(())
@ -671,8 +671,8 @@ mod tests {
#[test]
pub fn loads_filter_1() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("filter_1_rgb.bin")).as_path())?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("filter_1_rgb.png")).as_path())?;
let ref_bytes = load_raw_rgba(test_file("filter_1_rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file("filter_1_rgb.png"))?;
assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels);
Ok(())
@ -680,8 +680,8 @@ mod tests {
#[test]
pub fn loads_filter_2() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("filter_2_rgb.bin")).as_path())?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("filter_2_rgb.png")).as_path())?;
let ref_bytes = load_raw_rgba(test_file("filter_2_rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file("filter_2_rgb.png"))?;
assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels);
Ok(())
@ -689,8 +689,8 @@ mod tests {
#[test]
pub fn loads_filter_3() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("filter_3_rgb.bin")).as_path())?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("filter_3_rgb.png")).as_path())?;
let ref_bytes = load_raw_rgba(test_file("filter_3_rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file("filter_3_rgb.png"))?;
assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels);
Ok(())
@ -698,8 +698,8 @@ mod tests {
#[test]
pub fn loads_filter_4() -> Result<(), PngError> {
let ref_bytes = load_raw_rgba(test_file(Path::new("filter_4_rgb.bin")).as_path())?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("filter_4_rgb.png")).as_path())?;
let ref_bytes = load_raw_rgba(test_file("filter_4_rgb.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file("filter_4_rgb.png"))?;
assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels);
Ok(())
@ -707,13 +707,13 @@ mod tests {
#[test]
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 (bmp, palette) = IndexedBitmap::load_png_file(test_file(Path::new("large_1_indexed.png")).as_path())?;
let ref_bytes = load_raw_indexed(test_file("large_1_indexed.bin"))?;
let (bmp, palette) = IndexedBitmap::load_png_file(test_file("large_1_indexed.png"))?;
assert!(palette.is_some());
assert_eq!(ref_bytes, bmp.pixels);
let ref_bytes = load_raw_indexed(test_file(Path::new("large_2_indexed.bin")).as_path())?;
let (bmp, palette) = IndexedBitmap::load_png_file(test_file(Path::new("large_2_indexed.png")).as_path())?;
let ref_bytes = load_raw_indexed(test_file("large_2_indexed.bin"))?;
let (bmp, palette) = IndexedBitmap::load_png_file(test_file("large_2_indexed.png"))?;
assert!(palette.is_some());
assert_eq!(ref_bytes, bmp.pixels);
@ -722,13 +722,13 @@ mod tests {
#[test]
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 (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("large_1_rgb.png")).as_path())?;
let ref_bytes = load_raw_rgba(test_file("large_1_rgba.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file("large_1_rgb.png"))?;
assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels);
let ref_bytes = load_raw_rgba(test_file(Path::new("large_2_rgba.bin")).as_path())?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file(Path::new("large_2_rgb.png")).as_path())?;
let ref_bytes = load_raw_rgba(test_file("large_2_rgba.bin"))?;
let (bmp, palette) = RgbaBitmap::load_png_file(test_file("large_2_rgb.png"))?;
assert!(palette.is_none());
assert_eq!(ref_bytes, bmp.pixels);
@ -739,9 +739,9 @@ mod tests {
pub fn load_and_save_indexed_256_color() -> Result<(), PngError> {
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.height());
assert_eq!(bmp.pixels, ref_bytes);
@ -764,9 +764,9 @@ mod tests {
// 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!(200, bmp.height());
assert_eq!(bmp.pixels, ref_bytes);
@ -782,9 +782,9 @@ mod tests {
// 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!(200, bmp.height());
assert_eq!(bmp.pixels, ref_bytes);
@ -805,9 +805,9 @@ mod tests {
pub fn load_and_save_rgb_color() -> Result<(), PngError> {
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.height());
assert_eq!(bmp.pixels, ref_bytes);
@ -830,9 +830,9 @@ mod tests {
// 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!(200, bmp.height());
assert_eq!(bmp.pixels, ref_bytes);
@ -848,9 +848,9 @@ mod tests {
// 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!(200, bmp.height());
assert_eq!(bmp.pixels, ref_bytes);
@ -869,58 +869,43 @@ mod tests {
#[test]
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!(
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(..))
);
assert_matches!(
RgbaBitmap::load_png_file(test_file(Path::new("unsupported_greyscale_8bit.png")).as_path()),
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()),
RgbaBitmap::load_png_file(test_file("unsupported_indexed_16col.png")),
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!(
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(..))
);
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(..))
);
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(..))
);
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(..))
);
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(..))
);
// also test the extra formats that IndexedBitmap does not support which RgbaBitmap does
// (anything not 256-color indexed basically ...)
assert_matches!(
IndexedBitmap::load_png_file(test_file(Path::new("rgb.png")).as_path()),
Err(PngError::BadFile(..))
);
assert_matches!(
IndexedBitmap::load_png_file(test_file(Path::new("rgba.png")).as_path()),
Err(PngError::BadFile(..))
);
assert_matches!(IndexedBitmap::load_png_file(test_file("rgb.png")), Err(PngError::BadFile(..)));
assert_matches!(IndexedBitmap::load_png_file(test_file("rgba.png")), Err(PngError::BadFile(..)));
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
/// checked for validity, so it is up to you to ensure they lie within the bounds of the
/// bitmap.
/// Sets the pixel at the given coordinates to the color specified.
///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline]
pub unsafe fn set_pixel_unchecked(&mut self, x: i32, y: i32, color: PixelType) {
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
/// 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
/// ensure they lie within the bounds of the bitmap.
/// the given coordinates.
///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline]
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);
@ -57,8 +64,12 @@ impl<PixelType: Pixel> Bitmap<PixelType> {
self.pixels_at(x, y).map(|pixels| pixels[0])
}
/// Gets the pixel at the given coordinates. The coordinates are not checked for validity, so
/// it is up to you to ensure they lie within the bounds of the bitmap.
/// Gets the pixel at the given coordinates.
///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline]
pub unsafe fn get_pixel_unchecked(&self, x: i32, y: i32) -> PixelType {
*(self.pixels_at_ptr_unchecked(x, y))

View file

@ -111,6 +111,10 @@ pub enum RgbaBlitMethod {
}
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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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(
&mut 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]
#[rustfmt::skip]
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]
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);
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]
pub unsafe fn blit_atlas_unchecked(
&mut self,

View file

@ -60,8 +60,8 @@ impl RgbaBitmap {
Ok(bitmap)
}
pub fn load_file(path: &Path) -> Result<(Self, Option<Palette>), BitmapError> {
if let Some(extension) = path.extension() {
pub fn load_file(path: impl AsRef<Path>) -> Result<(Self, Option<Palette>), BitmapError> {
if let Some(extension) = path.as_ref().extension() {
let extension = extension.to_ascii_lowercase();
match extension.to_str() {
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,
/// The coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// Sets the pixel at the given coordinates using a blended color via the specified blend function.
///
/// # Safety
///
/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the
/// bounds of the bitmap.
#[inline]
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::{SimdFloat, SimdUint};
use std::simd::prelude::{SimdFloat, SimdUint};
use crate::graphics::{edge_function, per_pixel_triangle_2d, BlendFunction, RgbaBitmap, RGBA};
use crate::math::Vector2;

View file

@ -232,7 +232,7 @@ pub struct 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 mut reader = BufReader::new(f);
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 mut writer = BufWriter::new(f);
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])
}
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 mut reader = BufReader::new(f);
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 mut writer = BufWriter::new(f);
self.to_bytes(&mut writer)

View file

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

View file

@ -209,7 +209,7 @@ impl BitmaskFont {
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 mut reader = BufReader::new(f);
@ -232,8 +232,8 @@ impl BitmaskFont {
}
// read character widths (used for rendering)
for i in 0..NUM_CHARS {
characters[i].bounds.width = reader.read_u8()? as u32;
for character in characters.iter_mut().take(NUM_CHARS) {
character.bounds.width = reader.read_u8()? as u32;
}
// read global font height (used for rendering)
@ -242,7 +242,7 @@ impl BitmaskFont {
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 mut writer = BufWriter::new(f);
self.to_bytes(&mut writer)
@ -327,13 +327,13 @@ mod tests {
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)
}
#[test]
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!(CHAR_FIXED_WIDTH as u8, font.space_width);
for character in font.characters.iter() {
@ -347,7 +347,7 @@ mod tests {
#[test]
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, 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!((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));
}
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 g = reader.read_u8()?;
let b = reader.read_u8()?;
let color = RGBA::from_rgb([from_6bit(r), from_6bit(g), from_6bit(b)]);
colors[i] = color;
*color = RGBA::from_rgb([from_6bit(r), from_6bit(g), from_6bit(b)]);
}
Ok(colors)
}
@ -52,10 +51,10 @@ fn write_palette_6bit<T: WriteBytesExt>(
if num_colors > NUM_COLORS {
return Err(PaletteError::OutOfRange(num_colors));
}
for i in 0..num_colors {
writer.write_u8(to_6bit(colors[i].r()))?;
writer.write_u8(to_6bit(colors[i].g()))?;
writer.write_u8(to_6bit(colors[i].b()))?;
for color in colors.iter().take(num_colors) {
writer.write_u8(to_6bit(color.r()))?;
writer.write_u8(to_6bit(color.g()))?;
writer.write_u8(to_6bit(color.b()))?;
}
Ok(())
}
@ -66,12 +65,11 @@ fn read_palette_8bit<T: ReadBytesExt>(reader: &mut T, num_colors: usize) -> Resu
return Err(PaletteError::OutOfRange(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 g = reader.read_u8()?;
let b = reader.read_u8()?;
let color = RGBA::from_rgb([r, g, b]);
colors[i] = color;
*color = RGBA::from_rgb([r, g, b]);
}
Ok(colors)
}
@ -84,10 +82,10 @@ fn write_palette_8bit<T: WriteBytesExt>(
if num_colors > NUM_COLORS {
return Err(PaletteError::OutOfRange(num_colors));
}
for i in 0..num_colors {
writer.write_u8(colors[i].r())?;
writer.write_u8(colors[i].g())?;
writer.write_u8(colors[i].b())?;
for color in colors.iter().take(num_colors) {
writer.write_u8(color.r())?;
writer.write_u8(color.g())?;
writer.write_u8(color.b())?;
}
Ok(())
}
@ -137,7 +135,7 @@ impl Palette {
///
/// * `path`: the path of the palette file to be loaded
/// * `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 mut reader = BufReader::new(f);
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
/// * `num_colors`: the expected number of colors in the palette to be loaded (<= 256)
pub fn load_num_colors_from_file(
path: &Path,
path: impl AsRef<Path>,
format: PaletteFormat,
num_colors: usize,
) -> Result<Palette, PaletteError> {
@ -208,7 +206,7 @@ impl Palette {
///
/// * `path`: the path of the file to save the palette to
/// * `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 mut writer = BufWriter::new(f);
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)
pub fn num_colors_to_file(
&self,
path: &Path,
path: impl AsRef<Path>,
format: PaletteFormat,
num_colors: usize,
) -> Result<(), PaletteError> {
@ -471,6 +469,12 @@ impl Palette {
}
}
impl Default for Palette {
fn default() -> Self {
Self::new()
}
}
impl Index<u8> for Palette {
type Output = RGBA;
@ -499,7 +503,7 @@ mod tests {
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)
}
@ -538,7 +542,7 @@ mod tests {
// 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);
let save_path = tmp_dir.path().join("test_save_vga_format.pal");
@ -548,7 +552,7 @@ mod tests {
// 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");
palette.to_file(&save_path, PaletteFormat::Normal)?;
@ -564,8 +568,7 @@ mod tests {
// vga rgb format (6-bit)
let palette =
Palette::load_num_colors_from_file(test_file(Path::new("ega_6bit.pal")).as_path(), PaletteFormat::Vga, 16)?;
let palette = Palette::load_num_colors_from_file(test_file("ega_6bit.pal"), PaletteFormat::Vga, 16)?;
assert_ega_colors(&palette);
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)
let palette = Palette::load_num_colors_from_file(
test_file(Path::new("ega_8bit.pal")).as_path(),
PaletteFormat::Normal,
16,
)?;
let palette = Palette::load_num_colors_from_file(test_file("ega_8bit.pal"), PaletteFormat::Normal, 16)?;
let save_path = tmp_dir.path().join("test_save_normal_format_16_colors.pal");
palette.to_file(&save_path, PaletteFormat::Normal)?;

View file

@ -30,15 +30,15 @@ mod tests {
const TEST_ASSETS_PATH: &str = "./test-assets/";
#[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)
}
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)
}
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 mut reader = BufReader::new(f);
let mut buffer = Vec::new();
@ -46,7 +46,7 @@ mod tests {
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 mut reader = BufReader::new(f);
let mut buffer = Vec::new();

View file

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

View file

@ -1,6 +1,6 @@
use std::ops::{Add, Div, Mul, Sub};
use std::simd;
use std::simd::{SimdFloat, SimdPartialOrd};
use std::simd::prelude::{SimdFloat, SimdPartialOrd};
mod circle;
mod matrix3x3;
@ -272,6 +272,7 @@ mod tests {
assert!(nearly_equal(0.0, angle, 0.0001));
}
#[allow(clippy::approx_constant)]
#[test]
pub fn test_angle_to_direction() {
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));
}
#[allow(clippy::approx_constant)]
#[test]
pub fn test_from_angle() {
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)]
mod tests {
use claim::*;

View file

@ -55,6 +55,12 @@ impl Keyboard {
}
}
impl Default for Keyboard {
fn default() -> Self {
Self::new()
}
}
impl InputDevice for Keyboard {
fn update(&mut self) {
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> {
fn get_default() -> MouseCursorBitmap<IndexedBitmap> {
#[rustfmt::skip]

View file

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

View file

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

View file

@ -1,5 +1,8 @@
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
/// 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>;
}
/// 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.
let mut table = vec![None; 1usize.wrapping_shl(MAX_BITS as u32)];
for i in 0..initial_table_size {
table[i] = Some(vec![i as u8]);
for (i, item) in table.iter_mut().enumerate().take(initial_table_size) {
*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 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/";
fn reference_file(file: &Path) -> PathBuf {
fn reference_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(BASE_PATH).join(file)
}
@ -22,8 +22,8 @@ fn setup() -> (IndexedBitmap, Palette) {
}
fn setup_for_blending() -> (IndexedBitmap, Palette, BlendMap) {
let (texture, palette) = IndexedBitmap::load_file(test_assets_file(Path::new("texture.lbm")).as_path()).unwrap();
let blend_map = BlendMap::load_from_file(test_assets_file(Path::new("test.blendmap")).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("test.blendmap")).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 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)
}
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();
*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) {
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]
@ -133,11 +133,11 @@ fn pixel_drawing() {
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) {
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]
@ -169,11 +169,11 @@ fn blended_pixel_drawing() {
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) {
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]
@ -191,11 +191,11 @@ fn horiz_line_drawing() {
screen.horiz_line(100, 200, -10, 6);
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) {
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]
@ -213,11 +213,11 @@ fn blended_horiz_line_drawing() {
screen.blended_horiz_line(100, 200, -10, 6, &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) {
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]
@ -235,11 +235,11 @@ fn vert_line_drawing() {
screen.vert_line(-17, 10, 20, 6);
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) {
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]
@ -257,11 +257,11 @@ fn blended_vert_line_drawing() {
screen.blended_vert_line(-17, 10, 20, 6, &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) {
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]
@ -296,11 +296,11 @@ fn line_drawing() {
screen.line(-100, 120, -100, 239, 3);
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) {
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]
@ -335,11 +335,11 @@ fn blended_line_drawing() {
screen.blended_line(-100, 120, -100, 239, 3, &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) {
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]
@ -365,11 +365,11 @@ fn rect_drawing() {
screen.rect(300, 20, 340, -20, 13);
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) {
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]
@ -395,11 +395,11 @@ fn blended_rect_drawing() {
screen.blended_rect(300, 20, 340, -20, 13, &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) {
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]
@ -425,11 +425,11 @@ fn filled_rect_drawing() {
screen.filled_rect(300, 20, 340, -20, 13);
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) {
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]
@ -455,11 +455,11 @@ fn blended_filled_rect_drawing() {
screen.blended_filled_rect(300, 20, 340, -20, 13, &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) {
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]
@ -480,11 +480,11 @@ fn circle_drawing() {
screen.circle(319, 1, 22, 9);
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) {
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]
@ -505,11 +505,11 @@ fn filled_circle_drawing() {
screen.filled_circle(319, 1, 22, 9);
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) {
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]
@ -517,8 +517,8 @@ fn text_drawing() {
let (mut screen, palette) = setup();
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 chunky_font = BitmaskFont::load_from_file(test_assets_file(Path::new("chunky.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("chunky.fnt")).unwrap();
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, 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) {
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 {
@ -645,11 +645,11 @@ fn solid_blits() {
screen.blit(method.clone(), &bmp16, 196, 238);
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) {
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]
@ -716,11 +716,11 @@ fn blended_solid_blits() {
screen.blit(method.clone(), &bmp16, 196, 238);
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) {
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]
@ -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: 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) {
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]
@ -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: 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) {
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]
@ -919,11 +919,11 @@ fn solid_offset_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -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: 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) {
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]
@ -1061,11 +1061,11 @@ fn transparent_blits() {
screen.blit(method.clone(), &bmp16, 196, 238);
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) {
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]
@ -1132,11 +1132,11 @@ fn blended_transparent_blits() {
screen.blit(method.clone(), &bmp16, 196, 238);
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) {
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]
@ -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: 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) {
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]
@ -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: 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) {
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]
@ -1342,11 +1342,11 @@ fn transparent_offset_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -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: 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) {
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]
@ -1487,11 +1487,11 @@ fn transparent_single_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -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: 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) {
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]
@ -1628,11 +1628,11 @@ fn rotozoom_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -1697,11 +1697,11 @@ fn blended_rotozoom_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -1768,11 +1768,11 @@ fn rotozoom_offset_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -1839,11 +1839,11 @@ fn rotozoom_transparent_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -1916,11 +1916,11 @@ fn blended_rotozoom_transparent_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -1989,11 +1989,11 @@ fn rotozoom_transparent_offset_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -2203,11 +2203,11 @@ fn triangle_2d() {
color,
});
let path = reference_file(Path::new("triangle_2d.png"));
let path = &reference_file("triangle_2d.png");
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)]
@ -2378,11 +2378,11 @@ fn triangle_2d_solid_textured() {
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) {
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]
@ -2391,11 +2391,11 @@ fn triangle_2d_solid_blended() {
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) {
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]
@ -2406,9 +2406,9 @@ fn triangle_2d_solid_textured_blended() {
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) {
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/";
fn reference_file(file: &Path) -> PathBuf {
fn reference_file(file: impl AsRef<Path>) -> PathBuf {
PathBuf::from(BASE_PATH).join(file)
}
@ -38,7 +38,7 @@ fn setup() -> 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();
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 {
@ -49,7 +49,7 @@ fn setup_for_blending() -> 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();
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 {
@ -69,7 +69,7 @@ fn setup_for_blending_half_solid_half_semi_transparent() -> RgbaBitmap {
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();
*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) {
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]
@ -169,11 +169,11 @@ fn pixel_drawing() {
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) {
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]
@ -207,11 +207,11 @@ fn blended_pixel_drawing() {
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) {
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]
@ -229,11 +229,11 @@ fn horiz_line_drawing() {
screen.horiz_line(100, 200, -10, COLOR_BROWN);
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) {
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]
@ -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(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) {
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]
@ -275,11 +275,11 @@ fn vert_line_drawing() {
screen.vert_line(-17, 10, 20, COLOR_BROWN);
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) {
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]
@ -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(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) {
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]
@ -338,11 +338,11 @@ fn line_drawing() {
screen.line(-100, 120, -100, 239, COLOR_CYAN);
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) {
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]
@ -379,11 +379,11 @@ fn blended_line_drawing() {
screen.blended_line(-100, 120, -100, 239, COLOR_CYAN_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) {
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]
@ -409,11 +409,11 @@ fn rect_drawing() {
screen.rect(300, 20, 340, -20, COLOR_BRIGHT_MAGENTA);
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) {
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]
@ -441,11 +441,11 @@ fn blended_rect_drawing() {
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);
let path = reference_file(Path::new("blended_rect_drawing.png"));
let path = &reference_file("blended_rect_drawing.png");
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]
@ -471,11 +471,11 @@ fn filled_rect_drawing() {
screen.filled_rect(300, 20, 340, -20, COLOR_BRIGHT_MAGENTA);
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) {
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]
@ -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(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) {
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]
@ -528,11 +528,11 @@ fn circle_drawing() {
screen.circle(319, 1, 22, COLOR_BRIGHT_BLUE);
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) {
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]
@ -553,11 +553,11 @@ fn filled_circle_drawing() {
screen.filled_circle(319, 1, 22, COLOR_BRIGHT_BLUE);
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) {
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]
@ -565,8 +565,8 @@ fn text_drawing() {
let mut screen = setup();
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 chunky_font = BitmaskFont::load_from_file(test_assets_file(Path::new("chunky.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("chunky.fnt")).unwrap();
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, 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) {
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 {
@ -737,11 +737,11 @@ fn solid_blits() {
screen.blit(method.clone(), &bmp16, 196, 238);
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) {
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]
@ -808,11 +808,11 @@ fn solid_tinted_blits() {
screen.blit(method.clone(), &bmp16, 196, 238);
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) {
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]
@ -878,11 +878,11 @@ fn blended_solid_blits() {
screen.blit(method.clone(), &bmp16, 196, 238);
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) {
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]
@ -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: 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) {
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]
@ -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: 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) {
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]
@ -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: 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) {
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]
@ -1152,11 +1152,11 @@ fn transparent_blits() {
screen.blit(method.clone(), &bmp16, 196, 238);
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) {
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]
@ -1226,11 +1226,11 @@ fn transparent_tinted_blits() {
screen.blit(method.clone(), &bmp16, 196, 238);
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) {
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]
@ -1296,11 +1296,11 @@ fn blended_transparent_blits() {
screen.blit(method.clone(), &bmp16, 196, 238);
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) {
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]
@ -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: 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) {
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]
@ -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: 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) {
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]
@ -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: 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) {
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]
@ -1577,11 +1577,11 @@ fn transparent_single_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -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: 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) {
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]
@ -1714,11 +1714,11 @@ fn rotozoom_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -1785,11 +1785,11 @@ fn rotozoom_tinted_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -1854,11 +1854,11 @@ fn blended_rotozoom_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -1925,11 +1925,11 @@ fn rotozoom_transparent_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -1997,11 +1997,11 @@ fn rotozoom_transparent_tinted_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -2068,11 +2068,11 @@ fn blended_rotozoom_transparent_blits() {
screen.blit(method.clone(), &bmp, 196, 238);
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) {
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]
@ -2095,11 +2095,11 @@ fn blend_function_blend() {
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 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) {
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]
@ -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_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) {
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]
@ -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_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) {
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]
@ -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_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) {
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]
@ -2450,11 +2450,11 @@ fn triangle_2d() {
color,
});
let path = reference_file(Path::new("triangle_2d.png"));
let path = &reference_file("triangle_2d.png");
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)]
@ -2517,21 +2517,21 @@ fn get_quad(
},
],
TriangleType::SolidTextured => [
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_1, texcoord: texcoords_1, bitmap: texture.unwrap() },
RgbaTriangle2d::SolidTextured { position: positions_2, texcoord: texcoords_2, bitmap: texture.unwrap() },
],
TriangleType::SolidTexturedColored => [
RgbaTriangle2d::SolidTexturedColored {
position: positions_1,
texcoord: texcoords_1,
color: single_color,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
},
RgbaTriangle2d::SolidTexturedColored {
position: positions_2,
texcoord: texcoords_2,
color: single_color,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
},
],
TriangleType::SolidTexturedColoredBlended => [
@ -2539,14 +2539,14 @@ fn get_quad(
position: positions_1,
texcoord: texcoords_1,
color: single_color,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(128),
},
RgbaTriangle2d::SolidTexturedColoredBlended {
position: positions_2,
texcoord: texcoords_2,
color: single_color,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(128),
},
],
@ -2555,13 +2555,13 @@ fn get_quad(
position: positions_1,
texcoord: texcoords_1,
color: colors_1,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
},
RgbaTriangle2d::SolidTexturedMultiColored {
position: positions_2,
texcoord: texcoords_2,
color: colors_2,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
},
],
TriangleType::SolidTexturedMultiColoredBlended => [
@ -2569,14 +2569,14 @@ fn get_quad(
position: positions_1,
texcoord: texcoords_1,
color: colors_1,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(192),
},
RgbaTriangle2d::SolidTexturedMultiColoredBlended {
position: positions_2,
texcoord: texcoords_2,
color: colors_2,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(192),
},
],
@ -2584,13 +2584,13 @@ fn get_quad(
RgbaTriangle2d::SolidTexturedTinted {
position: positions_1,
texcoord: texcoords_1,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
tint: tint_color,
},
RgbaTriangle2d::SolidTexturedTinted {
position: positions_2,
texcoord: texcoords_2,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
tint: tint_color,
},
],
@ -2598,13 +2598,13 @@ fn get_quad(
RgbaTriangle2d::SolidTexturedBlended {
position: positions_1,
texcoord: texcoords_1,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(128),
},
RgbaTriangle2d::SolidTexturedBlended {
position: positions_2,
texcoord: texcoords_2,
bitmap: &texture.unwrap(),
bitmap: texture.unwrap(),
blend: BlendFunction::BlendSourceWithAlpha(128),
},
],
@ -2716,11 +2716,11 @@ fn triangle_2d_solid_blended() {
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) {
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]
@ -2729,11 +2729,11 @@ fn triangle_2d_solid_multicolor_blended() {
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) {
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]
@ -2745,11 +2745,11 @@ fn triangle_2d_solid_textured() {
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) {
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]
@ -2761,11 +2761,11 @@ fn triangle_2d_solid_textured_colored() {
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) {
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]
@ -2776,11 +2776,11 @@ fn triangle_2d_solid_textured_colored_blended() {
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) {
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]
@ -2792,11 +2792,11 @@ fn triangle_2d_solid_textured_multicolored() {
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) {
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]
@ -2807,11 +2807,11 @@ fn triangle_2d_solid_textured_multicolored_blended() {
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) {
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]
@ -2823,11 +2823,11 @@ fn triangle_2d_solid_textured_tinted() {
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) {
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]
@ -2838,9 +2838,9 @@ fn triangle_2d_solid_textured_blended() {
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) {
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 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)
}
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)
}
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 mut reader = BufReader::new(f);
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())
}
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 mut reader = BufReader::new(f);
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 {
fn handle_event(&mut self, event: &SystemEvent) -> bool {
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
// with imgui
let mut font = context.fonts();
let font = context.fonts();
let mut font_atlas_texture = font.build_rgba32_texture();
font.tex_id = texture_map.insert(
RgbaBitmap::from_bytes(

View file

@ -4,4 +4,4 @@
# 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
# here to get *some* peace of mind in terms of build stability.
channel = "nightly-2023-11-10"
channel = "nightly-2024-09-05"