diff options
author | kartofen <mladenovnasko0@gmail.com> | 2023-04-09 23:36:55 +0300 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2023-04-09 23:36:55 +0300 |
commit | 80ead50951c8b0d2c60c9fd57b8a4c943634b084 (patch) | |
tree | 635d8479b7e862d3cd7b3bc69b0cb64e31c38c2e /src/sector.c | |
parent | fc027f7d214028086178a7328926c9b14ead464d (diff) |
things...
Diffstat (limited to 'src/sector.c')
-rw-r--r-- | src/sector.c | 98 |
1 files changed, 90 insertions, 8 deletions
diff --git a/src/sector.c b/src/sector.c index 3374995..5db3f3e 100644 --- a/src/sector.c +++ b/src/sector.c @@ -6,6 +6,88 @@ #define VERTS_CAP 512 #define SECTS_CAP 512 #define NUMS_CAP 512 +#define MAX_QUEUE 32 + +#define hfov (0.73f*SH) // Affects the horizontal field of vision +#define vfov (.2f*SH) // Affects the vertical field of vision + +void vline(int x, int y1, int y2, uint32_t col); + +int map_draw(map_t *map, uint SW, uint SH) +{ + int ytop[SW], ybottom[SW]; + for(uint i = 0; i < SW; i++) { + ytop[i] = 0; + ybottom[i] = SH-1; + } + + struct { int sx1, sx2 } now = {0, SW-1}; + struct sector *sect = &map->sectors[map->player.sector]; + + for(size_t i = 0; i < sect->nverts; i++) + { + map->player.pos.z = sect->floor + 6; //temp + + size_t s0 = sect->vertices[i], s1 = sect->vertices[i+1]; + + float vx1 = map->vertices[s0].x - map->player.pos.x, vy1 = map->vertices[s0].y - map->player.pos.y; + float vx2 = map->vertices[s1].x - map->player.pos.x, vy2 = map->vertices[s1].y - map->player.pos.y; + + float pcos = map->player.anglecos, psin = map->player.anglesin; + float tx1 = vx1 * psin - vy1 * pcos, tz1 = vx1 * pcos + vy1 * psin; + float tx2 = vx2 * psin - vy2 * pcos, tz2 = vx2 * pcos + vy2 * psin; + + if(tz1 <= 0 && tz2 <= 0) continue; + + // ??? magic + if(tz1 <= 0 || tz2 <= 0) + { + float nearz = 1e-4f, farz = 5, nearside = 1e-5f, farside = 20.f; + // Find an intersection between the wall and the approximate edges of player's view + struct xy i1 = intersect(tx1,tz1,tx2,tz2, -nearside,nearz, -farside,farz); + struct xy i2 = intersect(tx1,tz1,tx2,tz2, nearside,nearz, farside,farz); + if(tz1 < nearz) { if(i1.y > 0) { tx1 = i1.x; tz1 = i1.y; } else { tx1 = i2.x; tz1 = i2.y; } } + if(tz2 < nearz) { if(i1.y > 0) { tx2 = i1.x; tz2 = i1.y; } else { tx2 = i2.x; tz2 = i2.y; } } + } + + float xscale1 = hfov / tz1, yscale1 = vfov / tz1; int x1 = SW/2 - (int)(tx1 * xscale1); + float xscale2 = hfov / tz2, yscale2 = vfov / tz2; int x2 = SW/2 - (int)(tx2 * xscale2); + if(x1 >= x2 || x2 < now.sx1 || x1 > now.sx2) continue; // Only render if it's visible + /* Acquire the floor and ceiling heights, relative to where the player's view is */ + float yceil = sect->ceil - map->player.pos.z; + float yfloor = sect->floor - map->player.pos.z; + + size_t neighbor = sect->neighbors[i]; + + int y1a = SH/2 - (int)(yceil * yscale1), y1b = SH/2 - (int)(yfloor * yscale1); + int y2a = SH/2 - (int)(yceil * yscale2), y2b = SH/2 - (int)(yfloor * yscale2); + + int beginx = max(x1, now.sx1), endx = min(x2, now.sx2); + for(int x = beginx; x <= endx; ++x) + { + // int z = ((x - x1) * (tz2-tz1) / (x2-x1) + tz1) * 8; + /* Acquire the Y coordinates for our ceiling & floor for this X coordinate. Clamp them. */ + int ya = (x - x1) * (y2a-y1a) / (x2-x1) + y1a, cya = clamp(ya, ytop[x],ybottom[x]); // top + int yb = (x - x1) * (y2b-y1b) / (x2-x1) + y1b, cyb = clamp(yb, ytop[x],ybottom[x]); // bottom + + /* Render ceiling: everything above this sector's ceiling height. */ + vline(x, ytop[x], cya-1, COLOR_GREEN); + /* Render floor: everything below this sector's floor height. */ + vline(x, cyb+1, ybottom[x], COLOR_BLUE); + + if(neighbor == (size_t)-1) + { + // vline(x, cya, cyb, x==x1||x==x2 ? COLOR_LIGHTWHITE : COLOR_WHITE); + vline(x, cya, cyb, COLOR_WHITE); + } + else + { + vline(x, cya, cyb, COLOR_RED); + } + } + } + return 0; +} int map_load(map_t *map, char *filename) { @@ -53,7 +135,7 @@ int map_load(map_t *map, char *filename) sscanf(ptr += offset, "%f %f %n", §ors[sects].floor, §ors[sects].ceil, &offset); - int numbers[NUMS_CAP]; + size_t numbers[NUMS_CAP]; size_t nums = 0; while(sscanf(ptr += offset, "%s %n", word, &offset) != EOF) { if(nums >= NUMS_CAP) { @@ -79,7 +161,7 @@ int map_load(map_t *map, char *filename) sectors[sects++].nverts = nverts; break; case 'p': // player - sscanf(ptr += offset, "%f %f %f %d %n", &player.pos.x, &player.pos.y, &player.angle, (int *)&player.sector, &offset); + sscanf(ptr += offset, "%f %f %f %zu %n", &player.pos.x, &player.pos.y, &player.angle, &player.sector, &offset); break; } } @@ -128,23 +210,23 @@ int map_save(map_t *map, char *filename) void map_print(map_t *map) { - log("%ld %ld", map->nverts, map->nsects); + log("%zu %zu", map->nverts, map->nsects); for(size_t i = 0; i < map->nverts; i++) { - printf("v %ld {%.1f %.1f}\n", i, map->vertices[i].x, map->vertices[i].y); + printf("v %zu {%.1f %.1f}\n", i, map->vertices[i].x, map->vertices[i].y); } for(size_t i = 0; i < map->nsects; i++) { - printf("s %ld %.1f %.1f ", i, map->sectors[i].floor, map->sectors[i].ceil); + printf("s %zu %.1f %.1f ", i, map->sectors[i].floor, map->sectors[i].ceil); for(size_t j = 0; j < map->sectors[i].nverts + 1; j++) - printf("%d ", map->sectors[i].vertices[j]); + printf("%zu ", map->sectors[i].vertices[j]); printf(" "); for(size_t j = 0; j < map->sectors[i].nverts; j++) - printf("%d ", map->sectors[i].neighbors[j]); + printf("%zu ", map->sectors[i].neighbors[j]); printf("\n"); } - printf("p %.1f %.1f %.1f %d", map->player.pos.x, map->player.pos.y, map->player.angle, map->player.sector); + printf("p %.1f %.1f %.1f %zu", map->player.pos.x, map->player.pos.y, map->player.angle, map->player.sector); } |