diff options
| author | KonAki <konaki@anokonaki.org> | 2026-10-11 04:51:06 +0800 |
|---|---|---|
| committer | KonAki <konaki@anokonaki.org> | 2026-10-11 04:51:06 +0800 |
| commit | 64a416a3fa0b5097afe723557ca71fc99606d3d9 (patch) | |
| tree | 6d5eea1ddec0ed709ab9a4ebdc1de9bb002c81ce /kon/konsector.h | |
| parent | d3b6458db0c189d23100331c0e9e5001ff96c2f1 (diff) | |
add sector module: room maps in a text format with entities
Diffstat (limited to 'kon/konsector.h')
| -rw-r--r-- | kon/konsector.h | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/kon/konsector.h b/kon/konsector.h new file mode 100644 index 0000000..58a4ecb --- /dev/null +++ b/kon/konsector.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: MIT */ +/* + * konsector.h + * + * Copyright (c) 2026 KonAki + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef KONSECTOR_H +#define KONSECTOR_H + +#include <stddef.h> + +#include "konmath.h" + +/*** definition ***/ + +/* a map is rooms seen from above. every room (sector) is a polygon of vertices with a floor and a ceiling height, and every + edge of the polygon is a wall. where two sectors share an edge it is an opening instead of a wall, and if their heights + differ there is a step or a lintel there. the plan is x going east and z going south, y is up like everywhere else. + a room cannot sit on top of another one */ + +#define KON_NAME_LENGTH 24 +#define KON_ENTITY_PROPS 8 + +typedef struct kon_sectorEdge { + int portal; /* the sector on the other side, -1 for a wall with nothing behind it */ + int texture; /* index into the map's textures, -1 uses the sector's wall texture */ +} kon_sectorEdge_t; + +typedef struct kon_sector { + int first, count; /* where its corners start in indices and edges, and how many there are */ + float floor, ceiling; + float light; /* 0 to 1, how bright the room is, 1 */ + int floorTexture, ceilingTexture, wallTexture; /* -1 for none */ +} kon_sector_t; + +typedef struct kon_entityProp { + char key[16]; + char value[32]; +} kon_entityProp_t; + +/* things placed in the map that are not walls: where you start, doors, buttons, lights. the engine only reads them, + what a kind does is up to the game. name and target are how things point at each other, a button with the target "door1" + is meant for the entity named "door1" */ +typedef struct kon_entity { + char kind[KON_NAME_LENGTH]; + char name[KON_NAME_LENGTH]; + char target[KON_NAME_LENGTH]; + kon_vec3_t position; + float angle; /* radians, 0 faces north (towards -z) and it turns clockwise from above like the camera yaw */ + int sector; /* the sector it is in, -1 if the position is outside every sector */ + int propCount; + kon_entityProp_t props[KON_ENTITY_PROPS]; +} kon_entity_t; + +typedef struct kon_sectorMap { + int vertexCount; + kon_vec2_t *vertices; /* x, z */ + + /* the corners of a sector are indices[first] to indices[first + count - 1], counter clockwise seen from above. + edge n runs from corner n to corner n + 1 and the last one closes the loop */ + int sectorCount; + kon_sector_t *sectors; + int indexCount; + int *indices; + kon_sectorEdge_t *edges; + + int entityCount; + kon_entity_t *entities; + + int textureCount; + char (*textures)[KON_NAME_LENGTH]; /* names only, the game decides what picture goes with each */ +} kon_sectorMap_t; + +/*** loading ***/ + +/* reads a map from text. returns NULL and fills error (if it is not NULL) with something like "line 12: sector 2 has a ceiling below its floor". + a clockwise sector is turned around, anything else wrong is an error */ +kon_sectorMap_t *kon_sectorParse(const char *text, char *error, size_t errorSize); +kon_sectorMap_t *kon_sectorLoad(const char *path, char *error, size_t errorSize); +void kon_sectorFree(kon_sectorMap_t *map); + +/* the same text format, so a map can be edited in the game and saved. returns 0 on success */ +int kon_sectorSave(const kon_sectorMap_t *map, const char *path); + +/*** looking things up ***/ + +/* the sector that holds the point, or -1. hint is a sector to try first (and its neighbours), pass -1 if you have none. + moving things should pass the sector they were in last frame, that makes this a few comparisons instead of a search */ +int kon_sectorAt(const kon_sectorMap_t *map, float x, float z, int hint); + +/* where corner n of a sector is */ +kon_vec2_t kon_sectorCorner(const kon_sectorMap_t *map, int sector, int n); + +/* the texture of an edge, the sector's own wall texture when the edge has none */ +int kon_sectorWallTexture(const kon_sectorMap_t *map, int sector, int edge); + +/* -1 if the name is not used in the map */ +int kon_sectorTextureIndex(const kon_sectorMap_t *map, const char *name); + +/*** entities ***/ + +/* the first entity with this name, or -1 */ +int kon_entityFind(const kon_sectorMap_t *map, const char *name); + +/* fills out with the indices of every entity named like this, up to max, and returns how many there are in total. + this is how a button finds what it is for: ask for the entities named like its target */ +int kon_entityTargets(const kon_sectorMap_t *map, const char *name, int *out, int max); + +/* props are the key=value pairs written after the entity in the file. they are text, these read them as numbers */ +const char *kon_entityString(const kon_entity_t *entity, const char *key, const char *fallback); +float kon_entityFloat(const kon_entity_t *entity, const char *key, float fallback); +int kon_entityInt(const kon_entity_t *entity, const char *key, int fallback); + +#endif |
