├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── img ├── 2017-08-19-074806_513x513_scrot.png └── 2017-08-19-075010_513x513_scrot.png └── main.c /.gitignore: -------------------------------------------------------------------------------- 1 | kvltland 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Gustav Louw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | BIN = kvltland 2 | 3 | CFLAGS = -std=c99 -Wall -Wextra -pedantic -Ofast -flto -march=native 4 | 5 | LDFLAGS = -lm -lSDL2 6 | 7 | CC = gcc 8 | 9 | SRC = main.c 10 | 11 | all: 12 | $(CC) $(CFLAGS) $(LDFLAGS) $(SRC) -o $(BIN) 13 | 14 | run: 15 | ./$(BIN) 16 | 17 | clean: 18 | rm -f $(BIN) 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kvltland 2 | 3 | Kvltland aims to be the most metal land generator you have ever seen. 4 | 5 | By metal I mean Scandinavian black metal metal. 6 | 7 | make; ./kvltland 8 | 9 | ![Screenshot](img/2017-08-19-074806_513x513_scrot.png) 10 | 11 | ![Screenshot](img/2017-08-19-075010_513x513_scrot.png) 12 | -------------------------------------------------------------------------------- /img/2017-08-19-074806_513x513_scrot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glouw/kvltland/fa9b0418bea658f99662c4a5c9c52fc8a3989a2f/img/2017-08-19-074806_513x513_scrot.png -------------------------------------------------------------------------------- /img/2017-08-19-075010_513x513_scrot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glouw/kvltland/fa9b0418bea658f99662c4a5c9c52fc8a3989a2f/img/2017-08-19-075010_513x513_scrot.png -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | typedef struct 6 | { 7 | int* grid; 8 | int size; 9 | } 10 | Map; 11 | 12 | typedef struct 13 | { 14 | int x; 15 | int y; 16 | } 17 | Cart; 18 | 19 | typedef struct 20 | { 21 | Cart a; 22 | Cart b; 23 | } 24 | Mesh; 25 | 26 | static void Interpolate(Map* map, const Mesh m) 27 | { 28 | for(int x = m.a.x; x < m.b.x; x++) 29 | for(int y = m.a.y; y < m.b.y; y++) 30 | map->grid[y + map->size * x] = ( 31 | map->grid[m.a.y + map->size * m.a.x] * (m.b.x - x) * (m.b.y - y) + 32 | map->grid[m.a.y + map->size * m.b.x] * (x - m.a.x) * (m.b.y - y) + 33 | map->grid[m.b.y + map->size * m.a.x] * (m.b.x - x) * (y - m.a.y) + 34 | map->grid[m.b.y + map->size * m.b.x] * (x - m.a.x) * (y - m.a.y) 35 | ) / ((m.b.x - m.a.x) * (m.b.y - m.a.y)); 36 | } 37 | 38 | static void Noise(Map* map, const int square) 39 | { 40 | if(square == 2) 41 | return; 42 | const int m = (square - 1) / 2; 43 | for(int i = m; i < map->size; i += 2 * m) 44 | for(int j = m; j < map->size; j += 2 * m) 45 | map->grid[j + map->size * i] += rand() % (2 * square + 1) - square; 46 | for(int i = 0; i < map->size - 1; i += m) 47 | for(int j = 0; j < map->size - 1; j += m) 48 | { 49 | const Mesh mesh = { { i, j }, { i + m, j + m } }; 50 | Interpolate(map, mesh); 51 | } 52 | Noise(map, m + 1); 53 | } 54 | 55 | static int Max(Map* map) 56 | { 57 | int max = INT_MIN; 58 | for(int i = 0; i < map->size; i++) 59 | for(int j = 0; j < map->size; j++) 60 | if(map->grid[j + map->size * i] > max) 61 | max = map->grid[j + map->size * i]; 62 | return max; 63 | } 64 | 65 | static int Min(Map* map) 66 | { 67 | int min = INT_MAX; 68 | for(int i = 0; i < map->size; i++) 69 | for(int j = 0; j < map->size; j++) 70 | if(map->grid[j + map->size * i] < min) 71 | min = map->grid[j + map->size * i]; 72 | return min; 73 | } 74 | 75 | static void Add(Map* map, const int val) 76 | { 77 | for(int i = 0; i < map->size; i++) 78 | for(int j = 0; j < map->size; j++) 79 | map->grid[j + map->size * i] += val; 80 | } 81 | 82 | static void Normalize(Map* map) 83 | { 84 | const int lowest = Min(map); 85 | Add(map, abs(lowest)); 86 | const int highest = Max(map); 87 | for(int i = 0; i < map->size; i++) 88 | for(int j = 0; j < map->size; j++) 89 | map->grid[j + map->size * i] = 0xFF * map->grid[j + map->size * i] / (float) highest; 90 | } 91 | 92 | static void Draw(Map* map, SDL_Renderer* const renderer) 93 | { 94 | Normalize(map); 95 | for(int i = 0; i < map->size; i++) 96 | for(int j = 0; j < map->size; j++) 97 | { 98 | const int a = 0x2A; // Sea floor. 99 | const int b = 0x5F; // Sea level. 100 | const int p = map->grid[j + map->size * i]; 101 | p < a ? 102 | SDL_SetRenderDrawColor(renderer, 0, 0, a, 0): // Sea floor. 103 | p < b ? 104 | SDL_SetRenderDrawColor(renderer, 0, 0, p, 0): // Sea. 105 | SDL_SetRenderDrawColor(renderer, p, p, p, 0); // Ice and snow. 106 | SDL_RenderDrawPoint(renderer, i, j); 107 | } 108 | SDL_RenderPresent(renderer); 109 | SDL_Delay(1000); 110 | } 111 | 112 | Map MP_Build(const int power) 113 | { 114 | const int size = pow(2, power) + 1; 115 | Map map = { 0 }; 116 | map.grid = calloc(size * size, sizeof(*map.grid)); 117 | map.size = size; 118 | Noise(&map, map.size); 119 | return map; 120 | } 121 | 122 | void MP_Clean(Map* map) 123 | { 124 | free(map->grid); 125 | } 126 | 127 | int main() 128 | { 129 | srand(time(0)); 130 | const int power = 9; 131 | Map map = MP_Build(power); 132 | SDL_Window* window; 133 | SDL_Renderer* renderer; 134 | SDL_CreateWindowAndRenderer(map.size, map.size, 0, &window, &renderer); 135 | Draw(&map, renderer); 136 | MP_Clean(&map); 137 | SDL_DestroyRenderer(renderer); 138 | SDL_DestroyWindow(window); 139 | return 0; 140 | } 141 | --------------------------------------------------------------------------------