From 3c903ff49fc5c73f3c0f966b15c630c0b22d7d14 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Mon, 10 Feb 2025 23:21:23 +0100 Subject: [PATCH] Add mirror block --- assets.h | 38 +++++------ data | 2 + map.h | 203 ++++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 170 insertions(+), 73 deletions(-) diff --git a/assets.h b/assets.h index a43422a..2b4f21d 100644 --- a/assets.h +++ b/assets.h @@ -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" - // MAP 1: "#MLicar1;4321 0 " ":*B3mL:!x6G:+L2H:+D38" // start, finish, CPs + // pillars: + ":nw0w2L:f151:m151" + ":nz0w2L:f151:m151" + ":nw0H2L:f151:m151" + ":nz0H2L:f151:m151" // big structure: ":=z09:f83D" ":=H0k:fa1s" @@ -156,11 +160,6 @@ static const char *LCR_internalDataFile = // finish ramp: ":-w5u:f31d" ":'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: - 400 character string @@ -191,6 +190,20 @@ static const char *LCR_internalDataFile = "#MLCtiny2;4321 2" ":*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: ":=t0d2:f71p" ":=t1B1:f711" @@ -198,19 +211,6 @@ static const char *LCR_internalDataFile = ":'u0n1I:f511:'u0o1:f511" // small bumps: ":~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 diff --git a/data b/data index b2e3e6a..ad774b0 100644 --- a/data +++ b/data @@ -2,3 +2,5 @@ #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 #Btestmap; + +#Maaaaa;4321 0 :*G1b:+n9H:!I1H :uJ3d- :vI3dL- :maaa diff --git a/map.h b/map.h index 650a776..9f8c5b4 100644 --- a/map.h +++ b/map.h @@ -127,6 +127,13 @@ size is given by block coords */ #define LCR_BLOCK_CUBOID_HOLLOW 'h' /**< same as cuboid special block, 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_QUIT 'e' /**< special block, ends reading the @@ -193,6 +200,32 @@ uint8_t LCR_mapBlockOppositeTransform(uint8_t 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) { 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 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]) { @@ -380,6 +413,59 @@ void _LCR_mapComputeHash(void) (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) { LCR_LOG0("loading map string"); @@ -484,6 +570,68 @@ uint8_t LCR_mapLoadFromStr(char (*getNextCharFunc)(void), const char *name) 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_HOLLOW: { @@ -555,59 +703,6 @@ uint8_t LCR_mapLoadFromStr(char (*getNextCharFunc)(void), const char *name) 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) { return (5 * 7) * z + 7 * y + x;