diff --git a/assets.h b/assets.h index 336068c..8cf565e 100644 --- a/assets.h +++ b/assets.h @@ -27,17 +27,26 @@ static const uint8_t map1[] = 0, LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,32,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,33,32,32,LCR_BLOCK_MATERIAL_GRASS,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,34,32,32,LCR_BLOCK_MATERIAL_GRASS,LCR_BLOCK_TRANSFORM_ROT_90), - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,35,32,32,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_90), - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,36,32,32,LCR_BLOCK_MATERIAL_ICE,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,37,32,32,LCR_BLOCK_MATERIAL_CONCRETE,0), - LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,38,32,32,LCR_BLOCK_MATERIAL_ICE,0), + LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,3,4,5,0,0), + + LCR_MAP_BLOCK(LCR_BLOCK_FULL_ACCEL,40,34,33,LCR_BLOCK_MATERIAL_CONCRETE,0), + LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,6,7,2,0,0), + +/* + LCR_MAP_BLOCK(LCR_BLOCK_FULL,50,20,20,LCR_BLOCK_MATERIAL_GRASS,0), + LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,5,5,5,0,0), + + LCR_MAP_BLOCK(LCR_BLOCK_FULL,10,10,10,LCR_BLOCK_MATERIAL_GRASS,0), + LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,7,3,8,0,0), + + LCR_MAP_BLOCK(LCR_BLOCK_FULL,0,15,30,LCR_BLOCK_MATERIAL_GRASS,0), + LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,7,4,8,0,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_GRASS,0), - LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,34,32,32,LCR_BLOCK_MATERIAL_GRASS,LCR_BLOCK_TRANSFORM_ROT_90), + LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,34,32,32,LCR_BLOCK_MATERIAL_GRASS,0), LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_WALL,35,32,32,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_ROT_90), LCR_MAP_BLOCK(LCR_BLOCK_FULL,63,35,32,LCR_BLOCK_MATERIAL_CONCRETE,0), @@ -57,7 +66,6 @@ static const uint8_t map1[] = LCR_MAP_BLOCK(LCR_BLOCK_FULL,32,32,33,LCR_BLOCK_MATERIAL_CONCRETE,0), LCR_MAP_BLOCK(LCR_BLOCK_FULL,33,32,33,LCR_BLOCK_MATERIAL_CONCRETE,0), */ - LCR_MAP_TERMINATOR }; diff --git a/frontend_sdl.c b/frontend_sdl.c index 947ba2e..cdbaa3d 100644 --- a/frontend_sdl.c +++ b/frontend_sdl.c @@ -50,6 +50,11 @@ void LCR_drawPixel(unsigned long index, uint16_t color) screen[index] = color; } +void LCR_log(const char *str) +{ + printf("LOG: %s\n",str); +} + int main(int argc, char *argv[]) { uint8_t running = 1; diff --git a/game.h b/game.h index 44c5334..01d344e 100644 --- a/game.h +++ b/game.h @@ -46,6 +46,13 @@ void LCR_sleep(uint16_t timeMs); */ void LCR_drawPixel(unsigned long index, uint16_t color); +/** + Implement this in your frontend. This function will be called to log what the + program is doing. If you want to ignore logging, simply make the function do + nothing. +*/ +void LCR_log(const char *str); + /** Call this function in your frontend at the start of the program. */ @@ -106,6 +113,8 @@ static inline void LCR_drawPixelXYSafe(unsigned int x, unsigned int y, void LCR_gameInit(void) { + LCR_log("initializing"); + for (int i = 0; i < LCR_KEYS_TOTAL; ++i) LCR_keyStates[i] = 0; diff --git a/map.h b/map.h index 68681d6..a6cb5f7 100644 --- a/map.h +++ b/map.h @@ -82,12 +82,12 @@ #define LCR_BLOCK_RAMP_CURVED_SHORT 0x08 #define LCR_BLOCK_RAMP_CURVED_WALL 0x09 -#define LCR_BLOCK_FULL_ACCEL 0x40 -#define LCR_BLOCK_FULL_STICKER 0x60 +#define LCR_BLOCK_FULL_ACCEL 0x20 +#define LCR_BLOCK_FULL_STICKER 0x30 -#define LCR_BLOCK_CHECKPOINT_0 0x10 ///< checkpoint, not taken -#define LCR_BLOCK_CHECKPOINT_1 0x11 ///< checkpoint, taken -#define LCR_BLOCK_FINISH 0x12 ///< finish +#define LCR_BLOCK_CHECKPOINT_0 0x40 ///< checkpoint, not taken +#define LCR_BLOCK_CHECKPOINT_1 0x41 ///< checkpoint, taken +#define LCR_BLOCK_FINISH 0x42 ///< finish // special blocks: #define LCR_BLOCK_NONE 0x80 /**< no block, can be used e.g to make @@ -130,6 +130,15 @@ static const uint8_t *LCR_maps[LCR_MAP_COUNT] = LCR_map0 }; +void LCR_makeMapBlock(uint8_t type, uint8_t x, uint8_t y, uint8_t z, + uint8_t material, uint8_t transform, uint8_t block[LCR_BLOCK_SIZE]) +{ + block[0] = type; + block[1] = x | (y << 6); + block[2] = (y >> 2) | (z << 4); + block[3] = (z >> 4) | (material << 2) | transform; +} + void LCR_mapBlockGetCoords(const uint8_t block[LCR_BLOCK_SIZE], uint8_t *x, uint8_t *y, uint8_t *z) { @@ -273,8 +282,42 @@ uint8_t LCR_mapLoad(const uint8_t *map) while (*map != LCR_MAP_TERMINATOR) { - if (!_LCR_mapAddBlock(map)) - return 0; + switch (*map) + { + case LCR_BLOCK_CUBOID_FILL: + { + 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) + { + LCR_makeMapBlock(prevBlock[0],x + i,y + j,z + k,mat,transform, + tmpBlock); + + if (!_LCR_mapAddBlock(tmpBlock)) + return 0; + } + + break; + } + + default: + if (!_LCR_mapAddBlock(map)) // normal block + return 0; + + break; + } map += 4; } diff --git a/renderer.h b/renderer.h index 4817ca1..cae24a6 100644 --- a/renderer.h +++ b/renderer.h @@ -151,7 +151,8 @@ S3L_Index _LCR_addMapVertex(S3L_Unit x, S3L_Unit y, S3L_Unit z) return LCR_renderer.mapModel->vertexCount - 1; } - // TODO: error print + LCR_log("couldn't add map vertex!"); + return 0; } @@ -247,13 +248,18 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1, uint8_t result = 0; int plane = -1; + S3L_Unit *vertices[6]; for (int i = 0; i < 3; ++i) - if (LCR_renderer.mapVertices[3 * t1[0] + i] == LCR_renderer.mapVertices[3 * t1[1] + i] && - LCR_renderer.mapVertices[3 * t1[1] + i] == LCR_renderer.mapVertices[3 * t1[2] + i] && - LCR_renderer.mapVertices[3 * t1[2] + i] == LCR_renderer.mapVertices[3 * t2[0] + i] && - LCR_renderer.mapVertices[3 * t2[0] + i] == LCR_renderer.mapVertices[3 * t2[1] + i] && - LCR_renderer.mapVertices[3 * t2[1] + i] == LCR_renderer.mapVertices[3 * t2[2] + i]) + { + vertices[i] = LCR_renderer.mapVertices + 3 * t1[i]; + vertices[3 + i] = LCR_renderer.mapVertices + 3 * t2[i]; + } + + for (int i = 0; i < 3; ++i) + if (vertices[0][i] == vertices[1][i] && vertices[1][i] == vertices[2][i] && + vertices[2][i] == vertices[3][i] && vertices[3][i] == vertices[4][i] && + vertices[4][i] == vertices[5][i]) { plane = i; break; @@ -270,10 +276,10 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1, for (int i = 0; i < 3; ++i) { - points2D[i * 2] = LCR_renderer.mapVertices[3 * t1[i] + coordX]; - points2D[i * 2 + 1] = LCR_renderer.mapVertices[3 * t1[i] + coordY]; - points2D[6 + i * 2] = LCR_renderer.mapVertices[3 * t2[i] + coordX]; - points2D[6 + i * 2 + 1] = LCR_renderer.mapVertices[3 * t2[i] + coordY]; + points2D[i * 2] = vertices[i][coordX]; + points2D[i * 2 + 1] = vertices[i][coordY]; + points2D[6 + i * 2] = vertices[3 + i][coordX]; + points2D[6 + i * 2 + 1] = vertices[3 + i][coordY]; } points2D[12] = (4 * points2D[6] + 3 * points2D[8] + points2D[10]) / 8; @@ -325,9 +331,18 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1, } } + // now swap both triangles and do it all again: + const S3L_Index *tmp = t1; t1 = t2; t2 = tmp; + + for (int i = 0; i < 3; ++i) + { + S3L_Unit *tmpCoord = vertices[i]; + vertices[i] = vertices[3 + i]; + vertices[3 + i] = tmpCoord; + } } } @@ -341,6 +356,8 @@ uint8_t _LCR_rendererCheckMapTriangleCover(const S3L_Index *t1, */ void _LCR_rendererCullHiddenMapTriangles(void) { + LCR_log("culling invisible triangles"); + int n = 0; // number of removed elements int i = 0; @@ -432,6 +449,8 @@ void _LCR_rendererCullHiddenMapTriangles(void) */ uint8_t _LCR_rendererBuildMapModel(void) { + LCR_log("building map model"); + uint8_t blockShapeBytes[LCR_MAP_BLOCK_SHAPE_MAX_BYTES]; uint8_t blockShapeByteCount; @@ -439,6 +458,9 @@ uint8_t _LCR_rendererBuildMapModel(void) for (int j = 0; j < LCR_currentMap.blockCount; ++j) { + if ((j + 1) % LCR_SETTING_TRIANGLE_CULLING_PERIOD == 0) + _LCR_rendererCullHiddenMapTriangles(); + S3L_Unit originOffset = -1 * LCR_MAP_SIZE_BLOCKS / 2 * LCR_RENDERER_UNIT; S3L_Index triangleIndices[3]; const uint8_t *block = LCR_currentMap.blocks + j * LCR_BLOCK_SIZE; @@ -552,6 +574,8 @@ uint8_t _LCR_rendererBuildMapModel(void) uint8_t LCR_rendererInit(void) { + LCR_log("initializing renderer"); + LCR_renderer.mapModel = LCR_renderer.models3D; if (!_LCR_rendererBuildMapModel()) diff --git a/settings.h b/settings.h index 31014cb..b86a9ba 100644 --- a/settings.h +++ b/settings.h @@ -57,4 +57,10 @@ #define LCR_SETTING_MAP_MAX_SIZE 4096 #endif +#ifndef LCR_SETTING_TRIANGLE_CULLING_PERIOD + /** This says how often (after how many triangles added) the map model + triangles will be culled. This value may affect how quickly maps load. */ + #define LCR_SETTING_TRIANGLE_CULLING_PERIOD 64 +#endif + #endif // guard