6 #include "engine/logger.h"
7 #include "engine/scene.h"
8 #include "engine/tga.h"
14 static const float BLOCKGRID_CELL_SIZE = 2.5f;
16 static Block blockEmpty = { .type = BLOCKTYPE_SPACE,
18 static Block blockWall01 = { .type = BLOCKTYPE_OBSTACLE,
21 static Transform playerSpawnTransform;
23 static void buildLevelFromImage(const TgaImage* image);
24 static inline Block* getBlockFromGrid(BlockGrid grid, size_t x, size_t z);
25 static inline void setBlockInGrid(BlockGrid grid, size_t x, size_t z, Block* block);
30 playerSpawnTransform = identity();
31 translate(&playerSpawnTransform, (Vector) { .x = -BLOCKGRID_CELL_SIZE,
33 .z = -BLOCKGRID_CELL_SIZE });
35 blockWall01.solid = importSolid("assets/wall01.3ds");
37 buildLevelFromImage(readTga("assets/level01.tga"));
39 Scene* levelScene = newScene();
41 for (size_t z = 0; z < levelGrid.depth; ++z) {
42 for (size_t x = 0; x < levelGrid.width; ++x) {
43 Scene* blockScene = newScene();
44 translate(&blockScene->transform, (Vector) { .x = x * BLOCKGRID_CELL_SIZE,
46 .z = z * BLOCKGRID_CELL_SIZE });
47 blockScene->solid = getBlockFromGrid(levelGrid, x, z)->solid;
48 insertChildScene(levelScene, blockScene);
52 currentScene = levelScene;
56 spawnPlayer(playerSpawnTransform);
59 static void buildLevelFromImage(const TgaImage* image) {
61 logError("Null image received, cannot build level");
65 if (image->header.imageBpp != 32) {
66 logError("Invalid level image format (%d bpp)", image->header.imageBpp);
70 BlockGrid newGrid = { .width = image->header.imageWidth,
71 .depth = image->header.imageHeight,
72 .blocks = malloc(image->header.imageWidth
73 * image->header.imageHeight
76 for (size_t row = 0; row < newGrid.depth; ++row) {
77 for (size_t x = 0; x < newGrid.width; ++x) {
78 // Flip the image vertically due to (0, 0) being bottom left
79 size_t z = newGrid.depth - row - 1;
81 uint32_t pixelColorARGB = ((uint32_t*) image->bytes)[(row * newGrid.width) + x];
83 switch (pixelColorARGB) {
89 playerSpawnTransform = identity();
90 translate(&playerSpawnTransform, (Vector) { .x = x * BLOCKGRID_CELL_SIZE,
92 .z = z * BLOCKGRID_CELL_SIZE });
98 setBlockInGrid(newGrid, x, z, block);
105 static inline Block* getBlockFromGrid(BlockGrid grid, size_t x, size_t z) {
106 return grid.blocks[(z * grid.width) + x];
109 static inline void setBlockInGrid(BlockGrid grid, size_t x, size_t z, Block* block) {
110 grid.blocks[(z * grid.width) + x] = block;