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 |