]> git.lizzy.rs Git - shadowclad.git/blob - src/game/level.c
0dd1d6146ee20416bc159faf3a5bfcc26c4d57cf
[shadowclad.git] / src / game / level.c
1 #include <GL/gl.h>
2 #include <stdlib.h>
3
4 #include "engine/logger.h"
5 #include "engine/scene.h"
6
7 #include "level.h"
8 #include "player.h"
9
10 static Block blockEmpty = { .type = BLOCKTYPE_SPACE,
11                             .solid = NULL };
12 static Block blockWall01 = { .type = BLOCKTYPE_OBSTACLE,
13                              .solid = NULL };
14
15 static Block* testBlocks[9] = { &blockWall01, &blockWall01, &blockWall01,
16                                 &blockEmpty, &blockEmpty, &blockEmpty,
17                                 &blockWall01, &blockEmpty, &blockWall01 };
18
19 BlockGrid levelGrid = { .width = 3,
20                         .depth = 3,
21                         .blocks = testBlocks };
22
23 #define DEFAULT_PLAYER_SPAWN_POS { -BLOCKGRID_CELL_SIZE, 0.0f, -BLOCKGRID_CELL_SIZE }
24 Vector3D playerSpawnPos = DEFAULT_PLAYER_SPAWN_POS;
25
26
27
28 void initLevel() {
29         blockWall01.solid = importSolid("assets/wall01.3ds");
30         
31         buildLevelFromImage(readTga("assets/level01.tga"));
32         
33         Scene* levelScene = newScene();
34         
35         for (size_t z = 0; z < levelGrid.depth; ++z) {
36                 for (size_t x = 0; x < levelGrid.width; ++x) {
37                         Scene* blockScene = newScene();
38                         translate(&blockScene->transform, (Vector3D) { .x = x * BLOCKGRID_CELL_SIZE,
39                                                                        .y = 0.0f,
40                                                                        .z = z * BLOCKGRID_CELL_SIZE });
41                         blockScene->solid = getBlockFromGrid(levelGrid, x, z)->solid;
42                         insertChildScene(levelScene, blockScene);
43                 }
44         }
45
46         currentScene = levelScene;
47 }
48
49 void buildLevelFromImage(TgaImage* image) {
50         if (image == NULL) {
51                 logError("Null image received, cannot build level");
52                 return;
53         }
54         
55         if (image->header.imageBpp != 32) {
56                 logError("Invalid level image format (%d bpp)", image->header.imageBpp);
57                 return;
58         }
59         
60         BlockGrid newGrid = { .width = image->header.imageWidth,
61                               .depth = image->header.imageHeight,
62                               .blocks = malloc(image->header.imageWidth
63                                                * image->header.imageHeight
64                                                * sizeof(Block*)) };
65         playerSpawnPos = (Vector3D) DEFAULT_PLAYER_SPAWN_POS;
66         
67         for (size_t row = 0; row < newGrid.depth; ++row) {
68                 for (size_t x = 0; x < newGrid.width; ++x) {
69                         // Flip the image vertically due to (0, 0) being bottom left
70                         size_t z = newGrid.depth - row - 1;
71                         
72                         uint32_t pixelColorARGB = ((uint32_t*) image->bytes)[(row * newGrid.width) + x];
73                         Block* block;
74                         switch (pixelColorARGB) {
75                                 case 0xFFFF0000:
76                                         block = &blockWall01;
77                                         break;
78                                 case 0xFF00FFFF:
79                                         block = &blockEmpty;
80                                         playerSpawnPos = (Vector3D) { x * BLOCKGRID_CELL_SIZE, 0.0f, z * BLOCKGRID_CELL_SIZE };
81                                         break;
82                                 default:
83                                         block = &blockEmpty;
84                                         break;
85                         }
86                         setBlockInGrid(newGrid, x, z, block);
87                 }
88         }
89         
90         levelGrid = newGrid;
91         spawnPlayer();
92 }