diff --git a/TODO.txt b/TODO.txt index 813113a..c422146 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,6 +1,7 @@ =========== GENERAL ============== - fix the ramp map again due to new physics +- should drifting make a sound? - keyboard ghosting is an issue, particularly when initiating drift with brake (arrow keys must be used with S for braking for left drift to work) -- think about what to do about this? or leave as is? @@ -63,7 +64,7 @@ - After adding the non-rotating physics feature, the car now gets funny when turned on the roof, once even shot to the ceiling of the map. - Managed to get the car stuck in non-rotating state, then after a while get - it back by crashing. + it back by crashing. MAY BE FIXED NOW, watch if it still happens - immediately after starting the map countdown seems to be lower (seems to perhaps be caused by nextPhysicsFrameTime, look into it) diff --git a/assets.h b/assets.h index 3607369..a54c429 100644 --- a/assets.h +++ b/assets.h @@ -7027,6 +7027,10 @@ void LCR_loadImage(unsigned int index) LCR_currentImage.palette[i] = *LCR_currentImage.image; LCR_currentImage.image++; LCR_currentImage.palette[i] |= ((uint16_t) (*LCR_currentImage.image)) << 8; + + LCR_currentImage.palette[i] = + LCR_CONVERT_COLOR(LCR_currentImage.palette[i]); + LCR_currentImage.image++; } @@ -7042,11 +7046,20 @@ void LCR_imageChangeBrightness(int up) { if (up) for (int i = 0; i < 256; ++i) - LCR_currentImage.palette[i] |= 0x18e3; + LCR_currentImage.palette[i] |= +#if LCR_SETTING_332_COLOR + 0x0024; +#else + 0x18e3; +#endif else for (int i = 0; i < 256; ++i) LCR_currentImage.palette[i] = +#if LCR_SETTING_332_COLOR + LCR_currentImage.palette[i] & 0x00db; +#else ((LCR_currentImage.palette[i] >> 1) & 0x7bef); +#endif } /** diff --git a/data b/data index d6de95e..71ffd2e 100644 --- a/data +++ b/data @@ -135,3 +135,12 @@ details #RLC1;00LC1;8bd6e314 0000455:0011:0169:0041:00a9:0031:0049:00a1:0059:0051:0059:0031:01e9:0071:0045:0039:00e1:0019:00d1:0079:0041:0049:0021:0049:0031:0039:0031:0069:0071:0029:0041:00c3:0041:00e9:0021:0145:0041:0253:01b1:00b3:0051:00a9:0071:0073:0031:00a3:0021:03b3:0031:00a9:0021:0073:0021 #RLCtiny5;00LCtiny5;5c14d8b6 0000306:00a1:0083:0041:0019:0051:0049:0041:0029:00a1:00c9:0051:0073:00e1:0019:00e1:0013:0211:0049:0051:0033:0051:0039:00c1:0023:00f1:0049:0041:0033:0071:0013:0041:0053:0061:0093:0041:0043:0041:0175:0041:00a3:0041:00b9:0021 #BLCtiny5; +#RLC3;00LC3;cb1b38e6 0000557:0011:00e9:0041:0043:0041:0110:0024:01d5:0021:0203:00b1:0113:0021:0063:0061:00d3:0041:00a3:0051:00d3:0021:0129:00b1:0123:0031:0039:0031:0023:0051:00d3:0031:0033:0061:0073:0061:01e3:00a1:00f3:00a1:00e5:0041:0039:0101:0093:0091:00b3:0051:0633:0031:0093:0031 +#BLC3; +#RLCtiny2;00LCtiny2;833ee4b2 0000185:01f1:0070:0081:02d0:0114 +#BLCtiny2; +#RLCtiny2;00LCtiny2;833ee4b2 0000174 +#RLCtiny2;00LCtiny2;833ee4b2 0000174 +#RLCtiny4;00LCtiny4;1787f12a 0000267:0221:0093:0091:00b3:0041:0033:0031:0043:0041:0033:0051:0063:01e2:00a3:00d1:0065:0059:0051:0043:0031:0063:00e1:0163:0031 +#BLCtiny4; +#RLCtiny4;00LCtiny4;1787f12a 0000184:0011:00c9:0071:0133:0051:0073:00e1:0033:00f1:0053:00a1:0063:0071:0123:0041 diff --git a/frontend_sdl.c b/frontend_sdl.c index 2b91c7c..1a396c7 100644 --- a/frontend_sdl.c +++ b/frontend_sdl.c @@ -18,7 +18,12 @@ SDL_Renderer *renderer; SDL_Texture *texture; SDL_Surface *screenSurface; -uint16_t screen[LCR_SETTING_RESOLUTION_X * LCR_SETTING_RESOLUTION_Y]; +#if LCR_SETTING_332_COLOR +uint8_t +#else +uint16_t +#endif +screen[LCR_SETTING_RESOLUTION_X * LCR_SETTING_RESOLUTION_Y]; FILE *musicFile = 0; FILE *dataFile = 0; @@ -208,7 +213,13 @@ int main(int argc, char *argv[]) } texture = - SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB565,SDL_TEXTUREACCESS_STATIC, + SDL_CreateTexture(renderer, +#if LCR_SETTING_332_COLOR + SDL_PIXELFORMAT_RGB332, +#else + SDL_PIXELFORMAT_RGB565, +#endif + SDL_TEXTUREACCESS_STATIC, LCR_SETTING_RESOLUTION_X,LCR_SETTING_RESOLUTION_Y); if (!texture) @@ -241,7 +252,13 @@ int main(int argc, char *argv[]) running &= LCR_gameStep(SDL_GetTicks()); SDL_UpdateTexture(texture,NULL,screen, - LCR_SETTING_RESOLUTION_X * sizeof(uint16_t)); + LCR_SETTING_RESOLUTION_X * sizeof( +#if LCR_SETTING_332_COLOR + uint8_t +#else + uint16_t +#endif + )); SDL_RenderClear(renderer); SDL_RenderCopy(renderer,texture,NULL,NULL); diff --git a/game.h b/game.h index bc89ed8..223fd61 100644 --- a/game.h +++ b/game.h @@ -441,7 +441,8 @@ void _LCR_physicdDebugDrawPixel(uint16_t x, uint16_t y, uint8_t color) if (x > 1 && x < LCR_EFFECTIVE_RESOLUTION_X - 2 && y > 1 && y < LCR_EFFECTIVE_RESOLUTION_Y - 2) { - uint16_t c = 0x8101 | (0x8f1f << (2 * color)); + uint16_t c = LCR_CONVERT_COLOR(0x8101) | + (LCR_CONVERT_COLOR(0x8f1f) << (2 * color)); for (int j = -1; j <= 2; ++j) for (int i = -1; i <= 2; ++i) @@ -1204,10 +1205,11 @@ void LCR_gameDrawPopupMessage(void) int textW = LCR_rendererComputeTextWidth(LCR_game.popupStr,_TEXT_SIZE); LCR_rendererDrawRect((LCR_EFFECTIVE_RESOLUTION_X - textW - 2 * LCR_GUI_GAP) - / 2,_OFFSET_V,textW + 2 * LCR_GUI_GAP,textH + 2 * LCR_GUI_GAP,0xffff,1); + / 2,_OFFSET_V,textW + 2 * LCR_GUI_GAP,textH + 2 * LCR_GUI_GAP, + LCR_CONVERT_COLOR(0xffff),1); LCR_rendererDrawText(LCR_game.popupStr,(LCR_EFFECTIVE_RESOLUTION_X - textW) - / 2,_OFFSET_V + LCR_GUI_GAP,0x0300,_TEXT_SIZE); + / 2,_OFFSET_V + LCR_GUI_GAP,LCR_CONVERT_COLOR(0x0300),_TEXT_SIZE); #undef _OFFSET_V #undef _TEXT_SIZE @@ -1287,12 +1289,13 @@ void LCR_gameDraw3DView(void) LCR_rendererComputeTextWidth(str,4)) / 2), LCR_EFFECTIVE_RESOLUTION_Y / 2, LCR_game.runTime <= LCR_currentMap.targetTime ? - 0x0700 : 0x4208,4); + LCR_CONVERT_COLOR(0x0700) : LCR_CONVERT_COLOR(0x4208),4); LCR_gameTimeToStr(LCR_currentMap.targetTime * LCR_RACING_TICK_MS,str); LCR_rendererDrawText(str,LCR_GUI_GAP,LCR_EFFECTIVE_RESOLUTION_Y - - LCR_rendererComputeTextHeight(2) - LCR_GUI_GAP,0x4208,2); + LCR_rendererComputeTextHeight(2) - LCR_GUI_GAP, + LCR_CONVERT_COLOR(0x4208),2); break; } @@ -1627,11 +1630,14 @@ uint8_t LCR_gameStep(uint32_t time) if (LCR_racingGetCarSpeedUnsigned() > 60) { if (LCR_racingCurrentGroundMaterial() == LCR_BLOCK_MATERIAL_GRASS) - LCR_rendererSetParticles(0x538a); + LCR_rendererSetParticles( + LCR_CONVERT_COLOR(LCR_SETTING_PARTICLE_COLOR_GRASS)); else if (LCR_racingCurrentGroundMaterial() == LCR_BLOCK_MATERIAL_DIRT) - LCR_rendererSetParticles(0x8c2b); + LCR_rendererSetParticles( + LCR_CONVERT_COLOR(LCR_SETTING_PARTICLE_COLOR_DIRT)); else if (LCR_racingCarIsDrifting()) - LCR_rendererSetParticles(0x4208); + LCR_rendererSetParticles( + LCR_CONVERT_COLOR(LCR_SETTING_PARTICLE_COLOR_DRIFT)); } #endif diff --git a/general.h b/general.h index c376856..79ba370 100644 --- a/general.h +++ b/general.h @@ -27,6 +27,13 @@ #define LCR_RACING_TICK_MS \ (100000 / (LCR_RACING_FPS * LCR_SETTING_TIME_MULTIPLIER)) +#if LCR_SETTING_332_COLOR + #define LCR_CONVERT_COLOR(c) \ + (((c & 0xe000) >> 8) | ((c & 0x0700) >> 6) | ((c & 0x001f) >> 3)) +#else + #define LCR_CONVERT_COLOR(c) c +#endif + char _LCR_hexDigit(int i) { return i < 10 ? '0' + i : ('a' - 10 + i); diff --git a/racing.h b/racing.h index 6d253b9..17fa27b 100644 --- a/racing.h +++ b/racing.h @@ -58,7 +58,7 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit #define LCR_PHYSICS_UNIT 4096 ///< len. of square for phys. engine #define TPE_RESHAPE_TENSION_LIMIT 3 -#define TPE_RESHAPE_ITERATIONS 3 /**< Empirically tested, seems to have a +#define TPE_RESHAPE_ITERATIONS 7 /**< Empirically tested, seems to have a big impact on bugs that happen when driving onto a curved ramp under various angles. */ @@ -1444,7 +1444,12 @@ uint32_t LCR_racingStep(unsigned int input) TPE_Joint joints[LCR_CAR_JOINTS]; - LCR_racing.carBody.flags |= TPE_BODY_FLAG_NONROTATING; + if (_LCR_racingCarShapeOK()) // in rare cases this may not hold + LCR_racing.carBody.flags |= TPE_BODY_FLAG_NONROTATING; + else + { + LCR_LOG1("car not OK in non-rotating step"); + } for (int i = 0; i < LCR_CAR_JOINTS; ++i) joints[i] = LCR_racing.carBody.joints[i]; @@ -1459,7 +1464,7 @@ uint32_t LCR_racingStep(unsigned int input) } LCR_racing.carBody.flags &= ~TPE_BODY_FLAG_NONROTATING; - + TPE_worldStep(&(LCR_racing.physicsWorld)); // normal step if ((LCR_racing.carBody.flags & TPE_BODY_FLAG_UNRESOLVED) || diff --git a/renderer.h b/renderer.h index a9c28d2..ea90ab2 100644 --- a/renderer.h +++ b/renderer.h @@ -328,6 +328,11 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel) // alter each triangle's color slightly: LCR_renderer.flatAndTransparent += pixel->triangleIndex % 4; + +#if LCR_SETTING_332_COLOR + LCR_renderer.flatAndTransparent = + LCR_CONVERT_COLOR(LCR_renderer.flatAndTransparent); +#endif } LCR_gameDrawPixelXYUnsafe(pixel->x,pixel->y,LCR_renderer.flatAndTransparent); @@ -359,6 +364,7 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel) #if (LCR_SETTING_CAR_TINT & 0x7) != 0x07 for (int i = 0; i < 256; ++i) + { LCR_currentImage.palette[i] &= #if LCR_SETTING_CAR_TINT & 0x01 0x001f | @@ -375,7 +381,12 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel) #else 0x1800 #endif - ; + ; +#if LCR_SETTING_332_COLOR + LCR_currentImage.palette[i] = + LCR_CONVERT_COLOR(LCR_currentImage.palette[i]); +#endif + } #endif } else @@ -399,14 +410,20 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel) #define CL (type ? 0x8210 : 0x0000) case LCR_RENDERER_MAT_CP0: LCR_renderer.flatAndTransparent = LCR_SETTING_CHECKPOINT_0_COLOR | CL; + LCR_renderer.flatAndTransparent = + LCR_CONVERT_COLOR(LCR_renderer.flatAndTransparent); break; case LCR_RENDERER_MAT_CP1: LCR_renderer.flatAndTransparent = LCR_SETTING_CHECKPOINT_1_COLOR | CL; + LCR_renderer.flatAndTransparent = + LCR_CONVERT_COLOR(LCR_renderer.flatAndTransparent); break; case LCR_RENDERER_MAT_FIN: LCR_renderer.flatAndTransparent = LCR_SETTING_FINISH_COLOR | CL; + LCR_renderer.flatAndTransparent = + LCR_CONVERT_COLOR(LCR_renderer.flatAndTransparent); break; #undef CL @@ -1410,7 +1427,7 @@ void LCR_rendererDrawSky(int sky, S3L_Unit offsetH, S3L_Unit offsetV) #if LCR_SETTING_POTATO_GRAPHICS LCR_rendererDrawRect(0,0,LCR_EFFECTIVE_RESOLUTION_X, - LCR_EFFECTIVE_RESOLUTION_Y,0x7bfd,0); + LCR_EFFECTIVE_RESOLUTION_Y,LCR_CONVERT_COLOR(0xffff),0); #else int anchorPoint[2], y; unsigned long pixelIndex; @@ -1870,8 +1887,8 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items, while (i < stripHeight * LCR_EFFECTIVE_RESOLUTION_X) { - LCR_gameDrawPixel(i,0x4a8c -#if LCR_SETTING_POTATO_GRAPHICS + LCR_gameDrawPixel(i,LCR_CONVERT_COLOR(0x4a8c) +#if LCR_SETTING_POTATO_GRAPHICS || LCR_SETTING_332_COLOR ); #else ^ (effect & 0x41c3)); @@ -1885,7 +1902,7 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items, #if LCR_SETTING_POTATO_GRAPHICS while (i < stripHeight * LCR_EFFECTIVE_RESOLUTION_X) { - LCR_gameDrawPixel(i,0x73ae); + LCR_gameDrawPixel(i,LCR_CONVERT_COLOR(0x73ae)); ++i; } #else @@ -1898,7 +1915,8 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items, { LCR_gameDrawPixel(i,(x > LCR_EFFECTIVE_RESOLUTION_X / 4 - limit && (x < LCR_EFFECTIVE_RESOLUTION_X - LCR_EFFECTIVE_RESOLUTION_X / 4 + limit) - ? 0x73ae : 0x31a6) + ((x + y) % 8)); + ? LCR_CONVERT_COLOR(0x73ae) : LCR_CONVERT_COLOR(0x31a6)) + + ((x + y) % 8)); i++; } } @@ -1906,11 +1924,11 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items, while (i < LCR_EFFECTIVE_RESOLUTION_Y * LCR_EFFECTIVE_RESOLUTION_X) { - LCR_gameDrawPixel(i,0xce9c + LCR_gameDrawPixel(i,LCR_CONVERT_COLOR(0xce9c) #if LCR_SETTING_POTATO_GRAPHICS ); #else - + (i & 0x1002)); + + (i & LCR_CONVERT_COLOR(0x1002))); #endif ++i; @@ -1922,12 +1940,12 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items, { const char *s = j ? (j <= itemCount ? items[j - 1] : "...") : tabName; const char *s2 = s; - uint16_t textColor = 0x5aeb; + uint16_t textColor = LCR_CONVERT_COLOR(0x5aeb); while (*s2) // if the item contains '#' (check), we draw it as green { if (*s2 == '#') - textColor = 0x0700; + textColor = LCR_CONVERT_COLOR(0x0700); s2++; } @@ -1944,7 +1962,8 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items, LCR_rendererDrawText(s,(LCR_EFFECTIVE_RESOLUTION_X - LCR_rendererComputeTextWidth(s,_FONT_SIZE)) / 2,i, - (j == 0 || j == selectedItem + 1) ? 0xf79c : textColor,_FONT_SIZE); + (j == 0 || j == selectedItem + 1) ? LCR_CONVERT_COLOR(0xf79c) : + textColor,_FONT_SIZE); if (j == 0) i = stripHeight + stripHeight2; @@ -1958,11 +1977,12 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items, #if !LCR_SETTING_POTATO_GRAPHICS LCR_rendererBlitImage(21,(LCR_EFFECTIVE_RESOLUTION_X - LCR_IMAGE_SIZE * (stripHeight / LCR_IMAGE_SIZE)) / 2,0, - stripHeight / LCR_IMAGE_SIZE,0xffff); + stripHeight / LCR_IMAGE_SIZE,LCR_CONVERT_COLOR(0xffff)); #endif LCR_rendererDrawText(LCR_texts[LCR_TEXTS_VERSION], - LCR_EFFECTIVE_RESOLUTION_X / 64,LCR_EFFECTIVE_RESOLUTION_Y / 64,0xe71c,2); + LCR_EFFECTIVE_RESOLUTION_X / 64,LCR_EFFECTIVE_RESOLUTION_Y / 64, + LCR_CONVERT_COLOR(0xe71c),2); LCR_renderer.frame++; } diff --git a/settings.h b/settings.h index 39cdf70..33da949 100644 --- a/settings.h +++ b/settings.h @@ -167,6 +167,12 @@ #define LCR_SETTING_POTATO_GRAPHICS 0 #endif +#ifndef LCR_SETTING_332_COLOR + /** If turned on, pixel colors will be converted to RGB332 format from the + default RGB565 (so that only the lower byte of a color is significant). */ + #define LCR_SETTING_332_COLOR 0 +#endif + #ifndef LCR_SETTING_MUSIC /** Whether to enable in game music. */ #define LCR_SETTING_MUSIC 1 @@ -246,6 +252,21 @@ #define LCR_SETTING_PARTICLES 1 #endif +#ifndef LCR_SETTING_PARTICLE_COLOR_DRIFT + /** Color of drifting particle effect. */ + #define LCR_SETTING_PARTICLE_COLOR_DRIFT 0x4208 +#endif + +#ifndef LCR_SETTING_PARTICLE_COLOR_GRASS + /** Color of grass particle effect. */ + #define LCR_SETTING_PARTICLE_COLOR_GRASS 0x5467 +#endif + +#ifndef LCR_SETTING_PARTICLE_COLOR_DIRT + /** Color of dirt particle effect. */ + #define LCR_SETTING_PARTICLE_COLOR_DIRT 0x8b84 +#endif + #ifndef LCR_SETTING_ONLY_SMALL_MAPS /** Turning this on will only include the small maps in the internal data file. This option exists for weak devices that couldn't handle big maps