address a number of cargo warnings and clippy lints

while also ignored some bullshit clippy lints
This commit is contained in:
Gered 2024-09-07 21:21:49 -04:00
parent 040e480dd0
commit 16eb66b219
35 changed files with 531 additions and 254 deletions

View file

@ -28,6 +28,7 @@ pub struct SineWaveGenerator {
t: usize,
}
#[allow(clippy::new_without_default)]
impl SineWaveGenerator {
pub fn new() -> Self {
SineWaveGenerator { t: 0 }
@ -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

@ -60,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;
@ -70,26 +69,22 @@ fn main() -> Result<()> {
ball.dir_x = -ball.dir_x;
ball.x = 0;
}
} else {
if 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 {
if ball.y <= 0 {
ball.dir_y = -ball.dir_y;
ball.y = 0;
}
} else {
if 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;
}
}
}
}
system.update()?;
system.res.video.clear(2);

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

@ -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,12 +85,13 @@ 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) {
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);
context.support.component_systems.update(&mut context.core);

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

@ -43,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);
@ -83,7 +83,7 @@ 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, "./assets/title_screen.map.json", 0.2, 1.0, 32);
@ -170,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);
}
@ -214,7 +214,7 @@ 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, "./assets/arena.map.json", 0.5, 2.0, 100);

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

@ -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::*;

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

@ -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;
}
}

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

@ -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

@ -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.")));
}
@ -593,8 +593,8 @@ impl RgbaBitmap {
writer,
self,
match format {
PngFormat::RGB => ColorFormat::RGB,
PngFormat::RGBA => ColorFormat::RGBA,
PngFormat::RGB => ColorFormat::Rgb,
PngFormat::RGBA => ColorFormat::Rgba,
},
None,
)

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

@ -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

@ -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)

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(())
}
@ -471,6 +469,12 @@ impl Palette {
}
}
impl Default for Palette {
fn default() -> Self {
Self::new()
}
}
impl Index<u8> for Palette {
type Output = RGBA;

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

@ -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

@ -217,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.

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

@ -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),
},
],

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(