diff --git a/TODO.txt b/TODO.txt index fefc843..5fe6400 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,5 +1,18 @@ =========== GENERAL ============== +- asset system: + - assets are to be loaded from one BIG string consisting of substrings, each + substring adds a map, replay, setting etc. + - part of the substring will be hardcoded (default maps) + - optionally a frontend can extend this from a file +- make the racing module usable by itself, e.g. to allow making tools for + verifying replays etc., i.e. make the module measure time, count checkpoints + etc. +- racing update step should return events that happened, e.g.: + - CP taken + - crash (to play sound) + - finish + - etc. - car shadow? - sound engine: probably all SFX will be procedurally generated, ok? - allow slowing down in air like in TM? diff --git a/assets.h b/assets.h index 6300072..3fc8cce 100644 --- a/assets.h +++ b/assets.h @@ -23,6 +23,7 @@ static const char *LCR_maps[] = "#=s0s0 #fd190" // big concrete "#+v0n0" + "#+w0o0" "#!x0n0" "#=s0B0 #fd910" // concrete wall diff --git a/game.h b/game.h index 6581ad2..b94a753 100644 --- a/game.h +++ b/game.h @@ -146,7 +146,6 @@ struct uint32_t nextRacingTickTime; uint8_t controlMode; uint8_t debugDraw; - uint8_t checkpointsTaken; uint32_t runTime; uint8_t musicVolume; @@ -218,7 +217,6 @@ void LCR_gameResetRun(void) LCR_GameUnit carTransform[6]; LCR_LOG0("resetting run"); - LCR_game.checkpointsTaken = 0; LCR_mapReset(); LCR_racingRestart(); LCR_rendererUnmarkCPs(); @@ -262,12 +260,12 @@ void LCR_gameEnd(void) uint8_t LCR_gameStep(uint32_t time) { + LCR_GameUnit carTransform[6]; + LCR_LOG2("game step start"); LCR_game.time = time; - LCR_GameUnit carTransform[6]; - for (int i = 0; i < LCR_KEYS_TOTAL; ++i) LCR_keyStates[i] = LCR_keyPressed(i) ? (LCR_keyStates[i] < 255 ? LCR_keyStates[i] + 1 : 255) : 0; @@ -292,40 +290,19 @@ uint8_t LCR_gameStep(uint32_t time) (LCR_keyStates[LCR_KEY_DOWN] ? LCR_RACING_INPUT_BACK : 0) | (LCR_keyStates[LCR_KEY_LEFT] ? LCR_RACING_INPUT_LEFT : 0); - LCR_racingStep(input); + uint32_t events = LCR_racingStep(input); - LCR_racingGetCarTransform(carTransform,carTransform + 3,0); - - carTransform[0] = (carTransform[0] + (LCR_GAME_UNIT * LCR_MAP_SIZE_BLOCKS) - / 2) / LCR_GAME_UNIT; - carTransform[1] = (carTransform[1] + (LCR_GAME_UNIT * LCR_MAP_SIZE_BLOCKS) - / 4) / (LCR_GAME_UNIT / 2); - 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]); - - if (blockIndex >= 0) + if (events & LCR_RACING_EVENT_CP_TAKEN) { - if (LCR_currentMap.blocks[blockIndex * LCR_BLOCK_SIZE] == - LCR_BLOCK_CHECKPOINT_0) - { - LCR_LOG1("CP taken"); + int carBlock[3]; - 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"); - - - } + LCR_racingGetCarBlockCoords(carBlock); + LCR_LOG1("CP taken"); + LCR_rendererMarkTakenCP(carBlock[0],carBlock[1],carBlock[2]); + } + else if (events & LCR_RACING_EVENT_FINISHED) + { + LCR_LOG1("finished"); } LCR_game.runTime++; @@ -338,9 +315,9 @@ uint8_t LCR_gameStep(uint32_t time) { LCR_LOG2("gonna render next frame"); -LCR_GameUnit physicsInterpolationParam = LCR_GAME_UNIT - - ((LCR_game.nextRacingTickTime - time) * LCR_GAME_UNIT) / - LCR_RACING_TICK_MS; + LCR_GameUnit physicsInterpolationParam = LCR_GAME_UNIT - + ((LCR_game.nextRacingTickTime - time) * LCR_GAME_UNIT) + / LCR_RACING_TICK_MS; LCR_racingGetCarTransform(carTransform,carTransform + 3, physicsInterpolationParam); diff --git a/racing.h b/racing.h index c6cb15f..fb56748 100644 --- a/racing.h +++ b/racing.h @@ -559,6 +559,7 @@ void _LCR_racingUpdateCarPosRot(void) void LCR_racingRestart(void) { LCR_LOG0("restarting race"); + LCR_mapReset(); LCR_racing.tick = 0; LCR_racing.fanForce = 0; @@ -690,6 +691,22 @@ void LCR_racingGetCarTransform(LCR_GameUnit position[3], #endif } +/** + Gets the current block coordinates of the car, without interpolation etc., + intended for checking accurately whether CP has been taken etc. +*/ +void LCR_racingGetCarBlockCoords(int coords[3]) +{ + coords[0] = (LCR_racing.carPositions[0].x + + (LCR_GAME_UNIT * LCR_MAP_SIZE_BLOCKS) / 2) / LCR_GAME_UNIT; + + coords[1] = (LCR_racing.carPositions[0].y + + (LCR_GAME_UNIT * LCR_MAP_SIZE_BLOCKS) / 4) / (LCR_GAME_UNIT / 2); + + coords[2] = (LCR_racing.carPositions[0].z + + (LCR_GAME_UNIT * LCR_MAP_SIZE_BLOCKS) / 2) / LCR_GAME_UNIT; +} + void _LCR_drawPhysicsDebugPixel(uint16_t x, uint16_t y, uint8_t color) { if (x > 1 && x < LCR_EFFECTIVE_RESOLUTION_X - 2 && @@ -1006,13 +1023,45 @@ uint32_t LCR_racingStep(unsigned int input) { TPE_bodyAccelerate(&(LCR_racing.carBody),TPE_vec3(0,LCR_racing.fanForce,0)); - LCR_racing.fanForce -= LCR_GRAVITY / LCR_FAN_FORCE_DECREASE; if (LCR_racing.fanForce < 0) LCR_racing.fanForce = 0; } + int carBlock[3]; + + LCR_racingGetCarBlockCoords(carBlock); + + carBlock[0] = LCR_mapGetBlockAt(carBlock[0],carBlock[1],carBlock[2]); + + if (carBlock[0] >= 0) + { + if (LCR_currentMap.blocks[carBlock[0] * LCR_BLOCK_SIZE] == + LCR_BLOCK_CHECKPOINT_0) + { + LCR_currentMap.blocks[carBlock[0] * LCR_BLOCK_SIZE] = + LCR_BLOCK_CHECKPOINT_1; + + result |= LCR_RACING_EVENT_CP_TAKEN; + } + else if (LCR_currentMap.blocks[carBlock[0] * LCR_BLOCK_SIZE] == + LCR_BLOCK_FINISH) + { + int valid = 1; + + for (int i = 0; i < LCR_currentMap.blockCount; ++i) + if (LCR_currentMap.blocks[i * LCR_BLOCK_SIZE] == LCR_BLOCK_CHECKPOINT_0) + { + valid = 0; + break; + } + + if (valid) + result |= LCR_RACING_EVENT_FINISHED; + } + } + LCR_LOG2("gonna step physics engine"); TPE_worldStep(&(LCR_racing.physicsWorld)); LCR_LOG2("stepping physics engine done");