switched from own vector to glam

This commit is contained in:
dani 2023-07-10 14:32:33 +00:00
parent 0d209125f0
commit ecc5209772
13 changed files with 169 additions and 241 deletions

7
Cargo.lock generated
View File

@ -386,6 +386,12 @@ dependencies = [
"weezl", "weezl",
] ]
[[package]]
name = "glam"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42218cb640844e3872cc3c153dc975229e080a6c4733b34709ef445610550226"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.0" version = "0.14.0"
@ -1033,6 +1039,7 @@ name = "skunk2d"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"gif", "gif",
"glam",
"measure_time", "measure_time",
"num", "num",
"rand", "rand",

View File

@ -13,3 +13,4 @@ num = "0.4.0"
measure_time = "0.8.2" measure_time = "0.8.2"
softbuffer = "0.3.0" softbuffer = "0.3.0"
rayon = "1.7.0" rayon = "1.7.0"
glam = "0.24.0"

View File

@ -1,3 +1,4 @@
use glam::IVec2;
use rand::Rng; use rand::Rng;
use skunk2d::*; use skunk2d::*;
use std::rc::Rc; use std::rc::Rc;
@ -8,7 +9,7 @@ const HEIGHT: i32 = 1080 / 3;
struct World { struct World {
img: Rc<Image>, img: Rc<Image>,
font: Rc<Tileset>, font: Rc<Tileset>,
pos: Vec2<i32>, pos: IVec2,
map: HexMap, map: HexMap,
} }
@ -23,12 +24,15 @@ impl Game for World {
window_state.scramble_palette(); window_state.scramble_palette();
Self { Self {
img: Image::load_data(include_bytes!("assets/test.gif")), img: Image::load_data(include_bytes!("assets/test.gif")),
font: Tileset::load_data(include_bytes!("assets/ega-8x14.gif"), Vec2 { x: 16, y: 16 }), font: Tileset::load_data(
pos: Vec2::zero(), include_bytes!("assets/ega-8x14.gif"),
IVec2 { x: 16, y: 16 },
),
pos: IVec2::ZERO,
map: HexMap::new( map: HexMap::new(
Vec2 { x: 27, y: 13 }, IVec2 { x: 27, y: 13 },
Tileset::load_data(include_bytes!("assets/hex2.gif"), Vec2 { x: 2, y: 1 }), Tileset::load_data(include_bytes!("assets/hex2.gif"), IVec2 { x: 2, y: 1 }),
Vec2 { x: 23, y: 13 }, IVec2 { x: 23, y: 13 },
), ),
} }
} }
@ -54,7 +58,7 @@ impl Game for World {
fn draw(&self, target: &mut Image) { fn draw(&self, target: &mut Image) {
target.clear(); target.clear();
target.draw_hexmap(Vec2 { x: 0, y: 0 }, &self.map); target.draw_hexmap(IVec2 { x: 0, y: 0 }, &self.map);
/*target.draw_image(Vec2 { x: 200, y: 100 }, &self.img); /*target.draw_image(Vec2 { x: 200, y: 100 }, &self.img);
target.draw_image(self.pos, self.font.get(68)); target.draw_image(self.pos, self.font.get(68));

2
rust-toolchain.toml Normal file
View File

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

View File

@ -1,4 +1,5 @@
use crate::{Image, Rect, Tileset, Vec2}; use crate::{IRect, Image, Tileset};
use glam::IVec2;
use std::collections::VecDeque; use std::collections::VecDeque;
pub(crate) struct Console { pub(crate) struct Console {
@ -29,13 +30,13 @@ impl Console {
} }
} }
pub(crate) fn draw_to_image(&self, target: &mut Image, pos: Vec2<i32>, font: &Tileset) { pub(crate) fn draw_to_image(&self, target: &mut Image, pos: IVec2, font: &Tileset) {
let height = self.max_lines as i32 * font.tile_size().y; let height = self.max_lines as i32 * font.tile_size().y;
let width = self.max_line_length as i32 * font.tile_size().x; let width = self.max_line_length as i32 * font.tile_size().x;
target.fill_rect( target.fill_rect(
Rect { IRect {
pos, pos,
size: Vec2 { size: IVec2 {
x: width, x: width,
y: height, y: height,
}, },
@ -44,8 +45,8 @@ impl Console {
); );
let y = height + pos.y; let y = height + pos.y;
target.draw_line( target.draw_line(
Vec2 { x: pos.x, y }, IVec2 { x: pos.x, y },
Vec2 { IVec2 {
x: pos.x + width, x: pos.x + width,
y, y,
}, },
@ -53,7 +54,7 @@ impl Console {
); );
for (i, str) in self.lines.iter().enumerate() { for (i, str) in self.lines.iter().enumerate() {
target.draw_string( target.draw_string(
pos + Vec2 { pos + IVec2 {
x: 0, x: 0,
y: i as i32 * font.tile_size().y, y: i as i32 * font.tile_size().y,
}, },

View File

@ -1,4 +1,6 @@
use crate::{Image, Tileset, Vec2}; use crate::vec_util::IVec2Helper;
use crate::{Image, Tileset};
use glam::IVec2;
use rand::distributions::Standard; use rand::distributions::Standard;
use rand::prelude::Distribution; use rand::prelude::Distribution;
use rand::Rng; use rand::Rng;
@ -6,10 +8,10 @@ use std::rc::Rc;
//odd-q vertical layout https://www.redblobgames.com/grids/hexagons //odd-q vertical layout https://www.redblobgames.com/grids/hexagons
pub struct HexMap { pub struct HexMap {
size: Vec2<i32>, size: IVec2,
data: Vec<i32>, data: Vec<i32>,
tileset: Rc<Tileset>, tileset: Rc<Tileset>,
pix_tile_off: Vec2<i32>, pix_tile_off: IVec2,
} }
pub enum Direction { pub enum Direction {
@ -24,7 +26,7 @@ pub enum Direction {
impl HexMap { impl HexMap {
//pub static //pub static
//pix_tile_off: x offset per tile, up/down alternating y offset on x axis //pix_tile_off: x offset per tile, up/down alternating y offset on x axis
pub fn new(size: Vec2<i32>, tileset: Rc<Tileset>, pix_tile_off: Vec2<i32>) -> Self { pub fn new(size: IVec2, tileset: Rc<Tileset>, pix_tile_off: IVec2) -> Self {
HexMap { HexMap {
size, size,
data: vec![0; size.size()], data: vec![0; size.size()],
@ -33,15 +35,15 @@ impl HexMap {
} }
} }
pub fn get_neighbour(coord: Vec2<i32>, dir: Direction) -> Vec2<i32> { pub fn get_neighbour(coord: IVec2, dir: Direction) -> IVec2 {
let yoff = coord.x % 2; let yoff = coord.x % 2;
(match dir { (match dir {
Direction::North => Vec2 { x: 0, y: -1 }, Direction::North => IVec2 { x: 0, y: -1 },
Direction::NorthEast => Vec2 { x: 1, y: -1 + yoff }, Direction::NorthEast => IVec2 { x: 1, y: -1 + yoff },
Direction::SouthEast => Vec2 { x: 1, y: 0 + yoff }, Direction::SouthEast => IVec2 { x: 1, y: 0 + yoff },
Direction::South => Vec2 { x: 0, y: 1 }, Direction::South => IVec2 { x: 0, y: 1 },
Direction::SouthWest => Vec2 { x: -1, y: 0 + yoff }, Direction::SouthWest => IVec2 { x: -1, y: 0 + yoff },
Direction::NorthWest => Vec2 { Direction::NorthWest => IVec2 {
x: -1, x: -1,
y: -1 + yoff, y: -1 + yoff,
}, },
@ -49,7 +51,7 @@ impl HexMap {
} }
//pub //pub
pub fn get(&self, coord: Vec2<i32>) -> i32 { pub fn get(&self, coord: IVec2) -> i32 {
if !self.is_valid_coord(coord) { if !self.is_valid_coord(coord) {
-1 -1
} else { } else {
@ -57,7 +59,7 @@ impl HexMap {
} }
} }
pub fn pixel_to_coord(&self, pixel: Vec2<i32>) -> Vec2<i32> { pub fn pixel_to_coord(&self, pixel: IVec2) -> IVec2 {
let tilesize = self.tileset.tile_size(); let tilesize = self.tileset.tile_size();
let xrepeat = pixel.x % self.pix_tile_off.x; let xrepeat = pixel.x % self.pix_tile_off.x;
let mut x = pixel.x / self.pix_tile_off.x; let mut x = pixel.x / self.pix_tile_off.x;
@ -68,7 +70,7 @@ impl HexMap {
}; };
let yrepeat = py % tilesize.y; let yrepeat = py % tilesize.y;
let mut y = py / tilesize.y; let mut y = py / tilesize.y;
let outside = self.tileset.get(0).get_pixel(Vec2 { let outside = self.tileset.get(0).get_pixel(IVec2 {
x: xrepeat, x: xrepeat,
y: yrepeat, y: yrepeat,
}) == 0; }) == 0;
@ -79,38 +81,38 @@ impl HexMap {
} }
y -= x % 2; y -= x % 2;
} }
Vec2 { x, y } IVec2 { x, y }
} }
fn coord_to_idx(&self, coord: Vec2<i32>) -> usize { fn coord_to_idx(&self, coord: IVec2) -> usize {
(coord.x + coord.y * self.size.x) as usize (coord.x + coord.y * self.size.x) as usize
} }
pub fn coord_to_pixel(&self, coord: Vec2<i32>) -> Vec2<i32> { pub fn coord_to_pixel(&self, coord: IVec2) -> IVec2 {
Vec2 { IVec2 {
x: coord.x * self.pix_tile_off.x, x: coord.x * self.pix_tile_off.x,
y: coord.y * self.tileset.tile_size().y + (coord.x % 2) * self.pix_tile_off.y, y: coord.y * self.tileset.tile_size().y + (coord.x % 2) * self.pix_tile_off.y,
} }
} }
pub fn coord_to_pixel_center(&self, coord: Vec2<i32>) -> Vec2<i32> { pub fn coord_to_pixel_center(&self, coord: IVec2) -> IVec2 {
let tilesize = self.tileset.tile_size(); let tilesize = self.tileset.tile_size();
self.coord_to_pixel(Vec2 { self.coord_to_pixel(IVec2 {
x: coord.x + tilesize.x / 2, x: coord.x + tilesize.x / 2,
y: coord.y + tilesize.y / 2, y: coord.y + tilesize.y / 2,
}) })
} }
pub fn is_valid_coord(&self, coord: Vec2<i32>) -> bool { pub fn is_valid_coord(&self, coord: IVec2) -> bool {
coord.x >= 0 && coord.y >= 0 && coord.x < self.size.x && coord.y < self.size.y coord.x >= 0 && coord.y >= 0 && coord.x < self.size.x && coord.y < self.size.y
} }
pub fn set(&mut self, coord: Vec2<i32>, val: i32) { pub fn set(&mut self, coord: IVec2, val: i32) {
let idx = self.coord_to_idx(coord); let idx = self.coord_to_idx(coord);
self.data[idx] = val; self.data[idx] = val;
} }
pub fn size(&self) -> Vec2<i32> { pub fn size(&self) -> IVec2 {
self.size self.size
} }
@ -119,12 +121,7 @@ impl HexMap {
} }
//pubcrate //pubcrate
pub(crate) fn draw_tile_to_image( pub(crate) fn draw_tile_to_image(&self, target: &mut Image, coord: IVec2, offset: IVec2) {
&self,
target: &mut Image,
coord: Vec2<i32>,
offset: Vec2<i32>,
) {
target.draw_image( target.draw_image(
self.coord_to_pixel(coord) + offset, self.coord_to_pixel(coord) + offset,
self.tileset.get(self.data[self.coord_to_idx(coord)]), self.tileset.get(self.data[self.coord_to_idx(coord)]),

View File

@ -1,18 +1,19 @@
use crate::vec2::Vec2; use crate::vec_util::IVec2Helper;
use crate::{HexMap, Rect, Tileset}; use crate::{HexMap, IRect, Tileset};
use glam::IVec2;
use std::fs; use std::fs;
use std::rc::Rc; use std::rc::Rc;
//todo: make dynamically different bitdepths //todo: make dynamically different bitdepths
pub struct Image { pub struct Image {
data: Vec<u8>, data: Vec<u8>,
size: Vec2<i32>, size: IVec2,
} }
impl Image { impl Image {
pub fn new(size: Vec2<i32>) -> Self { pub fn new(size: IVec2) -> Self {
Image { Image {
data: vec![0u8; size.size()], data: vec![0u8; (size.x * size.y) as usize],
size, size,
} }
} }
@ -34,7 +35,7 @@ impl Image {
decoder.read_into_buffer(&mut data).unwrap(); decoder.read_into_buffer(&mut data).unwrap();
Image { Image {
data, data,
size: Vec2 { size: IVec2 {
x: x as i32, x: x as i32,
y: y as i32, y: y as i32,
}, },
@ -54,26 +55,26 @@ impl Image {
self.data.as_slice() self.data.as_slice()
} }
pub fn draw_hexmap(&mut self, pos: Vec2<i32>, hexmap: &HexMap) { pub fn draw_hexmap(&mut self, pos: IVec2, hexmap: &HexMap) {
for i in hexmap.size().to_rect().iter() { for i in hexmap.size().to_rect().iter() {
hexmap.draw_tile_to_image(self, i, pos); hexmap.draw_tile_to_image(self, i, pos);
} }
} }
pub fn draw_image(&mut self, pos: Vec2<i32>, image: &Image) { pub fn draw_image(&mut self, pos: IVec2, image: &Image) {
self.draw_image_partial( self.draw_image_partial(
pos, pos,
image, image,
Rect { IRect {
pos: Vec2::zero(), pos: IVec2::ZERO,
size: image.size, size: image.size,
}, },
); );
} }
pub fn draw_image_partial(&mut self, pos: Vec2<i32>, image: &Image, src_rect: Rect<i32>) { pub fn draw_image_partial(&mut self, pos: IVec2, image: &Image, src_rect: IRect) {
//todo: write proper implementation later //todo: write proper implementation later
for i in Vec2::zero().iter_to(src_rect.size) { for i in IVec2::ZERO.iter_to(src_rect.size) {
//todo: implement better(very stupid to do per pixel) //todo: implement better(very stupid to do per pixel)
if self.size.to_rect().contains(i + pos) { if self.size.to_rect().contains(i + pos) {
let p = image.get_pixel(i + src_rect.pos); let p = image.get_pixel(i + src_rect.pos);
@ -84,7 +85,7 @@ impl Image {
} }
} }
pub fn draw_line(&mut self, pos1: Vec2<i32>, pos2: Vec2<i32>, color: u8) { pub fn draw_line(&mut self, pos1: IVec2, pos2: IVec2, color: u8) {
let (x1, y1, x2, y2) = (pos1.x, pos1.y, pos2.x, pos2.y); let (x1, y1, x2, y2) = (pos1.x, pos1.y, pos2.x, pos2.y);
let mut x = x1 as f32; let mut x = x1 as f32;
@ -100,7 +101,7 @@ impl Image {
let ys = ydiff / step; let ys = ydiff / step;
for _ in 1..=(step as i32) { for _ in 1..=(step as i32) {
self.set_pixel( self.set_pixel(
Vec2 { IVec2 {
x: x as i32, x: x as i32,
y: y as i32, y: y as i32,
}, },
@ -111,13 +112,13 @@ impl Image {
} }
} }
pub fn draw_string(&mut self, pos: Vec2<i32>, str: &str, font: &Tileset) { pub fn draw_string(&mut self, pos: IVec2, str: &str, font: &Tileset) {
assert!(str.is_ascii()); assert!(str.is_ascii());
let array = str.as_bytes(); let array = str.as_bytes();
//for i in 0..array.len() //for i in 0..array.len()
for (i, idx) in array.iter().enumerate() { for (i, idx) in array.iter().enumerate() {
self.draw_image( self.draw_image(
Vec2 { IVec2 {
x: pos.x + font.tile_size().x * i as i32, x: pos.x + font.tile_size().x * i as i32,
y: pos.y, y: pos.y,
}, },
@ -130,21 +131,21 @@ impl Image {
self.data.fill(color); self.data.fill(color);
} }
pub fn fill_rect(&mut self, rect: Rect<i32>, color: u8) { pub fn fill_rect(&mut self, rect: IRect, color: u8) {
for pos in rect.iter() { for pos in rect.iter() {
self.set_pixel(pos, color); self.set_pixel(pos, color);
} }
} }
pub fn get_pixel(&self, pos: Vec2<i32>) -> u8 { pub fn get_pixel(&self, pos: IVec2) -> u8 {
self.data[(pos.x + self.size.x * pos.y) as usize] self.data[(pos.x + self.size.x * pos.y) as usize]
} }
pub fn set_pixel(&mut self, pos: Vec2<i32>, color: u8) { pub fn set_pixel(&mut self, pos: IVec2, color: u8) {
self.data[(pos.x + self.size.x * pos.y) as usize] = color; self.data[(pos.x + self.size.x * pos.y) as usize] = color;
} }
pub fn size(&self) -> Vec2<i32> { pub fn size(&self) -> IVec2 {
self.size self.size
} }
} }

View File

@ -3,12 +3,11 @@ mod hexmap;
mod image; mod image;
mod rect; mod rect;
mod tileset; mod tileset;
mod vec2; mod vec_util;
mod window; mod window;
pub use hexmap::*; pub use hexmap::*;
pub use image::*; pub use image::*;
pub use rect::*; pub use rect::*;
pub use tileset::*; pub use tileset::*;
pub use vec2::*;
pub use window::*; pub use window::*;

View File

@ -1,30 +1,30 @@
use crate::vec2::Vec2; use crate::vec_util::{IVec2Helper, IVec2Iter};
use crate::Vec2Iter; use glam::IVec2;
use num::{Num, ToPrimitive}; use num::{Num, ToPrimitive};
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Rect<T: Num + Copy + ToPrimitive + PartialOrd> { pub struct IRect {
pub pos: Vec2<T>, pub pos: IVec2,
pub size: Vec2<T>, pub size: IVec2,
} }
impl<T: Num + Copy + ToPrimitive + PartialOrd> Rect<T> { impl IRect {
pub fn new(x: T, y: T, w: T, h: T) -> Rect<T> { pub fn new(x: i32, y: i32, w: i32, h: i32) -> IRect {
Rect { IRect {
pos: Vec2 { x, y }, pos: IVec2 { x, y },
size: Vec2 { x: w, y: h }, size: IVec2 { x: w, y: h },
} }
} }
pub fn pos2(&self) -> Vec2<T> { pub fn pos2(&self) -> IVec2 {
self.pos + self.size self.pos + self.size
} }
pub fn iter(&self) -> Vec2Iter<T> { pub fn iter(&self) -> IVec2Iter {
self.pos.iter_to(self.size) self.pos.iter_to(self.size)
} }
pub fn contains(&self, point: Vec2<T>) -> bool { pub fn contains(&self, point: IVec2) -> bool {
let p2 = self.pos2(); let p2 = self.pos2();
point.x >= self.pos.x && point.y >= self.pos.y && point.x < p2.x && point.y < p2.y point.x >= self.pos.x && point.y >= self.pos.y && point.x < p2.x && point.y < p2.y
} }

View File

@ -1,32 +1,34 @@
use crate::{Image, Rect, Vec2}; use crate::vec_util::IVec2Helper;
use crate::{IRect, Image};
use glam::IVec2;
use std::fs; use std::fs;
use std::rc::Rc; use std::rc::Rc;
pub struct Tileset { pub struct Tileset {
count: i32, count: i32,
size: Vec2<i32>, size: IVec2,
images: Vec<Image>, images: Vec<Image>,
} }
impl Tileset { impl Tileset {
pub fn load(path: &str, tile_count: Vec2<i32>) -> Rc<Self> { pub fn load(path: &str, tile_count: IVec2) -> Rc<Self> {
Self::load_data(fs::read(path).unwrap().as_slice(), tile_count) Self::load_data(fs::read(path).unwrap().as_slice(), tile_count)
} }
pub fn load_data(data: &[u8], tile_count: Vec2<i32>) -> Rc<Self> { pub fn load_data(data: &[u8], tile_count: IVec2) -> Rc<Self> {
let img = Image::load_data(data); let img = Image::load_data(data);
let mut images: Vec<Image> = vec![]; let mut images: Vec<Image> = vec![];
let size = Vec2 { let size = IVec2 {
x: img.size().x / tile_count.x, x: img.size().x / tile_count.x,
y: img.size().y / tile_count.y, y: img.size().y / tile_count.y,
}; };
for tile in tile_count.to_rect().iter() { for tile in tile_count.to_rect().iter() {
let mut image = Image::new(size); let mut image = Image::new(size);
image.draw_image_partial( image.draw_image_partial(
Vec2::zero(), IVec2::ZERO,
&img, &img,
Rect { IRect {
pos: Vec2 { pos: IVec2 {
x: tile.x * size.x, x: tile.x * size.x,
y: tile.y * size.y, y: tile.y * size.y,
}, },
@ -51,7 +53,7 @@ impl Tileset {
self.count self.count
} }
pub fn tile_size(&self) -> Vec2<i32> { pub fn tile_size(&self) -> IVec2 {
self.size self.size
} }
} }

View File

@ -1,116 +0,0 @@
use crate::Rect;
use num::{Num, ToPrimitive};
use std::cmp::Ordering;
use std::ops::{Add, AddAssign, Sub, SubAssign};
#[derive(Copy, Clone)]
pub struct Vec2<T: Num + Copy + ToPrimitive + PartialOrd> {
pub x: T,
pub y: T,
}
pub struct Vec2Iter<T: Num + Copy + ToPrimitive + PartialOrd> {
start: Vec2<T>,
end: Vec2<T>,
current: Vec2<T>,
}
impl<T: Num + Copy + ToPrimitive + PartialOrd> Vec2<T> {
//pub static
pub fn zero() -> Self {
Vec2 {
x: T::zero(),
y: T::zero(),
}
}
//pub
pub fn iter_to(self, other: Self) -> Vec2Iter<T> {
Vec2Iter {
start: self,
end: other,
current: Vec2 {
x: self.x - T::one(),
y: self.y,
},
}
}
pub fn size(&self) -> usize {
(self.x * self.y).to_usize().unwrap()
}
pub fn to_rect(self) -> Rect<T> {
Rect {
pos: Self::zero(),
size: self,
}
}
}
impl<T: Num + Copy + ToPrimitive + PartialOrd + Default> Default for Vec2<T> {
fn default() -> Self {
Vec2 {
x: T::default(),
y: T::default(),
}
}
}
impl<T: Num + Copy + ToPrimitive + PartialOrd> PartialEq for Vec2<T> {
fn eq(&self, other: &Self) -> bool {
self.x == other.x && self.y == other.y
}
}
impl<T: Num + Copy + ToPrimitive + PartialOrd> Iterator for Vec2Iter<T> {
type Item = Vec2<T>;
fn next(&mut self) -> Option<Self::Item> {
self.current.x = self.current.x + T::one();
if self.current.x >= self.end.x {
self.current.y = self.current.y + T::one();
self.current.x = self.start.x;
if self.current.y >= self.end.y {
return None;
}
}
Some(self.current)
}
}
impl<T: Num + Copy + ToPrimitive + PartialOrd> Add for Vec2<T> {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
impl<T: Num + Copy + ToPrimitive + PartialOrd> Sub for Vec2<T> {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
}
impl<T: Num + Copy + ToPrimitive + PartialOrd + AddAssign> AddAssign for Vec2<T> {
fn add_assign(&mut self, rhs: Self) {
self.x += rhs.x;
self.y += rhs.y;
}
}
impl<T: Num + Copy + ToPrimitive + PartialOrd + SubAssign> SubAssign for Vec2<T> {
fn sub_assign(&mut self, rhs: Self) {
self.x -= rhs.x;
self.y -= rhs.y;
}
}

54
src/vec_util.rs Normal file
View File

@ -0,0 +1,54 @@
use crate::IRect;
use glam::IVec2;
pub trait IVec2Helper {
fn iter_to(self, other: IVec2) -> IVec2Iter;
fn size(&self) -> usize;
fn to_rect(self) -> IRect;
}
pub struct IVec2Iter {
start: IVec2,
end: IVec2,
current: IVec2,
}
impl IVec2Helper for IVec2 {
fn iter_to(self, other: IVec2) -> IVec2Iter {
IVec2Iter {
start: self,
end: other,
current: IVec2 {
x: self.x - 1,
y: self.y,
},
}
}
fn size(&self) -> usize {
(self.x * self.y) as usize
}
fn to_rect(self) -> IRect {
IRect {
pos: IVec2::ZERO,
size: self,
}
}
}
impl Iterator for IVec2Iter {
type Item = IVec2;
fn next(&mut self) -> Option<Self::Item> {
self.current.x = self.current.x + 1;
if self.current.x >= self.end.x {
self.current.y = self.current.y + 1;
self.current.x = self.start.x;
if self.current.y >= self.end.y {
return None;
}
}
Some(self.current)
}
}

View File

@ -1,7 +1,7 @@
use crate::console::Console; use crate::console::Console;
use crate::image::Image; use crate::image::Image;
use crate::vec2::Vec2;
use crate::Tileset; use crate::Tileset;
use glam::IVec2;
use rand::Rng; use rand::Rng;
use rayon::prelude::*; use rayon::prelude::*;
use std::cmp::{max, min}; use std::cmp::{max, min};
@ -28,7 +28,7 @@ pub enum MouseButton {
} }
pub enum Event { pub enum Event {
MouseClick(MouseButton, Vec2<i32>), MouseClick(MouseButton, IVec2),
} }
pub trait Game { pub trait Game {
@ -40,7 +40,7 @@ pub trait Game {
pub struct WindowState { pub struct WindowState {
palette: [u32; 256], palette: [u32; 256],
mouse_pos: Vec2<i32>, mouse_pos: IVec2,
console: Console, console: Console,
} }
@ -51,13 +51,14 @@ impl WindowState {
} }
impl WindowState { impl WindowState {
fn new(console_size: Vec2<i32>) -> Self { fn new(console_size: IVec2) -> Self {
WindowState { WindowState {
palette: [0u32; 256], palette: [0u32; 256],
mouse_pos: Vec2::zero(), mouse_pos: IVec2::ZERO,
console: Console::new(console_size.y, console_size.x), console: Console::new(console_size.y, console_size.x),
} }
} }
pub fn set_palette(&mut self, index: u8, r: u8, g: u8, b: u8) { pub fn set_palette(&mut self, index: u8, r: u8, g: u8, b: u8) {
self.palette[index as usize] = self.palette[index as usize] =
(r as u32) | ((g as u32) << 8) | ((b as u32) << 16) | 0xff000000; (r as u32) | ((g as u32) << 8) | ((b as u32) << 16) | 0xff000000;
@ -70,7 +71,7 @@ impl WindowState {
} }
} }
pub fn mouse_pos(&self) -> Vec2<i32> { pub fn mouse_pos(&self) -> IVec2 {
self.mouse_pos self.mouse_pos
} }
} }
@ -92,12 +93,12 @@ pub fn run<T: Game + 'static>(width: i32, height: i32, target_fps: u32) {
//todo: replace Pixels with custom thingie (startup time slow because wgpu?) //todo: replace Pixels with custom thingie (startup time slow because wgpu?)
let context = unsafe { softbuffer::Context::new(&window) }.unwrap(); let context = unsafe { softbuffer::Context::new(&window) }.unwrap();
let mut surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap(); let mut surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap();
let mut screen = Image::new(Vec2 { let mut screen = Image::new(IVec2 {
x: width, x: width,
y: height, y: height,
}); });
let internal_font = Tileset::load_data(include_bytes!("ega-8x14.gif"), Vec2 { x: 16, y: 16 }); let internal_font = Tileset::load_data(include_bytes!("ega-8x14.gif"), IVec2 { x: 16, y: 16 });
let mut window_state = WindowState::new(Vec2 { let mut window_state = WindowState::new(IVec2 {
x: width / internal_font.tile_size().x, x: width / internal_font.tile_size().x,
y: height / internal_font.tile_size().y / 3, y: height / internal_font.tile_size().y / 3,
}); });
@ -157,7 +158,7 @@ pub fn run<T: Game + 'static>(width: i32, height: i32, target_fps: u32) {
WindowEvent::CursorMoved { position, .. } => { WindowEvent::CursorMoved { position, .. } => {
let x = (position.x as i32 - *off_x as i32) / *scale as i32; let x = (position.x as i32 - *off_x as i32) / *scale as i32;
let y = (position.y as i32 - *off_y as i32) / *scale as i32; let y = (position.y as i32 - *off_y as i32) / *scale as i32;
window_state.mouse_pos = Vec2 { window_state.mouse_pos = IVec2 {
x: min(width - 1, max(0, x)), x: min(width - 1, max(0, x)),
y: min(height - 1, max(0, y)), y: min(height - 1, max(0, y)),
} }
@ -205,7 +206,7 @@ pub fn run<T: Game + 'static>(width: i32, height: i32, target_fps: u32) {
if display_console { if display_console {
window_state.console.draw_to_image( window_state.console.draw_to_image(
&mut screen, &mut screen,
Vec2::zero(), IVec2::ZERO,
&internal_font, &internal_font,
); );
} }
@ -248,34 +249,9 @@ pub fn run<T: Game + 'static>(width: i32, height: i32, target_fps: u32) {
} }
} }
} }
/*
for (chunk_i, data) in chunk.iter_mut().enumerate() {
let i = chunk_i + chunk_idx * chunk_size;
let sx = i % window_width;
let sy = i / window_width;
let bx = sx / scale;
let by = sy / scale;
let p =
window_state.palette[screen_data[bx + by * width] as usize];
*data = p;
}
*/
}); });
} }
/*(0..height as usize).for_each(|y| {
for x in 0..width as usize {
let p = window_state.palette
[screen.data()[x + y * width as usize] as usize];
for iy in 0..*scale {
for ix in 0..*scale {
let tx = x * *scale + ix + *off_x;
let ty = y * *scale + iy + *off_y;
buf[tx + ty * size.width as usize] = p;
}
}
}
});*/
buf.present().unwrap(); buf.present().unwrap();
frames_since_last_second += 1; frames_since_last_second += 1;
last_frame += target_frame_duration; last_frame += target_frame_duration;