diff options
author | kartofen <mladenovnasko0@gmail.com> | 2023-04-10 22:23:26 +0300 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2023-04-10 22:23:26 +0300 |
commit | 685076399535d47e056eb2341baa18888d15482b (patch) | |
tree | d284bbbbd2d2f102520735dc7256e14d8911e749 | |
parent | 80ead50951c8b0d2c60c9fd57b8a4c943634b084 (diff) |
rendering one sector works
-rw-r--r-- | src/main.c | 47 | ||||
-rw-r--r-- | src/player.c | 42 | ||||
-rw-r--r-- | src/player.h | 10 | ||||
-rw-r--r-- | src/sector.c | 77 | ||||
-rw-r--r-- | src/sector.h | 4 |
5 files changed, 124 insertions, 56 deletions
@@ -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); |