summaryrefslogtreecommitdiff
path: root/src/sector.c
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2023-04-09 23:36:55 +0300
committerkartofen <mladenovnasko0@gmail.com>2023-04-09 23:36:55 +0300
commit80ead50951c8b0d2c60c9fd57b8a4c943634b084 (patch)
tree635d8479b7e862d3cd7b3bc69b0cb64e31c38c2e /src/sector.c
parentfc027f7d214028086178a7328926c9b14ead464d (diff)
things...
Diffstat (limited to 'src/sector.c')
-rw-r--r--src/sector.c98
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", &sectors[sects].floor, &sectors[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);
}