switched from own vector to glam
This commit is contained in:
parent
0d209125f0
commit
ecc5209772
|
@ -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",
|
||||||
|
|
|
@ -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"
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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)]),
|
||||||
|
|
41
src/image.rs
41
src/image.rs
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
26
src/rect.rs
26
src/rect.rs
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
116
src/vec2.rs
116
src/vec2.rs
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue