summaryrefslogtreecommitdiff
path: root/src/sector.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sector.c')
-rw-r--r--src/sector.c77
1 files changed, 58 insertions, 19 deletions
diff --git a/src/sector.c b/src/sector.c
index 5db3f3e..2d9b087 100644
--- a/src/sector.c
+++ b/src/sector.c
@@ -6,6 +6,7 @@
#define VERTS_CAP 512
#define SECTS_CAP 512
#define NUMS_CAP 512
+#define PLRS_CAP 512
#define MAX_QUEUE 32
#define hfov (0.73f*SH) // Affects the horizontal field of vision
@@ -13,22 +14,20 @@
void vline(int x, int y1, int y2, uint32_t col);
-int map_draw(map_t *map, uint SW, uint SH)
+int map_draw(map_t *map, int SW, int SH)
{
int ytop[SW], ybottom[SW];
- for(uint i = 0; i < SW; i++) {
+ for(int 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];
+ struct { size_t sectno; int sx1, sx2; } now = {map->player.sector, 0, SW-1};
+ struct sector *sect = &map->sectors[now.sectno];
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];
+ size_t s1 = sect->vertices[i], s0 = 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;
@@ -58,10 +57,19 @@ int map_draw(map_t *map, uint SW, uint SH)
float yfloor = sect->floor - map->player.pos.z;
size_t neighbor = sect->neighbors[i];
+ float nyceil = 0.0f, nyfloor = 0.0f;
+ if(neighbor != (size_t)-1) // Is another sector showing through this portal?
+ {
+ nyceil = map->sectors[neighbor].ceil - map->player.pos.z;
+ nyfloor = map->sectors[neighbor].floor - map->player.pos.z;
+ }
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 ny1a = SH/2 - (int)(nyceil * yscale1), ny1b = SH/2 - (int)(nyfloor * yscale1);
+ int ny2a = SH/2 - (int)(nyceil * yscale2), ny2b = SH/2 - (int)(nyfloor * yscale2);
+
int beginx = max(x1, now.sx1), endx = min(x2, now.sx2);
for(int x = beginx; x <= endx; ++x)
{
@@ -75,20 +83,47 @@ int map_draw(map_t *map, uint SW, uint SH)
/* 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);
+ if(neighbor == (size_t)-1) { // no neighbor
+ // vline(x, cya, cyb, x==x1||x==x2 ? : );
vline(x, cya, cyb, COLOR_WHITE);
- }
- else
- {
- vline(x, cya, cyb, COLOR_RED);
+ } else { // yes neighbor
+ int nyb = (x - x1) * (ny2b-ny1b) / (x2-x1) + ny1b, cnyb = clamp(nyb, ytop[x],ybottom[x]);
+ int nya = (x - x1) * (ny2a-ny1a) / (x2-x1) + ny1a, cnya = clamp(nya, ytop[x],ybottom[x]);
+
+ vline(x, cya, cnya-1, COLOR_WHITE); // upper wall
+ // vline(x, cnya, cnyb, COLOR_RED); // portal
+ vline(x, cnyb+1, cyb, COLOR_WHITE); // lower wall
+
+ ytop[x] = clamp(max(cya, cnya), ytop[x], SH-1); // Shrink the remaining window below these ceilings
+ ybottom[x] = clamp(min(cyb, cnyb), 0, ybottom[x]); // Shrink the remaining window above these floors
}
}
}
return 0;
}
+void map_player_sector(map_t *map)
+{
+ struct sector *sect = &map->sectors[map->player.sector];
+ float px = map->player.pos.x, py = map->player.pos.y;
+ float dx = map->player.velocity.x, dy = map->player.velocity.y;
+
+ #define vert(x) map->vertices[x]
+ for(unsigned i = 0; i < sect->nverts; i++)
+ {
+ size_t s1 = sect->vertices[i];
+ size_t s0 = sect->vertices[i+1];
+
+ if(sect->neighbors[i] != (size_t)-1
+ && intersectbox(px,py, px+dx,py+dy, vert(s0).x, vert(s0).y, vert(s1).x, vert(s1).y)
+ && pointside(px+dx, py+dy, vert(s0).x, vert(s0).y, vert(s1).x, vert(s1).y) < 0)
+ {
+ map->player.sector = sect->neighbors[i];
+ break;
+ }
+ }
+}
+
int map_load(map_t *map, char *filename)
{
int ret = 1;
@@ -104,7 +139,10 @@ int map_load(map_t *map, char *filename)
size_t verts = 0;
struct sector sectors[SECTS_CAP];
size_t sects = 0;
- player_t player = {0};
+
+ // player_t players[PLRS_CAP];
+ // size_t plrs = 0;
+ player_t players[1];
char line[512], *ptr;
int offset = 0;
@@ -161,7 +199,8 @@ int map_load(map_t *map, char *filename)
sectors[sects++].nverts = nverts;
break;
case 'p': // player
- sscanf(ptr += offset, "%f %f %f %zu %n", &player.pos.x, &player.pos.y, &player.angle, &player.sector, &offset);
+ player_default(&players[0]);
+ sscanf(ptr += offset, "%f %f %f %zu %n", &players[0].pos.x, &players[0].pos.y, &players[0].angle, &players[0].sector, &offset);
break;
}
}
@@ -174,7 +213,7 @@ int map_load(map_t *map, char *filename)
map->nverts = verts;
memcpy(map->vertices, vertices, verts * sizeof(*vertices));
- map->player = player;
+ memcpy(&map->player, &players[0], sizeof(map->player));
ret = 0;
exit:
@@ -220,11 +259,11 @@ void map_print(map_t *map)
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("%zu ", map->sectors[i].vertices[j]);
+ printf("%zd ", map->sectors[i].vertices[j]);
printf(" ");
for(size_t j = 0; j < map->sectors[i].nverts; j++)
- printf("%zu ", map->sectors[i].neighbors[j]);
+ printf("%zd ", map->sectors[i].neighbors[j]);
printf("\n");
}