diff --git a/assets.h b/assets.h index 7a777c8..bbf8f22 100644 --- a/assets.h +++ b/assets.h @@ -62,6 +62,9 @@ LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,3,5,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_B LCR_MAP_BLOCK(LCR_BLOCK_CHECKPOINT_0,3,1,4,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_CHECKPOINT_0,3,1,8,LCR_BLOCK_MATERIAL_CONCRETE,0), +LCR_MAP_BLOCK(LCR_BLOCK_FINISH,2,1,10,LCR_BLOCK_MATERIAL_CONCRETE,0), + /* LCR_MAP_BLOCK(LCR_BLOCK_FULL,2,1,9,LCR_BLOCK_MATERIAL_CONCRETE,0), LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,2,5,1,0,0), diff --git a/game.h b/game.h index ba5b095..57cd3b7 100644 --- a/game.h +++ b/game.h @@ -123,6 +123,7 @@ struct uint32_t nextRacingTickTime; uint8_t controlMode; uint8_t debugDraw; + uint8_t checkpointsTaken; } LCR_game; void LCR_drawPixelXYUnsafe(unsigned int x, unsigned int y, @@ -162,6 +163,14 @@ static inline void LCR_drawPixelXYSafe(unsigned int x, unsigned int y, LCR_drawPixelXYUnsafe(x,y,color); } +void LCR_gameResetRun(void) +{ + LCR_LOG0("resetting run"); + LCR_game.checkpointsTaken = 0; + LCR_mapReset(); + LCR_rendererUnmarkCPs(); +} + void LCR_gameInit(void) { LCR_LOG0("initializing"); @@ -178,6 +187,8 @@ void LCR_gameInit(void) LCR_game.controlMode = LCR_CONTROL_MODE_FREECAM; LCR_game.debugDraw = 0; + + LCR_gameResetRun(); } void LCR_gameEnd(void) @@ -234,15 +245,30 @@ if ((LCR_racing.tick % 32) == 0) carTransform[2] = (carTransform[2] + (LCR_GAME_UNIT * LCR_MAP_SIZE_BLOCKS) / 2) / LCR_GAME_UNIT; - int blockIndex = LCR_mapGetBlockAt(carTransform[0],carTransform[1],carTransform[2]); + int blockIndex = + LCR_mapGetBlockAt(carTransform[0],carTransform[1],carTransform[2]); - if (blockIndex >= 0 && LCR_currentMap.blocks[blockIndex * LCR_BLOCK_SIZE] == - LCR_BLOCK_CHECKPOINT_0) + if (blockIndex >= 0) { - LCR_currentMap.blocks[blockIndex * LCR_BLOCK_SIZE] = - LCR_BLOCK_CHECKPOINT_1; - LCR_rendererMarkTakenCP( - carTransform[0],carTransform[1],carTransform[2]); + if (LCR_currentMap.blocks[blockIndex * LCR_BLOCK_SIZE] == + LCR_BLOCK_CHECKPOINT_0) + { + LCR_LOG1("CP taken"); + + LCR_currentMap.blocks[blockIndex * LCR_BLOCK_SIZE] = + LCR_BLOCK_CHECKPOINT_1; + LCR_rendererMarkTakenCP( + carTransform[0],carTransform[1],carTransform[2]); + LCR_game.checkpointsTaken++; + } + else if (LCR_game.checkpointsTaken == LCR_currentMap.checkpointCount && + LCR_currentMap.blocks[blockIndex * LCR_BLOCK_SIZE] == LCR_BLOCK_FINISH) + { + LCR_LOG1("finished"); + +// TODO + + } } LCR_game.nextRacingTickTime += LCR_RACING_TICK_MS; diff --git a/map.h b/map.h index ba8645f..ed706fd 100644 --- a/map.h +++ b/map.h @@ -130,7 +130,7 @@ struct uint8_t startPos[4]; ///< Initial position and rotation. uint8_t environment; - + uint8_t checkpointCount; // TODO: name, desc? possibly as a single '\n' separated string? } LCR_currentMap; @@ -309,6 +309,18 @@ uint8_t _LCR_mapAddBlock(const uint8_t block[LCR_BLOCK_SIZE]) return 1; } +/** + Resets the map to start a run (including e.g. unmarking checkpoints etc.). +*/ +void LCR_mapReset(void) +{ + LCR_LOG0("resetting map"); + + for (int i = 0; i < LCR_currentMap.blockCount; ++i) + if (LCR_currentMap.blocks[i * LCR_BLOCK_SIZE] == LCR_BLOCK_CHECKPOINT_1) + LCR_currentMap.blocks[i * LCR_BLOCK_SIZE] = LCR_BLOCK_CHECKPOINT_0; +} + /** Loads and preprocesses given map. Returns 1 on success, otherwise 0. */ @@ -319,6 +331,7 @@ uint8_t LCR_mapLoad(const uint8_t *map) for (int i = 0; i < 4; ++i) LCR_currentMap.startPos[i] = 0; + LCR_currentMap.checkpointCount = 0; LCR_currentMap.blockCount = 0; if (map[0] != LCR_MAP_MAGIC_NUMBER1 || map[1] != LCR_MAP_MAGIC_NUMBER2) @@ -392,6 +405,9 @@ uint8_t LCR_mapLoad(const uint8_t *map) LCR_currentMap.startPos[3] = LCR_mapBlockGetTransform(map) & 0x60; break; + case LCR_BLOCK_CHECKPOINT_0: + LCR_currentMap.checkpointCount++; + // fall through default: if (!_LCR_mapAddBlock(map)) // normal block return 0; @@ -409,6 +425,8 @@ uint8_t LCR_mapLoad(const uint8_t *map) LCR_LOG2("map loaded") + LCR_mapReset(); + return 1; } diff --git a/renderer.h b/renderer.h index a257385..9128e3d 100644 --- a/renderer.h +++ b/renderer.h @@ -804,6 +804,20 @@ void _LCR_rendererComputeLOD(void) } } +/** + Unmarks all checkpoints that were marked with LCR_rendererMarkTakenCP. +*/ +void LCR_rendererUnmarkCPs(void) +{ + for (int i = 0; i < LCR_renderer.mapModel.triangleCount; ++i) + if ((LCR_renderer.mapTriangleData[i] & 0x0f) == LCR_RENDERER_MAT_CP1) + LCR_renderer.mapTriangleData[i] = (LCR_renderer.mapTriangleData[i] & 0xf0) + | LCR_RENDERER_MAT_CP0; +} + +/** + Marks checkpoint as taken, i.e. changes how a checkpoint will be drawn. +*/ void LCR_rendererMarkTakenCP(int x, int y, int z) { for (int i = 0; i < LCR_renderer.mapModel.triangleCount; ++i)