@ -17,7 +17,7 @@ union ColorConv {
} ;
inline uint32_t dumb_lighting ( uint32_t pixel , double distance ) {
if ( distance < 1 ) return pixel ;
if ( distance < 1.0 ) return pixel ;
ColorConv conv { . as_int = pixel } ;
conv . as_color . r / = distance ;
@ -84,7 +84,8 @@ void Raycaster::sprite_casting() {
for ( int i = 0 ; i < $ textures . NUM_SPRITES ; i + + ) {
int sprite_index = spriteOrder [ i ] ;
Sprite & sprite_rec = $ textures . get_sprite ( sprite_index ) ;
auto & sprite_texture = $ textures . get_texture ( sprite_rec . texture ) ;
// auto& sprite_texture = $textures.get_texture(sprite_rec.texture);
sf : : Sprite * sf_sprite = sprite_rec . sprite ;
double spriteX = sprite_rec . x - $ posX ;
double spriteY = sprite_rec . y - $ posY ;
@ -103,18 +104,10 @@ void Raycaster::sprite_casting() {
int spriteScreenX = int ( ( $ width / 2 ) * ( 1 + transformX / transformY ) ) ;
int vMoveScreen = int ( sprite_rec . elevation * - 1 / transformY ) ;
// calculate the height of the sprite on screen
//using "transformY" instead of the real distance prevents fisheye
int spriteHeight = abs ( int ( $ height / transformY ) ) / sprite_rec . vDiv ;
//calculate lowest and highest pixel to fill in current stripe
int drawStartY = - spriteHeight / 2 + $ height / 2 + vMoveScreen ;
if ( drawStartY < 0 ) drawStartY = 0 ;
int drawEndY = spriteHeight / 2 + $ height / 2 + vMoveScreen ;
if ( drawEndY > = $ height ) drawEndY = $ height - 1 ;
// calculate width the the sprite
// same as height of sprite, given that it's square
int spriteWidth = abs ( int ( $ height / transformY ) ) / sprite_rec . uDiv ;
@ -123,29 +116,29 @@ void Raycaster::sprite_casting() {
int drawEndX = spriteWidth / 2 + spriteScreenX ;
if ( drawEndX > $ width ) drawEndX = $ width ;
//loop through every vertical stripe of the sprite on screen
for ( int stripe = drawStartX ; stripe < drawEndX ; stripe + + ) {
int texX = int ( 256 * ( stripe - ( - spriteWidth / 2 + spriteScreenX ) ) * textureWidth / spriteWidth ) / 256 ;
// the conditions in the if are:
// 1) it's in front of the camera plane so you don't see things behind you
// 2) ZBuffer, with perpendicular distance
if ( transformY > 0 & & transformY < ZBuffer [ stripe ] ) {
for ( int y = drawStartY ; y < drawEndY ; y + + ) {
//256 and 128 factors to avoid floats
int d = ( y - vMoveScreen ) * 256 - $ height * 128 + spriteHeight * 128 ;
int texY = ( ( d * textureHeight ) / spriteHeight ) / 256 ;
//get current color from the texture
// BUG: this crashes sometimes when the math goes out of bounds
int index = textureWidth * texY + texX ;
if ( index < 0 | | ( size_t ) index > = sprite_texture . size ( ) ) continue ;
uint32_t color = sprite_texture [ index ] ;
// poor person's transparency, get current color from the texture
if ( ( color & 0x00FFFFFF ) ! = 0 ) {
RGBA pixel = color ;
$ pixels [ pixcoord ( stripe , y ) ] = pixel ;
}
}
}
if ( drawStartX < drawEndX & & transformY > 0 & & transformY < ZBuffer [ drawStartX ] ) {
int vMoveScreen = int ( sprite_rec . elevation * - 1 / transformY ) ;
//calculate lowest and highest pixel to fill in current stripe
int drawStartY = - spriteHeight / 2 + $ height / 2 + vMoveScreen ;
if ( drawStartY < 0 ) drawStartY = 0 ;
int drawEndY = spriteHeight / 2 + $ height / 2 + vMoveScreen ;
if ( drawEndY > = $ height ) drawEndY = $ height - 1 ;
float x = float ( drawStartX + RAY_VIEW_X ) ;
float y = float ( drawStartY + RAY_VIEW_Y ) ;
float sprite_w = float ( spriteWidth ) / float ( textureWidth ) ;
float sprite_h = float ( spriteHeight ) / float ( textureHeight ) ;
int texX = int ( 256 * ( drawStartX - ( - spriteWidth / 2 + spriteScreenX ) ) * textureWidth / spriteWidth ) / 256 ;
int texX_end = int ( 256 * ( drawEndX - ( - spriteWidth / 2 + spriteScreenX ) ) * textureWidth / spriteWidth ) / 256 ;
int d = ( y - vMoveScreen ) * 256 - $ height * 128 + spriteHeight * 128 ;
int texY = ( ( d * textureHeight ) / spriteHeight ) / 256 ;
sf_sprite - > setScale ( { sprite_h , sprite_w } ) ;
sf_sprite - > setTextureRect ( sf : : IntRect ( { texX , texY } , { texX_end , textureHeight } ) ) ;
sf_sprite - > setPosition ( { x , y } ) ;
$ window . draw ( * sf_sprite ) ;
}
}
}
@ -328,8 +321,8 @@ void Raycaster::draw_ceiling_floor() {
void Raycaster : : render ( ) {
draw_ceiling_floor ( ) ;
cast_rays ( ) ;
sprite_casting ( ) ;
draw_pixel_buffer ( ) ;
sprite_casting ( ) ;
}
bool Raycaster : : empty_space ( int new_x , int new_y ) {