diff --git a/TODO.txt b/TODO.txt index 0d324f9..f9c38fa 100644 --- a/TODO.txt +++ b/TODO.txt @@ -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: diff --git a/assets.h b/assets.h index 13378b0..92dc1c7 100644 --- a/assets.h +++ b/assets.h @@ -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), diff --git a/map.h b/map.h index 0576346..5eae974 100644 --- a/map.h +++ b/map.h @@ -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: diff --git a/renderer.h b/renderer.h index 9779d00..09f9c0f 100644 --- a/renderer.h +++ b/renderer.h @@ -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; - } } } @@ -213,7 +242,7 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel) { if (pixel->x % 2 == pixel->y % 2) LCR_drawPixelXYUnsafe(pixel->x,pixel->y,LCR_renderer.flatAndTransparent); - + return; } @@ -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], diff --git a/settings.h b/settings.h index 6afad11..071d217 100644 --- a/settings.h +++ b/settings.h @@ -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