Add potato mode

This commit is contained in:
Miloslav Ciz 2024-12-18 18:40:03 +01:00
parent 5d9038021a
commit e42212d7c1
4 changed files with 95 additions and 7 deletions

View file

@ -1,5 +1,6 @@
=========== GENERAL ==============
- car shadow?
- sound engine: probably all SFX will be procedurally generated, ok?
- allow slowing down in air like in TM?
- music?
@ -7,10 +8,6 @@
that be played by the frontend just ALL the time (maybe with the option in
menu to just turn music off) -- simple frontends can just ignore music
- allow car to be flipped upside down on start? with start block transform
- make a simple rendering setting:
- will exclude images and only draw solid colors, let's say only 16, so that
memory usage is reduced, CPU rendering is relieved, executable is smaller
AND frontend doesn't have to use RGB565 (it can basically choose any mode).
- camera behavior? what if car is riding upside down (on magnet) etc?
- compile time option to choose how many maps to include (for platforms with
lower memory)
@ -33,6 +30,10 @@
=========== HANDLED ==============
- allow stopping car rotation in air like in Trackmania
- make a simple rendering setting:
- will exclude images and only draw solid colors, let's say only 16, so that
memory usage is reduced, CPU rendering is relieved, executable is smaller
AND frontend doesn't have to use RGB565 (it can basically choose any mode).
- drifting: passing some upper threshold on steering force should reduce
steering friction until reaching some some lower threshold again probably
- maybe allow some more air control, like slowing down with brakes, like in TM

View file

@ -36,8 +36,8 @@ static const char *LCR_maps[] =
"#;p0w0L #f5130" // bugs
"#=f0s0 #fd110" // small labyrinth
"#=c0p0 #fd110"
"#>f0s0 #fd110" // small labyrinth
"#oc0p0 #fd110"
"#=f0s0 #f11d0"
"#=c0p0 #f11d0"
@ -153,6 +153,7 @@ uint16_t LCR_getFontChar(char c)
#define LCR_IMAGE_GROUND_FAN 7
#define LCR_IMAGE_CAR 20
#if !LCR_SETTING_POTATO_GRAPHICS
static const uint8_t LCR_images[] =
{
// 0: wall concrete
@ -2178,7 +2179,7 @@ static const uint8_t LCR_images[] =
0xe6,0xed,0xf1,0xfc,0xae,0xfa,0x89,0xf7,0x6b,0xc2,0xc2,0xe9,0xee,0xa7,0xa7,0xb5,
0xb5,0xb5,0xa7,0xa7,0xf9,0xee,0xf9,0xe9,0xf7,0x89,0xf6,0xae,0xd2,0xf1,0xff,0xe6,
0xff,0xfe,0xfd,0xed,0xfb,0xed,0xf1,0xf8,0xeb,0xf6,0xf5,0xf4,0xf3,0xf2,0xed,0xf0,
// 7: ground sticker
// 7: ground fan
0x2c,0x63,0x4d,0x6b,0x08,0x42,0x00,0x00,0x08,0x00,0x10,0x00,0x18,0x00,0x00,0x01,
0x08,0x01,0x10,0x01,0x18,0x01,0x00,0x02,0x08,0x02,0x10,0x02,0x18,0x02,0x00,0x03,
0x08,0x03,0x10,0x03,0x18,0x03,0x00,0x04,0x08,0x04,0x10,0x04,0x18,0x04,0x00,0x05,
@ -6225,9 +6226,11 @@ static const uint8_t LCR_images[] =
0x15,0x15,0x15,0x15,0x15,0x15,0x15,0xa5,0xf7,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xfb,
0x00,0xec,0xb6,0xb6,0xce,0x00,0xa5,0xa5,0x00,0x00,0xec,0xa5,0x01,0xcc,0xc1,0xc1
};
#endif // LCR_SETTING_POTATO_GRAPHICS
void LCR_loadImage(unsigned int index)
{
#if !LCR_SETTING_POTATO_GRAPHICS
LCR_currentImage.image = LCR_images + index * LCR_IMAGE_STORE_SIZE;
for (int i = 0; i < 256; ++i)
@ -6239,6 +6242,7 @@ void LCR_loadImage(unsigned int index)
}
LCR_currentImage.pixel = LCR_currentImage.image;
#endif
}
/**

View file

@ -12,6 +12,12 @@
#define S3L_NEAR_CROSS_STRATEGY 1
#define S3L_Z_BUFFER 1
#if LCR_SETTING_POTATO_GRAPHICS
#define S3L_PERSPECTIVE_CORRECTION 0
#define S3L_NEAR_CROSS_STRATEGY 1
#define S3L_FLAT 1
#endif
#include "small3dlib.h"
/// Renderer specific unit, length of one map square.
@ -190,6 +196,47 @@ void LCR_rendererDrawText(const char *text, int x, int y, uint16_t color,
void _LCR_pixelFunc3D(S3L_PixelInfo *pixel)
{
#if LCR_SETTING_POTATO_GRAPHICS
// simple shader for simplified graphics
if (pixel->triangleID != LCR_renderer.previousTriID)
{
LCR_renderer.previousTriID = pixel->triangleID;
LCR_renderer.flatAndTransparent = 0x630c; // base gray
if (pixel->modelIndex < 8)
{
uint8_t tData =
(LCR_renderer.mapTriangleData +
LCR_renderer.chunkStarts[LCR_renderer.loadedChunks[
pixel->modelIndex]])[pixel->triangleIndex];
switch (tData & 0x0f)
{
case 3: LCR_renderer.flatAndTransparent &= ~(0x3008); break; // grass
case 4: LCR_renderer.flatAndTransparent &= ~(0x0408); break; // mud
case 5: LCR_renderer.flatAndTransparent |= 0x0010; break; // ice
case 6: LCR_renderer.flatAndTransparent |= 0x8080; break; // acc
case 7: LCR_renderer.flatAndTransparent &= ~(0x4208); break; // fan
default: break;
}
tData &= 0x30;
LCR_renderer.flatAndTransparent |=
(((uint16_t) (tData)) >> 4) |
(((uint16_t) (tData)) << 2) |
(((uint16_t) (tData)) << 7);
}
else
LCR_renderer.flatAndTransparent >>= 1; // car, darken
LCR_renderer.flatAndTransparent += pixel->triangleIndex % 4;
}
LCR_drawPixelXYUnsafe(pixel->x,pixel->y,LCR_renderer.flatAndTransparent);
#else // LCR_SETTING_POTATO_GRAPHICS
// once we get a new triangle, we precompute things for it:
if (pixel->triangleID != LCR_renderer.previousTriID)
{
@ -352,6 +399,7 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel)
#endif
LCR_drawPixelXYUnsafe(pixel->x,pixel->y,color);
#endif // LCR_SETTING_POTATO_GRAPHICS
}
S3L_Index _LCR_rendererAddMapVert(S3L_Unit x, S3L_Unit y, S3L_Unit z)
@ -1199,6 +1247,10 @@ void LCR_rendererDrawSky(int sky, S3L_Unit offsetH, S3L_Unit offsetV)
{
LCR_LOG2("drawing sky");
#if LCR_SETTING_POTATO_GRAPHICS
LCR_rendererDrawRect(0,0,LCR_EFFECTIVE_RESOLUTION_X,
LCR_EFFECTIVE_RESOLUTION_Y,0x7bfd,0);
#else
int anchorPoint[2], y;
unsigned long pixelIndex;
unsigned int topColor, bottomColor;
@ -1319,6 +1371,7 @@ void LCR_rendererDrawSky(int sky, S3L_Unit offsetH, S3L_Unit offsetV)
y++;
}
#endif
}
void _LCR_rendererLoadMapChunk(uint8_t chunk, int8_t x, int8_t y, int8_t z)
@ -1672,7 +1725,31 @@ void LCR_rendererDraw(void)
LCR_rendererDrawLOD();
LCR_LOG2("gonna render 3D scene");
#if LCR_SETTING_POTATO_GRAPHICS
/* in potato mode we render twice so that car is always in front of the
level model (lack of precise depth causes artifacts otherwise) */
LCR_renderer.carModel->config.visible = 0;
LCR_renderer.ghostModel->config.visible = 0;
S3L_drawScene(LCR_renderer.scene);
for (int i = 0; i < LCR_renderer.scene.modelCount; ++i)
LCR_renderer.scene.models[i].config.visible = 0;
LCR_renderer.carModel->config.visible = 1;
LCR_renderer.ghostModel->config.visible = 1;
S3L_newFrame();
S3L_drawScene(LCR_renderer.scene);
for (int i = 0; i < LCR_renderer.scene.modelCount; ++i)
LCR_renderer.scene.models[i].config.visible = 1;
#else
S3L_drawScene(LCR_renderer.scene);
#endif
LCR_LOG2("rendering 3D scene done");
LCR_renderer.frame++;

View file

@ -164,4 +164,10 @@
#define LCR_SETTING_DEBUG_PHYSICS_DRAW 0
#endif
#ifndef LCR_SETTING_POTATO_GRAPHICS
/** Setting this will turn on very simple graphics without textures and etc.,
can be good for very weak devices. */
#define LCR_SETTING_POTATO_GRAPHICS 0
#endif
#endif // guard