@@ -11,6 +11,7 @@
# include <unordered_map>
# include <stdexcept>
# include <algorithm>
# include "triggers.h"
# define FOV 277
@@ -45,8 +46,8 @@ vec2 position = { 1056.0f, 3616.0f };
//vec2 position = {975.0f, -3525.0f};
float orientation = 90.0f ; //270.0f;
//float orientation = 180.0f;
float height = 32.0f ;
float real_height = 32.0f ;
float height = 41.0f ;
float real_height = 41.0f ;
float accel = 500.0f ;
float speed = 0.0f ;
@@ -60,6 +61,7 @@ float dt;
Uint32 * palette ;
//draw::surface_t *gif;
draw : : surface_t * spr ;
draw : : surface_t * sky ;
int drawColumn_count = 0 ;
@@ -233,7 +235,7 @@ void loadMap(const char* name)
for ( int i = 0 ; i < 8 ; + + i ) txt [ i ] = toupper ( * ( s + + ) ) ;
sec . floor_surf = wad : : loadFlat ( txt ) ;
for ( int i = 0 ; i < 8 ; + + i ) txt [ i ] = toupper ( * ( s + + ) ) ;
sec . ceil_surf = wad : : loadFlat ( txt ) ;
sec . ceil_surf = ( strcmp ( txt , " F_SKY1 " ) = = 0 ) ? nullptr : wad : : loadFlat ( txt ) ;
s + = 6 ;
sectors . push_back ( sec ) ;
}
@@ -305,80 +307,6 @@ void loadMap(const char* name)
}
/*
void createMap()
{
current_sector = 0;
{
sector s;
s.floor_height = 32.0f;
s.ceiling_height = 96.0f;
s.floor_surf = wad::loadFlat("FLOOR4_8");
s.ceil_surf = wad::loadFlat("CEIL3_1");
s.verts.push_back({ 64.0f, 0.0f});
s.verts.push_back({256.0f, 0.0f});
s.verts.push_back({256.0f, 64.0f});
s.verts.push_back({320.0f, 64.0f});
s.verts.push_back({320.0f, 320.0f});
s.verts.push_back({ 0.0f, 320.0f});
s.verts.push_back({ 0.0f, 64.0f});
s.verts.push_back({ 64.0f, 64.0f});
s.walls.push_back({0,1,{0,0},0.0f,0.0f, 1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({1,2,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({2,3,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({3,4,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({4,5,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({5,6,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({6,7,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({7,0,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
sectors.push_back(s);
}
{
sector s;
s.floor_height = 0.0f;
s.ceiling_height = 128.0f;
s.floor_surf = wad::loadFlat("FLOOR4_8");
s.ceil_surf = wad::loadFlat("CEIL3_1");
s.verts.push_back({256.0f, 0.0f});
s.verts.push_back({ 64.0f, 0.0f});
s.verts.push_back({ 64.0f,-256.0f});
s.verts.push_back({256.0f,-256.0f});
s.verts.push_back({128.0f,-128.0f});
s.verts.push_back({192.0f,-128.0f});
s.verts.push_back({192.0f,-192.0f});
s.verts.push_back({128.0f,-192.0f});
s.walls.push_back({0,1,{0,0},0.0f,0.0f, 0, wad::loadTexture("BROWNPIP")});
s.walls.push_back({1,2,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({2,3,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({3,0,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({4,5,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({5,6,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({6,7,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
s.walls.push_back({7,4,{0,0},0.0f,0.0f,-1, wad::loadTexture("BROWNPIP")});
sectors.push_back(s);
}
for (auto &s : sectors )
{
for (auto &w : s.walls )
{
w.u2 = distance(s.verts[w.v1], s.verts[w.v2]) / w.surf->w;
//w.v2 = distance(s.verts[w.v1], s.verts[w.v2]) / 32.0f;
vec2 norm = { s.verts[w.v2].x - s.verts[w.v1].x, s.verts[w.v2].y - s.verts[w.v1].y};
normalize(&norm);
const float tmp = norm.x; norm.x = -norm.y; norm.y = tmp;
w.normal = norm;
}
}
}
*/
int actual_sector = - 1 ;
int last_sector = - 1 ;
void drawColumn ( sector & s , int screen_column , int start , int end , float a_inc , vec2 origin , vec2 infi )
@@ -429,15 +357,16 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
}
// Pinta el sostre
for ( int y = start ; y < wall_start - 1 ; y + + ) {
float straight_dist = ( FOV * ( sector_height - ( height - s . floor_height ) ) ) / ( y - ( 240 > > 1 ) ) ;
float actual_dist = straight_dist / SDL_cosf ( a_inc * DEG_TO_RAD ) ;
int tx = SDL_abs ( int ( actual_dist * SDL_cosf ( angle * DEG_TO_RAD ) - position . x ) ) % s . ceil_surf - > w ;
int ty = SDL_abs ( int ( actual_dist * SDL_sinf ( angle * DEG_TO_RAD ) - position . y ) ) % s . ceil_surf - > h ;
draw : : putpd ( screen_column , y , s . ceil_surf - > pixels [ tx + ty * s . ceil_surf - > w ] , - straight_dist ) ;
if ( s . ceil_surf ) { // No el pintes si es el cel
for ( int y = start ; y < wall_start - 1 ; y + + ) {
float straight_dist = ( FOV * ( sector_height - ( height - s . floor_height ) ) ) / ( y - ( 240 > > 1 ) ) ;
float actual_dist = straight_dist / SDL_cosf ( a_inc * DEG_TO_RAD ) ;
int tx = SDL_abs ( int ( actual_dist * SDL_cosf ( angle * DEG_TO_RAD ) - position . x ) ) % s . ceil_surf - > w ;
int ty = SDL_abs ( int ( actual_dist * SDL_sinf ( angle * DEG_TO_RAD ) - position . y ) ) % s . ceil_surf - > h ;
draw : : putpd ( screen_column , y , s . ceil_surf - > pixels [ tx + ty * s . ceil_surf - > w ] , - straight_dist ) ;
}
}
if ( w - > portal = = - 1 )
{
// Pinta la pared
@@ -450,7 +379,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
}
}
} else {
if ( sectors [ w - > portal ] . ceiling_height < s . ceiling_height )
if ( ( sectors [ w - > portal ] . ceiling_height < s . ceiling_height ) & & sectors [ w - > portal ] . ceil_surf )
{
float upper_height = s . ceiling_height - sectors [ w - > portal ] . ceiling_height ;
float upper_wall_height = ( upper_height * FOV ) / dist ;
@@ -520,6 +449,7 @@ bool tryMove(float angle, float speed)
float sign = speed > 0 ? 1.0f : - 1.0f ;
bool moved = false ;
sector & s = sectors [ current_sector ] ;
int come_from = current_sector ;
vec2 newpos = { position . x + SDL_cosf ( angle * DEG_TO_RAD ) * 5 * sign , position . y } ;
bool collision = false ;
@@ -530,7 +460,7 @@ bool tryMove(float angle, float speed)
newpos . x = position . x + SDL_cosf ( angle * DEG_TO_RAD ) * dt * speed ;
if ( get_line_intersection ( position , newpos , verts [ w . v1 ] , verts [ w . v2 ] , NULL ) ) {
current_sector = w . portal ;
real_height = sectors [ current_sector ] . floor_height + 32.0f ;
real_height = sectors [ current_sector ] . floor_height + 41.0f ;
}
} else {
collision = true ;
@@ -549,7 +479,10 @@ bool tryMove(float angle, float speed)
if ( w . portal ! = - 1 ) {
newpos . y = position . y + SDL_sinf ( angle * DEG_TO_RAD ) * dt * speed ;
if ( get_line_intersection ( position , newpos , verts [ w . v1 ] , verts [ w . v2 ] , NULL ) )
current_sector = w . portal ;
if ( w . portal ! = come_from ) {
current_sector = w . portal ;
real_height = sectors [ current_sector ] . floor_height + 41.0f ;
}
} else {
collision = true ;
}
@@ -562,6 +495,37 @@ bool tryMove(float angle, float speed)
return moved ;
}
// angle is in degrees (0– 359), increasing clockwise like Doom.
// sky is your loaded surface_t containing the sky texture.
// screen_w = 320, screen_h = 240.
void draw_sky ( draw : : surface_t * sky , float angle_deg )
{
// Convert angle to a horizontal texture offset.
// Doom uses a bitshift, but this is equivalent:
// scroll = angle * (sky->w / 360)
float scroll_f = angle_deg * ( sky - > w / 360.0f ) ;
int scroll = ( int ) scroll_f ;
for ( int y = 0 ; y < 240 ; y + + )
{
// Map screen Y to sky Y.
// Doom's sky is not perspective-correct; it simply stretches vertically.
int ty = ( y * sky - > h ) / 240 ;
for ( int x = 0 ; x < 320 ; x + + )
{
// Horizontal wrap-around
int tx = ( x + scroll ) % sky - > w ;
if ( tx < 0 ) tx + = sky - > w ;
uint8_t color = sky - > pixels [ ty * sky - > w + tx ] ;
draw : : putp ( x , y , color ) ;
}
}
}
int main ( int argc , char * argv [ ] )
{
wad : : init ( " doom1.wad " ) ;
@@ -576,6 +540,7 @@ int main(int argc, char *argv[])
palette = wad : : loadPalette ( 0 ) ;
draw : : setpal ( palette ) ;
spr = draw : : loadgif ( " player1.gif " ) ;
sky = wad : : loadTexture ( " SKY1 " ) ;
// [DEBUG] Paleta per al depth buffer
//for(int i=0;i<256;++i) palette[i] = (255-i) | ((255-i)<<8) | ((255-i)<<16);
@@ -634,6 +599,9 @@ int main(int argc, char *argv[])
sectors [ 0 ] . floor_height + = dt * 100.0f ;
sectors [ 1 ] . floor_height + = dt * 100.0f ;
}
if ( keys [ SDL_SCANCODE_M ] ) {
triggers : : toggle ( " minimap " ) ;
}
if ( keys [ SDL_SCANCODE_RIGHT ] )
{
@@ -660,6 +628,7 @@ int main(int argc, char *argv[])
if ( speed ! = 0.0f ) if ( ! tryMove ( orientation , speed ) ) speed = 0.0f ;
draw : : cls ( ) ;
draw_sky ( sky , orientation ) ;
sector & s = sectors [ current_sector ] ;
actual_sector = current_sector ;
@@ -722,48 +691,48 @@ int main(int argc, char *argv[])
*/
// Draw map walls
//draw::cls();
int sec = 0 ;
vec2 normal = { SDL_cosf ( orientation * DEG_TO_RAD ) , SDL_sinf ( orientation * DEG_TO_RAD ) } ;
if ( triggers : : isEnabled ( " minimap " ) ) {
// Draw map walls
//draw::cls();
int sec = 0 ;
vec2 normal = { SDL_cosf ( orientation * DEG_TO_RAD ) , SDL_sinf ( orientation * DEG_TO_RAD ) } ;
for ( auto & s : sectors )
{
//if (sec==current_sector2)
for ( auto & w : s . walls ) {
//if (dot(normal, w.normal) >= 0) continue;
draw : : map : : line ( verts [ w . v1 ] . x , verts [ w . v1 ] . y , verts [ w . v2 ] . x , verts [ w . v2 ] . y , sec = = current_sector ? 20 : 4 , position . x , position . y ) ;
vec2 nx { ( verts [ w . v2 ] . x + verts [ w . v1 ] . x ) / 2 , ( verts [ w . v2 ] . y + verts [ w . v1 ] . y ) / 2 } ;
draw : : map : : line ( nx . x , nx . y , nx . x + w . normal . x * 20 , nx . y + w . normal . y * 20 , sec = = current_sector ? 22 : 3 , position . x , position . y ) ;
for ( auto & s : sectors )
{
//if (sec==current_sector2)
for ( auto & w : s . walls ) {
//if (dot(normal, w.normal) >= 0) continue;
draw : : map : : line ( verts [ w . v1 ] . x , verts [ w . v1 ] . y , verts [ w . v2 ] . x , verts [ w . v2 ] . y , sec = = current_sector ? 20 : 4 , position . x , position . y ) ;
vec2 nx { ( verts [ w . v2 ] . x + verts [ w . v1 ] . x ) / 2 , ( verts [ w . v2 ] . y + verts [ w . v1 ] . y ) / 2 } ;
draw : : map : : line ( nx . x , nx . y , nx . x + w . normal . x * 20 , nx . y + w . normal . y * 20 , sec = = current_sector ? 22 : 3 , position . x , position . y ) ;
}
sec + + ;
}
sec + + ;
}
vec2 infi ;
infi . x = position . x + SDL_cosf ( ( orientation + - 32.0f ) * DEG_TO_RAD ) * 40000 ;
infi . y = position . y + SDL_sinf ( ( orientation + - 32.0f ) * DEG_TO_RAD ) * 40000 ;
draw : : map : : line ( position . x , position . y , infi . x , infi . y , 32 , position . x , position . y ) ;
infi . x = position . x + SDL_cosf ( ( orientation ) * DEG_TO_RAD ) * 40000 ;
infi . y = position . y + SDL_sinf ( ( orientation ) * DEG_TO_RAD ) * 40000 ;
draw : : map : : line ( position . x , position . y , infi . x , infi . y , 42 , position . x , position . y ) ;
infi . x = position . x + SDL_cosf ( ( orientation + 32.0f ) * DEG_TO_RAD ) * 40000 ;
infi . y = position . y + SDL_sinf ( ( orientation + 32.0f ) * DEG_TO_RAD ) * 40000 ;
draw : : map : : line ( position . x , position . y , infi . x , infi . y , 32 , position . x , position . y ) ;
vec2 infi ;
infi . x = position . x + SDL_cosf ( ( orientation + - 32.0f ) * DEG_TO_RAD ) * 40000 ;
infi . y = position . y + SDL_sinf ( ( orientation + - 32.0f ) * DEG_TO_RAD ) * 40000 ;
draw : : map : : line ( position . x , position . y , infi . x , infi . y , 32 , position . x , position . y ) ;
infi . x = position . x + SDL_cosf ( ( orientation ) * DEG_TO_RAD ) * 40000 ;
infi . y = position . y + SDL_sinf ( ( orientation ) * DEG_TO_RAD ) * 40000 ;
draw : : map : : line ( position . x , position . y , infi . x , infi . y , 42 , position . x , position . y ) ;
infi . x = position . x + SDL_cosf ( ( orientation + 32.0f ) * DEG_TO_RAD ) * 40000 ;
infi . y = position . y + SDL_sinf ( ( orientation + 32.0f ) * DEG_TO_RAD ) * 40000 ;
draw : : map : : line ( position . x , position . y , infi . x , infi . y , 32 , position . x , position . y ) ;
// Draw map hero
vec2 lookat ;
lookat . x = SDL_cosf ( orientation * DEG_TO_RAD ) * 20 ;
lookat . y = SDL_sinf ( orientation * DEG_TO_RAD ) * 20 ;
draw : : map : : line ( 0 , 0 , lookat . x , lookat . y , 20 , 0 , 0 ) ;
draw : : map : : putp ( 0 , 0 , 20 ) ;
// Draw map hero
vec2 lookat ;
lookat . x = SDL_cosf ( orientation * DEG_TO_RAD ) * 20 ;
lookat . y = SDL_sinf ( orientation * DEG_TO_RAD ) * 20 ;
draw : : map : : line ( 0 , 0 , lookat . x , lookat . y , 20 , 0 , 0 ) ;
draw : : map : : putp ( 0 , 0 , 20 ) ;
for ( int i = 0 ; i < 256 ; + + i ) {
draw : : putp ( ( i & 0xf ) * 2 , ( i > > 4 ) * 2 , i ) ;
draw : : putp ( ( i & 0xf ) * 2 + 1 , ( i > > 4 ) * 2 , i ) ;
draw : : putp ( ( i & 0xf ) * 2 + 1 , ( i > > 4 ) * 2 + 1 , i ) ;
draw : : putp ( ( i & 0xf ) * 2 , ( i > > 4 ) * 2 + 1 , i ) ;
for ( int i = 0 ; i < 256 ; + + i ) {
draw : : putp ( ( i & 0xf ) * 2 , ( i > > 4 ) * 2 , i ) ;
draw : : putp ( ( i & 0xf ) * 2 + 1 , ( i > > 4 ) * 2 , i ) ;
draw : : putp ( ( i & 0xf ) * 2 + 1 , ( i > > 4 ) * 2 + 1 , i ) ;
draw : : putp ( ( i & 0xf ) * 2 , ( i > > 4 ) * 2 + 1 , i ) ;
}
}