Add scaling

This commit is contained in:
crumblingstatue 2023-04-06 20:44:18 +02:00
parent b2ccd962c9
commit ae380bb635
3 changed files with 45 additions and 15 deletions

View file

@ -1,17 +1,20 @@
use std::fmt::{self}; use std::fmt::{self};
use anyhow::Context;
use egui_sfml::{egui, SfEgui}; use egui_sfml::{egui, SfEgui};
use gamedebug_core::{imm, imm_dbg}; use gamedebug_core::{imm, imm_dbg};
use sfml::{ use sfml::{
audio::SoundSource, audio::SoundSource,
graphics::{Color, RenderTarget, RenderWindow}, graphics::{
Color, Rect, RenderTarget, RenderTexture, RenderWindow, Sprite, Transformable, View,
},
window::{Event, Key}, window::{Event, Key},
}; };
use crate::{ use crate::{
debug::DebugState, debug::DebugState,
game::{for_each_tile_on_screen, Biome, GameState}, game::{for_each_tile_on_screen, Biome, GameState},
graphics::{self, NATIVE_RESOLUTION}, graphics::{self, ScreenPosScalar, NATIVE_RESOLUTION},
input::Input, input::Input,
math::{px_per_frame_to_km_h, WorldPos, M_PER_PX, TILE_SIZE}, math::{px_per_frame_to_km_h, WorldPos, M_PER_PX, TILE_SIZE},
res::Res, res::Res,
@ -27,6 +30,10 @@ pub struct App {
pub sf_egui: SfEgui, pub sf_egui: SfEgui,
pub input: Input, pub input: Input,
pub debug: DebugState, pub debug: DebugState,
/// Integer scale for rendering the game
pub scale: u8,
/// RenderTexture for rendering the game at its native resolution
pub rt: RenderTexture,
} }
impl App { impl App {
@ -37,6 +44,8 @@ impl App {
res.surf_music.set_looping(true); res.surf_music.set_looping(true);
res.surf_music.set_volume(10.0); res.surf_music.set_volume(10.0);
res.surf_music.play(); res.surf_music.play();
let rt = RenderTexture::new(NATIVE_RESOLUTION.w.into(), NATIVE_RESOLUTION.h.into())
.context("Failed to create render texture")?;
Ok(Self { Ok(Self {
rw, rw,
should_quit: false, should_quit: false,
@ -45,6 +54,8 @@ impl App {
sf_egui, sf_egui,
input: Input::default(), input: Input::default(),
debug: DebugState::default(), debug: DebugState::default(),
scale: 1,
rt,
}) })
} }
@ -64,6 +75,10 @@ impl App {
self.input.update_from_event(&ev); self.input.update_from_event(&ev);
match ev { match ev {
Event::Closed => self.should_quit = true, Event::Closed => self.should_quit = true,
Event::Resized { width, height } => {
let view = View::from_rect(Rect::new(0., 0., width as f32, height as f32));
self.rw.set_view(&view);
}
_ => {} _ => {}
} }
} }
@ -147,7 +162,9 @@ impl App {
self.game.camera_offset.y = self.game.camera_offset.y =
(y - NATIVE_RESOLUTION.h as i32 / 2).try_into().unwrap_or(0); (y - NATIVE_RESOLUTION.h as i32 / 2).try_into().unwrap_or(0);
} }
let loc = self.input.mouse_down_loc; let mut loc = self.input.mouse_down_loc;
loc.x /= self.scale as ScreenPosScalar;
loc.y /= self.scale as ScreenPosScalar;
let mut wpos = self.game.camera_offset; let mut wpos = self.game.camera_offset;
wpos.x = wpos.x.saturating_add_signed(loc.x.into()); wpos.x = wpos.x.saturating_add_signed(loc.x.into());
wpos.y = wpos.y.saturating_add_signed(loc.y.into()); wpos.y = wpos.y.saturating_add_signed(loc.y.into());
@ -219,14 +236,24 @@ impl App {
} }
fn do_rendering(&mut self) { fn do_rendering(&mut self) {
self.rw.clear(Color::rgb(55, 221, 231)); self.rt.clear(Color::rgb(55, 221, 231));
self.game.render_pre_step(&mut self.res); self.game.render_pre_step(&mut self.res);
self.game.draw_world(&mut self.rw, &mut self.res); self.game.draw_world(&mut self.rt, &mut self.res);
self.game.draw_entities(&mut self.rw, &mut self.res); self.game.draw_entities(&mut self.rt, &mut self.res);
self.rt.display();
let mut spr = Sprite::with_texture(self.rt.texture());
spr.set_scale((self.scale as f32, self.scale as f32));
self.rw.draw(&spr);
self.sf_egui self.sf_egui
.do_frame(|ctx| { .do_frame(|ctx| {
if self.debug.panel { if self.debug.panel {
debug_panel_ui(&mut self.debug, &mut self.game, ctx, &mut self.res); debug_panel_ui(
&mut self.debug,
&mut self.game,
ctx,
&mut self.res,
&mut self.scale,
);
} }
}) })
.unwrap(); .unwrap();
@ -240,6 +267,7 @@ fn debug_panel_ui(
game: &mut GameState, game: &mut GameState,
ctx: &egui::Context, ctx: &egui::Context,
res: &mut Res, res: &mut Res,
scale: &mut u8,
) { ) {
egui::Window::new("Debug (F12)").show(ctx, |ui| { egui::Window::new("Debug (F12)").show(ctx, |ui| {
if debug.freecam { if debug.freecam {
@ -293,6 +321,8 @@ fn debug_panel_ui(
ui.separator(); ui.separator();
ui.label("Ambient light"); ui.label("Ambient light");
ui.add(egui::DragValue::new(&mut game.ambient_light).speed(0.01)); ui.add(egui::DragValue::new(&mut game.ambient_light).speed(0.01));
ui.label("Scale");
ui.add(egui::DragValue::new(scale));
egui::ScrollArea::vertical().show(ui, |ui| { egui::ScrollArea::vertical().show(ui, |ui| {
gamedebug_core::for_each_imm(|info| match info { gamedebug_core::for_each_imm(|info| match info {
gamedebug_core::Info::Msg(msg) => { gamedebug_core::Info::Msg(msg) => {

View file

@ -3,7 +3,7 @@ mod player;
use sfml::{ use sfml::{
graphics::{ graphics::{
glsl::{Vec2, Vec4}, glsl::{Vec2, Vec4},
Color, Rect, RectangleShape, RenderStates, RenderTarget, RenderWindow, Shape, Sprite, Color, Rect, RectangleShape, RenderStates, RenderTarget, RenderTexture, Shape, Sprite,
Transformable, Transformable,
}, },
system::Clock, system::Clock,
@ -40,7 +40,7 @@ pub enum Biome {
} }
impl GameState { impl GameState {
pub(crate) fn draw_world(&mut self, rw: &mut RenderWindow, res: &mut Res) { pub(crate) fn draw_world(&mut self, rw: &mut RenderTexture, res: &mut Res) {
let mut rs = RenderStates::default(); let mut rs = RenderStates::default();
res.lighting_shader.set_uniform_bool("has_texture", true); res.lighting_shader.set_uniform_bool("has_texture", true);
rs.set_shader(Some(&res.lighting_shader)); rs.set_shader(Some(&res.lighting_shader));
@ -62,7 +62,7 @@ impl GameState {
} }
}); });
} }
pub fn draw_entities(&mut self, rw: &mut RenderWindow, res: &mut Res) { pub fn draw_entities(&mut self, rw: &mut RenderTexture, res: &mut Res) {
let mut rend_st = RenderStates::default(); let mut rend_st = RenderStates::default();
res.lighting_shader.set_uniform_bool("has_texture", false); res.lighting_shader.set_uniform_bool("has_texture", false);
rend_st.set_shader(Some(&res.lighting_shader)); rend_st.set_shader(Some(&res.lighting_shader));
@ -120,8 +120,8 @@ impl GameState {
} }
pub fn for_each_tile_on_screen(camera_offset: WorldPos, mut f: impl FnMut(TilePos, ScreenPos)) { pub fn for_each_tile_on_screen(camera_offset: WorldPos, mut f: impl FnMut(TilePos, ScreenPos)) {
for y in (-32..NATIVE_RESOLUTION.h + 32).step_by(32) { for y in (-32..(NATIVE_RESOLUTION.h as i16) + 32).step_by(32) {
for x in (-32..NATIVE_RESOLUTION.w + 32).step_by(32) { for x in (-32..(NATIVE_RESOLUTION.w as i16) + 32).step_by(32) {
f( f(
TilePos { TilePos {
x: wp_to_tp(camera_offset.x.saturating_add(x.try_into().unwrap_or(0))), x: wp_to_tp(camera_offset.x.saturating_add(x.try_into().unwrap_or(0))),

View file

@ -8,8 +8,8 @@ use sfml_xt::graphics::RenderWindowExt;
use crate::math::FPS_TARGET; use crate::math::FPS_TARGET;
pub struct ScreenRes { pub struct ScreenRes {
pub w: i16, pub w: u16,
pub h: i16, pub h: u16,
} }
impl ScreenRes { impl ScreenRes {
@ -43,7 +43,7 @@ pub fn make_window() -> RenderWindow {
let mut rw = RenderWindow::new( let mut rw = RenderWindow::new(
NATIVE_RESOLUTION.to_sf(), NATIVE_RESOLUTION.to_sf(),
"Mantle Diver", "Mantle Diver",
Style::CLOSE, Style::DEFAULT,
&ContextSettings::default(), &ContextSettings::default(),
); );
rw.set_framerate_limit(FPS_TARGET.into()); rw.set_framerate_limit(FPS_TARGET.into());