diff --git a/frontend_sdl.c b/frontend_sdl.c index 7bb61ba..b0ff988 100644 --- a/frontend_sdl.c +++ b/frontend_sdl.c @@ -1 +1,100 @@ +#include +#include + #include "game.h" +#include "debug.h" + +SDL_Window *window; +SDL_Renderer *renderer; +SDL_Texture *texture; +SDL_Surface *screenSurface; +uint16_t screen[LCR_SETTING_RESOLUTION_X * LCR_SETTING_RESOLUTION_Y]; + +const uint8_t *keyboardState; + +uint8_t LCR_keyPressed(uint8_t key) +{ + switch (key) + { + case LCR_KEY_UP: return + keyboardState[SDL_SCANCODE_W] | keyboardState[SDL_SCANCODE_UP]; break; + + case LCR_KEY_RIGHT: return + keyboardState[SDL_SCANCODE_D] | keyboardState[SDL_SCANCODE_RIGHT]; break; + + case LCR_KEY_DOWN: return + keyboardState[SDL_SCANCODE_S] | keyboardState[SDL_SCANCODE_DOWN]; break; + + case LCR_KEY_LEFT: return + keyboardState[SDL_SCANCODE_A] | keyboardState[SDL_SCANCODE_LEFT]; break; + + case LCR_KEY_A: return + keyboardState[SDL_SCANCODE_K] | keyboardState[SDL_SCANCODE_RETURN]; break; + + case LCR_KEY_B: return + keyboardState[SDL_SCANCODE_L] | keyboardState[SDL_SCANCODE_ESCAPE]; break; + + default: break; + } + + return 0; +} + +void LCR_sleep(uint16_t timeMs) +{ +} + +void LCR_drawPixel(unsigned int x, unsigned int y, uint_fast16_t color) +{ + screen[y * LCR_SETTING_RESOLUTION_X + x] = color; +} + +int main(int argc, char *argv[]) +{ + uint8_t running = 1; + LCR_gameInit(); + + SDL_Init(0); + + window = + SDL_CreateWindow("Licar", SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, LCR_SETTING_RESOLUTION_X, LCR_SETTING_RESOLUTION_Y, + SDL_WINDOW_SHOWN); + + renderer = SDL_CreateRenderer(window,-1,0); + + texture = + SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB565,SDL_TEXTUREACCESS_STATIC, + LCR_SETTING_RESOLUTION_X,LCR_SETTING_RESOLUTION_Y); + + screenSurface = SDL_GetWindowSurface(window); + + SDL_ShowCursor(0); + + SDL_PumpEvents(); + keyboardState = SDL_GetKeyboardState(NULL); + + while (running) + { + SDL_PumpEvents(); + keyboardState = SDL_GetKeyboardState(NULL); + running = !keyboardState[SDL_SCANCODE_Q]; + + running &= LCR_gameStep(SDL_GetTicks()); + + SDL_UpdateTexture(texture,NULL,screen, + LCR_SETTING_RESOLUTION_X * sizeof(uint16_t)); + + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer,texture,NULL,NULL); + SDL_RenderPresent(renderer); + } + + SDL_DestroyTexture(texture); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + + LCR_gameEnd(); + + return 0; +} diff --git a/game.h b/game.h index 5a025e8..0d0ab08 100644 --- a/game.h +++ b/game.h @@ -1,42 +1,91 @@ +/** + Licar game: this file implements the backend of a complete, actually playable + licar game, and is meant to be included and used by specific frontends (which + will handle each platform's hardware details and I/O). +*/ + #ifndef _LCR_GAME_H #define _LCR_GAME_H #include "map.h" -#define LCR_KEY_UP 0x00 -#define LCR_KEY_RIGHT 0x01 -#define LCR_KEY_DOWN 0x02 -#define LCR_KEY_LEFT 0x03 -#define LCR_KEY_A 0x04 ///< confirm, restart race -#define LCR_KEY_B 0x05 ///< cancel, open menu +#define LCR_KEY_UP 0x00 +#define LCR_KEY_RIGHT 0x01 +#define LCR_KEY_DOWN 0x02 +#define LCR_KEY_LEFT 0x03 +#define LCR_KEY_A 0x04 ///< confirm, restart race +#define LCR_KEY_B 0x05 ///< cancel, open menu +#define LCR_KEYS_TOTAL 6 + +/* + FOR FRONTENDS: + - Implement the below described functions according to their description. + - Implement the main program and game loop. + - Call the below described functions as described. +*/ + +/** + Implement this in your frontend. Returns 1 if given key is pressed or 0 + otherwise. +*/ uint8_t LCR_keyPressed(uint8_t key); +/** + Implement this in your frontend. This function pauses program execution for + given amount of milliseconds and relieves the CPU usage. On platforms that + don't support this the function may simply do nothing. +*/ void LCR_sleep(uint16_t timeMs); +/** + Implement this in your frontend. This function draws a pixel of given color + to the screen back buffer (i.e. NOT directly to screen, back buffer shall + only be copied to front buffer once the LCR_gameStep function finishes all + rendering). This function should NOT check for out-of-screen coordinates, this + is handled by the game internals and out-of-screen pixels will never be drawn. + The color value depends on game settings but is normally an RGB565 value. +*/ void LCR_drawPixel(unsigned int x, unsigned int y, uint_fast16_t color); /** - Call at the start of the program. + Call this function in your frontend at the start of the program. */ void LCR_gameInit(void); /** - Call right before program end. + Call this function in your frontend right before program end. */ void LCR_gameEnd(void); /** - Call this repeatedly in your main loop, pass the current time as the number - of milliseconds since program start. Returns 0 if program should end, - otherwise 1. + Call this function in your frontend repeatedly inside the main loop, pass the + current time as the number of milliseconds since program start. This function + will perform the game step AND other things such as checking the input states, + rendering or sleeping (all using the above functions you should implement). + Returns 0 if program should end, otherwise 1. */ uint8_t LCR_gameStep(uint32_t timeMs); //------------------------------------------------------------------------------ +uint8_t _LCR_keyStates[LCR_KEYS_TOTAL]; /**< Assures unchanging key states + during a single frame. */ + +/** + Internal pixel drawing function that checks for out-of-screen coordinates. +*/ +static inline void _LCR_drawPixel(unsigned int x, unsigned int y, + uint_fast16_t color) +{ + if (x < LCR_SETTING_RESOLUTION_X && y < LCR_SETTING_RESOLUTION_Y) + LCR_drawPixel(x,y,color); +} + void LCR_gameInit(void) { + for (int i = 0; i < LCR_KEYS_TOTAL; ++i) + _LCR_keyStates[i] = 0; } void LCR_gameEnd(void) @@ -45,6 +94,14 @@ void LCR_gameEnd(void) uint8_t LCR_gameStep(uint32_t time) { + for (int i = 0; i < LCR_KEYS_TOTAL; ++i) + _LCR_keyStates[i] = LCR_keyPressed(i); + + for (int i = 0; i < 100; ++i) + for (int j = 0; j < 50; ++j) + _LCR_drawPixel(i,j,0x00ff); + + return 1; } #endif // guard diff --git a/main_sdl.c b/main_sdl.c deleted file mode 100644 index 6da7ff6..0000000 --- a/main_sdl.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include - -#include "game.h" -#include "debug.h" - -SDL_Window *window; -SDL_Renderer *renderer; -SDL_Texture *texture; -SDL_Surface *screenSurface; - -const uint8_t *sdlKeyboardState; - -int main(int argc, char *argv[]) -{ - uint8_t running = 1; - LCR_gameInit(); - - SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK); - - window = - SDL_CreateWindow("Licar", SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, LCR_SETTING_RESOLUTION_X, LCR_SETTING_RESOLUTION_Y, - SDL_WINDOW_SHOWN); - - renderer = SDL_CreateRenderer(window,-1,0); - - texture = - SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB565,SDL_TEXTUREACCESS_STATIC, - LCR_SETTING_RESOLUTION_X,LCR_SETTING_RESOLUTION_Y); - - screenSurface = SDL_GetWindowSurface(window); - - SDL_ShowCursor(0); - - SDL_PumpEvents(); - sdlKeyboardState = SDL_GetKeyboardState(NULL); - - while (running) - { - SDL_PumpEvents(); - sdlKeyboardState = SDL_GetKeyboardState(NULL); - running = !sdlKeyboardState[SDL_SCANCODE_Q]; - - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer,texture,NULL,NULL); - SDL_RenderPresent(renderer); - } - - SDL_DestroyTexture(texture); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - - LCR_gameEnd(); - - return 0; -} diff --git a/settings.h b/settings.h index f112fef..59059f8 100644 --- a/settings.h +++ b/settings.h @@ -2,11 +2,11 @@ #define _LCR_SETTINGS_H #ifndef LCR_SETTING_RESOLUTION_X - #define LCR_SETTING_RESOLUTION_X 800 + #define LCR_SETTING_RESOLUTION_X 1024 #endif #ifndef LCR_SETTING_RESOLUTION_Y - #define LCR_SETTING_RESOLUTION_Y 600 + #define LCR_SETTING_RESOLUTION_Y 768 #endif #ifndef LCR_SETTING_MAP_MAX_SIZE