Add countdown

This commit is contained in:
Miloslav Ciz 2025-01-01 01:23:43 +01:00
parent c7711b6cf4
commit d27bc59742
2 changed files with 119 additions and 65 deletions

179
game.h
View file

@ -189,6 +189,10 @@ struct
uint8_t controlMode; uint8_t controlMode;
uint8_t debugDraw; uint8_t debugDraw;
uint8_t musicVolume; uint8_t musicVolume;
uint8_t keyStates[LCR_KEYS_TOTAL]; /**< Assures unchanging key states
during a single frame, hold number of
frames for which the key has been
continuously held. */
struct struct
{ {
@ -226,11 +230,6 @@ static inline void LCR_drawPixelXYSafe(unsigned int x, unsigned int y,
#include "renderer.h" #include "renderer.h"
#include "audio.h" #include "audio.h"
uint8_t LCR_keyStates[LCR_KEYS_TOTAL]; /**< Assures unchanging key states
during a single frame, holds
number of frames for which the key
has been continuously held. */
void LCR_drawPixelXYUnsafe(unsigned int x, unsigned int y, void LCR_drawPixelXYUnsafe(unsigned int x, unsigned int y,
uint16_t color) uint16_t color)
{ {
@ -370,7 +369,6 @@ LCR_seekResourceByIndex(0); // TODO
LCR_mapLoadFromStr(LCR_gameGetNextResourceStrChar); LCR_mapLoadFromStr(LCR_gameGetNextResourceStrChar);
LCR_rendererLoadMap(); LCR_rendererLoadMap();
LCR_gameResetRun(); LCR_gameResetRun();
LCR_racingRestart();
} }
void LCR_gameInit(void) void LCR_gameInit(void)
@ -378,7 +376,7 @@ void LCR_gameInit(void)
LCR_LOG0("initializing"); LCR_LOG0("initializing");
for (int i = 0; i < LCR_KEYS_TOTAL; ++i) for (int i = 0; i < LCR_KEYS_TOTAL; ++i)
LCR_keyStates[i] = 0; LCR_game.keyStates[i] = 0;
LCR_rendererInit(); LCR_rendererInit();
LCR_racingInit(); LCR_racingInit();
@ -402,12 +400,8 @@ for (int i = 0; i < LCR_RESOURCE_ITEM_CHUNK; ++i)
LCR_game.musicVolume = 255; LCR_game.musicVolume = 255;
LCR_game.nextRenderFrameTime = 0; LCR_game.nextRenderFrameTime = 0;
LCR_game.nextRacingTickTime = 0; LCR_game.nextRacingTickTime = 0;
LCR_game.controlMode = LCR_CONTROL_MODE_FREECAM; LCR_game.controlMode = LCR_CONTROL_MODE_DRIVE;
LCR_gameStartRun(); LCR_gameStartRun();
LCR_game.state = LCR_GAME_STATE_RUN;
} }
/** /**
@ -447,99 +441,153 @@ void LCR_gameDraw3DView(void)
LCR_rendererDraw(); LCR_rendererDraw();
int val = LCR_carSpeedKMH();
if (val < 5) // don't show tiny oscillations when still
val = 0;
char str[6];
str[0] = val >= 100 ? '0' + (val / 100) % 10 : ' ';
str[1] = val >= 10 ? '0' + (val / 10) % 10 : ' ';
str[2] = '0' + val % 10;
str[3] = 0;
LCR_rendererDrawText(str,
LCR_EFFECTIVE_RESOLUTION_X -
LCR_rendererComputeTextWidth(str,2) - 20,
LCR_EFFECTIVE_RESOLUTION_Y -
LCR_rendererComputeTextHeight(2) - 20,0,2);
val = LCR_racingGetRunTimeMS() / 1000; // seconds
str[3] = '0' + (val % 60) / 10;
str[4] = '0' + val % 10;
val = (val / 60) % 100; // minutes
str[0] = '0' + val / 10;
str[1] = '0' + val % 10;
str[2] = '\'';
str[5] = 0;
LCR_rendererDrawText(str,20,LCR_EFFECTIVE_RESOLUTION_Y -
LCR_rendererComputeTextHeight(2) - 20,0,2);
#if LCR_SETTING_DEBUG_PHYSICS_DRAW #if LCR_SETTING_DEBUG_PHYSICS_DRAW
LCR_GameUnit camTr[7]; LCR_GameUnit camTr[7];
LCR_rendererGetCameraTransform(camTr,camTr + 3,camTr + 6); LCR_rendererGetCameraTransform(camTr,camTr + 3,camTr + 6);
LCR_physicsDebugDraw(camTr,camTr + 3,camTr[6]); LCR_physicsDebugDraw(camTr,camTr + 3,camTr[6]);
#endif #endif
// GUI/HUD:
char str[6];
switch (LCR_game.state)
{
case LCR_GAME_STATE_RUN_STARTING:
str[0] = '0' + LCR_SETTING_COUNTDOWN_SECONDS -
(LCR_game.time - LCR_game.stateStartTime) / 1000;
str[1] = 0;
LCR_rendererDrawText(str,
(LCR_EFFECTIVE_RESOLUTION_X - LCR_rendererComputeTextWidth(str,8)) / 2,
LCR_EFFECTIVE_RESOLUTION_Y / 2,0x0707,8);
break;
default:
{
int val = LCR_carSpeedKMH();
if (val < 5) // don't show tiny oscillations when still
val = 0;
str[0] = val >= 100 ? '0' + (val / 100) % 10 : ' ';
str[1] = val >= 10 ? '0' + (val / 10) % 10 : ' ';
str[2] = '0' + val % 10;
str[3] = 0;
LCR_rendererDrawText(str,
LCR_EFFECTIVE_RESOLUTION_X -
LCR_rendererComputeTextWidth(str,2) - 20,
LCR_EFFECTIVE_RESOLUTION_Y -
LCR_rendererComputeTextHeight(2) - 20,0,2);
val = LCR_racingGetRunTimeMS() / 1000; // seconds
str[3] = '0' + (val % 60) / 10;
str[4] = '0' + val % 10;
val = (val / 60) % 100; // minutes
str[0] = '0' + val / 10;
str[1] = '0' + val % 10;
str[2] = '\'';
str[5] = 0;
LCR_rendererDrawText(str,20,LCR_EFFECTIVE_RESOLUTION_Y -
LCR_rendererComputeTextHeight(2) - 20,0,2);
break;
}
}
} }
uint8_t LCR_gameStep(uint32_t time) uint8_t LCR_gameStep(uint32_t time)
{ {
uint32_t sleep = 0; uint32_t sleep = 0;
int paused = 0;
LCR_LOG2("game step start"); LCR_LOG2("game step start");
LCR_game.time = time; LCR_game.time = time;
for (int i = 0; i < LCR_KEYS_TOTAL; ++i) for (int i = 0; i < LCR_KEYS_TOTAL; ++i)
LCR_keyStates[i] = LCR_keyPressed(i) ? LCR_game.keyStates[i] = LCR_keyPressed(i) ?
(LCR_keyStates[i] < 255 ? LCR_keyStates[i] + 1 : 255) : 0; (LCR_game.keyStates[i] < 255 ? LCR_game.keyStates[i] + 1 : 255) : 0;
if (LCR_keyStates[LCR_KEY_B] == 1) switch (LCR_game.state)
{
case LCR_GAME_STATE_MENU:
paused = 1;
if (LCR_game.keyStates[LCR_KEY_B] == 1)
LCR_gameSetState(LCR_GAME_STATE_RUN);
break;
case LCR_GAME_STATE_RUN_STARTING:
paused = 1;
if (LCR_game.time - LCR_game.stateStartTime
>= 1000 * LCR_SETTING_COUNTDOWN_SECONDS)
LCR_gameSetState(LCR_GAME_STATE_RUN);
// fall through
default:
if (LCR_game.keyStates[LCR_KEY_B] == 1)
LCR_gameSetState(LCR_GAME_STATE_MENU);
else if (LCR_game.keyStates[LCR_KEY_A] == 1)
LCR_gameResetRun();
break;
}
/*
if (LCR_game.keyStates[LCR_KEY_B] == 1)
LCR_game.controlMode = LCR_game.controlMode == LCR_CONTROL_MODE_FREECAM ? LCR_game.controlMode = LCR_game.controlMode == LCR_CONTROL_MODE_FREECAM ?
LCR_CONTROL_MODE_DRIVE : LCR_CONTROL_MODE_FREECAM; LCR_CONTROL_MODE_DRIVE : LCR_CONTROL_MODE_FREECAM;
else if (LCR_keyStates[LCR_KEY_B] == 30) else if (LCR_game.keyStates[LCR_KEY_B] == 30)
LCR_gameResetRun(); LCR_gameResetRun();
*/
LCR_GameUnit offsets[5]; LCR_GameUnit offsets[5];
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
offsets[i] = 0; offsets[i] = 0;
/*
if (LCR_game.controlMode == LCR_CONTROL_MODE_FREECAM) if (LCR_game.controlMode == LCR_CONTROL_MODE_FREECAM)
{ {
if (LCR_keyStates[LCR_KEY_A]) if (LCR_game.keyStates[LCR_KEY_A])
{ {
if (LCR_keyStates[LCR_KEY_UP]) if (LCR_game.keyStates[LCR_KEY_UP])
offsets[4] = LCR_FREE_CAMERA_TURN_STEP; offsets[4] = LCR_FREE_CAMERA_TURN_STEP;
else if (LCR_keyStates[LCR_KEY_DOWN]) else if (LCR_game.keyStates[LCR_KEY_DOWN])
offsets[4] -= LCR_FREE_CAMERA_TURN_STEP; offsets[4] -= LCR_FREE_CAMERA_TURN_STEP;
if (LCR_keyStates[LCR_KEY_RIGHT]) if (LCR_game.keyStates[LCR_KEY_RIGHT])
offsets[3] -= LCR_FREE_CAMERA_TURN_STEP; offsets[3] -= LCR_FREE_CAMERA_TURN_STEP;
else if (LCR_keyStates[LCR_KEY_LEFT]) else if (LCR_game.keyStates[LCR_KEY_LEFT])
offsets[3] = LCR_FREE_CAMERA_TURN_STEP; offsets[3] = LCR_FREE_CAMERA_TURN_STEP;
} }
else else
{ {
if (LCR_keyStates[LCR_KEY_UP]) if (LCR_game.keyStates[LCR_KEY_UP])
offsets[0] = LCR_FREE_CAMERA_STEP; offsets[0] = LCR_FREE_CAMERA_STEP;
else if (LCR_keyStates[LCR_KEY_DOWN]) else if (LCR_game.keyStates[LCR_KEY_DOWN])
offsets[0] -= LCR_FREE_CAMERA_STEP; offsets[0] -= LCR_FREE_CAMERA_STEP;
if (LCR_keyStates[LCR_KEY_RIGHT]) if (LCR_game.keyStates[LCR_KEY_RIGHT])
offsets[1] = LCR_FREE_CAMERA_STEP; offsets[1] = LCR_FREE_CAMERA_STEP;
else if (LCR_keyStates[LCR_KEY_LEFT]) else if (LCR_game.keyStates[LCR_KEY_LEFT])
offsets[1] -= LCR_FREE_CAMERA_STEP; offsets[1] -= LCR_FREE_CAMERA_STEP;
} }
LCR_rendererMoveCamera(offsets,offsets + 3); LCR_rendererMoveCamera(offsets,offsets + 3);
} }
*/
// handle simulation:
while (time >= LCR_game.nextRacingTickTime) while (time >= LCR_game.nextRacingTickTime)
{ {
LCR_LOG2("gonna step racing engine"); LCR_LOG2("gonna step racing engine");
@ -547,12 +595,12 @@ uint8_t LCR_gameStep(uint32_t time)
if (LCR_game.controlMode != LCR_CONTROL_MODE_FREECAM) if (LCR_game.controlMode != LCR_CONTROL_MODE_FREECAM)
input = input =
(LCR_keyStates[LCR_KEY_UP] ? LCR_RACING_INPUT_FORW : 0) | (LCR_game.keyStates[LCR_KEY_UP] ? LCR_RACING_INPUT_FORW : 0) |
(LCR_keyStates[LCR_KEY_RIGHT] ? LCR_RACING_INPUT_RIGHT : 0) | (LCR_game.keyStates[LCR_KEY_RIGHT] ? LCR_RACING_INPUT_RIGHT : 0) |
(LCR_keyStates[LCR_KEY_DOWN] ? LCR_RACING_INPUT_BACK : 0) | (LCR_game.keyStates[LCR_KEY_DOWN] ? LCR_RACING_INPUT_BACK : 0) |
(LCR_keyStates[LCR_KEY_LEFT] ? LCR_RACING_INPUT_LEFT : 0); (LCR_game.keyStates[LCR_KEY_LEFT] ? LCR_RACING_INPUT_LEFT : 0);
uint32_t events = LCR_racingStep(input); uint32_t events = paused ? 0 : LCR_racingStep(input);
if (events & LCR_RACING_EVENT_CP_TAKEN) if (events & LCR_RACING_EVENT_CP_TAKEN)
{ {
@ -586,6 +634,7 @@ uint8_t LCR_gameStep(uint32_t time)
sleep = (3 * (LCR_game.nextRacingTickTime - time)) / 4; sleep = (3 * (LCR_game.nextRacingTickTime - time)) / 4;
// handle rendering:
if (time >= LCR_game.nextRenderFrameTime) if (time >= LCR_game.nextRenderFrameTime)
{ {
LCR_LOG2("gonna render next frame"); LCR_LOG2("gonna render next frame");

View file

@ -182,4 +182,9 @@
#define LCR_SETTING_ENABLE_RESOURCE_FILE 1 #define LCR_SETTING_ENABLE_RESOURCE_FILE 1
#endif #endif
#ifndef LCR_SETTING_COUNTDOWN_SECONDS
/** Run start countdown length in seconds. */
#define LCR_SETTING_COUNTDOWN_SECONDS 3
#endif
#endif // guard #endif // guard