convert RgbaBitmap to use ARGBu8x4 as its pixel type

This commit is contained in:
Gered 2023-05-04 18:54:37 -04:00
parent cf92d42b84
commit 09dbb913a5
38 changed files with 426 additions and 405 deletions

View file

@ -11,7 +11,7 @@ pub struct CoreContext {
pub delta: f32,
pub camera_x: i32,
pub camera_y: i32,
pub transparent_color: u32,
pub transparent_color: ARGBu8x4,
pub system: System<Standard>,
pub palette: Palette,
pub font: BitmaskFont,

View file

@ -63,7 +63,7 @@ impl TileMap {
tiles: &BitmapAtlas<RgbaBitmap>,
camera_x: i32,
camera_y: i32,
transparent_color: u32,
transparent_color: ARGBu8x4,
) {
let xt = camera_x / TILE_WIDTH as i32;
let yt = camera_y / TILE_HEIGHT as i32;

View file

@ -7,7 +7,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let height = 240;
let mut source = IndexedBitmap::new(width, height).unwrap();
let mut dest = vec![0u32; (width * height * 4) as usize].into_boxed_slice();
let mut dest = vec![ARGBu8x4::default(); (width * height) as usize].into_boxed_slice();
let palette = Palette::new_vga_palette().unwrap();
c.bench_function("deindex_bitmap_pixels", |b| b.iter(|| source.copy_as_argb_to(&mut dest, &palette)));

View file

@ -6,6 +6,10 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let width = 320;
let height = 240;
const BG_COLOR: ARGBu8x4 = ARGBu8x4::from_rgb([0, 0, 0]);
const SOLID_COLOR: ARGBu8x4 = ARGBu8x4::from_rgb([255, 0, 255]);
const BLEND_COLOR: ARGBu8x4 = ARGBu8x4::from_argb([127, 255, 0, 255]);
let mut dest = RgbaBitmap::new(width, height).unwrap();
// note that none of these are all-inclusive benchmarks that cover all kinds of different scenarios and such
@ -16,140 +20,142 @@ pub fn criterion_benchmark(c: &mut Criterion) {
// as i change other things in the future
c.bench_function("rgbabitmap_primitives_set_pixel", |b| {
dest.clear(0xff000000);
b.iter(|| dest.set_pixel(black_box(100), black_box(100), black_box(0xffff00ff)))
dest.clear(BG_COLOR);
b.iter(|| dest.set_pixel(black_box(100), black_box(100), black_box(SOLID_COLOR)))
});
c.bench_function("rgbabitmap_primitives_set_blended_pixel", |b| {
dest.clear(0xff000000);
dest.clear(BG_COLOR);
b.iter(|| {
dest.set_blended_pixel(
black_box(100),
black_box(100),
black_box(0x7fff00ff),
black_box(BLEND_COLOR),
black_box(BlendFunction::Blend),
)
})
});
c.bench_function("rgbabitmap_primitives_set_pixel_unchecked", |b| {
dest.clear(0xff000000);
b.iter(|| unsafe { dest.set_pixel_unchecked(black_box(100), black_box(100), black_box(0xffff00ff)) })
dest.clear(BG_COLOR);
b.iter(|| unsafe { dest.set_pixel_unchecked(black_box(100), black_box(100), black_box(SOLID_COLOR)) })
});
c.bench_function("rgbabitmap_primitives_set_blended_pixel_unchecked", |b| {
dest.clear(0xff000000);
dest.clear(BG_COLOR);
b.iter(|| unsafe {
dest.set_blended_pixel_unchecked(
black_box(100),
black_box(100),
black_box(0x7fff00ff),
black_box(BLEND_COLOR),
black_box(BlendFunction::Blend),
)
})
});
c.bench_function("rgbabitmap_primitives_line", |b| {
dest.clear(0xff000000);
b.iter(|| dest.line(black_box(10), black_box(50), black_box(310), black_box(120), black_box(0xffff00ff)))
dest.clear(BG_COLOR);
b.iter(|| dest.line(black_box(10), black_box(50), black_box(310), black_box(120), black_box(SOLID_COLOR)))
});
c.bench_function("rgbabitmap_primitives_blended_line", |b| {
dest.clear(0xff000000);
dest.clear(BG_COLOR);
b.iter(|| {
dest.blended_line(
black_box(10),
black_box(50),
black_box(310),
black_box(120),
black_box(0x7fff00ff),
black_box(BLEND_COLOR),
black_box(BlendFunction::Blend),
)
})
});
c.bench_function("rgbabitmap_primitives_horiz_line", |b| {
dest.clear(0xff000000);
b.iter(|| dest.horiz_line(black_box(10), black_box(310), black_box(70), black_box(0xffff00ff)))
dest.clear(BG_COLOR);
b.iter(|| dest.horiz_line(black_box(10), black_box(310), black_box(70), black_box(SOLID_COLOR)))
});
c.bench_function("rgbabitmap_primitives_blended_horiz_line", |b| {
dest.clear(0xff000000);
dest.clear(BG_COLOR);
b.iter(|| {
dest.blended_horiz_line(
black_box(10),
black_box(310),
black_box(70),
black_box(0x7fff00ff),
black_box(BLEND_COLOR),
black_box(BlendFunction::Blend),
)
})
});
c.bench_function("rgbabitmap_primitives_vert_line", |b| {
dest.clear(0xff000000);
b.iter(|| dest.vert_line(black_box(90), black_box(10), black_box(230), black_box(0xffff00ff)))
dest.clear(BG_COLOR);
b.iter(|| dest.vert_line(black_box(90), black_box(10), black_box(230), black_box(SOLID_COLOR)))
});
c.bench_function("rgbabitmap_primitives_blended_vert_line", |b| {
dest.clear(0xff000000);
dest.clear(BG_COLOR);
b.iter(|| {
dest.blended_vert_line(
black_box(90),
black_box(10),
black_box(230),
black_box(0x7fff00ff),
black_box(BLEND_COLOR),
black_box(BlendFunction::Blend),
)
})
});
c.bench_function("rgbabitmap_primitives_rect", |b| {
dest.clear(0xff000000);
b.iter(|| dest.rect(black_box(10), black_box(10), black_box(310), black_box(230), black_box(0xffff00ff)))
dest.clear(BG_COLOR);
b.iter(|| dest.rect(black_box(10), black_box(10), black_box(310), black_box(230), black_box(SOLID_COLOR)))
});
c.bench_function("rgbabitmap_primitives_blended_rect", |b| {
dest.clear(0xff000000);
dest.clear(BG_COLOR);
b.iter(|| {
dest.blended_rect(
black_box(10),
black_box(10),
black_box(310),
black_box(230),
black_box(0x7fff00ff),
black_box(BLEND_COLOR),
black_box(BlendFunction::Blend),
)
})
});
c.bench_function("rgbabitmap_primitives_filled_rect", |b| {
dest.clear(0xff000000);
b.iter(|| dest.filled_rect(black_box(10), black_box(10), black_box(310), black_box(230), black_box(0xffff00ff)))
dest.clear(BG_COLOR);
b.iter(|| {
dest.filled_rect(black_box(10), black_box(10), black_box(310), black_box(230), black_box(SOLID_COLOR))
})
});
c.bench_function("rgbabitmap_primitives_blended_filled_rect", |b| {
dest.clear(0xff000000);
dest.clear(BG_COLOR);
b.iter(|| {
dest.blended_filled_rect(
black_box(10),
black_box(10),
black_box(310),
black_box(230),
black_box(0x7fff00ff),
black_box(BLEND_COLOR),
black_box(BlendFunction::Blend),
)
})
});
c.bench_function("rgbabitmap_primitives_circle", |b| {
dest.clear(0xff000000);
b.iter(|| dest.circle(black_box(160), black_box(120), black_box(80), black_box(0xffff00ff)))
dest.clear(BG_COLOR);
b.iter(|| dest.circle(black_box(160), black_box(120), black_box(80), black_box(SOLID_COLOR)))
});
c.bench_function("rgbabitmap_primitives_filled_circle", |b| {
dest.clear(0xff000000);
b.iter(|| dest.filled_circle(black_box(160), black_box(120), black_box(80), black_box(0xffff00ff)))
dest.clear(BG_COLOR);
b.iter(|| dest.filled_circle(black_box(160), black_box(120), black_box(80), black_box(SOLID_COLOR)))
});
}

View file

@ -22,19 +22,20 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let texcoord_0_1 = Vector2::new(0.0, 1.0);
let texcoord_1_1 = Vector2::new(1.0, 1.0);
let color_1 = to_argb32([255, 255, 0, 0]);
let color_2 = to_argb32([255, 0, 255, 0]);
let color_3 = to_argb32([255, 0, 0, 255]);
let color = ARGBu8x4::from_rgb([255, 255, 255]);
let color_1 = ARGBu8x4::from_argb([255, 255, 0, 0]);
let color_2 = ARGBu8x4::from_argb([255, 0, 255, 0]);
let color_3 = ARGBu8x4::from_argb([255, 0, 0, 255]);
c.bench_function("rgbabitmap_triangle_2d_solid_color", |b| {
let triangle = RgbaTriangle2d::Solid { position: [big_v1, big_v2, big_v3], color: 5 };
let triangle = RgbaTriangle2d::Solid { position: [big_v1, big_v2, big_v3], color };
b.iter(|| {
dest.triangle_2d(black_box(&triangle));
})
});
c.bench_function("rgbabitmap_triangle_2d_solid_color_small", |b| {
let triangle = RgbaTriangle2d::Solid { position: [small_v1, small_v2, small_v3], color: 5 };
let triangle = RgbaTriangle2d::Solid { position: [small_v1, small_v2, small_v3], color };
b.iter(|| {
dest.triangle_2d(black_box(&triangle));
})

View file

@ -7,7 +7,7 @@
//! Only a subset of the most common Bitmap drawing operations will be provided here.
use crate::graphics::{
BitmapError, Font, FontRenderOpts, IndexedBitmap, IndexedBlitMethod, Pixel, RgbaBitmap, RgbaBlitMethod,
ARGBu8x4, BitmapError, Font, FontRenderOpts, IndexedBitmap, IndexedBlitMethod, Pixel, RgbaBitmap, RgbaBlitMethod,
};
use crate::math::Rect;
@ -220,7 +220,7 @@ impl GeneralBitmap for IndexedBitmap {
}
impl GeneralBitmap for RgbaBitmap {
type PixelType = u32;
type PixelType = ARGBu8x4;
#[inline]
fn new(width: u32, height: u32) -> Result<Self, BitmapError> {

View file

@ -1,6 +1,6 @@
use std::path::Path;
use crate::graphics::{Bitmap, BitmapError, Palette, RgbaBitmap};
use crate::graphics::{ARGBu8x4, Bitmap, BitmapError, Palette, RgbaBitmap};
mod blit;
mod primitives;
@ -51,7 +51,7 @@ impl IndexedBitmap {
///
/// * `dest`: destination 32-bit ARGB pixel buffer to copy converted pixels to
/// * `palette`: the 256 colour palette to use during pixel conversion
pub fn copy_as_argb_to(&self, dest: &mut [u32], palette: &Palette) {
pub fn copy_as_argb_to(&self, dest: &mut [ARGBu8x4], palette: &Palette) {
for (src, dest) in self.pixels().iter().zip(dest.iter_mut()) {
*dest = palette[*src];
}

View file

@ -5,7 +5,7 @@ use std::path::Path;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use thiserror::Error;
use crate::graphics::{from_rgb32, IndexedBitmap, Palette, PaletteError, PaletteFormat, RgbaBitmap};
use crate::graphics::{IndexedBitmap, Palette, PaletteError, PaletteFormat, RgbaBitmap};
use crate::utils::ReadFixedLengthByteArray;
#[derive(Error, Debug)]
@ -241,11 +241,10 @@ impl IndexedBitmap {
writer.write_u8(0xc)?;
for i in 0..=255 {
let argb = palette[i];
let [r, g, b] = from_rgb32(argb);
writer.write_u8(r)?;
writer.write_u8(g)?;
writer.write_u8(b)?;
let color = palette[i];
writer.write_u8(color.r())?;
writer.write_u8(color.g())?;
writer.write_u8(color.b())?;
}
Ok(())

View file

@ -7,10 +7,7 @@ use std::path::Path;
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use thiserror::Error;
use crate::graphics::{
from_argb32, from_rgb32, to_argb32, to_rgb32, Bitmap, IndexedBitmap, Palette, PaletteError, PaletteFormat, Pixel,
RgbaBitmap,
};
use crate::graphics::{ARGBu8x4, Bitmap, IndexedBitmap, Palette, PaletteError, PaletteFormat, Pixel, RgbaBitmap};
use crate::utils::ReadFixedLengthByteArray;
const PNG_HEADER: [u8; 8] = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];
@ -322,8 +319,8 @@ impl ScanlinePixelConverter<u8> for ScanlineBuffer {
}
}
impl ScanlinePixelConverter<u32> for ScanlineBuffer {
fn read_pixel(&mut self, x: usize, palette: &Option<Palette>) -> Result<u32, PngError> {
impl ScanlinePixelConverter<ARGBu8x4> for ScanlineBuffer {
fn read_pixel(&mut self, x: usize, palette: &Option<Palette>) -> Result<ARGBu8x4, PngError> {
let offset = x * self.bpp;
match self.format {
ColorFormat::IndexedColor => {
@ -340,35 +337,33 @@ impl ScanlinePixelConverter<u32> for ScanlineBuffer {
let r = self.current[offset];
let g = self.current[offset + 1];
let b = self.current[offset + 2];
Ok(to_rgb32([r, g, b]))
Ok(ARGBu8x4::from_rgb([r, g, b]))
}
ColorFormat::RGBA => {
let r = self.current[offset];
let g = self.current[offset + 1];
let b = self.current[offset + 2];
let a = self.current[offset + 3];
Ok(to_argb32([a, r, g, b]))
Ok(ARGBu8x4::from_argb([a, r, g, b]))
}
_ => Err(PngError::BadFile(format!("Unsupported color format for this PixelReader: {:?}", self.format))),
}
}
fn write_pixel(&mut self, x: usize, pixel: u32) -> Result<(), PngError> {
fn write_pixel(&mut self, x: usize, pixel: ARGBu8x4) -> Result<(), PngError> {
let offset = x * self.bpp;
match self.format {
ColorFormat::RGB => {
let [r, g, b] = from_rgb32(pixel);
self.current[offset] = r;
self.current[offset + 1] = g;
self.current[offset + 2] = b;
self.current[offset] = pixel.r();
self.current[offset + 1] = pixel.g();
self.current[offset + 2] = pixel.b();
Ok(())
}
ColorFormat::RGBA => {
let [a, r, g, b] = from_argb32(pixel);
self.current[offset] = r;
self.current[offset + 1] = g;
self.current[offset + 2] = b;
self.current[offset + 3] = a;
self.current[offset] = pixel.r();
self.current[offset + 1] = pixel.g();
self.current[offset + 2] = pixel.b();
self.current[offset + 3] = pixel.a();
Ok(())
}
_ => Err(PngError::BadFile(format!("Unsupported color format for this PixelReader: {:?}", self.format))),

View file

@ -1,6 +1,6 @@
use crate::graphics::{
clip_blit, per_pixel_blit, per_pixel_flipped_blit, per_pixel_rotozoom_blit, tint_argb32, BitmapAtlas,
BlendFunction, RgbaBitmap,
clip_blit, per_pixel_blit, per_pixel_flipped_blit, per_pixel_rotozoom_blit, ARGBu8x4, BitmapAtlas, BlendFunction,
RgbaBitmap,
};
use crate::math::Rect;
@ -8,7 +8,7 @@ use crate::math::Rect;
pub enum RgbaBlitMethod {
/// Solid blit, no transparency or other per-pixel adjustments.
Solid,
SolidTinted(u32),
SolidTinted(ARGBu8x4),
SolidBlended(BlendFunction),
/// Same as [RgbaBlitMethod::Solid] but the drawn image can also be flipped horizontally
/// and/or vertically.
@ -19,7 +19,7 @@ pub enum RgbaBlitMethod {
SolidFlippedTinted {
horizontal_flip: bool,
vertical_flip: bool,
tint_color: u32,
tint_color: ARGBu8x4,
},
SolidFlippedBlended {
horizontal_flip: bool,
@ -27,30 +27,30 @@ pub enum RgbaBlitMethod {
blend: BlendFunction,
},
/// Transparent blit, the specified source color pixels are skipped.
Transparent(u32),
Transparent(ARGBu8x4),
TransparentTinted {
transparent_color: u32,
tint_color: u32,
transparent_color: ARGBu8x4,
tint_color: ARGBu8x4,
},
TransparentBlended {
transparent_color: u32,
transparent_color: ARGBu8x4,
blend: BlendFunction,
},
/// Same as [RgbaBlitMethod::Transparent] but the drawn image can also be flipped horizontally
/// and/or vertically.
TransparentFlipped {
transparent_color: u32,
transparent_color: ARGBu8x4,
horizontal_flip: bool,
vertical_flip: bool,
},
TransparentFlippedTinted {
transparent_color: u32,
transparent_color: ARGBu8x4,
horizontal_flip: bool,
vertical_flip: bool,
tint_color: u32,
tint_color: ARGBu8x4,
},
TransparentFlippedBlended {
transparent_color: u32,
transparent_color: ARGBu8x4,
horizontal_flip: bool,
vertical_flip: bool,
blend: BlendFunction,
@ -58,15 +58,15 @@ pub enum RgbaBlitMethod {
/// Same as [RgbaBlitMethod::Transparent] except that the visible pixels on the destination are all
/// drawn using the same color.
TransparentSingle {
transparent_color: u32,
draw_color: u32,
transparent_color: ARGBu8x4,
draw_color: ARGBu8x4,
},
/// Combination of [RgbaBlitMethod::TransparentFlipped] and [RgbaBlitMethod::TransparentSingle].
TransparentFlippedSingle {
transparent_color: u32,
transparent_color: ARGBu8x4,
horizontal_flip: bool,
vertical_flip: bool,
draw_color: u32,
draw_color: ARGBu8x4,
},
/// Rotozoom blit, works the same as [RgbaBlitMethod::Solid] except that rotation and scaling is
/// performed.
@ -79,7 +79,7 @@ pub enum RgbaBlitMethod {
angle: f32,
scale_x: f32,
scale_y: f32,
tint_color: u32,
tint_color: ARGBu8x4,
},
RotoZoomBlended {
angle: f32,
@ -92,20 +92,20 @@ pub enum RgbaBlitMethod {
angle: f32,
scale_x: f32,
scale_y: f32,
transparent_color: u32,
transparent_color: ARGBu8x4,
},
RotoZoomTransparentTinted {
angle: f32,
scale_x: f32,
scale_y: f32,
transparent_color: u32,
tint_color: u32,
transparent_color: ARGBu8x4,
tint_color: ARGBu8x4,
},
RotoZoomTransparentBlended {
angle: f32,
scale_x: f32,
scale_y: f32,
transparent_color: u32,
transparent_color: ARGBu8x4,
blend: BlendFunction,
},
}
@ -117,7 +117,7 @@ impl RgbaBitmap {
src_region: &Rect,
dest_x: i32,
dest_y: i32,
tint_color: u32,
tint_color: ARGBu8x4,
) {
per_pixel_blit(
self, //
@ -126,7 +126,7 @@ impl RgbaBitmap {
dest_x,
dest_y,
|src_pixels, dest_pixels| {
*dest_pixels = tint_argb32(*src_pixels, tint_color);
*dest_pixels = (*src_pixels).tint(tint_color);
},
);
}
@ -146,7 +146,7 @@ impl RgbaBitmap {
dest_x,
dest_y,
|src_pixels, dest_pixels| {
*dest_pixels = blend.blend_1u32(*src_pixels, *dest_pixels);
*dest_pixels = blend.blend(*src_pixels, *dest_pixels);
},
);
}
@ -170,7 +170,7 @@ impl RgbaBitmap {
horizontal_flip,
vertical_flip,
|src_pixels, dest_pixels| {
*dest_pixels = blend.blend_1u32(*src_pixels, *dest_pixels);
*dest_pixels = blend.blend(*src_pixels, *dest_pixels);
},
);
}
@ -183,7 +183,7 @@ impl RgbaBitmap {
dest_y: i32,
horizontal_flip: bool,
vertical_flip: bool,
tint_color: u32,
tint_color: ARGBu8x4,
) {
per_pixel_flipped_blit(
self, //
@ -194,7 +194,7 @@ impl RgbaBitmap {
horizontal_flip,
vertical_flip,
|src_pixels, dest_pixels| {
*dest_pixels = tint_argb32(*src_pixels, tint_color);
*dest_pixels = (*src_pixels).tint(tint_color);
},
);
}
@ -205,8 +205,8 @@ impl RgbaBitmap {
src_region: &Rect,
dest_x: i32,
dest_y: i32,
transparent_color: u32,
tint_color: u32,
transparent_color: ARGBu8x4,
tint_color: ARGBu8x4,
) {
per_pixel_blit(
self, //
@ -216,7 +216,7 @@ impl RgbaBitmap {
dest_y,
|src_pixels, dest_pixels| {
if *src_pixels != transparent_color {
*dest_pixels = tint_argb32(*src_pixels, tint_color);
*dest_pixels = (*src_pixels).tint(tint_color);
}
},
);
@ -228,7 +228,7 @@ impl RgbaBitmap {
src_region: &Rect,
dest_x: i32,
dest_y: i32,
transparent_color: u32,
transparent_color: ARGBu8x4,
blend: BlendFunction,
) {
per_pixel_blit(
@ -239,7 +239,7 @@ impl RgbaBitmap {
dest_y,
|src_pixels, dest_pixels| {
if *src_pixels != transparent_color {
*dest_pixels = blend.blend_1u32(*src_pixels, *dest_pixels);
*dest_pixels = blend.blend(*src_pixels, *dest_pixels);
}
},
);
@ -251,10 +251,10 @@ impl RgbaBitmap {
src_region: &Rect,
dest_x: i32,
dest_y: i32,
transparent_color: u32,
transparent_color: ARGBu8x4,
horizontal_flip: bool,
vertical_flip: bool,
tint_color: u32,
tint_color: ARGBu8x4,
) {
per_pixel_flipped_blit(
self, //
@ -266,7 +266,7 @@ impl RgbaBitmap {
vertical_flip,
|src_pixels, dest_pixels| {
if *src_pixels != transparent_color {
*dest_pixels = tint_argb32(*src_pixels, tint_color);
*dest_pixels = (*src_pixels).tint(tint_color);
}
},
);
@ -278,7 +278,7 @@ impl RgbaBitmap {
src_region: &Rect,
dest_x: i32,
dest_y: i32,
transparent_color: u32,
transparent_color: ARGBu8x4,
horizontal_flip: bool,
vertical_flip: bool,
blend: BlendFunction,
@ -293,7 +293,7 @@ impl RgbaBitmap {
vertical_flip,
|src_pixels, dest_pixels| {
if *src_pixels != transparent_color {
*dest_pixels = blend.blend_1u32(*src_pixels, *dest_pixels);
*dest_pixels = blend.blend(*src_pixels, *dest_pixels);
}
},
);
@ -308,7 +308,7 @@ impl RgbaBitmap {
angle: f32,
scale_x: f32,
scale_y: f32,
tint_color: u32,
tint_color: ARGBu8x4,
) {
per_pixel_rotozoom_blit(
self, //
@ -320,7 +320,7 @@ impl RgbaBitmap {
scale_x,
scale_y,
|src_pixel, dest_bitmap, draw_x, draw_y| {
dest_bitmap.set_pixel(draw_x, draw_y, tint_argb32(src_pixel, tint_color));
dest_bitmap.set_pixel(draw_x, draw_y, src_pixel.tint(tint_color));
},
);
}
@ -347,7 +347,7 @@ impl RgbaBitmap {
scale_y,
|src_pixel, dest_bitmap, draw_x, draw_y| {
if let Some(dest_pixel) = dest_bitmap.get_pixel(draw_x, draw_y) {
dest_bitmap.set_pixel(draw_x, draw_y, blend.blend_1u32(src_pixel, dest_pixel))
dest_bitmap.set_pixel(draw_x, draw_y, blend.blend(src_pixel, dest_pixel))
}
},
);
@ -362,8 +362,8 @@ impl RgbaBitmap {
angle: f32,
scale_x: f32,
scale_y: f32,
transparent_color: u32,
tint_color: u32,
transparent_color: ARGBu8x4,
tint_color: ARGBu8x4,
) {
per_pixel_rotozoom_blit(
self, //
@ -376,7 +376,7 @@ impl RgbaBitmap {
scale_y,
|src_pixel, dest_bitmap, draw_x, draw_y| {
if transparent_color != src_pixel {
dest_bitmap.set_pixel(draw_x, draw_y, tint_argb32(src_pixel, tint_color));
dest_bitmap.set_pixel(draw_x, draw_y, src_pixel.tint(tint_color));
}
},
);
@ -391,7 +391,7 @@ impl RgbaBitmap {
angle: f32,
scale_x: f32,
scale_y: f32,
transparent_color: u32,
transparent_color: ARGBu8x4,
blend: BlendFunction,
) {
per_pixel_rotozoom_blit(
@ -406,7 +406,7 @@ impl RgbaBitmap {
|src_pixel, dest_bitmap, draw_x, draw_y| {
if transparent_color != src_pixel {
if let Some(dest_pixel) = dest_bitmap.get_pixel(draw_x, draw_y) {
dest_bitmap.set_pixel(draw_x, draw_y, blend.blend_1u32(src_pixel, dest_pixel))
dest_bitmap.set_pixel(draw_x, draw_y, blend.blend(src_pixel, dest_pixel))
}
}
},

View file

@ -1,7 +1,7 @@
use byteorder::ReadBytesExt;
use std::path::Path;
use crate::graphics::{to_argb32, to_rgb32, Bitmap, BitmapError, Palette};
use crate::graphics::{ARGBu8x4, Bitmap, BitmapError, Palette};
mod blit;
mod primitives;
@ -11,7 +11,7 @@ pub use blit::*;
pub use primitives::*;
pub use triangles::*;
pub type RgbaBitmap = Bitmap<u32>;
pub type RgbaBitmap = Bitmap<ARGBu8x4>;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum RgbaPixelFormat {
@ -29,7 +29,7 @@ impl RgbaBitmap {
///
/// returns: `Result<Bitmap, BitmapError>`
pub fn new(width: u32, height: u32) -> Result<Self, BitmapError> {
Self::internal_new(width, height, to_rgb32([0, 0, 0]))
Self::internal_new(width, height, ARGBu8x4::from_rgb([0, 0, 0]))
}
pub fn from_bytes<T: ReadBytesExt>(
@ -38,7 +38,7 @@ impl RgbaBitmap {
format: RgbaPixelFormat,
reader: &mut T,
) -> Result<Self, BitmapError> {
let mut bitmap = Self::internal_new(width, height, 0)?;
let mut bitmap = Self::internal_new(width, height, ARGBu8x4::from_rgb([0, 0, 0]))?;
for pixel in bitmap.pixels_mut().iter_mut() {
*pixel = match format {
RgbaPixelFormat::RGBA => {
@ -46,14 +46,14 @@ impl RgbaBitmap {
let g = reader.read_u8()?;
let b = reader.read_u8()?;
let a = reader.read_u8()?;
to_argb32([a, r, g, b])
ARGBu8x4::from_argb([a, r, g, b])
}
RgbaPixelFormat::ARGB => {
let a = reader.read_u8()?;
let r = reader.read_u8()?;
let g = reader.read_u8()?;
let b = reader.read_u8()?;
to_argb32([a, r, g, b])
ARGBu8x4::from_argb([a, r, g, b])
}
};
}

View file

@ -1,14 +1,14 @@
use crate::graphics::{BlendFunction, RgbaBitmap};
use crate::graphics::{ARGBu8x4, BlendFunction, RgbaBitmap};
impl RgbaBitmap {
/// Sets the pixel at the given coordinates using a blended color via the specified blend function
/// If the coordinates lie outside of the bitmaps clipping region, no pixels will be changed.
#[inline]
pub fn set_blended_pixel(&mut self, x: i32, y: i32, color: u32, blend: BlendFunction) {
pub fn set_blended_pixel(&mut self, x: i32, y: i32, color: ARGBu8x4, blend: BlendFunction) {
self.set_custom_pixel(
x, //
y,
|dest_color| blend.blend_1u32(color, dest_color),
|dest_color| blend.blend(color, dest_color),
);
}
@ -16,47 +16,47 @@ impl RgbaBitmap {
/// The 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: u32, blend: BlendFunction) {
pub unsafe fn set_blended_pixel_unchecked(&mut self, x: i32, y: i32, color: ARGBu8x4, blend: BlendFunction) {
self.set_custom_pixel_unchecked(
x, //
y,
|dest_color| blend.blend_1u32(color, dest_color),
|dest_color| blend.blend(color, dest_color),
);
}
/// Draws a line from x1,y1 to x2,y2 by blending the drawn pixels using the given blend function.
#[inline]
pub fn blended_line(&mut self, x1: i32, y1: i32, x2: i32, y2: i32, color: u32, blend: BlendFunction) {
pub fn blended_line(&mut self, x1: i32, y1: i32, x2: i32, y2: i32, color: ARGBu8x4, blend: BlendFunction) {
self.line_custom(
x1, //
y1,
x2,
y2,
|dest_color| blend.blend_1u32(color, dest_color),
|dest_color| blend.blend(color, dest_color),
);
}
/// Draws a horizontal line from x1,y to x2,y by blending the drawn pixels using the given
/// blend function.
#[inline]
pub fn blended_horiz_line(&mut self, x1: i32, x2: i32, y: i32, color: u32, blend: BlendFunction) {
pub fn blended_horiz_line(&mut self, x1: i32, x2: i32, y: i32, color: ARGBu8x4, blend: BlendFunction) {
self.horiz_line_custom(
x1, //
x2,
y,
|dest_color| blend.blend_1u32(color, dest_color),
|dest_color| blend.blend(color, dest_color),
);
}
/// Draws a vertical line from x,y1 to x,y2 by blending the drawn pixels using the given blend
/// function.
#[inline]
pub fn blended_vert_line(&mut self, x: i32, y1: i32, y2: i32, color: u32, blend: BlendFunction) {
pub fn blended_vert_line(&mut self, x: i32, y1: i32, y2: i32, color: ARGBu8x4, blend: BlendFunction) {
self.vert_line_custom(
x, //
y1,
y2,
|dest_color| blend.blend_1u32(color, dest_color),
|dest_color| blend.blend(color, dest_color),
);
}
@ -64,13 +64,13 @@ impl RgbaBitmap {
/// drawn, assuming they are specifying the top-left and bottom-right corners respectively.
/// The box is drawn by blending the drawn pixels using the given blend function.
#[inline]
pub fn blended_rect(&mut self, x1: i32, y1: i32, x2: i32, y2: i32, color: u32, blend: BlendFunction) {
pub fn blended_rect(&mut self, x1: i32, y1: i32, x2: i32, y2: i32, color: ARGBu8x4, blend: BlendFunction) {
self.rect_custom(
x1, //
y1,
x2,
y2,
|dest_color| blend.blend_1u32(color, dest_color),
|dest_color| blend.blend(color, dest_color),
);
}
@ -78,13 +78,13 @@ impl RgbaBitmap {
/// drawn, assuming they are specifying the top-left and bottom-right corners respectively. The
/// filled box is draw by blending the drawn pixels using the given blend function.
#[inline]
pub fn blended_filled_rect(&mut self, x1: i32, y1: i32, x2: i32, y2: i32, color: u32, blend: BlendFunction) {
pub fn blended_filled_rect(&mut self, x1: i32, y1: i32, x2: i32, y2: i32, color: ARGBu8x4, blend: BlendFunction) {
self.filled_rect_custom(
x1, //
y1,
x2,
y2,
|dest_color| blend.blend_1u32(color, dest_color),
|dest_color| blend.blend(color, dest_color),
);
}
}

View file

@ -1,29 +1,26 @@
use std::simd;
use crate::graphics::{
edge_function, from_argb32_simd, from_rgb32_simd, multiply_argb_simd, per_pixel_triangle_2d, tint_argb_simd,
to_argb32_simd, to_rgb32_simd, BlendFunction, RgbaBitmap,
};
use crate::graphics::{edge_function, per_pixel_triangle_2d, ARGBu8x4, BlendFunction, RgbaBitmap};
use crate::math::Vector2;
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum RgbaTriangle2d<'a> {
Solid {
position: [Vector2; 3], //
color: u32,
color: ARGBu8x4,
},
SolidBlended {
position: [Vector2; 3], //
color: u32,
color: ARGBu8x4,
blend: BlendFunction,
},
SolidMultiColor {
position: [Vector2; 3], //
color: [u32; 3],
color: [ARGBu8x4; 3],
},
SolidMultiColorBlended {
position: [Vector2; 3], //
color: [u32; 3],
color: [ARGBu8x4; 3],
blend: BlendFunction,
},
SolidTextured {
@ -34,26 +31,26 @@ pub enum RgbaTriangle2d<'a> {
SolidTexturedColored {
position: [Vector2; 3], //
texcoord: [Vector2; 3],
color: u32,
color: ARGBu8x4,
bitmap: &'a RgbaBitmap,
},
SolidTexturedColoredBlended {
position: [Vector2; 3], //
texcoord: [Vector2; 3],
color: u32,
color: ARGBu8x4,
bitmap: &'a RgbaBitmap,
blend: BlendFunction,
},
SolidTexturedMultiColored {
position: [Vector2; 3], //
texcoord: [Vector2; 3],
color: [u32; 3],
color: [ARGBu8x4; 3],
bitmap: &'a RgbaBitmap,
},
SolidTexturedMultiColoredBlended {
position: [Vector2; 3], //
texcoord: [Vector2; 3],
color: [u32; 3],
color: [ARGBu8x4; 3],
bitmap: &'a RgbaBitmap,
blend: BlendFunction,
},
@ -61,7 +58,7 @@ pub enum RgbaTriangle2d<'a> {
position: [Vector2; 3], //
texcoord: [Vector2; 3],
bitmap: &'a RgbaBitmap,
tint: u32,
tint: ARGBu8x4,
},
SolidTexturedBlended {
position: [Vector2; 3], //
@ -72,7 +69,7 @@ pub enum RgbaTriangle2d<'a> {
}
impl RgbaBitmap {
pub fn solid_triangle_2d(&mut self, positions: &[Vector2; 3], color: u32) {
pub fn solid_triangle_2d(&mut self, positions: &[Vector2; 3], color: ARGBu8x4) {
per_pixel_triangle_2d(
self, //
positions[0],
@ -82,24 +79,21 @@ impl RgbaBitmap {
)
}
pub fn solid_blended_triangle_2d(&mut self, positions: &[Vector2; 3], color: u32, blend: BlendFunction) {
let color = from_argb32_simd(color);
pub fn solid_blended_triangle_2d(&mut self, positions: &[Vector2; 3], color: ARGBu8x4, blend: BlendFunction) {
per_pixel_triangle_2d(
self, //
positions[0],
positions[1],
positions[2],
|dest_pixels, _w0, _w1, _w2| {
*dest_pixels = to_argb32_simd(blend.blend_simd(color, from_argb32_simd(*dest_pixels)))
},
|dest_pixels, _w0, _w1, _w2| *dest_pixels = blend.blend(color, *dest_pixels),
)
}
pub fn solid_multicolor_triangle_2d(&mut self, positions: &[Vector2; 3], colors: &[u32; 3]) {
pub fn solid_multicolor_triangle_2d(&mut self, positions: &[Vector2; 3], colors: &[ARGBu8x4; 3]) {
let area = simd::f32x4::splat(edge_function(positions[0], positions[1], positions[2]));
let color1 = from_rgb32_simd(colors[0]).cast();
let color2 = from_rgb32_simd(colors[1]).cast();
let color3 = from_rgb32_simd(colors[2]).cast();
let color1 = colors[0].0.cast();
let color2 = colors[1].0.cast();
let color3 = colors[2].0.cast();
per_pixel_triangle_2d(
self, //
positions[0],
@ -111,7 +105,7 @@ impl RgbaBitmap {
+ simd::f32x4::splat(w2) * color3)
/ area)
.cast();
*dest_pixels = to_rgb32_simd(color)
*dest_pixels = ARGBu8x4(color)
},
)
}
@ -119,13 +113,13 @@ impl RgbaBitmap {
pub fn solid_multicolor_blended_triangle_2d(
&mut self,
positions: &[Vector2; 3],
colors: &[u32; 3],
colors: &[ARGBu8x4; 3],
blend: BlendFunction,
) {
let area = simd::f32x4::splat(edge_function(positions[0], positions[1], positions[2]));
let color1 = from_argb32_simd(colors[0]).cast();
let color2 = from_argb32_simd(colors[1]).cast();
let color3 = from_argb32_simd(colors[2]).cast();
let color1 = colors[0].0.cast();
let color2 = colors[1].0.cast();
let color3 = colors[2].0.cast();
per_pixel_triangle_2d(
self, //
positions[0],
@ -137,7 +131,7 @@ impl RgbaBitmap {
+ simd::f32x4::splat(w2) * color3)
/ area)
.cast();
*dest_pixels = to_argb32_simd(blend.blend_simd(color, from_argb32_simd(*dest_pixels)))
*dest_pixels = blend.blend(ARGBu8x4(color), *dest_pixels)
},
)
}
@ -166,11 +160,10 @@ impl RgbaBitmap {
&mut self,
positions: &[Vector2; 3],
texcoords: &[Vector2; 3],
color: u32,
color: ARGBu8x4,
bitmap: &Self,
) {
let area = simd::f32x2::splat(edge_function(positions[0], positions[1], positions[2]));
let color = from_argb32_simd(color);
let texcoord1 = simd::f32x2::from_array([texcoords[0].x, texcoords[0].y]);
let texcoord2 = simd::f32x2::from_array([texcoords[1].x, texcoords[1].y]);
let texcoord3 = simd::f32x2::from_array([texcoords[2].x, texcoords[2].y]);
@ -184,8 +177,8 @@ impl RgbaBitmap {
+ simd::f32x2::splat(w1) * texcoord2
+ simd::f32x2::splat(w2) * texcoord3)
/ area;
let texel = from_argb32_simd(bitmap.sample_at(texcoord[0], texcoord[1]));
*dest_pixels = to_argb32_simd(multiply_argb_simd(texel, color))
let texel = bitmap.sample_at(texcoord[0], texcoord[1]);
*dest_pixels = texel * color
},
)
}
@ -194,12 +187,11 @@ impl RgbaBitmap {
&mut self,
positions: &[Vector2; 3],
texcoords: &[Vector2; 3],
color: u32,
color: ARGBu8x4,
bitmap: &Self,
blend: BlendFunction,
) {
let area = simd::f32x2::splat(edge_function(positions[0], positions[1], positions[2]));
let color = from_argb32_simd(color);
let texcoord1 = simd::f32x2::from_array([texcoords[0].x, texcoords[0].y]);
let texcoord2 = simd::f32x2::from_array([texcoords[1].x, texcoords[1].y]);
let texcoord3 = simd::f32x2::from_array([texcoords[2].x, texcoords[2].y]);
@ -213,9 +205,9 @@ impl RgbaBitmap {
+ simd::f32x2::splat(w1) * texcoord2
+ simd::f32x2::splat(w2) * texcoord3)
/ area;
let texel = from_argb32_simd(bitmap.sample_at(texcoord[0], texcoord[1]));
let src = multiply_argb_simd(texel, color);
*dest_pixels = to_argb32_simd(blend.blend_simd(src, from_argb32_simd(*dest_pixels)))
let texel = bitmap.sample_at(texcoord[0], texcoord[1]);
let src = texel * color;
*dest_pixels = blend.blend(src, *dest_pixels)
},
)
}
@ -224,13 +216,13 @@ impl RgbaBitmap {
&mut self,
positions: &[Vector2; 3],
texcoords: &[Vector2; 3],
colors: &[u32; 3],
colors: &[ARGBu8x4; 3],
bitmap: &Self,
) {
let area = simd::f32x4::splat(edge_function(positions[0], positions[1], positions[2]));
let color1 = from_rgb32_simd(colors[0]).cast();
let color2 = from_rgb32_simd(colors[1]).cast();
let color3 = from_rgb32_simd(colors[2]).cast();
let color1 = colors[0].0.cast();
let color2 = colors[1].0.cast();
let color3 = colors[2].0.cast();
// we are using a f32x4 here with two zero's at the end as dummy values just so that we can
// do the texture coordinate interpolation in the inner loop as f32x4 operations.
// however, for the texture coordinates, we only care about the first two lanes in the results ...
@ -248,8 +240,8 @@ impl RgbaBitmap {
let w2 = simd::f32x4::splat(w2);
let color = ((w0 * color1 + w1 * color2 + w2 * color3) / area).cast::<u8>();
let texcoord = (w0 * texcoord1 + w1 * texcoord2 + w2 * texcoord3) / area;
let texel = from_argb32_simd(bitmap.sample_at(texcoord[0], texcoord[1]));
*dest_pixels = to_rgb32_simd(multiply_argb_simd(texel, color))
let texel = bitmap.sample_at(texcoord[0], texcoord[1]);
*dest_pixels = texel * ARGBu8x4(color)
},
)
}
@ -258,14 +250,14 @@ impl RgbaBitmap {
&mut self,
positions: &[Vector2; 3],
texcoords: &[Vector2; 3],
colors: &[u32; 3],
colors: &[ARGBu8x4; 3],
bitmap: &Self,
blend: BlendFunction,
) {
let area = simd::f32x4::splat(edge_function(positions[0], positions[1], positions[2]));
let color1 = from_argb32_simd(colors[0]).cast();
let color2 = from_argb32_simd(colors[1]).cast();
let color3 = from_argb32_simd(colors[2]).cast();
let color1 = colors[0].0.cast();
let color2 = colors[1].0.cast();
let color3 = colors[2].0.cast();
// we are using a f32x4 here with two zero's at the end as dummy values just so that we can
// do the texture coordinate interpolation in the inner loop as f32x4 operations.
// however, for the texture coordinates, we only care about the first two lanes in the results ...
@ -283,10 +275,9 @@ impl RgbaBitmap {
let w2 = simd::f32x4::splat(w2);
let color = ((w0 * color1 + w1 * color2 + w2 * color3) / area).cast::<u8>();
let texcoord = (w0 * texcoord1 + w1 * texcoord2 + w2 * texcoord3) / area;
let texel = from_argb32_simd(bitmap.sample_at(texcoord[0], texcoord[1]));
let src = multiply_argb_simd(texel, color);
let dest = from_argb32_simd(*dest_pixels);
*dest_pixels = to_argb32_simd(blend.blend_simd(src, dest))
let texel = bitmap.sample_at(texcoord[0], texcoord[1]);
let src = texel * ARGBu8x4(color);
*dest_pixels = blend.blend(src, *dest_pixels)
},
)
}
@ -296,10 +287,9 @@ impl RgbaBitmap {
positions: &[Vector2; 3],
texcoords: &[Vector2; 3],
bitmap: &Self,
tint: u32,
tint: ARGBu8x4,
) {
let area = simd::f32x2::splat(edge_function(positions[0], positions[1], positions[2]));
let tint = from_argb32_simd(tint);
let texcoord1 = simd::f32x2::from_array([texcoords[0].x, texcoords[0].y]);
let texcoord2 = simd::f32x2::from_array([texcoords[1].x, texcoords[1].y]);
let texcoord3 = simd::f32x2::from_array([texcoords[2].x, texcoords[2].y]);
@ -313,8 +303,8 @@ impl RgbaBitmap {
+ simd::f32x2::splat(w1) * texcoord2
+ simd::f32x2::splat(w2) * texcoord3)
/ area;
let texel = from_argb32_simd(bitmap.sample_at(texcoord[0], texcoord[1]));
*dest_pixels = to_argb32_simd(tint_argb_simd(texel, tint));
let texel = bitmap.sample_at(texcoord[0], texcoord[1]);
*dest_pixels = texel.tint(tint);
},
)
}
@ -340,8 +330,8 @@ impl RgbaBitmap {
+ simd::f32x2::splat(w1) * texcoord2
+ simd::f32x2::splat(w2) * texcoord3)
/ area;
let texel = from_argb32_simd(bitmap.sample_at(texcoord[0], texcoord[1]));
*dest_pixels = to_argb32_simd(blend.blend_simd(texel, from_argb32_simd(*dest_pixels)));
let texel = bitmap.sample_at(texcoord[0], texcoord[1]);
*dest_pixels = blend.blend(texel, *dest_pixels);
},
)
}

View file

@ -5,7 +5,7 @@ use std::path::Path;
use byteorder::{ReadBytesExt, WriteBytesExt};
use thiserror::Error;
use crate::graphics::{from_rgb32, luminance, Palette};
use crate::graphics::Palette;
use crate::math::lerp;
use crate::utils::ReadFixedLengthByteArray;
@ -76,8 +76,7 @@ impl BlendMap {
let mut blend_map = Self::new(source_color, source_color);
for idx in 0..=255 {
let rgb = from_rgb32(palette[idx]);
let lit = (luminance(rgb) * 255.0) as u8;
let lit = (palette[idx].luminance() * 255.0) as u8;
blend_map
.set_mapping(
source_color,
@ -105,11 +104,9 @@ impl BlendMap {
let mut blend_map = BlendMap::new(0, 255);
for source_color in 0..=255 {
let source_rgb = from_rgb32(palette[source_color]);
let source_luminance = luminance(source_rgb);
let source_luminance = palette[source_color].luminance();
for dest_color in 0..=255 {
let dest_rgb = from_rgb32(palette[dest_color]);
let destination_luminance = luminance(dest_rgb);
let destination_luminance = palette[dest_color].luminance();
let weight = (f(source_luminance, destination_luminance) * 255.0) as u8;
blend_map
.set_mapping(
@ -135,10 +132,10 @@ impl BlendMap {
pub fn new_translucency_map(blend_r: f32, blend_g: f32, blend_b: f32, palette: &Palette) -> Self {
let mut blend_map = BlendMap::new(0, 255);
for source in 0..=255 {
let [source_r, source_g, source_b] = from_rgb32(palette[source]);
let [_, source_r, source_g, source_b] = palette[source].to_array();
let mapping = blend_map.get_mapping_mut(source).unwrap();
for dest in 0..=255 {
let [dest_r, dest_g, dest_b] = from_rgb32(palette[dest]);
let [_, dest_r, dest_g, dest_b] = palette[dest].to_array();
let find_r = lerp(dest_r as f32, source_r as f32, blend_r) as u8;
let find_g = lerp(dest_g as f32, source_g as f32, blend_g) as u8;

View file

@ -1,6 +1,10 @@
use std::ops::{Mul, MulAssign};
use std::simd;
use byteorder::{ReadBytesExt, WriteBytesExt};
use crate::utils::{ReadType, WriteType};
/// Packed 32-bit color, in the format: 0xAARRGGBB
pub type Color1u32 = u32;
@ -24,36 +28,36 @@ pub type SimdColor4f32 = simd::f32x4;
// these colours are taken from the default VGA palette
pub const COLOR_BLACK: Color1u32 = 0xff000000;
pub const COLOR_BLUE: Color1u32 = 0xff0000aa;
pub const COLOR_GREEN: Color1u32 = 0xff00aa00;
pub const COLOR_CYAN: Color1u32 = 0xff00aaaa;
pub const COLOR_RED: Color1u32 = 0xffaa0000;
pub const COLOR_MAGENTA: Color1u32 = 0xffaa00aa;
pub const COLOR_BROWN: Color1u32 = 0xffaa5500;
pub const COLOR_LIGHT_GRAY: Color1u32 = 0xffaaaaaa;
pub const COLOR_DARK_GRAY: Color1u32 = 0xff555555;
pub const COLOR_BRIGHT_BLUE: Color1u32 = 0xff5555ff;
pub const COLOR_BRIGHT_GREEN: Color1u32 = 0xff55ff55;
pub const COLOR_BRIGHT_CYAN: Color1u32 = 0xff55ffff;
pub const COLOR_BRIGHT_RED: Color1u32 = 0xffff5555;
pub const COLOR_BRIGHT_MAGENTA: Color1u32 = 0xffff55ff;
pub const COLOR_BRIGHT_YELLOW: Color1u32 = 0xffffff55;
pub const COLOR_BRIGHT_WHITE: Color1u32 = 0xffffffff;
pub const COLOR_BLACK: ARGBu8x4 = ARGBu8x4::from_rgb([0, 0, 0]);
pub const COLOR_BLUE: ARGBu8x4 = ARGBu8x4::from_rgb([0, 0, 170]);
pub const COLOR_GREEN: ARGBu8x4 = ARGBu8x4::from_rgb([0, 170, 0]);
pub const COLOR_CYAN: ARGBu8x4 = ARGBu8x4::from_rgb([0, 170, 170]);
pub const COLOR_RED: ARGBu8x4 = ARGBu8x4::from_rgb([170, 0, 0]);
pub const COLOR_MAGENTA: ARGBu8x4 = ARGBu8x4::from_rgb([170, 0, 170]);
pub const COLOR_BROWN: ARGBu8x4 = ARGBu8x4::from_rgb([170, 85, 0]);
pub const COLOR_LIGHT_GRAY: ARGBu8x4 = ARGBu8x4::from_rgb([170, 170, 170]);
pub const COLOR_DARK_GRAY: ARGBu8x4 = ARGBu8x4::from_rgb([85, 85, 85]);
pub const COLOR_BRIGHT_BLUE: ARGBu8x4 = ARGBu8x4::from_rgb([85, 85, 255]);
pub const COLOR_BRIGHT_GREEN: ARGBu8x4 = ARGBu8x4::from_rgb([85, 255, 85]);
pub const COLOR_BRIGHT_CYAN: ARGBu8x4 = ARGBu8x4::from_rgb([85, 255, 255]);
pub const COLOR_BRIGHT_RED: ARGBu8x4 = ARGBu8x4::from_rgb([255, 85, 85]);
pub const COLOR_BRIGHT_MAGENTA: ARGBu8x4 = ARGBu8x4::from_rgb([255, 85, 255]);
pub const COLOR_BRIGHT_YELLOW: ARGBu8x4 = ARGBu8x4::from_rgb([255, 255, 85]);
pub const COLOR_BRIGHT_WHITE: ARGBu8x4 = ARGBu8x4::from_rgb([255, 255, 255]);
// TODO: probably should name these better, after i do much more reading on the subject :-)
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum BlendFunction {
Blend,
BlendSourceWithAlpha(u8),
TintedBlend(Color1u32),
MultipliedBlend(Color1u32),
TintedBlend(ARGBu8x4),
MultipliedBlend(ARGBu8x4),
}
impl BlendFunction {
#[inline]
/// Blends the source and destination color together using the function associated with
/// this enum value. Both colors should be 32-bit packed colors in the format 0xAARRGGBB.
/// this enum value.
///
/// # Arguments
///
@ -61,35 +65,13 @@ impl BlendFunction {
/// * `dest`: the destination color to blend the source color over
///
/// returns: the blended color
pub fn blend_1u32(&self, src: Color1u32, dest: Color1u32) -> Color1u32 {
pub fn blend(&self, src: ARGBu8x4, dest: ARGBu8x4) -> ARGBu8x4 {
use BlendFunction::*;
match self {
Blend => blend_argb32(src, dest),
BlendSourceWithAlpha(opacity) => blend_argb32_source_by(src, dest, *opacity),
TintedBlend(tint) => tinted_blend_argb32(*tint, src, dest),
MultipliedBlend(color) => multiplied_blend_argb32(*color, src, dest),
}
}
#[inline]
pub fn blend_4u8(&self, src: Color4u8, dest: Color4u8) -> Color4u8 {
use BlendFunction::*;
match self {
Blend => blend_argb(src, dest),
BlendSourceWithAlpha(opacity) => blend_argb_source_by(src, dest, *opacity),
TintedBlend(tint) => tinted_blend_argb(from_argb32(*tint), src, dest),
MultipliedBlend(color) => multiplied_blend_argb(from_argb32(*color), src, dest),
}
}
#[inline]
pub fn blend_simd(&self, src: SimdColor4u8, dest: SimdColor4u8) -> SimdColor4u8 {
use BlendFunction::*;
match self {
Blend => blend_argb_simd(src, dest),
BlendSourceWithAlpha(opacity) => blend_argb_simd_source_by(src, dest, *opacity),
TintedBlend(tint) => tinted_blend_argb_simd(from_argb32_simd(*tint), src, dest),
MultipliedBlend(color) => multiplied_blend_argb_simd(from_argb32_simd(*color), src, dest),
Blend => src.blend(dest),
BlendSourceWithAlpha(opacity) => src.blend_with_alpha(dest, *opacity),
TintedBlend(tint) => src.tint(*tint).blend(dest),
MultipliedBlend(color) => src.mul(*color).blend(dest),
}
}
}
@ -566,6 +548,8 @@ pub trait ColorsAsBytes {
pub struct ARGBu8x4(pub simd::u8x4);
impl ARGBu8x4 {
pub const SIZE: usize = std::mem::size_of::<Self>();
#[inline]
pub const fn from_argb(argb: [u8; 4]) -> Self {
ARGBu8x4(simd::u8x4::from_array(argb))
@ -758,13 +742,33 @@ impl ColorsAsBytes for [ARGBu8x4] {
impl std::fmt::Debug for ARGBu8x4 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ARGBu8x4(0x{:2x}, 0x{:2x}, 0x{:2x}, 0x{:2x})", self.a(), self.r(), self.g(), self.b())
write!(f, "0x{:02x}{:02x}{:02x}{:02x}", self.a(), self.r(), self.g(), self.b())
}
}
impl std::fmt::Display for ARGBu8x4 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "0x{:2x}{:2x}{:2x}{:2x}", self.a(), self.r(), self.g(), self.b())
write!(f, "0x{:02x}{:02x}{:02x}{:02x}", self.a(), self.r(), self.g(), self.b())
}
}
impl WriteType for ARGBu8x4 {
type ErrorType = std::io::Error;
#[inline]
fn write<T: WriteBytesExt>(&self, writer: &mut T) -> Result<(), Self::ErrorType> {
writer.write_all(self.0.as_array())?;
Ok(())
}
}
impl ReadType for ARGBu8x4 {
type OutputType = Self;
type ErrorType = std::io::Error;
#[inline]
fn read<T: ReadBytesExt>(reader: &mut T) -> Result<Self::OutputType, Self::ErrorType> {
Ok(ARGBu8x4::from_argb([reader.read_u8()?, reader.read_u8()?, reader.read_u8()?, reader.read_u8()?]))
}
}

View file

@ -7,7 +7,7 @@ use std::path::Path;
use byteorder::{ReadBytesExt, WriteBytesExt};
use thiserror::Error;
use crate::graphics::{from_rgb32, lerp_rgb32, to_argb32, to_rgb32, IndexedBitmap};
use crate::graphics::{ARGBu8x4, IndexedBitmap};
use crate::utils::abs_diff;
const NUM_COLORS: usize = 256;
@ -29,16 +29,19 @@ fn to_6bit(value: u8) -> u8 {
}
// vga bios (0-63) format
fn read_palette_6bit<T: ReadBytesExt>(reader: &mut T, num_colors: usize) -> Result<[u32; NUM_COLORS], PaletteError> {
fn read_palette_6bit<T: ReadBytesExt>(
reader: &mut T,
num_colors: usize,
) -> Result<[ARGBu8x4; NUM_COLORS], PaletteError> {
if num_colors > NUM_COLORS {
return Err(PaletteError::OutOfRange(num_colors));
}
let mut colors = [to_argb32([255, 0, 0, 0]); NUM_COLORS];
let mut colors = [ARGBu8x4::from_argb([255, 0, 0, 0]); NUM_COLORS];
for i in 0..num_colors {
let r = reader.read_u8()?;
let g = reader.read_u8()?;
let b = reader.read_u8()?;
let color = to_rgb32([from_6bit(r), from_6bit(g), from_6bit(b)]);
let color = ARGBu8x4::from_rgb([from_6bit(r), from_6bit(g), from_6bit(b)]);
colors[i] = color;
}
Ok(colors)
@ -46,32 +49,34 @@ fn read_palette_6bit<T: ReadBytesExt>(reader: &mut T, num_colors: usize) -> Resu
fn write_palette_6bit<T: WriteBytesExt>(
writer: &mut T,
colors: &[u32; NUM_COLORS],
colors: &[ARGBu8x4; NUM_COLORS],
num_colors: usize,
) -> Result<(), PaletteError> {
if num_colors > NUM_COLORS {
return Err(PaletteError::OutOfRange(num_colors));
}
for i in 0..num_colors {
let [r, g, b] = from_rgb32(colors[i]);
writer.write_u8(to_6bit(r))?;
writer.write_u8(to_6bit(g))?;
writer.write_u8(to_6bit(b))?;
writer.write_u8(to_6bit(colors[i].r()))?;
writer.write_u8(to_6bit(colors[i].g()))?;
writer.write_u8(to_6bit(colors[i].b()))?;
}
Ok(())
}
// normal (0-255) format
fn read_palette_8bit<T: ReadBytesExt>(reader: &mut T, num_colors: usize) -> Result<[u32; NUM_COLORS], PaletteError> {
fn read_palette_8bit<T: ReadBytesExt>(
reader: &mut T,
num_colors: usize,
) -> Result<[ARGBu8x4; NUM_COLORS], PaletteError> {
if num_colors > NUM_COLORS {
return Err(PaletteError::OutOfRange(num_colors));
}
let mut colors = [to_argb32([255, 0, 0, 0]); NUM_COLORS];
let mut colors = [ARGBu8x4::from_argb([255, 0, 0, 0]); NUM_COLORS];
for i in 0..num_colors {
let r = reader.read_u8()?;
let g = reader.read_u8()?;
let b = reader.read_u8()?;
let color = to_rgb32([r, g, b]);
let color = ARGBu8x4::from_rgb([r, g, b]);
colors[i] = color;
}
Ok(colors)
@ -79,17 +84,16 @@ fn read_palette_8bit<T: ReadBytesExt>(reader: &mut T, num_colors: usize) -> Resu
fn write_palette_8bit<T: WriteBytesExt>(
writer: &mut T,
colors: &[u32; NUM_COLORS],
colors: &[ARGBu8x4; NUM_COLORS],
num_colors: usize,
) -> Result<(), PaletteError> {
if num_colors > NUM_COLORS {
return Err(PaletteError::OutOfRange(num_colors));
}
for i in 0..num_colors {
let [r, g, b] = from_rgb32(colors[i]);
writer.write_u8(r)?;
writer.write_u8(g)?;
writer.write_u8(b)?;
writer.write_u8(colors[i].r())?;
writer.write_u8(colors[i].g())?;
writer.write_u8(colors[i].b())?;
}
Ok(())
}
@ -114,19 +118,18 @@ pub enum PaletteFormat {
/// colors are all stored individually as 32-bit packed values in the format 0xAARRGGBB.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Palette {
colors: [u32; NUM_COLORS],
colors: [ARGBu8x4; NUM_COLORS],
}
impl Palette {
/// Creates a new Palette with all black colors.
pub fn new() -> Palette {
Palette { colors: [0; NUM_COLORS] }
Palette { colors: [ARGBu8x4::from_rgb([0, 0, 0]); NUM_COLORS] }
}
/// Creates a new Palette with all initial colors having the RGB values specified.
pub fn new_with_default(r: u8, g: u8, b: u8) -> Palette {
let rgb = to_rgb32([r, g, b]);
Palette { colors: [rgb; NUM_COLORS] }
Palette { colors: [ARGBu8x4::from_rgb([r, g, b]); NUM_COLORS] }
}
/// Creates a new Palette, pre-loaded with the default VGA BIOS colors.
@ -295,7 +298,9 @@ impl Palette {
pub fn fade_color_toward_rgb(&mut self, color: u8, target_r: u8, target_g: u8, target_b: u8, step: u8) -> bool {
let mut modified = false;
let [mut r, mut g, mut b] = from_rgb32(self.colors[color as usize]);
let mut r = self.colors[color as usize].r();
let mut g = self.colors[color as usize].g();
let mut b = self.colors[color as usize].b();
if r != target_r {
modified = true;
@ -328,7 +333,7 @@ impl Palette {
}
if modified {
self.colors[color as usize] = to_rgb32([r, g, b]);
self.colors[color as usize] = ARGBu8x4::from_rgb([r, g, b]);
}
(target_r == r) && (target_g == g) && (target_b == b)
@ -381,8 +386,7 @@ impl Palette {
pub fn fade_colors_toward_palette<T: ColorRange>(&mut self, colors: T, palette: &Palette, step: u8) -> bool {
let mut all_faded = true;
for color in colors {
let [r, g, b] = from_rgb32(palette[color]);
if !self.fade_color_toward_rgb(color, r, g, b, step) {
if !self.fade_color_toward_rgb(color, palette[color].r(), palette[color].g(), palette[color].b(), step) {
all_faded = false;
}
}
@ -400,7 +404,7 @@ impl Palette {
/// * `t`: the amount to interpolate between the two palettes, specified as a fraction
pub fn lerp<T: ColorRange>(&mut self, colors: T, a: &Palette, b: &Palette, t: f32) {
for color in colors {
self[color] = lerp_rgb32(a[color], b[color], t);
self[color] = a[color].lerp(b[color], t);
}
}
@ -439,15 +443,14 @@ impl Palette {
let mut closest = 0;
for (index, color) in self.colors.iter().enumerate() {
let [this_r, this_g, this_b] = from_rgb32(*color);
if r == this_r && g == this_g && b == this_b {
if r == color.r() && g == color.g() && b == color.b() {
return index as u8;
} else {
// this comparison method is using the sRGB Euclidean formula described here:
// https://en.wikipedia.org/wiki/Color_difference
let distance = abs_diff(this_r, r) as u32 + abs_diff(this_g, g) as u32 + abs_diff(this_b, b) as u32;
let distance =
abs_diff(color.r(), r) as u32 + abs_diff(color.g(), g) as u32 + abs_diff(color.b(), b) as u32;
if distance < closest_distance {
closest = index as u8;
@ -475,7 +478,7 @@ impl Palette {
}
impl Index<u8> for Palette {
type Output = u32;
type Output = ARGBu8x4;
#[inline]
fn index(&self, index: u8) -> &Self::Output {
@ -509,11 +512,11 @@ mod tests {
#[test]
fn get_and_set_colors() {
let mut palette = Palette::new();
assert_eq!(0, palette[0]);
assert_eq!(0, palette[1]);
palette[0] = 0x11223344;
assert_eq!(0x11223344, palette[0]);
assert_eq!(0, palette[1]);
assert_eq!(ARGBu8x4::from_rgb([0, 0, 0]), palette[0]);
assert_eq!(ARGBu8x4::from_rgb([0, 0, 0]), palette[1]);
palette[0] = 0x11223344.into();
assert_eq!(ARGBu8x4::from(0x11223344), palette[0]);
assert_eq!(ARGBu8x4::from_rgb([0, 0, 0]), palette[1]);
}
fn assert_ega_colors(palette: &Palette) {

View file

@ -21,7 +21,8 @@ mod tests {
use std::io::{BufReader, Read};
use std::path::{Path, PathBuf};
use byteorder::{LittleEndian, ReadBytesExt};
use crate::graphics::ARGBu8x4;
use crate::utils::ReadType;
#[allow(dead_code)]
const ASSETS_PATH: &str = "./assets/";
@ -45,12 +46,12 @@ mod tests {
Ok(buffer.into_boxed_slice())
}
pub fn load_raw_argb(bin_file: &Path) -> Result<Box<[u32]>, io::Error> {
pub fn load_raw_argb(bin_file: &Path) -> Result<Box<[ARGBu8x4]>, io::Error> {
let f = File::open(bin_file)?;
let mut reader = BufReader::new(f);
let mut buffer = Vec::new();
loop {
buffer.push(match reader.read_u32::<LittleEndian>() {
buffer.push(match ARGBu8x4::read(&mut reader) {
Ok(value) => value,
Err(err) if err.kind() == io::ErrorKind::UnexpectedEof => break,
Err(err) => return Err(err),

View file

@ -1,7 +1,6 @@
use byte_slice_cast::AsByteSlice;
use thiserror::Error;
use crate::graphics::{IndexedBitmap, Palette, RgbaBitmap};
use crate::graphics::{ARGBu8x4, ColorsAsBytes, IndexedBitmap, Palette, RgbaBitmap};
pub fn calculate_logical_screen_size(window_width: u32, window_height: u32, scale_factor: u32) -> (u32, u32) {
let logical_width = (window_width as f32 / scale_factor as f32).ceil() as u32;
@ -24,7 +23,7 @@ pub enum SdlFramebufferError {
pub struct SdlFramebuffer {
sdl_texture: sdl2::render::Texture,
sdl_texture_pitch: usize,
intermediate_texture: Option<Box<[u32]>>,
intermediate_texture: Option<Box<[ARGBu8x4]>>,
}
// TODO: i'm not totally happy with this implementation. i don't like the two display methods and how the caller
@ -46,11 +45,10 @@ impl SdlFramebuffer {
return Err(SdlFramebufferError::SDLError(error.to_string()));
}
let sdl_texture = match canvas.create_texture_streaming(
Some(sdl2::pixels::PixelFormatEnum::ARGB8888),
logical_screen_width,
logical_screen_height,
) {
let format = sdl2::pixels::PixelFormatEnum::BGRA8888;
let sdl_texture =
match canvas.create_texture_streaming(Some(format), logical_screen_width, logical_screen_height) {
Ok(texture) => texture,
Err(error) => return Err(SdlFramebufferError::SDLError(error.to_string())),
};
@ -61,9 +59,8 @@ impl SdlFramebuffer {
// SDL texture uploads each frame. necessary as applications are dealing with 8-bit indexed
// bitmaps, not 32-bit RGBA pixels, so this temporary buffer is where we convert the final
// application framebuffer to 32-bit RGBA pixels before it is uploaded to the SDL texture
let texture_pixels_size =
(logical_screen_width * logical_screen_height) as usize * SCREEN_TEXTURE_PIXEL_SIZE;
Some(vec![0u32; texture_pixels_size].into_boxed_slice())
let texture_pixels_size = (logical_screen_width * logical_screen_height) as usize;
Some(vec![ARGBu8x4::default(); texture_pixels_size].into_boxed_slice())
} else {
None
};
@ -83,7 +80,7 @@ impl SdlFramebuffer {
src.copy_as_argb_to(intermediate_texture, palette);
let texture_pixels = intermediate_texture.as_byte_slice();
let texture_pixels = intermediate_texture.as_bytes();
if let Err(error) = self.sdl_texture.update(None, texture_pixels, self.sdl_texture_pitch) {
return Err(SdlFramebufferError::SDLError(error.to_string()));
}
@ -106,7 +103,7 @@ impl SdlFramebuffer {
"Calls to display should only occur on SdlFramebuffers without an intermediate_texture"
);
let texture_pixels = src.pixels().as_byte_slice();
let texture_pixels = src.pixels().as_bytes();
if let Err(error) = self.sdl_texture.update(None, texture_pixels, self.sdl_texture_pitch) {
return Err(SdlFramebufferError::SDLError(error.to_string()));
}

View file

@ -1,4 +1,4 @@
use crate::graphics::{GeneralBitmap, GeneralBlitMethod, IndexedBitmap, RgbaBitmap};
use crate::graphics::{ARGBu8x4, ColorsAsBytes, GeneralBitmap, GeneralBlitMethod, IndexedBitmap, RgbaBitmap};
use crate::math::Rect;
use crate::system::Mouse;
@ -240,34 +240,34 @@ impl DefaultMouseCursorBitmaps<IndexedBitmap> for CustomMouseCursor<IndexedBitma
impl DefaultMouseCursorBitmaps<RgbaBitmap> for CustomMouseCursor<RgbaBitmap> {
fn get_default() -> MouseCursorBitmap<RgbaBitmap> {
#[rustfmt::skip]
const CURSOR_PIXELS: [u32; DEFAULT_MOUSE_CURSOR_WIDTH * DEFAULT_MOUSE_CURSOR_HEIGHT] = [
0x00000000, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0x00000000, 0x00000000, 0xffff00ff, 0xffff00ff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff,
0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0x00000000, 0x00000000, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff, 0xffff00ff
const CURSOR_PIXELS: [u8; DEFAULT_MOUSE_CURSOR_WIDTH * DEFAULT_MOUSE_CURSOR_HEIGHT * 4] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff,
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff
];
let mut cursor =
RgbaBitmap::new(DEFAULT_MOUSE_CURSOR_WIDTH as u32, DEFAULT_MOUSE_CURSOR_HEIGHT as u32).unwrap();
cursor.pixels_mut().copy_from_slice(&CURSOR_PIXELS);
cursor.pixels_mut().as_bytes_mut().copy_from_slice(&CURSOR_PIXELS);
MouseCursorBitmap {
cursor,
hotspot_x: DEFAULT_MOUSE_CURSOR_HOTSPOT_X,
hotspot_y: DEFAULT_MOUSE_CURSOR_HOTSPOT_Y,
transparent_color: 0xffff00ff,
transparent_color: ARGBu8x4::from(0xffff00ff),
}
}
}

View file

@ -1,3 +1,4 @@
use byteorder::{ReadBytesExt, WriteBytesExt};
use std::io::{Error, SeekFrom};
/// Provides a convenience method for determining the total size of a stream. This is provided
@ -20,3 +21,16 @@ impl<T: std::io::Read + std::io::Seek> StreamSize for T {
Ok(len)
}
}
pub trait ReadType {
type OutputType;
type ErrorType;
fn read<T: ReadBytesExt>(reader: &mut T) -> Result<Self::OutputType, Self::ErrorType>;
}
pub trait WriteType {
type ErrorType;
fn write<T: WriteBytesExt>(&self, writer: &mut T) -> Result<(), Self::ErrorType>;
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View file

@ -5,24 +5,24 @@ use helpers::test_assets_file;
pub mod helpers;
const LIGHTER_BACKGROUND: u32 = 0xff2c3041;
const LIGHTER_BACKGROUND: ARGBu8x4 = ARGBu8x4::from_rgb([0x2c, 0x30, 0x41]);
pub const COLOR_BLACK_HALF_ALPHA: u32 = 0x7f000000;
pub const COLOR_BLUE_HALF_ALPHA: u32 = 0x7f0000aa;
pub const COLOR_GREEN_HALF_ALPHA: u32 = 0x7f00aa00;
pub const COLOR_CYAN_HALF_ALPHA: u32 = 0x7f00aaaa;
pub const COLOR_RED_HALF_ALPHA: u32 = 0x7faa0000;
pub const COLOR_MAGENTA_HALF_ALPHA: u32 = 0x7faa00aa;
pub const COLOR_BROWN_HALF_ALPHA: u32 = 0x7faa5500;
pub const COLOR_LIGHT_GRAY_HALF_ALPHA: u32 = 0x7faaaaaa;
pub const COLOR_DARK_GRAY_HALF_ALPHA: u32 = 0x7f555555;
pub const COLOR_BRIGHT_BLUE_HALF_ALPHA: u32 = 0x7f5555ff;
pub const COLOR_BRIGHT_GREEN_HALF_ALPHA: u32 = 0x7f55ff55;
pub const COLOR_BRIGHT_CYAN_HALF_ALPHA: u32 = 0x7f55ffff;
pub const COLOR_BRIGHT_RED_HALF_ALPHA: u32 = 0x7fff5555;
pub const COLOR_BRIGHT_MAGENTA_HALF_ALPHA: u32 = 0x7fff55ff;
pub const COLOR_BRIGHT_YELLOW_HALF_ALPHA: u32 = 0x7fffff55;
pub const COLOR_BRIGHT_WHITE_HALF_ALPHA: u32 = 0x7fffffff;
pub const COLOR_BLACK_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0x00, 0x00, 0x00]);
pub const COLOR_BLUE_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0x00, 0x00, 0xaa]);
pub const COLOR_GREEN_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0x00, 0xaa, 0x00]);
pub const COLOR_CYAN_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0x00, 0xaa, 0xaa]);
pub const COLOR_RED_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0xaa, 0x00, 0x00]);
pub const COLOR_MAGENTA_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0xaa, 0x00, 0xaa]);
pub const COLOR_BROWN_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0xaa, 0x55, 0x00]);
pub const COLOR_LIGHT_GRAY_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0xaa, 0xaa, 0xaa]);
pub const COLOR_DARK_GRAY_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0x55, 0x55, 0x55]);
pub const COLOR_BRIGHT_BLUE_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0x55, 0x55, 0xff]);
pub const COLOR_BRIGHT_GREEN_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0x55, 0xff, 0x55]);
pub const COLOR_BRIGHT_CYAN_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0x55, 0xff, 0xff]);
pub const COLOR_BRIGHT_RED_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0xff, 0x55, 0x55]);
pub const COLOR_BRIGHT_MAGENTA_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0xff, 0x55, 0xff]);
pub const COLOR_BRIGHT_YELLOW_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0xff, 0xff, 0x55]);
pub const COLOR_BRIGHT_WHITE_HALF_ALPHA: ARGBu8x4 = ARGBu8x4::from_argb([0x7f, 0xff, 0xff, 0xff]);
const SCREEN_WIDTH: u32 = 320;
const SCREEN_HEIGHT: u32 = 240;
@ -60,9 +60,9 @@ fn setup_for_blending_half_solid_half_semi_transparent() -> RgbaBitmap {
for y in (screen.height() / 2)..screen.height() {
for x in 0..screen.width() {
unsafe {
let pixel = screen.get_pixel_unchecked(x as i32, y as i32);
let [r, g, b] = from_rgb32(pixel);
screen.set_pixel_unchecked(x as i32, y as i32, to_argb32([127, r, g, b]));
let mut pixel = screen.get_pixel_unchecked(x as i32, y as i32);
pixel.set_a(127);
screen.set_pixel_unchecked(x as i32, y as i32, pixel);
}
}
}
@ -83,7 +83,7 @@ fn pixel_addressing() {
let mut i = 0;
for _y in 0..16 {
for _x in 0..16 {
*pixels = to_rgb32([i, i, i]);
*pixels = ARGBu8x4::from_rgb([i, i, i]);
i = i.wrapping_add(1);
pixels = pixels.offset(1);
}
@ -634,12 +634,17 @@ fn generate_bitmap_with_varied_alpha(width: i32, height: i32) -> RgbaBitmap {
let y_third = height / 3;
let mut bitmap = RgbaBitmap::new(width as u32, height as u32).unwrap();
bitmap.clear(0); // alpha=0
bitmap.clear(0.into()); // alpha=0
bitmap.filled_rect(0, 0, x_third, y_third, 0x330000aa);
bitmap.filled_rect(x_third * 2 + 1, y_third * 2 + 1, width - 1, height - 1, 0x6600aa00);
bitmap.filled_rect(0, y_third * 2 + 1, x_third, height - 1, 0x9900aaaa);
bitmap.filled_rect(x_third * 2 + 1, 0, width - 1, y_third, 0xccaa0000);
let color1 = ARGBu8x4::from_argb([0x33, 0x00, 0x00, 0xaa]);
let color2 = ARGBu8x4::from_argb([0x66, 0x00, 0xaa, 0x00]);
let color3 = ARGBu8x4::from_argb([0x99, 0x00, 0xaa, 0xaa]);
let color4 = ARGBu8x4::from_argb([0xcc, 0xaa, 0x00, 0x00]);
bitmap.filled_rect(0, 0, x_third, y_third, color1);
bitmap.filled_rect(x_third * 2 + 1, y_third * 2 + 1, width - 1, height - 1, color2);
bitmap.filled_rect(0, y_third * 2 + 1, x_third, height - 1, color3);
bitmap.filled_rect(x_third * 2 + 1, 0, width - 1, y_third, color4);
bitmap.filled_rect(x_third, y_third, x_third * 2 + 1, y_third * 2 + 1, COLOR_MAGENTA);
bitmap.rect(0, 0, width - 1, height - 1, COLOR_BROWN);
@ -651,12 +656,17 @@ fn generate_solid_bitmap_with_varied_alpha(width: i32, height: i32) -> RgbaBitma
let y_third = height / 3;
let mut bitmap = RgbaBitmap::new(width as u32, height as u32).unwrap();
bitmap.clear(to_argb32([255, 0, 0, 0]));
bitmap.clear(ARGBu8x4::from_argb([255, 0, 0, 0]));
bitmap.filled_rect(0, 0, x_third, y_third, 0x330000aa);
bitmap.filled_rect(x_third * 2 + 1, y_third * 2 + 1, width - 1, height - 1, 0x6600aa00);
bitmap.filled_rect(0, y_third * 2 + 1, x_third, height - 1, 0x9900aaaa);
bitmap.filled_rect(x_third * 2 + 1, 0, width - 1, y_third, 0xccaa0000);
let color1 = ARGBu8x4::from_argb([0x33, 0x00, 0x00, 0xaa]);
let color2 = ARGBu8x4::from_argb([0x66, 0x00, 0xaa, 0x00]);
let color3 = ARGBu8x4::from_argb([0x99, 0x00, 0xaa, 0xaa]);
let color4 = ARGBu8x4::from_argb([0xcc, 0xaa, 0x00, 0x00]);
bitmap.filled_rect(0, 0, x_third, y_third, color1);
bitmap.filled_rect(x_third * 2 + 1, y_third * 2 + 1, width - 1, height - 1, color2);
bitmap.filled_rect(0, y_third * 2 + 1, x_third, height - 1, color3);
bitmap.filled_rect(x_third * 2 + 1, 0, width - 1, y_third, color4);
bitmap.filled_rect(x_third, y_third, x_third * 2 + 1, y_third * 2 + 1, COLOR_MAGENTA);
bitmap.rect(0, 0, width - 1, height - 1, COLOR_BROWN);
@ -746,7 +756,7 @@ fn solid_tinted_blits() {
let bmp21 = generate_bitmap(21, 21);
let bmp3 = generate_bitmap(3, 3);
let method = SolidTinted(to_argb32([127, 155, 242, 21]));
let method = SolidTinted(ARGBu8x4::from_argb([127, 155, 242, 21]));
let x = 40;
let y = 20;
@ -951,7 +961,7 @@ fn solid_flipped_tinted_blits() {
let bmp = generate_bitmap(16, 16);
let tint_color = to_argb32([127, 155, 242, 21]);
let tint_color = ARGBu8x4::from_argb([127, 155, 242, 21]);
let x = 40;
let y = 20;
@ -1090,7 +1100,7 @@ fn transparent_blits() {
let bmp21 = generate_bitmap(21, 21);
let bmp3 = generate_bitmap(3, 3);
let method = Transparent(to_rgb32([0, 0, 0]));
let method = Transparent(ARGBu8x4::from_rgb([0, 0, 0]));
let x = 40;
let y = 20;
@ -1161,8 +1171,10 @@ fn transparent_tinted_blits() {
let bmp21 = generate_bitmap(21, 21);
let bmp3 = generate_bitmap(3, 3);
let method =
TransparentTinted { transparent_color: to_rgb32([0, 0, 0]), tint_color: to_argb32([127, 155, 242, 21]) };
let method = TransparentTinted {
transparent_color: ARGBu8x4::from_rgb([0, 0, 0]),
tint_color: ARGBu8x4::from_argb([127, 155, 242, 21]),
};
let x = 40;
let y = 20;
@ -1232,7 +1244,8 @@ fn blended_transparent_blits() {
let bmp21 = generate_solid_bitmap_with_varied_alpha(21, 21);
let bmp3 = generate_solid_bitmap_with_varied_alpha(3, 3);
let method = TransparentBlended { transparent_color: to_argb32([255, 0, 0, 0]), blend: BlendFunction::Blend };
let method =
TransparentBlended { transparent_color: ARGBu8x4::from_argb([255, 0, 0, 0]), blend: BlendFunction::Blend };
let x = 40;
let y = 20;
@ -1299,7 +1312,7 @@ fn transparent_flipped_blits() {
let mut screen = setup();
screen.clear(LIGHTER_BACKGROUND);
let transparent_color = to_rgb32([0, 0, 0]);
let transparent_color = ARGBu8x4::from_rgb([0, 0, 0]);
let bmp = generate_bitmap(16, 16);
@ -1368,8 +1381,8 @@ fn transparent_flipped_tinted_blits() {
let mut screen = setup();
screen.clear(LIGHTER_BACKGROUND);
let transparent_color = to_rgb32([0, 0, 0]);
let tint_color = to_argb32([127, 155, 242, 21]);
let transparent_color = ARGBu8x4::from_rgb([0, 0, 0]);
let tint_color = ARGBu8x4::from_argb([127, 155, 242, 21]);
let bmp = generate_bitmap(16, 16);
@ -1439,7 +1452,7 @@ fn blended_transparent_flipped_blits() {
let bmp = generate_solid_bitmap_with_varied_alpha(16, 16);
let transparent_color = to_argb32([255, 0, 0, 0]);
let transparent_color = ARGBu8x4::from_argb([255, 0, 0, 0]);
let blend = BlendFunction::Blend;
let x = 40;
@ -1507,7 +1520,7 @@ fn transparent_single_blits() {
let mut screen = setup();
screen.clear(LIGHTER_BACKGROUND);
let transparent_color = to_rgb32([0, 0, 0]);
let transparent_color = ARGBu8x4::from_rgb([0, 0, 0]);
let bmp = generate_bitmap(16, 16);
@ -1580,7 +1593,7 @@ fn transparent_flipped_single_blits() {
let mut screen = setup();
screen.clear(LIGHTER_BACKGROUND);
let transparent_color = to_rgb32([0, 0, 0]);
let transparent_color = ARGBu8x4::from_rgb([0, 0, 0]);
let bmp = generate_bitmap(16, 16);
@ -1719,7 +1732,7 @@ fn rotozoom_tinted_blits() {
let bmp = generate_bitmap(16, 16);
let tint_color = to_argb32([127, 155, 242, 21]);
let tint_color = ARGBu8x4::from_argb([127, 155, 242, 21]);
let x = 40;
let y = 20;
@ -1857,7 +1870,7 @@ fn rotozoom_transparent_blits() {
let mut screen = setup();
screen.clear(LIGHTER_BACKGROUND);
let transparent_color = to_rgb32([0, 0, 0]);
let transparent_color = ARGBu8x4::from_rgb([0, 0, 0]);
let bmp = generate_bitmap(16, 16);
@ -1928,8 +1941,8 @@ fn rotozoom_transparent_tinted_blits() {
let mut screen = setup();
screen.clear(LIGHTER_BACKGROUND);
let transparent_color = to_rgb32([0, 0, 0]);
let tint_color = to_argb32([127, 155, 242, 21]);
let transparent_color = ARGBu8x4::from_rgb([0, 0, 0]);
let tint_color = ARGBu8x4::from_argb([127, 155, 242, 21]);
let bmp = generate_bitmap(16, 16);
@ -2001,7 +2014,7 @@ fn blended_rotozoom_transparent_blits() {
let bmp = generate_solid_bitmap_with_varied_alpha(16, 16);
let transparent_color = to_argb32([255, 0, 0, 0]);
let transparent_color = ARGBu8x4::from_argb([255, 0, 0, 0]);
let blend = BlendFunction::Blend;
let x = 40;
@ -2098,34 +2111,34 @@ fn blend_function_tinted_blend() {
let bmp_solid_with_varied_alpha = generate_solid_bitmap_with_varied_alpha(32, 32);
let bmp_with_varied_alpha = generate_bitmap_with_varied_alpha(32, 32);
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(to_argb32([255, 155, 242, 21])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(ARGBu8x4::from_argb([255, 155, 242, 21])));
screen.blit(method.clone(), &bmp_solid, 10, 5);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 5);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 5);
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(to_argb32([127, 155, 242, 21])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(ARGBu8x4::from_argb([127, 155, 242, 21])));
screen.blit(method.clone(), &bmp_solid, 10, 40);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 40);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 40);
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(to_argb32([0, 155, 242, 21])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(ARGBu8x4::from_argb([0, 155, 242, 21])));
screen.blit(method.clone(), &bmp_solid, 10, 75);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 75);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 75);
//////
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(to_argb32([255, 155, 242, 21])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(ARGBu8x4::from_argb([255, 155, 242, 21])));
screen.blit(method.clone(), &bmp_solid, 10, 125);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 125);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 125);
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(to_argb32([127, 155, 242, 21])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(ARGBu8x4::from_argb([127, 155, 242, 21])));
screen.blit(method.clone(), &bmp_solid, 10, 160);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 160);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 160);
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(to_argb32([0, 155, 242, 21])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::TintedBlend(ARGBu8x4::from_argb([0, 155, 242, 21])));
screen.blit(method.clone(), &bmp_solid, 10, 195);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 195);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 195);
@ -2192,34 +2205,34 @@ fn blend_function_multiplied_blend() {
let bmp_solid_with_varied_alpha = generate_solid_bitmap_with_varied_alpha(32, 32);
let bmp_with_varied_alpha = generate_bitmap_with_varied_alpha(32, 32);
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(to_argb32([255, 242, 29, 81])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(ARGBu8x4::from_argb([255, 242, 29, 81])));
screen.blit(method.clone(), &bmp_solid, 10, 5);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 5);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 5);
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(to_argb32([127, 242, 29, 81])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(ARGBu8x4::from_argb([127, 242, 29, 81])));
screen.blit(method.clone(), &bmp_solid, 10, 40);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 40);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 40);
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(to_argb32([0, 242, 29, 81])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(ARGBu8x4::from_argb([0, 242, 29, 81])));
screen.blit(method.clone(), &bmp_solid, 10, 75);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 75);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 75);
//////
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(to_argb32([255, 242, 29, 81])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(ARGBu8x4::from_argb([255, 242, 29, 81])));
screen.blit(method.clone(), &bmp_solid, 10, 125);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 125);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 125);
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(to_argb32([127, 242, 29, 81])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(ARGBu8x4::from_argb([127, 242, 29, 81])));
screen.blit(method.clone(), &bmp_solid, 10, 160);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 160);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 160);
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(to_argb32([0, 242, 29, 81])));
let method = RgbaBlitMethod::SolidBlended(BlendFunction::MultipliedBlend(ARGBu8x4::from_argb([0, 242, 29, 81])));
screen.blit(method.clone(), &bmp_solid, 10, 195);
screen.blit(method.clone(), &bmp_solid_with_varied_alpha, 100, 195);
screen.blit(method.clone(), &bmp_with_varied_alpha, 200, 195);
@ -2478,15 +2491,16 @@ fn get_quad(
let positions_2 = [top_left, bottom_right, top_right];
let texcoords_1 = [Vector2::new(0.0, 0.0), Vector2::new(0.0, 1.0), Vector2::new(1.0, 1.0)];
let texcoords_2 = [Vector2::new(0.0, 0.0), Vector2::new(1.0, 1.0), Vector2::new(1.0, 0.0)];
let single_color = to_argb32([128, 255, 0, 255]);
let colors_1 = [to_rgb32([255, 0, 0]), to_rgb32([0, 255, 0]), to_rgb32([0, 0, 255])];
let colors_2 = [to_rgb32([255, 0, 0]), to_rgb32([0, 0, 255]), to_rgb32([255, 255, 255])];
let tint_color = to_argb32([128, 192, 47, 160]);
let single_color = ARGBu8x4::from_argb([128, 255, 0, 255]);
let colors_1 = [ARGBu8x4::from_rgb([255, 0, 0]), ARGBu8x4::from_rgb([0, 255, 0]), ARGBu8x4::from_rgb([0, 0, 255])];
let colors_2 =
[ARGBu8x4::from_rgb([255, 0, 0]), ARGBu8x4::from_rgb([0, 0, 255]), ARGBu8x4::from_rgb([255, 255, 255])];
let tint_color = ARGBu8x4::from_argb([128, 192, 47, 160]);
match mode {
TriangleType::Solid => [
RgbaTriangle2d::Solid { position: positions_1, color: to_rgb32([255, 0, 255]) },
RgbaTriangle2d::Solid { position: positions_2, color: to_rgb32([255, 0, 255]) },
RgbaTriangle2d::Solid { position: positions_1, color: ARGBu8x4::from_rgb([255, 0, 255]) },
RgbaTriangle2d::Solid { position: positions_2, color: ARGBu8x4::from_rgb([255, 0, 255]) },
],
TriangleType::SolidBlended => [
RgbaTriangle2d::SolidBlended { position: positions_1, color: single_color, blend: BlendFunction::Blend },

View file

@ -2,7 +2,7 @@ use crate::BACKGROUND_COLOR;
use ggdt::prelude::*;
fn display_raw_keyboard_state(system: &mut System<Standard>, x: i32, y: i32) {
let font_opts = FontRenderOpts::Color(0xffffffff);
let font_opts = FontRenderOpts::Color(COLOR_BRIGHT_WHITE);
let font = &system.res.font;
system.res.video.print_string("Raw Keyboard State", x, x, font_opts, font);
@ -40,7 +40,7 @@ fn display_key_state(key: Scancode, system: &mut System<Standard>, x: i32, y: i3
),
x,
y,
FontRenderOpts::Color(0xffffffff),
FontRenderOpts::Color(COLOR_BRIGHT_WHITE),
&system.res.font,
);
}
@ -87,7 +87,7 @@ fn keyboard_state() {
display_key_state(*key, &mut system, 2, 160 + (idx as i32 * 10));
}
system.res.video.set_pixel(system.res.mouse.x(), system.res.mouse.y(), to_rgb32([255, 0, 255]));
system.res.video.set_pixel(system.res.mouse.x(), system.res.mouse.y(), COLOR_BRIGHT_MAGENTA);
system.display().unwrap();
}

View file

@ -22,7 +22,7 @@ mod system_resources_standard;
use ggdt::prelude::*;
const BACKGROUND_COLOR: u32 = 0xff2c3041;
const BACKGROUND_COLOR: ARGBu8x4 = ARGBu8x4::from_rgb([0x2c, 0x30, 0x41]);
fn draw_base_screen<BitmapType>(
dest: &mut BitmapType,

View file

@ -3,7 +3,7 @@ use ggdt::prelude::*;
fn display_mouse_state(system: &mut System<Standard>) {
let font = &system.res.font;
let font_opts = FontRenderOpts::Color(0xffffffff);
let font_opts = FontRenderOpts::Color(COLOR_BRIGHT_WHITE);
system.res.video.print_string(
&format!(
@ -62,7 +62,7 @@ fn mouse_with_custom_cursor() {
system.update().unwrap();
display_mouse_state(&mut system);
system.res.video.set_pixel(system.res.mouse.x(), system.res.mouse.y(), to_rgb32([255, 0, 255]));
system.res.video.set_pixel(system.res.mouse.x(), system.res.mouse.y(), COLOR_BRIGHT_MAGENTA);
system.display().unwrap();
}
@ -91,7 +91,7 @@ fn mouse_with_os_cursor() {
system.update().unwrap();
display_mouse_state(&mut system);
system.res.video.set_pixel(system.res.mouse.x(), system.res.mouse.y(), to_rgb32([255, 0, 255]));
system.res.video.set_pixel(system.res.mouse.x(), system.res.mouse.y(), COLOR_BRIGHT_MAGENTA);
system.display().unwrap();
}

View file

@ -40,7 +40,7 @@ fn system_events_display() {
&format!("{:?}", event),
2,
system.res.video.height() as i32 - 10 - (idx as i32 * 10),
FontRenderOpts::Color(to_rgb32([255, 255, 255])),
FontRenderOpts::Color(COLOR_BRIGHT_WHITE),
&system.res.font,
);
}

View file

@ -27,8 +27,8 @@ fn simple_main_loop(mut system: System<Standard>) {
draw_base_screen(
&mut system.res.video,
to_rgb32([32, 32, 32]),
to_rgb32([44, 44, 44]),
ARGBu8x4::from_rgb([32, 32, 32]),
ARGBu8x4::from_rgb([44, 44, 44]),
COLOR_BRIGHT_WHITE,
COLOR_BRIGHT_RED,
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -1,4 +1,4 @@
use ggdt::graphics::{to_argb32, BlendFunction, RgbaBitmap, RgbaPixelFormat};
use ggdt::graphics::{ARGBu8x4, BlendFunction, RgbaBitmap, RgbaPixelFormat};
use ggdt::math::{Rect, Vector2};
use imgui::internal::RawWrapper;
@ -67,9 +67,9 @@ impl Renderer {
Vector2::new(v3.uv[0], v3.uv[1]),
],
&[
to_argb32([v2.col[3], v2.col[0], v2.col[1], v2.col[2]]),
to_argb32([v1.col[3], v1.col[0], v1.col[1], v1.col[2]]),
to_argb32([v3.col[3], v3.col[0], v3.col[1], v3.col[2]]),
ARGBu8x4::from_argb([v2.col[3], v2.col[0], v2.col[1], v2.col[2]]),
ARGBu8x4::from_argb([v1.col[3], v1.col[0], v1.col[1], v1.col[2]]),
ARGBu8x4::from_argb([v3.col[3], v3.col[0], v3.col[1], v3.col[2]]),
],
bitmap,
BlendFunction::Blend,