Add stats mod
This commit is contained in:
parent
0231cd25c5
commit
5fe854373d
2 changed files with 237 additions and 1 deletions
|
@ -66,7 +66,7 @@ Please note however the game is still relatively simple and so **the physics IS
|
|||
- It is **super moddable and hackable**, the code is relatively simple and **well commented**, written to encourage hacking. There are no obstacles such as DRM, anti-cheating, obfuscation etc. Cheating and hacking is allowed, do literally what you want.
|
||||
- **No codes of censorship, flags, furry mascots or similar political bullshit.**
|
||||
- **No "modern" bullshit such as OOP, Python, Docker, meme design patterns, scripting, sandboxes, "memory safety" and similar crap**.
|
||||
- It is **absolutely and completely public domain free software with ZERO conditions on use** under CC0, it is legally more free that most "FOSS" software, there is no copyleft or credit requirement, you can do ABSOLUTELY anything you want with the project. This is a **selfless project aiming for no benefit of the creator** (include any non-financial benefit as well), this is made purely to bring more good to the world without gaining any advantage for self.
|
||||
- It is **absolutely and completely public domain free software with ZERO conditions on use** under CC0, it is legally more free that most "FOSS" software, there is no copyleft or credit requirement, you can do ABSOLUTELY anything you want with the project. This is a **selfless project aiming for no benefit of the creator** (include any non-financial benefit as well), this is made purely to bring more good to the world without gaining any advantage for self. Not only won't you be bothered by ads, you won't be bothered by begging for money either.
|
||||
- This game has **PURE SOUL** and REAL oldschool graphics in the "PS1" style. No Unity or Unreal, no "retro" imitation shaders, no assets from a store. This isn't a wannabe retro 90s pretender, this IS a real 90s game.
|
||||
- The game is **finished**, no need to update it ever.
|
||||
|
||||
|
|
236
mods/stats.diff
Normal file
236
mods/stats.diff
Normal file
|
@ -0,0 +1,236 @@
|
|||
Simple mod that will print run stats (such as maximum speed or acceleration) to
|
||||
the console upon finishing (in normal run or replay).
|
||||
|
||||
diff --git a/frontend_helper.h b/frontend_helper.h
|
||||
index f95b078..3b6bb44 100644
|
||||
--- a/frontend_helper.h
|
||||
+++ b/frontend_helper.h
|
||||
@@ -128,3 +128,60 @@ void closeDataFile(void)
|
||||
fclose(dataFile);
|
||||
#endif
|
||||
}
|
||||
+
|
||||
+void _printStatVal(int val, int divisor)
|
||||
+{
|
||||
+ if (val < 0)
|
||||
+ {
|
||||
+ putchar('-');
|
||||
+ val *= -1;
|
||||
+ }
|
||||
+
|
||||
+ printf("%d",val / divisor);
|
||||
+
|
||||
+ if (divisor > 1)
|
||||
+ printf(".%d",val % divisor);
|
||||
+}
|
||||
+
|
||||
+void LCR_presentStats(const int *stats)
|
||||
+{
|
||||
+ printf("run stats: ");
|
||||
+ printf("speed (max/avg): ");
|
||||
+ _printStatVal(stats[0],1);
|
||||
+ putchar(' ');
|
||||
+ _printStatVal(stats[1],1000);
|
||||
+
|
||||
+ printf("; accel (min/max/avg/avgAbs): ");
|
||||
+ _printStatVal(stats[2],1);
|
||||
+ putchar(' ');
|
||||
+ _printStatVal(stats[3],1);
|
||||
+ putchar(' ');
|
||||
+ _printStatVal(stats[4],1000);
|
||||
+ putchar(' ');
|
||||
+ _printStatVal(stats[5],1000);
|
||||
+
|
||||
+ printf("; dist: ");
|
||||
+ _printStatVal(stats[6],100);
|
||||
+
|
||||
+ printf("; surface %% (concr./grass/dirt/ice/air): ");
|
||||
+
|
||||
+ for (int i = 7; i <= 11; ++i)
|
||||
+ {
|
||||
+ _printStatVal(stats[i],1);
|
||||
+ putchar(i == 11 ? ';' : ' ');
|
||||
+ }
|
||||
+
|
||||
+ printf(" keys (U/D/R/L/avg): ");
|
||||
+
|
||||
+ _printStatVal(stats[12],1);
|
||||
+ putchar(' ');
|
||||
+ _printStatVal(stats[13],1);
|
||||
+ putchar(' ');
|
||||
+ _printStatVal(stats[14],1);
|
||||
+ putchar(' ');
|
||||
+ _printStatVal(stats[15],1);
|
||||
+ putchar(' ');
|
||||
+ _printStatVal(stats[16],100);
|
||||
+
|
||||
+ putchar('\n');
|
||||
+}
|
||||
diff --git a/game.h b/game.h
|
||||
index 1ad5131..c20b103 100644
|
||||
--- a/game.h
|
||||
+++ b/game.h
|
||||
@@ -167,6 +167,32 @@ uint8_t LCR_gameMusicOn(void);
|
||||
*/
|
||||
uint8_t LCR_gameGetNextAudioSample(void);
|
||||
|
||||
+#define LCR_STATS_SPEED_KMH_MAX 0
|
||||
+#define LCR_STATS_SPEED_MH_AVG 1
|
||||
+#define LCR_STATS_ACCEL_KMH_MIN 2
|
||||
+#define LCR_STATS_ACCEL_KMH_MAX 3
|
||||
+#define LCR_STATS_ACCEL_MHS_AVG 4
|
||||
+#define LCR_STATS_ACCEL_ABS_MHS_AVG 5
|
||||
+#define LCR_STATS_DIST_CM 6
|
||||
+#define LCR_STATS_SURF_PERC_CONCR 7
|
||||
+#define LCR_STATS_SURF_PERC_GRASS 8
|
||||
+#define LCR_STATS_SURF_PERC_DIRT 9
|
||||
+#define LCR_STATS_SURF_PERC_ICE 10
|
||||
+#define LCR_STATS_SURF_PERC_AIR 11
|
||||
+#define LCR_STATS_KEY_FRAMES_U 12
|
||||
+#define LCR_STATS_KEY_FRAMES_D 13
|
||||
+#define LCR_STATS_KEY_FRAMES_R 14
|
||||
+#define LCR_STATS_KEY_FRAMES_L 15
|
||||
+#define LCR_STATS_KEYS_AVG_X100 16
|
||||
+#define _LCR_STATS_TOTAL 17
|
||||
+
|
||||
+/**
|
||||
+ Will be called to present run stats, implement the presentation however you
|
||||
+ want (e.g. by printing to standard output). The stats array holds individual
|
||||
+ stats values, their meaning is described by the LCR_STATS_* constants.
|
||||
+*/
|
||||
+void LCR_presentStats(const int *stats);
|
||||
+
|
||||
/**
|
||||
This macro may be redefined by frontend to a command that will be periodically
|
||||
performed during map loading. This exists to prevent making the program seem
|
||||
@@ -386,6 +412,9 @@ struct
|
||||
uint8_t renderFramesMeasured;
|
||||
uint8_t physicsFramesMeasured;
|
||||
#endif
|
||||
+
|
||||
+ LCR_GameUnit prevSpeed;
|
||||
+ int stats[_LCR_STATS_TOTAL];
|
||||
} LCR_game;
|
||||
|
||||
uint8_t LCR_gameMusicOn(void)
|
||||
@@ -494,6 +523,11 @@ void LCR_gameResetRun(uint8_t replay, uint8_t ghost)
|
||||
LCR_racingGetCarTransform(carTransform,carTransform + 3,0);
|
||||
LCR_rendererSetCarTransform(carTransform,carTransform + 3);
|
||||
|
||||
+ LCR_game.prevSpeed = 0;
|
||||
+
|
||||
+ for (int i = 0; i < _LCR_STATS_TOTAL; ++i)
|
||||
+ LCR_game.stats[i] = 0;
|
||||
+
|
||||
if (LCR_game.cameraMode != LCR_CAMERA_MODE_FREE)
|
||||
{
|
||||
LCR_rendererCameraReset();
|
||||
@@ -1776,6 +1810,61 @@ uint8_t LCR_gameStep(uint32_t time)
|
||||
|
||||
uint32_t events = paused ? 0 : LCR_racingStep(input);
|
||||
|
||||
+ // collect stats:
|
||||
+
|
||||
+ int stat = LCR_carSpeedKMH();
|
||||
+
|
||||
+ if (stat > LCR_game.stats[LCR_STATS_SPEED_KMH_MAX])
|
||||
+ LCR_game.stats[LCR_STATS_SPEED_KMH_MAX] = stat;
|
||||
+
|
||||
+ LCR_game.stats[LCR_STATS_SPEED_MH_AVG] += stat;
|
||||
+
|
||||
+ if ((LCR_racing.wheelCollisions & 0x0f) == 0)
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_AIR]++;
|
||||
+ else if (LCR_racingCurrentGroundMaterial() == LCR_BLOCK_MATERIAL_GRASS)
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_GRASS]++;
|
||||
+ else if (LCR_racingCurrentGroundMaterial() == LCR_BLOCK_MATERIAL_DIRT)
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_DIRT]++;
|
||||
+ else if (LCR_racingCurrentGroundMaterial() == LCR_BLOCK_MATERIAL_ICE)
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_ICE]++;
|
||||
+ else
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_CONCR]++;
|
||||
+
|
||||
+ LCR_game.stats[LCR_STATS_KEY_FRAMES_U] +=
|
||||
+ (LCR_racing.currentInputs & LCR_RACING_INPUT_FORW) != 0;
|
||||
+ LCR_game.stats[LCR_STATS_KEY_FRAMES_D] +=
|
||||
+ (LCR_racing.currentInputs & LCR_RACING_INPUT_BACK) != 0;
|
||||
+ LCR_game.stats[LCR_STATS_KEY_FRAMES_R] +=
|
||||
+ (LCR_racing.currentInputs & LCR_RACING_INPUT_RIGHT) != 0;
|
||||
+ LCR_game.stats[LCR_STATS_KEY_FRAMES_L] +=
|
||||
+ (LCR_racing.currentInputs & LCR_RACING_INPUT_LEFT) != 0;
|
||||
+
|
||||
+ LCR_game.stats[LCR_STATS_KEYS_AVG_X100] +=
|
||||
+ ((LCR_racing.currentInputs & LCR_RACING_INPUT_FORW) != 0) +
|
||||
+ ((LCR_racing.currentInputs & LCR_RACING_INPUT_BACK) != 0) +
|
||||
+ ((LCR_racing.currentInputs & LCR_RACING_INPUT_RIGHT) != 0) +
|
||||
+ ((LCR_racing.currentInputs & LCR_RACING_INPUT_LEFT) != 0);
|
||||
+
|
||||
+ stat = LCR_carSpeedKMH() - LCR_game.prevSpeed;
|
||||
+
|
||||
+ if (LCR_game.runTime <= 1 ||
|
||||
+ stat > LCR_game.stats[LCR_STATS_ACCEL_KMH_MAX])
|
||||
+ LCR_game.stats[LCR_STATS_ACCEL_KMH_MAX] = stat;
|
||||
+
|
||||
+ if (LCR_game.runTime <= 1 ||
|
||||
+ stat < LCR_game.stats[LCR_STATS_ACCEL_KMH_MIN])
|
||||
+ LCR_game.stats[LCR_STATS_ACCEL_KMH_MIN] = stat;
|
||||
+
|
||||
+ LCR_game.stats[LCR_STATS_ACCEL_MHS_AVG] += stat;
|
||||
+
|
||||
+ if (stat < 0)
|
||||
+ stat *= -1;
|
||||
+
|
||||
+ LCR_game.stats[LCR_STATS_ACCEL_ABS_MHS_AVG] += stat;
|
||||
+ LCR_game.stats[LCR_STATS_DIST_CM] += LCR_racingGetCarSpeedUnsigned();
|
||||
+
|
||||
+ LCR_game.prevSpeed = LCR_carSpeedKMH();
|
||||
+
|
||||
#if LCR_SETTING_PARTICLES
|
||||
LCR_rendererSetParticles(0);
|
||||
|
||||
@@ -1816,6 +1905,46 @@ uint8_t LCR_gameStep(uint32_t time)
|
||||
LCR_LOG1("finished, time:");
|
||||
LCR_LOG1_NUM(LCR_game.runTime);
|
||||
|
||||
+ // now convert collected stats to correct units:
|
||||
+
|
||||
+ LCR_game.stats[LCR_STATS_SPEED_MH_AVG] =
|
||||
+ (LCR_game.stats[LCR_STATS_SPEED_MH_AVG] * 1000) / LCR_game.runTime;
|
||||
+
|
||||
+ LCR_game.stats[LCR_STATS_ACCEL_MHS_AVG] =
|
||||
+ (LCR_game.stats[LCR_STATS_ACCEL_MHS_AVG] * 1000 * LCR_RACING_FPS) /
|
||||
+ LCR_game.runTime;
|
||||
+
|
||||
+ LCR_game.stats[LCR_STATS_ACCEL_ABS_MHS_AVG] =
|
||||
+ (LCR_game.stats[LCR_STATS_ACCEL_ABS_MHS_AVG] * 1000 * LCR_RACING_FPS)
|
||||
+ / LCR_game.runTime;
|
||||
+
|
||||
+ int tmp =
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_CONCR] +
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_GRASS] +
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_DIRT] +
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_ICE] +
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_AIR];
|
||||
+
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_CONCR] =
|
||||
+ (100 * LCR_game.stats[LCR_STATS_SURF_PERC_CONCR]) / tmp;
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_GRASS] =
|
||||
+ (100 * LCR_game.stats[LCR_STATS_SURF_PERC_GRASS]) / tmp;
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_DIRT] =
|
||||
+ (100 * LCR_game.stats[LCR_STATS_SURF_PERC_DIRT]) / tmp;
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_ICE] =
|
||||
+ (100 * LCR_game.stats[LCR_STATS_SURF_PERC_ICE]) / tmp;
|
||||
+ LCR_game.stats[LCR_STATS_SURF_PERC_AIR] =
|
||||
+ (100 * LCR_game.stats[LCR_STATS_SURF_PERC_AIR]) / tmp;
|
||||
+
|
||||
+ LCR_game.stats[LCR_STATS_KEYS_AVG_X100] =
|
||||
+ (LCR_game.stats[LCR_STATS_KEYS_AVG_X100] * 100)/ LCR_game.runTime;
|
||||
+
|
||||
+ LCR_game.stats[LCR_STATS_DIST_CM] =
|
||||
+ (LCR_game.stats[LCR_STATS_DIST_CM] * LCR_SETTING_CMS_PER_BLOCK)
|
||||
+ / LCR_GAME_UNIT;
|
||||
+
|
||||
+ LCR_presentStats(LCR_game.stats);
|
||||
+
|
||||
if (LCR_game.runTime <= LCR_currentMap.targetTime
|
||||
#if LCR_SETTING_REPLAY_MAX_SIZE != 0
|
||||
&& !LCR_racing.replay.on
|
Loading…
Add table
Add a link
Reference in a new issue