Add ribbon mod
This commit is contained in:
parent
094ec2684e
commit
01bb187aba
1 changed files with 176 additions and 0 deletions
176
mods/ribbon.diff
Normal file
176
mods/ribbon.diff
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
Licar mod that adds a simple visual effect, a kind of ribbon light trail.
|
||||||
|
|
||||||
|
diff --git a/game.h b/game.h
|
||||||
|
index b1db32c..e9db9be 100644
|
||||||
|
--- a/game.h
|
||||||
|
+++ b/game.h
|
||||||
|
@@ -335,6 +335,7 @@ struct
|
||||||
|
uint32_t frame; ///< Current frame number.
|
||||||
|
uint32_t nextRenderFrameTime; ///< At which frame to render next frame.
|
||||||
|
uint32_t nextRacingTickTime; ///< When to simulate next physics tick.
|
||||||
|
+ uint32_t nextRibbonTime;
|
||||||
|
uint8_t cameraMode;
|
||||||
|
uint8_t musicOn;
|
||||||
|
uint8_t keyStates[LCR_KEYS_TOTAL]; /**< Assures unchanging key states
|
||||||
|
@@ -1102,6 +1103,7 @@ void LCR_gameInit(int argc, const char **argv)
|
||||||
|
LCR_game.musicOn = LCR_SETTING_MUSIC;
|
||||||
|
LCR_game.nextRenderFrameTime = 0;
|
||||||
|
LCR_game.nextRacingTickTime = 0;
|
||||||
|
+ LCR_game.nextRibbonTime = 0;
|
||||||
|
LCR_game.cameraMode = LCR_CAMERA_MODE_DRIVE;
|
||||||
|
LCR_currentMap.blockCount = 0; // means no map loaded
|
||||||
|
|
||||||
|
@@ -1771,6 +1773,9 @@ uint8_t LCR_gameStep(uint32_t time)
|
||||||
|
|
||||||
|
uint32_t events = paused ? 0 : LCR_racingStep(input);
|
||||||
|
|
||||||
|
+ if (LCR_racing.tick % LCR_SETTING_RIBBON_INTERVAL == 0)
|
||||||
|
+ LCR_rendererRibbonUpdate();
|
||||||
|
+
|
||||||
|
#if LCR_SETTING_PARTICLES
|
||||||
|
LCR_rendererSetParticles(0);
|
||||||
|
|
||||||
|
diff --git a/renderer.h b/renderer.h
|
||||||
|
index 735644e..6941398 100644
|
||||||
|
--- a/renderer.h
|
||||||
|
+++ b/renderer.h
|
||||||
|
@@ -153,6 +153,9 @@ struct
|
||||||
|
#if LCR_SETTING_PARTICLES
|
||||||
|
uint_fast16_t particleColor; ///< 0x0000 means no particles active.
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
+ int16_t ribbonPoints[LCR_SETTING_RIBBON_SEGMENTS * 3];
|
||||||
|
+ uint8_t ribbonLastSegment;
|
||||||
|
} LCR_renderer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -200,6 +203,23 @@ void LCR_rendererSetGhostTransform(LCR_GameUnit position[3],
|
||||||
|
_LCR_rendererSetModelTransform(LCR_renderer.ghostModel,position,rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void LCR_rendererRibbonUpdate(void)
|
||||||
|
+{
|
||||||
|
+ LCR_renderer.ribbonLastSegment =
|
||||||
|
+ (LCR_renderer.ribbonLastSegment + 1) % LCR_SETTING_RIBBON_SEGMENTS;
|
||||||
|
+
|
||||||
|
+ unsigned int n = 3 * LCR_renderer.ribbonLastSegment;
|
||||||
|
+
|
||||||
|
+ LCR_renderer.ribbonPoints[n] =
|
||||||
|
+ LCR_renderer.carModel->transform.translation.x / 2;
|
||||||
|
+ n++;
|
||||||
|
+ LCR_renderer.ribbonPoints[n] =
|
||||||
|
+ LCR_renderer.carModel->transform.translation.y / 2;
|
||||||
|
+ n++;
|
||||||
|
+ LCR_renderer.ribbonPoints[n] =
|
||||||
|
+ LCR_renderer.carModel->transform.translation.z / 2;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void LCR_rendererSetCarVisibility(uint8_t visible)
|
||||||
|
{
|
||||||
|
LCR_renderer.carModel->config.visible = visible;
|
||||||
|
@@ -2154,6 +2174,59 @@ void LCR_rendererSetWheelState(LCR_GameUnit rotation, LCR_GameUnit steer)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
+void LCR_rendererDrawRibbon(void)
|
||||||
|
+{
|
||||||
|
+ S3L_Vec4 p, r;
|
||||||
|
+ int16_t *s = // this will go backwards
|
||||||
|
+ LCR_renderer.ribbonPoints + 3 * LCR_renderer.ribbonLastSegment + 2;
|
||||||
|
+ int16_t prev[3]; // previous values for interpolation: screen x, y and size
|
||||||
|
+
|
||||||
|
+ p.x = LCR_renderer.carModel->transform.translation.x;
|
||||||
|
+ p.y = LCR_renderer.carModel->transform.translation.y;
|
||||||
|
+ p.z = LCR_renderer.carModel->transform.translation.z;
|
||||||
|
+ p.w = (LCR_SETTING_RIBBON_SIZE * LCR_SETTING_RESOLUTION_X) / 100;
|
||||||
|
+
|
||||||
|
+ S3L_project3DPointToScreen(p,LCR_renderer.scene.camera,&r);
|
||||||
|
+
|
||||||
|
+ prev[0] = r.x;
|
||||||
|
+ prev[1] = r.y;
|
||||||
|
+ prev[2] = r.w;
|
||||||
|
+
|
||||||
|
+ for (int i = 0; i < LCR_SETTING_RIBBON_SEGMENTS; ++i)
|
||||||
|
+ {
|
||||||
|
+ p.z = *s * 2; s--;
|
||||||
|
+ p.y = *s * 2; s--;
|
||||||
|
+ p.x = *s * 2; s--;
|
||||||
|
+ p.w = (LCR_SETTING_RIBBON_SIZE * LCR_SETTING_RESOLUTION_X) / 100;
|
||||||
|
+
|
||||||
|
+ // reducing size towards the tail:
|
||||||
|
+ p.w = (p.w * (LCR_SETTING_RIBBON_SEGMENTS - 1 - i))
|
||||||
|
+ / LCR_SETTING_RIBBON_SEGMENTS;
|
||||||
|
+
|
||||||
|
+ if (s <= LCR_renderer.ribbonPoints) // wrap to the end
|
||||||
|
+ s = LCR_renderer.ribbonPoints + (LCR_SETTING_RIBBON_SEGMENTS - 1) * 3 + 2;
|
||||||
|
+
|
||||||
|
+ S3L_project3DPointToScreen(p,LCR_renderer.scene.camera,&r);
|
||||||
|
+
|
||||||
|
+ for (int j = 0; j < LCR_SETTING_RIBBON_SUBDIV; ++j)
|
||||||
|
+ {
|
||||||
|
+ int w = prev[2] + (j * (r.w - prev[2])) / LCR_SETTING_RIBBON_SUBDIV;
|
||||||
|
+ int x = prev[0] + (j * (r.x - prev[0])) / LCR_SETTING_RIBBON_SUBDIV
|
||||||
|
+ - w / 2;
|
||||||
|
+ int y = prev[1] + (j * (r.y - prev[1])) / LCR_SETTING_RIBBON_SUBDIV
|
||||||
|
+ - w / 2;
|
||||||
|
+
|
||||||
|
+ if (w > 0 && x > 0 && y > 0 &&
|
||||||
|
+ x < LCR_EFFECTIVE_RESOLUTION_X && y < LCR_EFFECTIVE_RESOLUTION_Y)
|
||||||
|
+ LCR_rendererDrawRect(x,y,w,w,LCR_SETTING_RIBBON_COLOR,1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ prev[0] = r.x;
|
||||||
|
+ prev[1] = r.y;
|
||||||
|
+ prev[2] = r.w;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void LCR_rendererDraw3D(void)
|
||||||
|
{
|
||||||
|
LCR_LOG2("rendering frame (start)");
|
||||||
|
@@ -2304,6 +2377,8 @@ void LCR_rendererDraw3D(void)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ LCR_rendererDrawRibbon();
|
||||||
|
+
|
||||||
|
LCR_LOG2("3D rendering (end)");
|
||||||
|
LCR_LOG2("rendering frame (end)");
|
||||||
|
}
|
||||||
|
diff --git a/settings.h b/settings.h
|
||||||
|
index 332df45..47e27f8 100644
|
||||||
|
--- a/settings.h
|
||||||
|
+++ b/settings.h
|
||||||
|
@@ -200,6 +200,32 @@
|
||||||
|
#define LCR_SETTING_COUNTDOWN_MS 2200
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifndef LCR_SETTING_RIBBON_SEGMENTS
|
||||||
|
+ /** Ribbon mod: how many points to spawn. */
|
||||||
|
+ #define LCR_SETTING_RIBBON_SEGMENTS 10
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef LCR_SETTING_RIBBON_SUBDIV
|
||||||
|
+ /** Ribbon mod: number of splats to draw per segment, it's good to keep this a
|
||||||
|
+ power of 2. */
|
||||||
|
+ #define LCR_SETTING_RIBBON_SUBDIV 16
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef LCR_SETTING_RIBBON_INTERVAL
|
||||||
|
+ /** Ribbon mod: how often to spawn a new ribbon point (in physics ticks). */
|
||||||
|
+ #define LCR_SETTING_RIBBON_INTERVAL 4
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef LCR_SETTING_RIBBON_SIZE
|
||||||
|
+ /** Ribbon mod: ribbon splat size (in percents of screen width). */
|
||||||
|
+ #define LCR_SETTING_RIBBON_SIZE 6
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef LCR_SETTING_RIBBON_COLOR
|
||||||
|
+ /** Ribbon mod: ribbon color. */
|
||||||
|
+ #define LCR_SETTING_RIBBON_COLOR 0xffe6
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#ifndef LCR_SETTING_MAP_CHUNK_RELOAD_INTERVAL
|
||||||
|
/** Interval in rendering frames of reloading map chunks, should ideally be
|
||||||
|
kept a power of two, can't be 0. */
|
Loading…
Add table
Add a link
Reference in a new issue