diff --git a/TODO.txt b/TODO.txt index 7fb3c44..511d133 100644 --- a/TODO.txt +++ b/TODO.txt @@ -20,6 +20,7 @@ =========== BUGS ================= +- was able to take a CP without it changing color to gray, try to reproduce - drawing dithered transparent objects fills z-buffer in the transparent parts and then the geometry behind it isn't drawn <- PARTIALLY FIXED NOW diff --git a/game.h b/game.h index 8da7d29..81b37fd 100644 --- a/game.h +++ b/game.h @@ -168,8 +168,10 @@ uint8_t LCR_gameGetNextAudioSample(void); #endif #endif -#define LCR_CONTROL_MODE_FREECAM 0x00 -#define LCR_CONTROL_MODE_DRIVE 0x01 +#define LCR_CAMERA_MODE_DRIVE 0x00 +#define LCR_CAMERA_MODE_DRIVE2 0x01 +#define LCR_CAMERA_MODE_INSIDE 0x02 +#define LCR_CAMERA_MODE_FREE 0x03 #define LCR_GAME_STATE_MENU 0x00 #define LCR_GAME_STATE_RUN_STARTING 0x01 @@ -194,7 +196,7 @@ struct uint32_t frame; uint32_t nextRenderFrameTime; uint32_t nextRacingTickTime; - uint8_t controlMode; + uint8_t cameraMode; uint8_t debugDraw; uint8_t musicOn; uint8_t keyStates[LCR_KEYS_TOTAL]; /**< Assures unchanging key states @@ -414,7 +416,7 @@ void LCR_gameLoadMainMenuItems(void) { for (int i = 0; i < 5; ++i) { - char replaceChar = i == 0 ? 'X' : + char replaceChar = i == 0 ? '0' + LCR_game.cameraMode : (i == 1 ? '0' + LCR_game.musicOn : ('0' + LCR_audio.on)); LCR_gameSetMenuItemStr(i,LCR_texts[4 + i],replaceChar); @@ -447,7 +449,7 @@ void LCR_gameInit(void) LCR_game.musicOn = 1; LCR_game.nextRenderFrameTime = 0; LCR_game.nextRacingTickTime = 0; - LCR_game.controlMode = LCR_CONTROL_MODE_DRIVE; + LCR_game.cameraMode = LCR_CAMERA_MODE_DRIVE; LCR_gameLoadMainMenuItems(); @@ -545,8 +547,10 @@ void LCR_gameDraw3DView(void) LCR_rendererSetCarTransform(carTransform,carTransform + 3); - if (LCR_game.controlMode != LCR_CONTROL_MODE_FREECAM) - LCR_rendererCameraFollow(); + if (LCR_game.cameraMode != LCR_CAMERA_MODE_FREE) + LCR_rendererCameraFollow( + (LCR_game.cameraMode != LCR_CAMERA_MODE_INSIDE) + + (LCR_game.cameraMode == LCR_CAMERA_MODE_DRIVE2)); #if LCR_ANIMATE_CAR LCR_rendererSetWheelState(LCR_racingGetWheelRotation(), @@ -699,6 +703,10 @@ void LCR_gameHandleInput(void) switch (LCR_game.menuSelectedItem) { case 0: + LCR_game.cameraMode = (LCR_game.cameraMode + 1) % 4; + LCR_rendererSetCarVisibility( + LCR_game.cameraMode != LCR_CAMERA_MODE_INSIDE); + LCR_rendererCameraReset(); break; case 1: @@ -743,6 +751,40 @@ void LCR_gameHandleInput(void) LCR_gameSetState(LCR_GAME_STATE_MENU); LCR_game.menuSelectedItem = 0; } + else if (LCR_game.cameraMode == LCR_CAMERA_MODE_FREE) + { + LCR_GameUnit offsets[5]; + + for (int i = 0; i < 5; ++i) + offsets[i] = 0; + + if (LCR_game.keyStates[LCR_KEY_A]) + { + if (LCR_game.keyStates[LCR_KEY_UP]) + offsets[4] = LCR_FREE_CAMERA_TURN_STEP; + else if (LCR_game.keyStates[LCR_KEY_DOWN]) + offsets[4] -= LCR_FREE_CAMERA_TURN_STEP; + + if (LCR_game.keyStates[LCR_KEY_RIGHT]) + offsets[3] -= LCR_FREE_CAMERA_TURN_STEP; + else if (LCR_game.keyStates[LCR_KEY_LEFT]) + offsets[3] = LCR_FREE_CAMERA_TURN_STEP; + } + else + { + if (LCR_game.keyStates[LCR_KEY_UP]) + offsets[0] = LCR_FREE_CAMERA_STEP; + else if (LCR_game.keyStates[LCR_KEY_DOWN]) + offsets[0] -= LCR_FREE_CAMERA_STEP; + + if (LCR_game.keyStates[LCR_KEY_RIGHT]) + offsets[1] = LCR_FREE_CAMERA_STEP; + else if (LCR_game.keyStates[LCR_KEY_LEFT]) + offsets[1] -= LCR_FREE_CAMERA_STEP; + } + + LCR_rendererMoveCamera(offsets,offsets + 3); + } else if (LCR_game.keyStates[LCR_KEY_A] == 1) LCR_gameResetRun(); @@ -781,54 +823,23 @@ uint8_t LCR_gameStep(uint32_t time) LCR_gameHandleInput(); +/* LCR_GameUnit offsets[5]; for (int i = 0; i < 5; ++i) offsets[i] = 0; -/* - if (LCR_game.controlMode == LCR_CONTROL_MODE_FREECAM) - { - if (LCR_game.keyStates[LCR_KEY_A]) - { - if (LCR_game.keyStates[LCR_KEY_UP]) - offsets[4] = LCR_FREE_CAMERA_TURN_STEP; - else if (LCR_game.keyStates[LCR_KEY_DOWN]) - offsets[4] -= LCR_FREE_CAMERA_TURN_STEP; - - if (LCR_game.keyStates[LCR_KEY_RIGHT]) - offsets[3] -= LCR_FREE_CAMERA_TURN_STEP; - else if (LCR_game.keyStates[LCR_KEY_LEFT]) - offsets[3] = LCR_FREE_CAMERA_TURN_STEP; - } - else - { - if (LCR_game.keyStates[LCR_KEY_UP]) - offsets[0] = LCR_FREE_CAMERA_STEP; - else if (LCR_game.keyStates[LCR_KEY_DOWN]) - offsets[0] -= LCR_FREE_CAMERA_STEP; - - if (LCR_game.keyStates[LCR_KEY_RIGHT]) - offsets[1] = LCR_FREE_CAMERA_STEP; - else if (LCR_game.keyStates[LCR_KEY_LEFT]) - offsets[1] -= LCR_FREE_CAMERA_STEP; - } - - LCR_rendererMoveCamera(offsets,offsets + 3); - } */ // handle simulation: while (time >= LCR_game.nextRacingTickTime) { LCR_LOG2("gonna step racing engine"); - unsigned int input = 0; - if (LCR_game.controlMode != LCR_CONTROL_MODE_FREECAM) - input = - (LCR_game.keyStates[LCR_KEY_UP] ? LCR_RACING_INPUT_FORW : 0) | - (LCR_game.keyStates[LCR_KEY_RIGHT] ? LCR_RACING_INPUT_RIGHT : 0) | - (LCR_game.keyStates[LCR_KEY_DOWN] ? LCR_RACING_INPUT_BACK : 0) | - (LCR_game.keyStates[LCR_KEY_LEFT] ? LCR_RACING_INPUT_LEFT : 0); + unsigned int input = LCR_game.cameraMode == LCR_CAMERA_MODE_FREE ? 0 : + ((LCR_game.keyStates[LCR_KEY_UP] ? LCR_RACING_INPUT_FORW : 0) | + (LCR_game.keyStates[LCR_KEY_RIGHT] ? LCR_RACING_INPUT_RIGHT : 0) | + (LCR_game.keyStates[LCR_KEY_DOWN] ? LCR_RACING_INPUT_BACK : 0) | + (LCR_game.keyStates[LCR_KEY_LEFT] ? LCR_RACING_INPUT_LEFT : 0)); uint32_t events = paused ? 0 : LCR_racingStep(input); diff --git a/renderer.h b/renderer.h index 84a775d..12ef637 100644 --- a/renderer.h +++ b/renderer.h @@ -120,6 +120,11 @@ void LCR_rendererSetCarTransform(LCR_GameUnit position[3], S3L_F) / LCR_GAME_UNIT,S3L_F); } +void LCR_rendererSetCarVisibility(uint8_t visible) +{ + LCR_renderer.carModel->config.visible = visible; +} + void _LCR_rendererDrawFontPixel(int x, int y, uint16_t color) { #if LCR_FONT_PIXEL_SIZE == 1 @@ -1604,20 +1609,47 @@ void _LCR_rendererAnimateCar(void) } #endif -void LCR_rendererCameraFollow(void) +/** + Call every rendering frame to make the camera follow the car model. The + distance parameter can be either 0 (inside of car, car should be made + invisible for this), 1 (normal distance) or 2 (double distance). +*/ +void LCR_rendererCameraFollow(unsigned char distance) { LCR_LOG2("following camera"); + if (distance == 0) + { + LCR_renderer.scene.camera.transform.translation = + LCR_renderer.carModel->transform.translation; + + LCR_renderer.scene.camera.transform.translation.y += LCR_RENDERER_UNIT / 3; + + LCR_renderer.scene.camera.transform.rotation = + LCR_renderer.carModel->transform.rotation; + + LCR_renderer.scene.camera.transform.rotation.x = -1 * + ((LCR_renderer.scene.camera.transform.rotation.x + S3L_FRACTIONS_PER_UNIT / 4) % + (S3L_FRACTIONS_PER_UNIT / 2) - S3L_FRACTIONS_PER_UNIT / 4); + + LCR_renderer.scene.camera.transform.rotation.y += S3L_FRACTIONS_PER_UNIT / 2; + LCR_renderer.scene.camera.transform.rotation.z *= -1; + + return; + } + + int shift = distance != 1; + S3L_Transform3D transPrev = LCR_renderer.scene.camera.transform; LCR_renderer.scene.camera.transform.translation.y = S3L_clamp( LCR_renderer.scene.camera.transform.translation.y, LCR_renderer.carModel->transform.translation.y + - (LCR_SETTING_CAMERA_HEIGHT - LCR_SETTING_CAMERA_HEIGHT_BAND) * + ((LCR_SETTING_CAMERA_HEIGHT << shift) - LCR_SETTING_CAMERA_HEIGHT_BAND) * LCR_RENDERER_UNIT / 8, LCR_renderer.carModel->transform.translation.y + - (LCR_SETTING_CAMERA_HEIGHT + LCR_SETTING_CAMERA_HEIGHT_BAND) * + ((LCR_SETTING_CAMERA_HEIGHT << shift) + LCR_SETTING_CAMERA_HEIGHT_BAND) * LCR_RENDERER_UNIT / 8); S3L_Vec4 toCam = LCR_renderer.scene.camera.transform.translation; @@ -1634,9 +1666,9 @@ void LCR_rendererCameraFollow(void) S3L_Unit horizontalDistNew = S3L_clamp(horizontalDist, - (LCR_SETTING_CAMERA_DISTANCE - LCR_SETTING_CAMERA_DISTANCE_BAND) + ((LCR_SETTING_CAMERA_DISTANCE << shift) - LCR_SETTING_CAMERA_DISTANCE_BAND) * (LCR_RENDERER_UNIT / 4), - (LCR_SETTING_CAMERA_DISTANCE + LCR_SETTING_CAMERA_DISTANCE_BAND) + ((LCR_SETTING_CAMERA_DISTANCE << shift) + LCR_SETTING_CAMERA_DISTANCE_BAND) * (LCR_RENDERER_UNIT / 4)); if (horizontalDistNew != horizontalDist) @@ -1776,6 +1808,7 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items, #endif } +// TODO: what is this function even doing? void LCR_rendererCameraReset(void) { LCR_renderer.scene.camera.transform.translation = @@ -1787,7 +1820,10 @@ void LCR_rendererCameraReset(void) LCR_renderer.scene.camera.transform.translation.z += S3L_cos(LCR_renderer.carModel->transform.rotation.y); - LCR_rendererCameraFollow(); + LCR_renderer.scene.camera.transform.rotation.x = 0; + LCR_renderer.scene.camera.transform.rotation.z = 0; + + LCR_rendererCameraFollow(1); } void LCR_rendererSetWheelState(LCR_GameUnit rotation, LCR_GameUnit steer)