This commit is contained in:
Miloslav Ciz 2024-11-27 23:44:00 +01:00
parent 2cbbd8fb1a
commit 1c83fe4660
2 changed files with 28 additions and 250 deletions

View file

@ -16,88 +16,11 @@
#include <stdint.h>
#include "map.h"
static const char *LCR_maps[] =
{
"LM;aaa; bbb; 2; #=s0s0#=s1s0#f4120"
"LM;;;0; #=s0s0 #}r0s0-|L #*r0c0 "
};
/*
static const uint8_t map1[] =
{
LCR_MAP_MAGIC_NUMBER,
0,
10,
10,
0,
LCR_MAP_BLOCK(LCR_BLOCK_START,1,1,1,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,0,0,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,15,1,20,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,0,20,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,15,1,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED,0,1,19,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,8,1,1,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED,8,1,5,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_270),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,1,1,8,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_LEFT,5,1,5,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_90),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,2,1,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_LEFT,9,0,20,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,8,1,8,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,3,1,8,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,3,2,8,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,2,1,8,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,2,2,8,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,3,4,8,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,3,5,8,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,4,5,8,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,4,1,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_180),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,4,2,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_180),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,5,1,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_180),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,5,2,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_180),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,4,4,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V | LCR_BLOCK_TRANSFORM_ROT_180),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,4,5,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V | LCR_BLOCK_TRANSFORM_ROT_180),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,3,5,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V | LCR_BLOCK_TRANSFORM_ROT_180),
LCR_MAP_BLOCK(LCR_BLOCK_CHECKPOINT_0,3,1,4,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CHECKPOINT_0,3,1,8,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_FINISH,2,1,10,LCR_BLOCK_MATERIAL_CONCRETE,0),
*/
/*
LCR_MAP_BLOCK(LCR_BLOCK_FULL,2,1,9,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,2,5,1,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,4,1,5,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,2,5,1,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,3,6,6,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,2,1,3,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_CORNER,1,1,4,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,15,0,0,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,15,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,25,0,0,LCR_BLOCK_MATERIAL_ICE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,15,0,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,35,0,0,LCR_BLOCK_MATERIAL_DIRT,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,15,0,0),
LCR_MAP_TERMINATOR
};
*/
#define LCR_IMAGE_SIZE 64 ///< one-dimension resolution of bitmap image
#define LCR_IMAGE_STORE_SIZE (LCR_IMAGE_SIZE * LCR_IMAGE_SIZE + 256 * 2)

199
map.h
View file

@ -14,71 +14,54 @@
- x goes right, y goes up, z goes forward
- coordinate number is a single number obtained as x + 64 * y + 64 * 64 * z
The STORAGE map format is binary and consists of the following values:
- 76, 77 (for "LM", magic number)
- one byte recording the map environment
- ASCII map name
- 10 (separator)
- ASCII comment
- 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 (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.)
- bits C2 and C3 say the block material
- highest 4 bits of C (C4, C5, C6, C7) say the block's transform:
- first if C4 is set, the block is flipped in the X direction
- then the block is rotated around vertical axis by 0, 90, 180 or 270
degrees if C5C6 is 00, 01, 10 or 11.
- last if C7 is set, the block is flipped vertically
- 255 (terminator)
In this format order of blocks matters, latter blocks will replace previous
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.
The TEXT FORMAT serves for editing maps in human readable format, it more or
less corresponds to the binary storage format and has the following structure:
The TEXT format serves for editing maps in human readable format, it more or
less corresponds to the binary storage format (below) with some exceptions.
It has the following structure:
- Magic number string: "LM;".
- Until next ';': name.
- Until next ';': description.
- Until next ';': tags. Currently this may contain the following:
- digit N: set the map environment to N.
- Then a series of block strings follow. Blocks may be separated by
characters that aren't '#'. Block format is following:
- Then a series of block strings follows. Blocks may be separated by
characters that aren't '#' (comments may be added this way). Block format
is following:
#BXYZMT
where:
- B: is block type
- B is block type (for list of characters see the _LCR_mapCharToBlockType
function).
- X, Y and Z are block coordinates, each one a single character. The
following are characters signifying numbers 0 to 63:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$@
- M is block material ('0' to '3')
- T is an optinal transform string consisting from 0 to 3 characters,
which may be:
- M is block material ('0' to '3').
- T is an optinal transform string (for more detail see the binary format)
consisting from 0 to 3 characters, which may be:
- '|': flip horizontally
- '-': flip vertically
- 'L': rotate 90 degrees
- 'I': rotate 180 degrees
- 'J': rotate 270 degrees
Here the block order matters, latter blocks rewrite previously placed ones.
The internal BINARY map format is made from the text string. It can't contain
special blocks and blocks are ordered by their coordinate number (for fast
lookup). The format consists of blocks, each of format:
- 1 byte type: says the type of block. Special blocks are defined in code,
they have histest bit set to 1, but they only serve internal purposes and
can't end up in the final map.
- 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.)
- bits C2 and C3 say the block material
- highest 4 bits of C (C4, C5, C6, C7) say the block's transform:
- first if C4 is set, the block is flipped in the X direction
- then the block is rotated around vertical axis by 0, 90, 180 or 270
degrees if C5C6 is 00, 01, 10 or 11.
- last if C7 is set, the block is flipped vertically
*/
#define LCR_BLOCK_TRANSFORM_FLIP_H 0x10
#define LCR_BLOCK_TRANSFORM_ROT_90 0x20
#define LCR_BLOCK_TRANSFORM_ROT_180 0x40
@ -342,7 +325,6 @@ void LCR_mapReset(void)
LCR_currentMap.blocks[i * LCR_BLOCK_SIZE] = LCR_BLOCK_CHECKPOINT_0;
}
uint8_t _LCR_mapCharToBlockType(char c)
{
switch (c)
@ -587,133 +569,6 @@ uint8_t LCR_mapLoadFromStr(const char *mapStr)
return 1;
}
/**
Loads and preprocesses given map. Returns 1 on success, otherwise 0.
*/
/*
uint8_t LCR_mapLoad(const uint8_t *map)
{
LCR_LOG0("loading map")
for (int i = 0; i < 4; ++i)
LCR_currentMap.startPos[i] = 0;
LCR_currentMap.checkpointCount = 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++;
LCR_currentMap.environment = *map;
map++;
while (*map != LCR_MAP_TERMINATOR)
{
switch (*map)
{
case LCR_BLOCK_CUBOID_FILL:
case LCR_BLOCK_CUBOID_HOLLOW:
{
const uint8_t *prevBlock = map - LCR_BLOCK_SIZE;
uint8_t x, y, z, w, h, d, mat, transform;
uint8_t tmpBlock[LCR_BLOCK_SIZE];
if (LCR_currentMap.blockCount == 0 || (prevBlock[0] & 0x80))
return 0;
mat = LCR_mapBlockGetMaterial(prevBlock);
transform = LCR_mapBlockGetTransform(prevBlock);
LCR_mapBlockGetCoords(prevBlock,&x,&y,&z);
LCR_mapBlockGetCoords(map,&w,&h,&d);
for (uint8_t k = 0; k < d; ++k)
for (uint8_t j = 0; j < h; ++j)
for (uint8_t i = 0; i < w; ++i)
if (*map == LCR_BLOCK_CUBOID_FILL ||
k == 0 || k == d - 1 ||
j == 0 || j == h - 1 ||
i == 0 || i == w - 1)
{
LCR_makeMapBlock(prevBlock[0],x + i,y + j,z + k,mat,transform,
tmpBlock);
if (!_LCR_mapAddBlock(tmpBlock))
return 0;
}
break;
}
case LCR_BLOCK_START:
LCR_mapBlockGetCoords(map,
LCR_currentMap.startPos,
LCR_currentMap.startPos + 1,
LCR_currentMap.startPos + 2);
LCR_currentMap.startPos[3] = LCR_mapBlockGetTransform(map) & 0x60;
break;
case LCR_BLOCK_CHECKPOINT_0:
LCR_currentMap.checkpointCount++;
// fall through
default:
if (!_LCR_mapAddBlock(map)) // normal block
return 0;
break;
}
map += LCR_BLOCK_SIZE;
}
LCR_LOG2("clearing map block cache")
for (int i = 0; i < LCR_MAP_BLOCK_CACHE_SIZE; ++i)
_LCR_mapBlockCache[i] = 0xffffffff;
LCR_LOG2("map loaded")
LCR_mapReset();
return 1;
}
*/
/**
Same as LCR_mapGetBlockAt, but allows to specify start and end block of the
of the search to make it faster.