diff options
| author | kartofen <mladenovnasko0@gmail.com> | 2023-04-09 02:02:51 +0300 | 
|---|---|---|
| committer | kartofen <mladenovnasko0@gmail.com> | 2023-04-09 02:02:51 +0300 | 
| commit | fc027f7d214028086178a7328926c9b14ead464d (patch) | |
| tree | d2972055a06565f26a19626ac3fb26ead84e0766 | |
map loading done
| -rw-r--r-- | .gitignore | 2 | ||||
| -rwxr-xr-x | build.sh | 57 | ||||
| -rw-r--r-- | files/map_clear.txt | 40 | ||||
| -rw-r--r-- | src/common.h | 49 | ||||
| -rw-r--r-- | src/main.c | 97 | ||||
| -rw-r--r-- | src/player.c | 3 | ||||
| -rw-r--r-- | src/player.h | 14 | ||||
| -rw-r--r-- | src/sector.c | 150 | ||||
| -rw-r--r-- | src/sector.h | 28 | 
9 files changed, 440 insertions, 0 deletions
| diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cbbd0b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bin/ +obj/
\ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..6ddf9a4 --- /dev/null +++ b/build.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +cd ${0%/*} # go to project root + +NAME="main" + +DEBUG_FLAGS="-std=c99 -Wall -Wextra -g -pedantic -DDEBUG" +# PROD_FLAGS="-std=c99 ???" +SDL_FLAGS="`sdl2-config --cflags --libs`" +FLAGS="$DEBUG_FLAGS $SDL_FLAGS" + +SRC="src" +OBJ="obj" +BIN="bin" +FILES="files" +RUN=0 + +function __run__ { +    RUN=1 +} + +function __leak__ { +    VALGRND="valgrind --leak-check=full --show-leak-kinds=all -s" +    RUN=1 +} + +function __prod__ { +    FLAGS="$PROD_FLAGS $SDL_FLAGS" +} + +function __clean__ { +    rm -rf $BIN +    rm -rf $OBJ +    exit 0 +} + +set -xe + +mkdir -p $BIN +mkdir -p $OBJ +mkdir -p $FILES + +if ! { [[ $# -eq 0 ]]; } 2> /dev/null +then +    __$1__ +fi + +gcc -o $OBJ/main.o -c $SRC/main.c     $FLAGS +gcc -o $OBJ/player.o -c $SRC/player.c $FLAGS +gcc -o $OBJ/sector.o -c $SRC/sector.c $FLAGS + +gcc -o $BIN/$NAME     $OBJ/*.o        $FLAGS + +if ! { [[ $RUN -eq 0 ]]; } 2> /dev/null +then +    $VALGRND $BIN/$NAME +fi diff --git a/files/map_clear.txt b/files/map_clear.txt new file mode 100644 index 0000000..f5d9e4c --- /dev/null +++ b/files/map_clear.txt @@ -0,0 +1,40 @@ +vertex	0	0 6 28 +vertex	2	1 17.5 +vertex	5	4 6 18 21 +vertex	6.5	9 11 13 13.5 17.5 +vertex	7	5 7 8 9 11 13 13.5 15 17 19 21 +vertex	7.5	4 6 +vertex	10.5	4 6 +vertex	11	5 7 8 9 11 13 13.5 15 17 19 21 +vertex	11.5	9 11 13 13.5 17.5 +vertex	13	4 6 18 21 +vertex	16	1 17.5 +vertex	18	0 6 28 + +sector	0 20	 3 14 29 49             -1 1 11 22 +sector	0 20	 17 15 14 3 9           -1 12 11 0 21 +sector	0 20	 41 42 43 44 50 49 40   -1 20 -1 3 -1 -1 22 +sector	0 14	 12 13 44 43 35 20      -1 21 -1 2 -1 4 +sector	0 12	 16 20 35 31            -1 -1 3 -1 +sector	16 28	 24 8 2 53 48 39        18 -1 7 -1 6 -1 +sector	16 28	 53 52 46 47 48         5 -1 8 10 -1 +sector	16 28	 1 2 8 7 6              23 -1 5 -1 10 +sector	16 36	 46 52 51 45            -1 6 -1 24 +sector	16 36	 25 26 28 27            24 -1 10 -1 +sector	16 26	 6 7 47 46 28 26        -1 7 -1 6 -1 9 +sector	2 20	 14 15 30 29            0 1 12 22 +sector	4 20	 15 17 32 30            11 1 13 22 +sector	6 20	 17 18 33 32            12 -1 14 -1 +sector	8 20	 18 19 34 33            13 19 15 20 +sector	10 24	 19 21 36 34            14 -1 16 -1 +sector	12 24	 21 22 37 36            15 -1 17 -1 +sector	14 28	 22 23 38 37            16 -1 18 -1 +sector	16 28	 23 24 39 38            17 -1 5 -1 +sector	8 14	 10 11 19 18            -1 21 -1 14 +sector	8 14	 33 34 42 41            -1 14 -1 2 +sector	0 20	 4 13 12 11 10 9 3      -1 -1 3 -1 19 -1 1 +sector	0 20	 29 30 32 40 49         0 11 12 -1 2 +sector	16 36	 1 6 5 0                -1 7 -1 24 +sector	16 36	 0 5 25 27 45 51        -1 23 -1 9 -1 8 + +player	2 6	0	0 diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..d9a222f --- /dev/null +++ b/src/common.h @@ -0,0 +1,49 @@ +#ifndef COMMON_H +#define COMMON_H + +#include <stdint.h>  // for size_t + +typedef unsigned int uint; + +#define min(a, b)      (((a) < (b)) ? (a) : (b)) +#define max(a, b)      (((a) > (b)) ? (a) : (b)) +#define clamp(x, l, h) (min(max((x), (l)), (h))) +#define cross(x1, y1, x2, y2) ((x1)*(y2) - (x2)*(y1)) + +struct xy { +    float x, y; +}; + +struct xyz { +    float x, y, z; +}; + +#define COLOR_WHITE 0xFFFFFF +#define COLOR_BLACK 0x000000 +#define COLOR_RED   0xFF0000 +#define COLOR_GREEN 0x00FF00 +#define COLOR_BLUE  0x0000FF +#define COLOR_LIGHTWHITE 0xF5F5F5FF +#define color(col) (((col)>>16) & 0xFF), (((col)>>8) & 0xFF), ((col) & 0xFF) + +// macro wrapper for the sdl logging system +#include <SDL2/SDL.h> +#define LOG_APPLICATION SDL_LOG_CATEGORY_APPLICATION +#define LOG_ERROR       SDL_LOG_CATEGORY_ERROR +#define LOG_ASSERT      SDL_LOG_CATEGORY_ASSERT +#define LOG_SYSTEM      SDL_LOG_CATEGORY_SYSTEM +#define LOG_AUDIO       SDL_LOG_CATEGORY_AUDIO +#define LOG_VIDEO       SDL_LOG_CATEGORY_VIDEO +#define LOG_RENDER      SDL_LOG_CATEGORY_RENDER +#define LOG_INPUT       SDL_LOG_CATEGORY_INPUT +#define LOG_TEST        SDL_LOG_CATEGORY_TEST +#define LOG_CUSTOM      SDL_LOG_CATEGORY_CUSTOM + +#define log(f, ...) SDL_Log(f, ##__VA_ARGS__) +#define log_critical(c, f, ...) SDL_LogCritical(c, f, ##__VA_ARGS__) +#define log_error(c, f, ...)    SDL_LogError(c, f, ##__VA_ARGS__) +#define log_warn(c, f, ...)     SDL_LogWarn(c, f, ##__VA_ARGS__) +#define log_info(c, f, ...)     SDL_LogInfo(c, f, ##__VA_ARGS__) +#define log_debug(c, f, ...)    SDL_LogDebug(c, f, ##__VA_ARGS__) +#define log_verbose(c, f, ...)  SDL_LogVerbose(c, f, ##__VA_ARGS__) +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..8b5aa40 --- /dev/null +++ b/src/main.c @@ -0,0 +1,97 @@ +#include <stdio.h> +#include <stdbool.h> +#include <SDL2/SDL.h> +#include "sector.h" +#include "common.h" + +int SW = 1200; +int SH =  800; +char *name = "Thingy"; + +SDL_Surface *surface = NULL; + +void vline(int x, int y1, int y2, uint32_t col) +{ +    y1 = clamp(y1, 0, SH-1); +    y2 = clamp(y2, 0, SH-1); + +    uint32_t *pixels = (uint32_t*)surface->pixels; +    for(int y = min(y1, y2); y <= max(y1, y2); y++) { +        pixels[y * SW + x] = SDL_MapRGB(surface->format, color(col)); +    } +} + +int main(void) +{ +    // set logging priority +#ifdef DEBUG +    SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG); +#else +    SDL_LogSetAllPriority(SDL_LOG_PRIORITY_ERROR); +#endif + +    map_t m; +    if(map_load(&m, "files/map_clear.txt")) +        return 1; +    map_print(&m); +    map_unload(&m); + +    return 0; + +    // ----------------- START SDL ----------------- // +    int ret = 1; +    SDL_Window *window = NULL; + +    if(SDL_Init(SDL_INIT_VIDEO) != 0) { +        log_critical(LOG_VIDEO, "SDL_Init: %s", SDL_GetError()); +        goto exit; +    } + +    window = SDL_CreateWindow(name, +                              SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, +                              SW, SH, 0); +    if(window == NULL) { +        log_critical(LOG_VIDEO, "SDL_CreateWindow: %s", SDL_GetError()); +        goto exit; +    } + +    surface = SDL_GetWindowSurface(window); +    if(surface == NULL) { +        log_critical(LOG_VIDEO, "SDL_GetWindowSurface %s", SDL_GetError()); +        goto exit; +    } +    // --------------------------------------------- // + + +    bool quit = false; +    while(!quit) { +        // ----------------- GAME LOOP ----------------- // +        for(int i = 0; i < SW; i++) +            vline(i, 0, SH-1, COLOR_LIGHTWHITE); +        // --------------------------------------------- // + +        SDL_Event event; +        while(SDL_PollEvent(&event)) { +            // ----------------- EVENTS ----------------- // +            switch(event.type) { +            case SDL_QUIT: +                quit = true; +                break; +            default: +                log_debug(LOG_APPLICATION, "event: %d", event.type); +                break; +            } +            // ------------------------------------------ // +        } + +        if(SDL_UpdateWindowSurface(window) != 0) { +            log_error(LOG_VIDEO, "SDL_UpdateWindowSurface: %s", SDL_GetError()); +        } +    } + +    ret = 0; +exit: +    if(window != NULL) SDL_DestroyWindow(window); +    SDL_Quit(); +    return ret; +} diff --git a/src/player.c b/src/player.c new file mode 100644 index 0000000..4490f93 --- /dev/null +++ b/src/player.c @@ -0,0 +1,3 @@ +#include "player.h" + +// TODO: Implement the functions that manipulate a player diff --git a/src/player.h b/src/player.h new file mode 100644 index 0000000..91a9d5e --- /dev/null +++ b/src/player.h @@ -0,0 +1,14 @@ +#ifndef PLAYER_H +#define PLAYER_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 +    uint sector; // the sector that the player is in +} player_t; + +// TODO: Add functions to manipulate a player + +#endif diff --git a/src/sector.c b/src/sector.c new file mode 100644 index 0000000..3374995 --- /dev/null +++ b/src/sector.c @@ -0,0 +1,150 @@ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include "sector.h" + +#define VERTS_CAP 512 +#define SECTS_CAP 512 +#define NUMS_CAP  512 + +int map_load(map_t *map, char *filename) +{ +    int ret = 1; + +    FILE *fp = fopen(filename, "rb"); +    if(!fp) { +        log_critical(LOG_SYSTEM, "fopen (%s): %s\n", filename, strerror(errno)); +        return ret; +    } + +    // temp structures +    struct xy vertices[VERTS_CAP]; +    size_t verts = 0; +    struct sector sectors[SECTS_CAP]; +    size_t sects = 0; +    player_t player = {0}; + +    char line[512], *ptr; +    int offset = 0; +    while(fgets(line, sizeof(line), fp) != NULL) +    { +        char word[256] = {0}; +        if(sscanf(ptr = line, "%s %n", word, &offset) != 1) word[0] = '\0'; + +        switch(word[0]) +        { +        case 'v':; // vertex +            struct xy vert; +            sscanf(ptr += offset, "%f %n", &vert.x, &offset); + +            while(sscanf(ptr += offset, "%f %n", &vert.y, &offset) != EOF) { +                if(verts >= VERTS_CAP) { +                    log_critical(LOG_APPLICATION, "VERTS_CAP of %d reached", VERTS_CAP); +                    goto exit; +                } +                vertices[verts++] = vert; +            } +            break; +        case 's': // sector +            if(sects >= SECTS_CAP) { +                log_critical(LOG_APPLICATION, "SECTS_CAP of %d reached", SECTS_CAP); +                goto exit; +            } + +            sscanf(ptr += offset, "%f %f %n", §ors[sects].floor, §ors[sects].ceil, &offset); + +            int numbers[NUMS_CAP]; +            size_t nums = 0; +            while(sscanf(ptr += offset, "%s %n", word, &offset) != EOF) { +                if(nums >= NUMS_CAP) { +                    log_critical(LOG_APPLICATION, "NUMS_CAP of %d reached", NUMS_CAP); +                    goto exit; +                } + +                numbers[nums++] = (word[0] == 'x') ? -1 : atoi(word); +            } + +            size_t nverts = nums/2; +            // populate vertices +            sectors[sects].vertices = malloc((nverts + 1) * sizeof(*sectors[sects].vertices)); +            for(size_t i = 0; i < nverts; i++) +                sectors[sects].vertices[i+1] = numbers[i]; +            sectors[sects].vertices[0] = sectors[sects].vertices[nverts]; // need to form a loop + +            // populate neighbors +            sectors[sects].neighbors = malloc(nverts * sizeof(*sectors[sects].neighbors)); +            for(size_t i = 0; i < nverts; i++) +                sectors[sects].neighbors[i] = numbers[nverts + i]; + +            sectors[sects++].nverts = nverts; +            break; +        case 'p': // player +            sscanf(ptr += offset, "%f %f %f %d %n", &player.pos.x, &player.pos.y, &player.angle, (int *)&player.sector, &offset); +            break; +        } +    } + +    map->sectors = malloc(sects * sizeof(*sectors)); +    map->nsects = sects; +    memcpy(map->sectors, sectors, sects * sizeof(*sectors)); + +    map->vertices = malloc(verts * sizeof(*vertices)); +    map->nverts = verts; +    memcpy(map->vertices, vertices, verts * sizeof(*vertices)); + +    map->player = player; + +    ret = 0; +exit: +    fclose(fp); +    return ret; +} + +void map_unload(map_t *map) +{ +    for(size_t i = 0; i < map->nsects; i++) { +        free(map->sectors[i].vertices); +        free(map->sectors[i].neighbors); +    } + +    free(map->sectors); +    free(map->vertices); +} + +int map_save(map_t *map, char *filename) +{ +    FILE *fp = fopen(filename, "wb"); +    if(!fp) { +        log_error(LOG_SYSTEM, "fopen (%s): %s\n", filename, strerror(errno)); +        return 1; +    } + +    (void)map; + +    // something something + +    return 0; +} + +void map_print(map_t *map) +{ +    log("%ld %ld", map->nverts, map->nsects); +    for(size_t i = 0; i < map->nverts; i++) { +        printf("v %ld {%.1f %.1f}\n", i, map->vertices[i].x, map->vertices[i].y); +    } + +    for(size_t i = 0; i < map->nsects; i++) +    { +        printf("s %ld  %.1f %.1f  ", i, map->sectors[i].floor, map->sectors[i].ceil); + +        for(size_t j = 0; j < map->sectors[i].nverts + 1; j++) +            printf("%d ", map->sectors[i].vertices[j]); +        printf("  "); + +        for(size_t j = 0; j < map->sectors[i].nverts; j++) +            printf("%d ", map->sectors[i].neighbors[j]); +        printf("\n"); +    } + +    printf("p %.1f %.1f %.1f %d", map->player.pos.x, map->player.pos.y, map->player.angle, map->player.sector); +} diff --git a/src/sector.h b/src/sector.h new file mode 100644 index 0000000..20050f7 --- /dev/null +++ b/src/sector.h @@ -0,0 +1,28 @@ +#ifndef SECTOR_H +#define SECTOR_H + +#include "common.h" +#include "player.h" + +struct sector { +    float floor, ceil;   // floor and ceiling heights +    uint *vertices;      // index of each vertex (vertices[nverts]) +    uint *neighbors;     // index of each neighboring sector (neighbors[nverts]) +    size_t nverts;       // number of vertices defining the sector +}; + +typedef struct { +    struct sector *sectors;  // all the sectors in the map +    size_t nsects;           // sectors[nsects] +    struct xy *vertices;     // all vertices in the map +    size_t nverts;           // vertices[nverts] +    player_t player;         // the player (should be an array in the future) +} map_t; + +int map_load(map_t *map, char *filename); +void map_unload(map_t *map); + +void map_print(map_t *map); +int map_save(map_t *map, char *filename); + +#endif | 
