diff options
Diffstat (limited to 'src/sector.c')
-rw-r--r-- | src/sector.c | 77 |
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"); } |