summaryrefslogtreecommitdiff
path: root/src/sector.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sector.c')
-rw-r--r--src/sector.c71
1 files changed, 55 insertions, 16 deletions
diff --git a/src/sector.c b/src/sector.c
index c315382..f43ab86 100644
--- a/src/sector.c
+++ b/src/sector.c
@@ -14,6 +14,7 @@
void vline(int x, int y1, int y2, uint32_t col);
+// !! drawing is dogshit !!
int map_draw(map_t *map, int SW, int SH)
{
int sect_rendered[map->nsects];
@@ -85,7 +86,7 @@ int map_draw(map_t *map, int SW, int SH)
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;
+ 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
@@ -94,26 +95,27 @@ int map_draw(map_t *map, int SW, int SH)
// after (over) the walls
int old_ytop = ytop[x], old_ybottom = ybottom[x];
- // TODO: add depth shading
+ // depth-shaded white color
+ uint wall_col = scale_color(COLOR_WHITE, (2*z/3));
+
if(neighbor == (size_t)-1) { // no neighbor
- // vline(x, cya, cyb, x==x1||x==x2 ? : );
- vline(x, cya, cyb, COLOR_WHITE);
+ vline(x, cya, cyb, wall_col);
} 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, cya, cnya-1, wall_col); // upper wall
// vline(x, cnya, cnyb, COLOR_RED); // portal
- vline(x, cnyb+1, cyb, COLOR_WHITE); // lower wall
+ vline(x, cnyb+1, cyb, wall_col); // 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
}
/* Render ceiling: everything above this sector's ceiling height. */
- vline(x, old_ytop, cya-1, COLOR_GREEN);
+ vline(x, old_ytop, cya-1, scale_color(COLOR_GREEN, 0));
/* Render floor: everything below this sector's floor height. */
- vline(x, cyb+1, old_ybottom, COLOR_BLUE);
+ vline(x, cyb+1, old_ybottom, scale_color(COLOR_BLUE, 0));
}
if((neighbor != (size_t)-1) && (endx >= beginx) && ((tail+1)%MAX_QUEUE != head)) {
@@ -128,28 +130,65 @@ int map_draw(map_t *map, int SW, int SH)
return 0;
}
-void map_player_sector(map_t *map)
+// !! collision is dogshit !!
+void map_detect_collision(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;
+ player_t *player = &map->player;
+ struct sector *sect = &map->sectors[player->sector];
+ float eyeheight = player->ducking ? player->duck_height : player->stand_height;
+
+ player->velocity.z -= 0.05f;
+ float nextz = player->pos.z + player->velocity.z;
+ if(nextz < eyeheight + sect->floor) // falling inside the floor
+ {
+ player->pos.z = sect->floor + eyeheight;
+ player->velocity.z = 0.0f;
+ }
+ if(nextz + player->head_margin > sect->ceil) // falling up to the celling
+ {
+ player->pos.z = sect->ceil - player->head_margin;
+ player->velocity.z = 0.0f;
+ }
+
+ float px = player->pos.x, py = player->pos.y;
+ float dx = player->velocity.x, dy = player->velocity.y;
#define vert(x) map->vertices[x]
+
+ // wether the player is intersecting a sector edge
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)
+ if(!(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))
+ continue;
+
+ float hole_low = 0.0f, hole_high = 0.0f;
+ if(sect->neighbors[i] != (size_t)-1)
{
+ hole_high = min(sect->ceil, map->sectors[sect->neighbors[i]].ceil);
+ hole_low = map->sectors[sect->neighbors[i]].floor;
+ }
+
+ // slide along the wall
+ if(sect->neighbors[i] == (size_t)-1
+ || hole_high < player->pos.z + player->head_margin
+ || hole_low - player->pos.z > player->knee_height) {
+ // formula from wikipedia
+ float xd = vert(s1).x - vert(s0).x, yd = vert(s1).y - vert(s0).y;
+ player->velocity.x = xd * (dx*xd + yd*dy) / (xd*xd + yd*yd);
+ player->velocity.y = yd * (dx*xd + yd*dy) / (xd*xd + yd*yd);
+ } else {
map->player.sector = sect->neighbors[i];
- break;
}
+
+ break;
}
}
+
int map_load(map_t *map, char *filename)
{
int ret = 1;