From 943b79d9bb84e79ebb0a8048087b0df9081ffe18 Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Fri, 27 Feb 2026 19:02:39 +0100 Subject: [PATCH] =?UTF-8?q?-=20Ja=20carrega=20els=20nivells=20i=20funciona?= =?UTF-8?q?=20un=20poc,=20pero=20com=20els=20vertices=20no=20est=C3=A0n=20?= =?UTF-8?q?ordenats=20peta.=20TBD:=20ordenar=20clockwise=20els=20vertices?= =?UTF-8?q?=20de=20cada=20sector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- draw.cpp | 28 +++++-- draw.h | 3 +- main.cpp | 249 +++++++++++++++++++++++++++++++++++++++++++------------ wad.cpp | 51 +++++++++--- wad.h | 1 + 5 files changed, 255 insertions(+), 77 deletions(-) diff --git a/draw.cpp b/draw.cpp index 2b8afe4..d8f0f4b 100644 --- a/draw.cpp +++ b/draw.cpp @@ -28,6 +28,11 @@ namespace draw debug::init(sdl_renderer); } + void cls() + { + memset(screen, 0, 320*240); + } + surface_t *newsurf(int w, int h) { surface_t *surf = (surface_t*)malloc(sizeof(surface_t)); @@ -107,11 +112,17 @@ namespace draw void drawsurf(int x, int y, surface_t *src, surface_t *dst) { - int w = src->w; if (x+w > dst->w) w = dst->w-x; - int h = src->h; if (y+h > dst->h) h = dst->h-y; - for (int py=0;pypixels[(px+x)+(py+y)*dst->w] = src->pixels[x+y*src->w]; + int sw = src->w; int dx = x; int sx = 0; + if (x < 0) { sw = sw+x; sx=-x; dx=0; } + if (dx+sw > dst->w) sw = dst->w-dx; + + int sh = src->h; int dy = y; int sy = 0; + if (y < 0) { sh = sh+y; sy=-y; dy=0; } + if (dy+sh > dst->h) sh = dst->h-dy; + + for (int py=0;pypixels[(px+dx)+(py+dy)*dst->w] = src->pixels[(sx+px)+(sy+py)*src->w]; } void line(int x1, int y1, int x2, int y2, Uint8 color) @@ -161,14 +172,15 @@ namespace draw namespace map { + float zoom = 8; void putp(int x, int y, Uint8 color) { - draw::putp(160+(x/8), 120+(y/8), color); + draw::putp(160+(x/zoom), 120+(y/zoom), color); } - void line(int x1, int y1, int x2, int y2, Uint8 color) + void line(int x1, int y1, int x2, int y2, Uint8 color, int ox, int oy) { - draw::line(160+(x1/8), 120+(y1/8), 160+(x2/8), 120+(y2/8), color); + draw::line(160+(x1/zoom)-ox/zoom, 120+(-y1/zoom)+oy/zoom, 160+(x2/zoom)-ox/zoom, 120+(-y2/zoom)+oy/zoom, color); } } } \ No newline at end of file diff --git a/draw.h b/draw.h index 71141d5..20fd109 100644 --- a/draw.h +++ b/draw.h @@ -12,6 +12,7 @@ namespace draw }; void init(); + void cls(); surface_t *newsurf(int w, int h); surface_t *loadgif(const char* filename); uint32_t *loadpal(const char* filename); @@ -31,6 +32,6 @@ namespace draw namespace map { void putp(int x, int y, uint8_t color); - void line(int x1, int y1, int x2, int y2, uint8_t color); + void line(int x1, int y1, int x2, int y2, uint8_t color, int ox, int oy); } } diff --git a/main.cpp b/main.cpp index b360802..a1d808a 100644 --- a/main.cpp +++ b/main.cpp @@ -5,31 +5,42 @@ #include "util.h" #include "draw.h" #include "wad.h" +#include +#include #define FOV 277 +std::vector verts; + struct wall { - Uint16 v1, v2; - vec2 normal; - float u1, u2; - int portal; + Uint16 v1 {0}; + Uint16 v2 {0}; + vec2 normal {0.0f, 0.0f}; + float u1 {0.0f}; + float u2 {0.0f}; + int portal {-1}; + draw::surface_t *surf {nullptr}; + draw::surface_t *upper_surf {nullptr}; + draw::surface_t *lower_surf {nullptr}; }; struct sector { - float floor_height; - float ceiling_height; + float floor_height {0.0f}; + float ceiling_height {64.0f}; + draw::surface_t *floor_surf {nullptr}; + draw::surface_t *ceil_surf {nullptr}; std::vector walls; - std::vector verts; }; std::vector sectors; -int current_sector; +int current_sector = 38; +int current_sector2 = 38; -vec2 position = { 128.0f, 192.0f }; +vec2 position = { 1056.0f, -3616.0f }; float height = 48.0f; float real_height = 48.0f; -float orientation = 90.0f; +float orientation = 270.0f; float accel = 500.0f; float speed = 0.0f; @@ -41,9 +52,112 @@ float bobbing = 0.0f; float dt; Uint32 *palette; -draw::surface_t *gif; +//draw::surface_t *gif; draw::surface_t *spr; +#pragma pack(push, 1) +struct sidedef { + int16_t xoffset; + int16_t yoffset; + char upper_texture[8]; + char lower_texture[8]; + char middle_texture[8]; + int16_t sector; +}; +#pragma pack(pop) + +void loadMap(const char* name) +{ + int size; + + int16_t *vertices = (int16_t *)wad::load(name, "VERTEXES", &size); + const int num_vertices = size/4; + for (int i=0;iw : w.upper_surf ? w.upper_surf->w : w.lower_surf ? w.lower_surf->w : 64; + SDL_assert(width>=0); + + w.u2 = distance(verts[w.v1], verts[w.v2]) / width; + //w.v2 = distance(s.verts[w.v1], s.verts[w.v2]) / 32.0f; + vec2 norm = { verts[w.v2].x - verts[w.v1].x, verts[w.v2].y - verts[w.v1].y}; + normalize(&norm); + const float tmp = norm.x; norm.x = -norm.y; norm.y = tmp; + w.normal = norm; + } + } + +} + +/* void createMap() { current_sector = 0; @@ -51,6 +165,8 @@ void createMap() 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}); @@ -61,14 +177,14 @@ void createMap() 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}); - s.walls.push_back({1,2,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({2,3,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({3,4,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({4,5,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({5,6,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({6,7,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({7,0,{0,0},0.0f,0.0f,-1}); + 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); } @@ -76,6 +192,8 @@ void createMap() 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}); @@ -87,14 +205,14 @@ void createMap() 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}); - s.walls.push_back({1,2,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({2,3,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({3,0,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({4,5,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({5,6,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({6,7,{0,0},0.0f,0.0f,-1}); - s.walls.push_back({7,4,{0,0},0.0f,0.0f,-1}); + 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); } @@ -103,7 +221,7 @@ void createMap() { for (auto &w : s.walls ) { - w.u2 = distance(s.verts[w.v1], s.verts[w.v2]) / 8.0f; + 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); @@ -112,7 +230,9 @@ void createMap() } } } - +*/ +int actual_sector = -1; +int last_sector = -1; void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, vec2 infi) { const float angle = orientation + a_inc; @@ -124,7 +244,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v for (auto &wall : s.walls) { if (dot(normal, wall.normal) >= 0) continue; - if (get_line_intersection(position, infi, s.verts[wall.v1], s.verts[wall.v2], &tmp_result)) + if (get_line_intersection(position, infi, verts[wall.v1], verts[wall.v2], &tmp_result)) { const float d = distance(position, tmp_result);// * SDL_cosf(a_inc*DEG_TO_RAD); if (dh; //64; const float sector_height = s.ceiling_height - s.floor_height; + const int width = w->surf ? w->surf->w : w->upper_surf ? w->upper_surf->w : w->lower_surf ? w->lower_surf->w : 64; draw::map::putp(result.x, result.y, 6); float dist = stright_dist * SDL_cosf(a_inc*DEG_TO_RAD); - const vec2 AB = {s.verts[w->v2].x-s.verts[w->v1].x, s.verts[w->v2].y-s.verts[w->v1].y}; - const vec2 AP = {result.x-s.verts[w->v1].x, result.y-s.verts[w->v1].y}; - float v = dot(AP,AB) / dot(AB,AB); v *= w->u2; v = v*gif->w; //(v-int(v))*gif->w; + const vec2 AB = {verts[w->v2].x-verts[w->v1].x, verts[w->v2].y-verts[w->v1].y}; + const vec2 AP = {result.x-verts[w->v1].x, result.y-verts[w->v1].y}; + float v = dot(AP,AB) / dot(AB,AB); v *= w->u2; v = v*width; //w->surf->w; //(v-int(v))*gif->w; float wall_height = (sector_height*FOV)/dist; // [64=altura sector] float wall_cut = 0.0f; @@ -161,20 +282,23 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v for (int y=start; y> 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)) % gif->w; - int ty = SDL_abs(int(actual_dist * SDL_sinf(angle*DEG_TO_RAD) - position.y)) % gif->h; - draw::putpd(screen_column, y, gif->pixels[tx+ty*gif->w], -straight_dist); + 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 + draw::surface_t *surf = w->surf; + if (surf) { for (int i=0; i=end) break; - draw::putpd(screen_column, wall_start+i, gif->pixels[(int(v)%gif->w)+(int(cpix)%gif->h)*gif->w], stright_dist); + draw::putpd(screen_column, wall_start+i, surf->pixels[(int(v)%surf->w)+(int(cpix)%surf->h)*surf->w], stright_dist); cpix += dpix; } + } } else { if (sectors[w->portal].ceiling_height < s.ceiling_height) { @@ -186,7 +310,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v // Pinta la pared for (int i=0; i=end) break; - draw::putpd(screen_column, wall_start+i, gif->pixels[(int(v)%gif->w)+(int(cpix)%gif->h)*gif->w], stright_dist); + draw::putpd(screen_column, wall_start+i, w->surf->pixels[(int(v)%w->surf->w)+(int(cpix)%w->surf->h)*w->surf->w], stright_dist); cpix += dpix; } wall_start += upper_wall_height; @@ -199,6 +323,11 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v if (lower_wall_height>0.0f) wall_end -= lower_wall_height; wall_end = SDL_min(wall_end, end); + //SDL_assert(&s != §ors[w->portal]); + printf("Anem al sector: %i\n", w->portal); + //SDL_assert(w->portal != last_sector); + last_sector = actual_sector; + actual_sector = w->portal; drawColumn(sectors[w->portal], screen_column, wall_start, wall_end, a_inc, infi); if (lower_wall_height>0.0f) @@ -207,7 +336,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v // Pinta la pared for (int i=0; i=end) break; - draw::putpd(screen_column, wall_end+i, gif->pixels[(int(v)%gif->w)+(int(cpix)%gif->h)*gif->w], stright_dist); + draw::putpd(screen_column, wall_end+i, w->surf->pixels[(int(v)%w->surf->w)+(int(cpix)%w->surf->h)*w->surf->w], stright_dist); cpix += dpix; } //wall_start += upper_wall_height; @@ -221,9 +350,9 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v for (int y=paint_end+1; y> 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)) % gif->w; - int ty = SDL_abs(int(actual_dist * SDL_sinf(angle*DEG_TO_RAD) + position.y)) % gif->h; - draw::putpd(screen_column, y, gif->pixels[tx+ty*gif->w], straight_dist); + int tx = SDL_abs(int(actual_dist * SDL_cosf(angle*DEG_TO_RAD) + position.x)) % s.floor_surf->w; + int ty = SDL_abs(int(actual_dist * SDL_sinf(angle*DEG_TO_RAD) + position.y)) % s.floor_surf->h; + draw::putpd(screen_column, y, s.floor_surf->pixels[tx+ty*s.floor_surf->w], straight_dist); } //line(screen_column, 120-(wall_height), screen_column, 120+(wall_height), 5); } @@ -238,11 +367,11 @@ bool tryMove(float angle, float speed) vec2 newpos = { position.x + SDL_cosf(angle*DEG_TO_RAD)*5*sign, position.y }; bool collision=false; for (auto w : s.walls) { - if (get_line_intersection(position, newpos, s.verts[w.v1], s.verts[w.v2], NULL)) + if (get_line_intersection(position, newpos, verts[w.v1], verts[w.v2], NULL)) { if (w.portal != -1) { newpos.x = position.x + SDL_cosf(angle*DEG_TO_RAD)*dt*speed; - if (get_line_intersection(position, newpos, s.verts[w.v1], s.verts[w.v2], NULL) ) + if (get_line_intersection(position, newpos, verts[w.v1], verts[w.v2], NULL) ) current_sector = w.portal; } else { collision=true; @@ -256,11 +385,11 @@ bool tryMove(float angle, float speed) newpos = { position.x, position.y + SDL_sinf(angle*DEG_TO_RAD)*5*sign }; collision=false; for (auto w : s.walls) { - if (get_line_intersection(position, newpos, s.verts[w.v1], s.verts[w.v2], NULL)) + if (get_line_intersection(position, newpos, verts[w.v1], verts[w.v2], NULL)) { if (w.portal != -1) { newpos.y = position.y + SDL_sinf(angle*DEG_TO_RAD)*dt*speed; - if (get_line_intersection(position, newpos, s.verts[w.v1], s.verts[w.v2], NULL) ) + if (get_line_intersection(position, newpos, verts[w.v1], verts[w.v2], NULL) ) current_sector = w.portal; } else { collision=true; @@ -282,8 +411,8 @@ int main(int argc, char *argv[]) //gif = draw::loadgif("walls.gif"); //gif = wad::loadFlat("FLOOR4_8"); - //gif = wad::loadTexture("COMPSPAN"); - gif = wad::loadPatch("TTALL1_2"); + //gif = wad::loadTexture("BROWNPIP"); + //gif = wad::loadPatch("LADDER16"); //palette = draw::loadpal("walls.gif"); palette = wad::loadPalette(0); draw::setpal(palette); @@ -292,7 +421,8 @@ int main(int argc, char *argv[]) // [DEBUG] Paleta per al depth buffer //for(int i=0;i<256;++i) palette[i] = (255-i) | ((255-i)<<8) | ((255-i)<<16); - createMap(); + //createMap(); + loadMap("E1M1"); SDL_Event e; bool should_exit = false; @@ -314,6 +444,10 @@ int main(int argc, char *argv[]) { if (e.type==SDL_EVENT_QUIT) { should_exit=true; break; } if (e.type==SDL_EVENT_KEY_DOWN && e.key.scancode==SDL_SCANCODE_ESCAPE) { should_exit=true; break; } + if (e.type==SDL_EVENT_MOUSE_WHEEL) { + if (e.wheel.y>0) current_sector2++; else current_sector2--; + printf("Current sector: %i\n", current_sector2); + } } const bool *keys = SDL_GetKeyboardState(NULL); @@ -366,9 +500,11 @@ int main(int argc, char *argv[]) } if (speed != 0.0f) if (!tryMove(orientation, speed)) speed = 0.0f; + draw::cls(); sector &s = sectors[current_sector]; - + actual_sector = current_sector; + //printf("Current sector: %i\n", current_sector); // Clear screen //SDL_memset4(screen, 0x00000000, (320*240)>>2); @@ -380,6 +516,7 @@ int main(int argc, char *argv[]) infi.x = position.x + SDL_cosf(angle*DEG_TO_RAD)*40000; infi.y = position.y + SDL_sinf(angle*DEG_TO_RAD)*40000; + //printf("Column %i...\n", screen_column); drawColumn(s, screen_column, 0, 240, a_inc, infi); screen_column++; @@ -424,21 +561,23 @@ int main(int argc, char *argv[]) */ // Draw map walls + //draw::cls(); int sec = 0; for (auto &s : sectors) { + if (sec==current_sector2) for (auto &w : s.walls) { - draw::map::line(s.verts[w.v1].x, s.verts[w.v1].y, s.verts[w.v2].x, s.verts[w.v2].y, sec==current_sector?3:4); + draw::map::line(verts[w.v1].x, verts[w.v1].y, verts[w.v2].x, verts[w.v2].y, sec==current_sector2?20:4, position.x, position.y); } sec++; } // Draw map hero vec2 lookat; - lookat.x = position.x + SDL_cosf(orientation*DEG_TO_RAD)*20; - lookat.y = position.y + SDL_sinf(orientation*DEG_TO_RAD)*20; - draw::map::line(position.x, position.y, lookat.x, lookat.y, 3); - draw::map::putp(position.x, position.y, 7); + 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); diff --git a/wad.cpp b/wad.cpp index 1aa2d65..8cf2bb1 100644 --- a/wad.cpp +++ b/wad.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace wad { @@ -37,26 +38,28 @@ namespace wad { fread(&directory[i].filepos, 4, 1, f); fread(&directory[i].size, 4, 1, f); fread(directory[i].name, 8, 1, f); - if (strncmp("TEXTURE1", directory[i].name, 8)==0) - printf("num lumps: %8.10s % 6i % 6i\n", directory[i].name,directory[i].filepos, directory[i].size); + //if (strncmp("TEXTURE1", directory[i].name, 8)==0) + // printf("num lumps: %8.10s % 6i % 6i\n", directory[i].name,directory[i].filepos, directory[i].size); } fclose(f); uint8_t *pnames = load("PNAMES"); int num_pnames = *(uint32_t*)pnames; + //printf("num pnames: %i\n", num_pnames); //patch_names = (char (*)[8]) malloc(num_pnames * sizeof *patch_names); char *names = (char*)(pnames+4); for (int i=0;i