diff options
Diffstat (limited to 'src/camera.rs')
| -rw-r--r-- | src/camera.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/camera.rs b/src/camera.rs new file mode 100644 index 0000000..695baf5 --- /dev/null +++ b/src/camera.rs @@ -0,0 +1,58 @@ +use crate::{ + config::{PIXEL_BUFFER_HEIGHT, PIXEL_BUFFER_WIDTH}, + sim::{board::Board, materials::MATERIALS}, +}; + +pub struct CameraState { + // centre coords + pub x: f64, + pub y: f64, + // zoom scale factor, 1.0 = board <-> frame + pub zoom: f64, +} + +pub fn screen_position_to_board( + board: &Board, + camera: &CameraState, + screen_x: f64, + screen_y: f64, +) -> (f64, f64) { + let camera_width = camera.zoom * f64::from(board.size_x); + let camera_height = camera.zoom * f64::from(board.size_y); + let camera_start_x = camera.x - camera_width / 2.0; + let camera_start_y = camera.y - camera_height / 2.0; + ( + (screen_x / PIXEL_BUFFER_WIDTH as f64 * camera_width) + camera_start_x, + (screen_y / PIXEL_BUFFER_HEIGHT as f64 * camera_height) + camera_start_y, + ) +} + +pub fn write_frame_view( + frame: &mut [u8], + board: &Board, + camera: &CameraState, + get_overlay: impl Fn(i32, i32) -> (u8, u8, u8, u8), +) { + for frame_y in 0..PIXEL_BUFFER_HEIGHT { + for frame_x in 0..PIXEL_BUFFER_WIDTH { + let (x_coord, y_coord) = + screen_position_to_board(board, camera, frame_x as f64, frame_y as f64); + + let cell = board.cell_at_position(x_coord as i32, y_coord as i32); + let cell_color: Option<(u8, u8, u8, u8)> = cell.map(|c| { + let m = MATERIALS[c.material as usize]; + (m.r, m.g, m.b, 0xFF) + }); + let off_grid_color: (u8, u8, u8, u8) = (0x00, 0x00, 0x00, 0xFF); + + let target_color: (u8, u8, u8, u8) = cell_color.unwrap_or(off_grid_color); + let overlay = get_overlay(x_coord as i32, y_coord as i32); + + let frame_idx = ((frame_y * PIXEL_BUFFER_WIDTH + frame_x) * 4) as usize; + frame[frame_idx] = target_color.0.saturating_add(overlay.0); + frame[frame_idx + 1] = target_color.1.saturating_add(overlay.1); + frame[frame_idx + 2] = target_color.2.saturating_add(overlay.2); + frame[frame_idx + 3] = target_color.3.saturating_add(overlay.3); + } + } +} |
