- [NEW] Triggers, pa enablar i disablar coses en calent

- [WIP] Treballant en el depth buffer
- [FIX] Ja canvia de sector com toca sempre
- [NEW] Ja pinta el cel
- [NEW] El minimap es pot activar i desactivar amb "M"
This commit is contained in:
2026-03-02 11:12:45 +01:00
parent 0ceeed7a6a
commit 681e27fad0
4 changed files with 139 additions and 126 deletions

View File

@@ -16,6 +16,7 @@ namespace draw
Uint32 *palette;
Uint8 screen[320*240];
float depth_buffer[320*240];
float clear_block[256];
void init()
{
@@ -26,11 +27,13 @@ namespace draw
sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 320, 240);
SDL_SetTextureScaleMode(sdl_texture, SDL_SCALEMODE_NEAREST);
debug::init(sdl_renderer);
for (int i=0;i<256;++i) clear_block[i] = 0;
}
void cls()
{
memset(screen, 0, 320*240);
int pos=0; for (int i=0;i<300;++i) { memcpy(&depth_buffer[pos], clear_block, 256); pos+=256; }
}
surface_t *newsurf(int w, int h)
@@ -85,8 +88,11 @@ namespace draw
void putpd(int x, int y, Uint8 color, float depth)
{
if (x<0 || y<0 || x>=320 || y>=240) return;
screen[x+y*320]=color;
depth_buffer[x+y*320]=depth;
//if (depth_buffer[x+y*320]<=depth)
//{
screen[x+y*320]=color;
depth_buffer[x+y*320]=depth;
//}
}
void putps(int x, int y, Uint8 color, float depth)

217
main.cpp
View File

@@ -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 (0359), 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);
}
}

29
triggers.cpp Normal file
View File

@@ -0,0 +1,29 @@
#include "triggers.h"
#include <unordered_map>
#include <string>
namespace triggers
{
std::unordered_map<std::string, bool> keys;
void enable(const char* name)
{
keys[name] = true;
}
void disable(const char* name)
{
keys[name] = false;
}
void toggle(const char* name)
{
keys[name] = not keys[name];
}
const bool isEnabled(const char *name)
{
return keys[name];
}
}

9
triggers.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
namespace triggers
{
void enable(const char* name);
void disable(const char* name);
void toggle(const char* name);
const bool isEnabled(const char *name);
}