From 5567863745eacd9b3162d95d7a020bcceac15cd7 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Wed, 24 Jul 2024 20:28:57 +0200 Subject: [PATCH] Continue blocks shapes --- assets.h | 2 ++ constants.h | 2 ++ map.h | 102 +++++++++++++++++++++++++++++++++++----------------- renderer.h | 81 ++++++++++++++++++++--------------------- 4 files changed, 112 insertions(+), 75 deletions(-) diff --git a/assets.h b/assets.h index 6771d80..3368afe 100644 --- a/assets.h +++ b/assets.h @@ -12,8 +12,10 @@ static const uint8_t map1[] = 0, 10, 10, + 0, LCR_MAP_BLOCK(LCR_BLOCK_FULL,32,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0), LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0), + LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,34,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0), LCR_MAP_TERMINATOR }; diff --git a/constants.h b/constants.h index 900b5a0..840236c 100644 --- a/constants.h +++ b/constants.h @@ -15,6 +15,8 @@ #define LCR_FREE_CAMERA_TURN_STEP \ (LCR_SETTING_FREE_CAMERA_TURN_SPEED / LCR_SETTING_FPS) +#define LCR_MAP_SIZE_BLOCKS 64 + /** Maximum number of triangles of a block shape. */ #define LCR_MAP_BLOCK_SHAPE_MAX_BYTES 80 diff --git a/map.h b/map.h index 1eaea34..59309f4 100644 --- a/map.h +++ b/map.h @@ -53,7 +53,7 @@ #define LCR_BLOCK_TRANSFORM_ROT_270 0x60 #define LCR_BLOCK_TRANSFORM_FLIP_V 0x80 -#define LCR_BLOCK_XYZ_TO_COORD(x,y,z) +#define LCR_BLOCK_XYZ_TO_COORD(x,y,z) // ??? #define LCR_MAP_MAGIC_NUMBER1 'L' #define LCR_MAP_MAGIC_NUMBER2 'M' @@ -64,17 +64,24 @@ (unsigned char) ((z >> 4) | (m << 2) | \ (r << 4)) +#define LCR_BLOCK_SIZE 4 ///< size of map block, in bytes + #define LCR_BLOCK_MATERIAL_CONCRETE 0x00 #define LCR_BLOCK_MATERIAL_DIRT 0x01 #define LCR_MAP_COUNT 1 // 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 +#define LCR_BLOCK_FULL 0x00 ///< completely filled block +#define LCR_BLOCK_BOTTOM 0x01 ///< filled bottom half +#define LCR_BLOCK_LEFT 0x02 ///< filled left half +#define LCR_BLOCK_BOTTOM_LEFT 0x03 ///< filled bottom left quarter +#define LCR_BLOCK_BOTTOM_LEFT_FRONT 0x04 ///< filled bottom left front eigth +#define LCR_BLOCK_RAMP 0x05 +#define LCR_BLOCK_RAMP_HALF 0x06 +#define LCR_BLOCK_RAMP_CURVED 0x07 +#define LCR_BLOCK_RAMP_CURVED_SHORT 0x08 +#define LCR_BLOCK_RAMP_CURVED_WALL 0x09 #define LCR_BLOCK_CHECKPOINT_0 0x10 ///< checkpoint, not taken #define LCR_BLOCK_CHECKPOINT_1 0x11 ///< checkpoint, taken @@ -93,7 +100,7 @@ struct { uint16_t blockCount; - uint8_t blocks[LCR_SETTING_MAP_MAX_SIZE * 4]; + uint8_t blocks[LCR_SETTING_MAP_MAX_SIZE * LCR_BLOCK_SIZE]; uint32_t startPos; uint8_t environment; @@ -121,15 +128,15 @@ 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) +void LCR_mapBlockGetCoords(const uint8_t block[LCR_BLOCK_SIZE], + 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]) +uint32_t LCR_mapBlockGetCoordNumber(const uint8_t block[LCR_BLOCK_SIZE]) { return block[1] | (((uint32_t) block[2]) << 8) | ((((uint32_t) block[3]) & 0x3) << 16); @@ -145,7 +152,7 @@ uint8_t *LCR_getMapBlockAtCoordNumber(uint32_t coord) { uint16_t mid = (a + b) / 2; - uint8_t *block = LCR_currentMap.blocks + mid * 4; + uint8_t *block = LCR_currentMap.blocks + mid * LCR_BLOCK_SIZE; uint32_t coord2 = LCR_mapBlockGetCoordNumber(block); @@ -166,7 +173,7 @@ uint8_t *LCR_getMapBlockAtCoordNumber(uint32_t coord) 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]) +uint8_t _LCR_mapAddBlock(const uint8_t block[LCR_BLOCK_SIZE]) { if (LCR_currentMap.blockCount >= LCR_SETTING_MAP_MAX_SIZE) return 0; @@ -175,16 +182,19 @@ uint8_t _LCR_mapAddBlock(const uint8_t block[4]) uint16_t insertAt = 0; while (insertAt < LCR_currentMap.blockCount && - coord > LCR_mapBlockGetCoordNumber(LCR_currentMap.blocks + insertAt * 4)) + coord > LCR_mapBlockGetCoordNumber(LCR_currentMap.blocks + + insertAt * LCR_BLOCK_SIZE)) insertAt++; if (block[0] == LCR_BLOCK_NONE) { if (insertAt < LCR_currentMap.blockCount && - coord == LCR_mapBlockGetCoordNumber(LCR_currentMap.blocks + insertAt * 4)) + coord == LCR_mapBlockGetCoordNumber(LCR_currentMap.blocks + + insertAt * LCR_BLOCK_SIZE)) { // shift all left (remove the block): - for (uint16_t i = insertAt * 4; i < LCR_currentMap.blockCount * 4 - 1; ++i) + for (uint16_t i = insertAt * LCR_BLOCK_SIZE; + i < LCR_currentMap.blockCount * LCR_BLOCK_SIZE - 1; ++i) LCR_currentMap.blocks[i] = LCR_currentMap.blocks[i + 1]; LCR_currentMap.blockCount--; @@ -194,20 +204,23 @@ uint8_t _LCR_mapAddBlock(const uint8_t block[4]) } if (insertAt == LCR_currentMap.blockCount || - coord != LCR_mapBlockGetCoordNumber(LCR_currentMap.blocks + insertAt * 4)) + coord != LCR_mapBlockGetCoordNumber(LCR_currentMap.blocks + + insertAt * LCR_BLOCK_SIZE)) { // 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]; + for (int16_t i = ((int16_t) LCR_currentMap.blockCount) - 1; + i > insertAt; i--) + for (uint8_t j = 0; j < LCR_BLOCK_SIZE; ++j) + LCR_currentMap.blocks[i * LCR_BLOCK_SIZE + j] = + LCR_currentMap.blocks[(i - 1) * LCR_BLOCK_SIZE + j]; } - insertAt *= 4; + insertAt *= LCR_BLOCK_SIZE; - for (uint8_t j = 0; j < 4; ++j) + for (uint8_t j = 0; j < LCR_BLOCK_SIZE; ++j) LCR_currentMap.blocks[insertAt + j] = block[j]; return 1; @@ -338,43 +351,68 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform, switch (blockType) { case LCR_BLOCK_FULL: - default: + case LCR_BLOCK_BOTTOM: + case LCR_BLOCK_LEFT: + case LCR_BLOCK_BOTTOM_LEFT: + case LCR_BLOCK_BOTTOM_LEFT_FRONT: + { + uint8_t xRight = 6, yTop = 4, + zBack = 6 >> (blockType == LCR_BLOCK_BOTTOM_LEFT_FRONT); + + if (blockType == LCR_BLOCK_BOTTOM || blockType == LCR_BLOCK_BOTTOM_LEFT || + blockType == LCR_BLOCK_BOTTOM_LEFT_FRONT) + yTop /= 2; + + if (blockType == LCR_BLOCK_LEFT || + blockType == LCR_BLOCK_BOTTOM_LEFT || + blockType == LCR_BLOCK_BOTTOM_LEFT_FRONT) + xRight /= 2; + + ADD(0,0,0) ADD(xRight,0,0) ADD(xRight,yTop,0) // front + ADD(0,0,0) ADD(xRight,yTop,0) ADD(0,yTop,0) + ADD(xRight,0,0) ADD(xRight,0,zBack) ADD(xRight,yTop,zBack) // right + ADD(xRight,0,0) ADD(xRight,yTop,zBack) ADD(xRight,yTop,0) + ADD(0,0,0) ADD(0,yTop,0) ADD(0,yTop,zBack) // left + ADD(0,0,0) ADD(0,yTop,zBack) ADD(0,0,zBack) + ADD(0,0,zBack) ADD(0,yTop,zBack) ADD(xRight,yTop,zBack) // back + ADD(0,0,zBack) ADD(xRight,yTop,zBack) ADD(xRight,0,zBack) + ADD(0,yTop,0) ADD(xRight,yTop,0) ADD(xRight,yTop,zBack) // top + ADD(0,yTop,0) ADD(xRight,yTop,zBack) ADD(0,yTop,zBack) + ADD(0,0,0) ADD(xRight,0,zBack) ADD(xRight,0,0) // bottom + ADD(0,0,0) ADD(0,0,zBack) ADD(xRight,0,zBack) + + break; + } + + case LCR_BLOCK_RAMP_CURVED_WALL: ADD(0,0,0) ADD(5,0,0) ADD(0,1,3) // ramp ADD(0,1,3) ADD(5,0,0) ADD(5,1,3) - ADD(0,1,3) ADD(5,1,3) ADD(0,2,4) // ramp ADD(0,2,4) ADD(5,1,3) ADD(5,2,4) - ADD(0,2,4) ADD(5,2,4) ADD(0,4,5) // ramp ADD(0,4,5) ADD(5,2,4) ADD(5,4,5) - ADD(0,4,5) ADD(5,4,5) ADD(0,4,6) // top ADD(0,4,6) ADD(5,4,5) ADD(6,4,6) - ADD(5,4,5) ADD(6,4,0) ADD(6,4,6) // top ADD(5,4,5) ADD(5,4,0) ADD(6,4,0) - ADD(5,4,0) ADD(5,4,5) ADD(5,2,4) // inner side ADD(5,4,0) ADD(5,2,4) ADD(5,1,3) ADD(5,4,0) ADD(5,1,3) ADD(5,0,0) - ADD(5,4,0) ADD(5,0,0) ADD(6,4,0) // front ADD(6,4,0) ADD(5,0,0) ADD(6,0,0) - ADD(6,4,0) ADD(6,0,0) ADD(6,4,6) // right ADD(6,4,6) ADD(6,0,0) ADD(6,0,6) - ADD(0,0,6) ADD(0,4,5) ADD(0,4,6) // left ADD(0,0,6) ADD(0,2,4) ADD(0,4,5) ADD(0,0,6) ADD(0,1,3) ADD(0,2,4) ADD(0,0,6) ADD(0,0,0) ADD(0,1,3) - ADD(0,0,6) ADD(0,4,6) ADD(6,0,6) // back ADD(6,0,6) ADD(0,4,6) ADD(6,4,6) - ADD(0,0,0) ADD(6,0,6) ADD(6,0,0) // bottom ADD(0,0,0) ADD(0,0,6) ADD(6,0,6) break; + + default: break; } if (transform) diff --git a/renderer.h b/renderer.h index 15b8218..d31fbac 100644 --- a/renderer.h +++ b/renderer.h @@ -13,16 +13,12 @@ #include "small3dlib.h" -/** - Renderer specific unit, length of one map square. -*/ +/// Renderer specific unit, length of one map square. #define LCR_RENDERER_UNIT S3L_FRACTIONS_PER_UNIT struct LCR_Renderer { // TODO - - }; S3L_Scene LCR_scene3D; @@ -34,7 +30,7 @@ S3L_Index LCR_mapTriangles[LCR_SETTING_MAX_MAP_TRIANGLES * 3]; void LCR_pixelFunc3D(S3L_PixelInfo *pixel) { - LCR_drawPixelXYSafe(pixel->x,pixel->y, 0xff00 + (pixel->triangleID % 16) * 16 ); + LCR_drawPixelXYSafe(pixel->x,pixel->y,0xff00 + (pixel->triangleID % 16) * 16 ); } S3L_Index _LCR_addMapVertex(S3L_Unit x, S3L_Unit y, S3L_Unit z) @@ -52,7 +48,6 @@ S3L_Index _LCR_addMapVertex(S3L_Unit x, S3L_Unit y, S3L_Unit z) } // if it doesn't exist, add it - if (LCR_mapModel->vertexCount < LCR_SETTING_MAX_MAP_VERTICES) { *vertices = x; @@ -72,7 +67,7 @@ void _LCR_addMapTriangle(S3L_Index a, S3L_Index b, S3L_Index c) { if (LCR_mapModel->triangleCount < LCR_SETTING_MAX_MAP_TRIANGLES) { - S3L_Index *t = &(LCR_mapModel->triangles[LCR_mapModel->triangleCount * 3]); + S3L_Index *t = &(LCR_mapTriangles[LCR_mapModel->triangleCount * 3]); *t = a; t++; @@ -84,8 +79,10 @@ void _LCR_addMapTriangle(S3L_Index a, S3L_Index b, S3L_Index c) } } -/** Builds an internal 3D model of the currently loaded map. Returns 1 on - success, otherwise 0 (e.g. not enough space). */ +/** + Builds an internal 3D model of the currently loaded map. Returns 1 on success, + otherwise 0 (e.g. not enough space). +*/ uint8_t _LCR_rendererBuildMapModel(void) { uint8_t blockShapeBytes[LCR_MAP_BLOCK_SHAPE_MAX_BYTES]; @@ -93,41 +90,39 @@ uint8_t _LCR_rendererBuildMapModel(void) S3L_model3DInit(LCR_mapVertices,0,LCR_mapTriangles,0,LCR_mapModel); - LCR_mapGetBlockShape(0, - -LCR_BLOCK_TRANSFORM_ROT_270 -,blockShapeBytes,&blockShapeByteCount); - -uint8_t vx, vy, vz, vi = 0; -uint8_t *bytes = blockShapeBytes; -S3L_Index triangleIndices[3]; - -for (int i = 0; i < blockShapeByteCount; ++i) -{ - LCR_decodeMapBlockCoords(blockShapeBytes[i],&vx,&vy,&vz); - - triangleIndices[vi] = _LCR_addMapVertex( - (LCR_RENDERER_UNIT * ((S3L_Unit) vx)) / 12, - (LCR_RENDERER_UNIT / 2 * ((S3L_Unit) vy)) / 12, - (LCR_RENDERER_UNIT * ((S3L_Unit) vz)) / 12); - - if (vi < 2) - vi++; - else + for (int j = 0; j < LCR_currentMap.blockCount; ++j) { - _LCR_addMapTriangle( - triangleIndices[0],triangleIndices[1],triangleIndices[2]); - vi = 0; + uint8_t bx, by, bz; + LCR_mapBlockGetCoords(LCR_currentMap.blocks + j * LCR_BLOCK_SIZE,&bx,&by,&bz); + + LCR_mapGetBlockShape(LCR_currentMap.blocks[j * LCR_BLOCK_SIZE],0, + blockShapeBytes,&blockShapeByteCount); + + uint8_t vx, vy, vz, vi = 0; + uint8_t *bytes = blockShapeBytes; + S3L_Index triangleIndices[3]; + + S3L_Unit originOffset = -1 * LCR_MAP_SIZE_BLOCKS / 2 * LCR_RENDERER_UNIT; + + for (int i = 0; i < blockShapeByteCount; ++i) + { + LCR_decodeMapBlockCoords(blockShapeBytes[i],&vx,&vy,&vz); + + triangleIndices[vi] = _LCR_addMapVertex( + originOffset + (((S3L_Unit) bx) * LCR_RENDERER_UNIT) + (LCR_RENDERER_UNIT * ((S3L_Unit) vx)) / 12, + (originOffset + (((S3L_Unit) by) * LCR_RENDERER_UNIT)) / 2 + (LCR_RENDERER_UNIT / 2 * ((S3L_Unit) vy)) / 12, + originOffset + (((S3L_Unit) bz) * LCR_RENDERER_UNIT) + (LCR_RENDERER_UNIT * ((S3L_Unit) vz)) / 12); + + if (vi < 2) + vi++; + else + { + _LCR_addMapTriangle( + triangleIndices[0],triangleIndices[1],triangleIndices[2]); + vi = 0; + } + } } -} - -/* -a = _LCR_addMapVertex(-2000,-100,1000); -b = _LCR_addMapVertex(400,-100,2000); -c = _LCR_addMapVertex(0,400,2000); - -_LCR_addMapTriangle(a,b,c); -*/ return 1; }