- [NEW] Offsets de les textures aplicades

- [NEW] Llum de cada sector aplicada
- [NEW] La llum se fa fosca en la distancia (actualment massa. A més, vore com Doom arrechunta la llum del sector en la foscor de la distancia)
This commit is contained in:
2026-03-02 13:34:45 +01:00
parent 681e27fad0
commit abe6a250be

View File

@@ -23,6 +23,7 @@ struct wall {
vec2 normal {0.0f, 0.0f}; vec2 normal {0.0f, 0.0f};
float u1 {0.0f}; float u1 {0.0f};
float u2 {0.0f}; float u2 {0.0f};
float w1 {0.0f};
int portal {-1}; int portal {-1};
draw::surface_t *surf {nullptr}; draw::surface_t *surf {nullptr};
draw::surface_t *upper_surf {nullptr}; draw::surface_t *upper_surf {nullptr};
@@ -30,6 +31,7 @@ struct wall {
}; };
struct sector { struct sector {
float light;
float floor_height {0.0f}; float floor_height {0.0f};
float ceiling_height {64.0f}; float ceiling_height {64.0f};
draw::surface_t *floor_surf {nullptr}; draw::surface_t *floor_surf {nullptr};
@@ -65,6 +67,8 @@ draw::surface_t *sky;
int drawColumn_count = 0; int drawColumn_count = 0;
uint8_t *colormap;
#pragma pack(push, 1) #pragma pack(push, 1)
struct sidedef { struct sidedef {
int16_t xoffset; int16_t xoffset;
@@ -236,6 +240,8 @@ void loadMap(const char* name)
sec.floor_surf = wad::loadFlat(txt); sec.floor_surf = wad::loadFlat(txt);
for (int i=0;i<8;++i) txt[i] = toupper(*(s++)); for (int i=0;i<8;++i) txt[i] = toupper(*(s++));
sec.ceil_surf = (strcmp(txt, "F_SKY1")==0) ? nullptr : wad::loadFlat(txt); sec.ceil_surf = (strcmp(txt, "F_SKY1")==0) ? nullptr : wad::loadFlat(txt);
//sec.light = *((int16_t*)s); s+=2;
sec.light = float(*((int16_t*)s))/256.0f;
s += 6; s += 6;
sectors.push_back(sec); sectors.push_back(sec);
} }
@@ -261,6 +267,8 @@ void loadMap(const char* name)
wall w; wall w;
w.v1 = v1; w.v2 = v2; w.v1 = v1; w.v2 = v2;
w.portal = portal ? arr[ld2].sector : -1; w.portal = portal ? arr[ld2].sector : -1;
w.u1 = arr[ld1].xoffset;
w.w1 = arr[ld1].yoffset;
char txt[9]; txt[8]=0; char txt[9]; txt[8]=0;
for (int i=0;i<8;++i) txt[i] = toupper(arr[ld1].middle_texture[i]); for (int i=0;i<8;++i) txt[i] = toupper(arr[ld1].middle_texture[i]);
if (txt[0]!='-') { w.surf = wad::loadTexture(txt); SDL_assert(w.surf); } if (txt[0]!='-') { w.surf = wad::loadTexture(txt); SDL_assert(w.surf); }
@@ -274,6 +282,8 @@ void loadMap(const char* name)
wall w; wall w;
w.v1 = v2; w.v2 = v1; w.v1 = v2; w.v2 = v1;
w.portal = portal ? arr[ld1].sector : -1; w.portal = portal ? arr[ld1].sector : -1;
w.u1 = arr[ld2].xoffset;
w.w1 = arr[ld2].yoffset;
char txt[9]; txt[8]=0; char txt[9]; txt[8]=0;
for (int i=0;i<8;++i) txt[i] = toupper(arr[ld2].middle_texture[i]); for (int i=0;i<8;++i) txt[i] = toupper(arr[ld2].middle_texture[i]);
if (txt[0]!='-') { w.surf = wad::loadTexture(txt); SDL_assert(w.surf); } if (txt[0]!='-') { w.surf = wad::loadTexture(txt); SDL_assert(w.surf); }
@@ -296,6 +306,8 @@ void loadMap(const char* name)
const int width = w.surf ? w.surf->w : w.upper_surf ? w.upper_surf->w : w.lower_surf ? w.lower_surf->w : 64; const int width = w.surf ? w.surf->w : w.upper_surf ? w.upper_surf->w : w.lower_surf ? w.lower_surf->w : 64;
SDL_assert(width>=0); SDL_assert(width>=0);
w.u1 /= width;
w.w1 /= width;
w.u2 = distance(verts[w.v1], verts[w.v2]) / width; w.u2 = distance(verts[w.v1], verts[w.v2]) / width;
//w.v2 = distance(s.verts[w.v1], s.verts[w.v2]) / 32.0f; //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}; vec2 norm = { verts[w.v2].x - verts[w.v1].x, verts[w.v2].y - verts[w.v1].y};
@@ -342,19 +354,20 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
float dist = stright_dist * SDL_cosf(a_inc*DEG_TO_RAD); float dist = stright_dist * SDL_cosf(a_inc*DEG_TO_RAD);
const vec2 AB = {verts[w->v2].x-verts[w->v1].x, verts[w->v2].y-verts[w->v1].y}; 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}; 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 v = dot(AP,AB) / dot(AB,AB); v = (v+w->u1) * 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_height = (sector_height*FOV)/dist; // [64=altura sector]
float wall_cut = 0.0f; float wall_cut = 0.0f;
float dpix = sector_height/wall_height; // [64=crec que altura sector] float dpix = sector_height/wall_height; // [64=crec que altura sector]
float cpix = 0; float cpix = 0; //triggers::isEnabled("offsets") ? w->surf->h*w->w1 : 0;
float wall_start = 120-(wall_height/sector_height)*(sector_height-(height-s.floor_height)); // [64=els dos crec que altura sector] float wall_start = 120-(wall_height/sector_height)*(sector_height-(height-s.floor_height)); // [64=els dos crec que altura sector]
if (wall_start<start) { if (wall_start<start) {
wall_cut = start-wall_start; wall_cut = start-wall_start;
cpix = wall_cut*dpix; cpix += wall_cut;
wall_height -= wall_cut; wall_height -= wall_cut;
wall_start=start; wall_start=start;
} }
cpix *= dpix;
// Pinta el sostre // Pinta el sostre
if (s.ceil_surf) { // No el pintes si es el cel if (s.ceil_surf) { // No el pintes si es el cel
@@ -363,7 +376,11 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
float actual_dist = straight_dist / SDL_cosf(a_inc*DEG_TO_RAD); 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 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; 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); float light_dist = 1.0f - (-actual_dist>512 ? 1.0f : -actual_dist/512);
float light = 1.0f - (light_dist*s.light);
uint8_t pixcolor = s.ceil_surf->pixels[tx+ty*s.ceil_surf->w];
pixcolor = colormap[pixcolor + int(light*31)*256];
draw::putpd(screen_column, y, pixcolor, -straight_dist);
} }
} }
@@ -371,10 +388,16 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
{ {
// Pinta la pared // Pinta la pared
draw::surface_t *surf = w->surf; draw::surface_t *surf = w->surf;
float tex_height = (surf->h*FOV)/dist; // [64=altura sector]
if (triggers::isEnabled("offsets")) cpix += tex_height * w->w1 * dpix;
if (surf) { if (surf) {
for (int i=0; i<wall_height; ++i) { for (int i=0; i<wall_height; ++i) {
if (wall_start+i>=end) break; if (wall_start+i>=end) break;
draw::putpd(screen_column, wall_start+i, surf->pixels[(int(v)%surf->w)+(int(cpix)%surf->h)*surf->w], stright_dist); float light_dist = 1.0f - (dist>512 ? 1.0f : dist/512);
float light = 1.0f - (light_dist*s.light);
uint8_t pixcolor = surf->pixels[(int(v)%surf->w)+(int(cpix)%surf->h)*surf->w];
pixcolor = colormap[pixcolor + int(light*31)*256];
draw::putpd(screen_column, wall_start+i, pixcolor, stright_dist);
cpix += dpix; cpix += dpix;
} }
} }
@@ -390,7 +413,11 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
if (w->upper_surf) if (w->upper_surf)
for (int i=0; i<upper_wall_height; ++i) { for (int i=0; i<upper_wall_height; ++i) {
if (wall_start+i>=end) break; if (wall_start+i>=end) break;
draw::putpd(screen_column, wall_start+i, w->upper_surf->pixels[(int(v)%w->upper_surf->w)+(int(cpix)%w->upper_surf->h)*w->upper_surf->w], stright_dist); float light_dist = 1.0f - (dist>512 ? 1.0f : dist/512);
float light = 1.0f - (light_dist*s.light);
uint8_t pixcolor = w->upper_surf->pixels[(int(v)%w->upper_surf->w)+(int(cpix)%w->upper_surf->h)*w->upper_surf->w];
pixcolor = colormap[pixcolor + int(light*31)*256];
draw::putpd(screen_column, wall_start+i, pixcolor, stright_dist);
cpix += dpix; cpix += dpix;
} }
wall_start += upper_wall_height; wall_start += upper_wall_height;
@@ -422,7 +449,11 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
if (w->lower_surf) if (w->lower_surf)
for (int i=0; i<lower_wall_height; ++i) { for (int i=0; i<lower_wall_height; ++i) {
if (wall_end+i>=end) break; if (wall_end+i>=end) break;
draw::putpd(screen_column, wall_end+i, w->lower_surf->pixels[(int(v)%w->lower_surf->w)+(int(cpix)%w->lower_surf->h)*w->lower_surf->w], stright_dist); float light_dist = 1.0f - (dist>512 ? 1.0f : dist/512);
float light = 1.0f - (light_dist*s.light);
uint8_t pixcolor = w->lower_surf->pixels[(int(v)%w->lower_surf->w)+(int(cpix)%w->lower_surf->h)*w->lower_surf->w];
pixcolor = colormap[pixcolor + int(light*31)*256];
draw::putpd(screen_column, wall_end+i, pixcolor, stright_dist);
cpix += dpix; cpix += dpix;
} }
//wall_start += upper_wall_height; //wall_start += upper_wall_height;
@@ -438,7 +469,12 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
float actual_dist = straight_dist / SDL_cosf(a_inc*DEG_TO_RAD); 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.floor_surf->w; 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; 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);
float light_dist = 1.0f - (actual_dist>512 ? 1.0f : actual_dist/512);
float light = 1.0f - (light_dist*s.light);
uint8_t pixcolor = s.floor_surf->pixels[tx+ty*s.floor_surf->w];
pixcolor = colormap[pixcolor + int(light*31)*256];
draw::putpd(screen_column, y, pixcolor, straight_dist);
} }
//line(screen_column, 120-(wall_height), screen_column, 120+(wall_height), 5); //line(screen_column, 120-(wall_height), screen_column, 120+(wall_height), 5);
} }
@@ -530,6 +566,9 @@ int main(int argc, char *argv[])
{ {
wad::init("doom1.wad"); wad::init("doom1.wad");
int len;
colormap = wad::load("COLORMAP");
draw::init(); draw::init();
//gif = draw::loadgif("walls.gif"); //gif = draw::loadgif("walls.gif");
@@ -564,10 +603,12 @@ int main(int argc, char *argv[])
bobbing += dt*1000.0f; bobbing += dt*1000.0f;
height = real_height + SDL_sinf(bobbing*DEG_TO_RAD)*(speed/100.0f); height = real_height + SDL_sinf(bobbing*DEG_TO_RAD)*(speed/100.0f);
uint8_t key_pressed = SDL_SCANCODE_UNKNOWN;
while (SDL_PollEvent(&e)) while (SDL_PollEvent(&e))
{ {
if (e.type==SDL_EVENT_QUIT) { should_exit=true; break; } 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_KEY_DOWN && e.key.scancode==SDL_SCANCODE_ESCAPE) { should_exit=true; break; }
if (e.type==SDL_EVENT_KEY_UP) key_pressed = e.key.scancode;
if (e.type==SDL_EVENT_MOUSE_WHEEL) { if (e.type==SDL_EVENT_MOUSE_WHEEL) {
if (e.wheel.y>0) current_sector2++; else current_sector2--; if (e.wheel.y>0) current_sector2++; else current_sector2--;
printf("Current sector: %i\n", current_sector2); printf("Current sector: %i\n", current_sector2);
@@ -599,9 +640,8 @@ int main(int argc, char *argv[])
sectors[0].floor_height += dt*100.0f; sectors[0].floor_height += dt*100.0f;
sectors[1].floor_height += dt*100.0f; sectors[1].floor_height += dt*100.0f;
} }
if (keys[SDL_SCANCODE_M]) { if (key_pressed == SDL_SCANCODE_M) { triggers::toggle("minimap"); }
triggers::toggle("minimap"); if (key_pressed == SDL_SCANCODE_O) { triggers::toggle("offsets"); }
}
if (keys[SDL_SCANCODE_RIGHT]) if (keys[SDL_SCANCODE_RIGHT])
{ {