Add resolution subdivision

This commit is contained in:
Miloslav Ciz 2025-02-02 01:21:02 +01:00
parent ccbb9dfdc3
commit e47704dbb0
3 changed files with 62 additions and 39 deletions

View file

@ -1,5 +1,6 @@
=========== GENERAL ============== =========== GENERAL ==============
- bug: background horizon position depends on resolution! fix
- make a small txt game menual - make a small txt game menual
- test: - test:
- long replay - long replay

62
game.h
View file

@ -52,12 +52,12 @@
format (described in the map module) etc. format (described in the map module) etc.
*/ */
#define LCR_KEY_UP 0x00 #define LCR_KEY_UP 0x00
#define LCR_KEY_RIGHT 0x01 #define LCR_KEY_RIGHT 0x01
#define LCR_KEY_DOWN 0x02 #define LCR_KEY_DOWN 0x02
#define LCR_KEY_LEFT 0x03 #define LCR_KEY_LEFT 0x03
#define LCR_KEY_A 0x04 ///< confirm, restart race #define LCR_KEY_A 0x04 ///< confirm, restart race
#define LCR_KEY_B 0x05 ///< cancel, open menu #define LCR_KEY_B 0x05 ///< cancel, open menu
#define LCR_KEYS_TOTAL 6 #define LCR_KEYS_TOTAL 6
@ -201,19 +201,26 @@ uint8_t LCR_gameGetNextAudioSample(void);
// forward decls of pixel drawing functions for the renderer // forward decls of pixel drawing functions for the renderer
/**
Internal function for drawing pixels, takes into account setting etc., should
be used instead of directly calling LCR_drawPixel.
*/
static inline void LCR_gameDrawPixel(unsigned long index, uint16_t color);
/** /**
Internal pixel drawing function that puts a pixel at specified screen coords Internal pixel drawing function that puts a pixel at specified screen coords
without checking for safety (it's faster but can only be done if we know for without checking for safety (it's faster but can only be done if we know for
sure we're not drawing outside the screen). sure we're not drawing outside the screen).
*/ */
void LCR_drawPixelXYUnsafe(unsigned int x, unsigned int y, uint16_t color); static inline void LCR_gameDrawPixelXYUnsafe(unsigned int x, unsigned int y,
uint16_t color);
/** /**
Internal pixel drawing function that checks for out-of-screen coordinates. Use Internal pixel drawing function that checks for out-of-screen coordinates. Use
this if the pixel can potentially lie of screen (however if you know it won't, this if the pixel can potentially lie of screen (however if you know it won't,
use the normal unsafe function in sake of performance). use the normal unsafe function in sake of performance).
*/ */
static inline void LCR_drawPixelXYSafe(unsigned int x, unsigned int y, static inline void LCR_gameDrawPixelXYSafe(unsigned int x, unsigned int y,
uint_fast16_t color); uint_fast16_t color);
#include "general.h" #include "general.h"
@ -311,14 +318,32 @@ uint8_t LCR_gameMusicOn(void)
#endif #endif
} }
void LCR_drawPixelXYUnsafe(unsigned int x, unsigned int y, void LCR_gameDrawPixel(unsigned long index, uint16_t color)
{
#if LCR_SETTING_RESOLUTION_SUBDIVIDE <= 1
LCR_drawPixel(index,color);
#else
index = ((index / LCR_EFFECTIVE_RESOLUTION_X) * LCR_SETTING_RESOLUTION_X +
(index % LCR_EFFECTIVE_RESOLUTION_X)) * LCR_SETTING_RESOLUTION_SUBDIVIDE;
for (int y = 0; y < LCR_SETTING_RESOLUTION_SUBDIVIDE; ++y)
{
for (int x = 0; x < LCR_SETTING_RESOLUTION_SUBDIVIDE; ++x)
{
LCR_drawPixel(index,color);
index++;
}
index += LCR_SETTING_RESOLUTION_X - LCR_SETTING_RESOLUTION_SUBDIVIDE;
}
#endif
}
void LCR_gameDrawPixelXYUnsafe(unsigned int x, unsigned int y,
uint16_t color) uint16_t color)
{ {
#if LCR_SETTING_RESOLUTION_SUBDIVIDE == 1 LCR_gameDrawPixel(y * LCR_EFFECTIVE_RESOLUTION_X + x,color);
LCR_drawPixel(y * LCR_SETTING_RESOLUTION_X + x,color);
#else
// TODO
#endif
} }
void _LCR_physicdDebugDrawPixel(uint16_t x, uint16_t y, uint8_t color) void _LCR_physicdDebugDrawPixel(uint16_t x, uint16_t y, uint8_t color)
@ -330,15 +355,15 @@ void _LCR_physicdDebugDrawPixel(uint16_t x, uint16_t y, uint8_t color)
for (int j = -1; j <= 2; ++j) for (int j = -1; j <= 2; ++j)
for (int i = -1; i <= 2; ++i) for (int i = -1; i <= 2; ++i)
LCR_drawPixelXYUnsafe(x + i,y + j,c); LCR_gameDrawPixelXYUnsafe(x + i,y + j,c);
} }
} }
static inline void LCR_drawPixelXYSafe(unsigned int x, unsigned int y, static inline void LCR_gameDrawPixelXYSafe(unsigned int x, unsigned int y,
uint_fast16_t color) uint_fast16_t color)
{ {
if (x < LCR_EFFECTIVE_RESOLUTION_X && y < LCR_EFFECTIVE_RESOLUTION_Y) if (x < LCR_EFFECTIVE_RESOLUTION_X && y < LCR_EFFECTIVE_RESOLUTION_Y)
LCR_drawPixelXYUnsafe(x,y,color); LCR_gameDrawPixelXYUnsafe(x,y,color);
} }
void LCR_gameSetState(uint8_t state) void LCR_gameSetState(uint8_t state)
@ -969,9 +994,6 @@ void LCR_checkBeatenMaps(void)
} }
} }
void LCR_gameEnd(void) void LCR_gameEnd(void)
{ {
LCR_LOG0("ending"); LCR_LOG0("ending");

View file

@ -19,8 +19,8 @@
for far away areas with "something" we just draw some 2D rectangles. for far away areas with "something" we just draw some 2D rectangles.
*/ */
#define S3L_RESOLUTION_X LCR_SETTING_RESOLUTION_X #define S3L_RESOLUTION_X LCR_EFFECTIVE_RESOLUTION_X
#define S3L_RESOLUTION_Y LCR_SETTING_RESOLUTION_Y #define S3L_RESOLUTION_Y LCR_EFFECTIVE_RESOLUTION_Y
#define S3L_PIXEL_FUNCTION _LCR_pixelFunc3D #define S3L_PIXEL_FUNCTION _LCR_pixelFunc3D
#define S3L_PERSPECTIVE_CORRECTION 2 #define S3L_PERSPECTIVE_CORRECTION 2
#define S3L_NEAR_CROSS_STRATEGY 1 #define S3L_NEAR_CROSS_STRATEGY 1
@ -160,14 +160,14 @@ void LCR_rendererSetGhostVisibility(uint8_t visible)
void _LCR_rendererDrawFontPixel(int x, int y, uint16_t color) void _LCR_rendererDrawFontPixel(int x, int y, uint16_t color)
{ {
#if LCR_FONT_PIXEL_SIZE == 1 #if LCR_FONT_PIXEL_SIZE == 1
LCR_drawPixelXYSafe(x,y,color); LCR_gameDrawPixelXYSafe(x,y,color);
#else #else
if ((x >= 0) && (y >= 0) && if ((x >= 0) && (y >= 0) &&
(x < LCR_EFFECTIVE_RESOLUTION_X - LCR_FONT_PIXEL_SIZE) && (x < LCR_EFFECTIVE_RESOLUTION_X - LCR_FONT_PIXEL_SIZE) &&
(y < LCR_EFFECTIVE_RESOLUTION_Y - LCR_FONT_PIXEL_SIZE)) (y < LCR_EFFECTIVE_RESOLUTION_Y - LCR_FONT_PIXEL_SIZE))
for (int i = x; i < x + LCR_FONT_PIXEL_SIZE; ++i) for (int i = x; i < x + LCR_FONT_PIXEL_SIZE; ++i)
for (int j = y; j < y + LCR_FONT_PIXEL_SIZE; ++j) for (int j = y; j < y + LCR_FONT_PIXEL_SIZE; ++j)
LCR_drawPixelXYSafe(i,j,color); LCR_gameDrawPixelXYSafe(i,j,color);
#endif #endif
} }
@ -314,7 +314,7 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel)
LCR_renderer.flatAndTransparent += pixel->triangleIndex % 4; LCR_renderer.flatAndTransparent += pixel->triangleIndex % 4;
} }
LCR_drawPixelXYUnsafe(pixel->x,pixel->y,LCR_renderer.flatAndTransparent); LCR_gameDrawPixelXYUnsafe(pixel->x,pixel->y,LCR_renderer.flatAndTransparent);
#else // LCR_SETTING_POTATO_GRAPHICS #else // LCR_SETTING_POTATO_GRAPHICS
// once we get a new triangle, we precompute things for it: // once we get a new triangle, we precompute things for it:
@ -432,7 +432,7 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel)
if (LCR_renderer.flatAndTransparent) if (LCR_renderer.flatAndTransparent)
{ {
if (pixel->x % 2 == pixel->y % 2) if (pixel->x % 2 == pixel->y % 2)
LCR_drawPixelXYUnsafe(pixel->x,pixel->y,LCR_renderer.flatAndTransparent); LCR_gameDrawPixelXYUnsafe(pixel->x,pixel->y,LCR_renderer.flatAndTransparent);
else else
S3L_zBufferWrite(pixel->x,pixel->y,S3L_MAX_DEPTH); S3L_zBufferWrite(pixel->x,pixel->y,S3L_MAX_DEPTH);
/* ^ Clear z-buffer if we didn't draw the pixel. Without this further /* ^ Clear z-buffer if we didn't draw the pixel. Without this further
@ -470,7 +470,7 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel)
LCR_renderer.texSubsampleCount--; LCR_renderer.texSubsampleCount--;
#endif #endif
LCR_drawPixelXYUnsafe(pixel->x,pixel->y,_LCR_pixelColor); LCR_gameDrawPixelXYUnsafe(pixel->x,pixel->y,_LCR_pixelColor);
#endif // LCR_SETTING_POTATO_GRAPHICS #endif // LCR_SETTING_POTATO_GRAPHICS
} }
@ -1255,7 +1255,7 @@ void LCR_rendererDrawRect(int x, int y, unsigned int w, unsigned int h,
for (unsigned int i = 0; i < h; ++i) for (unsigned int i = 0; i < h; ++i)
{ {
for (unsigned int j = ((i % 2) == parity); j < w; j += 2) for (unsigned int j = ((i % 2) == parity); j < w; j += 2)
LCR_drawPixel(index + j,color); LCR_gameDrawPixel(index + j,color);
index += LCR_EFFECTIVE_RESOLUTION_X; index += LCR_EFFECTIVE_RESOLUTION_X;
} }
@ -1265,7 +1265,7 @@ void LCR_rendererDrawRect(int x, int y, unsigned int w, unsigned int h,
{ {
for (unsigned int j = 0; j < w; ++j) for (unsigned int j = 0; j < w; ++j)
{ {
LCR_drawPixel(index,color); LCR_gameDrawPixel(index,color);
index++; index++;
} }
@ -1366,7 +1366,7 @@ void LCR_rendererDrawSky(int sky, S3L_Unit offsetH, S3L_Unit offsetV)
{ {
for (int x = 0; x < LCR_EFFECTIVE_RESOLUTION_X; ++x) for (int x = 0; x < LCR_EFFECTIVE_RESOLUTION_X; ++x)
{ {
LCR_drawPixel(pixelIndex,topColor); LCR_gameDrawPixel(pixelIndex,topColor);
pixelIndex++; pixelIndex++;
} }
@ -1409,7 +1409,7 @@ void LCR_rendererDrawSky(int sky, S3L_Unit offsetH, S3L_Unit offsetV)
while (x < LCR_EFFECTIVE_RESOLUTION_X) while (x < LCR_EFFECTIVE_RESOLUTION_X)
{ {
LCR_drawPixel(startIndex + x,color); LCR_gameDrawPixel(startIndex + x,color);
x += 2 * LCR_IMAGE_SIZE * LCR_SETTING_SKY_SIZE; x += 2 * LCR_IMAGE_SIZE * LCR_SETTING_SKY_SIZE;
} }
} }
@ -1431,7 +1431,7 @@ void LCR_rendererDrawSky(int sky, S3L_Unit offsetH, S3L_Unit offsetV)
if (y >= 0) if (y >= 0)
for (int x = 0; x < LCR_EFFECTIVE_RESOLUTION_X; ++x) for (int x = 0; x < LCR_EFFECTIVE_RESOLUTION_X; ++x)
{ {
LCR_drawPixel(pixelIndex,topColor); LCR_gameDrawPixel(pixelIndex,topColor);
pixelIndex++; pixelIndex++;
} }
@ -1449,7 +1449,7 @@ void LCR_rendererDrawSky(int sky, S3L_Unit offsetH, S3L_Unit offsetV)
{ {
for (int x = 0; x < LCR_EFFECTIVE_RESOLUTION_X; ++x) for (int x = 0; x < LCR_EFFECTIVE_RESOLUTION_X; ++x)
{ {
LCR_drawPixel(pixelIndex,bottomColor); LCR_gameDrawPixel(pixelIndex,bottomColor);
pixelIndex++; pixelIndex++;
} }
@ -1775,7 +1775,7 @@ void LCR_rendererBlitImage(uint8_t index, unsigned int x, unsigned int y,
uint16_t color = LCR_getNextImagePixel(); uint16_t color = LCR_getNextImagePixel();
if (color != transparentColor) if (color != transparentColor)
LCR_drawPixel(i,color); LCR_gameDrawPixel(i,color);
i += scale; i += scale;
} }
@ -1795,7 +1795,7 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items,
while (i < stripHeight * LCR_EFFECTIVE_RESOLUTION_X) while (i < stripHeight * LCR_EFFECTIVE_RESOLUTION_X)
{ {
LCR_drawPixel(i,0x4a8c LCR_gameDrawPixel(i,0x4a8c
#if LCR_SETTING_POTATO_GRAPHICS #if LCR_SETTING_POTATO_GRAPHICS
); );
#else #else
@ -1811,7 +1811,7 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items,
#if LCR_SETTING_POTATO_GRAPHICS #if LCR_SETTING_POTATO_GRAPHICS
while (i < stripHeight * LCR_EFFECTIVE_RESOLUTION_X) while (i < stripHeight * LCR_EFFECTIVE_RESOLUTION_X)
{ {
LCR_drawPixel(i,0x73ae); LCR_gameDrawPixel(i,0x73ae);
++i; ++i;
} }
#else #else
@ -1822,7 +1822,7 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items,
for (int x = 0; x < LCR_EFFECTIVE_RESOLUTION_X; ++x) for (int x = 0; x < LCR_EFFECTIVE_RESOLUTION_X; ++x)
{ {
LCR_drawPixel(i,(x > LCR_EFFECTIVE_RESOLUTION_X / 4 - limit && LCR_gameDrawPixel(i,(x > LCR_EFFECTIVE_RESOLUTION_X / 4 - limit &&
(x < LCR_EFFECTIVE_RESOLUTION_X - LCR_EFFECTIVE_RESOLUTION_X / 4 + limit) (x < LCR_EFFECTIVE_RESOLUTION_X - LCR_EFFECTIVE_RESOLUTION_X / 4 + limit)
? 0x73ae : 0x31a6) + ((x + y) % 8)); ? 0x73ae : 0x31a6) + ((x + y) % 8));
i++; i++;
@ -1832,7 +1832,7 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items,
while (i < LCR_EFFECTIVE_RESOLUTION_Y * LCR_EFFECTIVE_RESOLUTION_X) while (i < LCR_EFFECTIVE_RESOLUTION_Y * LCR_EFFECTIVE_RESOLUTION_X)
{ {
LCR_drawPixel(i,0xce9c LCR_gameDrawPixel(i,0xce9c
#if LCR_SETTING_POTATO_GRAPHICS #if LCR_SETTING_POTATO_GRAPHICS
); );
#else #else
@ -1862,7 +1862,7 @@ void LCR_rendererDrawMenu(const char *tabName,const char **items,
for (int y = i - 10; y < i + LCR_rendererComputeTextHeight(3) + 10; ++y) for (int y = i - 10; y < i + LCR_rendererComputeTextHeight(3) + 10; ++y)
for (int x = LCR_EFFECTIVE_RESOLUTION_X / 4; for (int x = LCR_EFFECTIVE_RESOLUTION_X / 4;
x < LCR_EFFECTIVE_RESOLUTION_X - LCR_EFFECTIVE_RESOLUTION_X / 4; ++x) x < LCR_EFFECTIVE_RESOLUTION_X - LCR_EFFECTIVE_RESOLUTION_X / 4; ++x)
LCR_drawPixelXYSafe(x,y,0x5c1b + 4 * ((x & 0x10) == (y & 0x10))); LCR_gameDrawPixelXYSafe(x,y,0x5c1b + 4 * ((x & 0x10) == (y & 0x10)));
LCR_rendererDrawText(s,(LCR_EFFECTIVE_RESOLUTION_X - LCR_rendererDrawText(s,(LCR_EFFECTIVE_RESOLUTION_X -
LCR_rendererComputeTextWidth(s,3)) / 2,i, LCR_rendererComputeTextWidth(s,3)) / 2,i,