Almost complete double-res

shader120
Luke D. Jones 2022-05-27 22:05:49 +12:00
parent aee73fcd98
commit e02f2776b5
14 changed files with 257 additions and 169 deletions

24
.vscode/launch.json vendored
View File

@ -61,6 +61,30 @@
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug Doom",
"cargo": {
"args": [
"build",
"--bin=room4doom"
],
"filter": {
"name": "room4doom",
"kind": "bin"
}
},
"args": [
"--iwad",
"/home/luke/DOOM/doom.wad",
"-w1024",
"-h768",
"-v",
"debug"
],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",

View File

@ -9,7 +9,7 @@ panic = "abort"
[profile.dev]
debug = true
opt-level = 2
opt-level = 1
[profile.bench]
debug = false

View File

@ -40,15 +40,20 @@ pub fn d_doom_loop(
ctx: Context,
options: CLIOptions,
) -> Result<(), Box<dyn Error>> {
// TODO: switch 320x200 | 640x400 on option
let screen_width = 640;
let screen_height = 400;
// TODO: implement an openGL or Vulkan renderer
let mut renderer = SoftwareRenderer::new(
screen_width,
screen_height,
game.pic_data.clone(),
matches!(options.verbose, log::LevelFilter::Debug),
);
let mut timestep = TimeStep::new();
let mut render_buffer = PixelBuf::new(320, 200);
let mut render_buffer2 = PixelBuf::new(320, 200);
let mut render_buffer = PixelBuf::new(screen_width as u32, screen_height as u32);
let mut render_buffer2 = PixelBuf::new(screen_width as u32, screen_height as u32);
// TODO: sort this block of stuff out
let wsize = gl.drawable_size();
@ -305,7 +310,14 @@ fn d_display<I, S, H, F>(
}
// TODO: HU_Drawer();
// Fake crosshair
draw_buf.set_pixel(320 / 2, 200 / 2, 200, 14, 14, 255);
draw_buf.set_pixel(
disp_buf.width() as usize / 2,
disp_buf.height() as usize / 2,
200,
14,
14,
255,
);
}
match game.gamestate {

View File

@ -233,7 +233,7 @@ fn main() -> Result<(), Box<dyn Error>> {
if let Some(fullscreen) = options.fullscreen {
if fullscreen {
let mode = if options.width != 320 {
let mode = if options.width != 640 {
sdl2::video::FullscreenType::Desktop
} else {
sdl2::video::FullscreenType::True

View File

@ -144,9 +144,9 @@ impl MapData {
let map_height = self.extents.height as f32;
if map_height > map_width {
self.extents.automap_scale = map_height / 200.0 * 1.1;
self.extents.automap_scale = map_height / 400.0 * 1.1;
} else {
self.extents.automap_scale = map_width / 320.0 * 1.4;
self.extents.automap_scale = map_width / 640.0 * 1.4;
}
}

View File

@ -1,8 +1,8 @@
use crate::{Intermission, State, SHOW_NEXT_LOC_DELAY, TICRATE, TITLE_Y};
use gamestate_traits::{util::draw_num, GameMode, MachinationTrait, PixelBuf};
const SCREEN_WIDTH: i32 = 320;
const SCREEN_HEIGHT: i32 = 200;
const SCREEN_WIDTH: i32 = 640;
const SCREEN_HEIGHT: i32 = 400;
const SP_STATSX: i32 = 50;
const SP_STATSY: i32 = 50;

View File

@ -4,11 +4,7 @@ use super::{
things::VisSprite,
RenderData,
};
use crate::{
defs::{SCREENHEIGHT_HALF, SCREENWIDTH},
planes::make_spans,
utilities::CLASSIC_SCREEN_X_TO_VIEW,
};
use crate::{planes::make_spans, utilities::screen_to_x_view};
use gameplay::{
log::trace, Angle, Level, MapData, MapObject, Node, PicData, Player, Sector, Segment,
SubSector, IS_SSECTOR_MASK,
@ -76,7 +72,7 @@ impl PlayRenderer for SoftwareRenderer {
fn render_player_view(&mut self, player: &Player, level: &Level, pixels: &mut PixelBuf) {
let map = &level.map_data;
self.clear(player);
self.clear(player, pixels.width() as f32);
// TODO: netupdate
let mut count = 0;
self.checked_sectors.clear();
@ -97,9 +93,15 @@ impl PlayRenderer for SoftwareRenderer {
}
impl SoftwareRenderer {
pub fn new(texture_data: Rc<RefCell<PicData>>, debug: bool) -> Self {
pub fn new(
screen_width: usize,
screen_height: usize,
texture_data: Rc<RefCell<PicData>>,
debug: bool,
) -> Self {
dbg!();
Self {
r_data: RenderData::new(),
r_data: RenderData::new(screen_width, screen_height),
seg_renderer: SegRender::new(texture_data.clone()),
new_end: 0,
solidsegs: Vec::new(),
@ -111,14 +113,14 @@ impl SoftwareRenderer {
}
}
fn clear(&mut self, player: &Player) {
fn clear(&mut self, player: &Player, screen_width: f32) {
let view_angle = unsafe { player.mobj_unchecked().angle };
for vis in self.vissprites.iter_mut() {
vis.clear();
}
self.next_vissprite = 0;
self.clear_clip_segs();
self.clear_clip_segs(screen_width);
self.r_data.clear_data(view_angle);
self.seg_renderer = SegRender::new(self.texture_data.clone());
}
@ -139,7 +141,7 @@ impl SoftwareRenderer {
if plane.picnum == self.texture_data.borrow().sky_num() {
let colourmap = textures.colourmap(0);
let sky_mid = SCREENHEIGHT_HALF;
let sky_mid = pixels.height() / 2;
let skytex = textures.sky_pic();
for x in plane.minx.floor() as i32..=plane.maxx.floor() as i32 {
@ -147,7 +149,7 @@ impl SoftwareRenderer {
let dc_yh = plane.bottom[x as usize];
if dc_yl <= dc_yh {
let angle = (view_angle.rad().to_degrees()
+ CLASSIC_SCREEN_X_TO_VIEW[x as usize])
+ screen_to_x_view(x as f32, pixels.width() as f32).to_degrees())
* 2.8444;
let texture_column = textures.wall_pic_column(skytex, angle.floor() as i32);
@ -176,7 +178,7 @@ impl SoftwareRenderer {
plane.baseyscale = baseyscale;
plane.view_angle = view_angle;
let mut span_start = [0.0; SCREENWIDTH];
let mut span_start = vec![0.0; pixels.width() as usize];
for x in plane.minx.floor() as i32..=plane.maxx.floor() as i32 {
let mut step = x - 1;
if step < 0 {
@ -257,8 +259,8 @@ impl SoftwareRenderer {
angle1 += FRAC_PI_2;
angle2 += FRAC_PI_2;
let x1 = angle_to_screen(angle1.rad());
let x2 = angle_to_screen(angle2.rad());
let x1 = angle_to_screen(pixels.width() as f32, angle1.rad());
let x2 = angle_to_screen(pixels.width() as f32, angle2.rad());
// Does not cross a pixel?
if x1 == x2 {
@ -341,7 +343,7 @@ impl SoftwareRenderer {
}
/// R_ClearClipSegs - r_bsp
fn clear_clip_segs(&mut self) {
fn clear_clip_segs(&mut self, screen_width: f32) {
self.solidsegs.clear();
self.solidsegs.push(ClipRange {
first: f32::MAX,
@ -349,7 +351,7 @@ impl SoftwareRenderer {
});
for _ in 0..MAX_SEGS {
self.solidsegs.push(ClipRange {
first: SCREENWIDTH as f32,
first: screen_width,
last: f32::MAX,
});
}
@ -576,7 +578,7 @@ impl SoftwareRenderer {
// Possibly divide back space.
// check if each corner of the BB is in the FOV
//if node.point_in_bounds(&v, side ^ 1) {
if self.bb_extents_in_fov(node, mobj, side ^ 1) {
if self.bb_extents_in_fov(node, mobj, side ^ 1, pixels.width() as f32) {
self.render_bsp_node(map, player, node.child_index[side ^ 1], pixels, count);
}
}
@ -584,7 +586,13 @@ impl SoftwareRenderer {
/// R_CheckBBox - r_bsp
///
/// TODO: solidsegs list
fn bb_extents_in_fov(&self, node: &Node, mobj: &MapObject, side: usize) -> bool {
fn bb_extents_in_fov(
&self,
node: &Node,
mobj: &MapObject,
side: usize,
screen_width: f32,
) -> bool {
let view_angle = mobj.angle;
// BOXTOP = 0
// BOXBOT = 1
@ -697,8 +705,8 @@ impl SoftwareRenderer {
angle1 += FRAC_PI_2;
angle2 += FRAC_PI_2;
let x1 = angle_to_screen(angle1.rad());
let mut x2 = angle_to_screen(angle2.rad());
let x1 = angle_to_screen(screen_width, angle1.rad());
let mut x2 = angle_to_screen(screen_width, angle2.rad());
// Does not cross a pixel?
if x1 == x2 {
@ -718,12 +726,12 @@ impl SoftwareRenderer {
}
}
fn angle_to_screen(mut radian: f32) -> f32 {
fn angle_to_screen(screen_width: f32, mut radian: f32) -> f32 {
let mut x;
// Left side
let p = (SCREENWIDTH / 2) as f32; // / (FRAC_PI_4).tan();
// if radian >= FRAC_PI_2 {
let p = screen_width / 2.0; // / (FRAC_PI_4).tan();
// if radian >= FRAC_PI_2 {
radian -= FRAC_PI_2;
let t = radian.tan();
x = t * p;

View File

@ -7,8 +7,8 @@ pub const SIL_BOTTOM: i32 = 1;
pub const SIL_TOP: i32 = 2;
pub const SIL_BOTH: i32 = 3;
pub const SCREENWIDTH: usize = 320;
pub const SCREENHEIGHT: usize = 200;
pub const SCREENWIDTH: usize = 640;
pub const SCREENHEIGHT: usize = 400;
pub const SCREENHEIGHT_HALF: usize = SCREENHEIGHT / 2;
pub const MAXDRAWSEGS: usize = 1024;

View File

@ -34,13 +34,14 @@ pub(crate) struct RenderData {
}
impl RenderData {
pub(crate) fn new() -> Self {
pub(crate) fn new(screen_width: usize, screen_height: usize) -> Self {
dbg!();
Self {
rw_angle1: Angle::default(),
drawsegs: Vec::new(),
portal_clip: PortalClip::default(),
ds_p: 0,
visplanes: VisPlaneRender::new(),
visplanes: VisPlaneRender::new(screen_width, screen_height),
portal_clip: PortalClip::new(screen_width, screen_height),
}
}
@ -52,3 +53,27 @@ impl RenderData {
self.visplanes.clear_planes(view_angle);
}
}
#[cfg(test)]
mod tests {
use crate::{defs::Visplane, portals::PortalClip, RenderData};
use gameplay::Angle;
#[test]
fn default_portal_clip() {
let mut rd = PortalClip::new(640, 400);
rd.clear();
}
#[test]
fn default_vis_plane_render() {
let mut rd = Visplane::default();
rd.clear();
}
#[test]
fn default_render_data() {
let mut rd = RenderData::new(640, 400);
rd.clear_data(Angle::default());
}
}

View File

@ -1,13 +1,13 @@
use std::f32::consts::FRAC_PI_2;
use crate::{defs::SCREENHEIGHT_HALF, utilities::screen_to_x_view};
use crate::utilities::screen_to_x_view;
use gameplay::{Angle, FlatPic, PicData};
use glam::Vec2;
use render_traits::PixelBuf;
use super::defs::{Visplane, MAXOPENINGS, SCREENHEIGHT, SCREENWIDTH};
use super::defs::{Visplane, MAXOPENINGS};
pub const MAXVISPLANES: usize = 512;
pub const MAXVISPLANES: usize = 256;
pub struct VisPlaneRender {
// Here comes the obnoxious "visplane".
@ -22,29 +22,27 @@ pub struct VisPlaneRender {
pub openings: [f32; MAXOPENINGS],
pub lastopening: f32,
pub floorclip: [f32; SCREENWIDTH],
pub ceilingclip: [f32; SCREENWIDTH],
pub floorclip: Vec<f32>,
pub ceilingclip: Vec<f32>,
/// spanstart holds the start of a plane span
/// initialized to 0 at start
pub spanstart: [f32; SCREENHEIGHT],
pub spanstop: [f32; SCREENHEIGHT],
pub spanstart: Vec<f32>,
pub spanstop: Vec<f32>,
//lighttable_t **planezlight;
pub planeheight: f32,
pub yslope: [f32; SCREENHEIGHT],
pub distscale: [f32; SCREENWIDTH],
pub yslope: Vec<f32>,
pub distscale: Vec<f32>,
pub basexscale: f32,
pub baseyscale: f32,
pub cachedheight: [f32; SCREENHEIGHT],
pub cacheddistance: [f32; SCREENHEIGHT],
pub cachedxstep: [f32; SCREENHEIGHT],
pub cachedystep: [f32; SCREENHEIGHT],
screen_width: f32,
screen_height: f32,
}
impl VisPlaneRender {
pub fn new() -> Self {
pub fn new(screen_width: usize, screen_height: usize) -> Self {
VisPlaneRender {
visplanes: [Visplane::default(); MAXVISPLANES],
lastvisplane: 0,
@ -52,19 +50,17 @@ impl VisPlaneRender {
ceilingplane: 0,
openings: [f32::MAX; MAXOPENINGS],
lastopening: 0.0,
floorclip: [SCREENHEIGHT as f32; SCREENWIDTH],
ceilingclip: [-1.0; SCREENWIDTH],
spanstart: [0.0; SCREENHEIGHT],
spanstop: [0.0; SCREENHEIGHT],
floorclip: vec![screen_height as f32; screen_width],
ceilingclip: vec![-1.0; screen_width],
spanstart: vec![0.0; screen_height],
spanstop: vec![0.0; screen_height],
planeheight: 0.0,
yslope: [0.0; SCREENHEIGHT],
distscale: [0.0; SCREENWIDTH],
yslope: vec![0.0; screen_height],
distscale: vec![0.0; screen_width],
basexscale: 0.0,
baseyscale: 0.0,
cachedheight: [0.0; SCREENHEIGHT],
cacheddistance: [0.0; SCREENHEIGHT],
cachedxstep: [0.0; SCREENHEIGHT],
cachedystep: [0.0; SCREENHEIGHT],
screen_width: screen_width as f32,
screen_height: screen_height as f32,
}
}
@ -72,8 +68,8 @@ impl VisPlaneRender {
/// At begining of frame.
pub fn clear_planes(&mut self, view_angle: Angle) {
// opening / clipping determination
for i in 0..SCREENWIDTH {
self.floorclip[i] = SCREENHEIGHT as f32;
for i in 0..self.floorclip.len() {
self.floorclip[i] = self.screen_height;
self.ceilingclip[i] = -1.0;
}
@ -86,15 +82,10 @@ impl VisPlaneRender {
self.floorplane = 0;
self.ceilingplane = 0;
// texture calculation
// for i in self.cachedheight.iter_mut() {
// *i = 0.0;
// }
// left to right mapping
// TODO: angle = (viewangle - ANG90) >> ANGLETOFINESHIFT;
self.basexscale = (view_angle - FRAC_PI_2).cos() / (SCREENWIDTH / 2) as f32;
self.baseyscale = -((view_angle - FRAC_PI_2).sin() / (SCREENWIDTH / 2) as f32);
self.basexscale = (view_angle - FRAC_PI_2).cos() / (self.screen_width / 2.0);
self.baseyscale = -((view_angle - FRAC_PI_2).sin() / (self.screen_width / 2.0));
}
/// Find a plane matching height, picnum, light level. Otherwise return a new plane.
@ -132,7 +123,7 @@ impl VisPlaneRender {
check.height = height;
check.picnum = picnum;
check.lightlevel = light_level;
check.minx = SCREENWIDTH as f32;
check.minx = self.screen_width;
check.maxx = 0.0;
for t in &mut check.top {
*t = f32::MAX;
@ -163,7 +154,7 @@ impl VisPlaneRender {
// return plane_idx;
// }
for i in intrl.floor() as i32..=SCREENWIDTH as i32 {
for i in intrl.floor() as i32..=self.screen_width as i32 {
if i >= intrh.floor() as i32 {
plane.minx = unionl;
plane.maxx = unionh;
@ -210,7 +201,7 @@ pub fn make_spans(
viewz: f32,
extra_light: i32,
plane: &Visplane,
span_start: &mut [f32; SCREENWIDTH],
span_start: &mut [f32],
texture_data: &PicData,
pixels: &mut PixelBuf,
) {
@ -269,16 +260,16 @@ fn map_plane(
) {
let planeheight = (plane.height - viewz).abs();
// TODO: maybe cache?
let dy = y - SCREENHEIGHT_HALF as f32; // OK
let yslope = (SCREENWIDTH as f32 / 2.0) / dy.abs(); // OK
let dy = y - (pixels.height() as f32 / 2.0); // OK
let yslope = (pixels.width() as f32 / 2.0) / dy.abs(); // OK
let distance = planeheight * yslope; // OK
let ds_xstep = distance * plane.basexscale;
let ds_ystep = distance * plane.baseyscale;
// distance * distscale[i]
let distscale = screen_to_x_view(x1).cos().abs();
let distscale = screen_to_x_view(x1, pixels.width() as f32).cos().abs();
let length = distance * (1.0 / distscale);
let angle = plane.view_angle + screen_to_x_view(x1);
let angle = plane.view_angle + screen_to_x_view(x1, pixels.width() as f32);
let ds_xfrac = viewxy.x + angle.cos() * length;
let ds_yfrac = -viewxy.y - angle.sin() * length;
@ -354,3 +345,14 @@ impl<'a> DrawSpan<'a> {
}
}
}
#[cfg(test)]
mod tests {
use crate::defs::Visplane;
#[test]
fn default_vis_plane_render() {
let mut rd = Visplane::default();
rd.clear();
}
}

View File

@ -1,34 +1,41 @@
//! Vertical clipping for windows/portals, used in Segs render part
//! which will have some of it's function split out to here.
use super::defs::{SCREENHEIGHT, SCREENWIDTH};
pub struct PortalClip {
/// Clip values are the solid pixel bounding the range.
/// floorclip starts out SCREENHEIGHT
/// ceilingclip starts out -1
pub floorclip: [f32; SCREENWIDTH],
pub ceilingclip: [f32; SCREENWIDTH],
pub floorclip: Vec<f32>,
pub ceilingclip: Vec<f32>,
screen_width: usize,
screen_height: usize,
}
impl PortalClip {
pub fn new() -> Self {
pub fn new(screen_width: usize, screen_height: usize) -> Self {
PortalClip {
floorclip: [0.0; SCREENWIDTH],
ceilingclip: [0.0; SCREENWIDTH],
floorclip: vec![0.0; screen_width],
ceilingclip: vec![0.0; screen_width],
screen_width,
screen_height,
}
}
pub(super) fn clear(&mut self) {
for i in 0..SCREENWIDTH {
self.floorclip[i] = SCREENHEIGHT as f32;
for i in 0..self.screen_width {
self.floorclip[i] = self.screen_height as f32;
self.ceilingclip[i] = -1.0;
}
}
}
impl Default for PortalClip {
fn default() -> Self {
PortalClip::new()
#[cfg(test)]
mod tests {
use super::PortalClip;
#[test]
fn default_portal_clip() {
let mut rd = PortalClip::new(640, 400);
rd.clear();
}
}

View File

@ -1,4 +1,4 @@
use crate::{defs::SCREENWIDTH, utilities::screen_to_x_view};
use crate::utilities::screen_to_x_view;
use gameplay::{Angle, LineDefFlags, PicData, Player, Segment};
use render_traits::PixelBuf;
use std::{cell::RefCell, f32::consts::FRAC_PI_2, ptr::NonNull, rc::Rc};
@ -6,7 +6,7 @@ use std::{cell::RefCell, f32::consts::FRAC_PI_2, ptr::NonNull, rc::Rc};
use crate::utilities::{point_to_dist, scale_from_view_angle};
use super::{
defs::{DrawSeg, MAXDRAWSEGS, SCREENHEIGHT_HALF, SIL_BOTH, SIL_BOTTOM, SIL_NONE, SIL_TOP},
defs::{DrawSeg, MAXDRAWSEGS, SIL_BOTH, SIL_BOTTOM, SIL_NONE, SIL_TOP},
RenderData,
};
@ -134,7 +134,7 @@ impl SegRender {
let mut ds_p = &mut rdata.drawsegs[rdata.ds_p];
if !(0.0..SCREENWIDTH as f32).contains(&start) || start > stop {
if !(0.0..pixels.width() as f32 as f32).contains(&start) || start > stop {
panic!("Bad R_RenderWallRange: {} to {}", start, stop);
}
@ -163,11 +163,16 @@ impl SegRender {
let view_angle = mobj.angle;
// TODO: doublecheck the angles and bounds
let visangle = view_angle + screen_to_x_view(start);
self.rw_scale =
scale_from_view_angle(visangle, self.rw_normalangle, self.rw_distance, view_angle);
let visangle = view_angle + screen_to_x_view(start, pixels.width() as f32);
self.rw_scale = scale_from_view_angle(
visangle,
self.rw_normalangle,
self.rw_distance,
view_angle,
pixels.width() as f32,
);
let visangle = view_angle + screen_to_x_view(stop);
let visangle = view_angle + screen_to_x_view(stop, pixels.width() as f32);
ds_p.scale1 = self.rw_scale;
ds_p.x1 = start;
@ -177,8 +182,13 @@ impl SegRender {
if stop > start {
// scale2 and rw_scale appears corrrect
ds_p.scale2 =
scale_from_view_angle(visangle, self.rw_normalangle, self.rw_distance, view_angle);
ds_p.scale2 = scale_from_view_angle(
visangle,
self.rw_normalangle,
self.rw_distance,
view_angle,
pixels.width() as f32,
);
self.rw_scalestep = (ds_p.scale2 - self.rw_scale) / (stop - start);
ds_p.scalestep = self.rw_scalestep;
@ -370,19 +380,19 @@ impl SegRender {
}
self.topstep = -(self.worldtop * self.rw_scalestep);
self.topfrac = SCREENHEIGHT_HALF as f32 - (self.worldtop * self.rw_scale);
self.topfrac = pixels.height() as f32 / 2.0 - (self.worldtop * self.rw_scale);
self.bottomstep = -(self.worldbottom * self.rw_scalestep);
self.bottomfrac = SCREENHEIGHT_HALF as f32 - (self.worldbottom * self.rw_scale);
self.bottomfrac = pixels.height() as f32 / 2.0 - (self.worldbottom * self.rw_scale);
if seg.backsector.is_some() {
if self.worldhigh < self.worldtop {
self.pixhigh = SCREENHEIGHT_HALF as f32 - (self.worldhigh * self.rw_scale);
self.pixhigh = pixels.height() as f32 / 2.0 - (self.worldhigh * self.rw_scale);
self.pixhighstep = -(self.worldhigh * self.rw_scalestep);
}
if self.worldlow > self.worldbottom {
self.pixlow = SCREENHEIGHT_HALF as f32 - (self.worldlow * self.rw_scale);
self.pixlow = pixels.height() as f32 / 2.0 - (self.worldlow * self.rw_scale);
self.pixlowstep = -(self.worldlow * self.rw_scalestep);
}
}
@ -522,7 +532,7 @@ impl SegRender {
let mut dc_iscale = 0.0;
if self.segtextured {
angle = self.rw_centerangle + screen_to_x_view(self.rw_x);
angle = self.rw_centerangle + screen_to_x_view(self.rw_x, pixels.width() as f32);
texture_column = (self.rw_offset - angle.tan() * self.rw_distance).floor() as i32;
dc_iscale = 1.0 / self.rw_scale;
@ -681,7 +691,7 @@ impl<'a> DrawColumn<'a> {
pub fn draw_column(&mut self, textures: &PicData, pixels: &mut PixelBuf) {
let pal = textures.palette();
let mut frac =
self.dc_texturemid + (self.yl as f32 - SCREENHEIGHT_HALF as f32) * self.fracstep;
self.dc_texturemid + (self.yl as f32 - pixels.height() as f32 / 2.0) * self.fracstep;
for n in self.yl.floor() as i32..=self.yh.floor() as i32 {
// (frac - 0.01).floor() is a ridiculous magic number to prevent the

View File

@ -302,8 +302,8 @@ impl SoftwareRenderer {
/// Doom function name `R_DrawSprite`
fn draw_sprite(&mut self, player: &Player, vis: &VisSprite, pixels: &mut PixelBuf) {
let mut clip_bottom = [-2i32; SCREENWIDTH];
let mut clip_top = [-2i32; SCREENWIDTH];
let mut clip_bottom = vec![-2i32; pixels.width() as usize];
let mut clip_top = vec![-2i32; pixels.width() as usize];
// Breaking liftime to enable this loop
let segs = unsafe { &*(&self.r_data.drawsegs as *const Vec<DrawSeg>) };
@ -362,8 +362,8 @@ impl SoftwareRenderer {
clip_top[r as usize] = self.r_data.visplanes.openings
[(seg.sprtopclip.unwrap() + r) as usize]
.floor() as i32;
if clip_top[r as usize] >= SCREENHEIGHT as i32 {
clip_top[r as usize] = SCREENHEIGHT as i32;
if clip_top[r as usize] >= pixels.height() as i32 {
clip_top[r as usize] = pixels.height() as i32;
}
}
}
@ -371,7 +371,7 @@ impl SoftwareRenderer {
for x in vis.x1..=vis.x2 {
if clip_bottom[x as usize] == -2 {
clip_bottom[x as usize] = SCREENHEIGHT as i32;
clip_bottom[x as usize] = pixels.height() as i32;
}
if clip_top[x as usize] == -2 {
clip_top[x as usize] = -1;
@ -414,13 +414,13 @@ impl SoftwareRenderer {
let flip = frame.flip[0];
let mut tx = sprite.sx as i32 - 160 - patch.left_offset;
let x1 = (SCREENWIDTH as i32 / 2) + tx * pspritescale;
let x1 = (pixels.width() as i32 / 2) + tx * pspritescale;
if x1 >= SCREENWIDTH as i32 {
if x1 >= pixels.width() as i32 {
return;
}
tx += patch.data.len() as i32;
let x2 = ((SCREENWIDTH / 2) as i32 + tx * pspritescale) - 1;
let x2 = ((pixels.width() / 2) as i32 + tx * pspritescale) - 1;
if x2 < 0 {
return;
@ -429,10 +429,10 @@ impl SoftwareRenderer {
let mut vis = VisSprite::new();
vis.mobj_flags = flags;
vis.patch = frame.lump[0] as usize;
vis.texture_mid = SCREENHEIGHT_HALF as f32 - (sprite.sy.floor() - patch.top_offset as f32);
vis.texture_mid = -(sprite.sy.floor() - patch.top_offset as f32);
vis.x1 = if x1 < 0 { 0 } else { x1 };
vis.x2 = if x2 >= SCREENWIDTH as i32 {
SCREENWIDTH as i32
vis.x2 = if x2 >= pixels.width() as i32 {
pixels.width() as i32
} else {
x2
};
@ -488,7 +488,6 @@ impl SoftwareRenderer {
ds: &DrawSeg,
x1: i32,
x2: i32,
pixels: &mut PixelBuf,
) {
let seg = unsafe { ds.curline.as_ref() };
@ -548,15 +547,15 @@ impl SoftwareRenderer {
let mut mfloorclip = self.r_data.visplanes.openings
[(ds.sprbottomclip.unwrap() + x) as usize]
as i32;
if mceilingclip >= SCREENHEIGHT as i32 {
mceilingclip = SCREENHEIGHT as i32;
if mceilingclip >= pixels.height() as i32 {
mceilingclip = pixels.height() as i32;
}
if mfloorclip <= 0 {
mfloorclip = 0;
}
// // calculate unclipped screen coordinates for post
let sprtopscreen = SCREENHEIGHT_HALF as f32 - dc_texturemid * spryscale;
let sprtopscreen = (pixels.height() / 2) as f32 - dc_texturemid * spryscale;
let top = sprtopscreen.floor() as i32 + 1;
let bottom = top + (spryscale * texture_column.len() as f32).floor() as i32;
let mut yl = top;
@ -606,7 +605,7 @@ fn draw_masked_column(
pixels: &mut PixelBuf,
) {
let pal = &textures.palette();
let mut frac = dc_texturemid + (yl as f32 - SCREENHEIGHT_HALF as f32) * fracstep;
let mut frac = dc_texturemid + (yl as f32 - (pixels.height() / 2) as f32) * fracstep;
for n in yl..=yh {
let select = frac.floor() as usize;

View File

@ -5,57 +5,57 @@ use glam::Vec2;
use crate::defs::SCREENWIDTH;
fn player_dist_to_screen() -> f32 {
SCREENWIDTH as f32 / 2.0 / (45.0f32.to_radians()).tan()
fn player_dist_to_screen(screen_width: f32) -> f32 {
screen_width as f32 / 2.0 / (45.0f32.to_radians()).tan()
}
pub fn screen_to_x_view(x: f32) -> f32 {
((SCREENWIDTH as f32 / 2.0 - x) / player_dist_to_screen()).atan()
pub fn screen_to_x_view(x: f32, screen_width: f32) -> f32 {
((screen_width as f32 / 2.0 - x) / player_dist_to_screen(screen_width)).atan()
}
#[allow(clippy::excessive_precision)]
pub static CLASSIC_SCREEN_X_TO_VIEW: [f32; 321] = [
45.043945, 44.824219, 44.648437, 44.472656, 44.296875, 44.121094, 43.945312, 43.725586,
43.549805, 43.374023, 43.154297, 42.978516, 42.802734, 42.583008, 42.407227, 42.187500,
42.011719, 41.791992, 41.616211, 41.396484, 41.220703, 41.000977, 40.781250, 40.605469,
40.385742, 40.166016, 39.946289, 39.770508, 39.550781, 39.331055, 39.111328, 38.891602,
38.671875, 38.452148, 38.232422, 38.012695, 37.792969, 37.573242, 37.353516, 37.133789,
36.870117, 36.650391, 36.430664, 36.210937, 35.947266, 35.727539, 35.507812, 35.244141,
35.024414, 34.760742, 34.541016, 34.277344, 34.057617, 33.793945, 33.530273, 33.310547,
33.046875, 32.783203, 32.519531, 32.299805, 32.036133, 31.772461, 31.508789, 31.245117,
30.981445, 30.717773, 30.454102, 30.190430, 29.926758, 29.663086, 29.355469, 29.091797,
28.828125, 28.564453, 28.256836, 27.993164, 27.729492, 27.421875, 27.158203, 26.850586,
26.586914, 26.279297, 26.015625, 25.708008, 25.444336, 25.136719, 24.829102, 24.521484,
24.257812, 23.950195, 23.642578, 23.334961, 23.027344, 22.719727, 22.412109, 22.104492,
21.796875, 21.489258, 21.181641, 20.874023, 20.566406, 20.258789, 19.951172, 19.643555,
19.291992, 18.984375, 18.676758, 18.325195, 18.017578, 17.709961, 17.358398, 17.050781,
16.699219, 16.391602, 16.040039, 15.732422, 15.380859, 15.073242, 14.721680, 14.370117,
14.062500, 13.710937, 13.359375, 13.051758, 12.700195, 12.348633, 11.997070, 11.645508,
11.337891, 10.986328, 10.634766, 10.283203, 9.931641, 9.580078, 9.228516, 8.876953, 8.525391,
8.173828, 7.822266, 7.470703, 7.119141, 6.767578, 6.416016, 6.064453, 5.712891, 5.361328,
5.009766, 4.658203, 4.306641, 3.955078, 3.559570, 3.208008, 2.856445, 2.504883, 2.153320,
1.801758, 1.450195, 1.054687, 0.703125, 0.351562, 0.000000, 359.648437, 359.296875, 358.945312,
358.549805, 358.198242, 357.846680, 357.495117, 357.143555, 356.791992, 356.440430, 356.044922,
355.693359, 355.341797, 354.990234, 354.638672, 354.287109, 353.935547, 353.583984, 353.232422,
352.880859, 352.529297, 352.177734, 351.826172, 351.474609, 351.123047, 350.771484, 350.419922,
350.068359, 349.716797, 349.365234, 349.013672, 348.662109, 348.354492, 348.002930, 347.651367,
347.299805, 346.948242, 346.640625, 346.289062, 345.937500, 345.629883, 345.278320, 344.926758,
344.619141, 344.267578, 343.959961, 343.608398, 343.300781, 342.949219, 342.641601, 342.290039,
341.982422, 341.674805, 341.323242, 341.015625, 340.708008, 340.356445, 340.048828, 339.741211,
339.433594, 339.125977, 338.818359, 338.510742, 338.203125, 337.895508, 337.587891, 337.280273,
336.972656, 336.665039, 336.357422, 336.049805, 335.742187, 335.478516, 335.170898, 334.863281,
334.555664, 334.291992, 333.984375, 333.720703, 333.413086, 333.149414, 332.841797, 332.578125,
332.270508, 332.006836, 331.743164, 331.435547, 331.171875, 330.908203, 330.644531, 330.336914,
330.073242, 329.809570, 329.545898, 329.282227, 329.018555, 328.754883, 328.491211, 328.227539,
327.963867, 327.700195, 327.480469, 327.216797, 326.953125, 326.689453, 326.469727, 326.206055,
325.942383, 325.722656, 325.458984, 325.239258, 324.975586, 324.755859, 324.492187, 324.272461,
324.052734, 323.789062, 323.569336, 323.349609, 323.129883, 322.866211, 322.646484, 322.426758,
322.207031, 321.987305, 321.767578, 321.547852, 321.328125, 321.108398, 320.888672, 320.668945,
320.449219, 320.229492, 320.053711, 319.833984, 319.614258, 319.394531, 319.218750, 318.999023,
318.779297, 318.603516, 318.383789, 318.208008, 317.988281, 317.812500, 317.592773, 317.416992,
317.197266, 317.021484, 316.845703, 316.625977, 316.450195, 316.274414, 316.054687, 315.878906,
315.703125, 315.527344, 315.351562, 315.175781, 314.956055,
];
// #[allow(clippy::excessive_precision)]
// pub static CLASSIC_SCREEN_X_TO_VIEW: [f32; 321] = [
// 45.043945, 44.824219, 44.648437, 44.472656, 44.296875, 44.121094, 43.945312, 43.725586,
// 43.549805, 43.374023, 43.154297, 42.978516, 42.802734, 42.583008, 42.407227, 42.187500,
// 42.011719, 41.791992, 41.616211, 41.396484, 41.220703, 41.000977, 40.781250, 40.605469,
// 40.385742, 40.166016, 39.946289, 39.770508, 39.550781, 39.331055, 39.111328, 38.891602,
// 38.671875, 38.452148, 38.232422, 38.012695, 37.792969, 37.573242, 37.353516, 37.133789,
// 36.870117, 36.650391, 36.430664, 36.210937, 35.947266, 35.727539, 35.507812, 35.244141,
// 35.024414, 34.760742, 34.541016, 34.277344, 34.057617, 33.793945, 33.530273, 33.310547,
// 33.046875, 32.783203, 32.519531, 32.299805, 32.036133, 31.772461, 31.508789, 31.245117,
// 30.981445, 30.717773, 30.454102, 30.190430, 29.926758, 29.663086, 29.355469, 29.091797,
// 28.828125, 28.564453, 28.256836, 27.993164, 27.729492, 27.421875, 27.158203, 26.850586,
// 26.586914, 26.279297, 26.015625, 25.708008, 25.444336, 25.136719, 24.829102, 24.521484,
// 24.257812, 23.950195, 23.642578, 23.334961, 23.027344, 22.719727, 22.412109, 22.104492,
// 21.796875, 21.489258, 21.181641, 20.874023, 20.566406, 20.258789, 19.951172, 19.643555,
// 19.291992, 18.984375, 18.676758, 18.325195, 18.017578, 17.709961, 17.358398, 17.050781,
// 16.699219, 16.391602, 16.040039, 15.732422, 15.380859, 15.073242, 14.721680, 14.370117,
// 14.062500, 13.710937, 13.359375, 13.051758, 12.700195, 12.348633, 11.997070, 11.645508,
// 11.337891, 10.986328, 10.634766, 10.283203, 9.931641, 9.580078, 9.228516, 8.876953, 8.525391,
// 8.173828, 7.822266, 7.470703, 7.119141, 6.767578, 6.416016, 6.064453, 5.712891, 5.361328,
// 5.009766, 4.658203, 4.306641, 3.955078, 3.559570, 3.208008, 2.856445, 2.504883, 2.153320,
// 1.801758, 1.450195, 1.054687, 0.703125, 0.351562, 0.000000, 359.648437, 359.296875, 358.945312,
// 358.549805, 358.198242, 357.846680, 357.495117, 357.143555, 356.791992, 356.440430, 356.044922,
// 355.693359, 355.341797, 354.990234, 354.638672, 354.287109, 353.935547, 353.583984, 353.232422,
// 352.880859, 352.529297, 352.177734, 351.826172, 351.474609, 351.123047, 350.771484, 350.419922,
// 350.068359, 349.716797, 349.365234, 349.013672, 348.662109, 348.354492, 348.002930, 347.651367,
// 347.299805, 346.948242, 346.640625, 346.289062, 345.937500, 345.629883, 345.278320, 344.926758,
// 344.619141, 344.267578, 343.959961, 343.608398, 343.300781, 342.949219, 342.641601, 342.290039,
// 341.982422, 341.674805, 341.323242, 341.015625, 340.708008, 340.356445, 340.048828, 339.741211,
// 339.433594, 339.125977, 338.818359, 338.510742, 338.203125, 337.895508, 337.587891, 337.280273,
// 336.972656, 336.665039, 336.357422, 336.049805, 335.742187, 335.478516, 335.170898, 334.863281,
// 334.555664, 334.291992, 333.984375, 333.720703, 333.413086, 333.149414, 332.841797, 332.578125,
// 332.270508, 332.006836, 331.743164, 331.435547, 331.171875, 330.908203, 330.644531, 330.336914,
// 330.073242, 329.809570, 329.545898, 329.282227, 329.018555, 328.754883, 328.491211, 328.227539,
// 327.963867, 327.700195, 327.480469, 327.216797, 326.953125, 326.689453, 326.469727, 326.206055,
// 325.942383, 325.722656, 325.458984, 325.239258, 324.975586, 324.755859, 324.492187, 324.272461,
// 324.052734, 323.789062, 323.569336, 323.349609, 323.129883, 322.866211, 322.646484, 322.426758,
// 322.207031, 321.987305, 321.767578, 321.547852, 321.328125, 321.108398, 320.888672, 320.668945,
// 320.449219, 320.229492, 320.053711, 319.833984, 319.614258, 319.394531, 319.218750, 318.999023,
// 318.779297, 318.603516, 318.383789, 318.208008, 317.988281, 317.812500, 317.592773, 317.416992,
// 317.197266, 317.021484, 316.845703, 316.625977, 316.450195, 316.274414, 316.054687, 315.878906,
// 315.703125, 315.527344, 315.351562, 315.175781, 314.956055,
// ];
/// R_PointToDist
pub fn point_to_dist(x: f32, y: f32, to: Vec2) -> f32 {
@ -75,6 +75,7 @@ pub fn scale_from_view_angle(
rw_normalangle: Angle,
rw_distance: f32,
view_angle: Angle,
screen_width: f32,
) -> f32 {
let anglea = Angle::new(FRAC_PI_2 + (visangle - view_angle).rad()); // CORRECT
let angleb = Angle::new(FRAC_PI_2 + (visangle - rw_normalangle).rad()); // CORRECT
@ -84,7 +85,7 @@ pub fn scale_from_view_angle(
// projection
//m_iDistancePlayerToScreen = m_HalfScreenWidth / HalfFOV.GetTanValue();
let p = (SCREENWIDTH / 2) as f32; // / (FRAC_PI_4).tan();
let p = screen_width / 2.0; // / (FRAC_PI_4).tan();
let num = p * sineb;
let den = rw_distance * sinea;