Start checkpoint rendering

This commit is contained in:
Miloslav Ciz 2024-10-07 15:52:39 +02:00
parent e23fb2657a
commit 2c5162b635
5 changed files with 157 additions and 84 deletions

View file

@ -34,6 +34,9 @@
=========== BUGS =================
- drawing dithered transparent objects fills z-buffer in the transparent parts
and then the geometry behind it isn't drawn
=========== HANDLED ==============
- EFFICINT MAP DRAWING:

View file

@ -60,6 +60,9 @@ LCR_MAP_BLOCK(LCR_BLOCK_RAMP_STEEP,4,4,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_T
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,4,5,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V | LCR_BLOCK_TRANSFORM_ROT_180),
LCR_MAP_BLOCK(LCR_BLOCK_RAMP_CURVED_PLAT,3,5,6,LCR_BLOCK_MATERIAL_CONCRETE,LCR_BLOCK_TRANSFORM_FLIP_V | LCR_BLOCK_TRANSFORM_ROT_180),
LCR_MAP_BLOCK(LCR_BLOCK_CHECKPOINT_0,3,2,4,LCR_BLOCK_MATERIAL_CONCRETE,0),
/*
LCR_MAP_BLOCK(LCR_BLOCK_FULL,2,1,9,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,2,5,1,0,0),
@ -74,7 +77,6 @@ LCR_MAP_BLOCK(LCR_BLOCK_CORNER,1,1,4,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_FULL,15,0,0,LCR_BLOCK_MATERIAL_CONCRETE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,15,0,0),
/*
LCR_MAP_BLOCK(LCR_BLOCK_FULL,25,0,0,LCR_BLOCK_MATERIAL_ICE,0),
LCR_MAP_BLOCK(LCR_BLOCK_CUBOID_FILL,10,1,15,0,0),

14
map.h
View file

@ -516,6 +516,20 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform,
switch (blockType)
{
case LCR_BLOCK_CHECKPOINT_0:
case LCR_BLOCK_CHECKPOINT_1:
ADD(3,0,3) ADD(6,2,0) ADD(0,2,0)
ADD(3,0,3) ADD(6,2,6) ADD(6,2,0)
ADD(3,0,3) ADD(0,2,0) ADD(0,2,6)
ADD(3,0,3) ADD(0,2,6) ADD(6,2,6)
ADD(3,4,3) ADD(0,2,0) ADD(6,2,0)
ADD(3,4,3) ADD(6,2,0) ADD(6,2,6)
ADD(3,4,3) ADD(0,2,6) ADD(0,2,0)
ADD(3,4,3) ADD(6,2,6) ADD(0,2,6)
break;
case LCR_BLOCK_FULL:
case LCR_BLOCK_BOTTOM:
case LCR_BLOCK_LEFT:

View file

@ -35,6 +35,17 @@
kinda hotfixes it -- later try to discover source of this bug. TODO */
#define _LCR_MAP_MODEL_SCALE 1034
#define LCR_RENDERER_MAT_CP0 0x0f
#define LCR_RENDERER_MAT_CP1 0x0e
#define LCR_RENDERER_MAT_FIN 0x0d
struct
{
S3L_Scene scene;
@ -128,7 +139,6 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel)
else if (pixel->modelIndex == 8)
{
// car model
LCR_loadImage(LCR_IMAGE_CAR);
for (int i = 0; i < 6; ++i)
@ -156,56 +166,75 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel)
pixel->modelIndex]];
uint8_t type = triData[pixel->triangleIndex] >> 4;
uint8_t mat = triData[pixel->triangleIndex] & 0x0f;
LCR_loadImage(triData[pixel->triangleIndex] & 0x0f);
if (type == 0) // floor?
switch (mat)
{
if (v[0][1] != v[1][1] || v[1][1] != v[2][1]) // angled floor?
LCR_imageChangeBrightness(1);
case LCR_RENDERER_MAT_CP0:
LCR_renderer.flatAndTransparent = LCR_SETTING_CHECKPOINT0_COLOR;
break;
for (int i = 0; i < 6; ++i)
LCR_renderer.triUVs[i] = ((
(v[i / 2][(i % 2) * 2]) *
LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT);
}
else
{
if (type == 1)
LCR_imageChangeBrightness(0);
case LCR_RENDERER_MAT_CP1:
LCR_renderer.flatAndTransparent = LCR_SETTING_CHECKPOINT1_COLOR;
break;
for (int i = 0; i < 6; ++i)
{
LCR_renderer.triUVs[i] = ((
(v[i / 2][i % 2 ? 1 : (type == 1 ? 2 : 0)]) *
LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT);
case LCR_RENDERER_MAT_FIN:
LCR_renderer.flatAndTransparent = LCR_SETTING_FINISH_COLOR;
break;
if (i % 2)
LCR_renderer.triUVs[i] = LCR_IMAGE_SIZE -
LCR_renderer.triUVs[i];
}
default:
LCR_loadImage(mat);
if (type == 0) // floor?
{
if (v[0][1] != v[1][1] || v[1][1] != v[2][1]) // angled floor?
LCR_imageChangeBrightness(1);
for (int i = 0; i < 6; ++i)
LCR_renderer.triUVs[i] = ((
(v[i / 2][(i % 2) * 2]) *
LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT);
}
else
{
if (type == 1)
LCR_imageChangeBrightness(0);
for (int i = 0; i < 6; ++i)
{
LCR_renderer.triUVs[i] = ((
(v[i / 2][i % 2 ? 1 : (type == 1 ? 2 : 0)]) *
LCR_IMAGE_SIZE) / LCR_RENDERER_UNIT);
if (i % 2)
LCR_renderer.triUVs[i] = LCR_IMAGE_SIZE -
LCR_renderer.triUVs[i];
}
}
// shift the UVs to the origin (prevent high values of UV coords)
for (int i = 0; i < 2; ++i)
{
uint8_t minCoord = LCR_renderer.triUVs[i] <
LCR_renderer.triUVs[2 + i] ? (0 + i) : (2 + i);
if (LCR_renderer.triUVs[4 + i] < LCR_renderer.triUVs[minCoord])
minCoord = 4 + i;
S3L_Unit shiftBy = LCR_renderer.triUVs[minCoord] % LCR_IMAGE_SIZE;
if (shiftBy < 0)
shiftBy += LCR_IMAGE_SIZE;
shiftBy -= LCR_renderer.triUVs[minCoord];
LCR_renderer.triUVs[i] += shiftBy;
LCR_renderer.triUVs[2 + i] += shiftBy;
LCR_renderer.triUVs[4 + i] += shiftBy;
}
break;
}
// shift the UVs to the origin (prevent high values of UV coords)
for (int i = 0; i < 2; ++i)
{
uint8_t minCoord = LCR_renderer.triUVs[i] <
LCR_renderer.triUVs[2 + i] ? (0 + i) : (2 + i);
if (LCR_renderer.triUVs[4 + i] < LCR_renderer.triUVs[minCoord])
minCoord = 4 + i;
S3L_Unit shiftBy = LCR_renderer.triUVs[minCoord] % LCR_IMAGE_SIZE;
if (shiftBy < 0)
shiftBy += LCR_IMAGE_SIZE;
shiftBy -= LCR_renderer.triUVs[minCoord];
LCR_renderer.triUVs[i] += shiftBy;
LCR_renderer.triUVs[2 + i] += shiftBy;
LCR_renderer.triUVs[4 + i] += shiftBy;
}
}
}
@ -680,52 +709,62 @@ uint8_t _LCR_buildMapModel(void)
// don't add triangles completely at the floor or ceiling of the map
if (!edgeBits)
{
uint8_t triData;
if (blockType == LCR_BLOCK_CHECKPOINT_0)
triData = LCR_RENDERER_MAT_CP0;
else if (blockType == LCR_BLOCK_FINISH)
triData = LCR_RENDERER_MAT_FIN;
else
{
uint8_t blockMat = LCR_mapBlockGetMaterial(block);
#define VERT(n,c) LCR_renderer.mapVerts[3 * n + c]
uint8_t blockMat = LCR_mapBlockGetMaterial(block);
uint8_t triData =
(((VERT(triIndices[0],0) == VERT(triIndices[1],0)) &&
(VERT(triIndices[1],0) == VERT(triIndices[2],0))) << 4) |
(((VERT(triIndices[0],2) == VERT(triIndices[1],2)) &&
(VERT(triIndices[1],2) == VERT(triIndices[2],2))) << 5);
triData =
(((VERT(triIndices[0],0) == VERT(triIndices[1],0)) &&
(VERT(triIndices[1],0) == VERT(triIndices[2],0))) << 4) |
(((VERT(triIndices[0],2) == VERT(triIndices[1],2)) &&
(VERT(triIndices[1],2) == VERT(triIndices[2],2))) << 5);
#undef VERT
if (triData & 0xf0) // wall?
{
triData |=
((blockMat == LCR_BLOCK_MATERIAL_CONCRETE) ||
(blockMat == LCR_BLOCK_MATERIAL_ICE) ||
(blockType == LCR_BLOCK_FULL_ACCEL) ||
(blockType == LCR_BLOCK_FULL_FAN)) ?
LCR_IMAGE_WALL_CONCRETE : LCR_IMAGE_WALL_WOOD;
}
else
{ // TODO: tidy this mess?
if (blockType == LCR_BLOCK_FULL_ACCEL)
triData |= LCR_IMAGE_GROUND_ACCEL;
else if (blockType == LCR_BLOCK_FULL_FAN)
triData |= LCR_IMAGE_GROUND_FAN;
if (triData & 0xf0) // wall?
{
triData |=
((blockMat == LCR_BLOCK_MATERIAL_CONCRETE) ||
(blockMat == LCR_BLOCK_MATERIAL_ICE) ||
(blockType == LCR_BLOCK_FULL_ACCEL) ||
(blockType == LCR_BLOCK_FULL_FAN)) ?
LCR_IMAGE_WALL_CONCRETE : LCR_IMAGE_WALL_WOOD;
}
else
switch (blockMat)
{
case LCR_BLOCK_MATERIAL_CONCRETE:
triData |= LCR_IMAGE_GROUND_CONCRETE;
break;
{ // TODO: tidy this mess?
if (blockType == LCR_BLOCK_FULL_ACCEL)
triData |= LCR_IMAGE_GROUND_ACCEL;
else if (blockType == LCR_BLOCK_FULL_FAN)
triData |= LCR_IMAGE_GROUND_FAN;
else
switch (blockMat)
{
case LCR_BLOCK_MATERIAL_CONCRETE:
triData |= LCR_IMAGE_GROUND_CONCRETE;
break;
case LCR_BLOCK_MATERIAL_GRASS:
triData |= LCR_IMAGE_GROUND_GRASS;
break;
case LCR_BLOCK_MATERIAL_GRASS:
triData |= LCR_IMAGE_GROUND_GRASS;
break;
case LCR_BLOCK_MATERIAL_DIRT:
triData |= LCR_IMAGE_GROUND_DIRT;
break;
case LCR_BLOCK_MATERIAL_DIRT:
triData |= LCR_IMAGE_GROUND_DIRT;
break;
case LCR_BLOCK_MATERIAL_ICE:
triData |= LCR_IMAGE_GROUND_ICE;
break;
case LCR_BLOCK_MATERIAL_ICE:
triData |= LCR_IMAGE_GROUND_ICE;
break;
default:
break;
}
default:
break;
}
}
}
_LCR_rendererAddMapTri(triIndices[0],triIndices[1],triIndices[2],

View file

@ -126,6 +126,21 @@
#define LCR_SETTING_GHOST_COLOR 0xff00
#endif
#ifndef LCR_SETTING_CHECKPOINT0_COLOR
/** Color of untaken checkpoint (in RGB565). */
#define LCR_SETTING_CHECKPOINT0_COLOR 0x0f00
#endif
#ifndef LCR_SETTING_CHECKPOINT1_COLOR
/** Color of taken checkpoint (in RGB565). */
#define LCR_SETTING_CHECKPOINT1_COLOR 0xf000
#endif
#ifndef LCR_SETTING_FINISH_COLOR
/** Color of finish block (in RGB565). */
#define LCR_SETTING_FINISH_COLOR 0x00f0
#endif
#ifndef LCR_SETTING_SMOOTH_ANIMATIONS
/** Whether to smooth out animations (car physics, camera movement etc.). */
#define LCR_SETTING_SMOOTH_ANIMATIONS 1