summaryrefslogtreecommitdiff
path: root/graphics/src/render.rs
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/src/render.rs')
-rw-r--r--graphics/src/render.rs446
1 files changed, 245 insertions, 201 deletions
diff --git a/graphics/src/render.rs b/graphics/src/render.rs
index aaa9983..3232bf3 100644
--- a/graphics/src/render.rs
+++ b/graphics/src/render.rs
@@ -1,4 +1,4 @@
-use std::{io::Write, ops::Div};
+use std::{f32, io::Write};
use dungeon::{
Direction, Dungeon, Entity, EntityKind, Floor, Item, MAP_SIZE, PLAYER_INVENTORY_SIZE,
@@ -48,16 +48,31 @@ macro_rules! draw_text {
}
/// The baseline size of all ingame sprites and tile textures
-const BASE_TEXTURE_SIZE: u16 = 16;
+const TEXTURE_SIZE: u16 = 16;
/// The height of the wall (offset between tile layers)
const WALL_HEIGHT: u16 = 7;
/// The (prefered) view distance of the game
-const VIEW_DISTANCE: u16 = 5;
+const VIEW_DISTANCE: u16 = 6;
-/// The minimum width/height we will render to
-const MIN_RENDER_SIZE: u16 = BASE_TEXTURE_SIZE * (VIEW_DISTANCE + 2 + 2);
+/// The size of padding in the UI
+const UI_PADDING: u16 = 6;
+
+/// The size of the font
+const FONT_SIZE: u16 = TEXTURE_SIZE;
+
+/// The height of the UI
+const UI_HEIGHT: u16 = (UI_PADDING + FONT_SIZE) * 3 + UI_PADDING;
+
+/// The size of a tile drawn to the screen
+const TILE_SIZE: u16 = TEXTURE_SIZE * 3;
+
+/// The render height of the screen
+const RENDER_HEIGHT: u16 = UI_HEIGHT + (TILE_SIZE * VIEW_DISTANCE);
+
+/// The render width of the screen
+const RENDER_WIDTH: u16 = RENDER_HEIGHT * 4 / 3;
// Tile atlas.bmp textures
const ATLAS_WALL_SIDE: (u16, u16) = (0, 0);
@@ -78,10 +93,19 @@ const ATLAS_ERROR: (u16, u16) = (3, 3);
const FULL_SOURCE_REC: Rectangle = rect! {
0.0,
0.0,
- BASE_TEXTURE_SIZE,
- BASE_TEXTURE_SIZE,
+ TEXTURE_SIZE,
+ TEXTURE_SIZE,
};
+/* Precomputed UI text rows */
+const UI_ROW1: u16 = UI_PADDING;
+const UI_ROW2: u16 = UI_ROW1 + FONT_SIZE + UI_PADDING;
+const UI_ROW3: u16 = UI_ROW2 + FONT_SIZE + UI_PADDING;
+
+/* Precomputed UI text columns */
+const UI_COL1: u16 = UI_PADDING;
+const UI_COL2: u16 = UI_COL1 + FONT_SIZE * 10;
+
#[derive(Debug)]
struct Textures {
// Tilemap
@@ -127,15 +151,17 @@ pub struct Renderer {
tilemap_mm: RenderTexture2D,
/// Last computed hash of the tilemap (floor)
tiles_hash: Option<u64>,
+ /// Framebuffer to render the whole (unscaled) game to
+ framebuffer: Option<RenderTexture2D>,
/* Per Frame Caculated Data */
/// Current tile size we are rendering
- tile_size: u16,
+ //tile_size: u16,
/// Last known FPS
fps: u32,
/// Render width of the current frame
- width: u16,
+ //width: u16,
/// Render height of the current frame
- height: u16,
+ //height: u16,
/// The current frame
frame: u64,
/// Show debug UI
@@ -146,11 +172,16 @@ impl Renderer {
// Load resources
let textures = Textures::new(handle, thread)?;
// Load render textures
- let tex_size = (MAP_SIZE * BASE_TEXTURE_SIZE) as u32;
+ let tex_size = (MAP_SIZE * TEXTURE_SIZE) as u32;
let tilemap_fg = handle.load_render_texture(thread, tex_size, tex_size)?;
let tilemap_bg = handle.load_render_texture(thread, tex_size, tex_size)?;
let tilemap_mm =
handle.load_render_texture(thread, MAP_SIZE as u32, MAP_SIZE as u32)?;
+ let framebuffer = handle.load_render_texture(
+ thread,
+ RENDER_WIDTH as u32,
+ RENDER_HEIGHT as u32,
+ )?;
Ok(Self {
textures,
@@ -158,10 +189,11 @@ impl Renderer {
tilemap_bg,
tilemap_mm,
tiles_hash: None,
- tile_size: 0,
+ framebuffer: Some(framebuffer),
+ //tile_size: 0,
fps: 0,
- width: 0,
- height: 0,
+ //width: 0,
+ //height: 0,
frame: 0,
debug: false,
})
@@ -177,11 +209,53 @@ impl Renderer {
t: &RaylibThread,
dungeon: &Dungeon,
) {
+ let render_width = handle.get_render_width() as f32;
+ let render_height = handle.get_render_height() as f32;
+
+ // Update render info before drawing
self.update_per_frame_data(handle);
+
+ // Start the frame
let mut r = handle.begin_drawing(t);
- r.clear_background(Color::BLACK);
- self.draw_dungeon(&mut r, t, dungeon);
- self.draw_ui(&mut r, dungeon);
+
+ // Update cached tilemaps
+ self.update_tilemaps(&mut r, t, &dungeon.floor);
+
+ // Draw the frame to the framebuffer
+ if let Some(mut fb) = self.framebuffer.take() {
+ // Draw the dungeon and UI
+ {
+ let mut rt = r.begin_texture_mode(t, &mut fb);
+ rt.clear_background(Color::BLACK);
+ self.draw_dungeon(&mut rt, dungeon);
+ self.draw_ui(&mut rt, dungeon);
+ }
+
+ // Draw and scale the fb to the screen
+ r.clear_background(Color::BLACK);
+ let source_rec = rect! {
+ 0, 0, RENDER_WIDTH, -RENDER_HEIGHT.cast_signed(),
+ };
+ let scale = (render_width / RENDER_WIDTH as f32)
+ .min(render_height / RENDER_HEIGHT as f32);
+ let dest_rec = rect! {
+ (render_width - (RENDER_WIDTH as f32 * scale))/2.0,
+ (render_height - (RENDER_HEIGHT as f32 * scale))/2.0,
+ RENDER_WIDTH as f32 * scale,
+ RENDER_HEIGHT as f32 * scale,
+ };
+ r.draw_texture_pro(
+ &fb,
+ source_rec,
+ dest_rec,
+ Vector2::zero(),
+ 0.0,
+ Color::WHITE,
+ );
+
+ // Restore the fb
+ self.framebuffer = Some(fb);
+ };
}
/// Update frame metadata while we still have access to the
@@ -190,47 +264,26 @@ impl Renderer {
fn update_per_frame_data(&mut self, handle: &RaylibHandle) {
// Get last known fps
self.fps = handle.get_fps();
- // Get size of framebuffer
- self.width = downcast!(handle.get_render_width(), u16).max(MIN_RENDER_SIZE);
- self.height = downcast!(handle.get_render_height(), u16).max(MIN_RENDER_SIZE);
- // Get size (in pixels) to draw each tile
- self.tile_size = {
- let size = self.width.min(self.height);
- let dist = VIEW_DISTANCE * 2 + 1;
- let pixels = size.div(dist).max(BASE_TEXTURE_SIZE);
- 1 << (u16::BITS - pixels.leading_zeros())
- };
+ //// Get size of framebuffer
+ //self.width = downcast!(handle.get_render_width(), u16).max(MIN_RENDER_SIZE);
+ //self.height = downcast!(handle.get_render_height(), u16).max(MIN_RENDER_SIZE);
+ //// Get size (in pixels) to draw each tile
+ //self.tile_size = {
+ // let size = self.width.min(self.height);
+ // let dist = VIEW_DISTANCE * 2 + 1;
+ // let pixels = size.div(dist).max(TEXTURE_SIZE);
+ // 1 << (u16::BITS - pixels.leading_zeros())
+ //};
// Update frame counter
self.frame += 1;
}
- /// Returns the Raylib Camera setup with needed 2D position/transforms
- fn render_camera(&self, dungeon: &Dungeon) -> Camera2D {
- let cpos = dungeon.camera();
- let width = self.width;
- let height = self.height;
- let ui_height = self.get_ui_height();
- Camera2D {
- target: Vector2::from(cpos.xy())
- .scale_by(self.tile_size.into())
- .max(vec2! {width/2, height/2})
- .min(vec2! {
- (MAP_SIZE * self.tile_size) - (width/2),
- (MAP_SIZE * self.tile_size) - (height/2),
- }),
- offset: vec2! {width/2, height/2 + ui_height/2},
- rotation: 0.0,
- zoom: 1.0,
- }
- }
-
/// Draws the game dungeon
- fn draw_dungeon<R>(&mut self, r: &mut R, t: &RaylibThread, dungeon: &Dungeon)
+ fn draw_dungeon<R>(&mut self, r: &mut R, dungeon: &Dungeon)
where
- R: RaylibDraw + RaylibMode2DExt + RaylibTextureModeExt,
+ R: RaylibDraw + RaylibMode2DExt,
{
- self.update_tilemaps(r, t, &dungeon.floor);
- let camera = self.render_camera(dungeon);
+ let camera = render_camera(dungeon);
let mut rc = r.begin_mode2D(camera);
self.draw_bg_tilemap(&mut rc);
self.draw_entities(&mut rc, dungeon);
@@ -261,12 +314,11 @@ impl Renderer {
where
R: RaylibDraw + RaylibTextureModeExt,
{
- let size = BASE_TEXTURE_SIZE;
let mut rt = r.begin_texture_mode(t, &mut self.tilemap_fg);
rt.clear_background(Color::BLANK);
for pos in Pos::values() {
- let (xs, ys) = (pos.x() * size, pos.y() * size);
+ let (xs, ys) = (pos.x() * TEXTURE_SIZE, pos.y() * TEXTURE_SIZE);
// fg layer only draws a top walls
if floor.get(pos) != Tile::Wall {
@@ -274,22 +326,57 @@ impl Renderer {
};
// draw base wall top texture
- rt.draw_atlas(&self.textures.atlas, ATLAS_WALL_TOP, xs, ys, size, 0.0);
+ rt.draw_atlas(
+ &self.textures.atlas,
+ ATLAS_WALL_TOP,
+ xs,
+ ys,
+ TEXTURE_SIZE,
+ 0.0,
+ );
// draw top wall borders
let is_wall =
|dir| pos.step(dir).map_or(Tile::Wall, |p| floor.get(p)).is_wall();
if !is_wall(Direction::North) {
- rt.draw_atlas(&self.textures.atlas, ATLAS_WALL_EDGE, xs, ys, size, 0.0);
+ rt.draw_atlas(
+ &self.textures.atlas,
+ ATLAS_WALL_EDGE,
+ xs,
+ ys,
+ TEXTURE_SIZE,
+ 0.0,
+ );
}
if !is_wall(Direction::East) {
- rt.draw_atlas(&self.textures.atlas, ATLAS_WALL_EDGE, xs, ys, size, 90.0);
+ rt.draw_atlas(
+ &self.textures.atlas,
+ ATLAS_WALL_EDGE,
+ xs,
+ ys,
+ TEXTURE_SIZE,
+ 90.0,
+ );
}
if !is_wall(Direction::South) {
- rt.draw_atlas(&self.textures.atlas, ATLAS_WALL_EDGE, xs, ys, size, 180.0);
+ rt.draw_atlas(
+ &self.textures.atlas,
+ ATLAS_WALL_EDGE,
+ xs,
+ ys,
+ TEXTURE_SIZE,
+ 180.0,
+ );
}
if !is_wall(Direction::West) {
- rt.draw_atlas(&self.textures.atlas, ATLAS_WALL_EDGE, xs, ys, size, 270.0);
+ rt.draw_atlas(
+ &self.textures.atlas,
+ ATLAS_WALL_EDGE,
+ xs,
+ ys,
+ TEXTURE_SIZE,
+ 270.0,
+ );
}
}
}
@@ -299,7 +386,6 @@ impl Renderer {
where
R: RaylibDraw + RaylibTextureModeExt,
{
- let size = BASE_TEXTURE_SIZE;
let mut rt = r.begin_texture_mode(t, &mut self.tilemap_bg);
rt.clear_background(Color::BLACK);
@@ -312,7 +398,14 @@ impl Renderer {
Tile::Air if (x + y) % 2 == 1 => ATLAS_FLOOR_EMPTY,
_ => ATLAS_ERROR,
};
- rt.draw_atlas(&self.textures.atlas, idx, x * size, y * size, size, 0.0);
+ rt.draw_atlas(
+ &self.textures.atlas,
+ idx,
+ x * TEXTURE_SIZE,
+ y * TEXTURE_SIZE,
+ TEXTURE_SIZE,
+ 0.0,
+ );
}
}
@@ -345,7 +438,7 @@ impl Renderer {
&self.tilemap_fg,
0,
0,
- self.tile_size / BASE_TEXTURE_SIZE,
+ TILE_SIZE / TEXTURE_SIZE,
WALL_HEIGHT,
);
}
@@ -355,13 +448,7 @@ impl Renderer {
where
R: RaylibDraw,
{
- r.draw_tilemap(
- &self.tilemap_bg,
- 0,
- 0,
- self.tile_size / BASE_TEXTURE_SIZE,
- 0,
- );
+ r.draw_tilemap(&self.tilemap_bg, 0, 0, TILE_SIZE / TEXTURE_SIZE, 0);
}
/// Draws the entities on the map
@@ -380,66 +467,38 @@ impl Renderer {
where
R: RaylibDraw,
{
- let size = self.tile_size as f32;
+ let size = TILE_SIZE as f32;
let (fx, fy) = entity.fpos.xy();
let texture = match entity.kind {
EntityKind::Player => &self.textures.player,
_ => &self.textures.error,
};
- let (x, y) = match entity.dir {
+ let (ax, ay) = match entity.dir {
Direction::North => (0, 0),
Direction::South => (0, 1),
Direction::East => (1, 0),
Direction::West => (1, 1),
};
- let source_rec = rect! {
- x * BASE_TEXTURE_SIZE,
- y * BASE_TEXTURE_SIZE,
- BASE_TEXTURE_SIZE,
- BASE_TEXTURE_SIZE,
- };
let dest_rec = rect! {
fx * size - size/2.0,
fy * size - size/2.0,
size,
size,
};
- r.draw_texture_pro(
- texture,
- source_rec,
- dest_rec,
- Vector2::zero(),
- 0.0,
- Color::WHITE,
- );
+ r.draw_inv_atlas(texture, (ax, ay), dest_rec.x, dest_rec.y, size, 0.0);
if self.debug {
r.draw_rectangle_lines_ex(dest_rec, 1.0, Color::YELLOW);
}
}
- /// Returns the known UI height for this frame
- fn get_ui_height(&self) -> u16 {
- self.tile_size
- }
-
- /// Returns the padding used between ui elements
- fn get_ui_padding(&self) -> u16 {
- self.get_ui_height() / 10
- }
-
- /// Returns the font size for the UI
- fn get_ui_font_size(&self) -> u16 {
- self.get_ui_height() / 4
- }
-
/// Draws player HP, inventory, and floor number
fn draw_ui<R>(&self, r: &mut R, dungeon: &Dungeon)
where
R: RaylibDraw,
{
// Draw UI base rect
- r.draw_rectangle_ext(0, 0, self.width, self.get_ui_height(), Color::BLACK);
+ r.draw_rectangle_ext(0, 0, RENDER_WIDTH, UI_HEIGHT, Color::BLACK);
if self.debug {
self.draw_debug_ui(r, dungeon);
@@ -457,32 +516,20 @@ impl Renderer {
where
R: RaylibDraw,
{
- let padding = self.get_ui_padding();
- let y = padding;
+ const Y: u16 = UI_PADDING;
// Draw MAP vert text
- let text_x = padding;
- self.draw_text_vertical(r, b"MAP", text_x, y);
+ const TEXT_X: u16 = UI_PADDING;
+ self.draw_text_vertical(r, b"MAP", TEXT_X, Y);
// Draw minimap in top left of UI bar
- let minimap_x = text_x + self.get_ui_font_size() + padding;
- let minimap_y = padding;
- let size = self.get_ui_height() - padding * 2;
- r.draw_tilemap(&self.tilemap_mm, minimap_x, minimap_y, size / MAP_SIZE, 0);
+ const MINIMAP_X: u16 = TEXT_X + FONT_SIZE + UI_PADDING;
+ r.draw_tilemap(&self.tilemap_mm, MINIMAP_X, Y, 1, 0);
// Draw minimap entity's
- let dot_size = (size / MAP_SIZE).max(1);
let mut draw_dot = |pos: Pos, color| {
let (x, y) = pos.xy();
- let offset_x = x * (size / MAP_SIZE);
- let offset_y = y * (size / MAP_SIZE);
- r.draw_rectangle_ext(
- minimap_x + offset_x,
- minimap_y + offset_y,
- dot_size,
- dot_size,
- color,
- );
+ r.draw_pixel((MINIMAP_X + x).into(), (Y + y).into(), color);
};
// Draw enemy dots
@@ -500,22 +547,16 @@ impl Renderer {
where
R: RaylibDraw,
{
- let slots = downcast!(PLAYER_INVENTORY_SIZE, u16);
- let padding = self.get_ui_padding();
- let font_size = self.get_ui_font_size();
- let ui_height = self.get_ui_height();
-
- let text_len = font_size + padding;
- let slot_len = ui_height - padding * 2;
- let slots_len = slot_len * slots;
- let full_len = text_len + slots_len;
+ const TEXT_LEN: u16 = FONT_SIZE + UI_PADDING;
+ const SLOT_LEN: u16 = UI_HEIGHT - UI_PADDING * 2;
+ const SLOTS_LEN: u16 = SLOT_LEN * PLAYER_INVENTORY_SIZE;
+ const FULL_LEN: u16 = TEXT_LEN + SLOTS_LEN;
- let start_x = self.width / 2 - full_len / 2;
- let text_x = start_x;
- let slots_x = text_x + text_len;
+ const TEXT_X: u16 = RENDER_WIDTH / 2 - FULL_LEN / 2;
+ const SLOTS_X: u16 = TEXT_X + TEXT_LEN;
// Draw text
- self.draw_text_vertical(r, b"INV", text_x, padding);
+ self.draw_text_vertical(r, b"INV", TEXT_X, UI_PADDING);
// Draw slots
for idx in 0..PLAYER_INVENTORY_SIZE {
@@ -525,27 +566,26 @@ impl Renderer {
break;
}
- let slot_x = slots_x + slot_len * downcast!(idx, u16);
- let size = ui_height - padding * 2;
+ let slot_x = SLOTS_X + SLOT_LEN * idx;
// Draw slot container
r.draw_inv_atlas(
&self.textures.atlas,
ATLAS_INV_CONTAINER,
slot_x,
- padding,
- size,
+ UI_PADDING,
+ SLOT_LEN,
0.0,
);
- if let Some(item) = player.inventory.get(idx) {
+ if let Some(item) = player.inventory.get(idx as usize) {
let tex = self.textures.item_texture(item);
- let item_padding = padding * 3;
+ const ITEM_PADDDING: u16 = UI_PADDING * 3;
let dest_rec = rect! {
- slot_x + item_padding / 2,
- padding+ item_padding / 2,
- size - item_padding,
- size - item_padding,
+ slot_x + ITEM_PADDDING/2,
+ UI_PADDING + ITEM_PADDDING/2,
+ SLOT_LEN - ITEM_PADDDING,
+ SLOT_LEN - ITEM_PADDDING,
};
r.draw_texture_pro(
tex,
@@ -567,46 +607,34 @@ impl Renderer {
let health = player.entity.health.unwrap_or(0);
let damage = 0; // TODO: calc damage
- let padding = self.get_ui_padding();
- let font_size = self.get_ui_font_size();
-
- let text_width = font_size * 3 + padding;
- let icon_width = font_size + padding;
- let stats_x = self.width - text_width - icon_width;
- let icon_x = stats_x;
- let text_x = icon_x + icon_width;
+ const TEXT_WIDTH: u16 = FONT_SIZE * 3 + UI_PADDING;
+ const ICON_WIDTH: u16 = FONT_SIZE + UI_PADDING;
+ const ICON_X: u16 = RENDER_WIDTH - TEXT_WIDTH - ICON_WIDTH;
+ const TEXT_X: u16 = RENDER_WIDTH - TEXT_WIDTH;
// draw health
- let heart_y = padding;
- r.draw_inv_atlas(
+ const HEART_Y: u16 = UI_PADDING * 2;
+ r.draw_atlas(
&self.textures.atlas,
ATLAS_HEART_ICON,
- icon_x,
- heart_y,
- icon_width,
+ ICON_X + UI_PADDING,
+ HEART_Y + UI_PADDING,
+ FONT_SIZE,
0.0,
);
- draw_text!(self, r, text_x, heart_y + padding, b"x00", 1, "{health:02}");
+ draw_text!(self, r, TEXT_X, HEART_Y, b"x00", 1, "{health:02}");
// draw damage
- let damage_y = heart_y + font_size + padding;
- r.draw_inv_atlas(
+ const DAMAGE_Y: u16 = HEART_Y + FONT_SIZE + UI_PADDING;
+ r.draw_atlas(
&self.textures.atlas,
ATLAS_DAMAGE_ICON,
- icon_x,
- damage_y,
- icon_width,
+ ICON_X + UI_PADDING,
+ DAMAGE_Y + UI_PADDING,
+ FONT_SIZE,
0.0,
);
- draw_text!(
- self,
- r,
- text_x,
- damage_y + padding,
- b"x00",
- 1,
- "{damage:02}"
- );
+ draw_text!(self, r, TEXT_X, DAMAGE_Y, b"x00", 1, "{damage:02}");
}
/// Draws debug information ontop of other UI elements
@@ -614,39 +642,28 @@ impl Renderer {
where
R: RaylibDraw,
{
- let padding = self.get_ui_padding();
- let font_size = self.get_ui_font_size();
let player = &dungeon.player;
- // X Positions
- let col1 = padding;
- let col2 = padding + font_size * 10;
-
- // Y Positions
- let row1 = padding;
- let row2 = row1 + font_size;
- let row3 = row2 + font_size;
-
// Draw FPS
- draw_text!(self, r, col1, row1, b"FPS ", 4, "{}", self.fps);
+ draw_text!(self, r, UI_COL1, UI_ROW1, b"FPS ", 4, "{}", self.fps);
// Draw Player position
let (x, y) = &player.entity.pos.xy();
- draw_text!(self, r, col1, row2, b"POS 00,00", 4, "{x:02},{y:02}");
+ draw_text!(self, r, UI_COL1, UI_ROW2, b"POS 00,00", 4, "{x:02},{y:02}");
// Draw Player direction
let dir = &player.entity.dir;
- draw_text!(self, r, col1, row3, b"DIR ", 4, "{dir}");
+ draw_text!(self, r, UI_COL1, UI_ROW3, b"DIR ", 4, "{dir}");
// Draw Player Seed
let seed = &dungeon.floor.seed();
draw_text!(
self,
r,
- col2,
- row1,
- b" SEED 0x0000000000000000",
- 8,
+ UI_COL2,
+ UI_ROW1,
+ b" 0000000000000000",
+ 0,
"{seed:X}"
);
@@ -655,10 +672,10 @@ impl Renderer {
draw_text!(
self,
r,
- col2,
- row2,
- b" HASH 0x0000000000000000",
- 8,
+ UI_COL2,
+ UI_ROW2,
+ b" 0000000000000000",
+ 0,
"{hash:X}"
);
@@ -667,8 +684,8 @@ impl Renderer {
draw_text!(
self,
r,
- col2,
- row3,
+ UI_COL2,
+ UI_ROW3,
b"FRAME ",
6,
"{frame}"
@@ -680,9 +697,9 @@ impl Renderer {
where
R: RaylibDraw,
{
- let spacing = self.get_ui_font_size() + self.get_ui_padding() / 2;
+ const SPACING: u16 = FONT_SIZE + UI_PADDING / 2;
for (idx, char) in text.iter().enumerate() {
- let y = y_start + downcast!(idx, u16) * spacing;
+ let y = y_start + downcast!(idx, u16) * SPACING;
self.draw_char(r, *char, x, y);
}
}
@@ -693,7 +710,7 @@ impl Renderer {
R: RaylibDraw,
{
for (idx, char) in text.iter().enumerate() {
- let x = x_start + downcast!(idx, u16) * self.get_ui_font_size();
+ let x = x_start + downcast!(idx, u16) * FONT_SIZE;
self.draw_char(r, *char, x, y);
}
}
@@ -713,12 +730,39 @@ impl Renderer {
(ax.into(), ay.into()),
x,
y,
- self.get_ui_font_size(),
+ FONT_SIZE,
0.0,
);
}
}
+/// Returns the Raylib Camera setup with needed 2D position/transforms
+fn render_camera(dungeon: &Dungeon) -> Camera2D {
+ /// The minimum position the camera is allowed to go
+ const CAMERA_MIN: Vector2 = vec2! {
+ RENDER_WIDTH/2, RENDER_HEIGHT/2 - UI_HEIGHT/2,
+ };
+ /// The maximum position the camera is allowed to go
+ const CAMERA_MAX: Vector2 = vec2! {
+ MAP_SIZE * TILE_SIZE - RENDER_WIDTH/2,
+ MAP_SIZE * TILE_SIZE - RENDER_HEIGHT/2 - UI_HEIGHT/2,
+ };
+
+ let pos = dungeon.camera();
+ Camera2D {
+ target: Vector2::from(pos.xy())
+ .scale_by(TILE_SIZE.into())
+ .max(CAMERA_MIN)
+ .min(CAMERA_MAX),
+ offset: vec2! {
+ RENDER_WIDTH/2,
+ RENDER_HEIGHT/2 + UI_HEIGHT/2,
+ },
+ rotation: 0.0,
+ zoom: 1.0,
+ }
+}
+
trait Vector2Ext {
fn min(self, other: Self) -> Self;
fn max(self, other: Self) -> Self;
@@ -749,10 +793,10 @@ where
) {
let size_into = size.into();
let source_rec = rect! {
- ax * BASE_TEXTURE_SIZE,
- ay * BASE_TEXTURE_SIZE,
- BASE_TEXTURE_SIZE,
- BASE_TEXTURE_SIZE,
+ ax * TEXTURE_SIZE,
+ ay * TEXTURE_SIZE,
+ TEXTURE_SIZE,
+ TEXTURE_SIZE,
};
let dest_rec = rect! {
x.into(),