summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2023-04-10 22:23:26 +0300
committerkartofen <mladenovnasko0@gmail.com>2023-04-10 22:23:26 +0300
commit685076399535d47e056eb2341baa18888d15482b (patch)
treed284bbbbd2d2f102520735dc7256e14d8911e749
parent80ead50951c8b0d2c60c9fd57b8a4c943634b084 (diff)
rendering one sector works
-rw-r--r--src/main.c47
-rw-r--r--src/player.c42
-rw-r--r--src/player.h10
-rw-r--r--src/sector.c77
-rw-r--r--src/sector.h4
5 files changed, 124 insertions, 56 deletions
diff --git a/src/main.c b/src/main.c
index 108649d..326286c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -7,9 +7,10 @@
int SW = 1200;
int SH = 800;
char *name = "Thingy";
-
SDL_Surface *surface = NULL;
+#define CLEAR_SCREEN(c) for(int i = 0; i < SW-1; i++) vline(i, 0, SH-1, c);
+
void vline(int x, int y1, int y2, uint32_t col)
{
y1 = clamp(y1, 0, SH-1);
@@ -59,33 +60,28 @@ int main(void)
return 1;
bool quit = false;
- int wasd[4] = {0};
+ bool wasd[4] = {0};
while(!quit)
{
SDL_Event event;
while(SDL_PollEvent(&event)) {
// ----------------- EVENTS ----------------- //
+ #define KEY_SWITCH(b) \
+ switch(event.key.keysym.sym) { \
+ case 'w': wasd[0] = b; break; \
+ case 'a': wasd[1] = b; break; \
+ case 's': wasd[2] = b; break; \
+ case 'd': wasd[3] = b; break; }
+
switch(event.type) {
case SDL_QUIT:
quit = true;
break;
case SDL_KEYDOWN:
- switch(event.key.keysym.sym)
- {
- case 'w': wasd[0] = 1; break;
- case 'a': wasd[1] = 1; break;
- case 's': wasd[2] = 1; break;
- case 'd': wasd[3] = 1; break;
- }
+ KEY_SWITCH(true);
break;
case SDL_KEYUP:
- switch(event.key.keysym.sym)
- {
- case 'w': wasd[0] = 0; break;
- case 'a': wasd[1] = 0; break;
- case 's': wasd[2] = 0; break;
- case 'd': wasd[3] = 0; break;
- }
+ KEY_SWITCH(false);
break;
default:
// log_debug(LOG_APPLICATION, "event: %d", event.type);
@@ -95,26 +91,15 @@ int main(void)
}
// ----------------- GAME LOOP ----------------- //
-
int x,y;
SDL_GetRelativeMouseState(&x,&y);
- map.player.angle += x * 0.03f;
-
- float move_vec[2] = {0.f, 0.f};
- if(wasd[0]) { move_vec[0] += map.player.anglecos*0.2f; move_vec[1] += map.player.anglesin*0.2f; }
- if(wasd[2]) { move_vec[0] -= map.player.anglecos*0.2f; move_vec[1] -= map.player.anglesin*0.2f; }
- if(wasd[1]) { move_vec[0] += map.player.anglesin*0.2f; move_vec[1] -= map.player.anglecos*0.2f; }
- if(wasd[3]) { move_vec[0] -= map.player.anglesin*0.2f; move_vec[1] += map.player.anglecos*0.2f; }
- int pushing = wasd[0] || wasd[1] || wasd[2] || wasd[3];
- float acceleration = pushing ? 0.4 : 0.2;
-
- map.player.pos.x += move_vec[0] * acceleration;
- map.player.pos.y += move_vec[1] * acceleration;
+ player_input(&map.player, wasd, x, y);
+ map_player_sector(&map);
+ // map_detect_collision(&map);
player_update(&map.player);
- for(int i = 0; i < SW-1; i++)
- vline(i, 0, SH-1, COLOR_LIGHTWHITE);
+ CLEAR_SCREEN(COLOR_LIGHTWHITE);
map_draw(&map, SW, SH);
// --------------------------------------------- //
diff --git a/src/player.c b/src/player.c
index b94290d..2231b9e 100644
--- a/src/player.c
+++ b/src/player.c
@@ -1,10 +1,48 @@
#include <math.h>
#include "player.h"
-int player_update(player_t *player)
+#define DEFAULT_STAND_HEIGHT 6.0f
+#define DEFAULT_DUCK_HEIGHT 2.5f
+#define DEFAULT_HEAD_MARGIN 1.0f
+
+void player_default(player_t *player)
+{
+ player->pos = (struct xyz){0.0f, 0.0f, 0.0f};
+ player->velocity = (struct xyz){0.0f, 0.0f, 0.0f};
+
+ player->angle = 0.0f; player->anglesin = 0.0f; player->anglecos = 1.0f;
+ player->sector = 0;
+
+ player->stand_height = DEFAULT_STAND_HEIGHT;
+ player->duck_height = DEFAULT_DUCK_HEIGHT;
+ player->head_margin = DEFAULT_HEAD_MARGIN;
+
+ player->ground = false; player->falling = true;
+ player->moving = false; player->ducking = false;
+}
+void player_input(player_t *player, bool *input, int rmouse_x, int rmouse_y)
{
+ (void)rmouse_y;
+ player->angle += rmouse_x * 0.03f;
+
+ float move_vec[2] = {0.f, 0.f};
+ if(input[0]) { move_vec[0] += player->anglecos*0.2f; move_vec[1] += player->anglesin*0.2f; }
+ if(input[2]) { move_vec[0] -= player->anglecos*0.2f; move_vec[1] -= player->anglesin*0.2f; }
+ if(input[1]) { move_vec[0] += player->anglesin*0.2f; move_vec[1] -= player->anglecos*0.2f; }
+ if(input[3]) { move_vec[0] -= player->anglesin*0.2f; move_vec[1] += player->anglecos*0.2f; }
+ player->moving = input[0] || input[1] || input[2] || input[3];
+ float acceleration = player->moving ? 0.4f : 0.2f;
+
+ player->velocity.x = player->velocity.x * (1-acceleration) + move_vec[0] * acceleration;
+ player->velocity.y = player->velocity.y * (1-acceleration) + move_vec[1] * acceleration;
+
player->anglesin = sinf(player->angle);
player->anglecos = cosf(player->angle);
+}
- return 0;
+void player_update(player_t *player)
+{
+ player->pos.x += player->velocity.x;
+ player->pos.y += player->velocity.y;
+ player->pos.z = player->stand_height; // temp
}
diff --git a/src/player.h b/src/player.h
index ee5270b..c627bcf 100644
--- a/src/player.h
+++ b/src/player.h
@@ -1,16 +1,20 @@
#ifndef PLAYER_H
#define PLAYER_H
+#include <stdbool.h>
#include "common.h"
typedef struct player {
struct xyz pos, velocity; // vectors for the player
- float angle, anglesin, anglecos, yaw; // angle, and its sine and cosine
+ float angle, anglesin, anglecos; // angle, and its sine and cosine
size_t sector; // the sector that the player is in
+ float stand_height, duck_height, head_margin; // eyeheights; minimum margin between current height and celling
+ bool ground, falling, moving, ducking;
} player_t;
-int player_update(player_t *player);
+void player_default(player_t *player);
-// TODO: Add functions to manipulate a player
+void player_input(player_t *player, bool *input, int rmouse_x, int rmouse_y);
+void player_update(player_t *player);
#endif
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");
}
diff --git a/src/sector.h b/src/sector.h
index 8315ee6..438184b 100644
--- a/src/sector.h
+++ b/src/sector.h
@@ -19,7 +19,9 @@ typedef struct {
player_t player; // the player (should be an array in the future)
} map_t;
-int map_draw(map_t *map, uint SW, uint SH);
+int map_draw(map_t *map, int SW, int SH); // SW and SH should be uint
+void map_player_sector(map_t *map);
+
int map_load(map_t *map, char *filename);
void map_unload(map_t *map);