Add mirror block

This commit is contained in:
Miloslav Ciz 2025-02-10 23:21:23 +01:00
parent edb7bd94fa
commit 3c903ff49f
3 changed files with 170 additions and 73 deletions

View file

@ -93,10 +93,14 @@ static const char *LCR_internalDataFile =
"#Rrep1;testmap;482f70f9 00000188:00c1:0089:0111:00b9:0091:0109:0028:0050:00c1:0093:0030:00d1:0069:0041:0020:0071:0013:0012:0023:0022:0050:0032:0020:0022:0060:0024:00bc:0044" "#Rrep1;testmap;482f70f9 00000188:00c1:0089:0111:00b9:0091:0109:0028:0050:00c1:0093:0030:00d1:0069:0041:0020:0071:0013:0012:0023:0022:0050:0032:0020:0022:0060:0024:00bc:0044"
// MAP 1: // MAP 1:
"#MLicar1;4321 0 " "#MLicar1;4321 0 "
":*B3mL:!x6G:+L2H:+D38" // start, finish, CPs ":*B3mL:!x6G:+L2H:+D38" // start, finish, CPs
// pillars:
":nw0w2L:f151:m151"
":nz0w2L:f151:m151"
":nw0H2L:f151:m151"
":nz0H2L:f151:m151"
// big structure: // big structure:
":=z09:f83D" ":=z09:f83D"
":=H0k:fa1s" ":=H0k:fa1s"
@ -156,11 +160,6 @@ static const char *LCR_internalDataFile =
// finish ramp: // finish ramp:
":-w5u:f31d" ":-w5u:f31d"
":'w5G:f311" ":'w5G:f311"
// pillars:
":nv0v2|:f151:nw0v2:f151:nv0w2J|:f151:nw0w2L:f151"
":ny0v2|:f151:nz3v2:f121:ny0w2J|:f151:nz3w2L:f121"
":nv0G2|:f151:nw0G2:f151:nv0H2J|:f151:nw0H2L:f151"
":ny0G2|:f151:nz3G2:f121:ny0H2J|:f151:nz3H2L:f121"
/* tiny maps, max: /* tiny maps, max:
- 400 character string - 400 character string
@ -191,6 +190,20 @@ static const char *LCR_internalDataFile =
"#MLCtiny2;4321 2" "#MLCtiny2;4321 2"
":*w1d:!w1d:+w1A" ":*w1d:!w1d:+w1A"
// big bumps:
":vw1hJ:m111"
":vw1qJ:m111"
":vw1yJ:m111"
":vy1r1J:m111"
":vy1u2J:m111"
":vv1t3J:m111"
":vu1k1I:vu1l1|"
":vu1v2I:vu1w2|"
":vy1lL:vy1m"
":vy1v1L:vy1w1"
":vy1yL:vy1z"
// diagonal column:
":Aw1mL:m111"
// big structure: // big structure:
":=t0d2:f71p" ":=t0d2:f71p"
":=t1B1:f711" ":=t1B1:f711"
@ -198,19 +211,6 @@ static const char *LCR_internalDataFile =
":'u0n1I:f511:'u0o1:f511" ":'u0n1I:f511:'u0o1:f511"
// small bumps: // small bumps:
":~y1i1:~w1j3:~x1l:~x1p3:~u1q2:~w1s2:~x1v:~v1w1:~x1x3" ":~y1i1:~w1j3:~x1l:~x1p3:~u1q2:~w1s2:~x1v:~v1w1:~x1x3"
":Av1l|:Aw1l:Av1mI:Aw1mI|" // diagonal column
// big bumps:
":vv1gL:vv1h:vw1gI:vw1h|"
":vv1pL:vv1q:vw1pI:vw1q|"
":vv1xL:vv1y:vw1xI:vw1y|"
":vx1q1L:vx1r1:vy1q1I:vy1r1|"
":vx1t2L:vx1u2:vy1t2I:vy1u2|"
":vu1s3L:vu1t3:vv1s3I:vv1t3|"
":vu1k1I:vu1l1|"
":vu1v2I:vu1w2|"
":vy1lL:vy1m"
":vy1v1L:vy1w1"
":vy1yL:vy1z"
; ;
#define LCR_IMAGE_SIZE 64 ///< one-dimension resolution of bitmap image #define LCR_IMAGE_SIZE 64 ///< one-dimension resolution of bitmap image

2
data
View file

@ -2,3 +2,5 @@
#Bnomap #Bnomap
#Rrep2;testmap;482f70f9 00000843:0173:0081:0029:0111:0039:0071:00a3:0061:0169:0051:00b3:0041:0073:0081:0033:0041:0033:0231:0030:0098:0029:0011:0163:00f1:0053:0081:0033:0051:0023:0031:00f0:0032:0023:0131:00b9:0081:0023:00a1:0119:00e1:00c9:0071:0039:00a1:00d3:0021:01f9:0091:0079:0091:0039:0051:0049:0021:0083:0031:0083:0031:0083:0061:0089:0121:00a0:0058:002c:0048:0061:0013:0150:0052:00c0:00a1:0053:0041:0043:0031:0020:0092:0063:0181:0010:00a2:0013:0071:00e0:0028:00e9:0078:00a9:0043:0032:0123:0042:0080:0038:004c:01a8:0050:0032:0033:0101 #Rrep2;testmap;482f70f9 00000843:0173:0081:0029:0111:0039:0071:00a3:0061:0169:0051:00b3:0041:0073:0081:0033:0041:0033:0231:0030:0098:0029:0011:0163:00f1:0053:0081:0033:0051:0023:0031:00f0:0032:0023:0131:00b9:0081:0023:00a1:0119:00e1:00c9:0071:0039:00a1:00d3:0021:01f9:0091:0079:0091:0039:0051:0049:0021:0083:0031:0083:0031:0083:0061:0089:0121:00a0:0058:002c:0048:0061:0013:0150:0052:00c0:00a1:0053:0041:0043:0031:0020:0092:0063:0181:0010:00a2:0013:0071:00e0:0028:00e9:0078:00a9:0043:0032:0123:0042:0080:0038:004c:01a8:0050:0032:0033:0101
#Btestmap; #Btestmap;
#Maaaaa;4321 0 :*G1b:+n9H:!I1H :uJ3d- :vI3dL- :maaa

203
map.h
View file

@ -127,6 +127,13 @@
size is given by block coords */ size is given by block coords */
#define LCR_BLOCK_CUBOID_HOLLOW 'h' /**< same as cuboid special block, #define LCR_BLOCK_CUBOID_HOLLOW 'h' /**< same as cuboid special block,
but makes a hollow one */ but makes a hollow one */
#define LCR_BLOCK_MIRROR 'm' /**< makes a mirror copy along each
major axis, starting at coords of
last added block and iterating
over a block of size given by this
block's coords */
#define LCR_BLOCK_START '*' ///< specifies start block position #define LCR_BLOCK_START '*' ///< specifies start block position
#define LCR_BLOCK_QUIT 'e' /**< special block, ends reading the #define LCR_BLOCK_QUIT 'e' /**< special block, ends reading the
@ -193,6 +200,32 @@ uint8_t LCR_mapBlockOppositeTransform(uint8_t transform)
return transform; return transform;
} }
uint8_t LCR_mapBlockFlipTransformX(uint8_t transform)
{
transform ^= LCR_BLOCK_TRANSFORM_FLIP_H;
if ((transform & 0x60) == LCR_BLOCK_TRANSFORM_ROT_90)
return ((transform & (~0x60)) | LCR_BLOCK_TRANSFORM_ROT_270);
else if ((transform & 0x60) == LCR_BLOCK_TRANSFORM_ROT_270)
return ((transform & (~0x60)) | LCR_BLOCK_TRANSFORM_ROT_90);
return transform;
}
uint8_t LCR_mapBlockFlipTransformZ(uint8_t transform)
{
transform ^= LCR_BLOCK_TRANSFORM_FLIP_H;
if ((transform & 0x60) == LCR_BLOCK_TRANSFORM_ROT_180)
return transform & (~0x60);
else if ((transform & 0x60) == 0)
return transform | LCR_BLOCK_TRANSFORM_ROT_180;
return transform;
}
uint8_t LCR_mapBlockIsAccelerator(uint8_t block) uint8_t LCR_mapBlockIsAccelerator(uint8_t block)
{ {
return block == LCR_BLOCK_FULL_ACCEL || block == LCR_BLOCK_RAMP_ACCEL || return block == LCR_BLOCK_FULL_ACCEL || block == LCR_BLOCK_RAMP_ACCEL ||
@ -270,7 +303,7 @@ uint8_t *LCR_getMapBlockAtCoordNumber(uint32_t coord)
/** /**
Adds given block to current map, including possibly deleting a block by 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 adding LCR_BLOCK_NONE. The function handles sorting the block to the right
position. Returns pointer to the block on success, else 0. position.
*/ */
void _LCR_mapAddBlock(const uint8_t block[LCR_BLOCK_SIZE]) void _LCR_mapAddBlock(const uint8_t block[LCR_BLOCK_SIZE])
{ {
@ -380,6 +413,59 @@ void _LCR_mapComputeHash(void)
(LCR_currentMap.hash >> 13)) * 113; (LCR_currentMap.hash >> 13)) * 113;
} }
/**
Same as LCR_mapGetBlockAt, but allows to specify start and end block of the
of the search to make it faster.
*/
int LCR_mapGetBlockAtFast(uint8_t x, uint8_t y, uint8_t z,
int start, int end)
{
// binary search (the blocks are sorted)
uint32_t n = LCR_mapBlockCoordsToCoordNumber(x,y,z);
uint8_t cacheIndex = 2 * ((x % 2) | ((y % 2) << 1) | ((z % 2) << 2));
if (_LCR_mapBlockCache[cacheIndex] == n)
return
(_LCR_mapBlockCache[cacheIndex + 1] != 0xffffffff) ?
((int) _LCR_mapBlockCache[cacheIndex + 1]) : -1;
_LCR_mapBlockCache[cacheIndex] = n;
while (start <= end)
{
int m = (start + end) / 2;
uint32_t n2 = LCR_mapBlockGetCoordNumber(
LCR_currentMap.blocks + m * LCR_BLOCK_SIZE);
if (n2 < n)
start = m + 1;
else if (n2 > n)
end = m - 1;
else
{
_LCR_mapBlockCache[cacheIndex + 1] = m;
return m;
}
}
_LCR_mapBlockCache[cacheIndex + 1] = 0xffffffff;
return -1;
}
/**
Gets an index to a map block of the currently loaded map at given
coordinates. If there is no block at given coordinates, -1 is returned.
*/
int LCR_mapGetBlockAt(uint8_t x, uint8_t y, uint8_t z)
{
if (LCR_currentMap.blockCount == 0)
return -1;
return LCR_mapGetBlockAtFast(x,y,z,0,LCR_currentMap.blockCount - 1);
}
uint8_t LCR_mapLoadFromStr(char (*getNextCharFunc)(void), const char *name) uint8_t LCR_mapLoadFromStr(char (*getNextCharFunc)(void), const char *name)
{ {
LCR_LOG0("loading map string"); LCR_LOG0("loading map string");
@ -484,6 +570,68 @@ uint8_t LCR_mapLoadFromStr(char (*getNextCharFunc)(void), const char *name)
switch (block) switch (block)
{ {
case LCR_BLOCK_MIRROR:
{
uint8_t x, y, z, mat, transform, type;
uint8_t tmpBlock[LCR_BLOCK_SIZE];
LCR_mapBlockGetCoords(prevBlock,&x,&y,&z);
for (uint8_t k = 0; k < coords[2]; ++k)
for (uint8_t j = 0; j < coords[1]; ++j)
for (uint8_t i = 0; i < coords[0]; ++i)
{
int blockIndex = LCR_mapGetBlockAt(x + i,y + j,z + k);
if (blockIndex >= 0)
{
mat = LCR_mapBlockGetMaterial(
LCR_currentMap.blocks + blockIndex * LCR_BLOCK_SIZE);
transform = LCR_mapBlockGetTransform(
LCR_currentMap.blocks + blockIndex * LCR_BLOCK_SIZE);
type = LCR_currentMap.blocks[blockIndex * LCR_BLOCK_SIZE];
for (uint8_t l = 1; l < 8; ++l)
{
int8_t x2 = x + i, y2 = y + j, z2 = z + k;
uint8_t t2 = transform;
if (l & 0x01)
{
x2 = x - 1 - i;
t2 = LCR_mapBlockFlipTransformX(t2);
}
if (l & 0x02)
{
y2 = y - 1 - j;
t2 ^= LCR_BLOCK_TRANSFORM_FLIP_V;
}
if (l & 0x04)
{
z2 = z - 1 - k;
t2 = LCR_mapBlockFlipTransformZ(t2);
}
if (
x2 >= 0 && x2 < LCR_MAP_SIZE_BLOCKS &&
y2 >= 0 && y2 < LCR_MAP_SIZE_BLOCKS &&
z2 >= 0 && z2 < LCR_MAP_SIZE_BLOCKS)
{
LCR_makeMapBlock(type,x2,y2,z2,mat,t2,tmpBlock);
_LCR_mapAddBlock(tmpBlock);
}
}
}
}
break;
}
case LCR_BLOCK_CUBOID_FILL: case LCR_BLOCK_CUBOID_FILL:
case LCR_BLOCK_CUBOID_HOLLOW: case LCR_BLOCK_CUBOID_HOLLOW:
{ {
@ -555,59 +703,6 @@ uint8_t LCR_mapLoadFromStr(char (*getNextCharFunc)(void), const char *name)
return 1; return 1;
} }
/**
Same as LCR_mapGetBlockAt, but allows to specify start and end block of the
of the search to make it faster.
*/
int LCR_mapGetBlockAtFast(uint8_t x, uint8_t y, uint8_t z,
int start, int end)
{
// binary search (the blocks are sorted)
uint32_t n = LCR_mapBlockCoordsToCoordNumber(x,y,z);
uint8_t cacheIndex = 2 * ((x % 2) | ((y % 2) << 1) | ((z % 2) << 2));
if (_LCR_mapBlockCache[cacheIndex] == n)
return
(_LCR_mapBlockCache[cacheIndex + 1] != 0xffffffff) ?
((int) _LCR_mapBlockCache[cacheIndex + 1]) : -1;
_LCR_mapBlockCache[cacheIndex] = n;
while (start <= end)
{
int m = (start + end) / 2;
uint32_t n2 = LCR_mapBlockGetCoordNumber(
LCR_currentMap.blocks + m * LCR_BLOCK_SIZE);
if (n2 < n)
start = m + 1;
else if (n2 > n)
end = m - 1;
else
{
_LCR_mapBlockCache[cacheIndex + 1] = m;
return m;
}
}
_LCR_mapBlockCache[cacheIndex + 1] = 0xffffffff;
return -1;
}
/**
Gets an index to a map block of the currently loaded map at given
coordinates. If there is no block at given coordinates, -1 is returned.
*/
int LCR_mapGetBlockAt(uint8_t x, uint8_t y, uint8_t z)
{
if (LCR_currentMap.blockCount == 0)
return -1;
return LCR_mapGetBlockAtFast(x,y,z,0,LCR_currentMap.blockCount - 1);
}
uint8_t _LCR_encodeMapBlockCoords(uint8_t x, uint8_t y, uint8_t z) uint8_t _LCR_encodeMapBlockCoords(uint8_t x, uint8_t y, uint8_t z)
{ {
return (5 * 7) * z + 7 * y + x; return (5 * 7) * z + 7 * y + x;