Create block adding functions
This commit is contained in:
parent
7e8c82fae3
commit
e2d12804d2
6 changed files with 225 additions and 18 deletions
7
constants.h
Normal file
7
constants.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef _LCR_CONSTANTS_H
|
||||
#define _LCR_CONSTANTS_H
|
||||
|
||||
/** Maximum number of triangles of a block shape. */
|
||||
#define LCR_MAP_BLOCK_SHAPE_MAX_TRIANGLES 32
|
||||
|
||||
#endif
|
23
debug.h
Normal file
23
debug.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef _LCR_DEBUG_H
|
||||
#define _LCR_DEBUG_H
|
||||
|
||||
#include "map.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void LCR_debugPrintCurrentMap()
|
||||
{
|
||||
puts("current map:");
|
||||
|
||||
for (int i = 0; i < LCR_currentMap.blockCount; ++i)
|
||||
{
|
||||
uint8_t x, y, z;
|
||||
|
||||
LCR_mapBlockGetCoords(LCR_currentMap.blocks + i * 4,&x,&y,&z);
|
||||
|
||||
printf(" block %d: type %d, coord %d (%d %d %d)\n",i,
|
||||
LCR_currentMap.blocks[i * 4],LCR_mapBlockGetCoordNumber(
|
||||
LCR_currentMap.blocks + i * 4),x,y,z);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
1
frontend_sdl.c
Normal file
1
frontend_sdl.c
Normal file
|
@ -0,0 +1 @@
|
|||
#include "game.h"
|
8
main.c
8
main.c
|
@ -1,9 +1,13 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "game.h"
|
||||
#include "debug.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("aaa");
|
||||
return 1;
|
||||
LCR_mapLoad(LCR_map0);
|
||||
|
||||
LCR_debugPrintCurrentMap();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
202
map.h
202
map.h
|
@ -2,6 +2,8 @@
|
|||
#define _LCR_MAP
|
||||
|
||||
#include <stdint.h>
|
||||
#include "constants.h"
|
||||
#include "settings.h"
|
||||
|
||||
/**
|
||||
The map (track) module for Licar.
|
||||
|
@ -12,7 +14,7 @@
|
|||
- x goes right, y goes up, z goes forward
|
||||
- coordinate number is a single number obtained as x + 64 * y + 64 * 64 * z
|
||||
|
||||
Map format is binary and consists of the following values:
|
||||
The STORAGE map format is binary and consists of the following values:
|
||||
- 76, 77 (for "LM", magic number)
|
||||
- ASCII map name
|
||||
- 10 (separator)
|
||||
|
@ -20,7 +22,7 @@
|
|||
- 10 (separator)
|
||||
- block values, each one in the format:
|
||||
- 1 byte type: says the type of block. If the highest bit is 0, the block
|
||||
is normal, otherwise it is a special block (e.g. a "command")
|
||||
is normal, otherwise it is a special block (will be preprocessed)
|
||||
- 3 bytes: A, B, C, such that:
|
||||
- A, B and lowest 2 bits of C form the block coordinate number (A being
|
||||
the lowest part etc.)
|
||||
|
@ -36,6 +38,10 @@
|
|||
blocks placed on the same coordinate. Internally the map will be preprocessed
|
||||
to RAM when loaded so that thing like the magic number and special blocks are
|
||||
removed and the remaining blocks will be sorted for fast block searching.
|
||||
|
||||
The PREPROCESSED map format is similar, but only consists of block values but
|
||||
there are only normal blocks (no special blocks) and they are sorted by their
|
||||
coordinate number.
|
||||
*/
|
||||
|
||||
#define LCR_BLOCK_TRANSFORM_ROT_MASK 0x60
|
||||
|
@ -48,33 +54,62 @@
|
|||
|
||||
#define LCR_BLOCK_XYZ_TO_COORD(x,y,z)
|
||||
|
||||
#define LCR_MAP_MAGIC_NUMBER 'L', 'M'
|
||||
#define LCR_MAP_MAGIC_NUMBER1 'L'
|
||||
#define LCR_MAP_MAGIC_NUMBER2 'M'
|
||||
#define LCR_MAP_MAGIC_NUMBER LCR_MAP_MAGIC_NUMBER1, LCR_MAP_MAGIC_NUMBER2
|
||||
#define LCR_MAP_TERMINATOR 0xff
|
||||
#define LCR_MAP_BLOCK(t,x,y,z,r) 0 // TODO
|
||||
#define LCR_MAP_BLOCK(t,x,y,z,m,r) t,(unsigned char) (x | (y << 6)), \
|
||||
(unsigned char) ((y >> 2) | (z << 4)), \
|
||||
(unsigned char) ((z >> 4) | (m << 2) | \
|
||||
(r << 4))
|
||||
|
||||
#define LCR_BLOCK_MATERIAL_CONCRETE 0x00
|
||||
#define LCR_BLOCK_MATERIAL_DIRT 0x01
|
||||
|
||||
#define LCR_MAP_COUNT 1
|
||||
|
||||
#define LCR_BLOCK_FULL 0x00 ///< completely filled block
|
||||
#define LCR_BLOCK_BOTTOM 0x01 ///< filled bottom half of block
|
||||
#define LCR_BLOCK_LEFT 0x02 ///< filled left half of block
|
||||
#define LCR_BLOCK_LEFT_FRONT 0x03 ///< filled left front quarter of block
|
||||
#define LCR_BLOCK_BOTTOM_LEFT 0x04 ///< filled bottom left quarter of block
|
||||
// normal blocks:
|
||||
#define LCR_BLOCK_FULL 0x00 ///< completely filled block
|
||||
#define LCR_BLOCK_BOTTOM 0x01 ///< filled bottom half of block
|
||||
#define LCR_BLOCK_LEFT 0x02 ///< filled left half of block
|
||||
#define LCR_BLOCK_LEFT_FRONT 0x03 ///< filled left front quarter of block
|
||||
#define LCR_BLOCK_BOTTOM_LEFT 0x04 ///< filled bottom left quarter of block
|
||||
|
||||
typedef struct
|
||||
#define LCR_BLOCK_CHECKPOINT_NOT 0x10 ///< checkpoint, not taken
|
||||
#define LCR_BLOCK_CHECKPOINT_YES 0x11 ///< checkpoint, taken
|
||||
#define LCR_BLOCK_FINISH 0x12 ///< finish
|
||||
|
||||
// special blocks:
|
||||
#define LCR_BLOCK_NONE 0x80 /**< no block, can be used e.g to make
|
||||
holes */
|
||||
#define LCR_BLOCK_CUBOID_FILL 0x81 /**< makes a cuboid from the previously
|
||||
specified block, the size is given
|
||||
by block coordinates */
|
||||
#define LCR_BLOCK_CUBOID_HOLLOW 0x82 /**< same as the cuboid special block, but
|
||||
makes a hollow cuboid */
|
||||
#define LCR_BLOCK_START 0x83 /**< specifies start block position */
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t type; ///< block type
|
||||
uint8_t coordMatTrans[3]; ///< coordinate, material and transform
|
||||
} LCR_MapBlock;
|
||||
uint16_t blockCount;
|
||||
uint8_t blocks[LCR_SETTING_MAP_MAX_SIZE * 4];
|
||||
uint32_t startPos;
|
||||
|
||||
// TODO: name, desc? possibly as a single '\n' separated string?
|
||||
} LCR_currentMap;
|
||||
|
||||
static const uint8_t LCR_map0[] =
|
||||
{
|
||||
LCR_MAP_MAGIC_NUMBER,
|
||||
77, 48, 10 // map name: M0
|
||||
77, 48, 10, // map name: M0
|
||||
10, // map comment:
|
||||
|
||||
LCR_MAP_BLOCK( LCR_BLOCK_CUBE, 1, 2, 3, 0),
|
||||
LCR_MAP_BLOCK( LCR_BLOCK_NONE, 3, 0, 0, LCR_BLOCK_MATERIAL_CONCRETE, 0),
|
||||
LCR_MAP_BLOCK( LCR_BLOCK_FULL, 3, 0, 0, LCR_BLOCK_MATERIAL_CONCRETE, 0),
|
||||
LCR_MAP_BLOCK( LCR_BLOCK_FULL, 0, 1, 0, LCR_BLOCK_MATERIAL_CONCRETE, 0),
|
||||
LCR_MAP_BLOCK( LCR_BLOCK_FULL, 2, 0, 0, LCR_BLOCK_MATERIAL_CONCRETE, 0),
|
||||
LCR_MAP_BLOCK( LCR_BLOCK_FULL, 0, 1, 0, LCR_BLOCK_MATERIAL_CONCRETE, 0),
|
||||
LCR_MAP_BLOCK( LCR_BLOCK_FULL, 3, 0, 0, LCR_BLOCK_MATERIAL_CONCRETE, 0),
|
||||
LCR_MAP_TERMINATOR
|
||||
};
|
||||
|
||||
|
@ -83,4 +118,141 @@ static const uint8_t *LCR_maps[LCR_MAP_COUNT] =
|
|||
LCR_map0
|
||||
};
|
||||
|
||||
void LCR_mapBlockGetCoords(const uint8_t block[4], uint8_t *x, uint8_t *y,
|
||||
uint8_t *z)
|
||||
{
|
||||
*x = block[1] & 0x3f;
|
||||
*y = (block[1] >> 6) | ((block[2] & 0x0f) << 2);
|
||||
*z = (block[2] >> 4) | ((block[3] & 0x03) << 4);
|
||||
}
|
||||
|
||||
uint32_t LCR_mapBlockGetCoordNumber(const uint8_t block[4])
|
||||
{
|
||||
return block[1] | (((uint32_t) block[2]) << 8) |
|
||||
((((uint32_t) block[3]) & 0x3) << 16);
|
||||
}
|
||||
|
||||
/**
|
||||
Adds given block to current map, including possibly deleting a block by
|
||||
adding LCR_BLOCK_NONE. The function handles sorting the block to the right
|
||||
position. Returns 1 on success, else 0.
|
||||
*/
|
||||
uint8_t _LCR_mapAddBlock(const uint8_t block[4])
|
||||
{
|
||||
if (LCR_currentMap.blockCount >= LCR_SETTING_MAP_MAX_SIZE)
|
||||
return 0;
|
||||
|
||||
uint32_t coord = LCR_mapBlockGetCoordNumber(block);
|
||||
uint16_t insertAt = 0;
|
||||
|
||||
while (insertAt < LCR_currentMap.blockCount &&
|
||||
coord > LCR_mapBlockGetCoordNumber(LCR_currentMap.blocks + insertAt * 4))
|
||||
insertAt++;
|
||||
|
||||
if (block[0] == LCR_BLOCK_NONE)
|
||||
{
|
||||
if (insertAt < LCR_currentMap.blockCount &&
|
||||
coord == LCR_mapBlockGetCoordNumber(LCR_currentMap.blocks + insertAt * 4))
|
||||
{
|
||||
// shift all left (remove the block):
|
||||
for (uint16_t i = insertAt * 4; i < LCR_currentMap.blockCount * 4 - 1; ++i)
|
||||
LCR_currentMap.blocks[i] = LCR_currentMap.blocks[i + 1];
|
||||
|
||||
LCR_currentMap.blockCount--;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (insertAt == LCR_currentMap.blockCount ||
|
||||
coord != LCR_mapBlockGetCoordNumber(LCR_currentMap.blocks + insertAt * 4))
|
||||
{
|
||||
// shift from here to the right, make room for the new block
|
||||
|
||||
LCR_currentMap.blockCount++;
|
||||
|
||||
for (int16_t i = ((int16_t) LCR_currentMap.blockCount) - 1; i > insertAt; i--)
|
||||
for (uint8_t j = 0; j < 4; ++j)
|
||||
LCR_currentMap.blocks[i * 4 + j] = LCR_currentMap.blocks[(i - 1) * 4 + j];
|
||||
}
|
||||
|
||||
insertAt *= 4;
|
||||
|
||||
for (uint8_t j = 0; j < 4; ++j)
|
||||
LCR_currentMap.blocks[insertAt + j] = block[j];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Loads and preprocesses given map. Returns 1 on success, otherwise 0.
|
||||
*/
|
||||
uint8_t LCR_mapLoad(const uint8_t *map)
|
||||
{
|
||||
LCR_currentMap.startPos = 0;
|
||||
LCR_currentMap.blockCount = 0;
|
||||
|
||||
if (map[0] != LCR_MAP_MAGIC_NUMBER1 || map[1] != LCR_MAP_MAGIC_NUMBER2)
|
||||
return 1;
|
||||
|
||||
map += 2;
|
||||
|
||||
while (*map != 10) // read map name
|
||||
{
|
||||
// TODO
|
||||
map++;
|
||||
}
|
||||
|
||||
map++;
|
||||
|
||||
while (*map != 10) // read map description
|
||||
{
|
||||
// TODO
|
||||
map++;
|
||||
}
|
||||
|
||||
map++;
|
||||
|
||||
while (*map != LCR_MAP_TERMINATOR)
|
||||
{
|
||||
if (!_LCR_mapAddBlock(map))
|
||||
return 0;
|
||||
|
||||
map += 4;
|
||||
}
|
||||
|
||||
// process and remove special blocks:
|
||||
|
||||
// TODO
|
||||
|
||||
// sort the blocks (for fast searching):
|
||||
|
||||
// TODO
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Gets a pointer to a map block of the currently loaded map at given
|
||||
coordinates. If there is no block at given coordinates, 0 is returned.
|
||||
*/
|
||||
const uint8_t *LCR_mapGetBlockAt(uint8_t x, uint8_t y, uint8_t z)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Gets a shape of given map block type as a 3D model composed of triangles. The
|
||||
model is returned as an array of 16 bit ints, each of which represents
|
||||
X with lowest 5 bits, Y with next 5 bits and Z with next 5 bits (the
|
||||
directions of axes are same as map X, Y, Z directions). Each coordinate can
|
||||
go from 0 to 16; WATCH OUT, THIS IS 17 VALUES, NOT 16, so as to allow having
|
||||
a mid coord (8), mid-mid coords (4, 12) and mid-mid-mid coords.
|
||||
*/
|
||||
void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform,
|
||||
uint16_t triangles[LCR_MAP_BLOCK_SHAPE_MAX_TRIANGLES * 3],
|
||||
uint8_t *triangleCount)
|
||||
{
|
||||
}
|
||||
|
||||
#endif // guard
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#ifndef LCR_SETTING_MAP_MAX_SIZE
|
||||
/** Maximum number of blocks a map can consist of, decreasing will save RAM
|
||||
but also rule out loading bigger maps. */
|
||||
#define LCR_SETTING_MAP_MAX_SIZE 256
|
||||
#define LCR_SETTING_MAP_MAX_SIZE 4096
|
||||
#endif
|
||||
|
||||
#endif // guard
|
||||
|
|
Loading…
Reference in a new issue