From 14a49b6373b1ae62fc10f75808c32c36504db72a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Fri, 4 Oct 2019 16:32:24 +0200 Subject: [PATCH] Add resolution subdivider --- main.c | 54 ++++++++++++++++++++++++++++++++++------------ platform_pokitto.h | 13 ++++++----- platform_sdl.h | 15 +++++++------ settings.h | 28 ++++++++++++++++++++++-- 4 files changed, 83 insertions(+), 27 deletions(-) diff --git a/main.c b/main.c index 3dce3e0..dda9709 100755 --- a/main.c +++ b/main.c @@ -89,6 +89,12 @@ void SFG_init(); #include "assets.h" #include "palette.h" +#define SFG_GAME_RESOLUTION_X \ + (SFG_SCREEN_RESOLUTION_X / SFG_RESOLUTION_SCALEDOWN) + +#define SFG_GAME_RESOLUTION_Y \ + (SFG_SCREEN_RESOLUTION_Y / SFG_RESOLUTION_SCALEDOWN) + #define SFG_MS_PER_FRAME (1000 / SFG_FPS) // ms per frame with target FPS #define SFG_PLAYER_TURN_UNITS_PER_FRAME\ @@ -117,7 +123,7 @@ void SFG_init(); #define SFG_CEILING_MAX_HEIGHT\ (16 * RCL_UNITS_PER_SQUARE - RCL_UNITS_PER_SQUARE / 2 ) -int8_t SFG_backgroundScaleMap[SFG_RESOLUTION_Y]; +int8_t SFG_backgroundScaleMap[SFG_GAME_RESOLUTION_Y]; uint16_t SFG_backgroundScroll; struct @@ -130,6 +136,25 @@ struct air. */ } SFG_player; + +#if SFG_RESOLUTION_SCALEDOWN == 1 + #define SFG_setGamePixel SFG_setPixel +#else +/** + Sets the game pixel (a pixel that can potentially be bigger than the screen + pixel). +*/ +static inline void SFG_setGamePixel(uint16_t x, uint16_t y, uint8_t colorIndex) +{ + uint16_t screenY = y * SFG_RESOLUTION_SCALEDOWN; + uint16_t screenX = x * SFG_RESOLUTION_SCALEDOWN; + + for (uint16_t j = screenY; j < screenY + SFG_RESOLUTION_SCALEDOWN; ++j) + for (uint16_t i = screenX; i < screenX + SFG_RESOLUTION_SCALEDOWN; ++i) + SFG_setPixel(i,j,colorIndex); +} +#endif + void SFG_recompurePLayerDirection() { SFG_player.camera.direction = RCL_wrap(SFG_player.camera.direction,RCL_UNITS_PER_SQUARE); @@ -140,15 +165,15 @@ void SFG_recompurePLayerDirection() SFG_player.direction.y = (SFG_player.direction.y * SFG_PLAYER_MOVE_UNITS_PER_FRAME) / RCL_UNITS_PER_SQUARE; SFG_backgroundScroll = - ((SFG_player.camera.direction * 8) * SFG_RESOLUTION_Y) / RCL_UNITS_PER_SQUARE; + ((SFG_player.camera.direction * 8) * SFG_GAME_RESOLUTION_Y) / RCL_UNITS_PER_SQUARE; } void SFG_initPlayer() { RCL_initCamera(&SFG_player.camera); - SFG_player.camera.resolution.x = SFG_RESOLUTION_X / SFG_RAYCASTING_SUBSAMPLE; - SFG_player.camera.resolution.y = SFG_RESOLUTION_Y; + SFG_player.camera.resolution.x = SFG_GAME_RESOLUTION_X / SFG_RAYCASTING_SUBSAMPLE; + SFG_player.camera.resolution.y = SFG_GAME_RESOLUTION_Y; SFG_player.camera.height = RCL_UNITS_PER_SQUARE * 12; SFG_player.camera.position.x = RCL_UNITS_PER_SQUARE * 15; SFG_player.camera.position.y = RCL_UNITS_PER_SQUARE * 8; @@ -296,7 +321,7 @@ void SFG_pixelFunc(RCL_PixelInfo *pixel) else { color = SFG_getTexel(SFG_backgrounds[0], - SFG_backgroundScaleMap[(pixel->position.x * SFG_RAYCASTING_SUBSAMPLE + SFG_backgroundScroll) % SFG_RESOLUTION_Y], + SFG_backgroundScaleMap[(pixel->position.x * SFG_RAYCASTING_SUBSAMPLE + SFG_backgroundScroll) % SFG_GAME_RESOLUTION_Y], // ^ TODO: get rid of mod? SFG_backgroundScaleMap[pixel->position.y]); } @@ -305,12 +330,12 @@ void SFG_pixelFunc(RCL_PixelInfo *pixel) for (uint8_t i = 0; i < SFG_RAYCASTING_SUBSAMPLE; ++i) { - SFG_setPixel(screenX,pixel->position.y,color); + SFG_setGamePixel(screenX,pixel->position.y,color); screenX++; } } -#define SFG_MAX_SPRITE_SIZE SFG_RESOLUTION_X +#define SFG_MAX_SPRITE_SIZE SFG_GAME_RESOLUTION_X uint8_t SFG_spriteSamplingPoints[SFG_MAX_SPRITE_SIZE]; @@ -343,8 +368,8 @@ void SFG_drawScaledImage( int16_t x1 = topLeftX + size - 1; - if (x1 >= SFG_RESOLUTION_X) - x1 = SFG_RESOLUTION_X - 1; + if (x1 >= SFG_GAME_RESOLUTION_X) + x1 = SFG_GAME_RESOLUTION_X - 1; int16_t y0, v0; @@ -361,8 +386,8 @@ void SFG_drawScaledImage( int16_t y1 = topLeftY + size - 1; - if (y1 >= SFG_RESOLUTION_Y) - y1 = SFG_RESOLUTION_Y - 1; + if (y1 >= SFG_GAME_RESOLUTION_Y) + y1 = SFG_GAME_RESOLUTION_Y - 1; if ((x0 > x1) || (y0 > y1)) // completely outside screen? return; @@ -395,7 +420,7 @@ void SFG_drawScaledImage( for (int16_t x = x0, u = u0; x <= x1; ++x, ++u) for (int16_t y = y0, v = v0; y <= y1; ++y, ++v) - SFG_setPixel(x,y,SFG_getTexel(image, + SFG_setGamePixel(x,y,SFG_getTexel(image, SFG_spriteSamplingPoints[u], SFG_spriteSamplingPoints[v])); } @@ -497,8 +522,9 @@ void SFG_init() SFG_rayConstraints.maxHits = SFG_RAYCASTING_MAX_HITS; SFG_rayConstraints.maxSteps = SFG_RAYCASTING_MAX_STEPS; - for (uint16_t i = 0; i < SFG_RESOLUTION_Y; ++i) - SFG_backgroundScaleMap[i] = (i * SFG_TEXTURE_SIZE) / SFG_RESOLUTION_Y; + for (uint16_t i = 0; i < SFG_GAME_RESOLUTION_Y; ++i) + SFG_backgroundScaleMap[i] = + (i * SFG_TEXTURE_SIZE) / SFG_GAME_RESOLUTION_Y; SFG_backgroundScroll = 0; diff --git a/platform_pokitto.h b/platform_pokitto.h index 9ced7e6..723ca38 100644 --- a/platform_pokitto.h +++ b/platform_pokitto.h @@ -19,11 +19,14 @@ #undef SFG_FPS #define SFG_FPS 50 -#undef SFG_RESOLUTION_X -#define SFG_RESOLUTION_X 110 +#undef SFG_SCREEN_RESOLUTION_X +#define SFG_SCREEN_RESOLUTION_X 110 -#undef SFG_RESOLUTION_Y -#define SFG_RESOLUTION_Y 88 +#undef SFG_SCREEN_RESOLUTION_Y +#define SFG_SCREEN_RESOLUTION_Y 88 + +#undef SFG_RESOLUTION_SCALEDOWN +#define SFG_RESOLUTION_SCALEDOWN 1 #undef SFG_DITHERED_SHADOW #define SFG_DITHERED_SHADOW 0 @@ -43,7 +46,7 @@ uint8_t *pokittoScreen; void SFG_setPixel(uint16_t x, uint16_t y, uint8_t colorIndex) { - pokittoScreen[y * SFG_RESOLUTION_X + x] = colorIndex; + pokittoScreen[y * SFG_SCREEN_RESOLUTION_X + x] = colorIndex; } uint32_t SFG_getTimeMs() diff --git a/platform_sdl.h b/platform_sdl.h index f866c09..43290a1 100644 --- a/platform_sdl.h +++ b/platform_sdl.h @@ -28,11 +28,11 @@ const uint8_t *sdlKeyboardState; -uint16_t screen[SFG_RESOLUTION_X * SFG_RESOLUTION_Y]; // RGB565 format +uint16_t screen[SFG_SCREEN_RESOLUTION_X * SFG_SCREEN_RESOLUTION_Y]; // RGB565 format void SFG_setPixel(uint16_t x, uint16_t y, uint8_t colorIndex) { - screen[y * SFG_RESOLUTION_X + x] = paletteRGB565[colorIndex]; + screen[y * SFG_SCREEN_RESOLUTION_X + x] = paletteRGB565[colorIndex]; } uint32_t SFG_getTimeMs() @@ -128,7 +128,10 @@ int main(int argc, char *argv[]) printf("possible arguments:\n\n"); printf("-h print this help and end\n"); printf("-w force run in window\n"); - printf("-f force run fullscreen\n"); + printf("-f force run fullscreen\n\n"); + printf("controls:\n"); + printf("TODO\n"); + return 0; } @@ -138,14 +141,14 @@ int main(int argc, char *argv[]) SDL_Window *window = SDL_CreateWindow("raycasting", SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, SFG_RESOLUTION_X, SFG_RESOLUTION_Y, + SDL_WINDOWPOS_UNDEFINED, SFG_SCREEN_RESOLUTION_X, SFG_SCREEN_RESOLUTION_Y, SDL_WINDOW_SHOWN); SDL_Renderer *renderer = SDL_CreateRenderer(window,-1,0); SDL_Texture *texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB565,SDL_TEXTUREACCESS_STATIC, - SFG_RESOLUTION_X,SFG_RESOLUTION_Y); + SFG_SCREEN_RESOLUTION_X,SFG_SCREEN_RESOLUTION_Y); SDL_Surface *screenSurface = SDL_GetWindowSurface(window); @@ -174,7 +177,7 @@ int main(int argc, char *argv[]) SFG_mainLoopBody(); - SDL_UpdateTexture(texture,NULL,screen,SFG_RESOLUTION_X * sizeof(uint16_t)); + SDL_UpdateTexture(texture,NULL,screen,SFG_SCREEN_RESOLUTION_X * sizeof(uint16_t)); SDL_RenderClear(renderer); SDL_RenderCopy(renderer,texture,NULL,NULL); diff --git a/settings.h b/settings.h index c6fb726..970907a 100644 --- a/settings.h +++ b/settings.h @@ -17,9 +17,33 @@ #ifndef _SFG_SETTINGS_H #define _SFG_SETTINGS_H +/** + Target FPS (frames per second). This sets the game logic FPS and will try to + render at the same rate. If such fast rendering can't be achieved, frames will + be droped, but the game logic will still be forced to run at this speed, so + the game may actually become slowed down if FPS is set too high. +*/ #define SFG_FPS 60 -#define SFG_RESOLUTION_X 1024 -#define SFG_RESOLUTION_Y 768 + +/** + Width of the screen in pixels. Set this to ACTUAL resolution. If you want the + game to run at smaller resolution (with bigger pixels), do his using + SFG_RESOLUTION_SCALEDOWN; +*/ +#define SFG_SCREEN_RESOLUTION_X 1024 + +/** + Height of the screen in pixels. Set this to ACTUAL resolution. If you want the + game to run at smaller resolution (with bigger pixels), do his using + SFG_RESOLUTION_SCALEDOWN; +*/ +#define SFG_SCREEN_RESOLUTION_Y 768 + +/** + How many times the screen resolution will be divided (how many times a game + pixel will be bigger than the screen pixel). +*/ +#define SFG_RESOLUTION_SCALEDOWN 4 /** Turn on for previes mode for map editing (flying, noclip, fast movement etc.).