Continue blocks shapes

This commit is contained in:
Miloslav Ciz 2024-07-24 20:28:57 +02:00
parent c4d56de0d4
commit 5567863745
4 changed files with 112 additions and 75 deletions

View file

@ -12,8 +12,10 @@ static const uint8_t map1[] =
0, 0,
10, 10,
10, 10,
0,
LCR_MAP_BLOCK(LCR_BLOCK_FULL,32,32,32,LCR_BLOCK_MATERIAL_CONCRETE,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_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 LCR_MAP_TERMINATOR
}; };

View file

@ -15,6 +15,8 @@
#define LCR_FREE_CAMERA_TURN_STEP \ #define LCR_FREE_CAMERA_TURN_STEP \
(LCR_SETTING_FREE_CAMERA_TURN_SPEED / LCR_SETTING_FPS) (LCR_SETTING_FREE_CAMERA_TURN_SPEED / LCR_SETTING_FPS)
#define LCR_MAP_SIZE_BLOCKS 64
/** Maximum number of triangles of a block shape. */ /** Maximum number of triangles of a block shape. */
#define LCR_MAP_BLOCK_SHAPE_MAX_BYTES 80 #define LCR_MAP_BLOCK_SHAPE_MAX_BYTES 80

100
map.h
View file

@ -53,7 +53,7 @@
#define LCR_BLOCK_TRANSFORM_ROT_270 0x60 #define LCR_BLOCK_TRANSFORM_ROT_270 0x60
#define LCR_BLOCK_TRANSFORM_FLIP_V 0x80 #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_NUMBER1 'L'
#define LCR_MAP_MAGIC_NUMBER2 'M' #define LCR_MAP_MAGIC_NUMBER2 'M'
@ -64,6 +64,8 @@
(unsigned char) ((z >> 4) | (m << 2) | \ (unsigned char) ((z >> 4) | (m << 2) | \
(r << 4)) (r << 4))
#define LCR_BLOCK_SIZE 4 ///< size of map block, in bytes
#define LCR_BLOCK_MATERIAL_CONCRETE 0x00 #define LCR_BLOCK_MATERIAL_CONCRETE 0x00
#define LCR_BLOCK_MATERIAL_DIRT 0x01 #define LCR_BLOCK_MATERIAL_DIRT 0x01
@ -71,10 +73,15 @@
// normal blocks: // normal blocks:
#define LCR_BLOCK_FULL 0x00 ///< completely filled block #define LCR_BLOCK_FULL 0x00 ///< completely filled block
#define LCR_BLOCK_BOTTOM 0x01 ///< filled bottom half of block #define LCR_BLOCK_BOTTOM 0x01 ///< filled bottom half
#define LCR_BLOCK_LEFT 0x02 ///< filled left half of block #define LCR_BLOCK_LEFT 0x02 ///< filled left half
#define LCR_BLOCK_LEFT_FRONT 0x03 ///< filled left front quarter of block #define LCR_BLOCK_BOTTOM_LEFT 0x03 ///< filled bottom left quarter
#define LCR_BLOCK_BOTTOM_LEFT 0x04 ///< filled bottom left quarter of block #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_0 0x10 ///< checkpoint, not taken
#define LCR_BLOCK_CHECKPOINT_1 0x11 ///< checkpoint, taken #define LCR_BLOCK_CHECKPOINT_1 0x11 ///< checkpoint, taken
@ -93,7 +100,7 @@
struct struct
{ {
uint16_t blockCount; 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; uint32_t startPos;
uint8_t environment; uint8_t environment;
@ -121,15 +128,15 @@ static const uint8_t *LCR_maps[LCR_MAP_COUNT] =
LCR_map0 LCR_map0
}; };
void LCR_mapBlockGetCoords(const uint8_t block[4], uint8_t *x, uint8_t *y, void LCR_mapBlockGetCoords(const uint8_t block[LCR_BLOCK_SIZE],
uint8_t *z) uint8_t *x, uint8_t *y, uint8_t *z)
{ {
*x = block[1] & 0x3f; *x = block[1] & 0x3f;
*y = (block[1] >> 6) | ((block[2] & 0x0f) << 2); *y = (block[1] >> 6) | ((block[2] & 0x0f) << 2);
*z = (block[2] >> 4) | ((block[3] & 0x03) << 4); *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) | return block[1] | (((uint32_t) block[2]) << 8) |
((((uint32_t) block[3]) & 0x3) << 16); ((((uint32_t) block[3]) & 0x3) << 16);
@ -145,7 +152,7 @@ uint8_t *LCR_getMapBlockAtCoordNumber(uint32_t coord)
{ {
uint16_t mid = (a + b) / 2; 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 = uint32_t coord2 =
LCR_mapBlockGetCoordNumber(block); 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 adding LCR_BLOCK_NONE. The function handles sorting the block to the right
position. Returns 1 on success, else 0. 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) if (LCR_currentMap.blockCount >= LCR_SETTING_MAP_MAX_SIZE)
return 0; return 0;
@ -175,16 +182,19 @@ uint8_t _LCR_mapAddBlock(const uint8_t block[4])
uint16_t insertAt = 0; uint16_t insertAt = 0;
while (insertAt < LCR_currentMap.blockCount && while (insertAt < LCR_currentMap.blockCount &&
coord > LCR_mapBlockGetCoordNumber(LCR_currentMap.blocks + insertAt * 4)) coord > LCR_mapBlockGetCoordNumber(LCR_currentMap.blocks +
insertAt * LCR_BLOCK_SIZE))
insertAt++; insertAt++;
if (block[0] == LCR_BLOCK_NONE) if (block[0] == LCR_BLOCK_NONE)
{ {
if (insertAt < LCR_currentMap.blockCount && 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): // 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.blocks[i] = LCR_currentMap.blocks[i + 1];
LCR_currentMap.blockCount--; LCR_currentMap.blockCount--;
@ -194,20 +204,23 @@ uint8_t _LCR_mapAddBlock(const uint8_t block[4])
} }
if (insertAt == LCR_currentMap.blockCount || 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 // shift from here to the right, make room for the new block
LCR_currentMap.blockCount++; LCR_currentMap.blockCount++;
for (int16_t i = ((int16_t) LCR_currentMap.blockCount) - 1; i > insertAt; i--) for (int16_t i = ((int16_t) LCR_currentMap.blockCount) - 1;
for (uint8_t j = 0; j < 4; ++j) i > insertAt; i--)
LCR_currentMap.blocks[i * 4 + j] = LCR_currentMap.blocks[(i - 1) * 4 + j]; 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]; LCR_currentMap.blocks[insertAt + j] = block[j];
return 1; return 1;
@ -338,43 +351,68 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform,
switch (blockType) switch (blockType)
{ {
case LCR_BLOCK_FULL: 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,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,0,0) ADD(5,1,3)
ADD(0,1,3) ADD(5,1,3) ADD(0,2,4) // ramp 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,1,3) ADD(5,2,4)
ADD(0,2,4) ADD(5,2,4) ADD(0,4,5) // ramp 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,2,4) ADD(5,4,5)
ADD(0,4,5) ADD(5,4,5) ADD(0,4,6) // top 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(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(6,4,0) ADD(6,4,6) // top
ADD(5,4,5) ADD(5,4,0) ADD(6,4,0) 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,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,2,4) ADD(5,1,3)
ADD(5,4,0) ADD(5,1,3) ADD(5,0,0) 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(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(5,0,0) ADD(6,0,0)
ADD(6,4,0) ADD(6,0,0) ADD(6,4,6) // right 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(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,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,2,4) ADD(0,4,5)
ADD(0,0,6) ADD(0,1,3) ADD(0,2,4) 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,0,0) ADD(0,1,3)
ADD(0,0,6) ADD(0,4,6) ADD(6,0,6) // back 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(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(6,0,6) ADD(6,0,0) // bottom
ADD(0,0,0) ADD(0,0,6) ADD(6,0,6) ADD(0,0,0) ADD(0,0,6) ADD(6,0,6)
break; break;
default: break;
} }
if (transform) if (transform)

View file

@ -13,16 +13,12 @@
#include "small3dlib.h" #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 #define LCR_RENDERER_UNIT S3L_FRACTIONS_PER_UNIT
struct LCR_Renderer struct LCR_Renderer
{ {
// TODO // TODO
}; };
S3L_Scene LCR_scene3D; S3L_Scene LCR_scene3D;
@ -34,7 +30,7 @@ S3L_Index LCR_mapTriangles[LCR_SETTING_MAX_MAP_TRIANGLES * 3];
void LCR_pixelFunc3D(S3L_PixelInfo *pixel) 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) 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 it doesn't exist, add it
if (LCR_mapModel->vertexCount < LCR_SETTING_MAX_MAP_VERTICES) if (LCR_mapModel->vertexCount < LCR_SETTING_MAX_MAP_VERTICES)
{ {
*vertices = x; *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) 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 = a;
t++; 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 _LCR_rendererBuildMapModel(void)
{ {
uint8_t blockShapeBytes[LCR_MAP_BLOCK_SHAPE_MAX_BYTES]; uint8_t blockShapeBytes[LCR_MAP_BLOCK_SHAPE_MAX_BYTES];
@ -93,23 +90,28 @@ uint8_t _LCR_rendererBuildMapModel(void)
S3L_model3DInit(LCR_mapVertices,0,LCR_mapTriangles,0,LCR_mapModel); S3L_model3DInit(LCR_mapVertices,0,LCR_mapTriangles,0,LCR_mapModel);
LCR_mapGetBlockShape(0, for (int j = 0; j < LCR_currentMap.blockCount; ++j)
{
uint8_t bx, by, bz;
LCR_mapBlockGetCoords(LCR_currentMap.blocks + j * LCR_BLOCK_SIZE,&bx,&by,&bz);
LCR_BLOCK_TRANSFORM_ROT_270 LCR_mapGetBlockShape(LCR_currentMap.blocks[j * LCR_BLOCK_SIZE],0,
,blockShapeBytes,&blockShapeByteCount); blockShapeBytes,&blockShapeByteCount);
uint8_t vx, vy, vz, vi = 0; uint8_t vx, vy, vz, vi = 0;
uint8_t *bytes = blockShapeBytes; uint8_t *bytes = blockShapeBytes;
S3L_Index triangleIndices[3]; S3L_Index triangleIndices[3];
for (int i = 0; i < blockShapeByteCount; ++i) 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); LCR_decodeMapBlockCoords(blockShapeBytes[i],&vx,&vy,&vz);
triangleIndices[vi] = _LCR_addMapVertex( triangleIndices[vi] = _LCR_addMapVertex(
(LCR_RENDERER_UNIT * ((S3L_Unit) vx)) / 12, originOffset + (((S3L_Unit) bx) * LCR_RENDERER_UNIT) + (LCR_RENDERER_UNIT * ((S3L_Unit) vx)) / 12,
(LCR_RENDERER_UNIT / 2 * ((S3L_Unit) vy)) / 12, (originOffset + (((S3L_Unit) by) * LCR_RENDERER_UNIT)) / 2 + (LCR_RENDERER_UNIT / 2 * ((S3L_Unit) vy)) / 12,
(LCR_RENDERER_UNIT * ((S3L_Unit) vz)) / 12); originOffset + (((S3L_Unit) bz) * LCR_RENDERER_UNIT) + (LCR_RENDERER_UNIT * ((S3L_Unit) vz)) / 12);
if (vi < 2) if (vi < 2)
vi++; vi++;
@ -119,15 +121,8 @@ for (int i = 0; i < blockShapeByteCount; ++i)
triangleIndices[0],triangleIndices[1],triangleIndices[2]); triangleIndices[0],triangleIndices[1],triangleIndices[2]);
vi = 0; 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; return 1;
} }