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 /src | |
| parent | 80ead50951c8b0d2c60c9fd57b8a4c943634b084 (diff) | |
rendering one sector works
Diffstat (limited to 'src')
| -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); | 
