summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2023-04-09 02:02:51 +0300
committerkartofen <mladenovnasko0@gmail.com>2023-04-09 02:02:51 +0300
commitfc027f7d214028086178a7328926c9b14ead464d (patch)
treed2972055a06565f26a19626ac3fb26ead84e0766
map loading done
-rw-r--r--.gitignore2
-rwxr-xr-xbuild.sh57
-rw-r--r--files/map_clear.txt40
-rw-r--r--src/common.h49
-rw-r--r--src/main.c97
-rw-r--r--src/player.c3
-rw-r--r--src/player.h14
-rw-r--r--src/sector.c150
-rw-r--r--src/sector.h28
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", &sectors[sects].floor, &sectors[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